0031479: Modeling Algorithms - exception on geometry transformation of triangulation... IR-2022-07-08
authorazv <azv@opencascade.com>
Fri, 1 Jul 2022 13:46:55 +0000 (16:46 +0300)
committersmoskvin <smoskvin@opencascade.com>
Fri, 8 Jul 2022 16:30:13 +0000 (19:30 +0300)
* Avoid crash in BRepBuilderAPI_GTransform algorithm. The crash in BRepBuilder_Transform has been solved by 0032716.
* Move copying modifier to BRepTools package.
* Implement copying of triangulation in BRepTools_NurbsConvertModification.
* Implement transformation of a triangulation in BRepTools_GTrsfModification.
* Update test case bugs/mesh/bug22778 to clean the triangulation after conversion to NURBS (reproduce the same behavior as before).

src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx
src/BRepTools/BRepTools_CopyModification.cxx [new file with mode: 0644]
src/BRepTools/BRepTools_CopyModification.hxx [new file with mode: 0644]
src/BRepTools/BRepTools_GTrsfModification.cxx
src/BRepTools/BRepTools_GTrsfModification.hxx
src/BRepTools/BRepTools_NurbsConvertModification.cxx
src/BRepTools/BRepTools_NurbsConvertModification.hxx
src/BRepTools/FILES
tests/bugs/mesh/bug22778
tests/bugs/modalg_8/bug31479_1 [new file with mode: 0644]
tests/bugs/modalg_8/bug31479_2 [new file with mode: 0644]

index 36c25a41e526d2cf3478d0400f464dae245c8f4b..fab7de94b7f9411631ad22b176a2aefc8bb9fef6 100644 (file)
 // commercial license or contractual agreement.
 
 
-#include <BRep_Tool.hxx>
 #include <BRepBuilderAPI_Copy.hxx>
-#include <BRepTools_Modification.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Surface.hxx>
-#include <gp_Pnt.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <Poly_Triangulation.hxx>
-
-namespace {
-
-//! Tool class implementing necessary functionality for copying geometry
-class BRepBuilderAPI_Copy_Modification : public BRepTools_Modification 
-{
-public:
-  BRepBuilderAPI_Copy_Modification (const Standard_Boolean copyGeom,
-                                    const Standard_Boolean copyMesh)
-    : myCopyGeom(copyGeom),
-      myCopyMesh(copyMesh)
-  {
-  }
-
-  //! Returns true to indicate the need to copy face;
-  //! copies surface if requested
-  Standard_Boolean NewSurface (const TopoDS_Face& F, Handle(Geom_Surface)& S,
-                               TopLoc_Location& L, Standard_Real& Tol, 
-                               Standard_Boolean& RevWires, Standard_Boolean& RevFace) Standard_OVERRIDE
-  {
-    S = BRep_Tool::Surface(F,L);
-    Tol = BRep_Tool::Tolerance(F);
-    RevWires = RevFace = Standard_False;
-
-    if ( ! S.IsNull() && myCopyGeom )
-      S = Handle(Geom_Surface)::DownCast(S->Copy());
-
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy triangulation;
-  //! copies it if required
-  Standard_Boolean NewTriangulation(const TopoDS_Face& F, Handle(Poly_Triangulation)& T) Standard_OVERRIDE
-  {
-    if (!myCopyMesh
-      && BRep_Tool::IsGeometric (F))
-    {
-      return Standard_False;
-    }
-
-    TopLoc_Location L;
-    T = BRep_Tool::Triangulation(F, L);
-
-    if (T.IsNull())
-      return Standard_False;
-
-    // mesh is copied if and only if the geometry need to be copied too
-    if (myCopyGeom)
-      T = T->Copy();
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy edge;
-  //! copies curves if requested
-  Standard_Boolean NewCurve (const TopoDS_Edge& E, Handle(Geom_Curve)& C,
-                             TopLoc_Location& L, Standard_Real& Tol) Standard_OVERRIDE
-  {
-    Standard_Real f,l;
-    C = BRep_Tool::Curve (E, L, f, l);
-    Tol = BRep_Tool::Tolerance(E);
-
-    if ( ! C.IsNull() && myCopyGeom )
-      C = Handle(Geom_Curve)::DownCast(C->Copy());
-
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy polygon;
-  //! copies it if required
-  Standard_Boolean NewPolygon(const TopoDS_Edge& E, Handle(Poly_Polygon3D)& P) Standard_OVERRIDE
-  {
-    if (!myCopyMesh
-      && BRep_Tool::IsGeometric (E))
-    {
-      return Standard_False;
-    }
-
-    TopLoc_Location aLoc;
-    P = BRep_Tool::Polygon3D(E, aLoc);
-
-    if (P.IsNull())
-      return Standard_False;
-
-    // polygon is copied if and only if the geometry need to be copied too
-    if (myCopyGeom)
-      P = P->Copy();
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy polygon;
-  //! copies it if required
-  Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge& E, const TopoDS_Face& F,
-                                             Handle(Poly_PolygonOnTriangulation)& P) Standard_OVERRIDE
-  {
-    if (!myCopyMesh
-      && BRep_Tool::IsGeometric (E))
-    {
-      return Standard_False;
-    }
-
-    TopLoc_Location aLoc;
-    Handle(Poly_Triangulation) aTria = BRep_Tool::Triangulation(F, aLoc);
-    P = BRep_Tool::PolygonOnTriangulation(E, aTria, aLoc);
-
-    if (P.IsNull())
-      return Standard_False;
-
-    // polygon is copied if and only if the geometry need to be copied too
-    if (myCopyGeom)
-      P = P->Copy();
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy vertex
-  Standard_Boolean NewPoint (const TopoDS_Vertex& V, gp_Pnt& P,
-                             Standard_Real& Tol) Standard_OVERRIDE
-  {
-    P = BRep_Tool::Pnt(V);
-    Tol = BRep_Tool::Tolerance(V);
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy edge;
-  //! copies pcurve if requested
-  Standard_Boolean NewCurve2d (const TopoDS_Edge& E, 
-                               const TopoDS_Face& F,
-                               const TopoDS_Edge& /*NewE*/,
-                               const TopoDS_Face& /*NewF*/,
-                               Handle(Geom2d_Curve)& C, 
-                               Standard_Real& Tol) Standard_OVERRIDE
-  {
-    Tol = BRep_Tool::Tolerance(E);
-    Standard_Real f, l;
-    C = BRep_Tool::CurveOnSurface (E, F, f, l);
-
-    if ( ! C.IsNull() && myCopyGeom )
-      C = Handle(Geom2d_Curve)::DownCast (C->Copy());
-
-    return Standard_True;
-  }
-
-  //! Returns true to indicate the need to copy vertex
-  Standard_Boolean NewParameter (const TopoDS_Vertex& V, const TopoDS_Edge& E,
-                                 Standard_Real& P, Standard_Real& Tol) Standard_OVERRIDE
-  {
-    if (V.IsNull()) return Standard_False; // infinite edge may have Null vertex
-
-    Tol = BRep_Tool::Tolerance(V);
-    P = BRep_Tool::Parameter (V, E);
-
-    return Standard_True;
-  }
-
-  //! Returns the  continuity of E between F1 and F2
-  GeomAbs_Shape Continuity (const TopoDS_Edge& E, const TopoDS_Face& F1,
-                            const TopoDS_Face& F2, const TopoDS_Edge&,
-                            const TopoDS_Face&, const TopoDS_Face&) Standard_OVERRIDE
-  {
-    return BRep_Tool::Continuity (E, F1, F2);
-  }
-
-public:
-  DEFINE_STANDARD_RTTI_INLINE(BRepBuilderAPI_Copy_Modification,BRepTools_Modification)
-
-private: 
-  Standard_Boolean myCopyGeom;
-  Standard_Boolean myCopyMesh;
-};
-
-} // anonymous namespace
+#include <BRepTools_CopyModification.hxx>
 
 //=======================================================================
 //function : BRepBuilderAPI_Copy
@@ -203,7 +25,7 @@ private:
 
 BRepBuilderAPI_Copy::BRepBuilderAPI_Copy ()
 {
-  myModification = new BRepBuilderAPI_Copy_Modification(Standard_True, Standard_False);
+  myModification = new BRepTools_CopyModification(Standard_True, Standard_False);
 }
 
 
@@ -214,7 +36,7 @@ BRepBuilderAPI_Copy::BRepBuilderAPI_Copy ()
 
 BRepBuilderAPI_Copy::BRepBuilderAPI_Copy(const TopoDS_Shape& S, const Standard_Boolean copyGeom, const Standard_Boolean copyMesh)
 {
-  myModification = new BRepBuilderAPI_Copy_Modification(copyGeom, copyMesh);
+  myModification = new BRepTools_CopyModification(copyGeom, copyMesh);
   DoModif(S);
 }
 
@@ -226,7 +48,7 @@ BRepBuilderAPI_Copy::BRepBuilderAPI_Copy(const TopoDS_Shape& S, const Standard_B
 
 void BRepBuilderAPI_Copy::Perform(const TopoDS_Shape& S, const Standard_Boolean copyGeom, const Standard_Boolean copyMesh)
 {
-  myModification = new BRepBuilderAPI_Copy_Modification(copyGeom, copyMesh);
+  myModification = new BRepTools_CopyModification(copyGeom, copyMesh);
   NotDone(); // on force la copie si on vient deja d`en faire une
   DoModif(S);
 }
diff --git a/src/BRepTools/BRepTools_CopyModification.cxx b/src/BRepTools/BRepTools_CopyModification.cxx
new file mode 100644 (file)
index 0000000..7d9a7b2
--- /dev/null
@@ -0,0 +1,215 @@
+// Copyright (c) 1999-2022 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 <BRepTools_CopyModification.hxx>
+
+#include <BRep_Tool.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopoDS_Vertex.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(BRepTools_CopyModification, BRepTools_Modification)
+
+//=======================================================================
+//function : BRepTools_CopyModification
+//purpose  : 
+//=======================================================================
+BRepTools_CopyModification::BRepTools_CopyModification(const Standard_Boolean copyGeom,
+                                                       const Standard_Boolean copyMesh)
+  : myCopyGeom(copyGeom),
+    myCopyMesh(copyMesh)
+{
+}
+
+//=======================================================================
+//function : NewSurface
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewSurface(const TopoDS_Face&    theFace,
+                                                        Handle(Geom_Surface)& theSurf,
+                                                        TopLoc_Location&      theLoc,
+                                                        Standard_Real&        theTol,
+                                                        Standard_Boolean&     theRevWires,
+                                                        Standard_Boolean&     theRevFace)
+{
+  theSurf = BRep_Tool::Surface(theFace, theLoc);
+  theTol = BRep_Tool::Tolerance(theFace);
+  theRevWires = theRevFace = Standard_False;
+
+  if (!theSurf.IsNull() && myCopyGeom)
+    theSurf = Handle(Geom_Surface)::DownCast(theSurf->Copy());
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewTriangulation
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewTriangulation(const TopoDS_Face&          theFace,
+                                                              Handle(Poly_Triangulation)& theTri)
+{
+  if (!myCopyMesh && BRep_Tool::IsGeometric(theFace))
+  {
+    return Standard_False;
+  }
+
+  TopLoc_Location aLoc;
+  theTri = BRep_Tool::Triangulation(theFace, aLoc);
+
+  if (theTri.IsNull())
+    return Standard_False;
+
+  // mesh is copied if and only if the geometry need to be copied too
+  if (myCopyGeom)
+    theTri = theTri->Copy();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewCurve
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewCurve(const TopoDS_Edge&  theEdge,
+                                                      Handle(Geom_Curve)& theCurve,
+                                                      TopLoc_Location&    theLoc,
+                                                      Standard_Real&      theTol)
+{
+  Standard_Real aFirst, aLast;
+  theCurve = BRep_Tool::Curve(theEdge, theLoc, aFirst, aLast);
+  theTol = BRep_Tool::Tolerance(theEdge);
+
+  if (!theCurve.IsNull() && myCopyGeom)
+    theCurve = Handle(Geom_Curve)::DownCast(theCurve->Copy());
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPolygon
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewPolygon(const TopoDS_Edge&      theEdge,
+                                                        Handle(Poly_Polygon3D)& thePoly)
+{
+  if (!myCopyMesh && BRep_Tool::IsGeometric(theEdge))
+  {
+    return Standard_False;
+  }
+
+  TopLoc_Location aLoc;
+  thePoly = BRep_Tool::Polygon3D(theEdge, aLoc);
+
+  if (thePoly.IsNull())
+    return Standard_False;
+
+  // polygon is copied if and only if the geometry need to be copied too
+  if (myCopyGeom)
+    thePoly = thePoly->Copy();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPolygonOnTriangulation
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewPolygonOnTriangulation(
+  const TopoDS_Edge&                   theEdge,
+  const TopoDS_Face&                   theFace,
+  Handle(Poly_PolygonOnTriangulation)& thePoly)
+{
+  if (!myCopyMesh && BRep_Tool::IsGeometric(theEdge))
+  {
+    return Standard_False;
+  }
+
+  TopLoc_Location aLoc;
+  Handle(Poly_Triangulation) aTria = BRep_Tool::Triangulation(theFace, aLoc);
+  thePoly = BRep_Tool::PolygonOnTriangulation(theEdge, aTria, aLoc);
+
+  if (thePoly.IsNull())
+    return Standard_False;
+
+  // polygon is copied if and only if the geometry need to be copied too
+  if (myCopyGeom)
+    thePoly = thePoly->Copy();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPoint
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewPoint(const TopoDS_Vertex& theVertex, 
+                                                      gp_Pnt&              thePnt,
+                                                      Standard_Real&       theTol)
+{
+  thePnt = BRep_Tool::Pnt(theVertex);
+  theTol = BRep_Tool::Tolerance(theVertex);
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewCurve2d
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewCurve2d(const TopoDS_Edge&    theEdge,
+                                                        const TopoDS_Face&    theFace,
+                                                        const TopoDS_Edge&,
+                                                        const TopoDS_Face&,
+                                                        Handle(Geom2d_Curve)& theCurve,
+                                                        Standard_Real&        theTol)
+{
+  theTol = BRep_Tool::Tolerance(theEdge);
+  Standard_Real aFirst, aLast;
+  theCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirst, aLast);
+
+  if (!theCurve.IsNull() && myCopyGeom)
+    theCurve = Handle(Geom2d_Curve)::DownCast(theCurve->Copy());
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewParameter
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_CopyModification::NewParameter(const TopoDS_Vertex& theVertex,
+                                                          const TopoDS_Edge&   theEdge,
+                                                          Standard_Real&       thePnt,
+                                                          Standard_Real&       theTol)
+{
+  if (theVertex.IsNull())
+    return Standard_False; // infinite edge may have Null vertex
+
+  theTol = BRep_Tool::Tolerance(theVertex);
+  thePnt = BRep_Tool::Parameter(theVertex, theEdge);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Continuity
+//purpose  : 
+//=======================================================================
+GeomAbs_Shape BRepTools_CopyModification::Continuity(const TopoDS_Edge& theEdge,
+                                                     const TopoDS_Face& theFace1,
+                                                     const TopoDS_Face& theFace2,
+                                                     const TopoDS_Edge&,
+                                                     const TopoDS_Face&,
+                                                     const TopoDS_Face&)
+{
+  return BRep_Tool::Continuity(theEdge, theFace1, theFace2);
+}
+
+
diff --git a/src/BRepTools/BRepTools_CopyModification.hxx b/src/BRepTools/BRepTools_CopyModification.hxx
new file mode 100644 (file)
index 0000000..9caf2fb
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (c) 1999-2022 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.
+
+#ifndef _BRepTools_CopyModification_HeaderFile
+#define _BRepTools_CopyModification_HeaderFile
+
+#include <BRepTools_Modification.hxx>
+
+class BRepTools_CopyModification;
+DEFINE_STANDARD_HANDLE(BRepTools_CopyModification, BRepTools_Modification)
+
+//! Tool class implementing necessary functionality for copying geometry and triangulation.
+class BRepTools_CopyModification : public BRepTools_Modification
+{
+public:
+  //! Constructor.
+  //! \param[in] theCopyGeom  indicates that the geomtery (surfaces and curves) should be copied
+  //! \param[in] theCopyMesh  indicates that the triangulation should be copied
+  Standard_EXPORT explicit BRepTools_CopyModification(const Standard_Boolean theCopyGeom = Standard_True,
+                                                      const Standard_Boolean theCopyMesh = Standard_True);
+  
+  //! Returns true if theFace has been modified.
+  //! If the face has been modified:
+  //! - theSurf is the new geometry of the face,
+  //! - theLoc is its new location, and
+  //! - theTol is the new tolerance.
+  //! theRevWires, theRevFace are always set to false, because the orientaion is not changed.
+  Standard_EXPORT Standard_Boolean NewSurface(const TopoDS_Face&    theFace,
+                                              Handle(Geom_Surface)& theSurf,
+                                              TopLoc_Location&      theLoc,
+                                              Standard_Real&        theTol,
+                                              Standard_Boolean&     theRevWires,
+                                              Standard_Boolean&     theRevFace) Standard_OVERRIDE;
+
+  //! Returns true if theEdge has been modified.
+  //! If the edge has been modified:
+  //! - theCurve is the new geometric support of the edge,
+  //! - theLoc is the new location, and
+  //! - theTol is the new tolerance.
+  //! If the edge has not been modified, this function
+  //! returns false, and the values of theCurve, theLoc and theTol are not significant.
+  Standard_EXPORT Standard_Boolean NewCurve(const TopoDS_Edge&  theEdge,
+                                            Handle(Geom_Curve)& theCurve,
+                                            TopLoc_Location&    theLoc,
+                                            Standard_Real&      theTol) Standard_OVERRIDE;
+  
+  //! Returns true if theVertex has been modified.
+  //! If the vertex has been modified:
+  //! - thePnt is the new geometry of the vertex, and
+  //! - theTol is the new tolerance.
+  //! If the vertex has not been modified this function
+  //! returns false, and the values of thePnt and theTol are not significant.
+  Standard_EXPORT Standard_Boolean NewPoint(const TopoDS_Vertex& theVertex, gp_Pnt& thePnt, Standard_Real& theTol) Standard_OVERRIDE;
+  
+  //! Returns true if theEdge has a new curve on surface on theFace.
+  //! If a new curve exists:
+  //! - theCurve is the new geometric support of the edge,
+  //! - theTol the new tolerance.
+  //! If no new curve exists, this function returns false, and
+  //! the values of theCurve and theTol are not significant.
+  Standard_EXPORT Standard_Boolean NewCurve2d(const TopoDS_Edge&    theEdge,
+                                              const TopoDS_Face&    theFace,
+                                              const TopoDS_Edge&    theNewEdge,
+                                              const TopoDS_Face&    theNewFace,
+                                              Handle(Geom2d_Curve)& theCurve,
+                                              Standard_Real&        theTol) Standard_OVERRIDE;
+  
+  //! Returns true if theVertex has a new parameter on theEdge.
+  //! If a new parameter exists:
+  //! - thePnt is the parameter, and
+  //! - theTol is the new tolerance.
+  //! If no new parameter exists, this function returns false,
+  //! and the values of thePnt and theTol are not significant.
+  Standard_EXPORT Standard_Boolean NewParameter(const TopoDS_Vertex& theVertex,
+                                                const TopoDS_Edge&   theEdge,
+                                                Standard_Real&       thePnt,
+                                                Standard_Real&       theTol) Standard_OVERRIDE;
+  
+  //! Returns the continuity of theNewEdge between theNewFace1 and theNewFace2.
+  //!
+  //! theNewEdge is the new edge created from theEdge.  theNewFace1
+  //! (resp. theNewFace2) is the new face created from theFace1 (resp. theFace2).
+  Standard_EXPORT GeomAbs_Shape Continuity(const TopoDS_Edge& theEdge,
+                                           const TopoDS_Face& theFace1,
+                                           const TopoDS_Face& theFace2,
+                                           const TopoDS_Edge& theNewEdge,
+                                           const TopoDS_Face& theNewFace1,
+                                           const TopoDS_Face& theNewFace2) Standard_OVERRIDE;
+
+  //! Returns true if the face has been modified according to changed triangulation.
+  //! If the face has been modified:
+  //! - theTri is a new triangulation on the face
+  Standard_EXPORT Standard_Boolean NewTriangulation(const TopoDS_Face& theFace, Handle(Poly_Triangulation)& theTri) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon.
+  //! If the edge has been modified:
+  //! - thePoly is a new polygon
+  Standard_EXPORT Standard_Boolean NewPolygon(const TopoDS_Edge& theEdge, Handle(Poly_Polygon3D)& thePoly) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon on triangulation.
+  //! If the edge has been modified:
+  //! - thePoly is a new polygon on triangulation
+  Standard_EXPORT Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge&                   theEdge,
+                                                             const TopoDS_Face&                   theFace,
+                                                             Handle(Poly_PolygonOnTriangulation)& thePoly) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT(BRepTools_CopyModification, BRepTools_Modification)
+
+private:
+  Standard_Boolean myCopyGeom;
+  Standard_Boolean myCopyMesh;
+};
+
+#endif // _BRepTools_CopyModification_HeaderFile
index dfb116dc889967bc66bc2a19fa1f91e465381bd9..7f2d9731d601243afa604526dc43c7863ae1888c 100644 (file)
@@ -29,6 +29,7 @@
 #include <GeomLib.hxx>
 #include <gp_GTrsf.hxx>
 #include <gp_Pnt.hxx>
+#include <gp_Quaternion.hxx>
 #include <gp_XYZ.hxx>
 #include <Standard_NoSuchObject.hxx>
 #include <Standard_Type.hxx>
@@ -88,7 +89,13 @@ Standard_Boolean BRepTools_GTrsfModification::NewSurface
   gp_GTrsf gtrsf;
   gtrsf.SetVectorialPart(myGTrsf.VectorialPart());
   gtrsf.SetTranslationPart(myGTrsf.TranslationPart());
-  S = Handle(Geom_Surface)::DownCast(BRep_Tool::Surface(F,L)->Copy());
+  S = BRep_Tool::Surface(F, L);
+  if (S.IsNull())
+  {
+    //processing the case when there is no geometry
+    return Standard_False;
+  }
+  S = Handle(Geom_Surface)::DownCast(S->Copy());
 
   Tol = BRep_Tool::Tolerance(F);
   Tol *= myGScale;
@@ -173,7 +180,7 @@ Standard_Boolean BRepTools_GTrsfModification::NewCurve
     C = new Geom_TrimmedCurve(C, f, l);
   }
   L.Identity() ;  
-  return Standard_True;
+  return !C.IsNull();
 }
 
 //=======================================================================
@@ -214,6 +221,11 @@ Standard_Boolean BRepTools_GTrsfModification::NewCurve2d
   Tol *= myGScale;
   Standard_Real f,l;
   C = BRep_Tool::CurveOnSurface(E,F,f,l);
+  if (C.IsNull())
+  {
+    //processing the case when there is no geometry
+    return Standard_False;
+  }
   C = new Geom2d_TrimmedCurve(C, f, l);
   return Standard_True;
 }
@@ -251,4 +263,113 @@ GeomAbs_Shape BRepTools_GTrsfModification::Continuity
   return BRep_Tool::Continuity(E,F1,F2);
 }
 
+//=======================================================================
+//function : NewTriangulation
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_GTrsfModification::NewTriangulation(const TopoDS_Face&          theFace,
+                                                               Handle(Poly_Triangulation)& theTriangulation)
+{
+  TopLoc_Location aLoc;
+  theTriangulation = BRep_Tool::Triangulation(theFace, aLoc);
+  if (theTriangulation.IsNull())
+  {
+    return Standard_False;
+  }
+
+  gp_GTrsf aGTrsf;
+  aGTrsf.SetVectorialPart(myGTrsf.VectorialPart());
+  aGTrsf.SetTranslationPart(myGTrsf.TranslationPart());
+  aGTrsf.Multiply(aLoc.Transformation());
+
+  theTriangulation = theTriangulation->Copy();
+  theTriangulation->SetCachedMinMax(Bnd_Box()); // clear bounding box
+  theTriangulation->Deflection(theTriangulation->Deflection() * Abs(myGScale));
+  // apply transformation to 3D nodes
+  for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbNodes(); ++anInd)
+  {
+    gp_Pnt aP = theTriangulation->Node(anInd);
+    aGTrsf.Transforms(aP.ChangeCoord());
+    theTriangulation->SetNode(anInd, aP);
+  }
+  // modify triangles orientation in case of mirror transformation
+  if (myGScale < 0.0)
+  {
+    for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbTriangles(); ++anInd)
+    {
+      Poly_Triangle aTria = theTriangulation->Triangle(anInd);
+      Standard_Integer aN1, aN2, aN3;
+      aTria.Get(aN1, aN2, aN3);
+      aTria.Set(aN1, aN3, aN2);
+      theTriangulation->SetTriangle(anInd, aTria);
+    }
+  }
+  // modify normals
+  if (theTriangulation->HasNormals())
+  {
+    for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbTriangles(); ++anInd)
+    {
+      gp_Dir aNormal = theTriangulation->Normal(anInd);
+      aNormal.Transform(aGTrsf.Trsf());
+      theTriangulation->SetNormal(anInd, aNormal);
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPolygon
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_GTrsfModification::NewPolygon(const TopoDS_Edge&      theEdge,
+                                                         Handle(Poly_Polygon3D)& thePoly)
+{
+  TopLoc_Location aLoc;
+  thePoly = BRep_Tool::Polygon3D(theEdge, aLoc);
+  if (thePoly.IsNull())
+  {
+    return Standard_False;
+  }
+
+  gp_GTrsf aGTrsf;
+  aGTrsf.SetVectorialPart(myGTrsf.VectorialPart());
+  aGTrsf.SetTranslationPart(myGTrsf.TranslationPart());
+  aGTrsf.Multiply(aLoc.Transformation());
+
+  thePoly = thePoly->Copy();
+  thePoly->Deflection(thePoly->Deflection() * Abs(myGScale));
+  // transform nodes
+  TColgp_Array1OfPnt& aNodesArray = thePoly->ChangeNodes();
+  for (Standard_Integer anId = aNodesArray.Lower(); anId <= aNodesArray.Upper(); ++anId)
+  {
+    gp_Pnt& aP = aNodesArray.ChangeValue(anId);
+    aGTrsf.Transforms(aP.ChangeCoord());
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPolygonOnTriangulation
+//purpose  : 
+//=======================================================================
 
+Standard_Boolean BRepTools_GTrsfModification::NewPolygonOnTriangulation
+ (const TopoDS_Edge& theEdge,
+  const TopoDS_Face& theFace,
+  Handle(Poly_PolygonOnTriangulation)& thePoly)
+{
+  TopLoc_Location aLoc;
+  Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(theFace, aLoc);
+  if (aT.IsNull())
+  {
+    return Standard_False;
+  }
+
+  thePoly = BRep_Tool::PolygonOnTriangulation(theEdge, aT, aLoc);
+  if (!thePoly.IsNull())
+    thePoly = thePoly->Copy();
+  return Standard_True;
+}
index 20c9ca7f72656d3c53f4585046f36810673e34dc..1494397c61e1039388cb41e45563cca150d63258 100644 (file)
@@ -101,6 +101,25 @@ public:
   //! (resp. <F2>).
   Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2, const TopoDS_Edge& NewE, const TopoDS_Face& NewF1, const TopoDS_Face& NewF2) Standard_OVERRIDE;
 
+  //! Returns true if the face has been modified according to changed triangulation.
+  //! If the face has been modified:
+  //! - theTri is a new triangulation on the face
+  Standard_EXPORT Standard_Boolean NewTriangulation(const TopoDS_Face&          theFace,
+                                                    Handle(Poly_Triangulation)& theTri) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon.
+  //! If the edge has been modified:
+  //! - thePoly is a new polygon
+  Standard_EXPORT Standard_Boolean NewPolygon(const TopoDS_Edge&      theEdge,
+                                              Handle(Poly_Polygon3D)& thePoly) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon on triangulation.
+  //! If the edge has been modified:
+  //! - thePoly is a new polygon on triangulation
+  Standard_EXPORT Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge&                   theEdge,
+                                                             const TopoDS_Face&                   theFace,
+                                                             Handle(Poly_PolygonOnTriangulation)& thePoly) Standard_OVERRIDE;
+
 
 
 
index fff0a4d6b83516916ab0c5e42c2f2df51c2aefe8..85a30c63c6e754013988d742e58503db26a99b99 100644 (file)
 #include <BRep_TEdge.hxx>
 #include <BRepTools.hxx>
 #include <ElSLib.hxx>
+#include <Extrema_ExtPC2d.hxx>
+#include <Extrema_GenLocateExtPS.hxx>
 #include <Extrema_LocateExtPC.hxx>
+#include <Extrema_LocateExtPC2d.hxx>
 #include <Geom2d_BezierCurve.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <TopLoc_Location.hxx>
 #include <TopoDS_Edge.hxx>
 #include <BRep_Builder.hxx>
-IMPLEMENT_STANDARD_RTTIEXT(BRepTools_NurbsConvertModification,BRepTools_Modification)
+
+IMPLEMENT_STANDARD_RTTIEXT(BRepTools_NurbsConvertModification,BRepTools_CopyModification)
 
 //
-static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
-                  const Standard_Real newU1,
-                  const Standard_Real newU2)
-{
-  TColStd_Array1OfReal  knots(1,aSurface->NbUKnots()) ;
-  aSurface->UKnots(knots) ;
-  BSplCLib::Reparametrize(newU1,
-              newU2,
-              knots) ;
-  aSurface->SetUKnots(knots) ;
-}
-static void GeomLib_ChangeVBounds(Handle(Geom_BSplineSurface)& aSurface,
-                  const Standard_Real newV1,
-                  const Standard_Real newV2)
+namespace
 {
-  TColStd_Array1OfReal  knots(1,aSurface->NbVKnots()) ;
-  aSurface->VKnots(knots) ;
-  BSplCLib::Reparametrize(newV1,
-              newV2,
-              knots) ;
-  aSurface->SetVKnots(knots) ;
+  static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
+                                    const Standard_Real newU1,
+                                    const Standard_Real newU2)
+  {
+    TColStd_Array1OfReal  knots(1, aSurface->NbUKnots());
+    aSurface->UKnots(knots);
+    BSplCLib::Reparametrize(newU1, newU2, knots);
+    aSurface->SetUKnots(knots);
+  }
+
+  static void GeomLib_ChangeVBounds(Handle(Geom_BSplineSurface)& aSurface,
+                                    const Standard_Real newV1,
+                                    const Standard_Real newV2)
+  {
+    TColStd_Array1OfReal  knots(1, aSurface->NbVKnots());
+    aSurface->VKnots(knots);
+    BSplCLib::Reparametrize(newV1, newV2, knots);
+    aSurface->SetVKnots(knots);
+  }
+
+  // find 3D curve from theEdge in theMap, and return the transformed curve or NULL
+  static Handle(Geom_Curve) newCurve(const TColStd_IndexedDataMapOfTransientTransient& theMap,
+                                     const TopoDS_Edge& theEdge,
+                                     Standard_Real& theFirst,
+                                     Standard_Real& theLast)
+  {
+    Handle(Geom_Curve) aNewCurve;
+
+    TopLoc_Location aLoc;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aLoc, theFirst, theLast);
+    if (!aCurve.IsNull() && theMap.Contains(aCurve))
+    {
+      aNewCurve = Handle(Geom_Curve)::DownCast(theMap.FindFromKey(aCurve));
+      aNewCurve = Handle(Geom_Curve)::DownCast(aNewCurve->Transformed(aLoc.Transformation()));
+    }
+    return aNewCurve;
+  }
+
+  // find 2D curve from theEdge on theFace in theMap, and return the transformed curve or NULL
+  static Handle(Geom2d_Curve) newCurve(const TColStd_IndexedDataMapOfTransientTransient& theMap,
+                                       const TopoDS_Edge& theEdge,
+                                       const TopoDS_Face& theFace,
+                                       Standard_Real& theFirst,
+                                       Standard_Real& theLast)
+  {
+    Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, theFirst, theLast);
+    return (!aC2d.IsNull() && theMap.Contains(aC2d)) ? Handle(Geom2d_Curve)::DownCast(theMap.FindFromKey(aC2d))
+                                                     : Handle(Geom2d_Curve)();
+  }
+
+  // find surface from theFace in theMap, and return the transformed surface or NULL
+  static Handle(Geom_Surface) newSurface(const TColStd_IndexedDataMapOfTransientTransient& theMap,
+                                         const TopoDS_Face& theFace)
+  {
+    Handle(Geom_Surface) aNewSurf;
+
+    TopLoc_Location aLoc;
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace, aLoc);
+    if (!aSurf.IsNull() && theMap.Contains(aSurf))
+    {
+      aNewSurf = Handle(Geom_Surface)::DownCast(theMap.FindFromKey(aSurf));
+      aNewSurf = Handle(Geom_Surface)::DownCast(aNewSurf->Transformed(aLoc.Transformation()));
+    }
+    return aNewSurf;
+  }
+
+  static Standard_Boolean newParameter(const gp_Pnt& thePoint,
+                                       const Handle(Geom_Curve)& theCurve,
+                                       const Standard_Real theFirst,
+                                       const Standard_Real theLast,
+                                       const Standard_Real theTol,
+                                       Standard_Real& theParam)
+  {
+    GeomAdaptor_Curve anAdaptor(theCurve);
+    Extrema_LocateExtPC proj(thePoint, anAdaptor, theParam, theFirst, theLast, Precision::PConfusion());
+    if (proj.IsDone())
+    {
+      Standard_Real aDist2Min = proj.SquareDistance();
+      if (aDist2Min < theTol * theTol)
+      {
+        theParam = proj.Point().Parameter();
+        return Standard_True;
+      }
+    }
+    return Standard_False;
+  }
+
+  static Standard_Boolean newParameter(const gp_Pnt2d& theUV,
+                                       const Handle(Geom2d_Curve)& theCurve2d,
+                                       const Standard_Real theFirst,
+                                       const Standard_Real theLast,
+                                       const Standard_Real theTol,
+                                       Standard_Real& theParam)
+  {
+    Geom2dAdaptor_Curve anAdaptor(theCurve2d);
+    Extrema_LocateExtPC2d aProj(theUV, anAdaptor, theParam, Precision::PConfusion());
+    if (aProj.IsDone())
+    {
+      Standard_Real aDist2Min = aProj.SquareDistance();
+      if (aDist2Min < theTol * theTol)
+      {
+        theParam = aProj.Point().Parameter();
+        return Standard_True;
+      }
+    }
+    else
+    {
+      // Try to use general extrema to find the parameter, because Extrema_LocateExtPC2d
+      // sometimes could not find a solution if the parameter's first approach is several
+      // spans away from the expected solution (test bugs/modalg_7/bug28722).
+      Extrema_ExtPC2d anExt(theUV, anAdaptor, theFirst, theLast);
+      if (anExt.IsDone())
+      {
+        Standard_Integer aMinInd = 0;
+        Standard_Real aMinSqDist = Precision::Infinite();
+        for (Standard_Integer anIndex = 1; anIndex <= anExt.NbExt(); ++anIndex)
+          if (anExt.SquareDistance(anIndex) < aMinSqDist)
+          {
+            aMinSqDist = anExt.SquareDistance(anIndex);
+            aMinInd = anIndex;
+          }
+        if (aMinSqDist < theTol * theTol)
+        {
+          theParam = anExt.Point(aMinInd).Parameter();
+          return Standard_True;
+        }
+      }
+    }
+    return Standard_False;
+  }
+
+  static Standard_Boolean newUV(const gp_Pnt& thePoint,
+                                const Handle(Geom_Surface)& theSurf,
+                                const Standard_Real theTol,
+                                gp_Pnt2d& theUV)
+  {
+    GeomAdaptor_Surface anAdaptor(theSurf);
+    Extrema_GenLocateExtPS aProj(anAdaptor);
+    aProj.Perform(thePoint, theUV.X(), theUV.Y());
+    if (aProj.IsDone())
+    {
+      Standard_Real aDist2Min = aProj.SquareDistance();
+      if (aDist2Min < theTol * theTol)
+      {
+        gp_XY& aUV = theUV.ChangeCoord();
+        aProj.Point().Parameter(aUV.ChangeCoord(1), aUV.ChangeCoord(2));
+        return Standard_True;
+      }
+    }
+    return Standard_False;
+  }
 }
 
 //=======================================================================
@@ -102,6 +238,12 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
   RevWires = Standard_False;
   RevFace = Standard_False;
   Handle(Geom_Surface) SS = BRep_Tool::Surface(F,L);
+  if (SS.IsNull())
+  {
+    //processing the case when there is no geometry
+    return Standard_False;
+  }
+
   Handle(Standard_Type) TheTypeSS = SS->DynamicType();
   if ((TheTypeSS == STANDARD_TYPE(Geom_BSplineSurface)) ||
       (TheTypeSS == STANDARD_TYPE(Geom_BezierSurface))) {
@@ -115,7 +257,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
   //OCC466(apo)->
   U1 = curvU1;  U2 = curvU2;  
   V1 = curvV1;  V2 = curvV2;
-  SS->Bounds(surfU1,surfU2,surfV1,surfV2);
+  S->Bounds(surfU1,surfU2,surfV1,surfV2);
 
   if (Abs(U1 - surfU1) <= TolPar)
     U1 = surfU1;
@@ -192,10 +334,10 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
 
   if (Abs(surfU1-U1) > Tol || Abs(surfU2-U2) > Tol ||
       Abs(surfV1-V1) > Tol || Abs(surfV2-V2) > Tol)
-    SS = new Geom_RectangularTrimmedSurface(S, U1, U2, V1, V2);
-  SS->Bounds(surfU1,surfU2,surfV1,surfV2); 
+    S = new Geom_RectangularTrimmedSurface(S, U1, U2, V1, V2);
+  S->Bounds(surfU1,surfU2,surfV1,surfV2); 
 
-  S = GeomConvert::SurfaceToBSplineSurface(SS);
+  S = GeomConvert::SurfaceToBSplineSurface(S);
   Handle(Geom_BSplineSurface) BS = Handle(Geom_BSplineSurface)::DownCast(S) ;
   BS->Resolution(Tol, UTol, VTol) ;
   
@@ -210,6 +352,9 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
     GeomLib_ChangeVBounds(BS, V1, V2) ;
   }
 
+  if (!myMap.Contains(SS)) {
+    myMap.Add(SS, S);
+  }
   return Standard_True;
 }
 
@@ -234,6 +379,41 @@ static Standard_Boolean IsConvert(const TopoDS_Edge& E)
   
 }
 
+//=======================================================================
+//function : NewTriangulation
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_NurbsConvertModification::NewTriangulation(const TopoDS_Face&          theFace,
+                                                                      Handle(Poly_Triangulation)& theTri)
+{
+  if (!BRepTools_CopyModification::NewTriangulation(theFace, theTri))
+  {
+    return Standard_False;
+  }
+
+  // convert UV nodes of the mesh
+  if (theTri->HasUVNodes())
+  {
+    TopLoc_Location aLoc;
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace, aLoc);
+    Handle(Geom_Surface) aNewSurf = newSurface(myMap, theFace);
+    if (!aSurf.IsNull() && !aNewSurf.IsNull())
+    {
+      Standard_Real aTol = BRep_Tool::Tolerance(theFace);
+      for (Standard_Integer anInd = 1; anInd <= theTri->NbNodes(); ++anInd)
+      {
+        gp_Pnt2d aUV = theTri->UVNode(anInd);
+        gp_Pnt aPoint = aSurf->Value(aUV.X(), aUV.Y());
+        if (newUV(aPoint, aNewSurf, aTol, aUV))
+          theTri->SetUVNode(anInd, aUV);
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
 //=======================================================================
 //function : NewCurve
 //purpose  : 
@@ -312,6 +492,40 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve
   return Standard_True ;
 }
 
+//=======================================================================
+//function : NewPolygon
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_NurbsConvertModification::NewPolygon(const TopoDS_Edge&      theEdge,
+                                                                Handle(Poly_Polygon3D)& thePoly)
+{
+  if (!BRepTools_CopyModification::NewPolygon(theEdge, thePoly))
+  {
+    return Standard_False;
+  }
+
+  // update parameters of polygon
+  if (thePoly->HasParameters())
+  {
+    Standard_Real aTol = BRep_Tool::Tolerance(theEdge);
+    Standard_Real aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aFirst, aLast);
+    Handle(Geom_Curve) aNewCurve = newCurve(myMap, theEdge, aFirst, aLast);
+    if (!aCurve.IsNull() && !aNewCurve.IsNull()) // skip processing degenerated edges
+    {
+      TColStd_Array1OfReal& aParams = thePoly->ChangeParameters();
+      for (Standard_Integer anInd = aParams.Lower(); anInd <= aParams.Upper(); ++anInd)
+      {
+        Standard_Real& aParam = aParams(anInd);
+        gp_Pnt aPoint = aCurve->Value(aParam);
+        newParameter(aPoint, aNewCurve, aFirst, aLast, aTol, aParam);
+      }
+    }
+  }
+  return Standard_True;
+}
+
 //=======================================================================
 //function : NewPoint
 //purpose  : 
@@ -340,7 +554,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
 
   Tol = BRep_Tool::Tolerance(E);
   Standard_Real f2d,l2d;
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
+  Handle(Geom2d_Curve) aBaseC2d = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
   Standard_Real f3d,l3d;
   TopLoc_Location Loc;
   Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
@@ -348,6 +562,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
     !C3d->IsKind(STANDARD_TYPE(Geom_BezierCurve))) ||
     IsConvert(E));
 
+  Handle(Geom2d_Curve) C2d = aBaseC2d;
   if(BRep_Tool::Degenerated(E)) {
     //Curve2d = C2d;
     if(!C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
@@ -356,6 +571,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
       C2d = aTrimC;
     }
     Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
+    myMap.Add(aBaseC2d, Curve2d);
     return Standard_True;
   }
   if(!BRepTools::IsReallyClosed(E,F)) {
@@ -381,9 +597,11 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
     if(!newE.IsNull()) {
       C3d = BRep_Tool::Curve(newE, f3d, l3d);
     }
-    else {
+    if (C3d.IsNull()) {
       C3d = BRep_Tool::Curve(E,f3d,l3d);
     }
+    if (C3d.IsNull())
+      return Standard_False;
     GeomAdaptor_Curve   G3dAC(C3d, f3d, l3d);
     Handle(GeomAdaptor_Curve) G3dAHC = new GeomAdaptor_Curve(G3dAC);
     
@@ -403,13 +621,16 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
               Tol = newTol;
               myUpdatedEdges.Append(newE);
             }
+            myMap.Add(aBaseC2d, Curve2d);
             return Standard_True;
           }
           return Standard_False;
         }
       }
       else {
-        S = BRep_Tool::Surface(newF);
+        Handle(Geom_Surface) aNewS = BRep_Tool::Surface(newF);
+        if (!aNewS.IsNull())
+          S = aNewS;
       }
       S->Bounds(Uinf, Usup, Vinf, Vsup);
       //Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
@@ -451,6 +672,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
           Tol = newTol;
           myUpdatedEdges.Append(newE);
         }
+        myMap.Add(aBaseC2d, Curve2d);
         return Standard_True;
       }
       Curve2d = ProjOnCurve.BSpline();
@@ -460,6 +682,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
         Tol = newTol;
         myUpdatedEdges.Append(newE);
       }
+      myMap.Add(aBaseC2d, Curve2d);
       return Standard_True;
     }
 
@@ -502,6 +725,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
         Tol = newTol;
         myUpdatedEdges.Append(newE);
       }
+      myMap.Add(aBaseC2d, Curve2d);
       return Standard_True;
     }
     else {
@@ -512,6 +736,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
         Tol = newTol;
         myUpdatedEdges.Append(newE);
       }
+      myMap.Add(aBaseC2d, Curve2d);
       return Standard_True;
     }
   }
@@ -557,6 +782,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
              Tol = newTol;
              myUpdatedEdges.Append(newE);
            }
+           myMap.Add(aBaseC2d, Curve2d);
            return Standard_True;
          }
         return Standard_False;
@@ -582,6 +808,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
               Tol = newTol;
               myUpdatedEdges.Append(newE);
             }
+            myMap.Add(aBaseC2d, Curve2d);
             return Standard_True;
           }
           return Standard_False;
@@ -629,6 +856,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
           Tol = newTol;
           myUpdatedEdges.Append(newE);
         }
+        myMap.Add(aBaseC2d, Curve2d);
         return Standard_True;
       }
       else {
@@ -640,6 +868,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
           myUpdatedEdges.Append(newE);
         }
         mylcu.Append(C2dBis);
+        myMap.Add(aBaseC2d, Curve2d);
         return Standard_True;
       }
     }
@@ -651,11 +880,58 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
         return Standard_False;
       }
       Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
+      myMap.Add(aBaseC2d, Curve2d);
       return Standard_True;
     }
   }
 }
 
+//=======================================================================
+//function : NewPolygonOnTriangulation
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepTools_NurbsConvertModification::NewPolygonOnTriangulation(
+  const TopoDS_Edge&                   theEdge,
+  const TopoDS_Face&                   theFace,
+  Handle(Poly_PolygonOnTriangulation)& thePoly)
+{
+  if (!BRepTools_CopyModification::NewPolygonOnTriangulation(theEdge, theFace, thePoly))
+  {
+    return Standard_False;
+  }
+
+  // update parameters of 2D polygon
+  if (thePoly->HasParameters())
+  {
+    Standard_Real aTol = Max(BRep_Tool::Tolerance(theEdge), thePoly->Deflection());
+    TopLoc_Location aLoc;
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace, aLoc);
+    Handle(Geom_Surface) aNewSurf = newSurface(myMap, theFace);
+    Standard_Real aFirst, aLast;
+    Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirst, aLast);
+    Handle(Geom2d_Curve) aNewC2d = newCurve(myMap, theEdge, theFace, aFirst, aLast);
+    if (!aSurf.IsNull() && !aC2d.IsNull() && !aNewSurf.IsNull() && !aNewC2d.IsNull())
+    {
+      // compute 2D tolerance
+      GeomAdaptor_Surface aSurfAdapt(aSurf);
+      Standard_Real aTol2D = Max(aSurfAdapt.UResolution(aTol), aSurfAdapt.VResolution(aTol));
+
+      for (Standard_Integer anInd = 1; anInd <= thePoly->NbNodes(); ++anInd)
+      {
+        Standard_Real aParam = thePoly->Parameter(anInd);
+        gp_Pnt2d aUV = aC2d->Value(aParam);
+        gp_Pnt aPoint = aSurf->Value(aUV.X(), aUV.Y());
+        if (newUV(aPoint, aNewSurf, aTol, aUV) &&
+            newParameter(aUV, aNewC2d, aFirst, aLast, aTol2D, aParam))
+        {
+          thePoly->SetParameter(anInd, aParam);
+        }
+      }
+    }
+  }
+  return Standard_True;
+}
+
 //=======================================================================
 //function : NewParameter
 //purpose  : 
@@ -670,30 +946,12 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewParameter
   Tol =  BRep_Tool::Tolerance(V);
   if(BRep_Tool::Degenerated(E))
     return Standard_False;
-  Standard_Real f, l, param = BRep_Tool::Parameter(V,E);
-  TopLoc_Location L;
-
-  Handle(Geom_Curve) gc = BRep_Tool::Curve(E, L, f, l);
-  if(!myMap.Contains(gc))
-    return Standard_False;
-
-  Handle(Geom_BSplineCurve) gcc = 
-    Handle(Geom_BSplineCurve)::DownCast(myMap.FindFromKey(gc));
 
-  gcc = Handle(Geom_BSplineCurve)::DownCast(gcc->Transformed(L.Transformation()));
-
-  GeomAdaptor_Curve ac(gcc);
   gp_Pnt pnt = BRep_Tool::Pnt(V);
-
-  Extrema_LocateExtPC proj(pnt, ac, param, f, l, Tol);
-  if(proj.IsDone()) {
-    Standard_Real Dist2Min = proj.SquareDistance();
-    if (Dist2Min < Tol*Tol) {
-      P = proj.Point().Parameter();
-      return Standard_True;
-    }
-  }
-  return Standard_False;
+  P = BRep_Tool::Parameter(V,E);
+  Standard_Real aFirst, aLast;
+  Handle(Geom_Curve) aNewCurve = newCurve(myMap, E, aFirst, aLast);
+  return !aNewCurve.IsNull() && newParameter(pnt, aNewCurve, aFirst, aLast, Tol, P);
 }
 
 //=======================================================================
index 8bed3a7ae515c961e820c259b5b3dcbc0967f9ad..e12620de2fa7aa6994cf733ad4d02c88c56b23da 100644 (file)
@@ -22,7 +22,7 @@
 #include <TopTools_ListOfShape.hxx>
 #include <TColStd_ListOfTransient.hxx>
 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
-#include <BRepTools_Modification.hxx>
+#include <BRepTools_CopyModification.hxx>
 #include <Standard_Real.hxx>
 #include <GeomAbs_Shape.hxx>
 class TopoDS_Face;
@@ -36,12 +36,12 @@ class Geom2d_Curve;
 
 
 class BRepTools_NurbsConvertModification;
-DEFINE_STANDARD_HANDLE(BRepTools_NurbsConvertModification, BRepTools_Modification)
+DEFINE_STANDARD_HANDLE(BRepTools_NurbsConvertModification, BRepTools_CopyModification)
 
 //! Defines a modification of the  geometry by a  Trsf
 //! from gp. All methods return True and transform the
 //! geometry.
-class BRepTools_NurbsConvertModification : public BRepTools_Modification
+class BRepTools_NurbsConvertModification : public BRepTools_CopyModification
 {
 
 public:
@@ -100,11 +100,27 @@ public:
   //! (resp. <F2>).
   Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2, const TopoDS_Edge& NewE, const TopoDS_Face& NewF1, const TopoDS_Face& NewF2) Standard_OVERRIDE;
 
-  Standard_EXPORT const TopTools_ListOfShape& GetUpdatedEdges() const;
+  //! Returns true if the face has been modified according to changed triangulation.
+  //! If the face has been modified:
+  //! - theTri is a new triangulation on the face
+  Standard_EXPORT Standard_Boolean NewTriangulation(const TopoDS_Face& theFace, Handle(Poly_Triangulation)& theTri) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon.
+  //! If the edge has been modified:
+  //! - thePoly is a new polygon
+  Standard_EXPORT Standard_Boolean NewPolygon(const TopoDS_Edge& theEdge, Handle(Poly_Polygon3D)& thePoly) Standard_OVERRIDE;
 
+  //! Returns true if the edge has been modified according to changed polygon on triangulation.
+  //! If the edge has been modified:
+  //! - thePoly is a new polygon on triangulation
+  Standard_EXPORT Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge&                   theEdge,
+                                                             const TopoDS_Face&                   theFace,
+                                                             Handle(Poly_PolygonOnTriangulation)& thePoly) Standard_OVERRIDE;
+
+  Standard_EXPORT const TopTools_ListOfShape& GetUpdatedEdges() const;
 
 
-  DEFINE_STANDARD_RTTIEXT(BRepTools_NurbsConvertModification,BRepTools_Modification)
+  DEFINE_STANDARD_RTTIEXT(BRepTools_NurbsConvertModification,BRepTools_CopyModification)
 
 protected:
 
index 60a0c868040e62bb0d0907ffeb05170cf77864b1..3b1286ee80a72818f1cc3e86c5e4030f2eb0bafc 100644 (file)
@@ -1,5 +1,7 @@
 BRepTools.cxx
 BRepTools.hxx
+BRepTools_CopyModification.cxx
+BRepTools_CopyModification.hxx
 BRepTools_DataMapIteratorOfMapOfVertexPnt2d.hxx
 BRepTools_Debug.cxx
 BRepTools_GTrsfModification.cxx
index f0ace0936c47e9670e4e9c3a9e0c72947142e6ff..078f1d92821660c0de46412ba4b139cd55cb33c1 100644 (file)
@@ -14,6 +14,7 @@ regexp {([0-9]+) triangles} $trinfo_s str nbtri_s
 # face converted to NURBS
 nurbsconvert r s
 checkshape r
+tclean r
 incmesh r 0.001
 set trinfo_r [trinfo r]
 regexp {([0-9]+) triangles} $trinfo_r str nbtri_r
diff --git a/tests/bugs/modalg_8/bug31479_1 b/tests/bugs/modalg_8/bug31479_1
new file mode 100644 (file)
index 0000000..a9f80be
--- /dev/null
@@ -0,0 +1,31 @@
+puts "================================================================="
+puts "0031479: Modeling Algorithms - exceptiion geometry transformation"
+puts "         of triangulation-only shapes (without geometry surface) "
+puts "================================================================="
+puts ""
+
+restore [locate_data_file bug31479_P-51-Mustang-2.brep] s
+
+# reference data
+regexp {([0-9+-.eE]*) faces.* ([0-9+-.eE]*) triangles.* ([0-9+-.eE]*) nodes} [trinfo s] full nbFaces nbTri nbNodes
+regexp {Mass :\s*([0-9+-.eE]*)} [vprops s] full mass
+
+set scale 2
+set mass [expr $mass * $scale * $scale * $scale]
+
+# scaling
+tscale s 0 0 0 $scale -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+checkprops s -v $mass -eps 1.e-5
+
+# rotation
+trotate s 0 0 0  0 0 1  90  -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+checkprops s -v $mass -eps 1.e-5
+
+# translation
+ttranslate s 0 0 10 -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+checkprops s -v $mass -eps 1.e-5
+
+checkview -display s -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_8/bug31479_2 b/tests/bugs/modalg_8/bug31479_2
new file mode 100644 (file)
index 0000000..f3d82b7
--- /dev/null
@@ -0,0 +1,17 @@
+puts "================================================================="
+puts "0031479: Modeling Algorithms - exceptiion geometry transformation"
+puts "         of triangulation-only shapes (without geometry surface) "
+puts "================================================================="
+puts ""
+
+restore [locate_data_file bug31479_P-51-Mustang-2.brep] s
+
+# reference data
+regexp {([0-9+-.eE]*) faces.* ([0-9+-.eE]*) triangles.* ([0-9+-.eE]*) nodes} [trinfo s] full nbFaces nbTri nbNodes
+regexp {Mass :\s*([0-9+-.eE]*)} [vprops s] full mass
+
+deform res s 2 3 4
+checktrinfo res -face $nbFaces -nod $nbNodes -tri $nbTri
+checkprops res -v [expr $mass * 2 * 3 * 4] -eps 1.e-5
+
+checkview -display res -2d -path ${imagedir}/${test_image}.png