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;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//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
|
||||
//purpose :
|
||||
|
@@ -229,6 +229,10 @@ public:
|
||||
//! 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);
|
||||
|
||||
//! 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.
|
||||
//! 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
|
||||
|
@@ -19,6 +19,8 @@
|
||||
#include <IMeshData_Edge.hxx>
|
||||
#include <IMeshData_PCurve.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <Poly_TriangulationParameters.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
||||
|
||||
@@ -157,6 +159,47 @@ namespace
|
||||
|
||||
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(
|
||||
const Handle(IMeshData_Model)& theModel,
|
||||
const IMeshTools_Parameters& /*theParameters*/)
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
{
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
@@ -29,5 +29,7 @@ Poly_PolygonOnTriangulation.lxx
|
||||
Poly_Triangle.cxx
|
||||
Poly_Triangle.hxx
|
||||
Poly_Triangle.lxx
|
||||
Poly_TriangulationParameters.hxx
|
||||
Poly_TriangulationParameters.cxx
|
||||
Poly_Triangulation.cxx
|
||||
Poly_Triangulation.hxx
|
||||
|
@@ -34,6 +34,8 @@ class Standard_NullObject;
|
||||
|
||||
|
||||
class Poly_Triangulation;
|
||||
class Poly_TriangulationParameters;
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Poly_Triangulation, Standard_Transient)
|
||||
|
||||
//! Provides a triangulation for a surface, a set of surfaces, or
|
||||
@@ -106,6 +108,12 @@ public:
|
||||
//! Deallocates the UV nodes.
|
||||
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.
|
||||
Standard_Integer NbNodes() const { return myNodes.Length(); }
|
||||
|
||||
@@ -204,6 +212,7 @@ protected:
|
||||
Poly_Array1OfTriangle myTriangles;
|
||||
Handle(TShort_HArray1OfShortReal) myNormals;
|
||||
|
||||
Handle(Poly_TriangulationParameters) myParams;
|
||||
};
|
||||
|
||||
#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