]> OCCT Git - occt.git/commitdiff
0032999: Modeling Algorithms - New option in ShapeUpgrade_ShapeDivide algorithm:...
authorjgv <jgv@opencascade.com>
Sat, 30 Apr 2022 20:05:07 +0000 (23:05 +0300)
committersmoskvin <smoskvin@opencascade.com>
Thu, 30 Jun 2022 16:33:34 +0000 (19:33 +0300)
1. Multiple changes in ShapeUpgrade_ShapeDivideArea, ShapeUpgrade_FaceDivide, ShapeUpgrade_FaceDivideArea, ShapeUpgrade_SplitSurface, ShapeUpgrade_SplitSurfaceArea: new methods NbParts and SetSplittingByNumber, changes in ShapeUpgrade_FaceDivideArea::Perform and ShapeUpgrade_SplitSurfaceArea::Compute concerning new modes of splitting.
2. New Draw command "DT_SplitByNumber" for testing new modes of splitting.
3. New subgroups "split_number" and "split_two_numbers" in the group of tests "heal" for testing new modes of splitting.

45 files changed:
src/SWDRAW/SWDRAW_ShapeUpgrade.cxx
src/ShapeUpgrade/ShapeUpgrade_ClosedFaceDivide.cxx
src/ShapeUpgrade/ShapeUpgrade_ClosedFaceDivide.hxx
src/ShapeUpgrade/ShapeUpgrade_FaceDivide.cxx
src/ShapeUpgrade/ShapeUpgrade_FaceDivide.hxx
src/ShapeUpgrade/ShapeUpgrade_FaceDivideArea.cxx
src/ShapeUpgrade/ShapeUpgrade_FaceDivideArea.hxx
src/ShapeUpgrade/ShapeUpgrade_FaceDivideArea.lxx
src/ShapeUpgrade/ShapeUpgrade_ShapeDivideArea.cxx
src/ShapeUpgrade/ShapeUpgrade_ShapeDivideArea.hxx
src/ShapeUpgrade/ShapeUpgrade_ShapeDivideArea.lxx
src/ShapeUpgrade/ShapeUpgrade_SplitSurface.cxx
src/ShapeUpgrade/ShapeUpgrade_SplitSurface.hxx
src/ShapeUpgrade/ShapeUpgrade_SplitSurfaceArea.cxx
src/ShapeUpgrade/ShapeUpgrade_SplitSurfaceArea.hxx
src/ShapeUpgrade/ShapeUpgrade_SplitSurfaceArea.lxx
tests/heal/grids.list
tests/heal/split_number/A1 [new file with mode: 0644]
tests/heal/split_number/A2 [new file with mode: 0644]
tests/heal/split_number/A3 [new file with mode: 0644]
tests/heal/split_number/A4 [new file with mode: 0644]
tests/heal/split_number/A5 [new file with mode: 0644]
tests/heal/split_number/A6 [new file with mode: 0644]
tests/heal/split_number/A7 [new file with mode: 0644]
tests/heal/split_number/A8 [new file with mode: 0644]
tests/heal/split_number/B1 [new file with mode: 0644]
tests/heal/split_number/B2 [new file with mode: 0644]
tests/heal/split_number/B3 [new file with mode: 0644]
tests/heal/split_number/B4 [new file with mode: 0644]
tests/heal/split_number/B5 [new file with mode: 0644]
tests/heal/split_number/B6 [new file with mode: 0644]
tests/heal/split_number/C1 [new file with mode: 0644]
tests/heal/split_number/C2 [new file with mode: 0644]
tests/heal/split_number/D1 [new file with mode: 0644]
tests/heal/split_number/D2 [new file with mode: 0644]
tests/heal/split_number/end [new file with mode: 0644]
tests/heal/split_two_numbers/A1 [new file with mode: 0644]
tests/heal/split_two_numbers/A2 [new file with mode: 0644]
tests/heal/split_two_numbers/A3 [new file with mode: 0644]
tests/heal/split_two_numbers/A4 [new file with mode: 0644]
tests/heal/split_two_numbers/B1 [new file with mode: 0644]
tests/heal/split_two_numbers/B2 [new file with mode: 0644]
tests/heal/split_two_numbers/B3 [new file with mode: 0644]
tests/heal/split_two_numbers/B4 [new file with mode: 0644]
tests/heal/split_two_numbers/end [new file with mode: 0644]

index e0d534deede73b933c9e6d3e6929e310de059be9..f2a94082d7d9d06fb716ab605cfc4b6c78ec239f 100644 (file)
@@ -1190,6 +1190,52 @@ static Standard_Integer splitarea (Draw_Interpretor& di,
   return 0;
 }
 
+static Standard_Integer splitbynumber (Draw_Interpretor& di, 
+                                       Standard_Integer argc, 
+                                       const char** argv)
+{
+  if (argc < 4) {
+    di << "bad number of arguments\n";
+    return 1;
+  }
+  
+  TopoDS_Shape inputShape=DBRep::Get(argv[2], TopAbs_FACE);
+  if (inputShape.IsNull()) {
+    di << "Unknown face\n";
+    return 1;
+  }
+  
+  Standard_Integer aNbParts, aNumber1 = 0, aNumber2 = 0;
+  aNbParts = aNumber1 = Draw::Atoi (argv[3]);
+  if (argc > 4)
+    aNumber2 = Draw::Atoi (argv[4]);
+  
+  if (argc == 4 && aNbParts <= 0)
+  {
+    di << "Incorrect number of parts\n";
+    return 1;
+  }
+  if (argc == 5 &&
+      (aNumber1 <= 0 || aNumber2 <= 0))
+  {
+    di << "Incorrect numbers in U or V\n";
+    return 1;
+  }
+    
+  ShapeUpgrade_ShapeDivideArea tool (inputShape);
+  tool.SetSplittingByNumber (Standard_True);
+  if (argc == 4)
+    tool.NbParts() = aNbParts;
+  else
+    tool.SetNumbersUVSplits (aNumber1, aNumber2);
+  tool.Perform();
+  TopoDS_Shape res = tool.Result();
+  
+  ShapeFix::SameParameter ( res, Standard_False );
+  DBRep::Set ( argv[1], res );
+  return 0;
+}
+
 static Standard_Integer removeinternalwires (Draw_Interpretor& di, 
                                              Standard_Integer argc, 
                                              const char** argv)
@@ -1624,6 +1670,8 @@ static Standard_Integer reshape(Draw_Interpretor& /*theDI*/,
                   __FILE__,splitclosed,g);
   theCommands.Add ("DT_SplitByArea","result shape maxarea [preci]",
                   __FILE__,splitarea,g);
+  theCommands.Add ("DT_SplitByNumber","result face number [number2]",
+                   __FILE__,splitbynumber,g);
   
   theCommands.Add ("RemoveIntWires","result minarea wholeshape [faces or wires] [moderemoveface ]",
                    __FILE__,removeinternalwires,g);
index 332a87e3eaab25fc158f7db1f7ba3143f375e982..5f06125da1dbe13606aa3c5153cb94f912f0326b 100644 (file)
@@ -67,7 +67,7 @@ ShapeUpgrade_ClosedFaceDivide::ShapeUpgrade_ClosedFaceDivide(const TopoDS_Face&
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean ShapeUpgrade_ClosedFaceDivide::SplitSurface()
+Standard_Boolean ShapeUpgrade_ClosedFaceDivide::SplitSurface(const Standard_Real)
 {
   Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool();
   if ( SplitSurf.IsNull() ) return Standard_False;
index 71cc375834d150b80780ae1a89215991ac9f033f..ca5d97cacd5bccc51277a7431fd5d9e5fc510d73 100644 (file)
@@ -44,7 +44,7 @@ public:
   
   //! Performs splitting of surface and computes the shell
   //! from source face.
-  Standard_EXPORT virtual Standard_Boolean SplitSurface() Standard_OVERRIDE;
+  Standard_EXPORT virtual Standard_Boolean SplitSurface(const Standard_Real theArea = 0.) Standard_OVERRIDE;
   
   //! Sets the number of cutting lines by which closed face will be split.
   //! The resulting faces will be num+1.
index e27af14a5f91addb390b1865eec39bd8418cb3b4..39249cc8d65236218c112e5ad657288124769abc 100644 (file)
@@ -92,12 +92,12 @@ void ShapeUpgrade_FaceDivide::SetSurfaceSegmentMode(const Standard_Boolean Segme
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean ShapeUpgrade_FaceDivide::Perform ()
+Standard_Boolean ShapeUpgrade_FaceDivide::Perform (const Standard_Real theArea)
 {
   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
   if ( myFace.IsNull() ) return Standard_False;
   myResult = myFace;
-  SplitSurface();
+  SplitSurface (theArea);
   SplitCurves();
   return Status ( ShapeExtend_DONE );
  } 
@@ -107,7 +107,7 @@ Standard_Boolean ShapeUpgrade_FaceDivide::Perform ()
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean ShapeUpgrade_FaceDivide::SplitSurface ()  
+Standard_Boolean ShapeUpgrade_FaceDivide::SplitSurface (const Standard_Real theArea)
 {  
   Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool();
   if ( SplitSurf.IsNull() ) return Standard_False;
@@ -144,7 +144,7 @@ Standard_Boolean ShapeUpgrade_FaceDivide::SplitSurface ()
     if (Vl < aSVl) Vl += Min(dV, aSVl - Vl);
   }
 
-  SplitSurf->Init ( surf, Uf, Ul, Vf, Vl );
+  SplitSurf->Init (surf, Uf, Ul, Vf, Vl, theArea);
   SplitSurf->Perform(mySegmentMode);
 
   // If surface was neither split nor modified, do nothing
index 9db1c508543101595a2e12bdbc21c9474ab01cc2..d07744a1ef1b90cfabdd65a726c15ecc5b2983de 100644 (file)
@@ -72,11 +72,17 @@ public:
   //! The context is used to keep track of former splittings
   //! in order to keep sharings. It is updated according to
   //! modifications made.
-  Standard_EXPORT virtual Standard_Boolean Perform();
+  //! The optional argument <theArea> is used to initialize
+  //! the tool for splitting surface in the case of
+  //! splitting into N parts where N is user-defined.
+  Standard_EXPORT virtual Standard_Boolean Perform(const Standard_Real theArea = 0.);
   
   //! Performs splitting of surface and computes the shell
   //! from source face.
-  Standard_EXPORT virtual Standard_Boolean SplitSurface();
+  //! The optional argument <theArea> is used to initialize
+  //! the tool for splitting surface in the case of
+  //! splitting into N parts where N is user-defined.
+  Standard_EXPORT virtual Standard_Boolean SplitSurface(const Standard_Real theArea = 0.);
   
   //! Performs splitting of curves of all the edges in the
   //! shape and divides these edges.
index 6399d63da32565b37b457c4ca724590447662f19..03ca53df1f4c413e3903ddb4e637feb404f03465 100644 (file)
@@ -35,6 +35,9 @@ IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_FaceDivideArea,ShapeUpgrade_FaceDivide)
 ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea()
 {
   myMaxArea = Precision::Infinite();
+  myNbParts = 0;
+  myUnbSplit = myVnbSplit = -1;
+  myIsSplittingByNumber = Standard_False;
   SetPrecision(1.e-5);
   SetSplitSurfaceTool (new ShapeUpgrade_SplitSurfaceArea);
 }
@@ -47,6 +50,9 @@ ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea()
 ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea(const TopoDS_Face& F)
 {
   myMaxArea = Precision::Infinite();
+  myNbParts = 0;
+  myUnbSplit = myVnbSplit = -1;
+  myIsSplittingByNumber = Standard_False;
   SetPrecision(1.e-5);
   SetSplitSurfaceTool (new ShapeUpgrade_SplitSurfaceArea);
   Init(F);
@@ -57,54 +63,74 @@ ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea(const TopoDS_Face& F)
 //purpose  : 
 //=======================================================================
 
- Standard_Boolean ShapeUpgrade_FaceDivideArea::Perform() 
+ Standard_Boolean ShapeUpgrade_FaceDivideArea::Perform(const Standard_Real
 {
   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
   GProp_GProps aGprop;
-  
+
   BRepGProp::SurfaceProperties(myFace,aGprop,Precision());
   Standard_Real anArea = aGprop.Mass();
+
+  Standard_Integer anbParts = 0;
+  if (myMaxArea == -1)
+  {
+    anbParts = myNbParts;
+    myMaxArea = anArea / anbParts;
+  }
+  
   if((anArea - myMaxArea) < Precision::Confusion())
     return Standard_False;
-  Standard_Integer anbParts = RealToInt(ceil(anArea/myMaxArea));
+
+  if (anbParts == 0)
+    anbParts = RealToInt(ceil(anArea/myMaxArea));
+  
   Handle(ShapeUpgrade_SplitSurfaceArea) aSurfTool= Handle(ShapeUpgrade_SplitSurfaceArea)::
     DownCast(GetSplitSurfaceTool ());
   if(aSurfTool.IsNull())
     return Standard_False;
   aSurfTool->NbParts() = anbParts;
-  if(!ShapeUpgrade_FaceDivide::Perform())
+  if (myIsSplittingByNumber)
+  {
+    aSurfTool->SetSplittingIntoSquares(Standard_True);
+    aSurfTool->SetNumbersUVSplits (myUnbSplit, myVnbSplit);
+  }
+  if (!ShapeUpgrade_FaceDivide::Perform (anArea))
     return Standard_False;
   
   TopoDS_Shape aResult = Result();
   if(aResult.ShapeType() == TopAbs_FACE)
     return Standard_False;
   Standard_Integer aStatus = myStatus;
-  TopExp_Explorer aExpF(aResult,TopAbs_FACE);
-  TopoDS_Shape aCopyRes = aResult.EmptyCopied();
-  
-  Standard_Boolean isModified = Standard_False;
-  for( ; aExpF.More() ; aExpF.Next()) {
-    TopoDS_Shape aSh = Context()->Apply(aExpF.Current());
-    TopoDS_Face aFace = TopoDS::Face(aSh);
-    Init(aFace);
-    BRep_Builder aB;
-    if(Perform()) {
-      isModified = Standard_True;
-      TopoDS_Shape aRes = Result();
-      TopExp_Explorer aExpR(aRes,TopAbs_FACE);
-      for( ; aExpR.More(); aExpR.Next())
-        aB.Add(aCopyRes,aExpR.Current());
-    }
-    else
-      aB.Add(aCopyRes,aFace);
-  }
-  if(isModified)
+
+  if (!myIsSplittingByNumber)
   {
-    if (aCopyRes.ShapeType() == TopAbs_WIRE || aCopyRes.ShapeType() == TopAbs_SHELL)
-      aCopyRes.Closed (BRep_Tool::IsClosed (aCopyRes));
-    Context()->Replace(aResult,aCopyRes);
+    TopExp_Explorer aExpF(aResult,TopAbs_FACE);
+    TopoDS_Shape aCopyRes = aResult.EmptyCopied();
+    
+    Standard_Boolean isModified = Standard_False;
+    for( ; aExpF.More() ; aExpF.Next()) {
+      TopoDS_Shape aSh = Context()->Apply(aExpF.Current());
+      TopoDS_Face aFace = TopoDS::Face(aSh);
+      Init(aFace);
+      BRep_Builder aB;
+      if(Perform()) {
+        isModified = Standard_True;
+        TopoDS_Shape aRes = Result();
+        TopExp_Explorer aExpR(aRes,TopAbs_FACE);
+        for( ; aExpR.More(); aExpR.Next())
+          aB.Add(aCopyRes,aExpR.Current());
+      }
+      else
+        aB.Add(aCopyRes,aFace);
+    }
+    if(isModified)
+    {
+      if (aCopyRes.ShapeType() == TopAbs_WIRE || aCopyRes.ShapeType() == TopAbs_SHELL)
+        aCopyRes.Closed (BRep_Tool::IsClosed (aCopyRes));
+      Context()->Replace(aResult,aCopyRes);
+    }
   }
+  
   myStatus |= aStatus;  
   myResult = Context()->Apply ( aResult );
   return Status ( ShapeExtend_DONE ); 
index bfb3d1b62f17aa8599285603f9f68070c95f6c95..3595c165855e48125698b72f571422cd27bd072c 100644 (file)
@@ -40,12 +40,24 @@ public:
   
   //! Performs splitting and computes the resulting shell
   //! The context is used to keep track of former splittings
-  Standard_EXPORT virtual Standard_Boolean Perform() Standard_OVERRIDE;
+  Standard_EXPORT virtual Standard_Boolean Perform(const Standard_Real theArea = 0.) Standard_OVERRIDE;
   
   //! Set max area allowed for faces
     Standard_Real& MaxArea();
 
+  //! Set number of parts expected
+    Standard_Integer& NbParts();
 
+  //! Set fixed numbers of splits in U and V directions.
+  //! Only for "Splitting By Numbers" mode
+    void SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+                            const Standard_Integer theNbVsplits);
+  
+  //! Set splitting mode
+  //! If the mode is "splitting by number",
+  //! the face is splitted approximately into <myNbParts> parts,
+  //! the parts are similar to squares in 2D.
+    void SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber);
 
 
   DEFINE_STANDARD_RTTIEXT(ShapeUpgrade_FaceDivideArea,ShapeUpgrade_FaceDivide)
@@ -59,7 +71,10 @@ private:
 
 
   Standard_Real myMaxArea;
-
+  Standard_Integer myNbParts;
+  Standard_Integer myUnbSplit;
+  Standard_Integer myVnbSplit;
+  Standard_Boolean myIsSplittingByNumber;
 
 };
 
index 8bdf0388b39a1f901963f6979b6dbc29159114c1..9d16e772437f1df68c11bdd43b3d759035df5146 100644 (file)
@@ -17,3 +17,21 @@ inline Standard_Real& ShapeUpgrade_FaceDivideArea::MaxArea()
 }
 
  
+inline Standard_Integer& ShapeUpgrade_FaceDivideArea::NbParts() 
+{
+  return myNbParts;
+}
+
+inline void ShapeUpgrade_FaceDivideArea::SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber)
+{
+  myIsSplittingByNumber = theIsSplittingByNumber;
+}
+
+inline void ShapeUpgrade_FaceDivideArea::SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+                                                            const Standard_Integer theNbVsplits)
+{
+  myUnbSplit = theNbUsplits;
+  myVnbSplit = theNbVsplits;
+  if (myUnbSplit > 0 && myVnbSplit > 0)
+    myNbParts  = myUnbSplit * myVnbSplit;
+}
index 2cb65e31918c4d89d94fc789247eec4e21856948..0e9ac2917e864f5d1ed220506db59eb2e9e9ce43 100644 (file)
@@ -26,6 +26,9 @@ ShapeUpgrade_ShapeDivideArea::ShapeUpgrade_ShapeDivideArea():
        ShapeUpgrade_ShapeDivide()
 {
   myMaxArea = Precision::Infinite();
+  myNbParts = 0;
+  myUnbSplit = myVnbSplit = -1;
+  myIsSplittingByNumber = Standard_False;
 }
 
 //=======================================================================
@@ -38,6 +41,9 @@ ShapeUpgrade_ShapeDivideArea::ShapeUpgrade_ShapeDivideArea(const TopoDS_Shape& S
        
 {
   myMaxArea = Precision::Infinite();
+  myNbParts = 0;
+  myUnbSplit = myVnbSplit = -1;
+  myIsSplittingByNumber = Standard_False;
 }
 
 //=======================================================================
@@ -49,6 +55,9 @@ ShapeUpgrade_ShapeDivideArea::ShapeUpgrade_ShapeDivideArea(const TopoDS_Shape& S
 {
   Handle(ShapeUpgrade_FaceDivideArea) aFaceTool = new ShapeUpgrade_FaceDivideArea;
   aFaceTool->MaxArea() = myMaxArea;
+  aFaceTool->NbParts() = myNbParts;
+  aFaceTool->SetNumbersUVSplits (myUnbSplit, myVnbSplit);
+  aFaceTool->SetSplittingByNumber (myIsSplittingByNumber);
   return aFaceTool;
 }
 
index cf0b13674b59ac5ad4712252349e7f1594174f37..18aeacc50699d76114b106331c4ed6c4541a9c5a 100644 (file)
@@ -41,7 +41,20 @@ public:
   //! Set max area allowed for faces
     Standard_Real& MaxArea();
 
-
+  //! Set number of parts expected
+  //! for the case of splitting by number
+    Standard_Integer& NbParts();
+
+  //! Set fixed numbers of splits in U and V directions.
+  //! Only for "Splitting By Numbers" mode
+    void SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+                            const Standard_Integer theNbVsplits);
+  
+  //! Set splitting mode
+  //! If the mode is "splitting by number",
+  //! the face is splitted approximately into <myNbParts> parts,
+  //! the parts are similar to squares in 2D.
+    void SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber);
 
 
 protected:
@@ -57,8 +70,11 @@ private:
 
 
 
-  Standard_Real myMaxArea;
-
+  Standard_Real    myMaxArea;
+  Standard_Integer myNbParts;
+  Standard_Integer myUnbSplit;
+  Standard_Integer myVnbSplit;
+  Standard_Boolean myIsSplittingByNumber;
 
 };
 
index a3340b0c13b9b74f9a871b92c57aca16c14c315a..fb1230d8bd3f54c737f24312587d6f48d87037a3 100644 (file)
@@ -16,4 +16,25 @@ inline Standard_Real& ShapeUpgrade_ShapeDivideArea::MaxArea()
   return myMaxArea;
 }
 
+inline Standard_Integer& ShapeUpgrade_ShapeDivideArea::NbParts() 
+{
+  return myNbParts;
+}
+
+inline void ShapeUpgrade_ShapeDivideArea::SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber)
+{
+  myIsSplittingByNumber = theIsSplittingByNumber;
+  if (myIsSplittingByNumber)
+    myMaxArea = -1;
+}
  
+inline void ShapeUpgrade_ShapeDivideArea::SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+                                                             const Standard_Integer theNbVsplits)
+{
+  myIsSplittingByNumber = Standard_True;
+  myMaxArea = -1;
+  myUnbSplit = theNbUsplits;
+  myVnbSplit = theNbVsplits;
+  if (myUnbSplit > 0 && myVnbSplit > 0)
+    myNbParts  = myUnbSplit * myVnbSplit;
+}
index f5b5180ac4d6fe71a1bcafdc16e30bf1541227b3..9bac8b4458621b405dfd8be9bc7e2a95c8cece23 100644 (file)
 #include <TColGeom_HArray2OfSurface.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HSequenceOfReal.hxx>
+#include <TopoDS_Edge.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_SplitSurface,Standard_Transient)
 
@@ -79,8 +83,10 @@ void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S)
 //purpose  : 
 //=======================================================================
 
-void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S, const Standard_Real UFirst,const Standard_Real ULast,
-                                    const Standard_Real VFirst, const Standard_Real VLast)
+void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S,
+                                     const Standard_Real UFirst, const Standard_Real ULast,
+                                    const Standard_Real VFirst, const Standard_Real VLast,
+                                     const Standard_Real theArea)
 {
   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
   
@@ -92,6 +98,8 @@ void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S, const Standa
   myNbResultingRow =1;
   myNbResultingCol =1;
 
+  myArea = theArea;
+
   Standard_Real U1,U2,V1,V2;
   mySurface->Bounds(U1,U2,V1,V2);
   Standard_Real precision = Precision::PConfusion();
@@ -116,6 +124,24 @@ void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S, const Standa
     VF = Max(V1,VFirst);
     VL = Min(V2,VLast);
   }
+
+  if (myArea != 0.)
+  {
+    //<myArea> is set and will be used with <myUsize> and <myVsize>
+    //in further computations
+    Standard_Real Umid = (UF + UL)/2, Vmid = (VF + VL)/2;
+    Handle (Geom_RectangularTrimmedSurface) aTrSurf =
+      new Geom_RectangularTrimmedSurface (mySurface, UF, UL, VF, VL);
+    Handle(Geom_Curve) anUiso = aTrSurf->UIso (Umid);
+    Handle(Geom_Curve) aViso  = aTrSurf->VIso (Vmid);
+    TopoDS_Edge anEdgeUiso = BRepLib_MakeEdge (anUiso);
+    TopoDS_Edge anEdgeViso = BRepLib_MakeEdge (aViso);
+    GProp_GProps aGprop1, aGprop2;
+    BRepGProp::LinearProperties (anEdgeViso, aGprop1);
+    myUsize = aGprop1.Mass();
+    BRepGProp::LinearProperties (anEdgeUiso, aGprop2);
+    myVsize = aGprop2.Mass();
+  }
   
   if(UL-UF < precision) {
     Standard_Real p2 = precision/2.;
index 15c8f80f65bf9f599888cc566b29bfaf74489a35..61f726b1451a2570549d39c6863d4675a7f3bccc 100644 (file)
@@ -49,7 +49,10 @@ public:
   Standard_EXPORT void Init (const Handle(Geom_Surface)& S);
   
   //! Initializes with single supporting surface with bounding parameters.
-  Standard_EXPORT void Init (const Handle(Geom_Surface)& S, const Standard_Real UFirst, const Standard_Real ULast, const Standard_Real VFirst, const Standard_Real VLast);
+  Standard_EXPORT void Init (const Handle(Geom_Surface)& S,
+                             const Standard_Real UFirst, const Standard_Real ULast,
+                             const Standard_Real VFirst, const Standard_Real VLast,
+                             const Standard_Real theArea = 0.);
   
   //! Sets U parameters where splitting has to be done
   Standard_EXPORT void SetUSplitValues (const Handle(TColStd_HSequenceOfReal)& UValues);
@@ -109,6 +112,9 @@ protected:
   Handle(Geom_Surface) mySurface;
   Standard_Integer myStatus;
   Handle(ShapeExtend_CompositeSurface) myResSurfaces;
+  Standard_Real myArea;
+  Standard_Real myUsize;
+  Standard_Real myVsize;
 
 
 private:
index c746b9d2f026a8edf5d5c1b6f88670844579ad6f..72941c2bcb1a4ab372c233b4ec38bacfd2b125db 100644 (file)
@@ -26,7 +26,9 @@ IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_SplitSurfaceArea,ShapeUpgrade_SplitSurfa
 ShapeUpgrade_SplitSurfaceArea::ShapeUpgrade_SplitSurfaceArea():
        ShapeUpgrade_SplitSurface()
 {
-  myNbParts =1;
+  myNbParts = 1;
+  myUnbSplit = myVnbSplit = -1;
+  myIsSplittingIntoSquares = Standard_False;
 }
 
 //=======================================================================
@@ -52,12 +54,42 @@ ShapeUpgrade_SplitSurfaceArea::ShapeUpgrade_SplitSurfaceArea():
   Standard_Real  aNbUV =  aUSize/aVSize;
   Handle(TColStd_HSequenceOfReal) aFirstSplit = (aNbUV <1. ? myVSplitValues : myUSplitValues);
   Handle(TColStd_HSequenceOfReal) aSecondSplit = (aNbUV <1. ? myUSplitValues : myVSplitValues);
+  Standard_Boolean anIsUFirst = (aNbUV > 1.);
   if(aNbUV<1)
     aNbUV = 1./aNbUV;
-  
-  Standard_Integer nbSplitF = (aNbUV >=  myNbParts ? myNbParts : RealToInt(ceil(sqrt(myNbParts*ceil(aNbUV)))));
-  Standard_Integer nbSplitS = (aNbUV >=  myNbParts ? 0  : RealToInt(ceil((Standard_Real)myNbParts/(Standard_Real)nbSplitF)));
-  if(nbSplitS ==1)
+
+  Standard_Boolean anIsFixedUVnbSplits = (myUnbSplit > 0 && myVnbSplit > 0);
+  Standard_Integer nbSplitF, nbSplitS;
+  if (myIsSplittingIntoSquares && myNbParts > 0)
+  {
+    if (!anIsFixedUVnbSplits) //(myUnbSplit <= 0 || myVnbSplit <= 0)
+    {
+      Standard_Real aSquareSize = Sqrt (myArea / myNbParts);
+      myUnbSplit = (Standard_Integer)(myUsize / aSquareSize);
+      myVnbSplit = (Standard_Integer)(myVsize / aSquareSize);
+      if (myUnbSplit == 0)
+        myUnbSplit = 1;
+      if (myVnbSplit == 0)
+        myVnbSplit = 1;
+    }
+
+    if (anIsUFirst)
+    {
+      nbSplitF = myUnbSplit;
+      nbSplitS = myVnbSplit;
+    }
+    else
+    {
+      nbSplitF = myVnbSplit;
+      nbSplitS = myUnbSplit;
+    }
+  }
+  else
+  {
+    nbSplitF = (aNbUV >=  myNbParts ? myNbParts : RealToInt(ceil(sqrt(myNbParts*ceil(aNbUV)))));
+    nbSplitS = (aNbUV >=  myNbParts ? 0  : RealToInt(ceil((Standard_Real)myNbParts/(Standard_Real)nbSplitF)));
+  }
+  if(nbSplitS ==1 && !anIsFixedUVnbSplits)
     nbSplitS++;
   if(!nbSplitF)
     return;
index 96eafcfe24dc4c1baada14a371c062190575be3a..bbc2561ce17dd08f67a7d299afcbb1f9fee2ded5 100644 (file)
@@ -40,6 +40,17 @@ public:
   //! Set number of split for surfaces
     Standard_Integer& NbParts();
   
+  //! Set splitting mode
+  //! If the mode is "splitting into squares",
+  //! the face is splitted approximately into <myNbParts> parts,
+  //! the parts are similar to squares in 2D.
+    void SetSplittingIntoSquares(const Standard_Boolean theIsSplittingIntoSquares);
+
+  //! Set fixed numbers of splits in U and V directions.
+  //! Only for "Splitting Into Squares" mode
+    void SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+                            const Standard_Integer theNbVsplits);
+  
   Standard_EXPORT virtual void Compute (const Standard_Boolean Segment = Standard_True) Standard_OVERRIDE;
 
 
@@ -56,6 +67,9 @@ private:
 
 
   Standard_Integer myNbParts;
+  Standard_Integer myUnbSplit;
+  Standard_Integer myVnbSplit;
+  Standard_Boolean myIsSplittingIntoSquares;
 
 
 };
index 2127f5373dc10d5d8a29252e0e46cc4a708eb24b..b43390f4a7e8f11bb29602225efdc1ead53a08ac 100644 (file)
@@ -16,4 +16,16 @@ inline Standard_Integer& ShapeUpgrade_SplitSurfaceArea::NbParts()
   return myNbParts;
 }
 
+inline void ShapeUpgrade_SplitSurfaceArea::SetSplittingIntoSquares(const Standard_Boolean theIsSplittingIntoSquares) 
+{
+  myIsSplittingIntoSquares = theIsSplittingIntoSquares;
+}
  
+inline void ShapeUpgrade_SplitSurfaceArea::SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+                                                              const Standard_Integer theNbVsplits) 
+{
+  myUnbSplit = theNbUsplits;
+  myVnbSplit = theNbVsplits;
+  if (myUnbSplit > 0 && myVnbSplit > 0)
+    myNbParts  = myUnbSplit * myVnbSplit;
+}
index 53e9a0af1e4c5e18b906967e0ab7ac5d77e9848a..b5f90d47aabf336ced4940e5afb1ee2ebdaab9e7 100644 (file)
@@ -23,4 +23,6 @@
 023 unify_same_domain
 024 same_parameter_locked
 025 update_tolerance_locked
-026 checkshape
\ No newline at end of file
+026 checkshape
+027 split_number
+028 split_two_numbers
\ No newline at end of file
diff --git a/tests/heal/split_number/A1 b/tests/heal/split_number/A1
new file mode 100644 (file)
index 0000000..26e78ce
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 10
+
diff --git a/tests/heal/split_number/A2 b/tests/heal/split_number/A2
new file mode 100644 (file)
index 0000000..30afecb
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 102
+
diff --git a/tests/heal/split_number/A3 b/tests/heal/split_number/A3
new file mode 100644 (file)
index 0000000..f1aa41d
--- /dev/null
@@ -0,0 +1,10 @@
+psphere a 10  0 90
+pcylinder cc 4 15
+ttranslate cc 0 -5 0
+bcut b a cc
+explode b f
+
+DT_SplitByNumber result b_1 10
+
+checknbshapes result -t -face 10
+
diff --git a/tests/heal/split_number/A4 b/tests/heal/split_number/A4
new file mode 100644 (file)
index 0000000..7025073
--- /dev/null
@@ -0,0 +1,10 @@
+psphere a 10  0 90
+pcylinder cc 4 15
+ttranslate cc 0 -5 0
+bcut b a cc
+explode b f
+
+DT_SplitByNumber result b_1 100
+
+checknbshapes result -t -face 101
+
diff --git a/tests/heal/split_number/A5 b/tests/heal/split_number/A5
new file mode 100644 (file)
index 0000000..4847793
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90  90
+trotate a 0 0 0 0 0 1  -90
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 8
+
diff --git a/tests/heal/split_number/A6 b/tests/heal/split_number/A6
new file mode 100644 (file)
index 0000000..633c45c
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90  90
+trotate a 0 0 0 0 0 1  -90
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 96
+
diff --git a/tests/heal/split_number/A7 b/tests/heal/split_number/A7
new file mode 100644 (file)
index 0000000..12a1b0d
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10
+fit
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 10
+
diff --git a/tests/heal/split_number/A8 b/tests/heal/split_number/A8
new file mode 100644 (file)
index 0000000..a618014
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10
+fit
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 136
+
diff --git a/tests/heal/split_number/B1 b/tests/heal/split_number/B1
new file mode 100644 (file)
index 0000000..662f33a
--- /dev/null
@@ -0,0 +1,7 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 10
+
+checknbshapes result -t -face 9
+
diff --git a/tests/heal/split_number/B2 b/tests/heal/split_number/B2
new file mode 100644 (file)
index 0000000..3d828ec
--- /dev/null
@@ -0,0 +1,7 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 100
+
+checknbshapes result -t -face 106
+
diff --git a/tests/heal/split_number/B3 b/tests/heal/split_number/B3
new file mode 100644 (file)
index 0000000..0319e04
--- /dev/null
@@ -0,0 +1,12 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 60 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 10
+
+checknbshapes result -t -face 15
+
diff --git a/tests/heal/split_number/B4 b/tests/heal/split_number/B4
new file mode 100644 (file)
index 0000000..c995334
--- /dev/null
@@ -0,0 +1,12 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 60 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 100
+
+checknbshapes result -t -face 125
+
diff --git a/tests/heal/split_number/B5 b/tests/heal/split_number/B5
new file mode 100644 (file)
index 0000000..a5ad2b4
--- /dev/null
@@ -0,0 +1,12 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 5 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 10
+
+checknbshapes result -t -face 9
+
diff --git a/tests/heal/split_number/B6 b/tests/heal/split_number/B6
new file mode 100644 (file)
index 0000000..a922f33
--- /dev/null
@@ -0,0 +1,12 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 5 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 100
+
+checknbshapes result -t -face 106
+
diff --git a/tests/heal/split_number/C1 b/tests/heal/split_number/C1
new file mode 100644 (file)
index 0000000..91d6b12
--- /dev/null
@@ -0,0 +1,7 @@
+polyline a 0 0 0  10 0 0  2 5 0   0 0 0
+mkplane a a
+
+DT_SplitByNumber result a 10
+
+checknbshapes result -t -face 14
+
diff --git a/tests/heal/split_number/C2 b/tests/heal/split_number/C2
new file mode 100644 (file)
index 0000000..f206d6f
--- /dev/null
@@ -0,0 +1,7 @@
+polyline a 0 0 0  10 0 0  2 5 0   0 0 0
+mkplane a a
+
+DT_SplitByNumber result a 100
+
+checknbshapes result -t -face 118
+
diff --git a/tests/heal/split_number/D1 b/tests/heal/split_number/D1
new file mode 100644 (file)
index 0000000..3f524dc
--- /dev/null
@@ -0,0 +1,13 @@
+pcylinder a 10 50
+plane pp -20 0 10  1 0 0
+pcylinder b1 pp 3 40
+plane pp 0 -20 30  0 1 0
+pcylinder b2 pp 5 40
+bcut a a b1
+bcut a a b2
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 6
+
diff --git a/tests/heal/split_number/D2 b/tests/heal/split_number/D2
new file mode 100644 (file)
index 0000000..3b040fb
--- /dev/null
@@ -0,0 +1,13 @@
+pcylinder a 10 50
+plane pp -20 0 10  1 0 0
+pcylinder b1 pp 3 40
+plane pp 0 -20 30  0 1 0
+pcylinder b2 pp 5 40
+bcut a a b1
+bcut a a b2
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 99
+
diff --git a/tests/heal/split_number/end b/tests/heal/split_number/end
new file mode 100644 (file)
index 0000000..245dc21
--- /dev/null
@@ -0,0 +1 @@
+puts [checkshape result]
diff --git a/tests/heal/split_two_numbers/A1 b/tests/heal/split_two_numbers/A1
new file mode 100644 (file)
index 0000000..bc7a193
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 3 5
+
+checknbshapes result -t -face 15
+
diff --git a/tests/heal/split_two_numbers/A2 b/tests/heal/split_two_numbers/A2
new file mode 100644 (file)
index 0000000..73654c6
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 1 5
+
+checknbshapes result -t -face 5
+
diff --git a/tests/heal/split_two_numbers/A3 b/tests/heal/split_two_numbers/A3
new file mode 100644 (file)
index 0000000..1d55b31
--- /dev/null
@@ -0,0 +1,8 @@
+psphere a 10  0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 5 1
+
+checknbshapes result -t -face 5
+
diff --git a/tests/heal/split_two_numbers/A4 b/tests/heal/split_two_numbers/A4
new file mode 100644 (file)
index 0000000..5cf785e
--- /dev/null
@@ -0,0 +1,10 @@
+psphere a 10  0 90
+pcylinder cc 4 15
+ttranslate cc 0 -5 0
+bcut b a cc
+explode b f
+
+DT_SplitByNumber result b_1 3 5
+
+checknbshapes result -t -face 16
+
diff --git a/tests/heal/split_two_numbers/B1 b/tests/heal/split_two_numbers/B1
new file mode 100644 (file)
index 0000000..544226b
--- /dev/null
@@ -0,0 +1,7 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 3 5
+
+checknbshapes result -t -face 15
+
diff --git a/tests/heal/split_two_numbers/B2 b/tests/heal/split_two_numbers/B2
new file mode 100644 (file)
index 0000000..de83038
--- /dev/null
@@ -0,0 +1,7 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 1 5
+
+checknbshapes result -t -face 5
+
diff --git a/tests/heal/split_two_numbers/B3 b/tests/heal/split_two_numbers/B3
new file mode 100644 (file)
index 0000000..3ac928b
--- /dev/null
@@ -0,0 +1,7 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 5 1
+
+checknbshapes result -t -face 5
+
diff --git a/tests/heal/split_two_numbers/B4 b/tests/heal/split_two_numbers/B4
new file mode 100644 (file)
index 0000000..475935c
--- /dev/null
@@ -0,0 +1,12 @@
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 60 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 3 5
+
+checknbshapes result -t -face 14
+
diff --git a/tests/heal/split_two_numbers/end b/tests/heal/split_two_numbers/end
new file mode 100644 (file)
index 0000000..245dc21
--- /dev/null
@@ -0,0 +1 @@
+puts [checkshape result]