@@ -604,13 +604,17 @@ void CJGeoCreator::SplitInAndOuterHFaces(const TopoDS_Shape& inputFaces, std::ve
604604
605605TopoDS_Solid CJGeoCreator::extrudeFace (const TopoDS_Face& evalFace, bool downwards, double splittingFaceHeight)
606606{
607+ if (evalFace.IsNull ()) { return {}; }
608+ TopoDS_Face projectedFace = helperFunctions::projectFaceFlat (evalFace, splittingFaceHeight);
609+
610+ if (projectedFace.IsNull ()) { return {}; }
611+
607612 BRep_Builder brepBuilder;
608613 BRepBuilderAPI_Sewing brepSewer (SettingsCollection::getInstance ().precision ());
609614 TopoDS_Shell shell;
610615 brepBuilder.MakeShell (shell);
611616 TopoDS_Solid solidShape;
612617 brepBuilder.MakeSolid (solidShape);
613- TopoDS_Face projectedFace = helperFunctions::projectFaceFlat (evalFace, splittingFaceHeight);
614618
615619 std::vector<TopoDS_Wire> wireList;
616620 TopoDS_Wire outerWire = BRepTools::OuterWire (evalFace);
@@ -711,6 +715,9 @@ TopoDS_Solid CJGeoCreator::extrudeFace(const TopoDS_Face& evalFace, bool downwar
711715
712716 gp_Pnt p0 = helperFunctions::getFirstPointShape (evalFace);
713717 gp_Vec normal = helperFunctions::computeFaceNormal (evalFace);
718+
719+ if (normal.Magnitude () < 1e-6 ) { return {}; }
720+
714721 Handle (Geom_Plane) plane = new Geom_Plane (p0, normal);
715722
716723 Handle (Geom_Plane) planeFlat = new Geom_Plane (gp_Pnt (0 , 0 , splittingFaceHeight), gp_Vec (0 , 0 , -1 ));
@@ -959,11 +966,42 @@ std::vector<TopoDS_Face> CJGeoCreator::getSplitFaces(
959966 const std::vector<TopoDS_Face>& inputFaceList,
960967 bgi::rtree<std::pair<BoostBox3D, TopoDS_Face>, bgi::rstar<25 >> cuttingFaceIdx
961968)
969+ {
970+ // split the range over cores
971+ int coreUse = SettingsCollection::getInstance ().threadcount ();
972+ if (coreUse > inputFaceList.size ())
973+ {
974+ while (coreUse > inputFaceList.size ()) { coreUse /= 2 ; }
975+ }
976+
977+ int splitListSize = static_cast <int >(floor (inputFaceList.size () / coreUse));
978+
979+ std::vector<std::thread> threadList;
980+ std::mutex processMutex;
981+ std::vector<TopoDS_Face> outSplitFaceList;
982+
983+ for (size_t i = 0 ; i < coreUse; i++)
984+ {
985+ auto startIdx = inputFaceList.begin () + i * splitListSize;
986+ auto endIdx = (i == coreUse - 1 ) ? inputFaceList.end () : startIdx + splitListSize;
987+
988+ std::vector<TopoDS_Face> sublist (startIdx, endIdx);
989+ threadList.emplace_back ([this , &outSplitFaceList, &processMutex, sublist, &cuttingFaceIdx]() { getSplitFaces (outSplitFaceList, processMutex, sublist, cuttingFaceIdx); });
990+ }
991+
992+ for (auto & thread : threadList) {
993+ if (thread.joinable ()) {
994+ thread.join ();
995+ }
996+ }
997+ return outSplitFaceList;
998+ }
999+
1000+ void CJGeoCreator::getSplitFaces (std::vector<TopoDS_Face>& outFaceList, std::mutex& listMutex, const std::vector<TopoDS_Face>& inputFaceList, bgi::rtree<std::pair<BoostBox3D, TopoDS_Face>, bgi::rstar<25 >> cuttingFaceIdx)
9621001{
9631002 double precision = SettingsCollection::getInstance ().precisionCoarse ();
9641003
9651004 // split the topfaces with the cutting faces
966- std::vector<TopoDS_Face> splitFaceList;
9671005 for (const TopoDS_Face& currentRoofSurface : inputFaceList)
9681006 {
9691007 if (currentRoofSurface.IsNull ()) { continue ; }
@@ -973,7 +1011,9 @@ std::vector<TopoDS_Face> CJGeoCreator::getSplitFaces(
9731011
9741012 if (qResult.size () <= 1 )
9751013 {
976- splitFaceList.emplace_back (currentRoofSurface);
1014+ listMutex.lock ();
1015+ outFaceList.emplace_back (currentRoofSurface);
1016+ listMutex.unlock ();
9771017 continue ;
9781018 }
9791019
@@ -986,7 +1026,7 @@ std::vector<TopoDS_Face> CJGeoCreator::getSplitFaces(
9861026 {
9871027 TopoDS_Face currentSplitter = cuttingFace;
9881028 if (currentSplitter.IsEqual (currentRoofSurface)) { continue ; }
989-
1029+
9901030 divider.AddTool (currentSplitter);
9911031 }
9921032 divider.Perform ();
@@ -997,10 +1037,12 @@ std::vector<TopoDS_Face> CJGeoCreator::getSplitFaces(
9971037 TopExp::MapShapes (subFace, TopAbs_EDGE, aMap);
9981038
9991039 if (aMap.Size () <= 2 ) { continue ; }
1000- splitFaceList.emplace_back (subFace);
1040+ listMutex.lock ();
1041+ outFaceList.emplace_back (subFace);
1042+ listMutex.unlock ();
10011043 }
10021044 }
1003- return splitFaceList ;
1045+ return ;
10041046}
10051047
10061048std::vector<TopoDS_Face> CJGeoCreator::getVisTopSurfaces (const std::vector<TopoDS_Face>& faceList, double lowestZ, const std::vector<TopoDS_Face>& bufferSurfaceList)
@@ -1117,7 +1159,7 @@ std::vector<TopoDS_Shape> CJGeoCreator::computePrisms(const std::vector<TopoDS_F
11171159
11181160 // remove dub faces and split them
11191161 bgi::rtree<std::pair<BoostBox3D, TopoDS_Face>, bgi::rstar<25 >> cuttingFaceIdx = indexUniqueFaces (splittingfaceIdx);
1120- for (const auto & [currentBox, currentFace] : cuttingFaceIdx) { toBesSplitFaceList.emplace_back (currentFace); }
1162+ for (const auto & [currentBox, currentFace] : cuttingFaceIdx) { toBesSplitFaceList.emplace_back (currentFace);}
11211163
11221164 std::vector<TopoDS_Face> splitFaceList = getSplitFaces (toBesSplitFaceList, cuttingFaceIdx);
11231165
@@ -1615,33 +1657,6 @@ void CJGeoCreator::printTime(std::chrono::steady_clock::time_point startTime, st
16151657}
16161658
16171659
1618- bool CJGeoCreator::surfaceIsIncapsulated (const TopoDS_Face& innerSurface, const TopoDS_Shape& encapsulatedShape) // TODO: might be dup
1619- {
1620- double precision = SettingsCollection::getInstance ().precision ();
1621- for (TopExp_Explorer explorer (encapsulatedShape, TopAbs_FACE); explorer.More (); explorer.Next ())
1622- {
1623- const TopoDS_Face& outerSurface = TopoDS::Face (explorer.Current ());
1624- bool encapsulated = true ;
1625-
1626- for (TopExp_Explorer explorer2 (innerSurface, TopAbs_VERTEX); explorer2.More (); explorer2.Next ())
1627- {
1628- const TopoDS_Vertex& vertex = TopoDS::Vertex (explorer2.Current ());
1629-
1630- if (!helperFunctions::pointOnShape (outerSurface, BRep_Tool::Pnt (vertex)))
1631- {
1632- encapsulated = false ;
1633- break ;
1634- }
1635- }
1636- if (encapsulated)
1637- {
1638- return true ;
1639- }
1640- }
1641- return false ;
1642- }
1643-
1644-
16451660TopoDS_Face makeFace (const std::vector<gp_Pnt>& voxelPointList, const std::vector<int >& pointFaceIndx) {
16461661 gp_Pnt p0 (voxelPointList[pointFaceIndx[0 ]]);
16471662 gp_Pnt p1 (voxelPointList[pointFaceIndx[1 ]]);
0 commit comments