mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
0032716: Modeling Algorithms - BRepBuilderAPI_Transform discards triangulation
* Implement methods for copying tessellation to BRepTools_TrsfModification to keep the triangulation during transformation. * Add tests to reproduce the problem.
This commit is contained in:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
Reference in New Issue
Block a user