1 // Copyright (C) 2007-2023 CEA, EDF, 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);
1182 aBB.MakeCompound (theCompound);
1183 for (TopExp_Explorer aGlobalExplo (aGlobalRes, TopAbs_FACE);
1184 aGlobalExplo.More(), iface <= theNbPnts;
1185 aGlobalExplo.Next(), iface++)
1187 const TopoDS_Face& aFace = TopoDS::Face (aGlobalExplo.Current());
1188 Standard_Boolean anIsNaturalRestrictions = Standard_True;
1189 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1190 for (; anExplo.More(); anExplo.Next())
1192 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1193 if (BRep_Tool::Degenerated (anEdge))
1195 if (!aEFmap.Contains(anEdge) ||
1196 aEFmap.FindFromKey(anEdge).Extent() < 2)
1198 anIsNaturalRestrictions = Standard_False;
1203 gp_Pnt aPnt = GetMidPnt2d (aFace, anIsNaturalRestrictions);
1204 TopoDS_Vertex aVertex = BRepLib_MakeVertex (aPnt);
1205 aBB.Add (theCompound, aVertex);
1212 Standard_Boolean comp(const std::pair<TopoDS_Shape, Standard_Real>& theA,
1213 const std::pair<TopoDS_Shape, Standard_Real>& theB)
1215 return (theA.second < theB.second);
1218 Standard_Boolean IsUiso (const TopoDS_Edge& theEdge,
1219 const TopoDS_Face& theFace)
1221 BRepAdaptor_Curve2d aBAcurve2d (theEdge, theFace);
1224 aBAcurve2d.D1 (aBAcurve2d.FirstParameter(), aP2d, aVec);
1225 return (Abs(aVec.Y()) > Abs(aVec.X()));
1228 void CorrectShell (const TopoDS_Shape& theShell,
1229 const TopoDS_Face& theFace)
1231 BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
1232 GeomAbs_SurfaceType aType = aBAsurf.GetType();
1233 if (aType <= GeomAbs_Torus) //elementary surfaces
1236 TopLoc_Location anInputLoc;
1237 const Handle(Geom_Surface)& anInputSurf = BRep_Tool::Surface (theFace, anInputLoc);
1241 TopoDS_Iterator anIter (theShell);
1242 for (; anIter.More(); anIter.Next())
1244 const TopoDS_Face& aFace = TopoDS::Face (anIter.Value());
1245 TopLoc_Location aLoc;
1246 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLoc);
1247 if (aSurf == anInputSurf)
1250 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1251 for (; anExplo.More(); anExplo.Next())
1253 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1254 Standard_Real aFirst, aLast;
1255 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast);
1256 aBB.UpdateEdge (anEdge, aPCurve, anInputSurf, anInputLoc, 0.);
1258 Standard_Real aTol = BRep_Tool::Tolerance (aFace);
1259 aBB.UpdateFace (aFace, anInputSurf, anInputLoc, aTol);
1263 gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace,
1264 const Standard_Boolean theIsNaturalRestrictions)
1268 if (theIsNaturalRestrictions)
1270 BRepAdaptor_Surface aBAsurf (theFace);
1271 Standard_Real aUmin, aUmax, aVmin, aVmax;
1272 aUmin = aBAsurf.FirstUParameter();
1273 aUmax = aBAsurf.LastUParameter();
1274 aVmin = aBAsurf.FirstVParameter();
1275 aVmax = aBAsurf.LastVParameter();
1276 aResPnt = aBAsurf.Value ((aUmin + aUmax)/2, (aVmin + aVmax)/2);
1280 const Standard_Integer aNbSamples = 4;
1281 TopoDS_Wire aWire = BRepTools::OuterWire (theFace);
1282 TopTools_IndexedMapOfShape aEmap;
1283 TopExp::MapShapes (aWire, TopAbs_EDGE, aEmap);
1284 Standard_Integer aNbPointsOnContour = aNbSamples * aEmap.Extent();
1285 TColgp_Array1OfPnt anArray (1, aNbPointsOnContour);
1287 BRepTools_WireExplorer aWexp (aWire, theFace);
1288 Standard_Integer anInd = 0;
1289 TopTools_MapOfShape aUsedEmap;
1290 for (; aWexp.More(); aWexp.Next())
1292 const TopoDS_Edge& anEdge = aWexp.Current();
1293 if (!aUsedEmap.Add(anEdge)) continue;
1294 BRepAdaptor_Curve2d aBAcurve2d (anEdge, theFace);
1295 Standard_Real aDelta = (aBAcurve2d.LastParameter() - aBAcurve2d.FirstParameter())/aNbSamples;
1296 for (Standard_Integer ii = 0; ii < aNbSamples; ii++)
1298 Standard_Real aParam = aBAcurve2d.FirstParameter() + ii * aDelta;
1299 gp_Pnt2d aP2d = aBAcurve2d.Value (aParam);
1300 gp_Pnt aPnt (aP2d.X(), aP2d.Y(), 0.);
1301 anArray (++anInd) = aPnt;
1306 Standard_Boolean anIsSingular;
1307 GeomLib::AxeOfInertia (anArray, anAxis, anIsSingular);
1308 gp_Pnt aBaryCentre = anAxis.Location();
1309 gp_Pnt2d aCentre2d (aBaryCentre.X(), aBaryCentre.Y());
1310 BRepTopAdaptor_FClass2d aClassifier (theFace, Precision::Confusion());
1311 BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
1313 TopAbs_State aStatus = aClassifier.Perform (aCentre2d);
1314 gp_Pnt2d aP2d = aCentre2d;
1315 Standard_Integer anIndVertex = 0;
1316 const Standard_Integer aNbIter = 10;
1317 while (aStatus != TopAbs_IN && anIndVertex < aNbPointsOnContour)
1319 gp_Pnt aVertexPnt = anArray (anIndVertex+1);
1320 gp_Pnt2d aVertexP2d (aVertexPnt.X(), aVertexPnt.Y());
1321 TColgp_SequenceOfPnt2d aPseq;
1322 aPseq.Append (aCentre2d);
1323 aPseq.Append (aVertexP2d);
1324 for (Standard_Integer ii = 1; ii <= aNbIter; ii++)
1326 for (Standard_Integer jj = 1; jj < aPseq.Length(); jj++)
1328 aP2d.SetXY ((aPseq(jj).XY() + aPseq(jj+1).XY())/2);
1329 aStatus = aClassifier.Perform (aP2d);
1330 if (aStatus == TopAbs_IN)
1334 aPseq.InsertAfter (jj, aP2d);
1338 if (aStatus == TopAbs_IN)
1341 anIndVertex += aNbSamples;
1343 aResPnt = aBAsurf.Value (aP2d.X(), aP2d.Y());
1344 } //case of complex boundaries
1349 void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace,
1350 const Standard_Real theAverageArea,
1351 const Standard_Boolean theIsToAddFaces,
1352 Standard_Integer& theNbExtremalFaces,
1353 TopTools_MapOfShape& theExtremalFaces,
1354 const std::vector<std::pair<TopoDS_Shape, Standard_Real>> theFacesAndAreas,
1355 const TopTools_DataMapOfShapeReal& theFaceAreaMap,
1356 const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap,
1357 TopoDS_Shape& theRes,
1358 TopoDS_Shape& theGlobalRes,
1359 TopTools_MapOfShape& theRemovedFaces)
1361 BRepAdaptor_Surface aBAsurf (theInputFace, Standard_False);
1362 GeomAbs_SurfaceType aType = aBAsurf.GetType();
1365 const Standard_Integer aNbFaces = (Standard_Integer) theFacesAndAreas.size();
1367 const Standard_Integer aDiff = theNbExtremalFaces - theRemovedFaces.Extent();
1369 Standard_Integer aSum = 0;
1370 while (aSum < aDiff) //global loop
1372 Standard_Integer aNbFacesDone = 0, aNbFacesInTape = 0;
1373 TopoDS_Face aStartFace;
1375 Standard_Integer aStartIndex = (theIsToAddFaces)? aNbFaces-1 : 0;
1376 Standard_Integer anEndIndex = (theIsToAddFaces)? 0 : aNbFaces-1;
1377 Standard_Integer aStep = (theIsToAddFaces)? -1 : 1;
1379 for (Standard_Integer ii = aStartIndex; ii != anEndIndex; ii += aStep)
1381 const TopoDS_Face& aFace = TopoDS::Face (theFacesAndAreas[ii].first);
1382 if (!theRemovedFaces.Contains(aFace))
1388 if (aStartFace.IsNull())
1391 theRemovedFaces.Add (aStartFace);
1393 TopoDS_Edge aCommonEdge;
1394 TopoDS_Face aNextFace;
1395 Standard_Real anExtremalArea = (theIsToAddFaces)? 0. : Precision::Infinite();
1396 for (TopExp_Explorer anExplo(aStartFace, TopAbs_EDGE); anExplo.More(); anExplo.Next())
1398 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1399 const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge);
1400 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1401 for (; anItl.More(); anItl.Next())
1403 const TopoDS_Face& aFace = TopoDS::Face (anItl.Value());
1404 if (aFace.IsSame (aStartFace) ||
1405 theRemovedFaces.Contains(aFace))
1407 Standard_Real anArea = theFaceAreaMap(aFace);
1408 Standard_Boolean anIsToExchange = (theIsToAddFaces)? (anArea > anExtremalArea) : (anArea < anExtremalArea);
1411 anExtremalArea = anArea;
1412 aCommonEdge = anEdge;
1417 if (aCommonEdge.IsNull()) //all adjacent faces are already removed
1419 theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first);
1420 theNbExtremalFaces++;
1424 //Start filling the shell
1425 aBB.Remove (theRes, aStartFace);
1427 TopoDS_Shell aShell;
1428 aBB.MakeShell (aShell);
1429 Standard_Real anAreaOfTape = 0.;
1430 aBB.Add (aShell, aStartFace);
1432 anAreaOfTape += theFaceAreaMap (aStartFace);
1434 Standard_Boolean anIsUiso = IsUiso (aCommonEdge, aStartFace);
1435 //Find another faces on this level
1436 TopoDS_Face aCurrentFace = aNextFace;
1437 TopoDS_Edge aCurrentEdge = aCommonEdge;
1438 Standard_Boolean anIsFirstDirection = Standard_True;
1439 aBB.Remove (theRes, aCurrentFace);
1440 theRemovedFaces.Add (aCurrentFace);
1441 if (theExtremalFaces.Contains (aCurrentFace))
1445 aBB.Add (aShell, aCurrentFace);
1447 anAreaOfTape += theFaceAreaMap (aCurrentFace);
1448 Standard_Boolean anIsRound = Standard_False;
1449 for (;;) //local loop
1451 TopoDS_Edge aNextEdge;
1452 for (TopExp_Explorer anExplo(aCurrentFace, TopAbs_EDGE); anExplo.More(); anExplo.Next())
1454 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1455 if (anEdge.IsSame (aCurrentEdge))
1457 const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge);
1458 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1459 for (; anItl.More(); anItl.Next())
1461 const TopoDS_Face& aFace = TopoDS::Face (anItl.Value());
1462 if (aFace.IsSame (aCurrentFace))
1464 if (aFace.IsSame (aStartFace))
1466 anIsRound = Standard_True;
1467 if (aType > GeomAbs_Torus) { // non-elementary surfaces
1468 // remove last face to prevent close tape creation
1469 // it is a workaround for Tulip bos #26791
1470 // as there is a problem with closed tape on some surface types
1471 aBB.Remove (aShell, aCurrentFace);
1473 anAreaOfTape -= theFaceAreaMap(aCurrentFace);
1474 aBB.Add(theRes, aCurrentFace); // aaajfa ???
1475 theRemovedFaces.Remove(aCurrentFace);
1476 if (theExtremalFaces.Contains(aCurrentFace)) {
1482 if (theRemovedFaces.Contains(aFace))
1484 if (anIsUiso == IsUiso (anEdge, aFace))
1491 if (anIsRound || !aNextEdge.IsNull())
1494 if (anIsRound) //round tape: returned to start face
1496 if (aNextEdge.IsNull())
1498 if (anIsFirstDirection)
1500 aCurrentFace = aStartFace;
1501 aCurrentEdge = aCommonEdge;
1502 anIsFirstDirection = Standard_False;
1509 aBB.Add (aShell, aNextFace);
1511 anAreaOfTape += theFaceAreaMap (aNextFace);
1512 aBB.Remove (theRes, aNextFace);
1513 theRemovedFaces.Add (aNextFace);
1514 if (theExtremalFaces.Contains (aNextFace))
1518 aCurrentEdge = aNextEdge;
1519 aNextEdge.Nullify();
1520 aCurrentFace = aNextFace;
1521 } //end of local loop
1524 Standard_Integer aNumberToSplit = (theIsToAddFaces)? aNbFacesInTape + aNbFacesDone : aNbFacesInTape - aNbFacesDone;
1525 if (!theIsToAddFaces && aNbFacesDone > 1)
1527 Standard_Integer aRealNumberToSplit = (aNumberToSplit > 0)? aNumberToSplit : 1;
1528 Standard_Real anAverageAreaInTape = anAreaOfTape / aRealNumberToSplit;
1529 if (anAverageAreaInTape > theAverageArea)
1531 Standard_Integer aNewNumberToSplit = RealToInt(round(anAreaOfTape / theAverageArea));
1532 if (aNewNumberToSplit < aNbFacesInTape)
1534 Standard_Integer aNumberToIncrease = aNewNumberToSplit - aNumberToSplit;
1535 for (Standard_Integer jj = theNbExtremalFaces;
1536 jj < theNbExtremalFaces + aNumberToIncrease && jj < aNbFaces;
1538 theExtremalFaces.Add (theFacesAndAreas[jj].first);
1539 theNbExtremalFaces += aNumberToIncrease;
1540 aNumberToSplit = aNewNumberToSplit;
1544 if (anIsRound && aNumberToSplit <= 1)
1546 Standard_Integer aNumberToIncrease = 3 - aNumberToSplit;
1547 for (Standard_Integer jj = theNbExtremalFaces;
1548 jj < theNbExtremalFaces + aNumberToIncrease && jj < aNbFaces;
1550 theExtremalFaces.Add (theFacesAndAreas[jj].first);
1551 theNbExtremalFaces += aNumberToIncrease;
1554 CorrectShell (aShell, theInputFace);
1555 ShapeUpgrade_UnifySameDomain aUnifier;
1556 aUnifier.Initialize (aShell, Standard_True, Standard_True);
1558 TopoDS_Shape aUnifiedShape = aUnifier.Shape();
1560 TopoDS_Shape aLocalResult = aUnifiedShape;
1561 Standard_Integer aNbFacesInLocalResult;
1562 if (aNumberToSplit > 1)
1564 #if OCC_VERSION_LARGE < 0x07050304
1565 aNbFacesInLocalResult = 0;
1567 ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape);
1568 aLocalTool.SetSplittingByNumber (Standard_True);
1569 aLocalTool.MaxArea() = -1;
1571 aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1);
1573 aLocalTool.SetNumbersUVSplits (1, aNumberToSplit);
1574 aLocalTool.Perform();
1575 aLocalResult = aLocalTool.Result();
1576 aNbFacesInLocalResult = aNumberToSplit;
1581 aNbFacesInLocalResult = 1;
1582 if (aNumberToSplit == 0)
1584 if (theNbExtremalFaces < aNbFaces) {
1585 theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first);
1586 theNbExtremalFaces++;
1590 aBB.Add (theGlobalRes, aLocalResult);
1592 aSum += Abs(aNbFacesInTape - aNbFacesInLocalResult);
1593 } //end of global loop
1595 //Second global loop
1596 TopoDS_Compound aSecondComp;
1597 aBB.MakeCompound (aSecondComp);
1598 while (aSum < aDiff)
1600 TopoDS_Shape aMaxShell;
1601 Standard_Integer aMaxNbFaces = 0;
1602 TopoDS_Iterator anIter (theGlobalRes);
1603 for (; anIter.More(); anIter.Next())
1605 const TopoDS_Shape& aShell = anIter.Value();
1606 TopTools_IndexedMapOfShape aFaceMap;
1607 TopExp::MapShapes (aShell, TopAbs_FACE, aFaceMap);
1608 if (aFaceMap.Extent() > aMaxNbFaces)
1610 aMaxNbFaces = aFaceMap.Extent();
1615 if (aMaxNbFaces == 1)
1618 aBB.Remove (theGlobalRes, aMaxShell);
1620 Standard_Boolean anIsUiso = Standard_True;
1621 TopTools_IndexedDataMapOfShapeListOfShape aLocalEFmap;
1622 TopExp::MapShapesAndAncestors (aMaxShell, TopAbs_EDGE, TopAbs_FACE, aLocalEFmap);
1623 for (Standard_Integer jj = 1; jj <= aLocalEFmap.Extent(); jj++)
1625 const TopoDS_Edge& anEdge = TopoDS::Edge (aLocalEFmap.FindKey(jj));
1626 const TopTools_ListOfShape& aFaceList = aLocalEFmap(jj);
1627 if (aFaceList.Extent() == 2)
1629 const TopoDS_Face& aFace = TopoDS::Face (aFaceList.First());
1630 anIsUiso = IsUiso (anEdge, aFace);
1634 CorrectShell (aMaxShell, theInputFace);
1635 ShapeUpgrade_UnifySameDomain aUnifier;
1636 aUnifier.Initialize (aMaxShell, Standard_True, Standard_True);
1638 TopoDS_Shape aUnifiedShape = aUnifier.Shape();
1639 TopoDS_Shape aLocalResult = aUnifiedShape;
1641 Standard_Integer aNumberToSplit = (theIsToAddFaces)? aMaxNbFaces + (aDiff-aSum) : aMaxNbFaces - (aDiff-aSum);
1642 if (aNumberToSplit > 1)
1644 #if OCC_VERSION_LARGE < 0x07050304
1647 ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape);
1648 aLocalTool.SetSplittingByNumber (Standard_True);
1649 aLocalTool.MaxArea() = -1;
1651 aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1);
1653 aLocalTool.SetNumbersUVSplits (1, aNumberToSplit);
1654 aLocalTool.Perform();
1655 aLocalResult = aLocalTool.Result();
1661 aBB.Add (aSecondComp, aLocalResult);
1663 if (theIsToAddFaces)
1665 aSum += aMaxNbFaces - aNumberToSplit;
1667 aBB.Add (theGlobalRes, aSecondComp);