1 // Copyright (C) 2007-2024 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 <BRepGProp.hxx>
85 #include <IntTools_Tools.hxx>
87 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
88 #include <TopTools_ListOfShape.hxx>
89 #include <TopTools_MapOfShape.hxx>
90 #include <TopTools_DataMapOfShapeReal.hxx>
91 #include <TColgp_SequenceOfPnt2d.hxx>
93 #include <TopTools_ListIteratorOfListOfShape.hxx>
94 #include <TopTools_IndexedMapOfShape.hxx>
95 #include <TopAbs_ShapeEnum.hxx>
97 #include <IntTools_Tools.hxx>
99 #include <BOPTools_AlgoTools3D.hxx>
100 #include <BOPTools_AlgoTools2D.hxx>
102 #include <ShapeUpgrade_ShapeDivideArea.hxx>
103 #include <ShapeUpgrade_UnifySameDomain.hxx>
105 #include <GEOMAlgo_PassKeyShape.hxx>
110 void GetCount(const TopoDS_Shape& aS,
111 Standard_Integer& iCnt);
113 void CopySource(const TopoDS_Shape& aS,
114 TopTools_IndexedDataMapOfShapeShape& aMapSS,
117 static Standard_Boolean comp(const std::pair<TopoDS_Shape, Standard_Real>& theA,
118 const std::pair<TopoDS_Shape, Standard_Real>& theB);
120 static Standard_Boolean IsUiso (const TopoDS_Edge& theEdge,
121 const TopoDS_Face& theFace);
123 static void CorrectShell (const TopoDS_Shape& theShell,
124 const TopoDS_Face& theFace);
126 static gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace,
127 const Standard_Boolean theIsNaturalRestrictions);
129 static void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace,
130 const Standard_Real theAverageArea,
131 const Standard_Boolean theIsToAddFaces,
132 Standard_Integer& theNbExtremalFaces,
133 TopTools_MapOfShape& theExtremalFaces,
134 const std::vector<std::pair<TopoDS_Shape, Standard_Real>> theFacesAndAreas,
135 const TopTools_DataMapOfShapeReal& theFaceAreaMap,
136 const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap,
137 TopoDS_Shape& theRes,
138 TopoDS_Shape& theGlobalRes,
139 TopTools_MapOfShape& theRemovedFaces);
141 //=======================================================================
142 //function : CopyShape
144 //=======================================================================
145 void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS,
148 TopTools_IndexedDataMapOfShapeShape aMapSS;
150 CopySource(aS, aMapSS, aSC);
152 //=======================================================================
153 //function : CopyShape
155 //=======================================================================
156 void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS,
158 TopTools_IndexedDataMapOfShapeShape& aMapSS)
160 CopySource(aS, aMapSS, aSC);
162 //=======================================================================
163 //function : CopySource
165 //=======================================================================
166 void CopySource(const TopoDS_Shape& aS,
167 TopTools_IndexedDataMapOfShapeShape& aMapSS,
170 Standard_Boolean bFree;
178 if (aMapSS.Contains(aS)) {
179 aSC=aMapSS.ChangeFromKey(aS);
180 aSC.Orientation(aS.Orientation());
184 aSC=aS.EmptyCopied();
189 aSC.Free(Standard_True);
191 if (aT==TopAbs_EDGE){
192 TopAbs_Orientation aOr;
194 aOr=aS.Orientation();
195 if(aOr==TopAbs_INTERNAL) {
196 aSF.Orientation(TopAbs_FORWARD);
200 for (; aIt.More(); aIt.Next()) {
203 const TopoDS_Shape& aSx=aIt.Value();
205 CopySource (aSx, aMapSS, aSCx);
207 aSCx.Orientation(aSx.Orientation());
212 //=======================================================================
213 //function : FaceNormal
215 //=======================================================================
216 void GEOMAlgo_AlgoTools::FaceNormal (const TopoDS_Face& aF,
217 const Standard_Real U,
218 const Standard_Real V,
223 Handle(Geom_Surface) aSurface;
225 aSurface=BRep_Tool::Surface(aF);
226 aSurface->D1 (U, V, aPnt, aD1U, aD1V);
227 aN=aD1U.Crossed(aD1V);
229 if (aF.Orientation() == TopAbs_REVERSED){
234 //=======================================================================
235 //function : BuildPCurveForEdgeOnFace
237 //=======================================================================
238 Standard_Integer GEOMAlgo_AlgoTools::BuildPCurveForEdgeOnFace
239 (const TopoDS_Edge& aEold,
240 const TopoDS_Edge& aEnew,
241 const TopoDS_Face& aF,
242 const Handle(IntTools_Context)& aCtx)
244 Standard_Boolean bIsClosed, bUClosed, bHasOld;
245 Standard_Integer iRet, aNbPoints;
246 Standard_Real aTS, aTS1, aTS2, aT, aT1, aT2, aScPr, aTol;
247 Standard_Real aU, aV, aUS1, aVS1, aUS2, aVS2;
249 gp_Pnt2d aP2DS1, aP2DS2, aP2D;
250 gp_Vec2d aV2DS1, aV2DS2;
251 Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2;
252 Handle(Geom_Surface) aS;
257 bHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface(aEnew, aF, aC2D, aT1, aT2, aTol);
262 // Try to copy PCurve from old edge to the new one.
263 iRet = BOPTools_AlgoTools2D::AttachExistingPCurve(aEold, aEnew, aF, aCtx);
266 // Do PCurve using projection algorithm.
269 // The PCurve is attached successfully.
273 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aEnew, aF);
274 aC2D=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
280 bIsClosed=BRep_Tool::IsClosed(aEold, aF);
287 // 1. bUClosed - direction of closeness
290 aES.Orientation(TopAbs_FORWARD);
291 aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
293 aES.Orientation(TopAbs_REVERSED);
294 aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
296 aTS=IntTools_Tools::IntermediatePoint(aTS1, aTS2);
298 aC2DS1->D1(aTS, aP2DS1, aV2DS1);
299 aC2DS2->D1(aTS, aP2DS2, aV2DS2);
301 gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
302 gp_Dir2d aD2DS12(aV2DS12);
303 const gp_Dir2d& aD2DX=gp::DX2d();
306 bUClosed=Standard_True;
307 if (fabs(aScPr) < aTol) {
311 // 2. aP2D - point on curve aC2D, that corresponds to aP2DS1
312 aP2DS1.Coord(aUS1, aVS1);
313 aP2DS2.Coord(aUS2, aVS2);
315 aS=BRep_Tool::Surface(aF);
316 aS->D0(aUS1, aVS1, aP);
318 GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
321 aNbPoints=aProjPC.NbPoints();
327 aT=aProjPC.LowerDistanceParameter();
330 // 3. Build the second 2D curve
331 Standard_Boolean bRevOrder;
332 gp_Vec2d aV2DT, aV2D;
333 Handle(Geom2d_Curve) aC2Dnew;
334 Handle(Geom2d_TrimmedCurve) aC2DTnew;
337 aC2D->D1(aT, aP2D, aV2D);
340 aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
341 aC2DTnew = new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
344 if (!bUClosed) { // V Closed
345 if (fabs(aV-aVS2)<aTol) {
350 if (fabs(aU-aUS2)<aTol) {
355 aC2DTnew->Translate(aV2DT);
357 // 4 Order the 2D curves
358 bRevOrder=Standard_False;
361 bRevOrder=!bRevOrder;
364 // 5. Update the edge
365 aTol=BRep_Tool::Tolerance(aEnew);
367 aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
370 aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
375 //////////////////////////////////////////////////////////////////////////
376 //=======================================================================
377 // function: MakeContainer
379 //=======================================================================
380 void GEOMAlgo_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
386 case TopAbs_COMPOUND:{
388 aBB.MakeCompound(aC);
393 case TopAbs_COMPSOLID:{
394 TopoDS_CompSolid aCS;
395 aBB.MakeCompSolid(aCS);
402 aBB.MakeSolid(aSolid);
410 aBB.MakeShell(aShell);
426 //=======================================================================
427 //function : IsUPeriodic
429 //=======================================================================
430 Standard_Boolean GEOMAlgo_AlgoTools::IsUPeriodic(const Handle(Geom_Surface) &aS)
432 Standard_Boolean bRet;
433 GeomAbs_SurfaceType aType;
434 GeomAdaptor_Surface aGAS;
437 aType=aGAS.GetType();
438 bRet=(aType==GeomAbs_Cylinder||
439 aType==GeomAbs_Cone ||
440 aType==GeomAbs_Sphere);
445 //=======================================================================
446 //function : RefinePCurveForEdgeOnFace
448 //=======================================================================
449 void GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE,
450 const TopoDS_Face& aF,
451 const Standard_Real aUMin,
452 const Standard_Real aUMax)
454 Standard_Real aT1, aT2, aTx, aUx, aTol;
456 Handle(Geom_Surface) aS;
457 Handle(Geom2d_Curve) aC2D;
460 aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
461 if (!aC2D.IsNull()) {
462 if (BRep_Tool::IsClosed(aE, aF)) {
465 aTx=IntTools_Tools::IntermediatePoint(aT1, aT2);
468 if (aUx < aUMin || aUx > aUMax) {
470 Handle(Geom2d_Curve) aC2Dx;
472 aTol=BRep_Tool::Tolerance(aE);
473 aBB.UpdateEdge(aE, aC2Dx, aF, aTol);
477 //=======================================================================
478 //function :IsSplitToReverse
480 //=======================================================================
481 Standard_Boolean GEOMAlgo_AlgoTools::IsSplitToReverse
482 (const TopoDS_Edge& aEF1,
483 const TopoDS_Edge& aEF2,
484 const Handle(IntTools_Context)& aContext)
486 Standard_Boolean aFlag;
487 Standard_Real aT1, aT2, aScPr, a, b;
492 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b);
493 aT1=IntTools_Tools::IntermediatePoint(a, b);
495 aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
498 return Standard_False;
503 aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2);
505 return Standard_False;
508 aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
510 return Standard_False;
521 //=======================================================================
522 //function : ProjectPointOnShape
524 //=======================================================================
525 Standard_Boolean GEOMAlgo_AlgoTools::ProjectPointOnShape
527 const TopoDS_Shape& aS,
529 const Handle(IntTools_Context)& aCtx)
531 Standard_Boolean bIsDone = Standard_False;
533 TopAbs_ShapeEnum aType;
535 aType = aS.ShapeType();
540 const TopoDS_Edge& aE2 = TopoDS::Edge(aS);
542 if (BRep_Tool::Degenerated(aE2)) { // jfa
543 return Standard_True;
547 Handle(Geom_Curve) aC3D = BRep_Tool::Curve (aE2, f, l);
549 return Standard_True;
551 bIsDone = aCtx->ProjectPointOnEdge(aP1, aE2, aT2);
557 GEOMAlgo_AlgoTools::PointOnEdge(aE2, aT2, aP2);
563 const TopoDS_Face& aF2 = TopoDS::Face(aS);
564 GeomAPI_ProjectPointOnSurf& aProj = aCtx->ProjPS(aF2);
567 bIsDone = aProj.IsDone();
572 aP2 = aProj.NearestPoint();
582 //=======================================================================
583 //function : PointOnEdge
585 //=======================================================================
586 void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
589 Standard_Real aTx, aT1, aT2;
591 BRep_Tool::Curve(aE, aT1, aT2);
592 aTx=IntTools_Tools::IntermediatePoint(aT1, aT2);
593 GEOMAlgo_AlgoTools::PointOnEdge(aE, aTx, aP3D);
595 //=======================================================================
596 //function : PointOnEdge
598 //=======================================================================
599 void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
600 const Standard_Real aT,
603 Standard_Real aT1, aT2;
604 Handle(Geom_Curve) aC3D;
606 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
609 //=======================================================================
610 //function : PointOnFace
612 //=======================================================================
613 void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF,
614 const Standard_Real aU,
615 const Standard_Real aV,
618 Handle(Geom_Surface) aS;
620 aS=BRep_Tool::Surface(aF);
621 aS->D0(aU, aV, aP3D);
623 //=======================================================================
624 //function : PointOnFace
626 //=======================================================================
627 void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF,
630 Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax;
632 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
634 aU=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
635 aV=IntTools_Tools::IntermediatePoint(aVMin, aVMax);
637 GEOMAlgo_AlgoTools::PointOnFace(aF, aU, aV, aP3D);
639 //=======================================================================
640 //function : PointOnShape
642 //=======================================================================
643 void GEOMAlgo_AlgoTools::PointOnShape(const TopoDS_Shape& aS,
646 TopAbs_ShapeEnum aType;
648 aP3D.SetCoord(99.,99.,99.);
649 aType=aS.ShapeType();
652 const TopoDS_Edge& aE=TopoDS::Edge(aS);
653 GEOMAlgo_AlgoTools::PointOnEdge(aE, aP3D);
658 const TopoDS_Face& aF=TopoDS::Face(aS);
659 GEOMAlgo_AlgoTools::PointOnFace(aF, aP3D);
667 //=======================================================================
668 //function : FindSDShapes
670 //=======================================================================
671 Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
672 (const TopoDS_Shape& aE1,
673 const TopTools_ListOfShape& aLE,
674 const Standard_Real aTol,
675 TopTools_ListOfShape& aLESD,
676 const Handle(IntTools_Context)& aCtx)
678 Standard_Boolean bIsDone;
679 Standard_Real aTol2, aD2;
681 TopTools_ListIteratorOfListOfShape aIt;
684 GEOMAlgo_AlgoTools::PointOnShape(aE1, aP1);
687 for (; aIt.More(); aIt.Next()) {
688 const TopoDS_Shape& aE2=aIt.Value();
689 if (aE2.IsSame(aE1)) {
693 bIsDone=GEOMAlgo_AlgoTools::ProjectPointOnShape(aP1, aE2, aP2, aCtx);
696 continue; // jfa BUG 20361
698 aD2=aP1.SquareDistance(aP2);
707 //=======================================================================
708 //function : FindSDShapes
710 //=======================================================================
711 Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
712 (const TopTools_ListOfShape& aLE,
713 const Standard_Real aTol,
714 TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
715 const Handle(IntTools_Context)& aCtx)
717 Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
718 TopTools_ListOfShape aLESD;
719 TopTools_ListIteratorOfListOfShape aIt, aIt1;
720 TopTools_IndexedMapOfShape aMProcessed;
721 TopAbs_ShapeEnum aType;
728 return 0; // Nothing to do
732 aNbEProcessed=aMProcessed.Extent();
733 if (aNbEProcessed==aNbE) {
738 for (; aIt.More(); aIt.Next()) {
739 const TopoDS_Shape& aS=aIt.Value();
741 if (aMProcessed.Contains(aS)) {
745 aType=aS.ShapeType();
746 if (aType==TopAbs_EDGE) {
747 const TopoDS_Edge& aE=TopoDS::Edge(aS);
748 if (BRep_Tool::Degenerated(aE)) {
755 iErr=GEOMAlgo_AlgoTools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
760 aNbESD=aLESD.Extent();
767 aIt1.Initialize(aLESD);
768 for (; aIt1.More(); aIt1.Next()) {
769 const TopoDS_Shape& aE1=aIt1.Value();
770 aMProcessed.Add(aE1);
776 //=======================================================================
777 //function : RefineSDShapes
779 //=======================================================================
780 Standard_Integer GEOMAlgo_AlgoTools::RefineSDShapes
781 (GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMPKLE,
782 const Standard_Real aTol,
783 const Handle(IntTools_Context)& aCtx)
785 Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
786 TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
790 aNbE=aMPKLE.Extent();
791 for (i=1; i<=aNbE; ++i) {
792 TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
795 iErr=GEOMAlgo_AlgoTools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
802 continue; // nothing to do
805 for (j=1; j<=aNbEE; ++j) {
806 TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
813 const TopoDS_Shape& aE1=aLEE.First();
814 aMEToAdd.Add(aE1, aLEE);
819 aNbToAdd=aMEToAdd.Extent();
824 for (i=1; i<=aNbToAdd; ++i) {
825 GEOMAlgo_PassKeyShape aPKE1;
827 const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
828 const TopTools_ListOfShape& aLE=aMEToAdd(i);
830 aPKE1.SetShapes(aE1);
831 aMPKLE.Add(aPKE1, aLE);
837 //=======================================================================
838 //function : IsCompositeShape
840 //=======================================================================
841 Standard_Boolean GEOMAlgo_AlgoTools::IsCompositeShape(const TopoDS_Shape& aS)
843 Standard_Boolean bRet;
844 Standard_Integer iCnt;
853 //=======================================================================
854 //function : GetCount
856 //=======================================================================
857 void GetCount(const TopoDS_Shape& aS,
858 Standard_Integer& iCnt)
861 TopAbs_ShapeEnum aTS;
865 if (aTS==TopAbs_SHAPE) {
868 if (aTS!=TopAbs_COMPOUND) {
874 for (; aIt.More(); aIt.Next()) {
875 const TopoDS_Shape& aSx=aIt.Value();
880 //=======================================================================
881 //function : PntInFace
883 //=======================================================================
884 Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF,
888 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
889 Standard_Integer iErr, aIx, aNbDomains, i;
890 Standard_Real aUMin, aUMax, aVMin, aVMax;
891 Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
892 Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
893 gp_Dir2d aD2D (0., 1.);
896 Handle(Geom2d_Curve) aC2D;
897 Handle(Geom2d_TrimmedCurve) aCT2D;
898 Handle(Geom2d_Line) aL2D;
899 Handle(Geom_Surface) aS;
900 TopAbs_Orientation aOrE;
902 TopExp_Explorer aExp;
907 aTolTangfIntr=1.e-10;
909 Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
910 Geom2dHatch_Hatcher aHatcher(aIntr,
911 aTolHatch2D, aTolHatch3D,
912 Standard_True, Standard_False);
918 aFF.Orientation (TopAbs_FORWARD);
920 aS=BRep_Tool::Surface(aFF);
921 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
924 aExp.Init (aFF, TopAbs_EDGE);
925 for (; aExp.More() ; aExp.Next()) {
926 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
927 aOrE=aE.Orientation();
929 aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
930 if (aC2D.IsNull() ) {
934 if (fabs(aU1-aU2) < aEpsT) {
939 aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
940 aHatcher.AddElement(aCT2D, aOrE);
941 }// for (; aExp.More() ; aExp.Next()) {
944 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
945 aP2D.SetCoord(aUx, 0.);
946 aL2D=new Geom2d_Line (aP2D, aD2D);
947 Geom2dAdaptor_Curve aHCur(aL2D);
949 aIx=aHatcher.AddHatching(aHCur) ;
953 bIsDone=aHatcher.TrimDone(aIx);
959 aHatcher.ComputeDomains(aIx);
960 bIsDone=aHatcher.IsDone(aIx);
968 aNbDomains=aHatcher.NbDomains(aIx);
975 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
976 bHasFirstPoint=aDomain.HasFirstPoint();
977 if (!bHasFirstPoint) {
982 aV1=aDomain.FirstPoint().Parameter();
984 bHasSecondPoint=aDomain.HasSecondPoint();
985 if (!bHasSecondPoint) {
990 aV2=aDomain.SecondPoint().Parameter();
992 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
994 aS->D0(aUx, aVx, aPx);
996 theP2D.SetCoord(aUx, aVx);
1002 //=======================================================================
1003 //function : PointCloudInFace
1005 //=======================================================================
1006 Standard_Integer GEOMAlgo_AlgoTools::PointCloudInFace(const TopoDS_Face& theFace,
1007 const int theNbPnts,
1008 TopoDS_Compound& theCompound)
1010 #if OCC_VERSION_LARGE < 0x07050304
1013 ShapeUpgrade_ShapeDivideArea tool (theFace);
1014 tool.SetSplittingByNumber (Standard_True);
1015 tool.NbParts() = theNbPnts;
1017 TopoDS_Shape res = tool.Result();
1020 TopoDS_Compound aGlobalRes;
1021 aBB.MakeCompound (aGlobalRes);
1023 TopTools_IndexedMapOfShape aFaceMap;
1024 TopExp::MapShapes (res, TopAbs_FACE, aFaceMap);
1025 Standard_Integer aNbFaces = aFaceMap.Extent();
1027 TopTools_IndexedDataMapOfShapeListOfShape aEFmap;
1028 TopExp::MapShapesAndAncestors (res, TopAbs_EDGE, TopAbs_FACE, aEFmap);
1030 TopTools_MapOfShape aBiggestFaces, aSmallestFaces;
1031 Standard_Boolean aUseTriangulation = Standard_True;
1032 Standard_Boolean aSkipShared = Standard_False;
1033 if (aNbFaces != theNbPnts)
1035 Standard_Real aTotalArea = 0.;
1036 std::vector<std::pair<TopoDS_Shape, Standard_Real> > aFacesAndAreas (aNbFaces);
1037 for (Standard_Integer ii = 1; ii <= aNbFaces; ii++)
1039 GProp_GProps aProps;
1040 BRepGProp::SurfaceProperties (aFaceMap(ii), aProps, aSkipShared, aUseTriangulation);
1041 Standard_Real anArea = aProps.Mass();
1042 aTotalArea += anArea;
1043 std::pair<TopoDS_Shape, Standard_Real> aFaceWithArea (aFaceMap(ii), anArea);
1044 aFacesAndAreas[ii-1] = aFaceWithArea;
1046 std::sort (aFacesAndAreas.begin(), aFacesAndAreas.end(), comp);
1048 Standard_Real anAverageArea = aTotalArea / theNbPnts;
1050 TopTools_DataMapOfShapeReal aFaceAreaMap;
1051 for (Standard_Integer ii = 0; ii < aNbFaces; ii++)
1052 aFaceAreaMap.Bind (aFacesAndAreas[ii].first, aFacesAndAreas[ii].second);
1054 TopTools_MapOfShape aRemovedFaces;
1056 if (aNbFaces < theNbPnts)
1058 Standard_Integer aNbMissingFaces = theNbPnts - aNbFaces;
1059 for (Standard_Integer ii = aNbFaces-1; ii > aNbFaces - aNbMissingFaces - 1; ii--)
1060 aBiggestFaces.Add (aFacesAndAreas[ii].first);
1062 ModifyFacesForGlobalResult (theFace, anAverageArea,
1063 Standard_True, //to add faces
1064 aNbMissingFaces, aBiggestFaces,
1065 aFacesAndAreas, aFaceAreaMap, aEFmap,
1069 else //aNbFaces > theNbPnts
1071 Standard_Integer aNbExcessFaces = aNbFaces - theNbPnts;
1072 for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++)
1073 aSmallestFaces.Add (aFacesAndAreas[ii].first);
1075 TopTools_IndexedDataMapOfShapeListOfShape aVFmap;
1076 TopExp::MapShapesAndAncestors (res, TopAbs_VERTEX, TopAbs_FACE, aVFmap);
1078 //Remove smallest faces with free boundaries
1079 for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++)
1081 const TopoDS_Face& aFace = TopoDS::Face (aFacesAndAreas[ii].first);
1082 Standard_Boolean anIsFreeBoundFound = Standard_False;
1083 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1084 for (; anExplo.More(); anExplo.Next())
1086 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1087 if (!BRep_Tool::Degenerated (anEdge) &&
1088 aEFmap.FindFromKey(anEdge).Extent() < 2)
1090 anIsFreeBoundFound = Standard_True;
1094 if (anIsFreeBoundFound)
1096 Standard_Real aMaxArea = 0.;
1097 for (anExplo.Init(aFace, TopAbs_VERTEX); anExplo.More(); anExplo.Next())
1099 const TopoDS_Shape& aVertex = anExplo.Current();
1100 const TopTools_ListOfShape& aFaceList = aVFmap.FindFromKey (aVertex);
1101 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1102 for (; anItl.More(); anItl.Next())
1104 Standard_Real anArea = aFaceAreaMap (anItl.Value());
1105 if (anArea > aMaxArea)
1109 Standard_Real anArreaOfSmallestFace = aFaceAreaMap (aFace);
1110 if (anArreaOfSmallestFace < aMaxArea / 16)
1112 aBB.Remove (res, aFace);
1113 aRemovedFaces.Add (aFace);
1118 ModifyFacesForGlobalResult (theFace, anAverageArea,
1119 Standard_False, //to decrease number of faces
1120 aNbExcessFaces, aSmallestFaces,
1121 aFacesAndAreas, aFaceAreaMap, aEFmap,
1127 aBB.Add (aGlobalRes, res);
1130 aBB.MakeCompound (theCompound);
1131 for (TopExp_Explorer aGlobalExplo (aGlobalRes, TopAbs_FACE);
1132 aGlobalExplo.More(), iface <= theNbPnts;
1133 aGlobalExplo.Next(), iface++)
1135 const TopoDS_Face& aFace = TopoDS::Face (aGlobalExplo.Current());
1136 Standard_Boolean anIsNaturalRestrictions = Standard_True;
1137 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1138 for (; anExplo.More(); anExplo.Next())
1140 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1141 if (BRep_Tool::Degenerated (anEdge))
1143 if (!aEFmap.Contains(anEdge) ||
1144 aEFmap.FindFromKey(anEdge).Extent() < 2)
1146 anIsNaturalRestrictions = Standard_False;
1151 gp_Pnt aPnt = GetMidPnt2d (aFace, anIsNaturalRestrictions);
1152 TopoDS_Vertex aVertex = BRepLib_MakeVertex (aPnt);
1153 aBB.Add (theCompound, aVertex);
1160 Standard_Boolean comp(const std::pair<TopoDS_Shape, Standard_Real>& theA,
1161 const std::pair<TopoDS_Shape, Standard_Real>& theB)
1163 return (theA.second < theB.second);
1166 Standard_Boolean IsUiso (const TopoDS_Edge& theEdge,
1167 const TopoDS_Face& theFace)
1169 BRepAdaptor_Curve2d aBAcurve2d (theEdge, theFace);
1172 aBAcurve2d.D1 (aBAcurve2d.FirstParameter(), aP2d, aVec);
1173 return (Abs(aVec.Y()) > Abs(aVec.X()));
1176 void CorrectShell (const TopoDS_Shape& theShell,
1177 const TopoDS_Face& theFace)
1179 BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
1180 GeomAbs_SurfaceType aType = aBAsurf.GetType();
1181 if (aType <= GeomAbs_Torus) //elementary surfaces
1184 TopLoc_Location anInputLoc;
1185 const Handle(Geom_Surface)& anInputSurf = BRep_Tool::Surface (theFace, anInputLoc);
1189 TopoDS_Iterator anIter (theShell);
1190 for (; anIter.More(); anIter.Next())
1192 const TopoDS_Face& aFace = TopoDS::Face (anIter.Value());
1193 TopLoc_Location aLoc;
1194 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLoc);
1195 if (aSurf == anInputSurf)
1198 TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
1199 for (; anExplo.More(); anExplo.Next())
1201 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1202 Standard_Real aFirst, aLast;
1203 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast);
1204 aBB.UpdateEdge (anEdge, aPCurve, anInputSurf, anInputLoc, 0.);
1206 Standard_Real aTol = BRep_Tool::Tolerance (aFace);
1207 aBB.UpdateFace (aFace, anInputSurf, anInputLoc, aTol);
1211 gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace,
1212 const Standard_Boolean theIsNaturalRestrictions)
1216 if (theIsNaturalRestrictions)
1218 BRepAdaptor_Surface aBAsurf (theFace);
1219 Standard_Real aUmin, aUmax, aVmin, aVmax;
1220 aUmin = aBAsurf.FirstUParameter();
1221 aUmax = aBAsurf.LastUParameter();
1222 aVmin = aBAsurf.FirstVParameter();
1223 aVmax = aBAsurf.LastVParameter();
1224 aResPnt = aBAsurf.Value ((aUmin + aUmax)/2, (aVmin + aVmax)/2);
1228 const Standard_Integer aNbSamples = 4;
1229 TopoDS_Wire aWire = BRepTools::OuterWire (theFace);
1230 TopTools_IndexedMapOfShape aEmap;
1231 TopExp::MapShapes (aWire, TopAbs_EDGE, aEmap);
1232 Standard_Integer aNbPointsOnContour = aNbSamples * aEmap.Extent();
1233 TColgp_Array1OfPnt anArray (1, aNbPointsOnContour);
1235 BRepTools_WireExplorer aWexp (aWire, theFace);
1236 Standard_Integer anInd = 0;
1237 TopTools_MapOfShape aUsedEmap;
1238 for (; aWexp.More(); aWexp.Next())
1240 const TopoDS_Edge& anEdge = aWexp.Current();
1241 if (!aUsedEmap.Add(anEdge)) continue;
1242 BRepAdaptor_Curve2d aBAcurve2d (anEdge, theFace);
1243 // Initialization of curve could fail in constructor,
1244 // so we need to check if we actually have a curve here.
1245 if (!aBAcurve2d.Curve())
1250 Standard_Real aDelta = (aBAcurve2d.LastParameter() - aBAcurve2d.FirstParameter())/aNbSamples;
1251 for (Standard_Integer ii = 0; ii < aNbSamples; ii++)
1253 Standard_Real aParam = aBAcurve2d.FirstParameter() + ii * aDelta;
1254 gp_Pnt2d aP2d = aBAcurve2d.Value (aParam);
1255 gp_Pnt aPnt (aP2d.X(), aP2d.Y(), 0.);
1256 anArray (++anInd) = aPnt;
1261 Standard_Boolean anIsSingular;
1262 GeomLib::AxeOfInertia (anArray, anAxis, anIsSingular);
1263 gp_Pnt aBaryCentre = anAxis.Location();
1264 gp_Pnt2d aCentre2d (aBaryCentre.X(), aBaryCentre.Y());
1265 BRepTopAdaptor_FClass2d aClassifier (theFace, Precision::Confusion());
1266 BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
1268 TopAbs_State aStatus = aClassifier.Perform (aCentre2d);
1269 gp_Pnt2d aP2d = aCentre2d;
1270 Standard_Integer anIndVertex = 0;
1271 const Standard_Integer aNbIter = 10;
1272 while (aStatus != TopAbs_IN && anIndVertex < aNbPointsOnContour)
1274 gp_Pnt aVertexPnt = anArray (anIndVertex+1);
1275 gp_Pnt2d aVertexP2d (aVertexPnt.X(), aVertexPnt.Y());
1276 TColgp_SequenceOfPnt2d aPseq;
1277 aPseq.Append (aCentre2d);
1278 aPseq.Append (aVertexP2d);
1279 for (Standard_Integer ii = 1; ii <= aNbIter; ii++)
1281 for (Standard_Integer jj = 1; jj < aPseq.Length(); jj++)
1283 aP2d.SetXY ((aPseq(jj).XY() + aPseq(jj+1).XY())/2);
1284 aStatus = aClassifier.Perform (aP2d);
1285 if (aStatus == TopAbs_IN)
1289 aPseq.InsertAfter (jj, aP2d);
1293 if (aStatus == TopAbs_IN)
1296 anIndVertex += aNbSamples;
1298 aResPnt = aBAsurf.Value (aP2d.X(), aP2d.Y());
1299 } //case of complex boundaries
1304 void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace,
1305 const Standard_Real theAverageArea,
1306 const Standard_Boolean theIsToAddFaces,
1307 Standard_Integer& theNbExtremalFaces,
1308 TopTools_MapOfShape& theExtremalFaces,
1309 const std::vector<std::pair<TopoDS_Shape, Standard_Real>> theFacesAndAreas,
1310 const TopTools_DataMapOfShapeReal& theFaceAreaMap,
1311 const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap,
1312 TopoDS_Shape& theRes,
1313 TopoDS_Shape& theGlobalRes,
1314 TopTools_MapOfShape& theRemovedFaces)
1316 BRepAdaptor_Surface aBAsurf (theInputFace, Standard_False);
1317 GeomAbs_SurfaceType aType = aBAsurf.GetType();
1320 const Standard_Integer aNbFaces = (Standard_Integer) theFacesAndAreas.size();
1322 const Standard_Integer aDiff = theNbExtremalFaces - theRemovedFaces.Extent();
1324 Standard_Integer aSum = 0;
1325 while (aSum < aDiff) //global loop
1327 Standard_Integer aNbFacesDone = 0, aNbFacesInTape = 0;
1328 TopoDS_Face aStartFace;
1330 Standard_Integer aStartIndex = (theIsToAddFaces)? aNbFaces-1 : 0;
1331 Standard_Integer anEndIndex = (theIsToAddFaces)? 0 : aNbFaces-1;
1332 Standard_Integer aStep = (theIsToAddFaces)? -1 : 1;
1334 for (Standard_Integer ii = aStartIndex; ii != anEndIndex; ii += aStep)
1336 const TopoDS_Face& aFace = TopoDS::Face (theFacesAndAreas[ii].first);
1337 if (!theRemovedFaces.Contains(aFace))
1343 if (aStartFace.IsNull())
1346 theRemovedFaces.Add (aStartFace);
1348 TopoDS_Edge aCommonEdge;
1349 TopoDS_Face aNextFace;
1350 Standard_Real anExtremalArea = (theIsToAddFaces)? 0. : Precision::Infinite();
1351 for (TopExp_Explorer anExplo(aStartFace, TopAbs_EDGE); anExplo.More(); anExplo.Next())
1353 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1354 const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge);
1355 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1356 for (; anItl.More(); anItl.Next())
1358 const TopoDS_Face& aFace = TopoDS::Face (anItl.Value());
1359 if (aFace.IsSame (aStartFace) ||
1360 theRemovedFaces.Contains(aFace))
1362 Standard_Real anArea = theFaceAreaMap(aFace);
1363 Standard_Boolean anIsToExchange = (theIsToAddFaces)? (anArea > anExtremalArea) : (anArea < anExtremalArea);
1366 anExtremalArea = anArea;
1367 aCommonEdge = anEdge;
1372 if (aCommonEdge.IsNull()) //all adjacent faces are already removed
1374 theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first);
1375 theNbExtremalFaces++;
1379 //Start filling the shell
1380 aBB.Remove (theRes, aStartFace);
1382 TopoDS_Shell aShell;
1383 aBB.MakeShell (aShell);
1384 Standard_Real anAreaOfTape = 0.;
1385 aBB.Add (aShell, aStartFace);
1387 anAreaOfTape += theFaceAreaMap (aStartFace);
1389 Standard_Boolean anIsUiso = IsUiso (aCommonEdge, aStartFace);
1390 //Find another faces on this level
1391 TopoDS_Face aCurrentFace = aNextFace;
1392 TopoDS_Edge aCurrentEdge = aCommonEdge;
1393 Standard_Boolean anIsFirstDirection = Standard_True;
1394 aBB.Remove (theRes, aCurrentFace);
1395 theRemovedFaces.Add (aCurrentFace);
1396 if (theExtremalFaces.Contains (aCurrentFace))
1400 aBB.Add (aShell, aCurrentFace);
1402 anAreaOfTape += theFaceAreaMap (aCurrentFace);
1403 Standard_Boolean anIsRound = Standard_False;
1404 for (;;) //local loop
1406 TopoDS_Edge aNextEdge;
1407 for (TopExp_Explorer anExplo(aCurrentFace, TopAbs_EDGE); anExplo.More(); anExplo.Next())
1409 const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
1410 if (anEdge.IsSame (aCurrentEdge))
1412 const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge);
1413 TopTools_ListIteratorOfListOfShape anItl (aFaceList);
1414 for (; anItl.More(); anItl.Next())
1416 const TopoDS_Face& aFace = TopoDS::Face (anItl.Value());
1417 if (aFace.IsSame (aCurrentFace))
1419 if (aFace.IsSame (aStartFace))
1421 anIsRound = Standard_True;
1422 if (aType > GeomAbs_Torus) { // non-elementary surfaces
1423 // remove last face to prevent close tape creation
1424 // it is a workaround for Tulip bos #26791
1425 // as there is a problem with closed tape on some surface types
1426 aBB.Remove (aShell, aCurrentFace);
1428 anAreaOfTape -= theFaceAreaMap(aCurrentFace);
1429 aBB.Add(theRes, aCurrentFace); // aaajfa ???
1430 theRemovedFaces.Remove(aCurrentFace);
1431 if (theExtremalFaces.Contains(aCurrentFace)) {
1437 if (theRemovedFaces.Contains(aFace))
1439 if (anIsUiso == IsUiso (anEdge, aFace))
1446 if (anIsRound || !aNextEdge.IsNull())
1449 if (anIsRound) //round tape: returned to start face
1451 if (aNextEdge.IsNull())
1453 if (anIsFirstDirection)
1455 aCurrentFace = aStartFace;
1456 aCurrentEdge = aCommonEdge;
1457 anIsFirstDirection = Standard_False;
1464 aBB.Add (aShell, aNextFace);
1466 anAreaOfTape += theFaceAreaMap (aNextFace);
1467 aBB.Remove (theRes, aNextFace);
1468 theRemovedFaces.Add (aNextFace);
1469 if (theExtremalFaces.Contains (aNextFace))
1473 aCurrentEdge = aNextEdge;
1474 aNextEdge.Nullify();
1475 aCurrentFace = aNextFace;
1476 } //end of local loop
1479 Standard_Integer aNumberToSplit = (theIsToAddFaces)? aNbFacesInTape + aNbFacesDone : aNbFacesInTape - aNbFacesDone;
1480 if (!theIsToAddFaces && aNbFacesDone > 1)
1482 Standard_Integer aRealNumberToSplit = (aNumberToSplit > 0)? aNumberToSplit : 1;
1483 Standard_Real anAverageAreaInTape = anAreaOfTape / aRealNumberToSplit;
1484 if (anAverageAreaInTape > theAverageArea)
1486 Standard_Integer aNewNumberToSplit = RealToInt(round(anAreaOfTape / theAverageArea));
1487 if (aNewNumberToSplit < aNbFacesInTape)
1489 Standard_Integer aNumberToIncrease = aNewNumberToSplit - aNumberToSplit;
1490 for (Standard_Integer jj = theNbExtremalFaces;
1491 jj < theNbExtremalFaces + aNumberToIncrease && jj < aNbFaces;
1493 theExtremalFaces.Add (theFacesAndAreas[jj].first);
1494 theNbExtremalFaces += aNumberToIncrease;
1495 aNumberToSplit = aNewNumberToSplit;
1499 if (anIsRound && aNumberToSplit <= 1)
1501 Standard_Integer aNumberToIncrease = 3 - aNumberToSplit;
1502 for (Standard_Integer jj = theNbExtremalFaces;
1503 jj < theNbExtremalFaces + aNumberToIncrease && jj < aNbFaces;
1505 theExtremalFaces.Add (theFacesAndAreas[jj].first);
1506 theNbExtremalFaces += aNumberToIncrease;
1509 CorrectShell (aShell, theInputFace);
1510 ShapeUpgrade_UnifySameDomain aUnifier;
1511 aUnifier.Initialize (aShell, Standard_True, Standard_True);
1513 TopoDS_Shape aUnifiedShape = aUnifier.Shape();
1515 TopoDS_Shape aLocalResult = aUnifiedShape;
1516 Standard_Integer aNbFacesInLocalResult;
1517 if (aNumberToSplit > 1)
1519 #if OCC_VERSION_LARGE < 0x07050304
1520 aNbFacesInLocalResult = 0;
1522 ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape);
1523 aLocalTool.SetSplittingByNumber (Standard_True);
1524 aLocalTool.MaxArea() = -1;
1526 aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1);
1528 aLocalTool.SetNumbersUVSplits (1, aNumberToSplit);
1529 aLocalTool.Perform();
1530 aLocalResult = aLocalTool.Result();
1531 aNbFacesInLocalResult = aNumberToSplit;
1536 aNbFacesInLocalResult = 1;
1537 if (aNumberToSplit == 0)
1539 if (theNbExtremalFaces < aNbFaces) {
1540 theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first);
1541 theNbExtremalFaces++;
1545 aBB.Add (theGlobalRes, aLocalResult);
1547 aSum += Abs(aNbFacesInTape - aNbFacesInLocalResult);
1548 } //end of global loop
1550 //Second global loop
1551 TopoDS_Compound aSecondComp;
1552 aBB.MakeCompound (aSecondComp);
1553 while (aSum < aDiff)
1555 TopoDS_Shape aMaxShell;
1556 Standard_Integer aMaxNbFaces = 0;
1557 TopoDS_Iterator anIter (theGlobalRes);
1558 for (; anIter.More(); anIter.Next())
1560 const TopoDS_Shape& aShell = anIter.Value();
1561 TopTools_IndexedMapOfShape aFaceMap;
1562 TopExp::MapShapes (aShell, TopAbs_FACE, aFaceMap);
1563 if (aFaceMap.Extent() > aMaxNbFaces)
1565 aMaxNbFaces = aFaceMap.Extent();
1570 if (aMaxNbFaces == 1)
1573 aBB.Remove (theGlobalRes, aMaxShell);
1575 Standard_Boolean anIsUiso = Standard_True;
1576 TopTools_IndexedDataMapOfShapeListOfShape aLocalEFmap;
1577 TopExp::MapShapesAndAncestors (aMaxShell, TopAbs_EDGE, TopAbs_FACE, aLocalEFmap);
1578 for (Standard_Integer jj = 1; jj <= aLocalEFmap.Extent(); jj++)
1580 const TopoDS_Edge& anEdge = TopoDS::Edge (aLocalEFmap.FindKey(jj));
1581 const TopTools_ListOfShape& aFaceList = aLocalEFmap(jj);
1582 if (aFaceList.Extent() == 2)
1584 const TopoDS_Face& aFace = TopoDS::Face (aFaceList.First());
1585 anIsUiso = IsUiso (anEdge, aFace);
1589 CorrectShell (aMaxShell, theInputFace);
1590 ShapeUpgrade_UnifySameDomain aUnifier;
1591 aUnifier.Initialize (aMaxShell, Standard_True, Standard_True);
1593 TopoDS_Shape aUnifiedShape = aUnifier.Shape();
1594 TopoDS_Shape aLocalResult = aUnifiedShape;
1596 Standard_Integer aNumberToSplit = (theIsToAddFaces)? aMaxNbFaces + (aDiff-aSum) : aMaxNbFaces - (aDiff-aSum);
1597 if (aNumberToSplit > 1)
1599 #if OCC_VERSION_LARGE < 0x07050304
1602 ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape);
1603 aLocalTool.SetSplittingByNumber (Standard_True);
1604 aLocalTool.MaxArea() = -1;
1606 aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1);
1608 aLocalTool.SetNumbersUVSplits (1, aNumberToSplit);
1609 aLocalTool.Perform();
1610 aLocalResult = aLocalTool.Result();
1616 aBB.Add (aSecondComp, aLocalResult);
1618 if (theIsToAddFaces)
1620 aSum += aMaxNbFaces - aNumberToSplit;
1622 aBB.Add (theGlobalRes, aSecondComp);