From b47bcd7ea71797f861de917154c8c21e112fc62f Mon Sep 17 00:00:00 2001 From: isn Date: Tue, 7 Jun 2016 07:20:13 +0300 Subject: [PATCH] 0025957: nurbsconvert modifies original shape - 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 --- src/BRepTools/BRepTools_Modifier.cxx | 370 +++++++++++++----- src/BRepTools/BRepTools_Modifier.hxx | 76 +++- .../BRepTools_NurbsConvertModification.cxx | 1 + src/ShapeProcess/ShapeProcess_OperLibrary.cxx | 19 +- src/ShapeProcess/ShapeProcess_OperLibrary.hxx | 9 +- tests/bugs/iges/bug25632_2 | 1 + tests/bugs/modalg_5/bug25976 | 1 + tests/bugs/modalg_6/bug24890 | 1 + tests/bugs/modalg_6/bug25957_1 | 12 + tests/bugs/modalg_6/bug25957_2 | 13 + tests/bugs/moddata_2/bug466 | 1 + tests/bugs/moddata_3/bug623 | 1 + 12 files changed, 382 insertions(+), 123 deletions(-) create mode 100644 tests/bugs/modalg_6/bug25957_1 create mode 100644 tests/bugs/modalg_6/bug25957_2 diff --git a/src/BRepTools/BRepTools_Modifier.cxx b/src/BRepTools/BRepTools_Modifier.cxx index e92ec7b2ba..eb8cf010ee 100644 --- a/src/BRepTools/BRepTools_Modifier.cxx +++ b/src/BRepTools/BRepTools_Modifier.cxx @@ -57,13 +57,15 @@ #include #include +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; +} diff --git a/src/BRepTools/BRepTools_Modifier.hxx b/src/BRepTools/BRepTools_Modifier.hxx index c604279fc9..eadab91866 100644 --- a/src/BRepTools/BRepTools_Modifier.hxx +++ b/src/BRepTools/BRepTools_Modifier.hxx @@ -22,17 +22,26 @@ #include #include -#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include 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 . 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 . - 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 . + 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 myNCInfo; + NCollection_DataMap myNSInfo; + TopTools_MapOfShape myNonUpdFace; + TopTools_MapOfShape myHasNewGeom; + Standard_Boolean myMutableInput; }; diff --git a/src/BRepTools/BRepTools_NurbsConvertModification.cxx b/src/BRepTools/BRepTools_NurbsConvertModification.cxx index 7f678ec0c0..698ed411ae 100644 --- a/src/BRepTools/BRepTools_NurbsConvertModification.cxx +++ b/src/BRepTools/BRepTools_NurbsConvertModification.cxx @@ -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); diff --git a/src/ShapeProcess/ShapeProcess_OperLibrary.cxx b/src/ShapeProcess/ShapeProcess_OperLibrary.cxx index 316988e732..a609009534 100644 --- a/src/ShapeProcess/ShapeProcess_OperLibrary.cxx +++ b/src/ShapeProcess/ShapeProcess_OperLibrary.cxx @@ -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; diff --git a/src/ShapeProcess/ShapeProcess_OperLibrary.hxx b/src/ShapeProcess/ShapeProcess_OperLibrary.hxx index f57ba203c7..108f062bbd 100644 --- a/src/ShapeProcess/ShapeProcess_OperLibrary.hxx +++ b/src/ShapeProcess/ShapeProcess_OperLibrary.hxx @@ -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); diff --git a/tests/bugs/iges/bug25632_2 b/tests/bugs/iges/bug25632_2 index 13375f304f..d2a1a50c4d 100644 --- a/tests/bugs/iges/bug25632_2 +++ b/tests/bugs/iges/bug25632_2 @@ -12,6 +12,7 @@ mkface face p 0 100 0 100 smallview donly face +setflags face locked nurbsconvert r face mksurface s r diff --git a/tests/bugs/modalg_5/bug25976 b/tests/bugs/modalg_5/bug25976 index d270f4d6c0..aaa4d3a4f8 100644 --- a/tests/bugs/modalg_5/bug25976 +++ b/tests/bugs/modalg_5/bug25976 @@ -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 diff --git a/tests/bugs/modalg_6/bug24890 b/tests/bugs/modalg_6/bug24890 index 13018d4690..f590c3bbe3 100755 --- a/tests/bugs/modalg_6/bug24890 +++ b/tests/bugs/modalg_6/bug24890 @@ -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 index 0000000000..78da3dd248 --- /dev/null +++ b/tests/bugs/modalg_6/bug25957_1 @@ -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 index 0000000000..765690bfb6 --- /dev/null +++ b/tests/bugs/modalg_6/bug25957_2 @@ -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 diff --git a/tests/bugs/moddata_2/bug466 b/tests/bugs/moddata_2/bug466 index 7525c057f3..91d1528e79 100755 --- a/tests/bugs/moddata_2/bug466 +++ b/tests/bugs/moddata_2/bug466 @@ -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 diff --git a/tests/bugs/moddata_3/bug623 b/tests/bugs/moddata_3/bug623 index b8c7296283..d3b6c851a8 100644 --- a/tests/bugs/moddata_3/bug623 +++ b/tests/bugs/moddata_3/bug623 @@ -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 -- 2.20.1