1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMAlgo_AlgoTools.cxx
24 // Author : Peter KURNEV
26 #include <GEOMAlgo_AlgoTools.hxx>
28 #include <Basics_OCCTVersion.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <gp_Dir2d.hxx>
34 #include <Bnd_Box.hxx>
36 #include <BRepAdaptor_Curve2d.hxx>
37 #include <BRepTopAdaptor_FClass2d.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <Geom2d_TrimmedCurve.hxx>
41 #include <Geom2d_Line.hxx>
42 #include <Geom2d_TrimmedCurve.hxx>
44 #include <Geom2dHatch_Intersector.hxx>
45 #include <Geom2dHatch_Hatcher.hxx>
47 #include <Geom2dAdaptor_Curve.hxx>
48 #include <HatchGen_Domain.hxx>
50 #include <GeomLib.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom_Surface.hxx>
54 #include <GeomAdaptor_Surface.hxx>
56 #include <GeomAPI_ProjectPointOnSurf.hxx>
57 #include <GeomAPI_ProjectPointOnCurve.hxx>
59 #include <GProp_GProps.hxx>
61 #include <Poly_Triangulation.hxx>
63 #include <TopAbs_Orientation.hxx>
65 #include <TopLoc_Location.hxx>
68 #include <TopoDS_Iterator.hxx>
69 #include <TopoDS_Face.hxx>
70 #include <TopoDS_Edge.hxx>
71 #include <TopoDS_Compound.hxx>
74 #include <TopExp_Explorer.hxx>
76 #include <BRep_Tool.hxx>
77 #include <BRep_Builder.hxx>
78 #include <BRepLib_MakeVertex.hxx>
80 #include <BRepTools.hxx>
81 #include <BRepTools_WireExplorer.hxx>
82 #include <BRepBndLib.hxx>
83 #include <BRepMesh_IncrementalMesh.hxx>
84 #include <BRepGProp.hxx>
86 #include <IntTools_Tools.hxx>
88 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
89 #include <TopTools_ListOfShape.hxx>
90 #include <TopTools_MapOfShape.hxx>
91 #include <TopTools_DataMapOfShapeReal.hxx>
92 #include <TColgp_SequenceOfPnt2d.hxx>
94 #include <TopTools_ListIteratorOfListOfShape.hxx>
95 #include <TopTools_IndexedMapOfShape.hxx>
96 #include <TopAbs_ShapeEnum.hxx>
98 #include <IntTools_Tools.hxx>
100 #include <BOPTools_AlgoTools3D.hxx>
101 #include <BOPTools_AlgoTools2D.hxx>
103 #include <ShapeUpgrade_ShapeDivideArea.hxx>
104 #include <ShapeUpgrade_UnifySameDomain.hxx>
106 #include <GEOMAlgo_PassKeyShape.hxx>
111 void GetCount(const TopoDS_Shape& aS,
112 Standard_Integer& iCnt);
114 void CopySource(const TopoDS_Shape& aS,
115 TopTools_IndexedDataMapOfShapeShape& aMapSS,
118 static Standard_Boolean comp(const std::pair<TopoDS_Shape, Standard_Real>& theA,
119 const std::pair<TopoDS_Shape, Standard_Real>& theB);
121 static Standard_Boolean IsUiso (const TopoDS_Edge& theEdge,
122 const TopoDS_Face& theFace);
124 static void CorrectShell (const TopoDS_Shape& theShell,
125 const TopoDS_Face& theFace);
127 static gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace,
128 const Standard_Boolean theIsNaturalRestrictions);
130 static void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace,
131 const Standard_Real theAverageArea,
132 const Standard_Boolean theIsToAddFaces,
133 Standard_Integer& theNbExtremalFaces,
134 TopTools_MapOfShape& theExtremalFaces,
135 const std::vector<std::pair<TopoDS_Shape, Standard_Real>> theFacesAndAreas,
136 const TopTools_DataMapOfShapeReal& theFaceAreaMap,
137 const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap,
138 TopoDS_Shape& theRes,
139 TopoDS_Shape& theGlobalRes,
140 TopTools_MapOfShape& theRemovedFaces);
142 //=======================================================================
143 //function : CopyShape
145 //=======================================================================
146 void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS,
149 TopTools_IndexedDataMapOfShapeShape aMapSS;
151 CopySource(aS, aMapSS, aSC);
153 //=======================================================================
154 //function : CopyShape
156 //=======================================================================
157 void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS,
159 TopTools_IndexedDataMapOfShapeShape& aMapSS)
161 CopySource(aS, aMapSS, aSC);
163 //=======================================================================
164 //function : CopySource
166 //=======================================================================
167 void CopySource(const TopoDS_Shape& aS,
168 TopTools_IndexedDataMapOfShapeShape& aMapSS,
171 Standard_Boolean bFree;
179 if (aMapSS.Contains(aS)) {
180 aSC=aMapSS.ChangeFromKey(aS);
181 aSC.Orientation(aS.Orientation());
185 aSC=aS.EmptyCopied();
190 aSC.Free(Standard_True);
192 if (aT==TopAbs_EDGE){
193 TopAbs_Orientation aOr;
195 aOr=aS.Orientation();
196 if(aOr==TopAbs_INTERNAL) {
197 aSF.Orientation(TopAbs_FORWARD);
201 for (; aIt.More(); aIt.Next()) {
204 const TopoDS_Shape& aSx=aIt.Value();
206 CopySource (aSx, aMapSS, aSCx);
208 aSCx.Orientation(aSx.Orientation());
213 //=======================================================================
214 //function : FaceNormal
216 //=======================================================================
217 void GEOMAlgo_AlgoTools::FaceNormal (const TopoDS_Face& aF,
218 const Standard_Real U,
219 const Standard_Real V,
224 Handle(Geom_Surface) aSurface;
226 aSurface=BRep_Tool::Surface(aF);
227 aSurface->D1 (U, V, aPnt, aD1U, aD1V);
228 aN=aD1U.Crossed(aD1V);
230 if (aF.Orientation() == TopAbs_REVERSED){
235 //=======================================================================
236 //function : BuildPCurveForEdgeOnFace
238 //=======================================================================
239 Standard_Integer GEOMAlgo_AlgoTools::BuildPCurveForEdgeOnFace
240 (const TopoDS_Edge& aEold,
241 const TopoDS_Edge& aEnew,
242 const TopoDS_Face& aF,
243 const Handle(IntTools_Context)& aCtx)
245 Standard_Boolean bIsClosed, bUClosed, bHasOld;
246 Standard_Integer iRet, aNbPoints;
247 Standard_Real aTS, aTS1, aTS2, aT, aT1, aT2, aScPr, aTol;
248 Standard_Real aU, aV, aUS1, aVS1, aUS2, aVS2;
250 gp_Pnt2d aP2DS1, aP2DS2, aP2D;
251 gp_Vec2d aV2DS1, aV2DS2;
252 Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2;
253 Handle(Geom_Surface) aS;
258 bHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface(aEnew, aF, aC2D, aT1, aT2, aTol);
263 // Try to copy PCurve from old edge to the new one.
264 iRet = BOPTools_AlgoTools2D::AttachExistingPCurve(aEold, aEnew, aF, aCtx);
267 // Do PCurve using projection algorithm.
270 // The PCurve is attached successfully.
274 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aEnew, aF);
275 aC2D=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
281 bIsClosed=BRep_Tool::IsClosed(aEold, aF);
288 // 1. bUClosed - direction of closeness
291 aES.Orientation(TopAbs_FORWARD);
292 aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
294 aES.Orientation(TopAbs_REVERSED);
295 aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
297 aTS=IntTools_Tools::IntermediatePoint(aTS1, aTS2);
299 aC2DS1->D1(aTS, aP2DS1, aV2DS1);
300 aC2DS2->D1(aTS, aP2DS2, aV2DS2);
302 gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
303 gp_Dir2d aD2DS12(aV2DS12);
304 const gp_Dir2d& aD2DX=gp::DX2d();
307 bUClosed=Standard_True;
308 if (fabs(aScPr) < aTol) {
312 // 2. aP2D - point on curve aC2D, that corresponds to aP2DS1
313 aP2DS1.Coord(aUS1, aVS1);
314 aP2DS2.Coord(aUS2, aVS2);
316 aS=BRep_Tool::Surface(aF);
317 aS->D0(aUS1, aVS1, aP);
319 GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
322 aNbPoints=aProjPC.NbPoints();
328 aT=aProjPC.LowerDistanceParameter();
331 // 3. Build the second 2D curve
332 Standard_Boolean bRevOrder;
333 gp_Vec2d aV2DT, aV2D;
334 Handle(Geom2d_Curve) aC2Dnew;
335 Handle(Geom2d_TrimmedCurve) aC2DTnew;
338 aC2D->D1(aT, aP2D, aV2D);
341 aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
342 aC2DTnew = new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
345 if (!bUClosed) { // V Closed
346 if (fabs(aV-aVS2)<aTol) {
351 if (fabs(aU-aUS2)<aTol) {
356 aC2DTnew->Translate(aV2DT);
358 // 4 Order the 2D curves
359 bRevOrder=Standard_False;
362 bRevOrder=!bRevOrder;
365 // 5. Update the edge
366 aTol=BRep_Tool::Tolerance(aEnew);
368 aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
371 aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
376 //////////////////////////////////////////////////////////////////////////
377 //=======================================================================
378 // function: MakeContainer
380 //=======================================================================
381 void GEOMAlgo_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
387 case TopAbs_COMPOUND:{
389 aBB.MakeCompound(aC);
394 case TopAbs_COMPSOLID:{
395 TopoDS_CompSolid aCS;
396 aBB.MakeCompSolid(aCS);
403 aBB.MakeSolid(aSolid);
411 aBB.MakeShell(aShell);
427 //=======================================================================
428 //function : IsUPeriodic
430 //=======================================================================
431 Standard_Boolean GEOMAlgo_AlgoTools::IsUPeriodic(const Handle(Geom_Surface) &aS)
433 Standard_Boolean bRet;
434 GeomAbs_SurfaceType aType;
435 GeomAdaptor_Surface aGAS;
438 aType=aGAS.GetType();
439 bRet=(aType==GeomAbs_Cylinder||
440 aType==GeomAbs_Cone ||
441 aType==GeomAbs_Sphere);
446 //=======================================================================
447 //function : RefinePCurveForEdgeOnFace
449 //=======================================================================
450 void GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE,
451 const TopoDS_Face& aF,
452 const Standard_Real aUMin,
453 const Standard_Real aUMax)
455 Standard_Real aT1, aT2, aTx, aUx, aTol;
457 Handle(Geom_Surface) aS;
458 Handle(Geom2d_Curve) aC2D;
461 aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
462 if (!aC2D.IsNull()) {
463 if (BRep_Tool::IsClosed(aE, aF)) {
466 aTx=IntTools_Tools::IntermediatePoint(aT1, aT2);
469 if (aUx < aUMin || aUx > aUMax) {
471 Handle(Geom2d_Curve) aC2Dx;
473 aTol=BRep_Tool::Tolerance(aE);
474 aBB.UpdateEdge(aE, aC2Dx, aF, aTol);
478 //=======================================================================
479 //function :IsSplitToReverse
481 //=======================================================================
482 Standard_Boolean GEOMAlgo_AlgoTools::IsSplitToReverse
483 (const TopoDS_Edge& aEF1,
484 const TopoDS_Edge& aEF2,
485 const Handle(IntTools_Context)& aContext)
487 Standard_Boolean aFlag;
488 Standard_Real aT1, aT2, aScPr, a, b;
493 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b);
494 aT1=IntTools_Tools::IntermediatePoint(a, b);
496 aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
499 return Standard_False;
504 aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2);
506 return Standard_False;
509 aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
511 return Standard_False;
522 //=======================================================================
523 //function : ProjectPointOnShape
525 //=======================================================================
526 Standard_Boolean GEOMAlgo_AlgoTools::ProjectPointOnShape
528 const TopoDS_Shape& aS,
530 const Handle(IntTools_Context)& aCtx)
532 Standard_Boolean bIsDone = Standard_False;
534 TopAbs_ShapeEnum aType;
536 aType = aS.ShapeType();
541 const TopoDS_Edge& aE2 = TopoDS::Edge(aS);
543 if (BRep_Tool::Degenerated(aE2)) { // jfa
544 return Standard_True;
548 Handle(Geom_Curve) aC3D = BRep_Tool::Curve (aE2, f, l);
550 return Standard_True;
552 bIsDone = aCtx->ProjectPointOnEdge(aP1, aE2, aT2);
558 GEOMAlgo_AlgoTools::PointOnEdge(aE2, aT2, aP2);
564 const TopoDS_Face& aF2 = TopoDS::Face(aS);
565 GeomAPI_ProjectPointOnSurf& aProj = aCtx->ProjPS(aF2);
568 bIsDone = aProj.IsDone();
573 aP2 = aProj.NearestPoint();
583 //=======================================================================
584 //function : PointOnEdge
586 //=======================================================================
587 void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
590 Standard_Real aTx, aT1, aT2;
592 BRep_Tool::Curve(aE, aT1, aT2);
593 aTx=IntTools_Tools::IntermediatePoint(aT1, aT2);
594 GEOMAlgo_AlgoTools::PointOnEdge(aE, aTx, aP3D);
596 //=======================================================================
597 //function : PointOnEdge
599 //=======================================================================
600 void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
601 const Standard_Real aT,
604 Standard_Real aT1, aT2;
605 Handle(Geom_Curve) aC3D;
607 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
610 //=======================================================================
611 //function : PointOnFace
613 //=======================================================================
614 void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF,
615 const Standard_Real aU,
616 const Standard_Real aV,
619 Handle(Geom_Surface) aS;
621 aS=BRep_Tool::Surface(aF);
622 aS->D0(aU, aV, aP3D);
624 //=======================================================================
625 //function : PointOnFace
627 //=======================================================================
628 void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF,
631 Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax;
633 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
635 aU=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
636 aV=IntTools_Tools::IntermediatePoint(aVMin, aVMax);
638 GEOMAlgo_AlgoTools::PointOnFace(aF, aU, aV, aP3D);
640 //=======================================================================
641 //function : PointOnShape
643 //=======================================================================
644 void GEOMAlgo_AlgoTools::PointOnShape(const TopoDS_Shape& aS,
647 TopAbs_ShapeEnum aType;
649 aP3D.SetCoord(99.,99.,99.);
650 aType=aS.ShapeType();
653 const TopoDS_Edge& aE=TopoDS::Edge(aS);
654 GEOMAlgo_AlgoTools::PointOnEdge(aE, aP3D);
659 const TopoDS_Face& aF=TopoDS::Face(aS);
660 GEOMAlgo_AlgoTools::PointOnFace(aF, aP3D);
668 //=======================================================================
669 //function : FindSDShapes
671 //=======================================================================
672 Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
673 (const TopoDS_Shape& aE1,
674 const TopTools_ListOfShape& aLE,
675 const Standard_Real aTol,
676 TopTools_ListOfShape& aLESD,
677 const Handle(IntTools_Context)& aCtx)
679 Standard_Boolean bIsDone;
680 Standard_Real aTol2, aD2;
682 TopTools_ListIteratorOfListOfShape aIt;
685 GEOMAlgo_AlgoTools::PointOnShape(aE1, aP1);
688 for (; aIt.More(); aIt.Next()) {
689 const TopoDS_Shape& aE2=aIt.Value();
690 if (aE2.IsSame(aE1)) {
694 bIsDone=GEOMAlgo_AlgoTools::ProjectPointOnShape(aP1, aE2, aP2, aCtx);
697 continue; // jfa BUG 20361
699 aD2=aP1.SquareDistance(aP2);
708 //=======================================================================
709 //function : FindSDShapes
711 //=======================================================================
712 Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
713 (const TopTools_ListOfShape& aLE,
714 const Standard_Real aTol,
715 TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
716 const Handle(IntTools_Context)& aCtx)
718 Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
719 TopTools_ListOfShape aLESD;
720 TopTools_ListIteratorOfListOfShape aIt, aIt1;
721 TopTools_IndexedMapOfShape aMProcessed;
722 TopAbs_ShapeEnum aType;
729 return 0; // Nothing to do
733 aNbEProcessed=aMProcessed.Extent();
734 if (aNbEProcessed==aNbE) {
739 for (; aIt.More(); aIt.Next()) {
740 const TopoDS_Shape& aS=aIt.Value();
742 if (aMProcessed.Contains(aS)) {
746 aType=aS.ShapeType();
747 if (aType==TopAbs_EDGE) {
748 const TopoDS_Edge& aE=TopoDS::Edge(aS);
749 if (BRep_Tool::Degenerated(aE)) {
756 iErr=GEOMAlgo_AlgoTools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
761 aNbESD=aLESD.Extent();
768 aIt1.Initialize(aLESD);
769 for (; aIt1.More(); aIt1.Next()) {
770 const TopoDS_Shape& aE1=aIt1.Value();
771 aMProcessed.Add(aE1);
777 //=======================================================================
778 //function : RefineSDShapes
780 //=======================================================================
781 Standard_Integer GEOMAlgo_AlgoTools::RefineSDShapes
782 (GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMPKLE,
783 const Standard_Real aTol,
784 const Handle(IntTools_Context)& aCtx)
786 Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
787 TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
791 aNbE=aMPKLE.Extent();
792 for (i=1; i<=aNbE; ++i) {
793 TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
796 iErr=GEOMAlgo_AlgoTools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
803 continue; // nothing to do
806 for (j=1; j<=aNbEE; ++j) {
807 TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
814 const TopoDS_Shape& aE1=aLEE.First();
815 aMEToAdd.Add(aE1, aLEE);
820 aNbToAdd=aMEToAdd.Extent();
825 for (i=1; i<=aNbToAdd; ++i) {
826 GEOMAlgo_PassKeyShape aPKE1;
828 const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
829 const TopTools_ListOfShape& aLE=aMEToAdd(i);
831 aPKE1.SetShapes(aE1);
832 aMPKLE.Add(aPKE1, aLE);
837 //=======================================================================
838 //function : BuildTriangulation
840 //=======================================================================
842 GEOMAlgo_AlgoTools::BuildTriangulation (const TopoDS_Shape& theShape)
844 // calculate deflection
845 Standard_Real aDeviationCoefficient = 0.001;
848 BRepBndLib::Add(theShape, B);
849 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
850 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
852 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
853 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
854 Standard_Real aHLRAngle = 0.349066;
856 // build triangulation
857 BRepMesh_IncrementalMesh Inc (theShape, aDeflection, Standard_False, aHLRAngle);
859 // check triangulation
860 bool isTriangulation = true;
862 TopExp_Explorer exp (theShape, TopAbs_FACE);
865 TopLoc_Location aTopLoc;
866 Handle(Poly_Triangulation) aTRF;
867 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
869 isTriangulation = false;
872 else // no faces, try edges
874 TopExp_Explorer expe (theShape, TopAbs_EDGE);
876 isTriangulation = false;
879 TopLoc_Location aLoc;
880 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
882 isTriangulation = false;
886 return isTriangulation;
889 //=======================================================================
890 //function : IsCompositeShape
892 //=======================================================================
893 Standard_Boolean GEOMAlgo_AlgoTools::IsCompositeShape(const TopoDS_Shape& aS)
895 Standard_Boolean bRet;
896 Standard_Integer iCnt;
905 //=======================================================================
906 //function : GetCount
908 //=======================================================================
909 void GetCount(const TopoDS_Shape& aS,
910 Standard_Integer& iCnt)
913 TopAbs_ShapeEnum aTS;
917 if (aTS==TopAbs_SHAPE) {
920 if (aTS!=TopAbs_COMPOUND) {
926 for (; aIt.More(); aIt.Next()) {
927 const TopoDS_Shape& aSx=aIt.Value();
932 //=======================================================================
933 //function : PntInFace
935 //=======================================================================
936 Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF,
940 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
941 Standard_Integer iErr, aIx, aNbDomains, i;
942 Standard_Real aUMin, aUMax, aVMin, aVMax;
943 Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
944 Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
945 gp_Dir2d aD2D (0., 1.);
948 Handle(Geom2d_Curve) aC2D;
949 Handle(Geom2d_TrimmedCurve) aCT2D;
950 Handle(Geom2d_Line) aL2D;
951 Handle(Geom_Surface) aS;
952 TopAbs_Orientation aOrE;
954 TopExp_Explorer aExp;
959 aTolTangfIntr=1.e-10;
961 Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
962 Geom2dHatch_Hatcher aHatcher(aIntr,
963 aTolHatch2D, aTolHatch3D,
964 Standard_True, Standard_False);
970 aFF.Orientation (TopAbs_FORWARD);
972 aS=BRep_Tool::Surface(aFF);
973 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
976 aExp.Init (aFF, TopAbs_EDGE);
977 for (; aExp.More() ; aExp.Next()) {
978 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
979 aOrE=aE.Orientation();
981 aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
982 if (aC2D.IsNull() ) {
986 if (fabs(aU1-aU2) < aEpsT) {
991 aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
992 aHatcher.AddElement(aCT2D, aOrE);
993 }// for (; aExp.More() ; aExp.Next()) {
996 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
997 aP2D.SetCoord(aUx, 0.);
998 aL2D=new Geom2d_Line (aP2D, aD2D);
999 Geom2dAdaptor_Curve aHCur(aL2D);
1001 aIx=aHatcher.AddHatching(aHCur) ;
1005 bIsDone=aHatcher.TrimDone(aIx);
1011 aHatcher.ComputeDomains(aIx);
1012 bIsDone=aHatcher.IsDone(aIx);
1020 aNbDomains=aHatcher.NbDomains(aIx);
1027 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
1028 bHasFirstPoint=aDomain.HasFirstPoint();
1029 if (!bHasFirstPoint) {
1034 aV1=aDomain.FirstPoint().Parameter();
1036 bHasSecondPoint=aDomain.HasSecondPoint();
1037 if (!bHasSecondPoint) {
1042 aV2=aDomain.SecondPoint().Parameter();
1044 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
1046 aS->D0(aUx, aVx, aPx);
1048 theP2D.SetCoord(aUx, aVx);
1054 //=======================================================================
1055 //function : PointCloudInFace
1057 //=======================================================================
1058 Standard_Integer GEOMAlgo_AlgoTools::PointCloudInFace(const TopoDS_Face& theFace,
1059 const int theNbPnts,
1060 TopoDS_Compound& theCompound)
1062 #if OCC_VERSION_LARGE < 0x07050304
1065 ShapeUpgrade_ShapeDivideArea tool (theFace);
1066 tool.SetSplittingByNumber (Standard_True);
1067 tool.NbParts() = theNbPnts;
1069 TopoDS_Shape res = tool.Result();
1072 TopoDS_Compound aGlobalRes;
1073 aBB.MakeCompound (aGlobalRes);
1075 TopTools_IndexedMapOfShape aFaceMap;
1076 TopExp::MapShapes (res, TopAbs_FACE, aFaceMap);
1077 Standard_Integer aNbFaces = aFaceMap.Extent();
1079 TopTools_IndexedDataMapOfShapeListOfShape aEFmap;
1080 TopExp::MapShapesAndAncestors (res, TopAbs_EDGE, TopAbs_FACE, aEFmap);
1082 TopTools_MapOfShape aBiggestFaces, aSmallestFaces;
1083 Standard_Boolean aUseTriangulation = Standard_True;
1084 Standard_Boolean aSkipShared = Standard_False;
1085 if (aNbFaces != theNbPnts)
1087 Standard_Real aTotalArea = 0.;
1088 std::vector<std::pair<TopoDS_Shape, Standard_Real> > aFacesAndAreas (aNbFaces);
1089 for (Standard_Integer ii = 1; ii <= aNbFaces; ii++)
1091 GProp_GProps aProps;
1092 BRepGProp::SurfaceProperties (aFaceMap(ii), aProps, aSkipShared, aUseTriangulation);
1093 Standard_Real anArea = aProps.Mass();
1094 aTotalArea += anArea;
1095 std::pair<TopoDS_Shape, Standard_Real> aFaceWithArea (aFaceMap(ii), anArea);
1096 aFacesAndAreas[ii-1] = aFaceWithArea;
1098 std::sort (aFacesAndAreas.begin(), aFacesAndAreas.end(), comp);
1100 Standard_Real anAverageArea = aTotalArea / theNbPnts;
1102 TopTools_DataMapOfShapeReal aFaceAreaMap;
1103 for (Standard_Integer ii = 0; ii < aNbFaces; ii++)
1104 aFaceAreaMap.Bind (aFacesAndAreas[ii].first, aFacesAndAreas[ii].second);
1106 TopTools_MapOfShape aRemovedFaces;
1108 if (aNbFaces < theNbPnts)
1110 Standard_Integer aNbMissingFaces = theNbPnts - aNbFaces;
1111 for (Standard_Integer ii = aNbFaces-1; ii > aNbFaces - aNbMissingFaces - 1; ii--)
1112 aBiggestFaces.Add (aFacesAndAreas[ii].first);
1114 ModifyFacesForGlobalResult (theFace, anAverageArea,
1115 Standard_True, //to add faces
1116 aNbMissingFaces, aBiggestFaces,
1117 aFacesAndAreas, aFaceAreaMap, aEFmap,
1121 else //aNbFaces > theNbPnts
1123 Standard_Integer aNbExcessFaces = aNbFaces - theNbPnts;
1124 for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++)
1125 aSmallestFaces.Add (aFacesAndAreas[ii].first);
1127 TopTools_IndexedDataMapOfShapeListOfShape aVFmap;
1128 TopExp::MapShapesAndAncestors (res, TopAbs_VERTEX, TopAbs_FACE, aVFmap);
1130 //Remove smallest faces with free boundaries
1131 for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++)
1133 const TopoDS_Face& aFace = TopoDS::Face (aFacesAndAreas[ii].first);
1134 Standard_Boolean anIsFreeBoundFound = Standard_False;
1135 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1136 for (; anExplo.More(); anExplo.Next())
1138 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1139 if (!BRep_Tool::Degenerated (anEdge) &&
1140 aEFmap.FindFromKey(anEdge).Extent() < 2)
1142 anIsFreeBoundFound = Standard_True;
1146 if (anIsFreeBoundFound)
1148 Standard_Real aMaxArea = 0.;
1149 for (anExplo.Init(aFace, TopAbs_VERTEX); anExplo.More(); anExplo.Next())
1151 const TopoDS_Shape& aVertex = anExplo.Current();
1152 const TopTools_ListOfShape& aFaceList = aVFmap.FindFromKey (aVertex);
1153 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1154 for (; anItl.More(); anItl.Next())
1156 Standard_Real anArea = aFaceAreaMap (anItl.Value());
1157 if (anArea > aMaxArea)
1161 Standard_Real anArreaOfSmallestFace = aFaceAreaMap (aFace);
1162 if (anArreaOfSmallestFace < aMaxArea / 16)
1164 aBB.Remove (res, aFace);
1165 aRemovedFaces.Add (aFace);
1170 ModifyFacesForGlobalResult (theFace, anAverageArea,
1171 Standard_False, //to decrease number of faces
1172 aNbExcessFaces, aSmallestFaces,
1173 aFacesAndAreas, aFaceAreaMap, aEFmap,
1179 aBB.Add (aGlobalRes, res);
1181 aBB.MakeCompound (theCompound);
1182 for (TopExp_Explorer aGlobalExplo(aGlobalRes, TopAbs_FACE); aGlobalExplo.More(); aGlobalExplo.Next())
1184 const TopoDS_Face& aFace = TopoDS::Face (aGlobalExplo.Current());
1185 Standard_Boolean anIsNaturalRestrictions = Standard_True;
1186 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1187 for (; anExplo.More(); anExplo.Next())
1189 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1190 if (BRep_Tool::Degenerated (anEdge))
1192 if (!aEFmap.Contains(anEdge) ||
1193 aEFmap.FindFromKey(anEdge).Extent() < 2)
1195 anIsNaturalRestrictions = Standard_False;
1200 gp_Pnt aPnt = GetMidPnt2d (aFace, anIsNaturalRestrictions);
1201 TopoDS_Vertex aVertex = BRepLib_MakeVertex (aPnt);
1202 aBB.Add (theCompound, aVertex);
1209 Standard_Boolean comp(const std::pair<TopoDS_Shape, Standard_Real>& theA,
1210 const std::pair<TopoDS_Shape, Standard_Real>& theB)
1212 return (theA.second < theB.second);
1215 Standard_Boolean IsUiso (const TopoDS_Edge& theEdge,
1216 const TopoDS_Face& theFace)
1218 BRepAdaptor_Curve2d aBAcurve2d (theEdge, theFace);
1221 aBAcurve2d.D1 (aBAcurve2d.FirstParameter(), aP2d, aVec);
1222 return (Abs(aVec.Y()) > Abs(aVec.X()));
1225 void CorrectShell (const TopoDS_Shape& theShell,
1226 const TopoDS_Face& theFace)
1228 BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
1229 GeomAbs_SurfaceType aType = aBAsurf.GetType();
1230 if (aType <= GeomAbs_Torus) //elementary surfaces
1233 TopLoc_Location anInputLoc;
1234 const Handle(Geom_Surface)& anInputSurf = BRep_Tool::Surface (theFace, anInputLoc);
1238 TopoDS_Iterator anIter (theShell);
1239 for (; anIter.More(); anIter.Next())
1241 const TopoDS_Face& aFace = TopoDS::Face (anIter.Value());
1242 TopLoc_Location aLoc;
1243 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLoc);
1244 if (aSurf == anInputSurf)
1247 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1248 for (; anExplo.More(); anExplo.Next())
1250 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1251 Standard_Real aFirst, aLast;
1252 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast);
1253 aBB.UpdateEdge (anEdge, aPCurve, anInputSurf, anInputLoc, 0.);
1255 Standard_Real aTol = BRep_Tool::Tolerance (aFace);
1256 aBB.UpdateFace (aFace, anInputSurf, anInputLoc, aTol);
1260 gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace,
1261 const Standard_Boolean theIsNaturalRestrictions)
1265 if (theIsNaturalRestrictions)
1267 BRepAdaptor_Surface aBAsurf (theFace);
1268 Standard_Real aUmin, aUmax, aVmin, aVmax;
1269 aUmin = aBAsurf.FirstUParameter();
1270 aUmax = aBAsurf.LastUParameter();
1271 aVmin = aBAsurf.FirstVParameter();
1272 aVmax = aBAsurf.LastVParameter();
1273 aResPnt = aBAsurf.Value ((aUmin + aUmax)/2, (aVmin + aVmax)/2);
1277 const Standard_Integer aNbSamples = 4;
1278 TopoDS_Wire aWire = BRepTools::OuterWire (theFace);
1279 TopTools_IndexedMapOfShape aEmap;
1280 TopExp::MapShapes (aWire, TopAbs_EDGE, aEmap);
1281 Standard_Integer aNbPointsOnContour = aNbSamples * aEmap.Extent();
1282 TColgp_Array1OfPnt anArray (1, aNbPointsOnContour);
1284 BRepTools_WireExplorer aWexp (aWire, theFace);
1285 Standard_Integer anInd = 0;
1286 for (; aWexp.More(); aWexp.Next())
1288 const TopoDS_Edge& anEdge = aWexp.Current();
1289 BRepAdaptor_Curve2d aBAcurve2d (anEdge, theFace);
1290 Standard_Real aDelta = (aBAcurve2d.LastParameter() - aBAcurve2d.FirstParameter())/aNbSamples;
1291 for (Standard_Integer ii = 0; ii < aNbSamples; ii++)
1293 Standard_Real aParam = aBAcurve2d.FirstParameter() + ii * aDelta;
1294 gp_Pnt2d aP2d = aBAcurve2d.Value (aParam);
1295 gp_Pnt aPnt (aP2d.X(), aP2d.Y(), 0.);
1296 anArray (++anInd) = aPnt;
1301 Standard_Boolean anIsSingular;
1302 GeomLib::AxeOfInertia (anArray, anAxis, anIsSingular);
1303 gp_Pnt aBaryCentre = anAxis.Location();
1304 gp_Pnt2d aCentre2d (aBaryCentre.X(), aBaryCentre.Y());
1305 BRepTopAdaptor_FClass2d aClassifier (theFace, Precision::Confusion());
1306 BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
1308 TopAbs_State aStatus = aClassifier.Perform (aCentre2d);
1309 gp_Pnt2d aP2d = aCentre2d;
1310 Standard_Integer anIndVertex = 0;
1311 const Standard_Integer aNbIter = 10;
1312 while (aStatus != TopAbs_IN && anIndVertex < aNbPointsOnContour)
1314 gp_Pnt aVertexPnt = anArray (anIndVertex+1);
1315 gp_Pnt2d aVertexP2d (aVertexPnt.X(), aVertexPnt.Y());
1316 TColgp_SequenceOfPnt2d aPseq;
1317 aPseq.Append (aCentre2d);
1318 aPseq.Append (aVertexP2d);
1319 for (Standard_Integer ii = 1; ii <= aNbIter; ii++)
1321 for (Standard_Integer jj = 1; jj < aPseq.Length(); jj++)
1323 aP2d.SetXY ((aPseq(jj).XY() + aPseq(jj+1).XY())/2);
1324 aStatus = aClassifier.Perform (aP2d);
1325 if (aStatus == TopAbs_IN)
1329 aPseq.InsertAfter (jj, aP2d);
1333 if (aStatus == TopAbs_IN)
1336 anIndVertex += aNbSamples;
1338 aResPnt = aBAsurf.Value (aP2d.X(), aP2d.Y());
1339 } //case of complex boundaries
1344 void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace,
1345 const Standard_Real theAverageArea,
1346 const Standard_Boolean theIsToAddFaces,
1347 Standard_Integer& theNbExtremalFaces,
1348 TopTools_MapOfShape& theExtremalFaces,
1349 const std::vector<std::pair<TopoDS_Shape, Standard_Real>> theFacesAndAreas,
1350 const TopTools_DataMapOfShapeReal& theFaceAreaMap,
1351 const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap,
1352 TopoDS_Shape& theRes,
1353 TopoDS_Shape& theGlobalRes,
1354 TopTools_MapOfShape& theRemovedFaces)
1357 const Standard_Integer aNbFaces = (Standard_Integer) theFacesAndAreas.size();
1359 const Standard_Integer aDiff = theNbExtremalFaces - theRemovedFaces.Extent();
1361 Standard_Integer aSum = 0;
1362 while (aSum < aDiff) //global loop
1364 Standard_Integer aNbFacesDone = 0, aNbFacesInTape = 0;
1365 TopoDS_Face aStartFace;
1367 Standard_Integer aStartIndex = (theIsToAddFaces)? aNbFaces-1 : 0;
1368 Standard_Integer anEndIndex = (theIsToAddFaces)? 0 : aNbFaces-1;
1369 Standard_Integer aStep = (theIsToAddFaces)? -1 : 1;
1371 for (Standard_Integer ii = aStartIndex; ii != anEndIndex; ii += aStep)
1373 const TopoDS_Face& aFace = TopoDS::Face (theFacesAndAreas[ii].first);
1374 if (!theRemovedFaces.Contains(aFace))
1380 if (aStartFace.IsNull())
1383 theRemovedFaces.Add (aStartFace);
1385 TopoDS_Edge aCommonEdge;
1386 TopoDS_Face aNextFace;
1387 Standard_Real anExtremalArea = (theIsToAddFaces)? 0. : Precision::Infinite();
1388 for (TopExp_Explorer anExplo(aStartFace, TopAbs_EDGE); anExplo.More(); anExplo.Next())
1390 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1391 const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge);
1392 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1393 for (; anItl.More(); anItl.Next())
1395 const TopoDS_Face& aFace = TopoDS::Face (anItl.Value());
1396 if (aFace.IsSame (aStartFace) ||
1397 theRemovedFaces.Contains(aFace))
1399 Standard_Real anArea = theFaceAreaMap(aFace);
1400 Standard_Boolean anIsToExchange = (theIsToAddFaces)? (anArea > anExtremalArea) : (anArea < anExtremalArea);
1403 anExtremalArea = anArea;
1404 aCommonEdge = anEdge;
1409 if (aCommonEdge.IsNull()) //all adjacent faces are already removed
1411 theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first);
1412 theNbExtremalFaces++;
1416 //Start filling the shell
1417 aBB.Remove (theRes, aStartFace);
1419 TopoDS_Shell aShell;
1420 aBB.MakeShell (aShell);
1421 Standard_Real anAreaOfTape = 0.;
1422 aBB.Add (aShell, aStartFace);
1424 anAreaOfTape += theFaceAreaMap (aStartFace);
1426 Standard_Boolean anIsUiso = IsUiso (aCommonEdge, aStartFace);
1427 //Find another faces on this level
1428 TopoDS_Face aCurrentFace = aNextFace;
1429 TopoDS_Edge aCurrentEdge = aCommonEdge;
1430 Standard_Boolean anIsFirstDirection = Standard_True;
1431 aBB.Remove (theRes, aCurrentFace);
1432 theRemovedFaces.Add (aCurrentFace);
1433 if (theExtremalFaces.Contains (aCurrentFace))
1437 aBB.Add (aShell, aCurrentFace);
1439 anAreaOfTape += theFaceAreaMap (aCurrentFace);
1440 Standard_Boolean anIsRound = Standard_False;
1441 for (;;) //local loop
1443 TopoDS_Edge aNextEdge;
1444 for (TopExp_Explorer anExplo(aCurrentFace, TopAbs_EDGE); anExplo.More(); anExplo.Next())
1446 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1447 if (anEdge.IsSame (aCurrentEdge))
1449 const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge);
1450 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1451 for (; anItl.More(); anItl.Next())
1453 const TopoDS_Face& aFace = TopoDS::Face (anItl.Value());
1454 if (aFace.IsSame (aCurrentFace))
1456 if (aFace.IsSame (aStartFace))
1458 anIsRound = Standard_True;
1461 if (theRemovedFaces.Contains(aFace))
1463 if (anIsUiso == IsUiso (anEdge, aFace))
1470 if (anIsRound || !aNextEdge.IsNull())
1473 if (anIsRound) //round tape: returned to start face
1475 if (aNextEdge.IsNull())
1477 if (anIsFirstDirection)
1479 aCurrentFace = aStartFace;
1480 aCurrentEdge = aCommonEdge;
1481 anIsFirstDirection = Standard_False;
1488 aBB.Add (aShell, aNextFace);
1490 anAreaOfTape += theFaceAreaMap (aNextFace);
1491 aBB.Remove (theRes, aNextFace);
1492 theRemovedFaces.Add (aNextFace);
1493 if (theExtremalFaces.Contains (aNextFace))
1497 aCurrentEdge = aNextEdge;
1498 aNextEdge.Nullify();
1499 aCurrentFace = aNextFace;
1500 } //end of local loop
1503 Standard_Integer aNumberToSplit = (theIsToAddFaces)? aNbFacesInTape + aNbFacesDone : aNbFacesInTape - aNbFacesDone;
1504 if (!theIsToAddFaces && aNbFacesDone > 1)
1506 Standard_Integer aRealNumberToSplit = (aNumberToSplit > 0)? aNumberToSplit : 1;
1507 Standard_Real anAverageAreaInTape = anAreaOfTape / aRealNumberToSplit;
1508 if (anAverageAreaInTape > theAverageArea)
1510 Standard_Integer aNewNumberToSplit = RealToInt(round(anAreaOfTape / theAverageArea));
1511 if (aNewNumberToSplit < aNbFacesInTape)
1513 Standard_Integer aNumberToIncrease = aNewNumberToSplit - aNumberToSplit;
1514 for (Standard_Integer jj = theNbExtremalFaces; jj < theNbExtremalFaces + aNumberToIncrease; jj++)
1515 theExtremalFaces.Add (theFacesAndAreas[jj].first);
1516 theNbExtremalFaces += aNumberToIncrease;
1517 aNumberToSplit = aNewNumberToSplit;
1521 if (anIsRound && aNumberToSplit <= 1)
1523 Standard_Integer aNumberToIncrease = 3 - aNumberToSplit;
1524 for (Standard_Integer jj = theNbExtremalFaces; jj < theNbExtremalFaces + aNumberToIncrease; jj++)
1525 theExtremalFaces.Add (theFacesAndAreas[jj].first);
1526 theNbExtremalFaces += aNumberToIncrease;
1529 CorrectShell (aShell, theInputFace);
1530 ShapeUpgrade_UnifySameDomain aUnifier;
1531 aUnifier.Initialize (aShell, Standard_True, Standard_True);
1533 TopoDS_Shape aUnifiedShape = aUnifier.Shape();
1535 TopoDS_Shape aLocalResult = aUnifiedShape;
1536 Standard_Integer aNbFacesInLocalResult;
1537 if (aNumberToSplit > 1)
1539 #if OCC_VERSION_LARGE < 0x07050304
1540 aNbFacesInLocalResult = 0;
1542 ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape);
1543 aLocalTool.SetSplittingByNumber (Standard_True);
1544 aLocalTool.MaxArea() = -1;
1546 aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1);
1548 aLocalTool.SetNumbersUVSplits (1, aNumberToSplit);
1549 aLocalTool.Perform();
1550 aLocalResult = aLocalTool.Result();
1551 aNbFacesInLocalResult = aNumberToSplit;
1556 aNbFacesInLocalResult = 1;
1557 if (aNumberToSplit == 0)
1559 theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first);
1560 theNbExtremalFaces++;
1563 aBB.Add (theGlobalRes, aLocalResult);
1565 aSum += Abs(aNbFacesInTape - aNbFacesInLocalResult);
1566 } //end of global loop
1568 //Second global loop
1569 TopoDS_Compound aSecondComp;
1570 aBB.MakeCompound (aSecondComp);
1571 while (aSum < aDiff)
1573 TopoDS_Shape aMaxShell;
1574 Standard_Integer aMaxNbFaces = 0;
1575 TopoDS_Iterator anIter (theGlobalRes);
1576 for (; anIter.More(); anIter.Next())
1578 const TopoDS_Shape& aShell = anIter.Value();
1579 TopTools_IndexedMapOfShape aFaceMap;
1580 TopExp::MapShapes (aShell, TopAbs_FACE, aFaceMap);
1581 if (aFaceMap.Extent() > aMaxNbFaces)
1583 aMaxNbFaces = aFaceMap.Extent();
1588 if (aMaxNbFaces == 1)
1591 aBB.Remove (theGlobalRes, aMaxShell);
1593 Standard_Boolean anIsUiso = Standard_True;
1594 TopTools_IndexedDataMapOfShapeListOfShape aLocalEFmap;
1595 TopExp::MapShapesAndAncestors (aMaxShell, TopAbs_EDGE, TopAbs_FACE, aLocalEFmap);
1596 for (Standard_Integer jj = 1; jj <= aLocalEFmap.Extent(); jj++)
1598 const TopoDS_Edge& anEdge = TopoDS::Edge (aLocalEFmap.FindKey(jj));
1599 const TopTools_ListOfShape& aFaceList = aLocalEFmap(jj);
1600 if (aFaceList.Extent() == 2)
1602 const TopoDS_Face& aFace = TopoDS::Face (aFaceList.First());
1603 anIsUiso = IsUiso (anEdge, aFace);
1607 CorrectShell (aMaxShell, theInputFace);
1608 ShapeUpgrade_UnifySameDomain aUnifier;
1609 aUnifier.Initialize (aMaxShell, Standard_True, Standard_True);
1611 TopoDS_Shape aUnifiedShape = aUnifier.Shape();
1612 TopoDS_Shape aLocalResult = aUnifiedShape;
1614 Standard_Integer aNumberToSplit = (theIsToAddFaces)? aMaxNbFaces + (aDiff-aSum) : aMaxNbFaces - (aDiff-aSum);
1615 if (aNumberToSplit > 1)
1617 #if OCC_VERSION_LARGE < 0x07050304
1620 ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape);
1621 aLocalTool.SetSplittingByNumber (Standard_True);
1622 aLocalTool.MaxArea() = -1;
1624 aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1);
1626 aLocalTool.SetNumbersUVSplits (1, aNumberToSplit);
1627 aLocalTool.Perform();
1628 aLocalResult = aLocalTool.Result();
1634 aBB.Add (aSecondComp, aLocalResult);
1636 if (theIsToAddFaces)
1638 aSum += aMaxNbFaces - aNumberToSplit;
1640 aBB.Add (theGlobalRes, aSecondComp);