]> OCCT Git - occt-copy.git/commitdiff
0027729: UnifySameDomain: allow the user to specify linear and angular tolerances
authormsv <msv@opencascade.com>
Fri, 29 Jul 2016 15:23:57 +0000 (18:23 +0300)
committerakz <akz@opencascade.com>
Fri, 12 Aug 2016 10:17:52 +0000 (13:17 +0300)
- New methods SetLinearTolerance and SetAngularTolerance have been added in the class ShapeUpgrade_UnifySameDomain.
- The algorithm has been modified to consider new parameters when checking if two faces are same domain.
- The draw command unifysamedomain has been changed to accept new parameters.
- The internal method MergeSeq has been changed to avoid exception connected with access to unknown key in the data map.

src/SWDRAW/SWDRAW_ShapeUpgrade.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx

index 45c39fd7e109e90db7bcf4796797b0d6f2485ee0..4735f8fc16d5f3235f4d8c26a5309985c2f1b77d 100644 (file)
@@ -1284,14 +1284,16 @@ static ShapeUpgrade_UnifySameDomain& Unifier() {
 //=======================================================================
 static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
-  if (n < 3 || n > 6)
+  if (n < 3)
   {
-    di << "Use unifysamedom result shape [-f] [-e] [+b] [-i]\n";
+    di << "Use unifysamedom result shape [-f] [-e] [+b] [-i] [-t val] [-a val]\n";
     di << "options:\n";
-    di << "[-f] to switch off 'unify-faces' mode \n";
-    di << "[-e] to switch off 'unify-edges' mode\n";
-    di << "[+b] to switch on 'concat bspline' mode\n";
-    di << "[+i] to switch on 'allow internal edges' mode\n";
+    di << "-f to switch off 'unify-faces' mode \n";
+    di << "-e to switch off 'unify-edges' mode\n";
+    di << "+b to switch on 'concat bspline' mode\n";
+    di << "+i to switch on 'allow internal edges' mode\n";
+    di << "-t val to set linear tolerance\n";
+    di << "-a val to set angular tolerance\n";
     di << "'unify-faces' and 'unify-edges' modes are switched on by default";
     return 1;
   }
@@ -1305,6 +1307,8 @@ static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, c
   Standard_Boolean anUEdges = Standard_True;
   Standard_Boolean anConBS = Standard_False;
   Standard_Boolean isAllowInternal = Standard_False;
+  Standard_Real aLinTol = Precision::Confusion();
+  Standard_Real aAngTol = Precision::Angular();
 
   if (n > 3)
     for ( int i = 3; i < n; i++ ) 
@@ -1317,10 +1321,24 @@ static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, c
         anConBS = Standard_True;
       else if (!strcmp(a[i], "+i"))
         isAllowInternal = Standard_True;
+      else if (!strcmp(a[i], "-t") || !strcmp(a[i], "-a"))
+      {
+        if (++i < n)
+        {
+          (a[i-1][1] == 't' ? aLinTol : aAngTol) = Draw::Atof(a[i]);
+        }
+        else
+        {
+          di << "value expected after " << a[i-1];
+          return 1;
+        }
+      }
     }
 
   Unifier().Initialize(aShape, anUEdges, anUFaces, anConBS);
   Unifier().AllowInternalEdges(isAllowInternal);
+  Unifier().SetLinearTolerance(aLinTol);
+  Unifier().SetAngularTolerance(aAngTol);
   Unifier().Build();
   TopoDS_Shape Result = Unifier().Shape();
 
@@ -1556,7 +1574,7 @@ Standard_Integer reshape(Draw_Interpretor& di,
   theCommands.Add ("removeloc","result shape",__FILE__,removeloc,g);
   
   theCommands.Add ("unifysamedom",
-                   "unifysamedom result shape [-f] [-e] [+b]", __FILE__,unifysamedom,g);
+                   "unifysamedom result shape [-f] [-e] [+b] [-i] [-t val] [-a val]", __FILE__,unifysamedom,g);
   
   theCommands.Add ("unifysamedomgen",
                    "unifysamedomgen newshape oldshape : get new shape generated "
index 776b55d3a9456ed0ef30af17bff59a4cdaa4b535..014d20c39323465eedebb07d31fe1a45942d693d 100644 (file)
@@ -306,7 +306,9 @@ static Handle(Geom_Surface) ClearRts(const Handle(Geom_Surface)& aSurface)
 //purpose  : 
 //=======================================================================
 static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
-                                     const TopoDS_Face& aCheckedFace)
+                                     const TopoDS_Face& aCheckedFace,
+                                     const Standard_Real theLinTol,
+                                     const Standard_Real theAngTol)
 {
   //checking the same handles
   TopLoc_Location L1, L2;
@@ -318,9 +320,6 @@ static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
   if (S1 == S2 && L1 == L2)
     return Standard_True;
 
-  // planar and cylindrical cases (IMP 20052)
-  Standard_Real aPrec = Precision::Confusion();
-
   S1 = BRep_Tool::Surface(aFace);
   S2 = BRep_Tool::Surface(aCheckedFace);
 
@@ -333,6 +332,22 @@ static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
   //if (!aGOFS1.IsNull()) S1 = aGOFS1->BasisSurface();
   //if (!aGOFS2.IsNull()) S2 = aGOFS2->BasisSurface();
 
+  // case of two planar surfaces:
+  // all kinds of surfaces checked, including b-spline and bezier
+  GeomLib_IsPlanarSurface aPlanarityChecker1(S1, theLinTol);
+  if (aPlanarityChecker1.IsPlanar()) {
+    GeomLib_IsPlanarSurface aPlanarityChecker2(S2, theLinTol);
+    if (aPlanarityChecker2.IsPlanar()) {
+      gp_Pln aPln1 = aPlanarityChecker1.Plan();
+      gp_Pln aPln2 = aPlanarityChecker2.Plan();
+
+      if (aPln1.Position().Direction().IsParallel(aPln2.Position().Direction(), theAngTol) &&
+        aPln1.Distance(aPln2) < theLinTol) {
+        return Standard_True;
+      }
+    }
+  }
+
   // case of two elementary surfaces: use OCCT tool
   // elementary surfaces: ConicalSurface, CylindricalSurface,
   //                      Plane, SphericalSurface and ToroidalSurface
@@ -346,7 +361,7 @@ static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
     Handle(BRepTopAdaptor_TopolTool) aTT2 = new BRepTopAdaptor_TopolTool();
 
     try {
-      IntPatch_ImpImpIntersection anIIInt (aGA1, aTT1, aGA2, aTT2, aPrec, aPrec);
+      IntPatch_ImpImpIntersection anIIInt(aGA1, aTT1, aGA2, aTT2, theLinTol, theLinTol);
       if (!anIIInt.IsDone() || anIIInt.IsEmpty())
         return Standard_False;
 
@@ -357,22 +372,6 @@ static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
     }
   }
 
-  // case of two planar surfaces:
-  // all kinds of surfaces checked, including b-spline and bezier
-  GeomLib_IsPlanarSurface aPlanarityChecker1 (S1, aPrec);
-  if (aPlanarityChecker1.IsPlanar()) {
-    GeomLib_IsPlanarSurface aPlanarityChecker2 (S2, aPrec);
-    if (aPlanarityChecker2.IsPlanar()) {
-      gp_Pln aPln1 = aPlanarityChecker1.Plan();
-      gp_Pln aPln2 = aPlanarityChecker2.Plan();
-
-      if (aPln1.Position().Direction().IsParallel(aPln2.Position().Direction(),Precision::Angular()) &&
-          aPln1.Distance(aPln2) < aPrec) {
-        return Standard_True;
-      }
-    }
-  }
-
   // case of two cylindrical surfaces, at least one of which is a swept surface
   // swept surfaces: SurfaceOfLinearExtrusion, SurfaceOfRevolution
   if ((S1->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
@@ -382,14 +381,14 @@ static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
   {
     gp_Cylinder aCyl1, aCyl2;
     if (getCylinder(S1, aCyl1) && getCylinder(S2, aCyl2)) {
-      if (fabs(aCyl1.Radius() - aCyl2.Radius()) < aPrec) {
+      if (fabs(aCyl1.Radius() - aCyl2.Radius()) < theLinTol) {
         gp_Dir aDir1 = aCyl1.Position().Direction();
         gp_Dir aDir2 = aCyl2.Position().Direction();
         if (aDir1.IsParallel(aDir2, Precision::Angular())) {
           gp_Pnt aLoc1 = aCyl1.Location();
           gp_Pnt aLoc2 = aCyl2.Location();
           gp_Vec aVec12 (aLoc1, aLoc2);
-          if (aVec12.SquareMagnitude() < aPrec*aPrec ||
+          if (aVec12.SquareMagnitude() < theLinTol*theLinTol ||
               aVec12.IsParallel(aDir1, Precision::Angular())) {
             return Standard_True;
           }
@@ -1055,8 +1054,11 @@ static Standard_Boolean MergeSeq (TopTools_SequenceOfShape& SeqEdges,
       k++;
       for (Standard_Integer j = 2; j <= SeqOfSubsSeqOfEdges(i).SeqsEdges.Length(); j++)
       {
-        TopoDS_Shape OldEdge = NewEdges2OldEdges(SeqOfSubsSeqOfEdges(i).SeqsEdges(j));
-        theOldShapes.Bind(OldEdge, SeqOfSubsSeqOfEdges(i).UnionEdges);
+        const TopoDS_Shape& anOldEdge = SeqOfSubsSeqOfEdges(i).SeqsEdges(j);
+        const TopoDS_Shape* pOrigEdge = NewEdges2OldEdges.Seek(anOldEdge);
+        if (!pOrigEdge)
+          pOrigEdge = &anOldEdge;
+        theOldShapes.Bind(*pOrigEdge, SeqOfSubsSeqOfEdges(i).UnionEdges);
         theContext->Remove(SeqOfSubsSeqOfEdges(i).SeqsEdges(j));
       }
     }
@@ -1107,7 +1109,9 @@ static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges,
 //=======================================================================
 
 ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain()
-  : myUnifyFaces (Standard_True),
+  : myLinTol(Precision::Confusion()),
+    myAngTol(Precision::Angular()),
+    myUnifyFaces(Standard_True),
     myUnifyEdges (Standard_True),
     myConcatBSplines (Standard_False),
     myAllowInternal (Standard_False)
@@ -1125,7 +1129,9 @@ ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain(const TopoDS_Shape& a
                                                            const Standard_Boolean UnifyFaces,
                                                            const Standard_Boolean ConcatBSplines)
   : myInitShape (aShape),
-    myUnifyFaces (UnifyFaces),
+    myLinTol(Precision::Confusion()),
+    myAngTol(Precision::Angular()),
+    myUnifyFaces(UnifyFaces),
     myUnifyEdges (UnifyEdges),
     myConcatBSplines (ConcatBSplines),
     myAllowInternal (Standard_False),
@@ -1297,7 +1303,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
         if (IsCheckSharedEdgeOri && !CheckSharedEdgeOri(aFace, anCheckedFace, edge) )
           continue;
 
-        if (IsSameDomain(aFace,anCheckedFace)) {
+        if (IsSameDomain(aFace,anCheckedFace, myLinTol, myAngTol)) {
 
           // hotfix for 27271: prevent merging along periodic direction.
           if (IsLikeSeam(edge, aFace, aBaseSurface))
index de185b65ce032b1305193e41b4ac51ab3a600852..8286e9215d6843c8561f17aab658cdb7b4271bc1 100644 (file)
@@ -62,7 +62,19 @@ public:
   //! topology. Without this flag merging through multi connected edge
   //! is forbidden. Default value is false.
   Standard_EXPORT void AllowInternalEdges (const Standard_Boolean theValue);
-  
+
+  //! Sets the linear tolerance. Default value is Precision::Confusion().
+  void SetLinearTolerance(const Standard_Real theValue)
+  {
+    myLinTol = theValue;
+  }
+
+  //! Sets the angular tolerance. Default value is Precision::Angular().
+  void SetAngularTolerance(const Standard_Real theValue)
+  {
+    myAngTol = theValue;
+  }
+
   //! Builds the resulting shape
   Standard_EXPORT void Build();
   
@@ -100,6 +112,8 @@ private:
                      Standard_Boolean IsCheckSharedEdgeOri);
 
   TopoDS_Shape myInitShape;
+  Standard_Real myLinTol;
+  Standard_Real myAngTol;
   Standard_Boolean myUnifyFaces;
   Standard_Boolean myUnifyEdges;
   Standard_Boolean myConcatBSplines;