0023429: BRepFeat_SplitShape algorithm misses some section edges while building resul...
authorjgv <jgv@opencascade.com>
Fri, 14 Sep 2012 13:51:20 +0000 (17:51 +0400)
committerjgv <jgv@opencascade.com>
Fri, 14 Sep 2012 13:51:20 +0000 (17:51 +0400)
Adding test case bugs/modalg/CR23429

src/BRepFeat/BRepFeat_SplitShape.cdl
src/BRepFeat/BRepFeat_SplitShape.lxx
src/LocOpe/LocOpe_SplitShape.cxx
src/LocOpe/LocOpe_WiresOnShape.cdl
src/LocOpe/LocOpe_WiresOnShape.cxx
src/LocOpe/LocOpe_WiresOnShape.lxx
src/QABugs/QABugs_11.cxx
tests/bugs/grids.list
tests/bugs/modalg/CR23429 [new file with mode: 0755]
tests/bugs/modalg/end [new file with mode: 0755]

index 8f5ddb0..6abea8c 100755 (executable)
@@ -72,6 +72,11 @@ is
        ---C++: inline      
        is static;
 
+    SetCheckInterior(me: in out; ToCheckInterior: Boolean from Standard)
+       ---Purpose: Set the flag of check internal intersections
+       --          default value is True (to check)
+       ---C++: inline      
+       is static;
 
     Add(me: in out; W: Wire from TopoDS;
                    F: Face from TopoDS)
index 2019d52..8759dd8 100755 (executable)
@@ -60,6 +60,15 @@ inline void BRepFeat_SplitShape::Init(const TopoDS_Shape& S)
   }
 }
 
+//=======================================================================
+//function : SetCheckInterior
+//purpose  : 
+//=======================================================================
+
+inline void BRepFeat_SplitShape::SetCheckInterior(const Standard_Boolean ToCheckInterior)
+{
+  myWOnShape->SetCheckInterior(ToCheckInterior);
+}
 
 //=======================================================================
 //function : Add
index 738cb1b..87cfbbb 100755 (executable)
@@ -818,12 +818,23 @@ void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
     }
     aLocalFace  = FaceRef.Oriented(wfirst.Orientation());
     C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
+    Standard_Real dpar = (l - f)*0.01;
  
     if (LastEdge.Orientation() == TopAbs_FORWARD) {
       C2d->D1(l,plast,dlast);
+      if (dlast.Magnitude() < gp::Resolution())
+      {
+        gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
+        dlast.SetXY(plast.XY() - PrevPnt.XY());
+      }
     }
     else {
       C2d->D1(f,plast,dlast);
+      if (dlast.Magnitude() < gp::Resolution())
+      {
+        gp_Pnt2d NextPnt = C2d->Value(f + dpar);
+        dlast.SetXY(NextPnt.XY() - plast.XY());
+      }
       dlast.Reverse();
     }
 
@@ -865,12 +876,23 @@ void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
         TopoDS_Shape aLocalFace  = FaceRef.Oriented(wfirst.Orientation());
         C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()),
                                         TopoDS::Face(aLocalFace), f, l);
+        Standard_Real dpar = (l - f)*0.01;
 
         if (itm.Key().Orientation() == TopAbs_FORWARD) {
           C2d->D1(l,plast,dlast);
+          if (dlast.Magnitude() < gp::Resolution())
+          {
+            gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
+            dlast.SetXY(plast.XY() - PrevPnt.XY());
+          }
         }
         else {
           C2d->D1(f,plast,dlast);
+          if (dlast.Magnitude() < gp::Resolution())
+          {
+            gp_Pnt2d NextPnt = C2d->Value(f + dpar);
+            dlast.SetXY(NextPnt.XY() - plast.XY());
+          }
           dlast.Reverse();
         }
       }
@@ -944,19 +966,12 @@ void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
     }
     
     newW1.Oriented(orfila);
-    BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion());
-    if (classif.PerformInfinitePoint() == TopAbs_OUT) {
-      BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion());
-      if (classi.PerformInfinitePoint() == TopAbs_IN) {
-        TopoDS_Face tempF = newF2;
-        newF2 = newF1;
-        newF1 = tempF;
-        newW2.Oriented(orfila);
-        newW1.Oriented(TopAbs_FORWARD);
-      }
-    }
+    newW2.Oriented(orfila);
+    
     B.Add(newF1,newW1);
+    BRepTools::Write(newF1, "k:/queries/WrongBOP/NewF1.brep");
     B.Add(newF2,newW2);
+    BRepTools::Write(newF2, "k:/queries/WrongBOP/NewF2.brep");
     
     for (exp.ReInit(); exp.More(); exp.Next()) {
       const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
@@ -1380,6 +1395,7 @@ static void ChoixUV(const TopoDS_Edge& Last,
   gp_Dir2d ref2d(dlst);
 
   Handle(Geom2d_Curve) C2d;
+  Standard_Real dpar;
 
   Standard_Integer index = 0, imin=0;
   Standard_Real  angmax = -M_PI, dist, ang;
@@ -1388,14 +1404,25 @@ static void ChoixUV(const TopoDS_Edge& Last,
   for (It.Initialize(Poss); It.More(); It.Next()) {
     index++;
     C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
+    dpar = (l - f)*0.01;
     if (It.Key().Orientation() == TopAbs_FORWARD) {
       //      p2d = C2d->Value(f);
       C2d->D1(f,p2d,v2d);
+      if (v2d.Magnitude() < gp::Resolution())
+      {
+        gp_Pnt2d NextPnt = C2d->Value(f + dpar);
+        v2d.SetXY(NextPnt.XY() - p2d.XY());
+      }
       vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key()));
     }
     else {
       //      p2d = C2d->Value(l);
       C2d->D1(l,p2d,v2d);
+      if (v2d.Magnitude() < gp::Resolution())
+      {
+        gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
+        v2d.SetXY(p2d.XY() - PrevPnt.XY());
+      }
       v2d.Reverse();
       vtx = TopExp::LastVertex(TopoDS::Edge(It.Key()));
     }
@@ -1426,13 +1453,24 @@ static void ChoixUV(const TopoDS_Edge& Last,
   for (index = 1, It.Initialize(Poss); It.More(); It.Next()) {
     if (index == imin) {
       C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
+      dpar = (l - f)*0.01;
       if (It.Key().Orientation() == TopAbs_FORWARD) {
         //     plst = C2d->Value(l);
         C2d->D1(l,plst,dlst);
+        if (dlst.Magnitude() < gp::Resolution())
+        {
+          gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
+          dlst.SetXY(plst.XY() - PrevPnt.XY());
+        }
       }
       else {
         //     plst = C2d->Value(f);
         C2d->D1(f,plst,dlst);
+        if (dlst.Magnitude() < gp::Resolution())
+        {
+          gp_Pnt2d NextPnt = C2d->Value(f + dpar);
+          dlst.SetXY(NextPnt.XY() - plst.XY());
+        }
         dlst.Reverse();
       }
       break;
index 7dc9ba6..5171f20 100755 (executable)
@@ -48,6 +48,11 @@ is
     
        is static;
 
+    SetCheckInterior(me: mutable; ToCheckInterior: Boolean from Standard)
+       ---Purpose: Set the flag of check internal intersections
+       --          default value is True (to check)
+       ---C++: inline      
+       is static;
 
     Bind(me: mutable; W: Wire from TopoDS;
                       F: Face from TopoDS)
@@ -148,6 +153,7 @@ fields
     myShape : Shape                      from TopoDS;
     myMapEF : IndexedDataMapOfShapeShape from TopTools;
     myFacesWithSection : MapOfShape      from TopTools;
+    myCheckInterior : Boolean            from Standard;
     myMap   : DataMapOfShapeShape        from TopTools;
     myDone  : Boolean                    from Standard;
     myIndex : Integer                    from Standard;
index 4849783..2072fed 100755 (executable)
@@ -90,7 +90,7 @@ static void FindInternalIntersections(const TopoDS_Edge&,
 //=======================================================================
 
 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
-   myShape(S),myDone(Standard_False)
+  myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
 {}
 
 
@@ -103,6 +103,7 @@ LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
 {
    myShape = S;
+   myCheckInterior = Standard_True;
    myDone = Standard_False;
    myMap.Clear();
    myMapEF.Clear();
@@ -240,7 +241,8 @@ void LocOpe_WiresOnShape::BindAll()
     if (aPCurve.IsNull())
       continue;
 
-    FindInternalIntersections(edg, fac, Splits, myMap, theMap);
+    if (myCheckInterior)
+      FindInternalIntersections(edg, fac, Splits, myMap, theMap);
   }
 
   for (Ind = 1; Ind <= Splits.Extent(); Ind++)
index f334fae..8b5cd54 100755 (executable)
 
 
 
+//=======================================================================
+//function : SetCheckInterior
+//purpose  : 
+//=======================================================================
+
+inline void LocOpe_WiresOnShape::SetCheckInterior(const Standard_Boolean ToCheckInterior)
+{
+  myCheckInterior = Standard_True;
+}
+
 //=======================================================================
 //function : IsDone
 //purpose  : 
index c17eec4..65440a7 100755 (executable)
@@ -90,6 +90,8 @@
 #include <IGESData_IGESModel.hxx>
 #include <IGESData_IGESEntity.hxx>
 #include <V3d_View.hxx>
+#include <BRepFeat_SplitShape.hxx>
+#include <BRepAlgoAPI_Section.hxx>
 
 #include <tcl.h>
 
@@ -5280,6 +5282,54 @@ Standard_Integer OCC22736 (Draw_Interpretor& di, Standard_Integer argc, const ch
   return 0;
 }
 
+Standard_Integer OCC23429(Draw_Interpretor& di,
+                          Standard_Integer narg, const char** a)
+{
+  if (narg < 4) return 1;
+  
+  TopoDS_Shape aShape = DBRep::Get(a[2]);
+  if (aShape.IsNull()) return 1;
+  
+  BRepFeat_SplitShape Spls(aShape);
+  Spls.SetCheckInterior(Standard_False);
+
+  TopoDS_Shape aTool = DBRep::Get(a[3]);
+
+  BRepAlgoAPI_Section Builder(aShape, aTool, Standard_False);
+  Builder.ComputePCurveOn1(Standard_True);
+  if (narg == 5)
+    Builder.Approximation(Standard_True); 
+  Builder.Build();
+  TopoDS_Shape aSection = Builder.Shape();
+
+  TopExp_Explorer ExpSec(aSection, TopAbs_EDGE);
+  for (; ExpSec.More(); ExpSec.Next())
+  {
+    TopoDS_Edge anEdge = TopoDS::Edge(ExpSec.Current());
+    Handle(Geom2d_Curve) thePCurve;
+    Handle(Geom_Surface) theSurface;
+    TopLoc_Location theLoc;
+    Standard_Real fpar, lpar;
+    BRep_Tool::CurveOnSurface(anEdge, thePCurve, theSurface, theLoc, fpar, lpar);
+    TopoDS_Face aFace;
+    TopExp_Explorer ExpShape(aShape, TopAbs_FACE);
+    for (; ExpShape.More(); ExpShape.Next())
+    {
+      aFace = TopoDS::Face(ExpShape.Current());
+      TopLoc_Location aLoc;
+      Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace, aLoc);
+      if (aSurface == theSurface && aLoc == theLoc)
+        break;
+    }
+    Spls.Add(anEdge, aFace);
+  }
+
+  TopoDS_Shape Result = Spls.Shape();
+  DBRep::Set(a[1], Result);
+
+  return 0;
+}
+
 #include <BOPTColStd_CArray1OfInteger.hxx>
 //=======================================================================
 //function : DumpArray
@@ -5463,5 +5513,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC22762", "OCC22762 x1 y1 z1 x2 y2 z3", __FILE__, OCC22762, group);
   theCommands.Add("OCC22558", "OCC22558 x_vec y_vec z_vec x_dir y_dir z_dit x_pnt y_pnt z_pnt", __FILE__, OCC22558, group);
   theCommands.Add("CR23403", "CR23403 string", __FILE__, CR23403, group);
+  theCommands.Add("OCC23429", "OCC23429 res shape tool [appr]", __FILE__, OCC23429, group);
   return;
 }
index 678fa13..606d406 100755 (executable)
@@ -3,12 +3,5 @@
 003 iges
 004 vis
 005 xde
-
-
-
-
-
-
-
-
+006 modalg
 
diff --git a/tests/bugs/modalg/CR23429 b/tests/bugs/modalg/CR23429
new file mode 100755 (executable)
index 0000000..567ffcc
--- /dev/null
@@ -0,0 +1,24 @@
+puts "============"
+puts "CR23429"
+puts "============"
+puts ""
+##########################################################################################################
+# BRepFeat_SplitShape algorithm misses some section edges while building result from customer's shape
+##########################################################################################################
+pload QAcommands
+
+restore [locate_data_file CR23429-Shape1.brep] a
+restore [locate_data_file CR23429-Shape3.brep] b
+
+OCC23429 result a b
+
+set square 1120.52
+
+set 2dviewer 1
+
+
+
+
+
+
+
diff --git a/tests/bugs/modalg/end b/tests/bugs/modalg/end
new file mode 100755 (executable)
index 0000000..ce77fef
--- /dev/null
@@ -0,0 +1,62 @@
+if { [isdraw result] } {
+   #check if result is valid
+   
+   puts "checkshape"
+   set ch [checkshape result]
+   puts $ch
+   
+   if { [info exists square] } {
+      set prop "square"
+      set mass $square
+      regexp {Mass +: +([-0-9.+eE]+)} [sprops result] full m      
+   }
+   if { [info exists length] } {
+      set prop "length"
+      set mass $length
+      regexp {Mass +: +([-0-9.+eE]+)} [lprops result] full m      
+
+      puts "checksection"
+      puts [checksection result]
+   }
+
+   #if mass (length or square) is empty in test case then result should be an empty shape.
+   if { [string compare "$mass" "empty"] != 0 } {
+      if { $m == 0 } {
+                puts "Error : The $command is not valid. The $prop is 0."
+      }
+      if { $mass > 0 } {
+        puts "The expected $prop is $mass"
+      }
+      #check of change of square is < 1%
+      if { ($mass != 0 && [expr 1.*abs($mass - $m)/$mass] > 0.01) || ($mass == 0 && $m != 0) } {
+        puts "Error : The $prop of result shape is $m"
+      }
+      
+      if { [info exists nbsh_v ] } {
+       set arr_v [explode result v]
+       set nb_v [ llength $arr_v ]
+        if { $nb_v != $nbsh_v } {
+           puts "Error : Result shape is WRONG because it must contain $nbsh_v vertexes instead of $nb_v"
+        } else {
+           puts "Result shape contains $nb_v vertexes"
+        }
+        
+      }
+
+      if { [info exists nbsh_e ] } {
+       set arr_e [explode result e]
+       set nb_e [ llength $arr_e ]
+        if { $nb_e != $nbsh_e } {
+           puts "Error : Result shape is WRONG because it must contain $nbsh_e edges instead of $nb_e"
+        } else {
+           puts "Result shape contains $nb_e edges"
+        }
+      }
+   } else {
+      if { $m != 0 } {
+                puts "Error : The $command is not valid. The $prop is $m"
+      }
+   }
+} else {
+   puts "Error : The $command can not be build."
+}