47 void Foam::meshDualiser::checkPolyTopoChange(
const polyTopoChange& meshMod)
51 forAll(meshMod.points(), i)
53 points[i] = meshMod.points()[i];
65 if (nUnique <
points.size())
71 if (newToOld[newI].size() != 1)
74 <<
"duplicate verts:" << newToOld[newI]
76 << UIndirectList<point>(
points, newToOld[newI])
85 void Foam::meshDualiser::dumpPolyTopoChange
87 const polyTopoChange& meshMod,
88 const fileName& prefix
91 OFstream str1(prefix +
"Faces.obj");
92 OFstream str2(prefix +
"Edges.obj");
94 Info<<
"Dumping current polyTopoChange. Faces to " << str1.name()
95 <<
" , points and edges to " << str2.name() <<
endl;
97 const DynamicList<point>&
points = meshMod.points();
105 const DynamicList<face>& faces = meshMod.faces();
109 const face&
f = faces[facei];
114 str1<<
' ' <<
f[fp]+1;
121 str2<<
' ' <<
f[fp]+1;
123 str2<<
' ' <<
f[0]+1 <<
nl;
128 Foam::label Foam::meshDualiser::findDualCell
134 const labelList& dualCells = pointToDualCells_[pointi];
136 if (dualCells.size() == 1)
142 label index = mesh_.pointCells()[pointi].find(celli);
144 return dualCells[index];
149 void Foam::meshDualiser::generateDualBoundaryEdges
151 const bitSet& isBoundaryEdge,
153 polyTopoChange& meshMod
156 const labelList& pEdges = mesh_.pointEdges()[pointi];
160 label edgeI = pEdges[pEdgeI];
162 if (edgeToDualPoint_[edgeI] == -1 && isBoundaryEdge.test(edgeI))
164 const edge&
e = mesh_.edges()[edgeI];
166 edgeToDualPoint_[edgeI] = meshMod.addPoint
168 e.centre(mesh_.points()),
180 bool Foam::meshDualiser::sameDualCell
186 if (!mesh_.isInternalFace(facei))
189 <<
"face:" << facei <<
" is not internal face."
193 label own = mesh_.faceOwner()[facei];
194 label nei = mesh_.faceNeighbour()[facei];
196 return findDualCell(own, pointi) == findDualCell(nei, pointi);
200 Foam::label Foam::meshDualiser::addInternalFace
202 const label masterPointi,
203 const label masterEdgeI,
204 const label masterFacei,
206 const bool edgeOrder,
207 const label dualCell0,
208 const label dualCell1,
209 const DynamicList<label>& verts,
210 polyTopoChange& meshMod
215 if (edgeOrder != (dualCell0 < dualCell1))
222 pointField facePoints(meshMod.points(), newFace);
233 if (nUnique < facePoints.size())
236 <<
"verts:" << verts <<
" newFace:" << newFace
237 <<
" face points:" << facePoints
244 bool zoneFlip =
false;
245 if (masterFacei != -1)
247 zoneID = mesh_.faceZones().whichZone(masterFacei);
251 const faceZone& fZone = mesh_.faceZones()[
zoneID];
253 zoneFlip = fZone.flipMap()[fZone.whichFace(masterFacei)];
259 if (dualCell0 < dualCell1)
261 dualFacei = meshMod.addFace
288 dualFacei = meshMod.addFace
317 Foam::label Foam::meshDualiser::addBoundaryFace
319 const label masterPointi,
320 const label masterEdgeI,
321 const label masterFacei,
323 const label dualCelli,
325 const DynamicList<label>& verts,
326 polyTopoChange& meshMod
332 bool zoneFlip =
false;
333 if (masterFacei != -1)
335 zoneID = mesh_.faceZones().whichZone(masterFacei);
339 const faceZone& fZone = mesh_.faceZones()[
zoneID];
341 zoneFlip = fZone.flipMap()[fZone.whichFace(masterFacei)];
345 label dualFacei = meshMod.addFace
376 void Foam::meshDualiser::createFacesAroundEdge
378 const bool splitFace,
379 const bitSet& isBoundaryEdge,
381 const label startFacei,
382 polyTopoChange& meshMod,
386 const edge&
e = mesh_.edges()[edgeI];
387 const labelList& eFaces = mesh_.edgeFaces()[edgeI];
391 mesh_.faces()[startFacei],
396 edgeFaceCirculator ie
402 isBoundaryEdge.test(edgeI)
406 bool edgeOrder = ie.sameOrder(
e[0],
e[1]);
407 label startFaceLabel = ie.faceLabel();
418 DynamicList<label> verts(100);
420 if (edgeToDualPoint_[edgeI] != -1)
422 verts.append(edgeToDualPoint_[edgeI]);
424 if (faceToDualPoint_[ie.faceLabel()] != -1)
426 doneEFaces[eFaces.find(ie.faceLabel())] =
true;
427 verts.append(faceToDualPoint_[ie.faceLabel()]);
429 if (cellToDualPoint_[ie.cellLabel()] != -1)
431 verts.append(cellToDualPoint_[ie.cellLabel()]);
434 label currentDualCell0 = findDualCell(ie.cellLabel(),
e[0]);
435 label currentDualCell1 = findDualCell(ie.cellLabel(),
e[1]);
441 label facei = ie.faceLabel();
444 doneEFaces[eFaces.find(facei)] =
true;
446 if (faceToDualPoint_[facei] != -1)
448 verts.append(faceToDualPoint_[facei]);
451 label celli = ie.cellLabel();
461 label dualCell0 = findDualCell(celli,
e[0]);
462 label dualCell1 = findDualCell(celli,
e[1]);
470 dualCell0 != currentDualCell0
471 || dualCell1 != currentDualCell1
489 currentDualCell0 = dualCell0;
490 currentDualCell1 = dualCell1;
493 if (edgeToDualPoint_[edgeI] != -1)
495 verts.append(edgeToDualPoint_[edgeI]);
497 if (faceToDualPoint_[facei] != -1)
499 verts.append(faceToDualPoint_[facei]);
503 if (cellToDualPoint_[celli] != -1)
505 verts.append(cellToDualPoint_[celli]);
514 if (!isBoundaryEdge.test(edgeI))
516 label startDual = faceToDualPoint_[startFaceLabel];
518 if (startDual != -1 && !verts.found(startDual))
520 verts.append(startDual);
545 void Foam::meshDualiser::createFaceFromInternalFace
549 polyTopoChange& meshMod
552 const face&
f = mesh_.faces()[facei];
553 const labelList& fEdges = mesh_.faceEdges()[facei];
554 label own = mesh_.faceOwner()[facei];
555 label nei = mesh_.faceNeighbour()[facei];
566 DynamicList<label> verts(100);
568 verts.append(faceToDualPoint_[facei]);
569 verts.append(edgeToDualPoint_[fEdges[fp]]);
575 label currentDualCell0 = findDualCell(own,
f[fp]);
576 label currentDualCell1 = findDualCell(nei,
f[fp]);
581 if (pointToDualPoint_[
f[fp]] != -1)
583 verts.append(pointToDualPoint_[
f[fp]]);
587 label edgeI = fEdges[fp];
589 if (edgeToDualPoint_[edgeI] != -1)
591 verts.append(edgeToDualPoint_[edgeI]);
595 label nextFp =
f.fcIndex(fp);
598 label dualCell0 = findDualCell(own,
f[nextFp]);
599 label dualCell1 = findDualCell(nei,
f[nextFp]);
601 if (dualCell0 != currentDualCell0 || dualCell1 != currentDualCell1)
604 if (edgeToDualPoint_[edgeI] == -1)
607 <<
"face:" << facei <<
" verts:" <<
f
608 <<
" points:" << UIndirectList<point>(mesh_.points(),
f)
609 <<
" no feature edge between " <<
f[fp]
610 <<
" and " <<
f[nextFp] <<
" although have different"
611 <<
" dual cells." <<
endl
612 <<
"point " <<
f[fp] <<
" has dual cells "
613 << currentDualCell0 <<
" and " << currentDualCell1
614 <<
" ; point "<<
f[nextFp] <<
" has dual cells "
615 << dualCell0 <<
" and " << dualCell1
643 void Foam::meshDualiser::createFacesAroundBoundaryPoint
646 const label patchPointi,
647 const label startFacei,
648 polyTopoChange& meshMod,
652 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
653 const polyPatch& pp =
patches[patchi];
655 const labelList& own = mesh_.faceOwner();
657 label pointi = pp.meshPoints()[patchPointi];
659 if (pointToDualPoint_[pointi] == -1)
665 label facei = startFacei;
667 DynamicList<label> verts(4);
671 label index =
pFaces.find(facei-pp.start());
674 if (donePFaces[index])
678 donePFaces[index] =
true;
681 verts.append(faceToDualPoint_[facei]);
683 label dualCelli = findDualCell(own[facei], pointi);
686 const face&
f = mesh_.faces()[facei];
687 label fp =
f.find(pointi);
688 label prevFp =
f.rcIndex(fp);
689 label edgeI = mesh_.faceEdges()[facei][prevFp];
691 if (edgeToDualPoint_[edgeI] != -1)
693 verts.
append(edgeToDualPoint_[edgeI]);
697 edgeFaceCirculator circ
710 while (mesh_.isInternalFace(circ.faceLabel()));
713 facei = circ.faceLabel();
715 if (facei < pp.start() || facei >= pp.start()+pp.size())
718 <<
"Walked from face on patch:" << patchi
719 <<
" to face:" << facei
720 <<
" fc:" << mesh_.faceCentres()[facei]
726 if (dualCelli != findDualCell(own[facei], pointi))
729 <<
"Different dual cells but no feature edge"
730 <<
" inbetween point:" << pointi
731 <<
" coord:" << mesh_.points()[pointi]
738 label dualCelli = findDualCell(own[facei], pointi);
758 label facei = startFacei;
761 DynamicList<label> verts(mesh_.faces()[facei].size());
764 verts.append(pointToDualPoint_[pointi]);
767 const labelList& fEdges = mesh_.faceEdges()[facei];
768 label nextEdgeI = fEdges[mesh_.faces()[facei].find(pointi)];
769 if (edgeToDualPoint_[nextEdgeI] != -1)
771 verts.
append(edgeToDualPoint_[nextEdgeI]);
776 label index =
pFaces.find(facei-pp.start());
779 if (donePFaces[index])
783 donePFaces[index] =
true;
786 verts.append(faceToDualPoint_[facei]);
789 const labelList& fEdges = mesh_.faceEdges()[facei];
790 const face&
f = mesh_.faces()[facei];
791 label prevFp =
f.rcIndex(
f.find(pointi));
792 label edgeI = fEdges[prevFp];
794 if (edgeToDualPoint_[edgeI] != -1)
798 verts.
append(edgeToDualPoint_[edgeI]);
804 findDualCell(own[facei], pointi),
811 verts.append(pointToDualPoint_[pointi]);
812 verts.append(edgeToDualPoint_[edgeI]);
816 edgeFaceCirculator circ
829 while (mesh_.isInternalFace(circ.faceLabel()));
832 facei = circ.faceLabel();
837 && facei >= pp.start()
838 && facei < pp.start()+pp.size()
841 if (verts.size() > 2)
849 findDualCell(own[facei], pointi),
861 Foam::meshDualiser::meshDualiser(
const polyMesh&
mesh)
864 pointToDualCells_(mesh_.
nPoints()),
865 pointToDualPoint_(mesh_.
nPoints(), -1),
866 cellToDualPoint_(mesh_.nCells()),
867 faceToDualPoint_(mesh_.nFaces(), -1),
868 edgeToDualPoint_(mesh_.nEdges(), -1)
876 const bool splitFace,
879 const labelList& singleCellFeaturePoints,
881 polyTopoChange& meshMod
884 const labelList& own = mesh_.faceOwner();
885 const labelList& nei = mesh_.faceNeighbour();
886 const vectorField& cellCentres = mesh_.cellCentres();
891 bitSet isBoundaryEdge(mesh_.nEdges());
892 for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
894 const labelList& fEdges = mesh_.faceEdges()[facei];
896 isBoundaryEdge.
set(fEdges);
909 boolList featureFaceSet(mesh_.nFaces(),
false);
912 featureFaceSet[featureFaces[i]] =
true;
914 label facei = featureFaceSet.find(
false);
919 <<
"In split-face-mode (splitFace=true) but not all faces"
920 <<
" marked as feature faces." <<
endl
921 <<
"First conflicting face:" << facei
922 <<
" centre:" << mesh_.faceCentres()[facei]
926 boolList featureEdgeSet(mesh_.nEdges(),
false);
929 featureEdgeSet[featureEdges[i]] =
true;
931 label edgeI = featureEdgeSet.find(
false);
935 const edge&
e = mesh_.edges()[edgeI];
937 <<
"In split-face-mode (splitFace=true) but not all edges"
938 <<
" marked as feature edges." <<
endl
939 <<
"First conflicting edge:" << edgeI
941 <<
" coords:" << mesh_.points()[
e[0]] << mesh_.points()[
e[1]]
949 boolList featureFaceSet(mesh_.nFaces(),
false);
952 featureFaceSet[featureFaces[i]] =
true;
956 label facei = mesh_.nInternalFaces();
957 facei < mesh_.nFaces();
961 if (!featureFaceSet[facei])
964 <<
"Not all boundary faces marked as feature faces."
966 <<
"First conflicting face:" << facei
967 <<
" centre:" << mesh_.faceCentres()[facei]
997 autoPtr<OFstream> dualCcStr;
1000 dualCcStr.reset(
new OFstream(
"dualCc.obj"));
1001 Pout<<
"Dumping centres of dual cells to " << dualCcStr().
name()
1016 forAll(singleCellFeaturePoints, i)
1018 label pointi = singleCellFeaturePoints[i];
1020 pointToDualPoint_[pointi] = meshMod.addPoint
1022 mesh_.points()[pointi],
1024 mesh_.pointZones().whichZone(pointi),
1029 pointToDualCells_[pointi].setSize(1);
1030 pointToDualCells_[pointi][0] = meshMod.addCell
1038 if (dualCcStr.valid())
1045 forAll(multiCellFeaturePoints, i)
1047 label pointi = multiCellFeaturePoints[i];
1049 if (pointToDualCells_[pointi].size() > 0)
1052 <<
"Point " << pointi <<
" at:" << mesh_.points()[pointi]
1053 <<
" is both in singleCellFeaturePoints"
1054 <<
" and multiCellFeaturePoints."
1058 pointToDualPoint_[pointi] = meshMod.addPoint
1060 mesh_.points()[pointi],
1062 mesh_.pointZones().whichZone(pointi),
1068 const labelList& pCells = mesh_.pointCells()[pointi];
1070 pointToDualCells_[pointi].
setSize(pCells.size());
1074 pointToDualCells_[pointi][pCelli] = meshMod.addCell
1080 mesh_.cellZones().whichZone(pCells[pCelli])
1082 if (dualCcStr.valid())
1087 0.5*(mesh_.points()[pointi]+cellCentres[pCells[pCelli]])
1093 forAll(mesh_.points(), pointi)
1095 if (pointToDualCells_[pointi].empty())
1097 pointToDualCells_[pointi].setSize(1);
1098 pointToDualCells_[pointi][0] = meshMod.addCell
1107 if (dualCcStr.valid())
1118 forAll(cellToDualPoint_, celli)
1120 cellToDualPoint_[celli] = meshMod.addPoint
1123 mesh_.faces()[mesh_.cells()[celli][0]][0],
1133 label facei = featureFaces[i];
1135 faceToDualPoint_[facei] = meshMod.addPoint
1137 mesh_.faceCentres()[facei],
1138 mesh_.faces()[facei][0],
1146 for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
1148 if (faceToDualPoint_[facei] == -1)
1150 const face&
f = mesh_.faces()[facei];
1154 label ownDualCell = findDualCell(own[facei],
f[fp]);
1155 label neiDualCell = findDualCell(nei[facei],
f[fp]);
1157 if (ownDualCell != neiDualCell)
1159 faceToDualPoint_[facei] = meshMod.addPoint
1161 mesh_.faceCentres()[facei],
1177 label edgeI = featureEdges[i];
1179 const edge&
e = mesh_.edges()[edgeI];
1181 edgeToDualPoint_[edgeI] = meshMod.addPoint
1183 e.centre(mesh_.points()),
1198 if (edgeToDualPoint_[edgeI] == -1)
1200 const edge&
e = mesh_.edges()[edgeI];
1205 const labelList& eCells = mesh_.edgeCells()[edgeI];
1207 label dualE0 = findDualCell(eCells[0],
e[0]);
1208 label dualE1 = findDualCell(eCells[0],
e[1]);
1210 for (label i = 1; i < eCells.size(); i++)
1212 label newDualE0 = findDualCell(eCells[i],
e[0]);
1214 if (dualE0 != newDualE0)
1216 edgeToDualPoint_[edgeI] = meshMod.addPoint
1218 e.centre(mesh_.points()),
1220 mesh_.pointZones().whichZone(
e[0]),
1227 label newDualE1 = findDualCell(eCells[i],
e[1]);
1229 if (dualE1 != newDualE1)
1231 edgeToDualPoint_[edgeI] = meshMod.addPoint
1233 e.centre(mesh_.points()),
1235 mesh_.pointZones().whichZone(
e[1]),
1247 forAll(singleCellFeaturePoints, i)
1249 generateDualBoundaryEdges
1252 singleCellFeaturePoints[i],
1256 forAll(multiCellFeaturePoints, i)
1258 generateDualBoundaryEdges
1261 multiCellFeaturePoints[i],
1270 dumpPolyTopoChange(meshMod,
"generatedPoints_");
1271 checkPolyTopoChange(meshMod);
1285 const edgeList& edges = mesh_.edges();
1289 const labelList& eFaces = mesh_.edgeFaces()[edgeI];
1291 boolList doneEFaces(eFaces.size(),
false);
1301 label startFacei = eFaces[i];
1310 createFacesAroundEdge
1325 dumpPolyTopoChange(meshMod,
"generatedFacesFromEdges_");
1334 forAll(faceToDualPoint_, facei)
1336 if (faceToDualPoint_[facei] != -1 && mesh_.isInternalFace(facei))
1338 const face&
f = mesh_.faces()[facei];
1339 const labelList& fEdges = mesh_.faceEdges()[facei];
1348 bool foundStart =
false;
1354 edgeToDualPoint_[fEdges[fp]] != -1
1355 && !sameDualCell(facei,
f.nextLabel(fp))
1371 createFaceFromInternalFace
1384 dumpPolyTopoChange(meshMod,
"generatedFacesFromFeatFaces_");
1390 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
1394 const polyPatch& pp =
patches[patchi];
1398 forAll(pointFaces, patchPointi)
1409 label startFacei = pp.start()+
pFaces[i];
1418 createFacesAroundBoundaryPoint
1433 dumpPolyTopoChange(meshMod,
"generatedFacesFromBndFaces_");