X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMAlgo%2FGEOMAlgo_AlgoTools.cxx;fp=src%2FGEOMAlgo%2FGEOMAlgo_AlgoTools.cxx;h=7965b41a5abcd1ed6f72bcbcf847ceaaf275c97f;hb=66a2554913f5c53b13a4e811160becede9b11132;hp=06acad4f48605d94c9b14f961ceff93ef25d986b;hpb=ade417c569fc552473b95f31f9624449dce21b8a;p=modules%2Fgeom.git diff --git a/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx b/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx index 06acad4f4..7965b41a5 100644 --- a/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx +++ b/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx @@ -25,11 +25,17 @@ #include +#include + #include #include #include +#include #include +#include +#include + #include #include #include @@ -41,6 +47,7 @@ #include #include +#include #include #include @@ -49,6 +56,8 @@ #include #include +#include + #include #include @@ -59,20 +68,28 @@ #include #include #include +#include +#include #include #include #include +#include #include +#include #include #include +#include #include #include #include +#include +#include +#include #include #include @@ -83,8 +100,12 @@ #include #include +#include +#include + #include +#include static void GetCount(const TopoDS_Shape& aS, @@ -94,6 +115,30 @@ static TopTools_IndexedDataMapOfShapeShape& aMapSS, TopoDS_Shape& aSC); +static Standard_Boolean comp(const std::pair& theA, + const std::pair& theB); + +static Standard_Boolean IsUiso (const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace); + +static void CorrectShell (const TopoDS_Shape& theShell, + const TopoDS_Face& theFace); + +static gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace, + const Standard_Boolean theIsNaturalRestrictions); + +static void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace, + const Standard_Real theAverageArea, + const Standard_Boolean theIsToAddFaces, + Standard_Integer& theNbExtremalFaces, + TopTools_MapOfShape& theExtremalFaces, + const std::vector> theFacesAndAreas, + const TopTools_DataMapOfShapeReal& theFaceAreaMap, + const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap, + TopoDS_Shape& theRes, + TopoDS_Shape& theGlobalRes, + TopTools_MapOfShape& theRemovedFaces); + //======================================================================= //function : CopyShape //purpose : @@ -883,6 +928,7 @@ void GetCount(const TopoDS_Shape& aS, GetCount(aSx, iCnt); } } + //======================================================================= //function : PntInFace //purpose : @@ -1004,3 +1050,592 @@ Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF, // return iErr; } + +//======================================================================= +//function : PointCloudInFace +//purpose : +//======================================================================= +Standard_Integer GEOMAlgo_AlgoTools::PointCloudInFace(const TopoDS_Face& theFace, + const int theNbPnts, + TopoDS_Compound& theCompound) +{ +#if OCC_VERSION_LARGE < 0x07050304 + return -1; +#else + ShapeUpgrade_ShapeDivideArea tool (theFace); + tool.SetSplittingByNumber (Standard_True); + tool.NbParts() = theNbPnts; + tool.Perform(); + TopoDS_Shape res = tool.Result(); + + BRep_Builder aBB; + TopoDS_Compound aGlobalRes; + aBB.MakeCompound (aGlobalRes); + + TopTools_IndexedMapOfShape aFaceMap; + TopExp::MapShapes (res, TopAbs_FACE, aFaceMap); + Standard_Integer aNbFaces = aFaceMap.Extent(); + + TopTools_IndexedDataMapOfShapeListOfShape aEFmap; + TopExp::MapShapesAndAncestors (res, TopAbs_EDGE, TopAbs_FACE, aEFmap); + + TopTools_MapOfShape aBiggestFaces, aSmallestFaces; + Standard_Boolean aUseTriangulation = Standard_True; + Standard_Boolean aSkipShared = Standard_False; + if (aNbFaces != theNbPnts) + { + Standard_Real aTotalArea = 0.; + std::vector > aFacesAndAreas (aNbFaces); + for (Standard_Integer ii = 1; ii <= aNbFaces; ii++) + { + GProp_GProps aProps; + BRepGProp::SurfaceProperties (aFaceMap(ii), aProps, aSkipShared, aUseTriangulation); + Standard_Real anArea = aProps.Mass(); + aTotalArea += anArea; + std::pair aFaceWithArea (aFaceMap(ii), anArea); + aFacesAndAreas[ii-1] = aFaceWithArea; + } + std::sort (aFacesAndAreas.begin(), aFacesAndAreas.end(), comp); + + Standard_Real anAverageArea = aTotalArea / theNbPnts; + + TopTools_DataMapOfShapeReal aFaceAreaMap; + for (Standard_Integer ii = 0; ii < aNbFaces; ii++) + aFaceAreaMap.Bind (aFacesAndAreas[ii].first, aFacesAndAreas[ii].second); + + TopTools_MapOfShape aRemovedFaces; + + if (aNbFaces < theNbPnts) + { + Standard_Integer aNbMissingFaces = theNbPnts - aNbFaces; + for (Standard_Integer ii = aNbFaces-1; ii > aNbFaces - aNbMissingFaces - 1; ii--) + aBiggestFaces.Add (aFacesAndAreas[ii].first); + + ModifyFacesForGlobalResult (theFace, anAverageArea, + Standard_True, //to add faces + aNbMissingFaces, aBiggestFaces, + aFacesAndAreas, aFaceAreaMap, aEFmap, + res, aGlobalRes, + aRemovedFaces); + } + else //aNbFaces > theNbPnts + { + Standard_Integer aNbExcessFaces = aNbFaces - theNbPnts; + for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++) + aSmallestFaces.Add (aFacesAndAreas[ii].first); + + TopTools_IndexedDataMapOfShapeListOfShape aVFmap; + TopExp::MapShapesAndAncestors (res, TopAbs_VERTEX, TopAbs_FACE, aVFmap); + + //Remove smallest faces with free boundaries + for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++) + { + const TopoDS_Face& aFace = TopoDS::Face (aFacesAndAreas[ii].first); + Standard_Boolean anIsFreeBoundFound = Standard_False; + TopExp_Explorer anExplo (aFace, TopAbs_EDGE); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + if (!BRep_Tool::Degenerated (anEdge) && + aEFmap.FindFromKey(anEdge).Extent() < 2) + { + anIsFreeBoundFound = Standard_True; + break; + } + } + if (anIsFreeBoundFound) + { + Standard_Real aMaxArea = 0.; + for (anExplo.Init(aFace, TopAbs_VERTEX); anExplo.More(); anExplo.Next()) + { + const TopoDS_Shape& aVertex = anExplo.Current(); + const TopTools_ListOfShape& aFaceList = aVFmap.FindFromKey (aVertex); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + Standard_Real anArea = aFaceAreaMap (anItl.Value()); + if (anArea > aMaxArea) + aMaxArea = anArea; + } + } + Standard_Real anArreaOfSmallestFace = aFaceAreaMap (aFace); + if (anArreaOfSmallestFace < aMaxArea / 16) + { + aBB.Remove (res, aFace); + aRemovedFaces.Add (aFace); + } + } + } + + ModifyFacesForGlobalResult (theFace, anAverageArea, + Standard_False, //to decrease number of faces + aNbExcessFaces, aSmallestFaces, + aFacesAndAreas, aFaceAreaMap, aEFmap, + res, aGlobalRes, + aRemovedFaces); + } + } + + aBB.Add (aGlobalRes, res); + + aBB.MakeCompound (theCompound); + for (TopExp_Explorer aGlobalExplo(aGlobalRes, TopAbs_FACE); aGlobalExplo.More(); aGlobalExplo.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aGlobalExplo.Current()); + Standard_Boolean anIsNaturalRestrictions = Standard_True; + TopExp_Explorer anExplo (aFace, TopAbs_EDGE); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + if (BRep_Tool::Degenerated (anEdge)) + continue; + if (!aEFmap.Contains(anEdge) || + aEFmap.FindFromKey(anEdge).Extent() < 2) + { + anIsNaturalRestrictions = Standard_False; + break; + } + } + + gp_Pnt aPnt = GetMidPnt2d (aFace, anIsNaturalRestrictions); + TopoDS_Vertex aVertex = BRepLib_MakeVertex (aPnt); + aBB.Add (theCompound, aVertex); + } + + return 0; +#endif +} + +Standard_Boolean comp(const std::pair& theA, + const std::pair& theB) +{ + return (theA.second < theB.second); +} + +Standard_Boolean IsUiso (const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace) +{ + BRepAdaptor_Curve2d aBAcurve2d (theEdge, theFace); + gp_Pnt2d aP2d; + gp_Vec2d aVec; + aBAcurve2d.D1 (aBAcurve2d.FirstParameter(), aP2d, aVec); + return (Abs(aVec.Y()) > Abs(aVec.X())); +} + +void CorrectShell (const TopoDS_Shape& theShell, + const TopoDS_Face& theFace) +{ + BRepAdaptor_Surface aBAsurf (theFace, Standard_False); + GeomAbs_SurfaceType aType = aBAsurf.GetType(); + if (aType <= GeomAbs_Torus) //elementary surfaces + return; + + TopLoc_Location anInputLoc; + const Handle(Geom_Surface)& anInputSurf = BRep_Tool::Surface (theFace, anInputLoc); + + BRep_Builder aBB; + + TopoDS_Iterator anIter (theShell); + for (; anIter.More(); anIter.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (anIter.Value()); + TopLoc_Location aLoc; + const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLoc); + if (aSurf == anInputSurf) + continue; + + TopExp_Explorer anExplo (aFace, TopAbs_EDGE); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + Standard_Real aFirst, aLast; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast); + aBB.UpdateEdge (anEdge, aPCurve, anInputSurf, anInputLoc, 0.); + } + Standard_Real aTol = BRep_Tool::Tolerance (aFace); + aBB.UpdateFace (aFace, anInputSurf, anInputLoc, aTol); + } +} + +gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace, + const Standard_Boolean theIsNaturalRestrictions) +{ + gp_Pnt aResPnt; + + if (theIsNaturalRestrictions) + { + BRepAdaptor_Surface aBAsurf (theFace); + Standard_Real aUmin, aUmax, aVmin, aVmax; + aUmin = aBAsurf.FirstUParameter(); + aUmax = aBAsurf.LastUParameter(); + aVmin = aBAsurf.FirstVParameter(); + aVmax = aBAsurf.LastVParameter(); + aResPnt = aBAsurf.Value ((aUmin + aUmax)/2, (aVmin + aVmax)/2); + } + else + { + const Standard_Integer aNbSamples = 4; + TopoDS_Wire aWire = BRepTools::OuterWire (theFace); + TopTools_IndexedMapOfShape aEmap; + TopExp::MapShapes (aWire, TopAbs_EDGE, aEmap); + Standard_Integer aNbPointsOnContour = aNbSamples * aEmap.Extent(); + TColgp_Array1OfPnt anArray (1, aNbPointsOnContour); + + BRepTools_WireExplorer aWexp (aWire, theFace); + Standard_Integer anInd = 0; + for (; aWexp.More(); aWexp.Next()) + { + const TopoDS_Edge& anEdge = aWexp.Current(); + BRepAdaptor_Curve2d aBAcurve2d (anEdge, theFace); + Standard_Real aDelta = (aBAcurve2d.LastParameter() - aBAcurve2d.FirstParameter())/aNbSamples; + for (Standard_Integer ii = 0; ii < aNbSamples; ii++) + { + Standard_Real aParam = aBAcurve2d.FirstParameter() + ii * aDelta; + gp_Pnt2d aP2d = aBAcurve2d.Value (aParam); + gp_Pnt aPnt (aP2d.X(), aP2d.Y(), 0.); + anArray (++anInd) = aPnt; + } + } + + gp_Ax2 anAxis; + Standard_Boolean anIsSingular; + GeomLib::AxeOfInertia (anArray, anAxis, anIsSingular); + gp_Pnt aBaryCentre = anAxis.Location(); + gp_Pnt2d aCentre2d (aBaryCentre.X(), aBaryCentre.Y()); + BRepTopAdaptor_FClass2d aClassifier (theFace, Precision::Confusion()); + BRepAdaptor_Surface aBAsurf (theFace, Standard_False); + + TopAbs_State aStatus = aClassifier.Perform (aCentre2d); + gp_Pnt2d aP2d = aCentre2d; + Standard_Integer anIndVertex = 0; + const Standard_Integer aNbIter = 10; + while (aStatus != TopAbs_IN && anIndVertex < aNbPointsOnContour) + { + gp_Pnt aVertexPnt = anArray (anIndVertex+1); + gp_Pnt2d aVertexP2d (aVertexPnt.X(), aVertexPnt.Y()); + TColgp_SequenceOfPnt2d aPseq; + aPseq.Append (aCentre2d); + aPseq.Append (aVertexP2d); + for (Standard_Integer ii = 1; ii <= aNbIter; ii++) + { + for (Standard_Integer jj = 1; jj < aPseq.Length(); jj++) + { + aP2d.SetXY ((aPseq(jj).XY() + aPseq(jj+1).XY())/2); + aStatus = aClassifier.Perform (aP2d); + if (aStatus == TopAbs_IN) + break; + else + { + aPseq.InsertAfter (jj, aP2d); + jj++; + } + } + if (aStatus == TopAbs_IN) + break; + } + anIndVertex += aNbSamples; + } + aResPnt = aBAsurf.Value (aP2d.X(), aP2d.Y()); + } //case of complex boundaries + + return aResPnt; +} + +void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace, + const Standard_Real theAverageArea, + const Standard_Boolean theIsToAddFaces, + Standard_Integer& theNbExtremalFaces, + TopTools_MapOfShape& theExtremalFaces, + const std::vector> theFacesAndAreas, + const TopTools_DataMapOfShapeReal& theFaceAreaMap, + const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap, + TopoDS_Shape& theRes, + TopoDS_Shape& theGlobalRes, + TopTools_MapOfShape& theRemovedFaces) +{ + BRep_Builder aBB; + const Standard_Integer aNbFaces = (Standard_Integer) theFacesAndAreas.size(); + + const Standard_Integer aDiff = theNbExtremalFaces - theRemovedFaces.Extent(); + + Standard_Integer aSum = 0; + while (aSum < aDiff) //global loop + { + Standard_Integer aNbFacesDone = 0, aNbFacesInTape = 0; + TopoDS_Face aStartFace; + + Standard_Integer aStartIndex = (theIsToAddFaces)? aNbFaces-1 : 0; + Standard_Integer anEndIndex = (theIsToAddFaces)? 0 : aNbFaces-1; + Standard_Integer aStep = (theIsToAddFaces)? -1 : 1; + + for (Standard_Integer ii = aStartIndex; ii != anEndIndex; ii += aStep) + { + const TopoDS_Face& aFace = TopoDS::Face (theFacesAndAreas[ii].first); + if (!theRemovedFaces.Contains(aFace)) + { + aStartFace = aFace; + break; + } + } + if (aStartFace.IsNull()) + break; + + theRemovedFaces.Add (aStartFace); + + TopoDS_Edge aCommonEdge; + TopoDS_Face aNextFace; + Standard_Real anExtremalArea = (theIsToAddFaces)? 0. : Precision::Infinite(); + for (TopExp_Explorer anExplo(aStartFace, TopAbs_EDGE); anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (anItl.Value()); + if (aFace.IsSame (aStartFace) || + theRemovedFaces.Contains(aFace)) + continue; + Standard_Real anArea = theFaceAreaMap(aFace); + Standard_Boolean anIsToExchange = (theIsToAddFaces)? (anArea > anExtremalArea) : (anArea < anExtremalArea); + if (anIsToExchange) + { + anExtremalArea = anArea; + aCommonEdge = anEdge; + aNextFace = aFace; + } + } + } + if (aCommonEdge.IsNull()) //all adjacent faces are already removed + { + theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first); + theNbExtremalFaces++; + continue; + } + + //Start filling the shell + aBB.Remove (theRes, aStartFace); + aNbFacesDone++; + TopoDS_Shell aShell; + aBB.MakeShell (aShell); + Standard_Real anAreaOfTape = 0.; + aBB.Add (aShell, aStartFace); + aNbFacesInTape++; + anAreaOfTape += theFaceAreaMap (aStartFace); + + Standard_Boolean anIsUiso = IsUiso (aCommonEdge, aStartFace); + //Find another faces on this level + TopoDS_Face aCurrentFace = aNextFace; + TopoDS_Edge aCurrentEdge = aCommonEdge; + Standard_Boolean anIsFirstDirection = Standard_True; + aBB.Remove (theRes, aCurrentFace); + theRemovedFaces.Add (aCurrentFace); + if (theExtremalFaces.Contains (aCurrentFace)) + { + aNbFacesDone++; + } + aBB.Add (aShell, aCurrentFace); + aNbFacesInTape++; + anAreaOfTape += theFaceAreaMap (aCurrentFace); + Standard_Boolean anIsRound = Standard_False; + for (;;) //local loop + { + TopoDS_Edge aNextEdge; + for (TopExp_Explorer anExplo(aCurrentFace, TopAbs_EDGE); anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + if (anEdge.IsSame (aCurrentEdge)) + continue; + const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (anItl.Value()); + if (aFace.IsSame (aCurrentFace)) + continue; + if (aFace.IsSame (aStartFace)) + { + anIsRound = Standard_True; + break; + } + if (theRemovedFaces.Contains(aFace)) + continue; + if (anIsUiso == IsUiso (anEdge, aFace)) + { + aNextEdge = anEdge; + aNextFace = aFace; + break; + } + } + if (anIsRound || !aNextEdge.IsNull()) + break; + } + if (anIsRound) //round tape: returned to start face + break; + if (aNextEdge.IsNull()) + { + if (anIsFirstDirection) + { + aCurrentFace = aStartFace; + aCurrentEdge = aCommonEdge; + anIsFirstDirection = Standard_False; + continue; + } + else + break; + } + + aBB.Add (aShell, aNextFace); + aNbFacesInTape++; + anAreaOfTape += theFaceAreaMap (aNextFace); + aBB.Remove (theRes, aNextFace); + theRemovedFaces.Add (aNextFace); + if (theExtremalFaces.Contains (aNextFace)) + { + aNbFacesDone++; + } + aCurrentEdge = aNextEdge; + aNextEdge.Nullify(); + aCurrentFace = aNextFace; + } //end of local loop + + //Tape is formed + Standard_Integer aNumberToSplit = (theIsToAddFaces)? aNbFacesInTape + aNbFacesDone : aNbFacesInTape - aNbFacesDone; + if (!theIsToAddFaces && aNbFacesDone > 1) + { + Standard_Integer aRealNumberToSplit = (aNumberToSplit > 0)? aNumberToSplit : 1; + Standard_Real anAverageAreaInTape = anAreaOfTape / aRealNumberToSplit; + if (anAverageAreaInTape > theAverageArea) + { + Standard_Integer aNewNumberToSplit = RealToInt(round(anAreaOfTape / theAverageArea)); + if (aNewNumberToSplit < aNbFacesInTape) + { + Standard_Integer aNumberToIncrease = aNewNumberToSplit - aNumberToSplit; + for (Standard_Integer jj = theNbExtremalFaces; jj < theNbExtremalFaces + aNumberToIncrease; jj++) + theExtremalFaces.Add (theFacesAndAreas[jj].first); + theNbExtremalFaces += aNumberToIncrease; + aNumberToSplit = aNewNumberToSplit; + } + } + } + if (anIsRound && aNumberToSplit <= 1) + { + Standard_Integer aNumberToIncrease = 3 - aNumberToSplit; + for (Standard_Integer jj = theNbExtremalFaces; jj < theNbExtremalFaces + aNumberToIncrease; jj++) + theExtremalFaces.Add (theFacesAndAreas[jj].first); + theNbExtremalFaces += aNumberToIncrease; + aNumberToSplit = 3; + } + CorrectShell (aShell, theInputFace); + ShapeUpgrade_UnifySameDomain aUnifier; + aUnifier.Initialize (aShell, Standard_True, Standard_True); + aUnifier.Build(); + TopoDS_Shape aUnifiedShape = aUnifier.Shape(); + //Splitting + TopoDS_Shape aLocalResult = aUnifiedShape; + Standard_Integer aNbFacesInLocalResult; + if (aNumberToSplit > 1) + { +#if OCC_VERSION_LARGE < 0x07050304 + aNbFacesInLocalResult = 0; +#else + ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape); + aLocalTool.SetSplittingByNumber (Standard_True); + aLocalTool.MaxArea() = -1; + if (anIsUiso) + aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1); + else + aLocalTool.SetNumbersUVSplits (1, aNumberToSplit); + aLocalTool.Perform(); + aLocalResult = aLocalTool.Result(); + aNbFacesInLocalResult = aNumberToSplit; +#endif + } + else + { + aNbFacesInLocalResult = 1; + if (aNumberToSplit == 0) + { + theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first); + theNbExtremalFaces++; + } + } + aBB.Add (theGlobalRes, aLocalResult); + + aSum += Abs(aNbFacesInTape - aNbFacesInLocalResult); + } //end of global loop + + //Second global loop + TopoDS_Compound aSecondComp; + aBB.MakeCompound (aSecondComp); + while (aSum < aDiff) + { + TopoDS_Shape aMaxShell; + Standard_Integer aMaxNbFaces = 0; + TopoDS_Iterator anIter (theGlobalRes); + for (; anIter.More(); anIter.Next()) + { + const TopoDS_Shape& aShell = anIter.Value(); + TopTools_IndexedMapOfShape aFaceMap; + TopExp::MapShapes (aShell, TopAbs_FACE, aFaceMap); + if (aFaceMap.Extent() > aMaxNbFaces) + { + aMaxNbFaces = aFaceMap.Extent(); + aMaxShell = aShell; + } + } + + if (aMaxNbFaces == 1) + break; + + aBB.Remove (theGlobalRes, aMaxShell); + //Find iso + Standard_Boolean anIsUiso = Standard_True; + TopTools_IndexedDataMapOfShapeListOfShape aLocalEFmap; + TopExp::MapShapesAndAncestors (aMaxShell, TopAbs_EDGE, TopAbs_FACE, aLocalEFmap); + for (Standard_Integer jj = 1; jj <= aLocalEFmap.Extent(); jj++) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (aLocalEFmap.FindKey(jj)); + const TopTools_ListOfShape& aFaceList = aLocalEFmap(jj); + if (aFaceList.Extent() == 2) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceList.First()); + anIsUiso = IsUiso (anEdge, aFace); + break; + } + } + CorrectShell (aMaxShell, theInputFace); + ShapeUpgrade_UnifySameDomain aUnifier; + aUnifier.Initialize (aMaxShell, Standard_True, Standard_True); + aUnifier.Build(); + TopoDS_Shape aUnifiedShape = aUnifier.Shape(); + TopoDS_Shape aLocalResult = aUnifiedShape; + + Standard_Integer aNumberToSplit = (theIsToAddFaces)? aMaxNbFaces + (aDiff-aSum) : aMaxNbFaces - (aDiff-aSum); + if (aNumberToSplit > 1) + { +#if OCC_VERSION_LARGE < 0x07050304 + aNumberToSplit = 1; +#else + ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape); + aLocalTool.SetSplittingByNumber (Standard_True); + aLocalTool.MaxArea() = -1; + if (anIsUiso) + aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1); + else + aLocalTool.SetNumbersUVSplits (1, aNumberToSplit); + aLocalTool.Perform(); + aLocalResult = aLocalTool.Result(); +#endif + } + else + aNumberToSplit = 1; + + aBB.Add (aSecondComp, aLocalResult); + + if (theIsToAddFaces) + break; + aSum += aMaxNbFaces - aNumberToSplit; + } + aBB.Add (theGlobalRes, aSecondComp); +}