mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-18 14:27:39 +03:00
#32471 Mesh - Deflection of the triangulation is not recomputed for planar face
Correction fix for CR32741 to provide binary compatibility with Products 750
This commit is contained in:
@@ -2444,6 +2444,174 @@ Standard_Boolean BRepLib::
|
|||||||
return aRetVal;
|
return aRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : UpdateDeflection
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
//! Tool to estimate deflection of the given UV point
|
||||||
|
//! with regard to its representation in 3D space.
|
||||||
|
struct EvalDeflection
|
||||||
|
{
|
||||||
|
BRepAdaptor_Surface Surface;
|
||||||
|
|
||||||
|
//! Initializes tool with the given face.
|
||||||
|
EvalDeflection (const TopoDS_Face& theFace)
|
||||||
|
: Surface (theFace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Evaluates deflection of the given 2d point from its 3d representation.
|
||||||
|
Standard_Real Eval (const gp_Pnt2d& thePoint2d, const gp_Pnt& thePoint3d)
|
||||||
|
{
|
||||||
|
gp_Pnt aPnt;
|
||||||
|
Surface.D0 (thePoint2d.X (), thePoint2d.Y (), aPnt);
|
||||||
|
return (thePoint3d.XYZ () - aPnt.XYZ ()).SquareModulus ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Represents link of triangulation.
|
||||||
|
struct Link
|
||||||
|
{
|
||||||
|
Standard_Integer Node[2];
|
||||||
|
|
||||||
|
//! Constructor
|
||||||
|
Link (const Standard_Integer theNode1, const Standard_Integer theNode2)
|
||||||
|
{
|
||||||
|
Node[0] = theNode1;
|
||||||
|
Node[1] = theNode2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Computes a hash code for the this link
|
||||||
|
Standard_Integer HashCode (const Standard_Integer theUpperBound) const
|
||||||
|
{
|
||||||
|
return ::HashCode (Node[0] + Node[1], theUpperBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns true if this link has the same nodes as the other.
|
||||||
|
Standard_Boolean IsEqual (const Link& theOther) const
|
||||||
|
{
|
||||||
|
return ((Node[0] == theOther.Node[0] && Node[1] == theOther.Node[1]) ||
|
||||||
|
(Node[0] == theOther.Node[1] && Node[1] == theOther.Node[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias for IsEqual.
|
||||||
|
Standard_Boolean operator ==(const Link& theOther) const
|
||||||
|
{
|
||||||
|
return IsEqual (theOther);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Computes a hash code for the given link
|
||||||
|
inline Standard_Integer HashCode (const Link& theLink, const Standard_Integer theUpperBound)
|
||||||
|
{
|
||||||
|
return theLink.HashCode (theUpperBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BRepLib::UpdateDeflection (const TopoDS_Shape& theShape)
|
||||||
|
{
|
||||||
|
TopExp_Explorer anExpFace (theShape, TopAbs_FACE);
|
||||||
|
for (; anExpFace.More(); anExpFace.Next())
|
||||||
|
{
|
||||||
|
const TopoDS_Face& aFace = TopoDS::Face (anExpFace.Current());
|
||||||
|
const Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aFace);
|
||||||
|
if (aSurf.IsNull())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopLoc_Location aLoc;
|
||||||
|
const Handle(Poly_Triangulation)& aPT = BRep_Tool::Triangulation (aFace, aLoc);
|
||||||
|
if (aPT.IsNull() || !aPT->HasUVNodes())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect all nodes of degenerative edges and skip elements
|
||||||
|
// build upon them due to huge distortions introduced by passage
|
||||||
|
// from UV space to 3D.
|
||||||
|
NCollection_Map<Standard_Integer> aDegNodes;
|
||||||
|
TopExp_Explorer anExpEdge (aFace, TopAbs_EDGE);
|
||||||
|
for (; anExpEdge.More(); anExpEdge.Next())
|
||||||
|
{
|
||||||
|
const TopoDS_Edge& aEdge = TopoDS::Edge (anExpEdge.Current());
|
||||||
|
if (BRep_Tool::Degenerated (aEdge))
|
||||||
|
{
|
||||||
|
const Handle(Poly_PolygonOnTriangulation)& aPolygon = BRep_Tool::PolygonOnTriangulation (aEdge, aPT, aLoc);
|
||||||
|
if (aPolygon.IsNull ())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer aNodeIt = aPolygon->Nodes().Lower(); aNodeIt <= aPolygon->Nodes().Upper(); ++aNodeIt)
|
||||||
|
{
|
||||||
|
aDegNodes.Add (aPolygon->Nodes().Value (aNodeIt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalDeflection aTool (aFace);
|
||||||
|
NCollection_Map<Link> aLinks;
|
||||||
|
Standard_Real aSqDeflection = 0.;
|
||||||
|
const gp_Trsf& aTrsf = aLoc.Transformation();
|
||||||
|
for (Standard_Integer aTriIt = 1; aTriIt <= aPT->NbTriangles(); ++aTriIt)
|
||||||
|
{
|
||||||
|
const Poly_Triangle& aTriangle = aPT->Triangle (aTriIt);
|
||||||
|
|
||||||
|
int aNode[3];
|
||||||
|
aTriangle.Get (aNode[0], aNode[1], aNode[2]);
|
||||||
|
if (aDegNodes.Contains (aNode[0]) ||
|
||||||
|
aDegNodes.Contains (aNode[1]) ||
|
||||||
|
aDegNodes.Contains (aNode[2]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gp_Pnt aP3d[3] = {
|
||||||
|
aPT->Node (aNode[0]).Transformed (aTrsf),
|
||||||
|
aPT->Node (aNode[1]).Transformed (aTrsf),
|
||||||
|
aPT->Node (aNode[2]).Transformed (aTrsf)
|
||||||
|
};
|
||||||
|
|
||||||
|
const gp_Pnt2d aP2d[3] = {
|
||||||
|
aPT->UVNode (aNode[0]),
|
||||||
|
aPT->UVNode (aNode[1]),
|
||||||
|
aPT->UVNode (aNode[2])
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check midpoint of triangle.
|
||||||
|
const gp_Pnt aMid3d_t = (aP3d[0].XYZ() + aP3d[1].XYZ() + aP3d[2].XYZ()) / 3.;
|
||||||
|
const gp_Pnt2d aMid2d_t = (aP2d[0].XY () + aP2d[1].XY () + aP2d[2].XY ()) / 3.;
|
||||||
|
|
||||||
|
aSqDeflection = Max (aSqDeflection, aTool.Eval (aMid2d_t, aMid3d_t));
|
||||||
|
|
||||||
|
for (Standard_Integer i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
const Standard_Integer j = (i + 1) % 3;
|
||||||
|
const Link aLink (aNode[i], aNode[j]);
|
||||||
|
if (!aLinks.Add (aLink))
|
||||||
|
{
|
||||||
|
// Do not estimate boundary links due to high distortions at the edge.
|
||||||
|
const gp_Pnt& aP3d1 = aP3d[i];
|
||||||
|
const gp_Pnt& aP3d2 = aP3d[j];
|
||||||
|
|
||||||
|
const gp_Pnt2d& aP2d1 = aP2d[i];
|
||||||
|
const gp_Pnt2d& aP2d2 = aP2d[j];
|
||||||
|
|
||||||
|
const gp_Pnt aMid3d_l = (aP3d1.XYZ() + aP3d2.XYZ()) / 2.;
|
||||||
|
const gp_Pnt2d aMid2d_l = (aP2d1.XY () + aP2d2.XY ()) / 2.;
|
||||||
|
|
||||||
|
aSqDeflection = Max (aSqDeflection, aTool.Eval (aMid2d_l, aMid3d_l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aPT->Deflection (Sqrt (aSqDeflection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SortFaces
|
//function : SortFaces
|
||||||
//purpose :
|
//purpose :
|
||||||
|
@@ -229,6 +229,10 @@ public:
|
|||||||
//! Returns TRUE if any correction is done.
|
//! Returns TRUE if any correction is done.
|
||||||
Standard_EXPORT static Standard_Boolean EnsureNormalConsistency (const TopoDS_Shape& S, const Standard_Real theAngTol = 0.001, const Standard_Boolean ForceComputeNormals = Standard_False);
|
Standard_EXPORT static Standard_Boolean EnsureNormalConsistency (const TopoDS_Shape& S, const Standard_Real theAngTol = 0.001, const Standard_Boolean ForceComputeNormals = Standard_False);
|
||||||
|
|
||||||
|
//! Updates value of deflection in Poly_Triangulation of faces
|
||||||
|
//! by the maximum deviation measured on existing triangulation.
|
||||||
|
Standard_EXPORT static void UpdateDeflection (const TopoDS_Shape& S);
|
||||||
|
|
||||||
//! Calculates the bounding sphere around the set of vertexes from the theLV list.
|
//! Calculates the bounding sphere around the set of vertexes from the theLV list.
|
||||||
//! Returns the center (theNewCenter) and the radius (theNewTol) of this sphere.
|
//! Returns the center (theNewCenter) and the radius (theNewTol) of this sphere.
|
||||||
//! This can be used to construct the new vertex which covers the given set of
|
//! This can be used to construct the new vertex which covers the given set of
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
#include <IMeshData_Edge.hxx>
|
#include <IMeshData_Edge.hxx>
|
||||||
#include <IMeshData_PCurve.hxx>
|
#include <IMeshData_PCurve.hxx>
|
||||||
#include <OSD_Parallel.hxx>
|
#include <OSD_Parallel.hxx>
|
||||||
|
#include <BRepLib.hxx>
|
||||||
|
#include <Poly_TriangulationParameters.hxx>
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
||||||
|
|
||||||
@@ -157,6 +159,47 @@ namespace
|
|||||||
|
|
||||||
Handle(IMeshData_Model) myModel;
|
Handle(IMeshData_Model) myModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Estimates and updates deflection of triangulations for corresponding faces.
|
||||||
|
class DeflectionEstimator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
DeflectionEstimator (const Handle(IMeshData_Model)& theModel,
|
||||||
|
const IMeshTools_Parameters& theParams)
|
||||||
|
: myModel (theModel)
|
||||||
|
, myParams (new Poly_TriangulationParameters (
|
||||||
|
theParams.Deflection, theParams.Angle, theParams.MinSize))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Main functor.
|
||||||
|
void operator()(const Standard_Integer theFaceIndex) const
|
||||||
|
{
|
||||||
|
const IMeshData::IFaceHandle& aDFace = myModel->GetFace (theFaceIndex);
|
||||||
|
if (aDFace->IsSet (IMeshData_Failure) ||
|
||||||
|
aDFace->IsSet (IMeshData_Reused))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRepLib::UpdateDeflection (aDFace->GetFace());
|
||||||
|
|
||||||
|
TopLoc_Location aLoc;
|
||||||
|
const Handle(Poly_Triangulation)& aTriangulation =
|
||||||
|
BRep_Tool::Triangulation (aDFace->GetFace(), aLoc);
|
||||||
|
|
||||||
|
if (!aTriangulation.IsNull())
|
||||||
|
{
|
||||||
|
aTriangulation->Parameters (myParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Handle(IMeshData_Model) myModel;
|
||||||
|
Handle(Poly_TriangulationParameters) myParams;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -181,7 +224,7 @@ BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor()
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Boolean BRepMesh_ModelPostProcessor::performInternal(
|
Standard_Boolean BRepMesh_ModelPostProcessor::performInternal(
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& /*theParameters*/)
|
const IMeshTools_Parameters& theParameters)
|
||||||
{
|
{
|
||||||
if (theModel.IsNull())
|
if (theModel.IsNull())
|
||||||
{
|
{
|
||||||
@@ -189,6 +232,10 @@ Standard_Boolean BRepMesh_ModelPostProcessor::performInternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Force single threaded solution due to data races on edges sharing the same TShape
|
// TODO: Force single threaded solution due to data races on edges sharing the same TShape
|
||||||
OSD_Parallel::For(0, theModel->EdgesNb(), PolygonCommitter(theModel), Standard_True/*!theParameters.InParallel*/);
|
OSD_Parallel::For (0, theModel->EdgesNb(), PolygonCommitter (theModel), Standard_True/*!theParameters.InParallel*/);
|
||||||
|
|
||||||
|
// Estimate deflection here due to BRepLib::EstimateDeflection requires
|
||||||
|
// existence of both Poly_Triangulation and Poly_PolygonOnTriangulation.
|
||||||
|
OSD_Parallel::For (0, theModel->FacesNb(), DeflectionEstimator (theModel, theParameters), !theParameters.InParallel);
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
@@ -29,5 +29,7 @@ Poly_PolygonOnTriangulation.lxx
|
|||||||
Poly_Triangle.cxx
|
Poly_Triangle.cxx
|
||||||
Poly_Triangle.hxx
|
Poly_Triangle.hxx
|
||||||
Poly_Triangle.lxx
|
Poly_Triangle.lxx
|
||||||
|
Poly_TriangulationParameters.hxx
|
||||||
|
Poly_TriangulationParameters.cxx
|
||||||
Poly_Triangulation.cxx
|
Poly_Triangulation.cxx
|
||||||
Poly_Triangulation.hxx
|
Poly_Triangulation.hxx
|
||||||
|
@@ -34,6 +34,8 @@ class Standard_NullObject;
|
|||||||
|
|
||||||
|
|
||||||
class Poly_Triangulation;
|
class Poly_Triangulation;
|
||||||
|
class Poly_TriangulationParameters;
|
||||||
|
|
||||||
DEFINE_STANDARD_HANDLE(Poly_Triangulation, Standard_Transient)
|
DEFINE_STANDARD_HANDLE(Poly_Triangulation, Standard_Transient)
|
||||||
|
|
||||||
//! Provides a triangulation for a surface, a set of surfaces, or
|
//! Provides a triangulation for a surface, a set of surfaces, or
|
||||||
@@ -106,6 +108,12 @@ public:
|
|||||||
//! Deallocates the UV nodes.
|
//! Deallocates the UV nodes.
|
||||||
Standard_EXPORT void RemoveUVNodes();
|
Standard_EXPORT void RemoveUVNodes();
|
||||||
|
|
||||||
|
//! Returns initial set of parameters used to generate this triangulation.
|
||||||
|
const Handle(Poly_TriangulationParameters)& Parameters() const { return myParams; }
|
||||||
|
|
||||||
|
//! Updates initial set of parameters used to generate this triangulation.
|
||||||
|
void Parameters (const Handle(Poly_TriangulationParameters)& theParams) { myParams = theParams; }
|
||||||
|
|
||||||
//! Returns the number of nodes for this triangulation.
|
//! Returns the number of nodes for this triangulation.
|
||||||
Standard_Integer NbNodes() const { return myNodes.Length(); }
|
Standard_Integer NbNodes() const { return myNodes.Length(); }
|
||||||
|
|
||||||
@@ -204,6 +212,7 @@ protected:
|
|||||||
Poly_Array1OfTriangle myTriangles;
|
Poly_Array1OfTriangle myTriangles;
|
||||||
Handle(TShort_HArray1OfShortReal) myNormals;
|
Handle(TShort_HArray1OfShortReal) myNormals;
|
||||||
|
|
||||||
|
Handle(Poly_TriangulationParameters) myParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _Poly_Triangulation_HeaderFile
|
#endif // _Poly_Triangulation_HeaderFile
|
||||||
|
18
src/Poly/Poly_TriangulationParameters.cxx
Normal file
18
src/Poly/Poly_TriangulationParameters.cxx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Created on: 2021-07-20
|
||||||
|
// Copyright (c) 2021 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// 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 <Poly_TriangulationParameters.hxx>
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT (Poly_TriangulationParameters, Standard_Transient)
|
93
src/Poly/Poly_TriangulationParameters.hxx
Normal file
93
src/Poly/Poly_TriangulationParameters.hxx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Created on: 2021-07-20
|
||||||
|
// Copyright (c) 2021 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// 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 _Poly_TriangulationParameters_HeaderFile
|
||||||
|
#define _Poly_TriangulationParameters_HeaderFile
|
||||||
|
|
||||||
|
#include <Standard_Transient.hxx>
|
||||||
|
#include <Standard_DefineHandle.hxx>
|
||||||
|
|
||||||
|
//! Represents initial set of parameters triangulation is built for.
|
||||||
|
class Poly_TriangulationParameters : public Standard_Transient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor.
|
||||||
|
//! Initializes object with the given parameters.
|
||||||
|
//! @param theDeflection linear deflection
|
||||||
|
//! @param theAngle angular deflection
|
||||||
|
//! @param theMinSize minimum size
|
||||||
|
Poly_TriangulationParameters (const Standard_Real theDeflection = -1.,
|
||||||
|
const Standard_Real theAngle = -1.,
|
||||||
|
const Standard_Real theMinSize = -1.)
|
||||||
|
: myDeflection (theDeflection)
|
||||||
|
, myAngle (theAngle)
|
||||||
|
, myMinSize (theMinSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
virtual ~Poly_TriangulationParameters()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns true if linear deflection is defined.
|
||||||
|
Standard_Boolean HasDeflection() const
|
||||||
|
{
|
||||||
|
return !(myDeflection < 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns true if angular deflection is defined.
|
||||||
|
Standard_Boolean HasAngle() const
|
||||||
|
{
|
||||||
|
return !(myAngle < 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns true if minimum size is defined.
|
||||||
|
Standard_Boolean HasMinSize() const
|
||||||
|
{
|
||||||
|
return !(myMinSize < 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns linear deflection or -1 if undefined.
|
||||||
|
Standard_Real Deflection() const
|
||||||
|
{
|
||||||
|
return myDeflection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns angular deflection or -1 if undefined.
|
||||||
|
Standard_Real Angle() const
|
||||||
|
{
|
||||||
|
return myAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns minimum size or -1 if undefined.
|
||||||
|
Standard_Real MinSize() const
|
||||||
|
{
|
||||||
|
return myMinSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTIEXT (Poly_TriangulationParameters, Standard_Transient)
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Standard_Real myDeflection;
|
||||||
|
Standard_Real myAngle;
|
||||||
|
Standard_Real myMinSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STANDARD_HANDLE (Poly_TriangulationParameters, Standard_Transient)
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user