]> OCCT Git - occt.git/commitdiff
0032716: Modeling Algorithms - BRepBuilderAPI_Transform discards triangulation
authorabulyche <abulyche@opencascade.com>
Wed, 20 Apr 2022 14:14:07 +0000 (17:14 +0300)
committersmoskvin <smoskvin@opencascade.com>
Fri, 8 Jul 2022 16:30:13 +0000 (19:30 +0300)
* Implement methods for copying tessellation to BRepTools_TrsfModification to keep the triangulation during transformation.
* Add tests to reproduce the problem.

src/BRepBuilderAPI/BRepBuilderAPI_Transform.cxx
src/BRepBuilderAPI/BRepBuilderAPI_Transform.hxx
src/BRepTest/BRepTest_BasicCommands.cxx
src/BRepTools/BRepTools_TrsfModification.cxx
src/BRepTools/BRepTools_TrsfModification.hxx
tests/bugs/modalg_8/bug32716_1 [new file with mode: 0644]
tests/bugs/modalg_8/bug32716_2 [new file with mode: 0644]
tests/bugs/modalg_8/bug32716_3 [new file with mode: 0644]
tests/bugs/modalg_8/bug32716_4 [new file with mode: 0644]

index 3b5b233e69c7ad17a7e7ff9bff076a2c4357d069..d161d1a73ebafb0c8df8b3906967d4f687f67fd9 100644 (file)
@@ -36,13 +36,14 @@ BRepBuilderAPI_Transform::BRepBuilderAPI_Transform (const gp_Trsf& T) :
 //purpose  : 
 //=======================================================================
 
-BRepBuilderAPI_Transform::BRepBuilderAPI_Transform (const TopoDS_Shape& S,
-                                     const gp_Trsf& T,
-                                     const Standard_Boolean Copy) :
-  myTrsf(T)
+BRepBuilderAPI_Transform::BRepBuilderAPI_Transform (const TopoDS_Shape&    theShape,
+                                                    const gp_Trsf&         theTrsf,
+                                                    const Standard_Boolean theCopyGeom,
+                                                    const Standard_Boolean theCopyMesh)
+  : myTrsf(theTrsf)
 {
-  myModification = new BRepTools_TrsfModification(T);
-  Perform(S,Copy);
+  myModification = new BRepTools_TrsfModification(theTrsf);
+  Perform(theShape, theCopyGeom, theCopyMesh);
 }
 
 
@@ -52,19 +53,21 @@ BRepBuilderAPI_Transform::BRepBuilderAPI_Transform (const TopoDS_Shape& S,
 //purpose  : 
 //=======================================================================
 
-void BRepBuilderAPI_Transform::Perform(const TopoDS_Shape& S,
-                               const Standard_Boolean Copy)
+void BRepBuilderAPI_Transform::Perform(const TopoDS_Shape&    theShape,
+                                       const Standard_Boolean theCopyGeom,
+                                       const Standard_Boolean theCopyMesh)
 {
-  myUseModif = Copy || myTrsf.IsNegative() || (Abs(Abs(myTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec());
+  myUseModif = theCopyGeom || myTrsf.IsNegative() || (Abs(Abs(myTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec());
   if (myUseModif) {
     Handle(BRepTools_TrsfModification) theModif = 
       Handle(BRepTools_TrsfModification)::DownCast(myModification);
     theModif->Trsf() = myTrsf;
-    DoModif(S,myModification);
+    theModif->IsCopyMesh() = theCopyMesh;
+    DoModif(theShape, myModification);
   }
   else {
     myLocation = myTrsf;
-    myShape = S.Moved(myLocation);
+    myShape = theShape.Moved(myLocation);
     Done();
   }
 
index ac27d62600c2502fddab70f5e5e02a8681dd93a3..b0cdaa1813ca3d0856bbc0ee15c341552e9be3da 100644 (file)
@@ -50,28 +50,37 @@ public:
   //! to define the shape to transform.
   Standard_EXPORT BRepBuilderAPI_Transform(const gp_Trsf& T);
   
-  //! Creates a transformation from the gp_Trsf <T>, and
-  //! applies it to the shape <S>. If the transformation
+  //! Creates a transformation from the gp_Trsf <theTrsf>, and
+  //! applies it to the shape <theShape>. If the transformation
   //! is  direct   and isometric (determinant  =  1) and
-  //! <Copy> =  Standard_False,  the resulting shape  is
-  //! <S> on   which  a  new  location has    been  set.
+  //! <theCopyGeom> =  Standard_False,  the resulting shape  is
+  //! <theShape> on   which  a  new  location has    been  set.
   //! Otherwise,  the   transformation is applied   on a
-  //! duplication of <S>.
-  Standard_EXPORT BRepBuilderAPI_Transform(const TopoDS_Shape& S, const gp_Trsf& T, const Standard_Boolean Copy = Standard_False);
+  //! duplication of <theShape>.
+  //! If <theCopyMesh> is true, the triangulation will be copied,
+  //! and the copy will be assigned to the result shape.
+  Standard_EXPORT BRepBuilderAPI_Transform(const TopoDS_Shape&    theShape,
+                                           const gp_Trsf&         theTrsf,
+                                           const Standard_Boolean theCopyGeom = Standard_False,
+                                           const Standard_Boolean theCopyMesh = Standard_False);
   
-  //! pplies the geometric transformation defined at the
+  //! Applies the geometric transformation defined at the
   //! time of construction of this framework to the shape S.
   //! - If the transformation T is direct and isometric, in
   //! other words, if the determinant of the vectorial part
-  //! of T is equal to 1., and if Copy equals false (the
+  //! of T is equal to 1., and if theCopyGeom equals false (the
   //! default value), the resulting shape is the same as
   //! the original but with a new location assigned to it.
-  //! -   In all other cases, the transformation is applied to a duplicate of S.
+  //! - In all other cases, the transformation is applied to a duplicate of theShape.
+  //! - If theCopyMesh is true, the triangulation will be copied,
+  //! and the copy will be assigned to the result shape.
   //! Use the function Shape to access the result.
   //! Note: this framework can be reused to apply the same
   //! geometric transformation to other shapes. You only
   //! need to specify them by calling the function Perform again.
-  Standard_EXPORT void Perform (const TopoDS_Shape& S, const Standard_Boolean Copy = Standard_False);
+  Standard_EXPORT void Perform (const TopoDS_Shape&    theShape,
+                                const Standard_Boolean theCopyGeom = Standard_False, 
+                                const Standard_Boolean theCopyMesh = Standard_False);
   
   //! Returns the modified shape corresponding to <S>.
   Standard_EXPORT virtual TopoDS_Shape ModifiedShape (const TopoDS_Shape& S) const Standard_OVERRIDE;
index 216dc8ccf437d8d026dfbb3d19378fc4474419a7..76019fd643fda93afade416f2d7cab12434be485 100644 (file)
@@ -124,7 +124,14 @@ static Standard_Integer transform(Draw_Interpretor&,Standard_Integer n,const cha
   Standard_Boolean isBasic = Standard_False;
   Standard_Boolean isForced = Standard_False;
   Standard_Boolean isCopy = Standard_False;
+  Standard_Boolean isCopyMesh = Standard_False;
 
+  // Check "copymesh" flag.
+  if (!strcmp(a[n - 1], "-copymesh"))
+  {
+    isCopyMesh = Standard_True;
+    last = --n;
+  }
   // Check "copy" flag.
   if (!strcmp(a[n-1], "-copy")) {
     isCopy = Standard_True;
@@ -218,7 +225,7 @@ static Standard_Integer transform(Draw_Interpretor&,Standard_Integer n,const cha
         return 1;
       }
       else {
-        trf.Perform(S, isCopy);
+        trf.Perform(S, isCopy, isCopyMesh);
         if (!trf.IsDone())
           return 1;
         DBRep::Set(a[i],trf.Shape());
@@ -1487,27 +1494,27 @@ void  BRepTest::BasicCommands(Draw_Interpretor& theCommands)
                  transform,g);
 
   theCommands.Add("tmove",
-                 "tmove name1 name2 ... name, set location from name [-copy]",
+                 "tmove name1 name2 ... name, set location from name [-copy] [-copymesh]",
                  __FILE__,
                  transform,g);
 
   theCommands.Add("ttranslate",
-                 "ttranslate name1 name2 ... dx dy dz [-copy]",
+                 "ttranslate name1 name2 ... dx dy dz [-copy [-copymesh]]",
                  __FILE__,
                  transform,g);
 
   theCommands.Add("trotate",
-                 "trotate name1 name2 ... x y z dx dy dz angle [-copy]",
+                 "trotate name1 name2 ... x y z dx dy dz angle [-copy [-copymesh]]",
                  __FILE__,
                  transform,g);
 
   theCommands.Add("tmirror",
-                 "tmirror name x y z dx dy dz [-copy]",
+                 "tmirror name x y z dx dy dz [-copy] [-copymesh]",
                  __FILE__,
                  transform,g);
 
   theCommands.Add("tscale",
-                 "tscale name x y z scale [-copy]",
+                 "tscale name x y z scale [-copy] [-copymesh]",
                  __FILE__,
                  transform,g);
 
index acf1d6773ffb5168defe5688f2db0dcbf5659e63..238afe6970cd29f55b396c7a14ea563a6c3245a0 100644 (file)
@@ -23,6 +23,7 @@
 #include <Geom_Surface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomLib.hxx>
+#include <GeomLib_Tool.hxx>
 #include <gp_GTrsf2d.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Trsf.hxx>
@@ -43,7 +44,8 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepTools_TrsfModification,BRepTools_Modification)
 //purpose  : 
 //=======================================================================
 BRepTools_TrsfModification::BRepTools_TrsfModification(const gp_Trsf& T) :
-myTrsf(T)
+myTrsf(T),
+myCopyMesh(Standard_False)
 {
 }
 
@@ -58,6 +60,16 @@ gp_Trsf& BRepTools_TrsfModification::Trsf ()
   return myTrsf;
 }
 
+//=======================================================================
+//function : IsCopyMesh
+//purpose  :
+//=======================================================================
+
+Standard_Boolean& BRepTools_TrsfModification::IsCopyMesh()
+{
+  return myCopyMesh;
+}
+
 //=======================================================================
 //function : NewSurface
 //purpose  : 
@@ -72,6 +84,12 @@ Standard_Boolean BRepTools_TrsfModification::NewSurface
        Standard_Boolean& RevFace)
 {
   S = BRep_Tool::Surface(F,L);
+  if (S.IsNull())
+  {
+    //processing cases when there is no geometry
+    return Standard_False;
+  }
+
   Tol = BRep_Tool::Tolerance(F);
   Tol *= Abs(myTrsf.ScaleFactor());
   RevWires = Standard_False;
@@ -87,6 +105,194 @@ Standard_Boolean BRepTools_TrsfModification::NewSurface
   return Standard_True;
 }
 
+//=======================================================================
+//function : NewTriangulation
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_TrsfModification::NewTriangulation
+(const TopoDS_Face& theFace,
+  Handle(Poly_Triangulation)& theTriangulation)
+{
+  if (!myCopyMesh)
+  {
+    return Standard_False;
+  }
+
+  TopLoc_Location aLoc;
+  theTriangulation = BRep_Tool::Triangulation(theFace, aLoc);
+
+  if (theTriangulation.IsNull())
+  {
+    return Standard_False;
+  }
+
+  gp_Trsf aTrsf = myTrsf;
+  if (!aLoc.IsIdentity())
+  {
+    aTrsf = aLoc.Transformation().Inverted() * aTrsf * aLoc.Transformation();
+  }
+
+  theTriangulation = theTriangulation->Copy();
+  theTriangulation->SetCachedMinMax(Bnd_Box()); // clear bounding box
+  theTriangulation->Deflection(theTriangulation->Deflection() * Abs(myTrsf.ScaleFactor()));
+  // apply transformation to 3D nodes
+  for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbNodes(); ++anInd)
+  {
+    gp_Pnt aP = theTriangulation->Node(anInd);
+    aP.Transform(aTrsf);
+    theTriangulation->SetNode(anInd, aP);
+  }
+  // modify 2D nodes
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace, aLoc);
+  if (theTriangulation->HasUVNodes() && !aSurf.IsNull())
+  {
+    for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbNodes(); ++anInd)
+    {
+      gp_Pnt2d aP2d = theTriangulation->UVNode(anInd);
+      aSurf->TransformParameters(aP2d.ChangeCoord().ChangeCoord(1),
+                                 aP2d.ChangeCoord().ChangeCoord(2),
+                                 myTrsf);
+      theTriangulation->SetUVNode(anInd, aP2d);
+    }
+  }
+  // modify triangles orientation in case of mirror transformation
+  if (myTrsf.ScaleFactor() < 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(aTrsf);
+      theTriangulation->SetNormal(anInd, aNormal);
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPolygon
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_TrsfModification::NewPolygon
+(const TopoDS_Edge& theE,
+  Handle(Poly_Polygon3D)& theP)
+{
+  if (!myCopyMesh)
+  {
+    return Standard_False;
+  }
+
+  TopLoc_Location aLoc;
+  theP = BRep_Tool::Polygon3D(theE, aLoc);
+  if (theP.IsNull())
+  {
+    return Standard_False;
+  }
+
+  gp_Trsf aTrsf = myTrsf;
+  if (!aLoc.IsIdentity())
+  {
+    aTrsf = aLoc.Transformation().Inverted() * aTrsf * aLoc.Transformation();
+  }
+
+  theP = theP->Copy();
+  theP->Deflection(theP->Deflection() * Abs(myTrsf.ScaleFactor()));
+  TColgp_Array1OfPnt& aNodesArray = theP->ChangeNodes();
+  for (Standard_Integer anId = aNodesArray.Lower(); anId <= aNodesArray.Upper(); ++anId)
+  {
+    //Applying the transformation to each node of polygon
+    aNodesArray.ChangeValue(anId).Transform(aTrsf);
+  }
+  // transform the parametrization
+  if (theP->HasParameters())
+  {
+    TopLoc_Location aCurveLoc;
+    Standard_Real aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theE, aCurveLoc, aFirst, aLast);
+    if (!aCurve.IsNull())
+    {
+      Standard_Real aReparametrization = aCurve->ParametricTransformation(aTrsf);
+      if (Abs(aReparametrization - 1.0) > Precision::PConfusion())
+      {
+        TColStd_Array1OfReal& aParams = theP->ChangeParameters();
+        for (Standard_Integer anInd = aParams.Lower(); anInd <= aParams.Upper(); ++anInd)
+        {
+          aParams(anInd) *= aReparametrization;
+        }
+      }
+    }
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NewPolygonOnTriangulation
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean BRepTools_TrsfModification::NewPolygonOnTriangulation
+(const TopoDS_Edge& theE,
+  const TopoDS_Face& theF,
+  Handle(Poly_PolygonOnTriangulation)& theP)
+{
+  if (!myCopyMesh)
+  {
+    return Standard_False;
+  }
+
+  TopLoc_Location aLoc;
+  Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(theF, aLoc);
+  if (aT.IsNull())
+  {
+    theP = Handle(Poly_PolygonOnTriangulation) ();
+    return Standard_False;
+  }
+
+  theP = BRep_Tool::PolygonOnTriangulation(theE, aT, aLoc);
+  if (theP.IsNull())
+  {
+    return Standard_False;
+  }
+  theP = theP->Copy();
+  theP->Deflection(theP->Deflection() * Abs(myTrsf.ScaleFactor()));
+
+  // transform the parametrization
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theF, aLoc);
+  Standard_Real aFirst, aLast;
+  Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast);
+  if (!aSurf.IsNull() && !aC2d.IsNull() && Abs(Abs(myTrsf.ScaleFactor()) - 1.0) > TopLoc_Location::ScalePrec())
+  {
+    gp_GTrsf2d aGTrsf = aSurf->ParametricTransformation(myTrsf);
+    if (aGTrsf.Form() != gp_Identity)
+    {
+      Handle(Geom2d_Curve) aNewC2d = GeomLib::GTransform(aC2d, aGTrsf);
+      for (Standard_Integer anInd = 1; anInd <= theP->NbNodes(); ++anInd)
+      {
+        Standard_Real aParam = theP->Parameter(anInd);
+        gp_Pnt2d aP2d = aC2d->Value(aParam);
+        aGTrsf.Transforms(aP2d.ChangeCoord());
+        GeomLib_Tool::Parameter(aNewC2d, aP2d, theP->Deflection(), aParam);
+        theP->SetParameter(anInd, aParam);
+      }
+    }
+  }
+
+  return Standard_True;
+}
 
 //=======================================================================
 //function : NewCurve
@@ -101,6 +307,10 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve
 {
   Standard_Real f,l;
   C = BRep_Tool::Curve(E,L,f,l);
+  if (C.IsNull())
+  {
+    return Standard_False;
+  }
 
   Tol = BRep_Tool::Tolerance(E);
   Tol *= Abs(myTrsf.ScaleFactor());
@@ -153,6 +363,12 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d
   Standard_Real scale = myTrsf.ScaleFactor();
   Tol *= Abs(scale);
   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,loc);
+
+  if (S.IsNull())
+  {
+    // processing the case when the surface (geometry) is deleted
+    return Standard_False;
+  }
   GeomAdaptor_Surface GAsurf(S);
   if (GAsurf.GetType() == GeomAbs_Plane)
     return Standard_False;
index f0df27766bb23cb44d9d0f93a3e26abb8491454a..2215b3d03b86a41132a312c9d048580f5ab82733 100644 (file)
@@ -50,6 +50,9 @@ public:
   //! Provides access to the gp_Trsf associated with this
   //! modification. The transformation can be changed.
   Standard_EXPORT gp_Trsf& Trsf();
+
+  //! Sets a flag to indicate the need to copy mesh.
+  Standard_EXPORT Standard_Boolean& IsCopyMesh();
   
   //! Returns true if the face F has been modified.
   //! If the face has been modified:
@@ -64,6 +67,21 @@ public:
   //! associated with this modification is negative.
   Standard_EXPORT 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;
   
+  //! Returns true if the face has been modified according to changed triangulation.
+  //! If the face has been modified:
+  //! - T is a new triangulation on the face
+  Standard_EXPORT Standard_Boolean NewTriangulation(const TopoDS_Face& F, Handle(Poly_Triangulation)& T) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon.
+  //! If the edge has been modified:
+  //! - P is a new polygon
+  Standard_EXPORT Standard_Boolean NewPolygon(const TopoDS_Edge& E, Handle(Poly_Polygon3D)& P) Standard_OVERRIDE;
+
+  //! Returns true if the edge has been modified according to changed polygon on triangulation.
+  //! If the edge has been modified:
+  //! - P is a new polygon on triangulation
+  Standard_EXPORT Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge& E, const TopoDS_Face& F, Handle(Poly_PolygonOnTriangulation)& P) Standard_OVERRIDE;
+
   //! Returns true if the edge E has been modified.
   //! If the edge has been modified:
   //! - C is the new geometric support of the edge,
@@ -120,6 +138,7 @@ private:
 
 
   gp_Trsf myTrsf;
+  Standard_Boolean myCopyMesh;
 
 
 };
diff --git a/tests/bugs/modalg_8/bug32716_1 b/tests/bugs/modalg_8/bug32716_1
new file mode 100644 (file)
index 0000000..2b20b3f
--- /dev/null
@@ -0,0 +1,57 @@
+puts "================================================================="
+puts "0032716: Modeling Algorithms - BRepBuilderAPI_Transform discards triangulation"
+puts "================================================================="
+puts ""
+
+psphere s1 10
+pcylinder s2 8 20
+pcone s3 10 8 5
+ttranslate s1 0 0 25
+ttranslate s3 0 0 -5
+
+baddobjects s1
+baddtools s2 s3
+bfillds
+bbop s fuse
+
+incmesh s 0.1
+
+# reference data
+regexp {([0-9+-.eE]*) faces.* ([0-9+-.eE]*) triangles.* ([0-9+-.eE]*) nodes} [trinfo s] full nbFaces nbTri nbNodes
+
+# scaling
+tscale s 0 0 0  2 -copymesh
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# mirror
+tmirror s 1 0 0  1 1 1 -copymesh
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# translate
+ttranslate s 0 0 10
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# rotate
+trotate s 0 0 0  0 0 1  45
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# display shape
+triangles s
+isos s 0
+checkview -display s -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_8/bug32716_2 b/tests/bugs/modalg_8/bug32716_2
new file mode 100644 (file)
index 0000000..bfe1fc0
--- /dev/null
@@ -0,0 +1,57 @@
+puts "================================================================="
+puts "0032716: Modeling Algorithms - BRepBuilderAPI_Transform discards triangulation"
+puts "================================================================="
+puts ""
+
+psphere s1 10
+pcylinder s2 8 20
+pcone s3 10 8 5
+ttranslate s1 0 0 25
+ttranslate s3 0 0 -5
+
+baddobjects s1
+baddtools s2 s3
+bfillds
+bbop s fuse
+
+incmesh s 0.1
+
+# reference data
+regexp {([0-9+-.eE]*) faces.* ([0-9+-.eE]*) triangles.* ([0-9+-.eE]*) nodes} [trinfo s] full nbFaces nbTri nbNodes
+
+# scaling
+tscale s 0 0 0  2 -copy -copymesh
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# mirror
+tmirror s 1 0 0  1 1 1 -copy -copymesh
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# translate
+ttranslate s 0 0 10 -copy -copymesh
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# rotate
+trotate s 0 0 0  0 0 1  45  -copy -copymesh
+checkshape s
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# display shape
+triangles s
+isos s 0
+checkview -display s -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_8/bug32716_3 b/tests/bugs/modalg_8/bug32716_3
new file mode 100644 (file)
index 0000000..706a36d
--- /dev/null
@@ -0,0 +1,54 @@
+puts "================================================================="
+puts "0032716: Modeling Algorithms - BRepBuilderAPI_Transform discards triangulation"
+puts "================================================================="
+puts ""
+
+psphere s1 10
+pcylinder s2 8 20
+pcone s3 10 8 5
+ttranslate s1 0 0 25
+ttranslate s3 0 0 -5
+
+baddobjects s1
+baddtools s2 s3
+bfillds
+bbop s fuse
+
+incmesh s 0.1
+tclean -geom s
+
+# reference data
+regexp {([0-9+-.eE]*) faces.* ([0-9+-.eE]*) triangles.* ([0-9+-.eE]*) nodes} [trinfo s] full nbFaces nbTri nbNodes
+
+# scaling
+tscale s 0 0 0  2 -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# mirror
+tmirror s 1 0 0  1 1 1 -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# translate
+ttranslate s 0 0 10
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# rotate
+trotate s 0 0 0  0 0 1  45
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# display shape
+triangles s
+isos s 0
+checkview -display s -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_8/bug32716_4 b/tests/bugs/modalg_8/bug32716_4
new file mode 100644 (file)
index 0000000..79e6783
--- /dev/null
@@ -0,0 +1,54 @@
+puts "================================================================="
+puts "0032716: Modeling Algorithms - BRepBuilderAPI_Transform discards triangulation"
+puts "================================================================="
+puts ""
+
+psphere s1 10
+pcylinder s2 8 20
+pcone s3 10 8 5
+ttranslate s1 0 0 25
+ttranslate s3 0 0 -5
+
+baddobjects s1
+baddtools s2 s3
+bfillds
+bbop s fuse
+
+incmesh s 0.1
+tclean -geom s
+
+# reference data
+regexp {([0-9+-.eE]*) faces.* ([0-9+-.eE]*) triangles.* ([0-9+-.eE]*) nodes} [trinfo s] full nbFaces nbTri nbNodes
+
+# scaling
+tscale s 0 0 0  2 -copy -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# mirror
+tmirror s 1 0 0  1 1 1 -copy -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# translate
+ttranslate s 0 0 10 -copy -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# rotate
+trotate s 0 0 0  0 0 1  45  -copy -copymesh
+checktrinfo s -face $nbFaces -nod $nbNodes -tri $nbTri
+if {[tricheck s] != ""} {
+  puts "ERROR: Wrong triangulation"
+}
+
+# display shape
+triangles s
+isos s 0
+checkview -display s -2d -path ${imagedir}/${test_image}.png