diff --git a/iModelCore/GeomLibs/geom/src/polyface/PolyfaceSectionMTG.h b/iModelCore/GeomLibs/geom/src/polyface/PolyfaceSectionMTG.h index 59a928cb64..96b59fd4b4 100644 --- a/iModelCore/GeomLibs/geom/src/polyface/PolyfaceSectionMTG.h +++ b/iModelCore/GeomLibs/geom/src/polyface/PolyfaceSectionMTG.h @@ -735,7 +735,7 @@ bool CollectAndVisitSuperFace(bvector& superFace, MTGNodeId seed, MTG // Mark exterior super-faces in the graph if they are unambiguous. // @param avoidMask [in] super-faces follow fSucc pointers where the next edge at a vertex is the first vPred without this mask -// @param mask [in] what exterior faces are marked with (e.g., visitMask) +// @param mask [in] what exterior faces will be marked with // @param planeNormal [in] the plane in which signed xy-areas are computed. In this plane, exterior and interior // faces have xy-areas with opposite sign. // @param graphIsReversed [out] on a true return, whether the graph's interior face loops are CW with respect to planeNormal @@ -783,6 +783,9 @@ bool MarkExteriorSuperFaces(MTGMask avoidMask, MTGMask mask, DVec3dCR planeNorma MTGARRAY_END_SET_LOOP(nodeId, &m_graph) m_graph.DropMask(myVisitMask); + if (superFaceAreas.empty()) + return false; + double areaTol = this->m_coordinateMap->GetXYZAbsTol(); double smallestArea = areaTol * areaTol; areaTol = smallestArea + this->m_coordinateMap->GetXYZRelTol() * maxAbsArea; diff --git a/iModelCore/GeomLibs/geom/test/PolyfaceTest/t_section.cpp b/iModelCore/GeomLibs/geom/test/PolyfaceTest/t_section.cpp index 2dea8949c6..4923b48c12 100644 --- a/iModelCore/GeomLibs/geom/test/PolyfaceTest/t_section.cpp +++ b/iModelCore/GeomLibs/geom/test/PolyfaceTest/t_section.cpp @@ -260,6 +260,35 @@ TEST(Polyface, PlaneSlice) Check::ClearGeometry("Polyface.PlaneSlice"); } +TEST(Polyface, PlaneSlice2) + { + BeFileName fullPathName; + BeTest::GetHost().GetDocumentsRoot(fullPathName); + fullPathName.AppendToPath(L"GeomLibsTestData").AppendToPath(L"Polyface").AppendToPath(L"Clipping").AppendToPath(L"mesh-small-open.imjs"); + + DPlane3d plane = DPlane3d::FromOriginAndNormal(0.0, 0.0, -54.674777215387010, 0.0, 0.0, -1.0); + Check::SaveTransformed(plane); + + bvector geometry; + if (Check::True(GTestFileOps::JsonFileToGeometry(fullPathName, geometry), "Parse inputs")) + { + auto mesh = geometry.front()->GetAsPolyfaceHeader(); + if (Check::True(mesh.IsValid(), "Have mesh") && Check::True(mesh->HasFacets(), "Nonempty mesh")) + { + Check::SaveTransformed(mesh); + auto slice = mesh->PlaneSlice(plane, true); // as called by ClipPlaneSet::ClipPlaneSetSectionPolyface in GeometryClipper::ProductCutGeometry + if (Check::True(slice.IsValid(), "Slice is valid")) + { + Check::SaveTransformed(slice); + Check::False(slice->IsAnyRegionType(), "Slice is not a region"); + Check::True(slice->GetBoundaryType() == CurveVector::BOUNDARY_TYPE_None, "Boundary type is None"); + Check::Size(slice->size(), 4, "Four linestrings in the section"); + } + } + } + Check::ClearGeometry("Polyface.PlaneSlice2"); + } + enum class DrapeAction { ClassicDrape, diff --git a/iModelCore/GeomLibs/geom/test/data/Polyface/Clipping/mesh-small-open.imjs b/iModelCore/GeomLibs/geom/test/data/Polyface/Clipping/mesh-small-open.imjs new file mode 100644 index 0000000000..077278c3b8 --- /dev/null +++ b/iModelCore/GeomLibs/geom/test/data/Polyface/Clipping/mesh-small-open.imjs @@ -0,0 +1,2 @@ +[{"indexedMesh":{"point":[[109.42066502284089,-101.36946137316438,-53.493208198506501],[109.43336502284096,-101.36946137316438,-53.493208198506501],[109.43336502284090,-101.36946137316438,-55.550608198506502],[109.42066502284089,-101.36946137316438,-55.550608198506502],[109.43336502284090,-101.31866137316449,-55.550608198506502],[109.42066502284089,-101.31866137316449,-55.550608198506502],[109.43336502284096,-105.86526137316449,-52.502608198506501],[109.43336502284096,-105.86526137316449,-55.550608198506502],[109.42066502284096,-105.86526137316449,-55.550608198506502],[109.42066502284096,-105.86526137316449,-52.502608198506501],[-109.43336502284096,-105.78906137316449,-55.550608198506502],[-109.42066502284089,-105.78906137316449,-55.550608198506502],[-109.43336502284092,-102.28386137316450,-53.493208198506501],[-109.42066502284091,-102.28386137316450,-53.493208198506501],[-109.42066502284089,-102.28386137316450,-55.550608198506502],[-109.43336502284092,-102.28386137316450,-55.550608198506502],[-109.42066502284089,-102.36006137316450,-55.550608198506502],[-109.43336502284092,-102.36006137316450,-55.550608198506502],[-109.42066502284091,-102.36006137316450,-52.807408198506501],[-109.43336502284092,-102.36006137316450,-52.807408198506501],[-109.42066502284095,-104.79846137316450,-52.807408198506501],[-109.43336502284095,-104.79846137316450,-52.807408198506501],[-109.42066502284095,-104.79846137316450,-55.550608198506502],[-109.43336502284095,-104.79846137316450,-55.550608198506502],[-109.43336502284096,-105.78906137316449,-53.493208198506501],[-109.42066502284096,-105.78906137316449,-53.493208198506501],[-109.43336502284090,-101.31866137316449,-52.502608198506501],[-109.43336502284095,-104.87466137316450,-55.550608198506502],[-109.43336502284095,-104.87466137316450,-53.493208198506501],[-109.42066502284095,-104.87466137316450,-53.493208198506501],[-109.42066502284095,-104.87466137316450,-55.550608198506502]],"pointIndex":[1,2,-3,0,3,4,-1,0,3,5,-6,0,6,4,-3,0,7,8,-9,0,9,10,-7,0,11,12,-9,0,9,8,-11,0,13,2,-1,0,1,14,-13,0,14,15,-16,0,16,13,-14,0,15,17,-18,0,18,16,-15,0,18,17,-19,0,19,20,-18,0,20,19,-21,0,21,22,-20,0,23,24,-22,0,22,21,-23,0,25,26,-12,0,12,11,-25,0,-27,2,-13,0,-2,27,-5,0,5,3,-2,0,13,16,-18,0,18,-20,-13,0,-13,-20,-27,0,-27,20,-22,0,-22,7,-27,0,24,28,-29,0,25,11,-8,0,8,-7,-25,0,29,-25,-7,0,-7,-22,-29,0,-29,22,-24,0,29,30,-26,0,26,25,-29,0,28,31,-30,0,30,29,-28,0,24,23,-31,0,31,28,-24,0]}}] + \ No newline at end of file