0025957: nurbsconvert modifies original shape
authorisn <isn@opencascade.com>
Tue, 7 Jun 2016 04:20:13 +0000 (07:20 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 18 Aug 2016 11:46:13 +0000 (14:46 +0300)
- Ensure that the subshapes from the original shape will not be changed after nurbsconvert operation.
For that create the new vertexes (NewPoint(..)) as well as new curves (NewCurve(..)) and new surfaces (NewSurface(..)) before calling of Rebuild() method. Make copies of all vertexes impacted by curve or surface modifications. This eliminates necessity of creation of new vertices during recursive rebuilding of the entire shape.

- Compatibility with the old behavior of BRepTools_Modifier has been retained as an option. For that the new flag MutableInput has been added in the interface of the class.

- This patch also impacts other operations based on BRepTools_Modifier, in the sense that they also become safe regarding input shapes.

- Create new test cases. Some test cases with nurbsconvert command are changed to lock input shapes from modifications.

fix regressions

12 files changed:
src/BRepTools/BRepTools_Modifier.cxx
src/BRepTools/BRepTools_Modifier.hxx
src/BRepTools/BRepTools_NurbsConvertModification.cxx
src/ShapeProcess/ShapeProcess_OperLibrary.cxx
src/ShapeProcess/ShapeProcess_OperLibrary.hxx
tests/bugs/iges/bug25632_2
tests/bugs/modalg_5/bug25976
tests/bugs/modalg_6/bug24890
tests/bugs/modalg_6/bug25957_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug25957_2 [new file with mode: 0644]
tests/bugs/moddata_2/bug466
tests/bugs/moddata_3/bug623

index e92ec7b2ba7767ce3162006d48c6820415dc1f46..eb8cf010ee5435a37c712df16d49a686ce6c9bef 100644 (file)
 #include <Message_ProgressSentry.hxx>
 #include <Geom_Surface.hxx>
 
+static void SetShapeFlags(const TopoDS_Shape& theInSh, TopoDS_Shape& theOutSh);
 
 //=======================================================================
 //function : BRepTools_Modifier
 //purpose  : 
 //=======================================================================
 
-BRepTools_Modifier::BRepTools_Modifier ():myDone(Standard_False)
+BRepTools_Modifier::BRepTools_Modifier (Standard_Boolean theMutableInput):
+myDone(Standard_False), myMutableInput (theMutableInput)
 {}
 
 //=======================================================================
@@ -72,9 +74,8 @@ BRepTools_Modifier::BRepTools_Modifier ():myDone(Standard_False)
 //=======================================================================
 
 BRepTools_Modifier::BRepTools_Modifier (const TopoDS_Shape& S) :
-  myShape(S),myDone(Standard_False)
+myShape(S),myDone(Standard_False), myMutableInput (Standard_False)
 {
-  myMap.Clear();
   Put(S);
 }
 
@@ -85,9 +86,10 @@ BRepTools_Modifier::BRepTools_Modifier (const TopoDS_Shape& S) :
 
 BRepTools_Modifier::BRepTools_Modifier
   (const TopoDS_Shape& S,
-   const Handle(BRepTools_Modification)& M) : myShape(S),myDone(Standard_False)
+   const Handle(BRepTools_Modification)& M)
+   : myShape(S), myDone(Standard_False), 
+     myMutableInput (Standard_False)
 {
-  myMap.Clear();
   Put(S);
   Perform(M);
 }
@@ -102,7 +104,6 @@ void BRepTools_Modifier::Init(const TopoDS_Shape& S)
 {
   myShape = S;
   myDone = Standard_False;
-  myMap.Clear();
   Put(S);
 }
 
@@ -111,34 +112,39 @@ void BRepTools_Modifier::Init(const TopoDS_Shape& S)
 //function : Perform
 //purpose  : 
 //=======================================================================
+#ifdef DEBUG_Modifier
+static TopTools_IndexedMapOfShape MapE, MapF;
+#endif
 
 void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M, const Handle(Message_ProgressIndicator) & aProgress)
 {
   if (myShape.IsNull()) {
     Standard_NullObject::Raise();
   }
+#ifdef DEBUG_Modifier
+  MapE.Clear(); MapF.Clear();
+  TopExp::MapShapes(myShape, TopAbs_EDGE, MapE);
+  TopExp::MapShapes(myShape, TopAbs_FACE, MapF);
+#endif
   TopTools_DataMapIteratorOfDataMapOfShapeShape theIter(myMap);
 
-  // Set to Null the value of shapes, in case when another modification is applied to the start shape.
+  Message_ProgressSentry aPSentry(aProgress, "Converting Shape", 0, 2, 1);
 
-  if (!theIter.Value().IsNull()) {
-    while (theIter.More()) {
-      myMap(theIter.Value()).Nullify();
-      theIter.Next();
-    }
-    theIter.Reset();
-  }
+  TopTools_IndexedDataMapOfShapeListOfShape aMVE, aMEF;
+  TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
+  TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aMEF);
 
-  /*
-  while (theIter.More()) {
-    Rebuild(theIter.Key(),M);
-    theIter.Next();
-  }
-  */
+  CreateNewVertices(aMVE, M);
 
-  Message_ProgressSentry aPSentry(aProgress, "Converting Shape", 0, 2, 1);
+  FillNewCurveInfo(aMEF, M);
+
+  FillNewSurfaceInfo(M);
 
-  Rebuild(myShape, M, aProgress);
+  if (!myMutableInput)
+    CreateOtherVertices(aMVE, aMEF, M);
+
+  Standard_Boolean aNewGeom;
+  Rebuild(myShape, M, aNewGeom, aProgress);
 
   if (!aPSentry.More())
   {
@@ -162,9 +168,8 @@ void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M, const
 
   // Update the continuities
 
-  TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
-  TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
-  BRep_Builder B;
+
+  BRep_Builder aBB;
 
 /*
   Standard_Boolean RecomputeTriangles = Standard_False;
@@ -174,27 +179,13 @@ void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M, const
   TopLoc_Location Loc;
 */
 
-  while (theIter.More()) {
-    const TopoDS_Shape& S = theIter.Key();
-/*
-    if (S.ShapeType() == TopAbs_FACE && !S.IsSame(theIter.Value())) {
-      Tr = BRep_Tool::Triangulation(TopoDS::Face(S),Loc);
-      if (!Tr.IsNull()) {
-        RecomputeTriangles = Standard_True;
-        MaxDeflection = Max(MaxDeflection,Tr->Deflection());
-      }
-    }
-    else */ if (S.ShapeType() == TopAbs_EDGE && !S.IsSame(theIter.Value())) {
-      const TopoDS_Edge& edg = TopoDS::Edge(S);
-/*
-      Po = BRep_Tool::Polygon3D(edg,Loc);
-      if (!Po.IsNull()) {
-       RecomputeTriangles = Standard_True;
-       MaxDeflection = Max(MaxDeflection,Po->Deflection());
-      }
-*/
+  for (int ii = 1; ii <= aMEF.Extent(); ii++)
+  {
+    const TopoDS_Edge& CurE = TopoDS::Edge(aMEF.FindKey(ii));
+    const TopoDS_Edge& NewE = TopoDS::Edge(myMap(CurE));
+    if (!CurE.IsSame(NewE)) {
       TopTools_ListIteratorOfListOfShape it;
-      it.Initialize(theEFMap.FindFromKey(edg));
+      it.Initialize(aMEF.FindFromKey(CurE));
       TopoDS_Face F1,F2;
       while (it.More() && F2.IsNull()) {
         if (F1.IsNull()) {
@@ -206,12 +197,11 @@ void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M, const
         it.Next();
       }
       if (!F2.IsNull()) {
-        const TopoDS_Edge& newedg = TopoDS::Edge(myMap(edg));
         const TopoDS_Face& newf1  = TopoDS::Face(myMap(F1));
         const TopoDS_Face& newf2  = TopoDS::Face(myMap(F2));
-        GeomAbs_Shape Newcont = M->Continuity(edg,F1,F2,newedg,newf1,newf2);
+        GeomAbs_Shape Newcont = M->Continuity(CurE,F1,F2,NewE,newf1,newf2);
         if (Newcont > GeomAbs_C0) {
-          B.Continuity(newedg,newf1,newf2,Newcont);
+          aBB.Continuity(NewE,newf1,newf2,Newcont);
         }
       }
     }
@@ -251,11 +241,20 @@ void BRepTools_Modifier::Put(const TopoDS_Shape& S)
 Standard_Boolean BRepTools_Modifier::Rebuild
   (const TopoDS_Shape& S,
    const Handle(BRepTools_Modification)& M,
+   Standard_Boolean& theNewGeom,
    const Handle(Message_ProgressIndicator)& aProgress)
 {
+#ifdef DEBUG_Modifier
+  int iF = MapF.Contains(S) ? MapF.FindIndex(S) : 0;
+  int iE = MapE.Contains(S) ? MapE.FindIndex(S) : 0;
+#endif
+  TopAbs_ShapeEnum ts = S.ShapeType();
   TopoDS_Shape& result = myMap(S);
-//  if (!result.IsNull()) return ! S.IsEqual(result);
-  if (!result.IsNull()) return ! S.IsSame(result);
+  if (!result.IsNull())
+  {
+    theNewGeom = myHasNewGeom.Contains(S);
+    return !S.IsSame(result);
+  }
   Standard_Boolean rebuild = Standard_False, RevWires = Standard_False;
   TopAbs_Orientation ResOr = TopAbs_FORWARD;
   BRep_Builder B;
@@ -265,26 +264,21 @@ Standard_Boolean BRepTools_Modifier::Rebuild
 
   // new geometry ?
 
-  TopAbs_ShapeEnum ts = S.ShapeType();
   switch (ts) {
   case TopAbs_FACE:
     {
-      Standard_Boolean RevFace;
-      Handle(Geom_Surface) surface;
-      TopLoc_Location location;
-      rebuild = M->NewSurface(TopoDS::Face(S),surface,location,tol,
-                             RevWires,RevFace);
-      if (rebuild) {
-       B.MakeFace(TopoDS::Face(result),surface,
-                  location.Predivided(S.Location()),tol);
-       result.Location(S.Location());
-//     result.Orientation(S.Orientation());
-       if (RevFace) {
-         ResOr = TopAbs_REVERSED;
-       }
-       // set specifics flags of a Face
-       B.NaturalRestriction(TopoDS::Face(result),
-                            BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
+      rebuild = myNSInfo.IsBound(TopoDS::Face(S));
+      if (rebuild) 
+      {
+        const NewSurfaceInfo& aNSinfo = myNSInfo(TopoDS::Face(S));
+        RevWires = aNSinfo.myRevWires;
+        B.MakeFace(TopoDS::Face(result),aNSinfo.mySurface,
+          aNSinfo.myLoc.Predivided(S.Location()),aNSinfo.myToler);
+        result.Location(S.Location());
+        if (aNSinfo.myRevFace) 
+          ResOr = TopAbs_REVERSED;
+        // set specifics flags of a Face
+        B.NaturalRestriction(TopoDS::Face(result), BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
       }
 
       // update triangulation on the copied face
@@ -305,20 +299,20 @@ Standard_Boolean BRepTools_Modifier::Rebuild
 
   case TopAbs_EDGE:
     {
-      Handle(Geom_Curve) curve;
-      TopLoc_Location location;
-      rebuild = M->NewCurve(TopoDS::Edge(S),curve,location,tol);
-      if (rebuild) {
-       if (curve.IsNull()) {
+      rebuild = myNCInfo.IsBound(TopoDS::Edge(S));
+      if (rebuild) 
+      {
+        const NewCurveInfo& aNCinfo = myNCInfo(TopoDS::Edge(S));
+        if (aNCinfo.myCurve.IsNull()) {
          B.MakeEdge(TopoDS::Edge(result));
          B.Degenerated(TopoDS::Edge(result),
                        BRep_Tool::Degenerated(TopoDS::Edge(S)));
-         B.UpdateEdge(TopoDS::Edge(result),tol);  //OCC217
+          B.UpdateEdge(TopoDS::Edge(result),aNCinfo.myToler);  //OCC217
          No3DCurve = Standard_True;
        }
        else {
-         B.MakeEdge(TopoDS::Edge(result),curve,
-                    location.Predivided(S.Location()),tol);
+          B.MakeEdge(TopoDS::Edge(result),aNCinfo.myCurve,
+            aNCinfo.myLoc.Predivided(S.Location()),aNCinfo.myToler);
          No3DCurve = Standard_False;
        }
        result.Location(S.Location());
@@ -346,25 +340,14 @@ Standard_Boolean BRepTools_Modifier::Rebuild
       }
     }
     break;
-
-  case TopAbs_VERTEX:
-    {
-      gp_Pnt vtx;
-      rebuild = M->NewPoint(TopoDS::Vertex(S),vtx,tol);
-      if (rebuild) {
-       B.MakeVertex(TopoDS::Vertex(result),vtx,tol);
-      }
-    }
-    break;
-
   default:
-    {
-    }
+    ;
   }
 
   // rebuild sub-shapes and test new sub-shape ?
 
   Standard_Boolean newgeom = rebuild;
+  theNewGeom = rebuild;
 
   TopoDS_Iterator it;
 
@@ -378,8 +361,10 @@ Standard_Boolean BRepTools_Modifier::Rebuild
     //
     for (it.Initialize(S, Standard_False); it.More() && aPSentry.More(); it.Next(), aPSentry.Next()) {
       // always call Rebuild
-      Standard_Boolean subrebuilt = Rebuild(it.Value(), M, aProgress);
+      Standard_Boolean isSubNewGeom = Standard_False;
+      Standard_Boolean subrebuilt = Rebuild(it.Value(), M, isSubNewGeom, aProgress);
       rebuild =  subrebuilt || rebuild ;
+      theNewGeom = theNewGeom || isSubNewGeom;
     }
     if (!aPSentry.More())
     {
@@ -387,6 +372,8 @@ Standard_Boolean BRepTools_Modifier::Rebuild
       return Standard_False;
     }
   }
+  if (theNewGeom)
+    myHasNewGeom.Add(S);
 
   // make an empty copy
   if (rebuild && !newgeom) {
@@ -419,7 +406,11 @@ Standard_Boolean BRepTools_Modifier::Rebuild
       {
         const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
 
-        if (M->NewCurve2d(edge, face, TopoDS::Edge(myMap(ex.Current())), TopoDS::Face(result), curve2d, tol))
+#ifdef DEBUG_Modifier
+        iE = MapE.Contains(edge) ? MapE.FindIndex(edge) : 0;
+#endif
+        if (theNewGeom && M->NewCurve2d
+            (edge, face, TopoDS::Edge(myMap(ex.Current())), TopoDS::Face(result), curve2d, tol))
         {
           // rem dub 16/09/97 : Make constant topology or not make at all.
           // Do not make if CopySurface = 1
@@ -484,8 +475,8 @@ Standard_Boolean BRepTools_Modifier::Rebuild
               if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
               B.UpdateEdge (CurE, curve2d, curve2d1, CurF, 0.);
             }
-            currcurv = BRep_Tool::CurveOnSurface(edge,face,f,l);
-            B.Range(edge,f,l);
+            currcurv = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
+            B.Range(CurE,f,l);
           }
           else {
             B.UpdateEdge(TopoDS::Edge(myMap(ex.Current())),
@@ -589,8 +580,8 @@ Standard_Boolean BRepTools_Modifier::Rebuild
         TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
         aLocalVertex.Orientation(vtxrelat);
         //B.UpdateVertex(TopoDS::Vertex(myMap(vertex).Oriented(vtxrelat)),
-        B.UpdateVertex(aLocalVertex, param, TopoDS::Edge(result), tol);
-
+        if (myMutableInput || !aLocalVertex.IsSame(vertex))
+          B.UpdateVertex(aLocalVertex, param, TopoDS::Edge(result), tol);
         ex.Next();
       }
 
@@ -608,14 +599,193 @@ Standard_Boolean BRepTools_Modifier::Rebuild
   // Set flag of the shape.
   result.Orientation(ResOr);
 
-  result.Modified  (S.Modified());
-  result.Checked   (S.Checked());
-  result.Orientable(S.Orientable());
-  result.Closed    (S.Closed());
-  result.Infinite  (S.Infinite());
-  result.Convex    (S.Convex());
+  SetShapeFlags(S, result);
 
   return rebuild;
 }
 
+void BRepTools_Modifier::CreateNewVertices( const TopTools_IndexedDataMapOfShapeListOfShape& theMVE, const Handle(BRepTools_Modification)& M)
+{
+  double aToler;
+  BRep_Builder aBB;
+  gp_Pnt aPnt;  
+  for (int i = 1; i <= theMVE.Extent(); i++ )
+  {
+    //fill MyMap only with vertices with NewPoint == true
+    const TopoDS_Vertex& aV = TopoDS::Vertex(theMVE.FindKey(i));
+    Standard_Boolean IsNewP = M->NewPoint(aV, aPnt, aToler);
+    if (IsNewP)
+    {
+      TopoDS_Vertex aNewV;
+      aBB.MakeVertex(aNewV, aPnt, aToler);
+      SetShapeFlags(aV, aNewV);
+      myMap(aV) = aNewV;
+      myHasNewGeom.Add(aV);
+    }
+    else if (myMutableInput)
+      myMap(aV) = aV.Oriented(TopAbs_FORWARD);
+  }
+}
+
+void BRepTools_Modifier::FillNewCurveInfo(const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Handle(BRepTools_Modification)& M)
+{
+  Handle(Geom_Curve) aCurve;
+  TopLoc_Location aLocation;
+  BRepTools_Modifier::NewCurveInfo aNCinfo;
+  double aToler;
+  for (int i = 1; i <= theMEF.Extent(); i++ )
+  {
+    const TopoDS_Edge& anE = TopoDS::Edge(theMEF.FindKey(i));
+    Standard_Boolean IsNewCur = M->NewCurve(anE, aCurve, aLocation, aToler);
+    if (IsNewCur)
+    {
+      aNCinfo.myCurve = aCurve;
+      aNCinfo.myLoc = aLocation;
+      aNCinfo.myToler = aToler;
+      myNCInfo.Bind(anE, aNCinfo);
+      myHasNewGeom.Add(anE);
+    }
+  }
+}
+
+void BRepTools_Modifier::FillNewSurfaceInfo(const Handle(BRepTools_Modification)& M)
+{
+  TopTools_IndexedMapOfShape aMF;  
+  TopExp::MapShapes(myShape, TopAbs_FACE, aMF);
+  BRepTools_Modifier::NewSurfaceInfo aNSinfo;
+  for (int i = 1; i <= aMF.Extent(); i++ )
+  {
+    const TopoDS_Face& aF = TopoDS::Face(aMF(i));
+    Standard_Boolean RevFace;
+    Standard_Boolean RevWires;
+    Handle(Geom_Surface) aSurface;
+    TopLoc_Location aLocation;
+    double aToler1;
+    Standard_Boolean IsNewSur = M->NewSurface(aF, aSurface, aLocation, aToler1, RevWires,RevFace);
+    if (IsNewSur)
+    {
+      aNSinfo.mySurface = aSurface;
+      aNSinfo.myLoc = aLocation;
+      aNSinfo.myToler = aToler1;
+      aNSinfo.myRevWires = RevWires;
+      aNSinfo.myRevFace = RevFace;
+      myNSInfo.Bind(aF, aNSinfo);
+      myHasNewGeom.Add(aF);
+    }
+    else
+    {
+      //check if subshapes will be modified 
+      Standard_Boolean notRebuilded = Standard_True;
+      TopExp_Explorer exE(aF, TopAbs_EDGE);
+      while (exE.More() && notRebuilded) 
+      {
+        const TopoDS_Edge& anEE = TopoDS::Edge(exE.Current());
+        if (myNCInfo.IsBound(anEE))
+        {
+          notRebuilded = Standard_False;
+          break;
+        }
+        TopExp_Explorer exV(anEE, TopAbs_VERTEX);
+        while (exV.More() && notRebuilded) 
+        {
+          const TopoDS_Vertex& aVV = TopoDS::Vertex(exV.Current());
+          if (!myMap(aVV).IsNull())
+          {
+            notRebuilded = Standard_False;
+            break;
+          }
+          exV.Next();
+        }
+        exE.Next();
+      }
+      if (notRebuilded)
+      {
+        //subshapes is not going to be modified
+        myNonUpdFace.Add(aF); 
+      }
+    }
+  }
+
+}
+
+void BRepTools_Modifier::CreateOtherVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theMVE, 
+                                             const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, 
+                                             const Handle(BRepTools_Modification)& M)
+{
+  double aToler;
+  //The following logic in some ways repeats the logic from the Rebuild() method.
+  //If the face with its subshapes is not going to be modified 
+  //(i.e. NewSurface() for this face and NewCurve(), NewPoint() for its edges/vertices returns false)
+  //then the calling of NewCurve2d() for this face with its edges is not performed. 
+  //Therefore, the updating of vertices will not present in such cases and 
+  //the EmptyCopied() operation for vertices from this face is not needed. 
+
+  for (int i = 1; i <= theMVE.Extent(); i++ )
+  {
+    const TopoDS_Vertex& aV = TopoDS::Vertex(theMVE.FindKey(i));
+    TopoDS_Vertex aNewV = TopoDS::Vertex(myMap(aV));
+    if ( aNewV.IsNull()) 
+    {
+       const TopTools_ListOfShape& aLEdges = theMVE(i);
+       Standard_Boolean toReplace = Standard_False;
+       TopTools_ListIteratorOfListOfShape it(aLEdges);
+       for (; it.More() && !toReplace; it.Next()) 
+       {
+         const TopoDS_Edge& anE = TopoDS::Edge(it.Value());
+         if (myNCInfo.IsBound(anE) && !myNCInfo(anE).myCurve.IsNull())
+            toReplace = Standard_True;
+
+         if (!toReplace)
+         {
+           const TopTools_ListOfShape& aLFaces = theMEF.FindFromKey(anE);
+           TopTools_ListIteratorOfListOfShape it2(aLFaces);
+           for (; it2.More(); it2.Next()) 
+           {
+             const TopoDS_Face& aF = TopoDS::Face(it2.Value());
+             if (!myNonUpdFace.Contains(aF))
+             {
+               Handle(Geom2d_Curve) aCurve2d;
+               //some NewCurve2d()s may use NewE arg internally, so the 
+               //null TShape as an arg may lead to the exceptions 
+               TopoDS_Edge aDummyE = TopoDS::Edge(anE.EmptyCopied());
+               if (M->NewCurve2d(anE, aF, aDummyE, TopoDS_Face(), aCurve2d, aToler))
+               {
+                 toReplace = true;
+                 break;
+               }
+             }
+           }
+         }
+       }
+       if (toReplace)
+         aNewV = TopoDS::Vertex(aV.EmptyCopied());
+       else
+         aNewV = aV;
+       aNewV.Orientation(TopAbs_FORWARD);
+       myMap(aV) = aNewV;
+    }
+  }
+}
+
+
+static void SetShapeFlags(const TopoDS_Shape& theInSh, TopoDS_Shape& theOutSh)
+{
+  theOutSh.Modified  (theInSh.Modified());
+  theOutSh.Checked   (theInSh.Checked());
+  theOutSh.Orientable(theInSh.Orientable());
+  theOutSh.Closed    (theInSh.Closed());
+  theOutSh.Infinite  (theInSh.Infinite());
+  theOutSh.Convex    (theInSh.Convex());
+}
+
+
+Standard_Boolean BRepTools_Modifier::IsMutableInput() const
+{
+  return myMutableInput;
+}
+
+void BRepTools_Modifier::SetMutableInput(Standard_Boolean theMutableInput)
+{
+  myMutableInput = theMutableInput;
+}
 
index c604279fc9ac91ff888ba162534b0358ae70c7b6..eadab91866ab537af4663662938eafe2e94a15c2 100644 (file)
 #include <Standard_Handle.hxx>
 
 #include <TopTools_DataMapOfShapeShape.hxx>
-#include <TopoDS_Shape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <Standard_Boolean.hxx>
 
 #include <Message_ProgressIndicator.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+#include <TopLoc_Location.hxx>
 
 class Standard_NullObject;
 class Standard_NoSuchObject;
 class TopoDS_Shape;
 class BRepTools_Modification;
 class Message_ProgressIndicator;
-
+class Geom_Curve;
+class Geom_Surface;
 
 //! Performs geometric modifications on a shape.
 class BRepTools_Modifier 
@@ -40,10 +49,9 @@ class BRepTools_Modifier
 public:
 
   DEFINE_STANDARD_ALLOC
-
   
   //! Creates an empty Modifier.
-  Standard_EXPORT BRepTools_Modifier();
+  Standard_EXPORT BRepTools_Modifier(Standard_Boolean theMutableInput = Standard_False);
   
   //! Creates a modifier on the shape <S>.
   Standard_EXPORT BRepTools_Modifier(const TopoDS_Shape& S);
@@ -60,32 +68,72 @@ public:
   
   //! Returns Standard_True if the modification has
   //! been computed successfully.
-    Standard_Boolean IsDone() const;
-  
-  //! Returns the modified shape corresponding to <S>.
-    const TopoDS_Shape& ModifiedShape (const TopoDS_Shape& S) const;
+  Standard_Boolean IsDone() const;
 
+  //! Returns the current mutable input state
+  Standard_EXPORT Standard_Boolean IsMutableInput() const;
 
+  //! Sets the mutable input state
+  //! If true then the input (original) shape can be modified 
+  //! during modification process
+  Standard_EXPORT void SetMutableInput(Standard_Boolean theMutableInput);
 
+  //! Returns the modified shape corresponding to <S>.
+  const TopoDS_Shape& ModifiedShape (const TopoDS_Shape& S) const;
+  
 
 protected:
-
-
-
+  
 
 
 private:
 
-  
+  struct NewCurveInfo
+  {
+    Handle(Geom_Curve) myCurve;
+    TopLoc_Location myLoc;
+    Standard_Real myToler;
+  };
+
+  struct NewSurfaceInfo
+  {
+    Handle(Geom_Surface) mySurface;
+    TopLoc_Location myLoc;
+    Standard_Real myToler;
+    Standard_Boolean myRevWires;
+    Standard_Boolean myRevFace;
+  };
+
   Standard_EXPORT void Put (const TopoDS_Shape& S);
   
-  Standard_EXPORT Standard_Boolean Rebuild (const TopoDS_Shape& S, const Handle(BRepTools_Modification)& M, const Handle(Message_ProgressIndicator)& aProgress = NULL);
+  Standard_EXPORT Standard_Boolean Rebuild (const TopoDS_Shape& S,
+                                            const Handle(BRepTools_Modification)& M,
+                                            Standard_Boolean& theNewGeom,
+                                            const Handle(Message_ProgressIndicator)& aProgress = NULL);
 
+  Standard_EXPORT void CreateNewVertices(
+    const TopTools_IndexedDataMapOfShapeListOfShape& theMVE, 
+    const Handle(BRepTools_Modification)& M);
+
+  Standard_EXPORT void FillNewCurveInfo(
+    const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, 
+    const Handle(BRepTools_Modification)& M);
+
+  Standard_EXPORT void FillNewSurfaceInfo(const Handle(BRepTools_Modification)& M);
+
+  Standard_EXPORT void CreateOtherVertices(
+    const TopTools_IndexedDataMapOfShapeListOfShape& theMVE, 
+    const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, 
+    const Handle(BRepTools_Modification)& M);
 
   TopTools_DataMapOfShapeShape myMap;
   TopoDS_Shape myShape;
   Standard_Boolean myDone;
-
+  NCollection_DataMap<TopoDS_Edge, NewCurveInfo, TopTools_ShapeMapHasher> myNCInfo;
+  NCollection_DataMap<TopoDS_Face, NewSurfaceInfo, TopTools_ShapeMapHasher> myNSInfo;
+  TopTools_MapOfShape myNonUpdFace;
+  TopTools_MapOfShape myHasNewGeom;
+  Standard_Boolean myMutableInput;
 
 };
 
index 7f678ec0c0cd00bf3beb3444793bcf5b9d09a718..698ed411aeb64bf1b9bec84c9d30be9c9a62698f 100644 (file)
@@ -662,6 +662,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewParameter
     Standard_Real& P, 
     Standard_Real& Tol)
 {
+  Tol =  BRep_Tool::Tolerance(V);
   if(BRep_Tool::Degenerated(E))
     return Standard_False;
   Standard_Real f, l, param = BRep_Tool::Parameter(V,E);
index 316988e7322e071278bd667a1b4eea425b5a5dd4..a60900953492506654c88fe6348f2659f53f7caa 100644 (file)
@@ -61,7 +61,8 @@ TopoDS_Shape ShapeProcess_OperLibrary::ApplyModifier (const TopoDS_Shape &S,
                                                       const Handle(ShapeProcess_ShapeContext)& context,
                                                       const Handle(BRepTools_Modification) &M,
                                                       TopTools_DataMapOfShapeShape &map,
-                                                      const Handle(ShapeExtend_MsgRegistrator) &msg)
+                                                      const Handle(ShapeExtend_MsgRegistrator) &msg,
+                                                      Standard_Boolean theMutableInput)
 {
   // protect against INTERNAL/EXTERNAL shapes
   TopoDS_Shape SF = S.Oriented(TopAbs_FORWARD);
@@ -81,7 +82,7 @@ TopoDS_Shape ShapeProcess_OperLibrary::ApplyModifier (const TopoDS_Shape &S,
        res = map.Find ( shape ).Oriented ( shape.Orientation() );
 
       else {
-       res = ApplyModifier (shape, context, M, map );
+       res = ApplyModifier (shape, context, M, map, 0, theMutableInput );
        map.Bind ( shape, res );
       }
       if ( ! res.IsSame ( shape ) ) locModified = Standard_True;
@@ -95,7 +96,9 @@ TopoDS_Shape ShapeProcess_OperLibrary::ApplyModifier (const TopoDS_Shape &S,
   }
 
   // Modify the shape
-  BRepTools_Modifier MD(SF,M);
+  BRepTools_Modifier MD(SF);
+  MD.SetMutableInput(theMutableInput);
+  MD.Perform(M);
   context->RecordModification ( SF, MD, msg );
   return MD.ModifiedShape(SF).Oriented(S.Orientation());
 }
@@ -118,7 +121,7 @@ static Standard_Boolean directfaces (const Handle(ShapeProcess_Context)& context
   Handle(ShapeCustom_DirectModification) DM = new ShapeCustom_DirectModification;
   DM->SetMsgRegistrator( msg );
   TopTools_DataMapOfShapeShape map;
-  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, DM, map, msg );
+  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, DM, map,  msg, Standard_True );
   ctx->RecordModification ( map, msg );
   ctx->SetResult ( res );
   return Standard_True;
@@ -271,7 +274,7 @@ static Standard_Boolean bsplinerestriction (const Handle(ShapeProcess_Context)&
                                         aMaxDeg, aMaxSeg, ModeDeg, Rational, aParameters );
   LD->SetMsgRegistrator( msg );
   TopTools_DataMapOfShapeShape map;
-  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, LD, map, msg );
+  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, LD, map,  msg, Standard_True );
   ctx->RecordModification ( map, msg );
   ctx->SetResult ( res );
   return Standard_True;
@@ -295,7 +298,7 @@ static Standard_Boolean torevol (const Handle(ShapeProcess_Context)& context)
   Handle(ShapeCustom_ConvertToRevolution) CR = new ShapeCustom_ConvertToRevolution();
   CR->SetMsgRegistrator( msg );
   TopTools_DataMapOfShapeShape map;
-  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, CR, map, msg );
+  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, CR, map,  msg, Standard_True );
   ctx->RecordModification ( map, msg );
   ctx->SetResult ( res );
   return Standard_True;
@@ -319,7 +322,7 @@ static Standard_Boolean swepttoelem (const Handle(ShapeProcess_Context)& context
   Handle(ShapeCustom_SweptToElementary) SE = new ShapeCustom_SweptToElementary();
   SE->SetMsgRegistrator( msg );
   TopTools_DataMapOfShapeShape map;
-  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, SE, map, msg );
+  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, SE, map, msg, Standard_True  );
   ctx->RecordModification ( map, msg );
   ctx->SetResult ( res );
   return Standard_True;
@@ -415,7 +418,7 @@ static Standard_Boolean converttobspline (const Handle(ShapeProcess_Context)& co
   CBspl->SetMsgRegistrator( msg );
     
   TopTools_DataMapOfShapeShape map;
-  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier( ctx->Result(), ctx, CBspl, map, msg );
+  TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier( ctx->Result(), ctx, CBspl, map,  msg, Standard_True );
   ctx->RecordModification ( map, msg );
   ctx->SetResult ( res );
   return Standard_True;
index f57ba203c700d0b8148713b6b8cab3a9de5c4565..108f062bbd5c6c4b1078ad589e56eec9c056d3be 100644 (file)
@@ -57,7 +57,14 @@ public:
   
   //! Applies BRepTools_Modification to a shape,
   //! taking into account sharing of components of compounds.
-  Standard_EXPORT static TopoDS_Shape ApplyModifier (const TopoDS_Shape& S, const Handle(ShapeProcess_ShapeContext)& context, const Handle(BRepTools_Modification)& M, TopTools_DataMapOfShapeShape& map, const Handle(ShapeExtend_MsgRegistrator)& msg = 0);
+  //! if theMutableInput vat is set to true then imput shape S
+  //! can be modified during the modification process.
+  Standard_EXPORT static TopoDS_Shape ApplyModifier (const TopoDS_Shape& S, 
+                                                     const Handle(ShapeProcess_ShapeContext)& context, 
+                                                     const Handle(BRepTools_Modification)& M, 
+                                                     TopTools_DataMapOfShapeShape& map,
+                                                     const Handle(ShapeExtend_MsgRegistrator)& msg = 0,
+                                                     Standard_Boolean theMutableInput = Standard_False);
 
 
 
index 13375f304f5ddcfcbfd0d85f35a5621073a7a105..d2a1a50c4db428f32b08af21cdfa324bfdac6fb2 100644 (file)
@@ -12,6 +12,7 @@ mkface face p 0 100 0 100
 smallview
 donly face
 
+setflags face locked
 nurbsconvert r face
 mksurface s r
 
index d270f4d6c062dafba699041957f2bb81ea0fe57f..aaa4d3a4f82eaffed349ef45c189d592a129d51a 100644 (file)
@@ -8,6 +8,7 @@ puts ""
 
 smallview
 restore [locate_data_file OCC25976-copiedFace.brep] f
+setflags f locked
 nurbsconvert r f
 fit
 checkview -screenshot -2d -path ${imagedir}/${test_image}.png
index 13018d469029e60ccbcbca2a2bf4ea290a4fc752..f590c3bbe3e1b2ba17b0ac2e25016bb5b3ac193f 100755 (executable)
@@ -8,6 +8,7 @@ puts ""
 
 restore [locate_data_file bug24890_f0.brep] f0
 
+setflags f0 locked
 nurbsconvert result f0
 
 checkshape result
diff --git a/tests/bugs/modalg_6/bug25957_1 b/tests/bugs/modalg_6/bug25957_1
new file mode 100644 (file)
index 0000000..78da3dd
--- /dev/null
@@ -0,0 +1,12 @@
+puts "============"
+puts "OCC25957"
+puts "============"
+puts ""
+######################################################
+# nurbsconvert modifies original shape
+######################################################
+
+psphere s 10
+setflags s locked
+nurbsconvert q s
+checkshape s
diff --git a/tests/bugs/modalg_6/bug25957_2 b/tests/bugs/modalg_6/bug25957_2
new file mode 100644 (file)
index 0000000..765690b
--- /dev/null
@@ -0,0 +1,13 @@
+puts "============"
+puts "OCC25957"
+puts "============"
+puts ""
+######################################################
+# nurbsconvert modifies original shape
+######################################################
+
+restore [locate_data_file bug25957__face2.brep] s
+checkshape s
+setflags s locked
+nurbsconvert nurbs_s s
+checkshape s
\ No newline at end of file
index 7525c057f3ff935c05dd152cc9fc089c6eb9a129..91d1528e79277b63d1fa6d80bb27dfd145270a41 100755 (executable)
@@ -7,6 +7,7 @@ puts ""
 restore [locate_data_file OCC466.brep] res 
 checkshape res
 
+setflags res locked
 nurbsconvert result res
 
 checkprops result -s 693.577
index b8c7296283cc49b1f8780548484d4f91639251e0..d3b6c851a8aec72f02a08af9fb77e50d45afb969 100644 (file)
@@ -12,6 +12,7 @@ pload XDE
 
 stepread [locate_data_file OCC623.step] a *
 
+setflags a_1 locked
 dchrono h reset
 dchrono h start
 nurbsconvert result a_1