1
0
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:
oan
2023-01-16 14:59:31 +03:00
parent d44ac07d7b
commit 73a572f26c
7 changed files with 343 additions and 2 deletions

View File

@@ -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 :

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View 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)

View 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