Modeling - Refactor GeomGridEval with sequential evaluation (#952)

- Removed SetUVParams/SetParams methods from all GeomGridEval classes
- Updated all evaluation methods to accept parameters directly as arguments
- Added new EvaluatePoints methods for arbitrary UV pair evaluation
- Updated all callers to use the new direct evaluation pattern
This commit is contained in:
Pasukhin Dmitry
2025-12-25 21:22:55 +00:00
committed by GitHub
parent e7d1148e8f
commit ace750e3d5
70 changed files with 8541 additions and 4971 deletions
@@ -79,8 +79,7 @@ inline void InitUniform(GeomGridEval_Surface& theEval,
}
// Evaluate grid
theEval.SetUVParams(aUParams, aVParams);
const NCollection_Array2<gp_Pnt> aGrid = theEval.EvaluateGrid();
const NCollection_Array2<gp_Pnt> aGrid = theEval.EvaluateGrid(aUParams, aVParams);
// Copy results to output arrays (convert from 2D grid to 1D linear indexing)
int Index = 1;
@@ -122,8 +121,7 @@ inline void InitWithParams(GeomGridEval_Surface& theEval,
Bnd_Box& theBnd)
{
// Evaluate grid using provided parameters
theEval.SetUVParams(theUpars, theVpars);
const NCollection_Array2<gp_Pnt> aGrid = theEval.EvaluateGrid();
const NCollection_Array2<gp_Pnt> aGrid = theEval.EvaluateGrid(theUpars, theVpars);
const int i0 = theUpars.Lower();
const int j0 = theVpars.Lower();
@@ -144,61 +142,6 @@ inline void InitWithParams(GeomGridEval_Surface& theEval,
}
}
//! Calculate deflection on a single triangle.
//! Evaluates the center point on the surface and computes deflection.
//! @tparam SurfaceType Type of surface (e.g., Handle(Adaptor3d_Surface) or pointer)
//! @param[in] theSurface The surface (accessed via ->Value())
//! @param[in] theP1 First vertex point
//! @param[in] theP2 Second vertex point
//! @param[in] theP3 Third vertex point
//! @param[in] theU1 U parameter at first vertex
//! @param[in] theV1 V parameter at first vertex
//! @param[in] theU2 U parameter at second vertex
//! @param[in] theV2 V parameter at second vertex
//! @param[in] theU3 U parameter at third vertex
//! @param[in] theV3 V parameter at third vertex
//! @return Deflection value (distance from triangle center to surface)
template <typename SurfaceType>
double DeflectionOnTriangle(const SurfaceType& theSurface,
const gp_Pnt& theP1,
const gp_Pnt& theP2,
const gp_Pnt& theP3,
const double theU1,
const double theV1,
const double theU2,
const double theV2,
const double theU3,
const double theV3)
{
// Check for degenerate triangles
if (theP1.SquareDistance(theP2) <= THE_MIN_EDGE_LENGTH_SQUARED)
return 0.0;
if (theP1.SquareDistance(theP3) <= THE_MIN_EDGE_LENGTH_SQUARED)
return 0.0;
if (theP2.SquareDistance(theP3) <= THE_MIN_EDGE_LENGTH_SQUARED)
return 0.0;
// Compute normal vector
const gp_XYZ XYZ1 = theP2.XYZ() - theP1.XYZ();
const gp_XYZ XYZ2 = theP3.XYZ() - theP2.XYZ();
const gp_XYZ XYZ3 = theP1.XYZ() - theP3.XYZ();
gp_Vec NormalVector((XYZ1 ^ XYZ2) + (XYZ2 ^ XYZ3) + (XYZ3 ^ XYZ1));
const double aNormLen = NormalVector.Magnitude();
if (aNormLen < gp::Resolution())
return 0.0;
NormalVector.Divide(aNormLen);
// Calculate center point on surface and compute distance to triangle plane
const double u = (theU1 + theU2 + theU3) / 3.0;
const double v = (theV1 + theV2 + theV3) / 3.0;
const gp_Pnt aCenter = theSurface->Value(u, v);
const gp_Vec P1P(theP1, aCenter);
return std::abs(P1P.Dot(NormalVector));
}
//! Compute border deflection for a boundary isoline using grid evaluation.
//! Uses batch evaluation for better performance on complex surfaces.
//! @param[in,out] theEval Grid evaluator (will be reused for isoline evaluation)
@@ -238,16 +181,9 @@ inline double ComputeBorderDeflection(GeomGridEval_Surface& theEval,
}
// Evaluate grid: 1xN or Nx1 depending on isoline direction
if (theIsUIso)
{
theEval.SetUVParams(aFixedParams, aVaryingParams);
}
else
{
theEval.SetUVParams(aVaryingParams, aFixedParams);
}
const NCollection_Array2<gp_Pnt> aGrid = theEval.EvaluateGrid();
const NCollection_Array2<gp_Pnt> aGrid = theIsUIso
? theEval.EvaluateGrid(aFixedParams, aVaryingParams)
: theEval.EvaluateGrid(aVaryingParams, aFixedParams);
// Compute max deflection from pre-evaluated points
double aDeflection = RealFirst();
@@ -650,30 +586,93 @@ inline void FillBounding(const gp_Pnt* thePnts,
}
}
//! Compute the maximum deflection over all triangles.
//! @tparam SurfaceType Type of surface (e.g., Handle(Adaptor3d_Surface) or pointer)
//! Compute deflection for a single triangle given a pre-evaluated center point.
//! @param[in] theP1 First vertex
//! @param[in] theP2 Second vertex
//! @param[in] theP3 Third vertex
//! @param[in] theCenter Pre-evaluated center point on surface
//! @return Deflection value (distance from triangle center to surface)
inline double ComputeDeflectionWithCenter(const gp_Pnt& theP1,
const gp_Pnt& theP2,
const gp_Pnt& theP3,
const gp_Pnt& theCenter)
{
// Check for degenerate triangles
if (theP1.SquareDistance(theP2) <= THE_MIN_EDGE_LENGTH_SQUARED)
return 0.0;
if (theP1.SquareDistance(theP3) <= THE_MIN_EDGE_LENGTH_SQUARED)
return 0.0;
if (theP2.SquareDistance(theP3) <= THE_MIN_EDGE_LENGTH_SQUARED)
return 0.0;
// Compute normal vector
const gp_XYZ XYZ1 = theP2.XYZ() - theP1.XYZ();
const gp_XYZ XYZ2 = theP3.XYZ() - theP2.XYZ();
const gp_XYZ XYZ3 = theP1.XYZ() - theP3.XYZ();
gp_Vec NormalVector((XYZ1 ^ XYZ2) + (XYZ2 ^ XYZ3) + (XYZ3 ^ XYZ1));
const double aNormLen = NormalVector.Magnitude();
if (aNormLen < gp::Resolution())
return 0.0;
NormalVector.Divide(aNormLen);
// Compute distance from center to triangle plane
const gp_Vec P1P(theP1, theCenter);
return std::abs(P1P.Dot(NormalVector));
}
//! Compute the maximum deflection over all triangles using batch evaluation.
//! Uses GeomGridEval_Surface::EvaluatePoints() to batch-evaluate all triangle centroids.
//! @tparam PolyhedronType Type of polyhedron class
//! @param[in] theSurface The surface (accessed via ->Value())
//! @param[in] theEval Pre-initialized grid evaluator
//! @param[in] thePolyhedron The polyhedron object (provides Triangle/Point access)
//! @param[in] theNbTriangles Number of triangles
//! @return Maximum deflection value
template <typename SurfaceType, typename PolyhedronType>
double ComputeMaxDeflection(const SurfaceType& theSurface,
template <typename PolyhedronType>
double ComputeMaxDeflection(GeomGridEval_Surface& theEval,
const PolyhedronType& thePolyhedron,
const int theNbTriangles)
{
double tol = 0.0;
if (theNbTriangles <= 0)
return 0.0;
// Collect all triangle centroid UV pairs
NCollection_Array1<gp_Pnt2d> aCentroidUVs(1, theNbTriangles);
for (int i = 1; i <= theNbTriangles; ++i)
{
int i1, i2, i3;
thePolyhedron.Triangle(i, i1, i2, i3);
double u1, v1, u2, v2, u3, v3;
gp_Pnt P1 = thePolyhedron.Point(i1, u1, v1);
gp_Pnt P2 = thePolyhedron.Point(i2, u2, v2);
gp_Pnt P3 = thePolyhedron.Point(i3, u3, v3);
thePolyhedron.Point(i1, u1, v1);
thePolyhedron.Point(i2, u2, v2);
thePolyhedron.Point(i3, u3, v3);
double tol1 = DeflectionOnTriangle(theSurface, P1, P2, P3, u1, v1, u2, v2, u3, v3);
const double uCenter = (u1 + u2 + u3) / 3.0;
const double vCenter = (v1 + v2 + v3) / 3.0;
aCentroidUVs.SetValue(i, gp_Pnt2d(uCenter, vCenter));
}
// Batch evaluate all centroids
NCollection_Array1<gp_Pnt> aCenterPoints = theEval.EvaluatePoints(aCentroidUVs);
if (aCenterPoints.IsEmpty())
return 0.0;
// Compute max deflection using pre-evaluated center points
double tol = 0.0;
for (int i = 1; i <= theNbTriangles; ++i)
{
int i1, i2, i3;
thePolyhedron.Triangle(i, i1, i2, i3);
double u1, v1, u2, v2, u3, v3;
const gp_Pnt P1 = thePolyhedron.Point(i1, u1, v1);
const gp_Pnt P2 = thePolyhedron.Point(i2, u2, v2);
const gp_Pnt P3 = thePolyhedron.Point(i3, u3, v3);
const double tol1 = ComputeDeflectionWithCenter(P1, P2, P3, aCenterPoints.Value(i));
if (tol1 > tol)
tol = tol1;
}
@@ -103,7 +103,7 @@ void IntCurveSurface_ThePolyhedronOfHInter::Init(const Handle(Adaptor3d_Surface)
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
Standard_Real tol = PolyUtils::ComputeMaxDeflection(Surface, *this, NbTriangles());
Standard_Real tol = PolyUtils::ComputeMaxDeflection(anEval, *this, NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
@@ -132,7 +132,7 @@ void IntCurveSurface_ThePolyhedronOfHInter::Init(const Handle(Adaptor3d_Surface)
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
Standard_Real tol = PolyUtils::ComputeMaxDeflection(Surface, *this, NbTriangles());
Standard_Real tol = PolyUtils::ComputeMaxDeflection(anEval, *this, NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
@@ -147,19 +147,6 @@ void IntCurveSurface_ThePolyhedronOfHInter::Init(const Handle(Adaptor3d_Surface)
//==================================================================================================
Standard_Real IntCurveSurface_ThePolyhedronOfHInter::DeflectionOnTriangle(
const Handle(Adaptor3d_Surface)& Surface,
const Standard_Integer Triang) const
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
Standard_Real u1, v1, u2, v2, u3, v3;
gp_Pnt P1 = Point(i1, u1, v1), P2 = Point(i2, u2, v2), P3 = Point(i3, u3, v3);
return PolyUtils::DeflectionOnTriangle(Surface, P1, P2, P3, u1, v1, u2, v2, u3, v3);
}
//==================================================================================================
void IntCurveSurface_ThePolyhedronOfHInter::Parameters(const Standard_Integer Index,
Standard_Real& U,
Standard_Real& V) const
@@ -47,9 +47,6 @@ public:
Standard_EXPORT void DeflectionOverEstimation(const Standard_Real flec);
Standard_EXPORT Standard_Real DeflectionOnTriangle(const Handle(Adaptor3d_Surface)& Surface,
const Standard_Integer Index) const;
Standard_EXPORT void UMinSingularity(const Standard_Boolean Sing);
Standard_EXPORT void UMaxSingularity(const Standard_Boolean Sing);
@@ -15,11 +15,14 @@
// commercial license or contractual agreement.
#include <Adaptor3d_Surface.hxx>
#include <GeomGridEval_Surface.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
#include <IntCurveSurface_PolyhedronUtils.pxx>
#include <IntPatch_HInterTool.hxx>
#include <IntPatch_Polyhedron.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <stdio.h>
@@ -29,6 +32,8 @@
#define DEFLECTION_COEFF 1.1
#define NBMAXUV 30
namespace PolyUtils = IntCurveSurface_PolyhedronUtils;
//================================================================================
static Standard_Integer NbPOnU(const Handle(Adaptor3d_Surface)& S)
{
@@ -90,34 +95,42 @@ IntPatch_Polyhedron::IntPatch_Polyhedron(const Handle(Adaptor3d_Surface)& Surfac
const Standard_Real v0 = Surface->FirstVParameter();
const Standard_Real v1 = Surface->LastVParameter();
const Standard_Real U1mU0sNbdeltaU = (u1 - u0) / (Standard_Real)nbdeltaU;
const Standard_Real V1mV0sNbdeltaV = (v1 - v0) / (Standard_Real)nbdeltaV;
// Build UV parameter arrays
TColStd_Array1OfReal aUParams(0, nbdeltaU);
TColStd_Array1OfReal aVParams(0, nbdeltaV);
const Standard_Real U1mU0sNbdeltaU = (u1 - u0) / (Standard_Real)nbdeltaU;
const Standard_Real V1mV0sNbdeltaV = (v1 - v0) / (Standard_Real)nbdeltaV;
gp_Pnt TP;
Standard_Real U, V;
Standard_Integer i1, i2, Index = 1;
for (i1 = 0, U = u0; i1 <= nbdeltaU; i1++, U += U1mU0sNbdeltaU)
for (Standard_Integer i = 0; i <= nbdeltaU; ++i)
{
for (i2 = 0, V = v0; i2 <= nbdeltaV; i2++, V += V1mV0sNbdeltaV)
aUParams.SetValue(i, u0 + i * U1mU0sNbdeltaU);
}
for (Standard_Integer j = 0; j <= nbdeltaV; ++j)
{
aVParams.SetValue(j, v0 + j * V1mV0sNbdeltaV);
}
// Use grid evaluator for batch point evaluation
GeomGridEval_Surface anEval;
anEval.Initialize(*Surface);
NCollection_Array2<gp_Pnt> aGridPnts = anEval.EvaluateGrid(aUParams, aVParams);
// Copy to internal arrays and build bounding box
Standard_Integer Index = 1;
for (Standard_Integer i1 = 0; i1 <= nbdeltaU; ++i1)
{
for (Standard_Integer i2 = 0; i2 <= nbdeltaV; ++i2)
{
Surface->D0(U, V, TP);
CMyPnts[Index] = TP;
CMyU[Index] = U;
CMyV[Index] = V;
TheBnd.Add(TP);
CMyPnts[Index] = aGridPnts.Value(i1 + 1, i2 + 1);
CMyU[Index] = aUParams.Value(i1);
CMyV[Index] = aVParams.Value(i2);
TheBnd.Add(CMyPnts[Index]);
Index++;
}
}
Standard_Real tol = 0.0;
const Standard_Integer nbtriangles = NbTriangles();
for (i1 = 1; i1 <= nbtriangles; i1++)
{
const Standard_Real tol1 = DeflectionOnTriangle(Surface, i1);
if (tol1 > tol)
tol = tol1;
}
// Compute max deflection using batch evaluation
Standard_Real tol = PolyUtils::ComputeMaxDeflection(anEval, *this, NbTriangles());
tol *= DEFLECTION_COEFF;
DeflectionOverEstimation(tol);
@@ -153,34 +166,42 @@ IntPatch_Polyhedron::IntPatch_Polyhedron(const Handle(Adaptor3d_Surface)& Surfac
const Standard_Real v0 = Surface->FirstVParameter();
const Standard_Real v1 = Surface->LastVParameter();
const Standard_Real U1mU0sNbdeltaU = (u1 - u0) / (Standard_Real)nbdeltaU;
const Standard_Real V1mV0sNbdeltaV = (v1 - v0) / (Standard_Real)nbdeltaV;
// Build UV parameter arrays
TColStd_Array1OfReal aUParams(0, nbdeltaU);
TColStd_Array1OfReal aVParams(0, nbdeltaV);
const Standard_Real U1mU0sNbdeltaU = (u1 - u0) / (Standard_Real)nbdeltaU;
const Standard_Real V1mV0sNbdeltaV = (v1 - v0) / (Standard_Real)nbdeltaV;
gp_Pnt TP;
Standard_Real U, V;
Standard_Integer i1, i2, Index = 1;
for (i1 = 0, U = u0; i1 <= nbdeltaU; i1++, U += U1mU0sNbdeltaU)
for (Standard_Integer i = 0; i <= nbdeltaU; ++i)
{
for (i2 = 0, V = v0; i2 <= nbdeltaV; i2++, V += V1mV0sNbdeltaV)
aUParams.SetValue(i, u0 + i * U1mU0sNbdeltaU);
}
for (Standard_Integer j = 0; j <= nbdeltaV; ++j)
{
aVParams.SetValue(j, v0 + j * V1mV0sNbdeltaV);
}
// Use grid evaluator for batch point evaluation
GeomGridEval_Surface anEval;
anEval.Initialize(*Surface);
NCollection_Array2<gp_Pnt> aGridPnts = anEval.EvaluateGrid(aUParams, aVParams);
// Copy to internal arrays and build bounding box
Standard_Integer Index = 1;
for (Standard_Integer i1 = 0; i1 <= nbdeltaU; ++i1)
{
for (Standard_Integer i2 = 0; i2 <= nbdeltaV; ++i2)
{
Surface->D0(U, V, TP);
CMyPnts[Index] = TP;
CMyU[Index] = U;
CMyV[Index] = V;
TheBnd.Add(TP);
CMyPnts[Index] = aGridPnts.Value(i1 + 1, i2 + 1);
CMyU[Index] = aUParams.Value(i1);
CMyV[Index] = aVParams.Value(i2);
TheBnd.Add(CMyPnts[Index]);
Index++;
}
}
Standard_Real tol = 0.0;
const Standard_Integer nbtriangles = NbTriangles();
for (i1 = 1; i1 <= nbtriangles; i1++)
{
const Standard_Real tol1 = DeflectionOnTriangle(Surface, i1);
if (tol1 > tol)
tol = tol1;
}
// Compute max deflection using batch evaluation
Standard_Real tol = PolyUtils::ComputeMaxDeflection(anEval, *this, NbTriangles());
tol *= DEFLECTION_COEFF;
DeflectionOverEstimation(tol);
@@ -189,44 +210,6 @@ IntPatch_Polyhedron::IntPatch_Polyhedron(const Handle(Adaptor3d_Surface)& Surfac
//=================================================================================================
Standard_Real IntPatch_Polyhedron::DeflectionOnTriangle(const Handle(Adaptor3d_Surface)& Surface,
const Standard_Integer Triang) const
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
//-- Calcul de l eqution du plan
Standard_Real u1, v1, u2, v2, u3, v3;
gp_Pnt P1, P2, P3;
P1 = Point(i1, u1, v1);
P2 = Point(i2, u2, v2);
P3 = Point(i3, u3, v3);
if (P1.SquareDistance(P2) <= LONGUEUR_MINI_EDGE_TRIANGLE)
return (0);
if (P1.SquareDistance(P3) <= LONGUEUR_MINI_EDGE_TRIANGLE)
return (0);
if (P2.SquareDistance(P3) <= LONGUEUR_MINI_EDGE_TRIANGLE)
return (0);
gp_XYZ XYZ1 = P2.XYZ() - P1.XYZ();
gp_XYZ XYZ2 = P3.XYZ() - P2.XYZ();
gp_XYZ XYZ3 = P1.XYZ() - P3.XYZ();
gp_Vec NormalVector((XYZ1 ^ XYZ2) + (XYZ2 ^ XYZ3) + (XYZ3 ^ XYZ1));
Standard_Real aNormLen = NormalVector.Magnitude();
if (aNormLen < gp::Resolution())
{
return 0.;
}
//
NormalVector.Divide(aNormLen);
//-- Calcul du point u,v au centre du triangle
Standard_Real u = (u1 + u2 + u3) / 3.0;
Standard_Real v = (v1 + v2 + v3) / 3.0;
gp_Vec P1P(P1, Surface->Value(u, v));
return (std::abs(P1P.Dot(NormalVector)));
}
//=================================================================================================
void IntPatch_Polyhedron::Parameters(const Standard_Integer Index,
Standard_Real& U,
Standard_Real& V) const
@@ -45,9 +45,6 @@ public:
Standard_EXPORT void DeflectionOverEstimation(const Standard_Real flec);
Standard_EXPORT Standard_Real DeflectionOnTriangle(const Handle(Adaptor3d_Surface)& Surface,
const Standard_Integer Index) const;
Standard_EXPORT void UMinSingularity(const Standard_Boolean Sing);
Standard_EXPORT void UMaxSingularity(const Standard_Boolean Sing);
@@ -102,7 +102,7 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Init(HLRBRep_Surface* Surface,
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
Standard_Real tol = PolyUtils::ComputeMaxDeflection(Surface, *this, NbTriangles());
Standard_Real tol = PolyUtils::ComputeMaxDeflection(anEval, *this, NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
@@ -131,7 +131,7 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Init(HLRBRep_Surface* Surface
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
Standard_Real tol = PolyUtils::ComputeMaxDeflection(Surface, *this, NbTriangles());
Standard_Real tol = PolyUtils::ComputeMaxDeflection(anEval, *this, NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
@@ -146,19 +146,6 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Init(HLRBRep_Surface* Surface
//==================================================================================================
Standard_Real HLRBRep_ThePolyhedronOfInterCSurf::DeflectionOnTriangle(
HLRBRep_Surface* Surface,
const Standard_Integer Triang) const
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
Standard_Real u1, v1, u2, v2, u3, v3;
gp_Pnt P1 = Point(i1, u1, v1), P2 = Point(i2, u2, v2), P3 = Point(i3, u3, v3);
return PolyUtils::DeflectionOnTriangle(Surface, P1, P2, P3, u1, v1, u2, v2, u3, v3);
}
//==================================================================================================
void HLRBRep_ThePolyhedronOfInterCSurf::Parameters(const Standard_Integer Index,
Standard_Real& U,
Standard_Real& V) const
@@ -55,9 +55,6 @@ public:
Standard_EXPORT void DeflectionOverEstimation(const Standard_Real flec);
Standard_EXPORT Standard_Real DeflectionOnTriangle(HLRBRep_Surface* Surface,
const Standard_Integer Index) const;
Standard_EXPORT void UMinSingularity(const Standard_Boolean Sing);
Standard_EXPORT void UMaxSingularity(const Standard_Boolean Sing);