0025243: BRepFeat_SplitShape algorithm processes incorrect faces with degenerated...
authorjgv <jgv@opencascade.com>
Thu, 25 Sep 2014 10:06:35 +0000 (14:06 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Sep 2014 11:58:20 +0000 (15:58 +0400)
Test case for issue #25243

src/LocOpe/LocOpe.cdl
src/LocOpe/LocOpe_BuildWires.cdl
src/LocOpe/LocOpe_BuildWires.cxx
src/LocOpe/LocOpe_ProjectedWires.cdl [deleted file]
src/LocOpe/LocOpe_ProjectedWires.cxx [deleted file]
src/LocOpe/LocOpe_Spliter.cdl
src/LocOpe/LocOpe_Spliter.cxx
src/LocOpe/LocOpe_WiresOnShape.cdl
src/LocOpe/LocOpe_WiresOnShape.cxx
tests/bugs/modalg_5/bug25243 [new file with mode: 0644]

index d894a98..0848579 100644 (file)
@@ -41,7 +41,7 @@ is
 
     class SplitShape;
 
-    deferred class ProjectedWires;      -- inherits TShared from MMgt
+    --deferred class ProjectedWires;      -- inherits TShared from MMgt
     
     class WiresOnShape;                 -- inherits ProjectedWires from LocOpe
 
index eaee3cb..83143d4 100644 (file)
@@ -23,7 +23,7 @@ private class BuildWires from LocOpe
 
 -- Modified by skv - Mon May 31 12:53:04 2004 OCC5865 Begin
 uses ListOfShape from TopTools,
-     ProjectedWires from LocOpe
+     WiresOnShape from LocOpe
 -- Modified by skv - Mon May 31 12:53:05 2004 OCC5865 End
 
 raises NotDone from StdFail
@@ -37,7 +37,7 @@ is
 
 -- Modified by skv - Mon May 31 12:54:10 2004 OCC5865 Begin
     Create(Ledges: ListOfShape from TopTools;
-          PW    : ProjectedWires  from  LocOpe)
+          PW    : WiresOnShape  from  LocOpe)
 -- Modified by skv - Mon May 31 12:54:11 2004 OCC5865 End
     
        returns BuildWires from LocOpe;
@@ -45,7 +45,7 @@ is
 
 -- Modified by skv - Mon May 31 12:54:10 2004 OCC5865 Begin
     Perform(me: in out; Ledges: ListOfShape from TopTools; 
-                       PW    : ProjectedWires  from  LocOpe)
+                       PW    : WiresOnShape  from  LocOpe)
 -- Modified by skv - Mon May 31 12:54:11 2004 OCC5865 End
     
        is static;
index 1b03d87..52da359 100644 (file)
@@ -60,7 +60,7 @@ LocOpe_BuildWires::LocOpe_BuildWires () : myDone(Standard_False)
 
 //  Modified by skv - Mon May 31 12:58:27 2004 OCC5865 Begin
 LocOpe_BuildWires::LocOpe_BuildWires (const TopTools_ListOfShape& L,
-                                     const Handle(LocOpe_ProjectedWires)& PW)
+                                     const Handle(LocOpe_WiresOnShape)& PW)
 {
   Perform(L, PW);
 }
@@ -74,7 +74,7 @@ LocOpe_BuildWires::LocOpe_BuildWires (const TopTools_ListOfShape& L,
 
 //  Modified by skv - Mon May 31 12:59:09 2004 OCC5865 Begin
 void LocOpe_BuildWires::Perform(const TopTools_ListOfShape& L,
-                               const Handle(LocOpe_ProjectedWires)& PW)
+                               const Handle(LocOpe_WiresOnShape)& PW)
 {
 //  Modified by skv - Mon May 31 12:59:10 2004 OCC5865 End
   myDone = Standard_False;
diff --git a/src/LocOpe/LocOpe_ProjectedWires.cdl b/src/LocOpe/LocOpe_ProjectedWires.cdl
deleted file mode 100644 (file)
index 69d054b..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
--- Created on: 1996-01-08
--- Created by: Jacques GOUSSARD
--- Copyright (c) 1996-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
-deferred class ProjectedWires from LocOpe inherits TShared from MMgt
-
-       ---Purpose: 
-
-uses Face   from TopoDS,
-     Wire   from TopoDS,
-     Edge   from TopoDS,
-     Vertex from TopoDS,
-     Shape  from TopoDS
-
-is
-
-    InitEdgeIterator(me: mutable)
-    
-       is deferred;
-
-
-    MoreEdge(me: mutable)
-       returns Boolean from Standard
-       is deferred;
-
-
-    Edge(me: mutable)
-       returns Edge from TopoDS
-       is deferred;
-
-
-    OnFace(me: mutable)
-       ---Purpose: Returns the face of the shape on which the current
-       --          edge is projected.
-       returns Face from TopoDS
-       is deferred;
-
-    
-    OnEdge(me: mutable; E: out Edge from TopoDS)
-       ---Purpose: If the   current  edge is  projected  on  an edge,
-       --          returns <Standard_True> and sets the value of <E>.
-       --          Otherwise, returns <Standard_False>.
-       returns Boolean from Standard
-       is deferred;
-
-
-    NextEdge(me: mutable)
-    
-       is deferred;
-
-
-    OnVertex(me: mutable; Vwire :     Vertex from TopoDS;
-                         Vshape: out Vertex from TopoDS)
-                         
-       returns Boolean from Standard
-       is deferred;
-
-
-    OnEdge(me: mutable; V: Vertex from TopoDS;
-                        E: out Edge from TopoDS;
-                       P: out Real from Standard)
-       ---Purpose: If the vertex <V> lies on  an edge of the original
-       --          shape,  returns     <Standard_True> and   sets the
-       --          concerned edge in  <E>,  and the parameter on  the
-       --          edge in <P>.
-       --          Else returns <Standard_False>.
-       returns Boolean from Standard
-       is deferred;
-
-    IsFaceWithSection(me; aFace : Shape from TopoDS)
-       ---Purpose: tells is the face to be split by section or not
-       returns Boolean from Standard
-       is deferred;
-
-end ProjectedWires;
diff --git a/src/LocOpe/LocOpe_ProjectedWires.cxx b/src/LocOpe/LocOpe_ProjectedWires.cxx
deleted file mode 100644 (file)
index 941d9e5..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Created on: 1996-01-08
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1996-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <LocOpe_ProjectedWires.ixx>
index fad5a9b..834cfa2 100644 (file)
@@ -20,7 +20,7 @@ class Spliter from LocOpe
 
 uses Shape                     from TopoDS,
      Face                      from TopoDS,
-     ProjectedWires            from LocOpe,
+     WiresOnShape              from LocOpe,
      ListOfShape               from TopTools,
      DataMapOfShapeListOfShape from TopTools
 
@@ -50,7 +50,7 @@ is
        is static;
 
 
-    Perform(me: in out; PW: ProjectedWires from LocOpe)
+    Perform(me: in out; PW: WiresOnShape from LocOpe)
                        
        raises NullObject from Standard         
        is static;
index 4d1c87d..002f7af 100644 (file)
 
 #include <LocOpe_Spliter.ixx>
 
-#include <LocOpe_ProjectedWires.hxx>
+//#include <LocOpe_ProjectedWires.hxx>
 
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
@@ -56,7 +58,7 @@
 //  Modified by skv - Mon May 31 13:00:30 2004 OCC5865 Begin
 // static void RebuildWires(TopTools_ListOfShape&);
 static void RebuildWires(TopTools_ListOfShape&,
-                        const Handle(LocOpe_ProjectedWires)&);
+                        const Handle(LocOpe_WiresOnShape)&);
 //  Modified by skv - Mon May 31 13:00:31 2004 OCC5865 End
 
 static void Put(const TopoDS_Shape&,
@@ -71,7 +73,7 @@ static void Select(const TopoDS_Edge&,
 //purpose  : 
 //=======================================================================
 
-void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
+void LocOpe_Spliter::Perform(const Handle(LocOpe_WiresOnShape)& PW)
 {
   if (myShape.IsNull()) {
     Standard_NullObject::Raise();
@@ -150,7 +152,7 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
       if (!mapV.Contains(vtx)) {
        mapV.Add(vtx);
-       if (PW->OnEdge(vtx,Ed,prm)) {
+       if (PW->OnEdge(vtx,edg,Ed,prm)) {
          // on devrait verifier que le vtx n`existe pas deja sur l`edge
          if(!myMap.IsBound(Ed)) continue;
          Ed = TopoDS::Edge(myMap(Ed).First());
@@ -323,6 +325,69 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
     myRes = theSubs.Copy(myRes).First();
   }
 
+  ////remove superfluous vertices on degenerated edges
+  theSubs.Clear();
+  TopTools_IndexedMapOfShape Emap;
+  TopExp::MapShapes(myRes, TopAbs_EDGE, Emap);
+  TopTools_SequenceOfShape DegEdges;
+  Standard_Integer i, j;
+  for (i = 1; i <= Emap.Extent(); i++)
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(i));
+    if (BRep_Tool::Degenerated(anEdge))
+      DegEdges.Append(anEdge);
+  }
+  
+  TopTools_SequenceOfShape DegWires;
+  for (;;)
+  {
+    if (DegEdges.IsEmpty())
+      break;
+    TopoDS_Wire aDegWire;
+    BB.MakeWire(aDegWire);
+    BB.Add(aDegWire, DegEdges(1));
+    DegEdges.Remove(1);
+    TopoDS_Vertex Vfirst, Vlast;
+    for (;;)
+    {
+      TopExp::Vertices(aDegWire, Vfirst, Vlast);
+      Standard_Boolean found = Standard_False;
+      for (i = 1; i <= DegEdges.Length(); i++)
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(DegEdges(i));
+        TopoDS_Vertex V1, V2;
+        TopExp::Vertices(anEdge, V1, V2);
+        if (V1.IsSame(Vfirst) || V1.IsSame(Vlast) || V2.IsSame(Vfirst) || V2.IsSame(Vlast))
+        {
+          BB.Add(aDegWire, anEdge);
+          DegEdges.Remove(i);
+          found = Standard_True;
+          break;
+        }
+      }
+      if (!found)
+        break;
+    }
+    DegWires.Append(aDegWire);
+  }
+
+  for (i = 1; i <= DegWires.Length(); i++)
+  {
+    TopTools_IndexedMapOfShape Vmap;
+    TopExp::MapShapes(DegWires(i), TopAbs_VERTEX, Vmap);
+    TopTools_ListOfShape LV;
+    LV.Append(Vmap(1).Oriented(TopAbs_FORWARD));
+    for (j = 2; j <= Vmap.Extent(); j++)
+    {
+      if (!Vmap(j).IsSame(Vmap(1)))
+        theSubs.Substitute(Vmap(j), LV);
+    }
+  }
+  theSubs.Build(myRes);
+  if (theSubs.IsCopied(myRes))
+    myRes = theSubs.Copy(myRes).First();
+  ////
+
   myDLeft.Clear();
   myLeft.Clear();
   mapV.Clear();
@@ -483,7 +548,7 @@ const TopTools_ListOfShape& LocOpe_Spliter::Left() const
 //  Modified by skv - Mon May 31 12:31:39 2004 OCC5865 Begin
 //static void RebuildWires(TopTools_ListOfShape& ledge)
 static void RebuildWires(TopTools_ListOfShape& ledge,
-                        const Handle(LocOpe_ProjectedWires)& PW)
+                        const Handle(LocOpe_WiresOnShape)& PW)
 {
   LocOpe_BuildWires theBuild(ledge, PW);
 //  Modified by skv - Mon May 31 12:31:40 2004 OCC5865 End
index a893a58..2527774 100644 (file)
@@ -14,7 +14,7 @@
 -- Alternatively, this file may be used under the terms of Open CASCADE
 -- commercial license or contractual agreement.
 
-class WiresOnShape from LocOpe inherits ProjectedWires from LocOpe
+class WiresOnShape from LocOpe inherits TShared from MMgt
 
        ---Purpose: 
 
@@ -134,6 +134,18 @@ is
        returns Boolean from Standard
        ;
        
+    OnEdge(me: mutable; V: Vertex from TopoDS;
+                       EdgeFrom: Edge from TopoDS;
+                        E: out Edge from TopoDS;
+                       P: out Real from Standard)
+       ---Purpose: If the vertex <V> lies on  an edge of the original
+       --          shape,  returns     <Standard_True> and   sets the
+       --          concerned edge in  <E>,  and the parameter on  the
+       --          edge in <P>.
+       --          Else returns <Standard_False>.
+       returns Boolean from Standard
+       ;
+       
     IsFaceWithSection(me; aFace : Shape from TopoDS)
        ---Purpose: tells is the face to be split by section or not
        ---C++: inline
index 712c1d4..905d616 100644 (file)
@@ -24,6 +24,7 @@
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <Geom_Curve.hxx>
@@ -56,6 +57,7 @@
 
 
 static Standard_Boolean Project(const TopoDS_Vertex&,
+                                const gp_Pnt2d&,
                                const TopoDS_Face&,
                                TopoDS_Edge&,
                                Standard_Real&);
@@ -63,6 +65,11 @@ static Standard_Boolean Project(const TopoDS_Vertex&,
 static Standard_Real Project(const TopoDS_Vertex&,
                             const TopoDS_Edge&);
 
+static Standard_Real Project(const TopoDS_Vertex&,
+                             const gp_Pnt2d&,
+                            const TopoDS_Edge&,
+                             const TopoDS_Face&);
+
 
 static void PutPCurve(const TopoDS_Edge&,
                      const TopoDS_Face&);
@@ -274,9 +281,14 @@ void LocOpe_WiresOnShape::BindAll()
       if (theMap.Contains(vtx)) {
        continue;
       }
+      ////
+      Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg);
+      BRepAdaptor_Curve2d BAcurve2d(edg, fac);
+      gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
+      ////
       TopoDS_Edge Epro;
-      Standard_Real prm;
-      Standard_Boolean ok = Project(vtx,fac,Epro,prm);
+      Standard_Real prm = 0.;
+      Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm);
       if (ok) {
        for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
          const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
@@ -284,8 +296,13 @@ void LocOpe_WiresOnShape::BindAll()
            break;
          }
          else if (BRepTools::Compare(vtx,vtx2)) {
-           myMap.Bind(vtx,vtx2);
-           break;
+            if (!BRep_Tool::Degenerated(Epro) ||
+                Abs(prm-BAcurve2d.FirstParameter()) <= Precision::PConfusion() ||
+                Abs(prm-BAcurve2d.LastParameter())  <= Precision::PConfusion())
+            {
+              myMap.Bind(vtx,vtx2);
+              break;
+            }
          }
        }
        if (!exp2.More()) {
@@ -408,8 +425,6 @@ Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
 }
 
 
-
-
 //=======================================================================
 //function : OnEdge
 //purpose  : 
@@ -429,6 +444,32 @@ Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
   return Standard_True;
 }
 
+//=======================================================================
+//function : OnEdge
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
+                                             const TopoDS_Edge& EdgeFrom,
+                                             TopoDS_Edge& Ed,
+                                             Standard_Real& prm)
+{
+  if (!myMap.IsBound(V) ||
+      myMap(V).ShapeType() == TopAbs_VERTEX) {
+    return Standard_False;
+  }
+  
+  Ed = TopoDS::Edge(myMap(V));
+  TopoDS_Face theFace = TopoDS::Face(myMapEF.FindFromKey(EdgeFrom));
+  ////
+  Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom);
+  BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, theFace);
+  gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
+  ////
+  prm = Project(V, p2d, Ed, theFace);
+  return Standard_True;
+}
+
 
 //=======================================================================
 //function : Project
@@ -436,36 +477,32 @@ Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
 //=======================================================================
 
 Standard_Boolean Project(const TopoDS_Vertex& V,
+                         const gp_Pnt2d& p2d,
                         const TopoDS_Face& F,
                         TopoDS_Edge& theEdge,
                         Standard_Real& param)
 {
-  Handle(Geom_Curve) C;
-  TopLoc_Location Loc;
+  Handle(Geom2d_Curve) PC;
+  //TopLoc_Location Loc;
   Standard_Real f,l;
 
   Standard_Real dmin = RealLast();
-  gp_Pnt toproj(BRep_Tool::Pnt(V));
+  //gp_Pnt toproj(BRep_Tool::Pnt(V));
   Standard_Boolean valret = Standard_False;
-  GeomAPI_ProjectPointOnCurve proj;
+  Geom2dAPI_ProjectPointOnCurve proj;
 
   for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
        exp.More(); exp.Next()) {
     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
-    if (!BRep_Tool::Degenerated(edg)) {
-      C = BRep_Tool::Curve(edg,Loc,f,l);
-      if (!Loc.IsIdentity()) {
-       Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
-       C = *((Handle(Geom_Curve)*)&GG);
-      }
-      proj.Init(toproj,C,f,l);
-      if (proj.NbPoints() > 0) {
-       if (proj.LowerDistance() < dmin) {
-         theEdge = edg;
-         theEdge.Orientation(edg.Orientation());
-         dmin = proj.LowerDistance();
-         param = proj.LowerDistanceParameter();
-       }
+    //C = BRep_Tool::Curve(edg,Loc,f,l);
+    PC = BRep_Tool::CurveOnSurface(edg, F, f, l);
+    proj.Init(p2d, PC, f, l);
+    if (proj.NbPoints() > 0) {
+      if (proj.LowerDistance() < dmin) {
+        theEdge = edg;
+        theEdge.Orientation(edg.Orientation());
+        dmin = proj.LowerDistance();
+        param = proj.LowerDistanceParameter();
       }
     }
   }
@@ -514,6 +551,35 @@ Standard_Real Project(const TopoDS_Vertex& V,
   return proj.LowerDistanceParameter();
 }
 
+//=======================================================================
+//function : Project
+//purpose  : 
+//=======================================================================
+
+Standard_Real Project(const TopoDS_Vertex&,
+                      const gp_Pnt2d&      p2d,
+                     const TopoDS_Edge& theEdge,
+                      const TopoDS_Face& theFace)
+{
+  //Handle(Geom_Curve) C;
+  Handle(Geom2d_Curve) PC;
+  //TopLoc_Location Loc;
+  Standard_Real f,l;
+
+  Geom2dAPI_ProjectPointOnCurve proj;
+
+  PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
+  /*
+  if (!Loc.IsIdentity()) {
+    Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
+    C = *((Handle(Geom_Curve)*)&GG);
+  }
+  */
+  proj.Init(p2d, PC, f, l);
+
+  return proj.LowerDistanceParameter();
+}
+
 
 //=======================================================================
 //function : PutPCurve
@@ -944,7 +1010,13 @@ void PutPCurves(const TopoDS_Edge& Efrom,
 
     C->D1(f,pt,d1f);
 
-    Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),Eto);
+    ////
+    TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
+    Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
+    BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
+    gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
+    ////
+    Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
     
     C = BRep_Tool::Curve(Eto,Loc,f,l);
     if (!Loc.IsIdentity()) {
diff --git a/tests/bugs/modalg_5/bug25243 b/tests/bugs/modalg_5/bug25243
new file mode 100644 (file)
index 0000000..3005c97
--- /dev/null
@@ -0,0 +1,27 @@
+puts "========"
+puts "OCC25243"
+puts "========"
+puts ""
+##################################################################################
+# BRepFeat_SplitShape algorithm processes incorrect faces with degenerated edges
+##################################################################################
+
+restore [locate_data_file bug25243_Context.brep] a
+restore [locate_data_file bug25243_splitterEdge_1_1.brep] e
+
+smallview
+
+explode a
+
+donly a_4 e
+fit
+
+splitshape result a_4 a_4 e
+
+set bug_info [checkshape result]
+if {[string compare $bug_info "This shape seems to be valid"] != 0} {
+  puts "ERROR: OCC25243 is reproduced"
+  puts "       shape result is invalid"
+}
+
+set only_screen_axo 1