0027780: Face-face intersection produces 2D curve that has reversed derivative at...
authormsv <msv@opencascade.com>
Tue, 16 Aug 2016 09:41:23 +0000 (12:41 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Aug 2016 08:26:05 +0000 (11:26 +0300)
The matter was that with starting point paased into intersector the walking line goes one point outside of the surface domain. Then during purging this extra point is removed from the line but its geometry is used for the last vertex. This makes a set of points invalid for approximation, and as a result we obtain the curve with reversed tangent direction at the end.

The API of the method IntPatch_WLineTool::ComputePurgedWLine has been changed to insert a new Boolean parameter RestrictLine. If this parameter is false than the step of removing of outside points is skipped, and the result line is not distorted. This flag is determined inside IntTools_FaceFace to tell the intersector if it is needed to limit intersection line by surface domain.

Test case has been added.

src/IntPatch/IntPatch_Intersection.cxx
src/IntPatch/IntPatch_WLineTool.cxx
src/IntPatch/IntPatch_WLineTool.hxx
tests/bugs/modalg_6/bug27780 [new file with mode: 0644]

index 5e02c67..75b6ba4 100644 (file)
@@ -910,9 +910,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   //                              3. ts1 == ts2 == 0 <Param-Param>
 
   // Geom - Geom
+  const Standard_Boolean RestrictLine = Standard_True;
   if(ts1 == ts2 && ts1 == 1)
   {
-    const Standard_Boolean RestrictLine = Standard_True;
     IntSurf_ListOfPntOn2S ListOfPnts;
     ListOfPnts.Clear();
     if(isGeomInt)
@@ -946,7 +946,6 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   // Param - Param 
   if(ts1 == ts2 && ts1 == 0)
   {
-    const Standard_Boolean RestrictLine = Standard_True;
     IntSurf_ListOfPntOn2S ListOfPnts;
     ListOfPnts.Clear();
 
@@ -964,7 +963,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     if(aWL.IsNull())
       continue;
 
-    Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+    Handle(IntPatch_WLine) aRW =
+      IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
 
     if(aRW.IsNull())
       continue;
@@ -1207,7 +1207,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     if(!aWL->IsPurgingAllowed())
       continue;
 
-    Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+    Handle(IntPatch_WLine) aRW = 
+      IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
 
     if(aRW.IsNull())
       continue;
@@ -1720,7 +1721,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
     if(aWL.IsNull())
       continue;
 
-    Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
+    Handle(IntPatch_WLine) aRW =
+      IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2, Standard_True);
 
     if(aRW.IsNull())
       continue;
index 1b823b6..ca38c1c 100644 (file)
@@ -1197,7 +1197,8 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
                      const Handle(Adaptor3d_HSurface)   &theS1,
                      const Handle(Adaptor3d_HSurface)   &theS2,
                      const Handle(Adaptor3d_TopolTool)  &theDom1,
-                     const Handle(Adaptor3d_TopolTool)  &theDom2)
+                     const Handle(Adaptor3d_TopolTool)  &theDom2,
+                     const Standard_Boolean              theRestrictLine)
 {
   Standard_Integer i, k, v, nb, nbvtx;
   Handle(IntPatch_WLine) aResult;
@@ -1300,13 +1301,15 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
     return aLocalWLine;
   }
 
-  // II: Delete out of borders points.
-  Handle(IntPatch_WLine) aLocalWLineOuter = 
-    DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
+  if (theRestrictLine)
+  {
+    // II: Delete out of borders points.
+    aLocalWLine = DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
+  }
 
   // III: Delete points by tube criteria.
   Handle(IntPatch_WLine) aLocalWLineTube = 
-    DeleteByTube(aLocalWLineOuter, theS1, theS2);
+    DeleteByTube(aLocalWLine, theS1, theS2);
 
   if(aLocalWLineTube->NbPnts() > 1)
   {
index 865913c..90b0d5d 100644 (file)
@@ -39,6 +39,7 @@ public:
   //!
   //! II
   //! Removes point out of borders in case of non periodic surfaces.
+  //! This step is done only if theRestrictLine is true.
   //!
   //! III
   //! Removes exceed points using tube criteria:
@@ -52,7 +53,8 @@ public:
                                               const Handle(Adaptor3d_HSurface) &theS1,
                                               const Handle(Adaptor3d_HSurface) &theS2,
                                               const Handle(Adaptor3d_TopolTool)  &theDom1,
-                                              const Handle(Adaptor3d_TopolTool)  &theDom2);
+                                              const Handle(Adaptor3d_TopolTool)  &theDom2,
+                                              const Standard_Boolean      theRestrictLine);
 
 //! Joins all WLines from theSlin to one if it is possible and records 
 //! the result into theSlin again. Lines will be kept to be splitted if:
diff --git a/tests/bugs/modalg_6/bug27780 b/tests/bugs/modalg_6/bug27780
new file mode 100644 (file)
index 0000000..4df90be
--- /dev/null
@@ -0,0 +1,33 @@
+puts "============"
+puts "OCC27780"
+puts "============"
+puts ""
+######################################################
+# Face-face intersection produces 2D curve that has reversed derivative at its end
+######################################################
+
+restore [locate_data_file buc60532a.brep] p 
+restore [locate_data_file buc60532b.brep] t1
+explode t1 f
+
+bopcurves p t1_2 -2d -p 6.2406621764215551 0.23999999463558200 0.00034444887595448459 -5.0019657458625186
+
+pcurve p
+trim c c2d1_1 0 1
+2dcvalue c 0 u0 v0
+2dcvalue c 1 u1 v1 du dv
+dset u01 u1-u0
+dset v01 v1-v0
+dset dot u01*du+v01*dv
+
+if {[dval dot] < 0} {
+  puts "Error: p-curve has reversed direction at its end"
+} else {
+  puts "OK: p-curve has correct direction at its end"
+}
+
+view 1 -2D- 728 450 400 400
+don p_* c
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png