55 { pointStatus::CONVEX,
"convex" },
56 { pointStatus::CONCAVE,
"concave" },
58 { pointStatus::NONFEATURE,
"nonFeature" },
68 { edgeStatus::EXTERNAL,
"external" },
69 { edgeStatus::INTERNAL,
"internal" },
70 { edgeStatus::FLAT,
"flat" },
71 { edgeStatus::OPEN,
"open" },
72 { edgeStatus::MULTIPLE,
"multiple" },
73 { edgeStatus::NONE,
"none" },
83 { sideVolumeType::INSIDE,
"inside" },
84 { sideVolumeType::OUTSIDE,
"outside" },
85 { sideVolumeType::BOTH,
"both" },
86 { sideVolumeType::NEITHER,
"neither" },
103 return wordHashSet(*fileExtensionConstructorTablePtr_);
109 return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
115 return edgeMeshFormatsCore::checkSupport
127 return edgeMeshFormatsCore::checkSupport
146 return canReadType(ext, verbose);
158 const labelList& ptEds(pointEdges()[ptI]);
160 label nPtEds = ptEds.
size();
172 edgeStatus edStat = getEdgeStatus(ptEds[i]);
174 if (edStat == EXTERNAL)
178 else if (edStat == INTERNAL)
184 if (nExternal == nPtEds)
188 else if (nInternal == nPtEds)
199 const searchableSurface& surf,
208 const edgeList& edges = this->edges();
212 List<List<pointIndexHit>> edgeHits(edges.size());
218 const edge&
e = edges[edgeI];
222 surf.findLineAll(start,
end, edgeHits);
229 nHits += edgeHits[edgeI].size();
232 DynamicField<point> newPoints(
points);
235 newPoints.setCapacity(newPoints.size()+nHits);
236 newToOldPoint.setCapacity(newPoints.capacity());
238 DynamicList<edge> newEdges(edges);
239 DynamicList<label> newToOldEdge(
identity(edges.size()));
241 newEdges.setCapacity(newEdges.size()+nHits);
242 newToOldEdge.setCapacity(newEdges.capacity());
245 DynamicList<label> dynPointsFromEdge(nHits);
246 DynamicList<label> dynOldEdge(nHits);
247 DynamicList<label> dynSurfTri(nHits);
251 const List<pointIndexHit>& eHits = edgeHits[edgeI];
255 label prevPtI = edges[edgeI][0];
258 label newPtI = newPoints.size();
260 newPoints.append(eHits[eHitI].hitPoint());
261 newToOldPoint.append(edges[edgeI][0]);
262 dynPointsFromEdge.append(newPtI);
263 dynOldEdge.append(edgeI);
264 dynSurfTri.append(eHits[eHitI].index());
268 newEdges[edgeI] = edge(prevPtI, newPtI);
272 newEdges.append(edge(prevPtI, newPtI));
273 newToOldEdge.append(edgeI);
277 newEdges.append(edge(prevPtI, edges[edgeI][1]));
278 newToOldEdge.append(edgeI);
284 pointMap.transfer(newToOldPoint);
288 edgeMap.transfer(newToOldEdge);
290 pointsFromEdge.transfer(dynPointsFromEdge);
291 oldEdge.transfer(dynOldEdge);
292 surfTri.transfer(dynSurfTri);
295 autoMap(
allPoints, allEdges, pointMap, edgeMap);
307 const edgeList& edges = this->edges();
316 const edge&
e = edges[edgeI];
319 List<volumeType> volTypes;
324 label compactEdgeI = 0;
328 if (volTypes[edgeI] == volType)
330 edgeMap[compactEdgeI++] = edgeI;
339 const edge&
e = edges[edgeMap[i]];
345 label compactPointI = 0;
346 forAll(pointToCompact, pointI)
348 if (pointToCompact[pointI] != -1)
350 pointToCompact[pointI] = compactPointI;
351 pointMap[compactPointI++] = pointI;
354 pointMap.
setSize(compactPointI);
361 const edge&
e = edges[edgeMap[i]];
362 subEdges[i][0] = pointToCompact[
e[0]];
363 subEdges[i][1] = pointToCompact[
e[1]];
367 autoMap(subPoints, subEdges, pointMap, edgeMap);
390 normalVolumeTypes_(0),
392 normalDirections_(0),
394 featurePointNormals_(0),
395 featurePointEdges_(0),
408 nonFeatureStart_(-1),
414 normalVolumeTypes_(0),
416 normalDirections_(0),
418 featurePointNormals_(0),
419 featurePointEdges_(0),
430 concaveStart_(fem.concaveStart()),
431 mixedStart_(fem.mixedStart()),
432 nonFeatureStart_(fem.nonFeatureStart()),
433 internalStart_(fem.internalStart()),
434 flatStart_(fem.flatStart()),
435 openStart_(fem.openStart()),
436 multipleStart_(fem.multipleStart()),
437 normals_(fem.normals()),
438 normalVolumeTypes_(fem.normalVolumeTypes()),
439 edgeDirections_(fem.edgeDirections()),
440 normalDirections_(fem.normalDirections()),
441 edgeNormals_(fem.edgeNormals()),
442 featurePointNormals_(fem.featurePointNormals()),
443 featurePointEdges_(fem.featurePointEdges()),
444 regionEdges_(fem.regionEdges()),
465 this->storedPoints() =
points;
466 this->storedEdges() = edges;
479 this->storedEdges().transfer(edges);
518 label sFEI = featureEdges[i];
521 const labelList& eFaces = edgeFaces[sFEI];
525 label eFI = eFaces[j];
532 surfBaffleRegions[surf[eFI].region()]
546 const PrimitivePatch<faceList, pointField>& surf,
552 extendedEdgeMesh(nullptr)
570 label nonFeatureStart,
586 concaveStart_(concaveStart),
587 mixedStart_(mixedStart),
588 nonFeatureStart_(nonFeatureStart),
589 internalStart_(internalStart),
590 flatStart_(flatStart),
591 openStart_(openStart),
592 multipleStart_(multipleStart),
594 normalVolumeTypes_(normalVolumeTypes),
595 edgeDirections_(edgeDirections),
596 normalDirections_(normalDirections),
597 edgeNormals_(edgeNormals),
598 featurePointNormals_(featurePointNormals),
599 featurePointEdges_(featurePointEdges),
600 regionEdges_(regionEdges),
642 const fileName&
name,
647 transfer(*
New(
name, fileType));
655 scalar searchDistSqr,
659 info = pointTree().findNearest
670 scalar searchDistSqr,
674 info = edgeTree().findNearest
707 List<pointIndexHit>& info
710 const PtrList<indexedOctree<treeDataEdge>>& edgeTrees = edgeTreesByType();
712 info.resize(edgeTrees.size());
716 const auto&
tree = edgeTrees[i];
717 const auto& treeData = edgeTrees[i].shapes();
719 info[i] =
tree.findNearest(sample, searchDistSqr[i]);
725 info[i].setIndex(treeData.objectIndex(info[i].index()));
733 scalar searchRadiusSqr,
734 List<pointIndexHit>& info
744 DynamicList<pointIndexHit> dynPointHit(elems.size());
746 const auto& treeData = pointTree().shapes();
748 for (
const label index : elems)
750 const point& pt = treeData.centre(index);
754 dynPointHit.append(nearHit);
757 info.transfer(dynPointHit);
764 const scalar searchRadiusSqr,
765 List<pointIndexHit>& info
768 const PtrList<indexedOctree<treeDataEdge>>& edgeTrees = edgeTreesByType();
770 DynamicList<pointIndexHit> dynEdgeHit(edgeTrees.size()*3);
775 const auto&
tree = edgeTrees[i];
776 const auto& treeData =
tree.shapes();
781 for (
const label index : elems)
783 pointHit hitPoint = treeData.line(index).nearestDist(sample);
788 const label hitIndex = treeData.objectIndex(index);
794 info.transfer(dynEdgeHit);
816 new indexedOctree<treeDataPoint>
818 treeDataPoint(
points(), featurePointLabels),
848 new indexedOctree<treeDataEdge>
850 treeDataEdge(edges(),
points()),
867 if (edgeTreesByType_.empty())
878 List<labelRange> sliceEdges(nEdgeTypes);
881 sliceEdges[0].reset(externalStart_, (internalStart_ - externalStart_));
884 sliceEdges[1].reset(internalStart_, (flatStart_ - internalStart_));
887 sliceEdges[2].reset(flatStart_, (openStart_ - flatStart_));
890 sliceEdges[3].reset(openStart_, (multipleStart_ - openStart_));
893 sliceEdges[4].reset(multipleStart_, (edges().size() - multipleStart_));
896 edgeTreesByType_.resize(nEdgeTypes);
898 forAll(edgeTreesByType_, i)
903 new indexedOctree<treeDataEdge>
906 treeDataEdge(edges(),
points(), sliceEdges[i]),
917 return edgeTreesByType_;
930 concaveStart_ =
mesh.concaveStart_;
931 mixedStart_ =
mesh.mixedStart_;
932 nonFeatureStart_ =
mesh.nonFeatureStart_;
933 internalStart_ =
mesh.internalStart_;
934 flatStart_ =
mesh.flatStart_;
935 openStart_ =
mesh.openStart_;
936 multipleStart_ =
mesh.multipleStart_;
938 normalVolumeTypes_.transfer(
mesh.normalVolumeTypes_);
939 edgeDirections_.transfer(
mesh.edgeDirections_);
940 normalDirections_.transfer(
mesh.normalDirections_);
941 edgeNormals_.transfer(
mesh.edgeNormals_);
942 featurePointNormals_.transfer(
mesh.featurePointNormals_);
943 featurePointEdges_.transfer(
mesh.featurePointEdges_);
944 regionEdges_.transfer(
mesh.regionEdges_);
945 pointTree_ = std::move(
mesh.pointTree_);
946 edgeTree_ = std::move(
mesh.edgeTree_);
947 edgeTreesByType_.transfer(
mesh.edgeTreesByType_);
958 nonFeatureStart_ = 0;
964 normalVolumeTypes_.clear();
965 edgeDirections_.clear();
966 normalDirections_.clear();
967 edgeNormals_.clear();
968 featurePointNormals_.clear();
969 featurePointEdges_.clear();
970 regionEdges_.clear();
971 pointTree_.reset(
nullptr);
972 edgeTree_.reset(
nullptr);
973 edgeTreesByType_.clear();
987 for (label i = 0; i < concaveStart(); i++)
998 for (label i = concaveStart(); i < mixedStart(); i++)
1009 for (label i = mixedStart(); i < nonFeatureStart(); i++)
1020 for (label i = nonFeatureStart(); i <
points().
size(); i++)
1030 newPoints.rmap(
points(), reversePointMap);
1031 newPoints.rmap(fem.
points(), reverseFemPointMap);
1038 labelList reverseEdgeMap(edges().size());
1043 for (label i = 0; i < internalStart(); i++)
1045 reverseEdgeMap[i] = newEdgeI++;
1049 reverseFemEdgeMap[i] = newEdgeI++;
1053 label newInternalStart = newEdgeI;
1054 for (label i = internalStart(); i < flatStart(); i++)
1056 reverseEdgeMap[i] = newEdgeI++;
1060 reverseFemEdgeMap[i] = newEdgeI++;
1064 label newFlatStart = newEdgeI;
1065 for (label i = flatStart(); i < openStart(); i++)
1067 reverseEdgeMap[i] = newEdgeI++;
1071 reverseFemEdgeMap[i] = newEdgeI++;
1075 label newOpenStart = newEdgeI;
1076 for (label i = openStart(); i < multipleStart(); i++)
1078 reverseEdgeMap[i] = newEdgeI++;
1082 reverseFemEdgeMap[i] = newEdgeI++;
1086 label newMultipleStart = newEdgeI;
1087 for (label i = multipleStart(); i < edges().
size(); i++)
1089 reverseEdgeMap[i] = newEdgeI++;
1093 reverseFemEdgeMap[i] = newEdgeI++;
1099 const edge&
e = edges()[i];
1100 newEdges[reverseEdgeMap[i]] = edge
1102 reversePointMap[
e[0]],
1103 reversePointMap[
e[1]]
1108 const edge&
e = fem.
edges()[i];
1109 newEdges[reverseFemEdgeMap[i]] = edge
1111 reverseFemPointMap[
e[0]],
1112 reverseFemPointMap[
e[1]]
1118 edgeDirections().size()
1121 newEdgeDirections.
rmap(edgeDirections(), reverseEdgeMap);
1129 DynamicField<point> newNormals
1134 newNormals.append(normals());
1135 newNormals.append(fem.
normals());
1141 edgeNormals().size()
1145 UIndirectList<labelList>
1148 SubList<label>(reverseEdgeMap, edgeNormals().
size())
1150 UIndirectList<labelList>
1158 const label mapI = reverseFemEdgeMap[i];
1162 en[j] += normals().
size();
1170 featurePointNormals().size()
1175 UIndirectList<labelList>
1177 newFeaturePointNormals,
1178 SubList<label>(reversePointMap, featurePointNormals().
size())
1179 ) = featurePointNormals();
1180 UIndirectList<labelList>
1182 newFeaturePointNormals,
1188 const label mapI = reverseFemPointMap[i];
1189 labelList& fn = newFeaturePointNormals[mapI];
1192 fn[j] += normals().
size();
1198 DynamicList<label> newRegionEdges
1200 regionEdges().size()
1205 newRegionEdges.append(reverseEdgeMap[regionEdges()[i]]);
1209 newRegionEdges.append(reverseFemEdgeMap[fem.
regionEdges()[i]]);
1217 concaveStart_ = newConcaveStart;
1218 mixedStart_ = newMixedStart;
1219 nonFeatureStart_ = newNonFeatureStart;
1223 edgeMesh newmesh(std::move(newPoints), std::move(newEdges));
1228 internalStart_ = newInternalStart;
1229 flatStart_ = newFlatStart;
1230 openStart_ = newOpenStart;
1231 multipleStart_ = newMultipleStart;
1233 edgeDirections_.transfer(newEdgeDirections);
1235 normals_.transfer(newNormals);
1236 edgeNormals_.transfer(newEdgeNormals);
1237 featurePointNormals_.transfer(newFeaturePointNormals);
1239 regionEdges_.transfer(newRegionEdges);
1241 pointTree_.reset(
nullptr);
1242 edgeTree_.reset(
nullptr);
1243 edgeTreesByType_.clear();
1259 for (label i = concaveStart(); i < mixedStart(); i++)
1265 for (label i = 0; i < concaveStart(); i++)
1281 for (label i = internalStart(); i < flatStart(); i++)
1283 reverseEdgeMap[i] = newEdgeI++;
1286 label newInternalStart = newEdgeI;
1287 for (label i = 0; i < internalStart(); i++)
1289 reverseEdgeMap[i] = newEdgeI++;
1294 newPoints.rmap(
points(), reversePointMap);
1299 const edge&
e = edges()[i];
1300 newEdges[reverseEdgeMap[i]] = edge
1302 reversePointMap[
e[0]],
1303 reversePointMap[
e[1]]
1311 pointField newEdgeDirections(edges().size());
1312 newEdgeDirections.rmap(-1.0*edgeDirections(), reverseEdgeMap);
1317 UIndirectList<labelList>(newEdgeNormals, reverseEdgeMap) = edgeNormals();
1319 labelListList newFeaturePointNormals(featurePointNormals().size());
1322 UIndirectList<labelList>
1324 newFeaturePointNormals,
1325 SubList<label>(reversePointMap, featurePointNormals().
size())
1326 ) = featurePointNormals();
1328 labelList newRegionEdges(regionEdges().size());
1331 newRegionEdges[i] = reverseEdgeMap[regionEdges()[i]];
1335 concaveStart_ = newConcaveStart;
1339 edgeMesh newmesh(std::move(newPoints), std::move(newEdges));
1344 internalStart_ = newInternalStart;
1346 edgeDirections_.transfer(newEdgeDirections);
1347 normals_.transfer(newNormals);
1348 edgeNormals_.transfer(newEdgeNormals);
1349 featurePointNormals_.transfer(newFeaturePointNormals);
1350 regionEdges_.transfer(newRegionEdges);
1352 pointTree_.reset(
nullptr);
1353 edgeTree_.reset(
nullptr);
1354 edgeTreesByType_.clear();
1367 label subIntStart = edgeMap.
size();
1368 label subFlatStart = edgeMap.
size();
1369 label subOpenStart = edgeMap.
size();
1370 label subMultipleStart = edgeMap.
size();
1372 forAll(edgeMap, subEdgeI)
1374 label edgeI = edgeMap[subEdgeI];
1375 if (edgeI >= internalStart() && subIntStart == edgeMap.
size())
1377 subIntStart = subEdgeI;
1379 if (edgeI >= flatStart() && subFlatStart == edgeMap.
size())
1381 subFlatStart = subEdgeI;
1383 if (edgeI >= openStart() && subOpenStart == edgeMap.
size())
1385 subOpenStart = subEdgeI;
1387 if (edgeI >= multipleStart() && subMultipleStart == edgeMap.
size())
1389 subMultipleStart = subEdgeI;
1396 label subConcaveStart = pointMap.
size();
1397 label subMixedStart = pointMap.
size();
1398 label subNonFeatStart = pointMap.
size();
1400 forAll(pointMap, subPointI)
1402 label pointI = pointMap[subPointI];
1403 if (pointI >= concaveStart() && subConcaveStart == pointMap.
size())
1405 subConcaveStart = subPointI;
1407 if (pointI >= mixedStart() && subMixedStart == pointMap.
size())
1409 subMixedStart = subPointI;
1413 pointI >= nonFeatureStart()
1414 && subNonFeatStart == pointMap.
size()
1417 subNonFeatStart = subPointI;
1426 bitSet isRegionEdge(edges().size(), regionEdges());
1428 DynamicList<label> newRegionEdges(regionEdges().size());
1429 forAll(edgeMap, subEdgeI)
1431 if (isRegionEdge.test(edgeMap[subEdgeI]))
1433 newRegionEdges.append(subEdgeI);
1436 subRegionEdges.transfer(newRegionEdges);
1441 if (featurePointEdges().size())
1443 subFeaturePointEdges.
setSize(subNonFeatStart);
1444 for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
1446 label pointI = pointMap[subPointI];
1447 const labelList& pEdges = featurePointEdges()[pointI];
1449 labelList& subPEdges = subFeaturePointEdges[subPointI];
1450 subPEdges.
setSize(pEdges.size());
1456 subPEdges[i] = edgeMap[pEdges[i]];
1463 vectorField subEdgeDirections(edgeDirections(), edgeMap);
1466 labelList reverseNormalMap(normals().size(), -1);
1467 DynamicList<label> normalMap(normals().size());
1470 bitSet isSubNormal(normals().size());
1471 for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
1473 label pointI = pointMap[subPointI];
1474 const labelList& pNormals = featurePointNormals()[pointI];
1476 isSubNormal.
set(pNormals);
1478 forAll(edgeMap, subEdgeI)
1480 label edgeI = edgeMap[subEdgeI];
1481 const labelList& eNormals = edgeNormals()[edgeI];
1483 isSubNormal.
set(eNormals);
1486 forAll(isSubNormal, normalI)
1488 if (isSubNormal.test(normalI))
1490 label subNormalI = normalMap.size();
1491 reverseNormalMap[normalI] = subNormalI;
1492 normalMap.append(subNormalI);
1501 if (normalDirections().size())
1505 forAll(edgeMap, subEdgeI)
1507 label edgeI = edgeMap[subEdgeI];
1508 const labelList& eNormals = normalDirections()[edgeI];
1510 labelList& subNormals = subNormalDirections[subEdgeI];
1511 subNormals.
setSize(eNormals.size());
1514 if (eNormals[i] >= 0)
1516 subNormals[i] = reverseNormalMap[eNormals[i]];
1527 forAll(edgeMap, subEdgeI)
1529 label edgeI = edgeMap[subEdgeI];
1530 const labelList& eNormals = edgeNormals()[edgeI];
1531 labelList& subNormals = subEdgeNormals[subEdgeI];
1537 for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
1539 label pointI = pointMap[subPointI];
1540 const labelList& pNormals = featurePointNormals()[pointI];
1541 labelList& subNormals = subPointNormals[subPointI];
1549 List<extendedEdgeMesh::sideVolumeType> subNormalVolumeTypes;
1550 if (normalVolumeTypes().size())
1552 subNormalVolumeTypes =
1553 UIndirectList<extendedEdgeMesh::sideVolumeType>
1555 normalVolumeTypes(),
1560 extendedEdgeMesh subMesh
1578 subNormalVolumeTypes,
1584 subNormalDirections,
1590 subFeaturePointEdges,
1630 select(surf, volType, subPointMap, subEdgeMap);
1641 edgeStat[edgeI] = getEdgeStatus(edgeI);
1643 forAll(pointStat, pointI)
1645 pointStat[pointI] = getPointStatus(pointI);
1649 labelList oldPointToIndex(nOldPoints, -1);
1650 forAll(pointsFromEdge, i)
1652 oldPointToIndex[pointsFromEdge[i]] = i;
1654 forAll(subPointMap, pointI)
1656 label oldPointI = subPointMap[pointI];
1657 label index = oldPointToIndex[oldPointI];
1660 pointStat[pointI] = classifyFeaturePoint(pointI);
1671 sortedToOriginalPoint,
1672 sortedToOriginalEdge
1676 pointMap =
labelUIndList(pointMap, sortedToOriginalPoint)();
1690 label pointConcaveStart;
1691 label pointMixedStart;
1692 label pointNonFeatStart;
1694 label edgeInternalStart;
1695 label edgeFlatStart;
1696 label edgeOpenStart;
1697 label edgeMultipleStart;
1702 sortedToOriginalPoint,
1703 sortedToOriginalEdge,
1718 forAll(sortedToOriginalPoint, sortedI)
1720 reversePointMap[sortedToOriginalPoint[sortedI]] = sortedI;
1723 edgeList sortedEdges(UIndirectList<edge>(edges(), sortedToOriginalEdge)());
1724 forAll(sortedEdges, sortedI)
1734 sortedToOriginalPoint,
1735 sortedToOriginalEdge
1739 concaveStart_ = pointConcaveStart;
1740 mixedStart_ = pointMixedStart;
1741 nonFeatureStart_ = pointNonFeatStart;
1742 internalStart_ = edgeInternalStart;
1743 flatStart_ = edgeFlatStart;
1744 openStart_ = edgeOpenStart;
1745 multipleStart_ = edgeMultipleStart;
1751 const scalar mergeDist,
1770 forAll(oldToMerged, oldI)
1772 label newI = oldToMerged[oldI];
1773 if (pointMap[newI] == -1)
1775 pointMap[newI] = oldI;
1783 const edge& oldE = edges()[edgeI];
1784 newEdges[edgeI] = edge(oldToMerged[oldE[0]], oldToMerged[oldE[1]]);
1797 List<edgeStatus> edgeStat(edges().size());
1800 edgeStat[edgeI] = getEdgeStatus(edgeI);
1803 List<pointStatus> pointStat(
points().size());
1804 forAll(pointStat, pointI)
1806 pointStat[pointI] = getPointStatus(pointI);
1811 forAll(oldToMerged, oldPointI)
1813 nPoints[oldToMerged[oldPointI]]++;
1820 pointStat[pointI] = classifyFeaturePoint(pointI);
1829 sortedToOriginalPoint,
1832 pointMap =
labelUIndList(pointMap, sortedToOriginalPoint)();
1834 return nNewPoints != nOldPoints;
1840 Info<<
nl <<
"Writing extendedEdgeMesh components to " << prefix
1846 OBJstream convexFtPtStr(prefix +
"_convexFeaturePts.obj");
1847 Info<<
"Writing " << concaveStart_
1848 <<
" convex feature points to " << convexFtPtStr.name() <<
endl;
1850 for (label i = 0; i < concaveStart_; i++)
1857 OBJstream concaveFtPtStr(prefix +
"_concaveFeaturePts.obj");
1858 Info<<
"Writing " << mixedStart_-concaveStart_
1859 <<
" concave feature points to " 1860 << concaveFtPtStr.name() <<
endl;
1862 for (label i = concaveStart_; i < mixedStart_; i++)
1869 OBJstream mixedFtPtStr(prefix +
"_mixedFeaturePts.obj");
1870 Info<<
"Writing " << nonFeatureStart_-mixedStart_
1871 <<
" mixed feature points to " << mixedFtPtStr.name() <<
endl;
1873 for (label i = mixedStart_; i < nonFeatureStart_; i++)
1880 OBJstream mixedFtPtStructureStr(prefix+
"_mixedFeaturePtsStructure.obj");
1882 << nonFeatureStart_-mixedStart_
1883 <<
" mixed feature point structure to " 1884 << mixedFtPtStructureStr.name() <<
endl;
1886 for (label i = mixedStart_; i < nonFeatureStart_; i++)
1888 const labelList& ptEds = pointEdges()[i];
1890 for (
const label edgei : ptEds)
1892 const edge&
e = edges()[edgei];
1893 mixedFtPtStructureStr.write(
e,
points());
1899 OBJstream externalStr(prefix +
"_externalEdges.obj");
1900 Info<<
"Writing " << internalStart_-externalStart_
1901 <<
" external edges to " << externalStr.name() <<
endl;
1903 for (label i = externalStart_; i < internalStart_; i++)
1905 const edge&
e = edges()[i];
1906 externalStr.write(
e,
points());
1911 OBJstream internalStr(prefix +
"_internalEdges.obj");
1912 Info<<
"Writing " << flatStart_-internalStart_
1913 <<
" internal edges to " << internalStr.name() <<
endl;
1915 for (label i = internalStart_; i < flatStart_; i++)
1917 const edge&
e = edges()[i];
1918 internalStr.write(
e,
points());
1923 OBJstream flatStr(prefix +
"_flatEdges.obj");
1924 Info<<
"Writing " << openStart_-flatStart_
1925 <<
" flat edges to " << flatStr.name() <<
endl;
1927 for (label i = flatStart_; i < openStart_; i++)
1929 const edge&
e = edges()[i];
1935 OBJstream openStr(prefix +
"_openEdges.obj");
1936 Info<<
"Writing " << multipleStart_-openStart_
1937 <<
" open edges to " << openStr.name() <<
endl;
1939 for (label i = openStart_; i < multipleStart_; i++)
1941 const edge&
e = edges()[i];
1947 OBJstream multipleStr(prefix +
"_multipleEdges.obj");
1948 Info<<
"Writing " << edges().
size()-multipleStart_
1949 <<
" multiple edges to " << multipleStr.name() <<
endl;
1951 for (label i = multipleStart_; i < edges().
size(); i++)
1953 const edge&
e = edges()[i];
1954 multipleStr.write(
e,
points());
1959 OBJstream regionStr(prefix +
"_regionEdges.obj");
1960 Info<<
"Writing " << regionEdges_.size()
1961 <<
" region edges to " << regionStr.name() <<
endl;
1963 for (
const label edgei : regionEdges_)
1965 const edge&
e = edges()[edgei];
1971 OBJstream edgeDirsStr(prefix +
"_edgeDirections.obj");
1972 Info<<
"Writing " << edgeDirections_.size()
1973 <<
" edge directions to " << edgeDirsStr.name() <<
endl;
1975 forAll(edgeDirections_, i)
1977 const vector& eVec = edgeDirections_[i];
1978 const edge&
e = edges()[i];
1980 edgeDirsStr.writeLine
1994 os <<
indent <<
"point classification :" <<
nl;
1996 os <<
indent <<
"convex feature points : " 1997 <<
setw(8) << concaveStart_-convexStart_
2000 os <<
indent <<
"concave feature points : " 2001 <<
setw(8) << mixedStart_-concaveStart_
2004 os <<
indent <<
"mixed feature points : " 2005 <<
setw(8) << nonFeatureStart_-mixedStart_
2008 os <<
indent <<
"other (non-feature) points : " 2014 os <<
indent <<
"edge classification :" <<
nl;
2016 os <<
indent <<
"external (convex angle) edges : " 2017 <<
setw(8) << internalStart_-externalStart_
2020 os <<
indent <<
"internal (concave angle) edges : " 2021 <<
setw(8) << flatStart_-internalStart_
2024 os <<
indent <<
"flat region edges : " 2025 <<
setw(8) << openStart_-flatStart_
2029 <<
setw(8) << multipleStart_-openStart_
2032 os <<
indent <<
"multiply connected edges : " 2033 <<
setw(8) << edges().
size()-multipleStart_
2048 label nEdNorms = edNorms.
size();
2054 else if (nEdNorms == 2)
2056 const vector& n0(norms[edNorms[0]]);
2057 const vector& n1(norms[edNorms[1]]);
2059 if ((n0 & n1) > cosNormalAngleTol_)
2063 else if ((fC0tofC1 & n0) > 0.0)
2072 else if (nEdNorms > 2)
2089 label& pointConcaveStart,
2090 label& pointMixedStart,
2091 label& pointNonFeatStart,
2093 label& edgeInternalStart,
2094 label& edgeFlatStart,
2095 label& edgeOpenStart,
2096 label& edgeMultipleStart
2100 sortedToOriginalPoint = -1;
2103 sortedToOriginalEdge = -1;
2114 forAll(pointStat, pointI)
2116 switch (pointStat[pointI])
2141 label convexStart = 0;
2142 label concaveStart = nConvex;
2143 label mixedStart = concaveStart+nConcave;
2144 label nonFeatStart = mixedStart+nMixed;
2148 pointConcaveStart = concaveStart;
2149 pointMixedStart = mixedStart;
2150 pointNonFeatStart = nonFeatStart;
2152 forAll(pointStat, pointI)
2154 switch (pointStat[pointI])
2157 sortedToOriginalPoint[convexStart++] = pointI;
2161 sortedToOriginalPoint[concaveStart++] = pointI;
2165 sortedToOriginalPoint[mixedStart++] = pointI;
2169 sortedToOriginalPoint[nonFeatStart++] = pointI;
2178 label nExternal = 0;
2179 label nInternal = 0;
2186 switch (edgeStat[edgeI])
2216 label externalStart = 0;
2217 label internalStart = nExternal;
2218 label flatStart = internalStart + nInternal;
2219 label openStart = flatStart + nFlat;
2220 label multipleStart = openStart + nOpen;
2224 edgeInternalStart = internalStart;
2225 edgeFlatStart = flatStart;
2226 edgeOpenStart = openStart;
2227 edgeMultipleStart = multipleStart;
2231 switch (edgeStat[edgeI])
2234 sortedToOriginalEdge[externalStart++] = edgeI;
2238 sortedToOriginalEdge[internalStart++] = edgeI;
2242 sortedToOriginalEdge[flatStart++] = edgeI;
2246 sortedToOriginalEdge[openStart++] = edgeI;
2250 sortedToOriginalEdge[multipleStart++] = edgeI;
2287 os << static_cast<label>(vt);
2296 os <<
"// points" <<
nl 2297 << em.points() <<
nl 2300 <<
"// concaveStart mixedStart nonFeatureStart" <<
nl 2303 << em.nonFeatureStart_ <<
nl 2304 <<
"// internalStart flatStart openStart multipleStart" <<
nl 2308 << em.multipleStart_ <<
nl 2309 <<
"// normals" <<
nl 2310 << em.normals_ <<
nl 2311 <<
"// normal volume types" <<
nl 2312 << em.normalVolumeTypes_ <<
nl 2313 <<
"// normalDirections" <<
nl 2314 << em.normalDirections_ <<
nl 2315 <<
"// edgeNormals" <<
nl 2316 << em.edgeNormals_ <<
nl 2317 <<
"// featurePointNormals" <<
nl 2318 << em.featurePointNormals_ <<
nl 2319 <<
"// featurePointEdges" <<
nl 2320 << em.featurePointEdges_ <<
nl 2321 <<
"// regionEdges" <<
nl 2333 is >>
static_cast<edgeMesh&
>(em)
2336 >> em.nonFeatureStart_
2337 >> em.internalStart_
2340 >> em.multipleStart_
2342 >> em.normalVolumeTypes_
2343 >> em.normalDirections_
2345 >> em.featurePointNormals_
2346 >> em.featurePointEdges_
extendedEdgeMesh()
Default construct.
label nonFeatureStart() const
Return the index of the start of the non-feature points.
const labelListList & featurePointNormals() const
Return the indices of the normals that are adjacent to the.
void size(const label n)
Older name for setAddressableSize.
static const Enum< sideVolumeType > sideVolumeTypeNames_
A class for handling file names.
static wordHashSet readTypes()
Summary of supported read file types.
Ostream & indent(Ostream &os)
Indent stream.
vectorField normals_
Normals of the features, to be referred to by index by both feature.
const pointField & points() const noexcept
Return points.
label nRegionEdges() const
Return number of region edges.
const labelListList & edgeNormals() const
Return the indices of the normals that are adjacent to the.
errorManipArg< error, int > exit(error &err, const int errNo=1)
void nearestFeaturePoint(const point &sample, scalar searchDistSqr, pointIndexHit &info) const
Find nearest surface edge for the sample point.
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Mixed uniform/non-uniform (eg, after reduction)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
List< edge > edgeList
List of edge.
void transfer(extendedEdgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
void select(const searchableSurface &surf, const volumeType volType, labelList &pMap, labelList &eMap)
Remove outside/inside edges. volType denotes which side to keep.
virtual void writeStats(Ostream &os) const
Dump some information.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
constexpr char nl
The newline '\n' character (0x0a)
Description of feature edges and points.
label multipleStart() const
Return the index of the start of the multiply-connected feature.
void trim(const searchableSurface &surf, const volumeType volType, labelList &pointMap, labelList &edgeMap)
Trim to surface. Keep volType side. Return map from current back.
UIndirectList< label > labelUIndList
UIndirectList of labels.
scalarField samples(nIntervals, Zero)
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool canWriteType(const word &fileType, bool verbose=false)
Can we write this file format type?
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
static void write(const fileName &name, const edgeMesh &mesh, IOstreamOption streamOpt=IOstreamOption(), const dictionary &options=dictionary::null)
Write to file (format implicit in the extension)
void cut(const searchableSurface &, labelList &pMap, labelList &eMap, labelList &pointsFromEdge, labelList &oldEdge, labelList &surfTri)
Cut edges with surface. Return map from cut points&edges back.
virtual void clear()
Clear all storage.
const vectorField & normals() const
Return the normals of the surfaces adjacent to the feature edges.
label openStart() const
Return the index of the start of the open feature edges.
This class describes the interaction of an object (often a face) and a point. It carries the info of ...
List< sideVolumeType > normalVolumeTypes_
Type per normal: which side of normal to mesh.
const labelList & featureEdges() const
Return feature edge list.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines. WIP.
const labelList & regionEdges() const
Return the feature edges which are on the boundary between.
static bool canReadType(const word &fileType, bool verbose=false)
Can we read this file format?
void writeObj(const fileName &prefix) const
Write all components of the extendedEdgeMesh as obj files.
An enumeration wrapper for classification of a location as being inside/outside of a volume...
A point surrounded by both convex and concave edges.
bool mergePointsAndSort(const scalar mergeDist, labelList &pointMap, labelList &edgeMap)
Geometric merge points. Returns true if any points merged.
List< labelList > labelListList
List of labelList.
void add(const extendedEdgeMesh &fem)
Add extendedEdgeMesh. No filtering of duplicates.
void setFromStatus(const List< extendedEdgeMesh::pointStatus > &pointStat, const List< extendedEdgeMesh::edgeStatus > &edgeStat, labelList &sortedToOriginalPoint, labelList &sortedToOriginalEdge)
Order according to point and edge status.
UList< label > labelUList
A UList of labels.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
bool read(const char *buf, int32_t &val)
Same as readInt32.
#define forAll(list, i)
Loop across all elements in list.
word ext() const
Return file name extension (part after last .)
label mergePoints(const PointList &points, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol=SMALL, const bool verbose=false)
Calculate merge mapping, preserving the original point order. All points closer/equal mergeTol are to...
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
vectorField pointField
pointField is a vectorField.
static void sortedOrder(const List< extendedEdgeMesh::pointStatus > &pointStat, const List< extendedEdgeMesh::edgeStatus > &edgeStat, labelList &sortedToOriginalPoint, labelList &sortedToOriginalEdge, label &pointConcaveStart, label &pointMixedStart, label &pointNonFeatStart, label &edgeInternalStart, label &edgeFlatStart, label &edgeOpenStart, label &edgeMultipleStart)
Determine the ordering.
const dimensionedScalar e
Elementary charge.
void flipNormals()
Flip normals. All concave become convex, all internal external.
void setSize(const label n)
Alias for resize()
label flatStart() const
Return the index of the start of the flat feature edges.
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
bool has_ext() const
Various checks for extensions.
static label convexStart_
Index of the start of the convex feature points - static as 0.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
label internalStart() const
Return the index of the start of the internal feature edges.
Info<< nl<< "Wrote faMesh in vtk format: "<< writer.output().name()<< nl;}{ const Field< vector > edgeCentres(faMeshTools::flattenEdgeField(aMesh.edgeCentres(), true))
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Istream & operator>>(Istream &, directionInfo &)
const triSurface & surface() const
Tree tree(triangles.begin(), triangles.end())
word lessExt() const
Return word without extension (part before last .)
sideVolumeType
Normals point to the outside.
static label externalStart_
Index of the start of the external feature edges - static as 0.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
const labelListList & edgeFaces() const
Return edge-face addressing.
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
static const Enum< edgeStatus > edgeStatusNames_
A location inside the volume.
const indexedOctree< treeDataEdge > & edgeTree() const
Demand driven construction of octree for boundary edges.
void autoMap(const pointField &subPoints, const edgeList &subEdges, const labelList &pointMap, const labelList &edgeMap)
Update with derived geometry.
A location outside the volume.
void sortPointsAndEdges(const Patch &, const labelUList &featureEdges, const labelUList ®ionFeatureEdges, const labelUList &feaurePoints)
static scalar cosNormalAngleTol_
Angular closeness tolerance for treating normals as the same.
label mixedStart() const
Return the index of the start of the mixed type feature points.
Fully convex point (w.r.t normals)
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Istream and Ostream manipulators taking arguments.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
An OFstream that keeps track of vertices and provides convenience output methods for OBJ files...
const labelList & featurePoints() const
Return feature point list.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
Mesh data needed to do the Finite Area discretisation.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
virtual void writeStats(Ostream &) const
Only connected to a single face.
const PtrList< indexedOctree< treeDataEdge > > & edgeTreesByType() const
Demand driven construction of octree for boundary edges by type.
static edgeStatus classifyEdge(const List< vector > &norms, const labelList &edNorms, const vector &fC0tofC1)
Classify the type of feature edge. Requires face centre 0 to face.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
virtual void clear()
Clear all storage.
const vectorField & edgeDirections() const
Return the edgeDirection vectors.
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
vector point
Point is a vector.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
const edgeList & edges() const noexcept
Return edges.
static const Enum< pointStatus > pointStatusNames_
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
void transfer(edgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
bool read(const fileName &name, const word &ext)
Read from file. Chooses reader based on explicit extension.
void clear()
Clear all entries from the registry.
virtual void getVolumeType(const pointField &, List< volumeType > &) const =0
Determine type (inside/outside) for point.
messageStream Info
Information stream (stdout output on master, null elsewhere)
void allNearestFeatureEdges(const point &sample, const scalar searchRadiusSqr, List< pointIndexHit > &info) const
Find all the feature edges within searchDistSqr of sample.
const indexedOctree< treeDataPoint > & pointTree() const
Demand driven construction of octree for feature points.
static wordHashSet writeTypes()
Summary of supported write file types.
Field< vector > vectorField
Specialisation of Field<T> for vector.
Omanip< int > setw(const int i)
List< label > labelList
A List of labels.
Neither concave or convex, on a flat surface.
Triangulated surface description with patch information.
void nearestFeatureEdge(const point &sample, scalar searchDistSqr, pointIndexHit &info) const
Find nearest surface edge for the sample point.
Multiply connected (connected to more than two faces)
Ostream & incrIndent(Ostream &os)
Increment the indent level.
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
void nearestFeatureEdgeByType(const point &sample, const scalarField &searchDistSqr, List< pointIndexHit > &info) const
Find the nearest point on each type of feature edge.
Unclassified (consistency with surfaceFeatures)
Holds feature edges/points of surface.
PointHit< point > pointHit
A PointHit with a 3D point.
label concaveStart() const
Return the index of the start of the concave feature points.
void allNearestFeaturePoints(const point &sample, scalar searchRadiusSqr, List< pointIndexHit > &info) const
Find all the feature points within searchDistSqr of sample.
static constexpr const zero Zero
Global zero (0)
pointStatus classifyFeaturePoint(label ptI) const
Classify the type of feature point. Requires valid stored member.