Modeling - Complete code sharing for IntCurveSurface Polyhedron classes (#936)

Completed the migration of IntCurveSurface_ThePolyhedronOfHInter and
HLRBRep_ThePolyhedronOfInterCSurf to fully utilize shared template
functions in IntCurveSurface_PolyhedronUtils.pxx.

The original commit fff55ee5fc introduced the .pxx template pattern but
only migrated 4 functions, leaving significant code duplication between
the two polyhedron implementations

Changes:
- Extended IntCurveSurface_PolyhedronUtils.pxx with 15 additional
  template functions: AllocateArrays, Destroy, NbTriangles, NbPoints,
  Triangle, TriConnex, PlaneEquation, Contain, FillBounding, IsOnBound,
  ComputeMaxDeflection, ComputeMaxBorderDeflection,
  SetDeflectionOverEstimation, Parameters, Point (3 overloads)
- Refactored both .cxx files to delegate all logic to PolyUtils namespace

This aligns the Polyhedron classes with other properly migrated classes
(Polygon, Inter, QuadricCurveExactInter) where the Utils.pxx contains
all shared logic and .cxx files are minimal wrappers.
This commit is contained in:
Pasukhin Dmitry
2025-12-18 15:47:08 +00:00
committed by GitHub
parent d8992095c2
commit f64e2dfeb5
5 changed files with 774 additions and 939 deletions

View File

@@ -15,6 +15,7 @@
#define IntCurveSurface_PolyhedronUtils_pxx_HeaderFile
#include <Bnd_Box.hxx>
#include <Bnd_HArray1OfBox.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
@@ -234,6 +235,626 @@ double ComputeBorderDeflection(const SurfaceType& theSurface,
return aDeflection;
}
//! Compute the number of triangles in the polyhedron.
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @return Number of triangles (2 * nbdeltaU * nbdeltaV)
inline int NbTriangles(const int theNbDeltaU, const int theNbDeltaV)
{
return theNbDeltaU * theNbDeltaV * 2;
}
//! Compute the number of points in the polyhedron.
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @return Number of points ((nbdeltaU + 1) * (nbdeltaV + 1))
inline int NbPoints(const int theNbDeltaU, const int theNbDeltaV)
{
return (theNbDeltaU + 1) * (theNbDeltaV + 1);
}
//! Get the three vertex indices of a triangle.
//! @param[in] theIndex Triangle index (1-based)
//! @param[out] theP1 First vertex index
//! @param[out] theP2 Second vertex index
//! @param[out] theP3 Third vertex index
//! @param[in] theNbDeltaV Number of V subdivisions
inline void Triangle(const int theIndex, int& theP1, int& theP2, int& theP3, const int theNbDeltaV)
{
const int line = 1 + ((theIndex - 1) / (theNbDeltaV * 2));
const int colon = 1 + ((theIndex - 1) % (theNbDeltaV * 2));
const int colpnt = (colon + 1) / 2;
theP1 = (line - 1) * (theNbDeltaV + 1) + colpnt;
theP2 = line * (theNbDeltaV + 1) + colpnt + ((colon - 1) % 2);
theP3 = (line - 1 + (colon % 2)) * (theNbDeltaV + 1) + colpnt + 1;
}
//! Navigate to a connected triangle given a pivot point and edge point.
//! This function computes triangle connectivity for mesh traversal.
//! @param[in] theTriang Current triangle index (0 if unknown)
//! @param[in] thePivot Pivot point index
//! @param[in] thePedge Edge point index (0 if unknown)
//! @param[out] theTriCon Connected triangle index (0 if on boundary)
//! @param[out] theOtherP The other point of the connected triangle
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @return Connected triangle index
inline int TriConnex(const int theTriang,
const int thePivot,
const int thePedge,
int& theTriCon,
int& theOtherP,
const int theNbDeltaU,
const int theNbDeltaV)
{
const int Pivotm1 = thePivot - 1;
const int nbdeltaVp1 = theNbDeltaV + 1;
const int nbdeltaVm2 = theNbDeltaV + theNbDeltaV;
const int ligP = Pivotm1 / nbdeltaVp1;
const int colP = Pivotm1 - ligP * nbdeltaVp1;
int ligE = 0, colE = 0, typE = 0;
if (thePedge != 0)
{
ligE = (thePedge - 1) / nbdeltaVp1;
colE = (thePedge - 1) - (ligE * nbdeltaVp1);
if (ligP == ligE)
typE = 1;
else if (colP == colE)
typE = 2;
else
typE = 3;
}
int linT = 0, colT = 0;
int linO = 0, colO = 0;
int t = 0, tt = 0;
if (theTriang != 0)
{
t = (theTriang - 1) / nbdeltaVm2;
tt = (theTriang - 1) - t * nbdeltaVm2;
linT = 1 + t;
colT = 1 + tt;
if (typE == 0)
{
if (ligP == linT)
{
ligE = ligP - 1;
colE = colP - 1;
typE = 3;
}
else
{
if (colT == ligP + ligP)
{
ligE = ligP;
colE = colP - 1;
typE = 1;
}
else
{
ligE = ligP + 1;
colE = colP + 1;
typE = 3;
}
}
}
switch (typE)
{
case 1:
if (linT == ligP)
{
linT++;
linO = ligP + 1;
colO = (colP > colE) ? colP : colE;
}
else
{
linT--;
linO = ligP - 1;
colO = (colP < colE) ? colP : colE;
}
break;
case 2:
if (colT == (colP + colP))
{
colT++;
linO = (ligP > ligE) ? ligP : ligE;
colO = colP + 1;
}
else
{
colT--;
linO = (ligP < ligE) ? ligP : ligE;
colO = colP - 1;
}
break;
case 3:
if ((colT & 1) == 0)
{
colT--;
linO = (ligP > ligE) ? ligP : ligE;
colO = (colP < colE) ? colP : colE;
}
else
{
colT++;
linO = (ligP < ligE) ? ligP : ligE;
colO = (colP > colE) ? colP : colE;
}
break;
}
}
else
{
if (thePedge == 0)
{
linT = (1 > ligP) ? 1 : ligP;
colT = (1 > (colP + colP)) ? 1 : (colP + colP);
if (ligP == 0)
linO = ligP + 1;
else
linO = ligP - 1;
colO = colP;
}
else
{
switch (typE)
{
case 1:
linT = ligP + 1;
colT = (colP > colE) ? colP : colE;
colT += colT;
linO = ligP + 1;
colO = (colP > colE) ? colP : colE;
break;
case 2:
linT = (ligP > ligE) ? ligP : ligE;
colT = colP + colP;
linO = (ligP < ligE) ? ligP : ligE;
colO = colP - 1;
break;
case 3:
linT = (ligP > ligE) ? ligP : ligE;
colT = colP + colE;
linO = (ligP > ligE) ? ligP : ligE;
colO = (colP < colE) ? colP : colE;
break;
}
}
}
theTriCon = (linT - 1) * nbdeltaVm2 + colT;
if (linT < 1)
{
linO = 0;
colO = colP + colP - colE;
if (colO < 0)
{
colO = 0;
linO = 1;
}
else if (colO > theNbDeltaV)
{
colO = theNbDeltaV;
linO = 1;
}
theTriCon = 0;
}
else if (linT > theNbDeltaU)
{
linO = theNbDeltaU;
colO = colP + colP - colE;
if (colO < 0)
{
colO = 0;
linO = theNbDeltaU - 1;
}
else if (colO > theNbDeltaV)
{
colO = theNbDeltaV;
linO = theNbDeltaU - 1;
}
theTriCon = 0;
}
if (colT < 1)
{
colO = 0;
linO = ligP + ligP - ligE;
if (linO < 0)
{
linO = 0;
colO = 1;
}
else if (linO > theNbDeltaU)
{
linO = theNbDeltaU;
colO = 1;
}
theTriCon = 0;
}
else if (colT > theNbDeltaV)
{
colO = theNbDeltaV;
linO = ligP + ligP - ligE;
if (linO < 0)
{
linO = 0;
colO = theNbDeltaV - 1;
}
else if (linO > theNbDeltaU)
{
linO = theNbDeltaU;
colO = theNbDeltaV - 1;
}
theTriCon = 0;
}
theOtherP = linO * nbdeltaVp1 + colO + 1;
return theTriCon;
}
//! Compute the plane equation of a triangle.
//! @param[in] theP1 First vertex point
//! @param[in] theP2 Second vertex point
//! @param[in] theP3 Third vertex point
//! @param[out] theNormalVector Normal vector of the plane
//! @param[out] thePolarDistance Distance from origin to plane along normal
inline void PlaneEquation(const gp_Pnt& theP1,
const gp_Pnt& theP2,
const gp_Pnt& theP3,
gp_XYZ& theNormalVector,
double& thePolarDistance)
{
const gp_XYZ v1 = theP2.XYZ() - theP1.XYZ();
const gp_XYZ v2 = theP3.XYZ() - theP2.XYZ();
const gp_XYZ v3 = theP1.XYZ() - theP3.XYZ();
if (v1.SquareModulus() <= THE_MIN_EDGE_LENGTH_SQUARED)
{
theNormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
if (v2.SquareModulus() <= THE_MIN_EDGE_LENGTH_SQUARED)
{
theNormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
if (v3.SquareModulus() <= THE_MIN_EDGE_LENGTH_SQUARED)
{
theNormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
theNormalVector = (v1 ^ v2) + (v2 ^ v3) + (v3 ^ v1);
const double aNormLen = theNormalVector.Modulus();
if (aNormLen < gp::Resolution())
{
thePolarDistance = 0.0;
}
else
{
theNormalVector.Divide(aNormLen);
thePolarDistance = theNormalVector * theP1.XYZ();
}
}
//! Check if a point is contained within a triangle.
//! @param[in] theP1 First vertex point
//! @param[in] theP2 Second vertex point
//! @param[in] theP3 Third vertex point
//! @param[in] theTestPnt Point to test
//! @return True if point is inside triangle
inline bool Contain(const gp_Pnt& theP1,
const gp_Pnt& theP2,
const gp_Pnt& theP3,
const gp_Pnt& theTestPnt)
{
const gp_XYZ v1 = (theP2.XYZ() - theP1.XYZ()) ^ (theTestPnt.XYZ() - theP1.XYZ());
const gp_XYZ v2 = (theP3.XYZ() - theP2.XYZ()) ^ (theTestPnt.XYZ() - theP2.XYZ());
const gp_XYZ v3 = (theP1.XYZ() - theP3.XYZ()) ^ (theTestPnt.XYZ() - theP3.XYZ());
return (v1 * v2 >= 0.0 && v2 * v3 >= 0.0 && v3 * v1 >= 0.0);
}
//! Fill bounding boxes for all triangles in the polyhedron.
//! @param[in] thePnts Array of points
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @param[in] theDeflection Deflection value for enlarging boxes
//! @param[in,out] theComponentsBnd Array of bounding boxes to fill
inline void FillBounding(const gp_Pnt* thePnts,
const int theNbDeltaU,
const int theNbDeltaV,
const double theDeflection,
const Handle(Bnd_HArray1OfBox)& theComponentsBnd)
{
Bnd_Box Boite;
int np1, np2, np3;
const int nbtriangles = NbTriangles(theNbDeltaU, theNbDeltaV);
for (int iTri = 1; iTri <= nbtriangles; ++iTri)
{
Triangle(iTri, np1, np2, np3, theNbDeltaV);
const gp_Pnt& p1 = thePnts[np1];
const gp_Pnt& p2 = thePnts[np2];
const gp_Pnt& p3 = thePnts[np3];
Boite.SetVoid();
if (p1.SquareDistance(p2) > THE_MIN_EDGE_LENGTH_SQUARED)
{
if (p1.SquareDistance(p3) > THE_MIN_EDGE_LENGTH_SQUARED)
{
if (p2.SquareDistance(p3) > THE_MIN_EDGE_LENGTH_SQUARED)
{
Boite.Add(p1);
Boite.Add(p2);
Boite.Add(p3);
Boite.Enlarge(theDeflection);
}
}
}
Boite.Enlarge(theDeflection);
theComponentsBnd->SetValue(iTri, Boite);
}
}
//! Compute the maximum deflection over all triangles.
//! @tparam SurfaceType Type of surface
//! @tparam SurfaceTool Tool class providing surface operations
//! @tparam PolyhedronType Type of polyhedron class
//! @param[in] theSurface The surface
//! @param[in] thePolyhedron The polyhedron object (provides Triangle/Point access)
//! @param[in] theNbTriangles Number of triangles
//! @return Maximum deflection value
template <typename SurfaceType, typename SurfaceTool, typename PolyhedronType>
double ComputeMaxDeflection(const SurfaceType& theSurface,
const PolyhedronType& thePolyhedron,
const int theNbTriangles)
{
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;
gp_Pnt P1 = thePolyhedron.Point(i1, u1, v1);
gp_Pnt P2 = thePolyhedron.Point(i2, u2, v2);
gp_Pnt P3 = thePolyhedron.Point(i3, u3, v3);
double tol1 = DeflectionOnTriangle<SurfaceType,
SurfaceTool>(theSurface, P1, P2, P3, u1, v1, u2, v2, u3, v3);
if (tol1 > tol)
tol = tol1;
}
return tol;
}
//! Compute the maximum border deflection over all four boundaries.
//! @tparam SurfaceType Type of surface
//! @tparam SurfaceTool Tool class providing surface operations
//! @param[in] theSurface The surface
//! @param[in] theU0 First U parameter
//! @param[in] theV0 First V parameter
//! @param[in] theU1 Last U parameter
//! @param[in] theV1 Last V parameter
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @return Maximum border deflection
template <typename SurfaceType, typename SurfaceTool>
double ComputeMaxBorderDeflection(const SurfaceType& theSurface,
const double theU0,
const double theV0,
const double theU1,
const double theV1,
const int theNbDeltaU,
const int theNbDeltaV)
{
double maxDeflection = RealFirst();
// Lower bound (U-isoline)
double aDeflection = ComputeBorderDeflection<SurfaceType, SurfaceTool>(theSurface,
theU0,
theV0,
theV1,
true,
theNbDeltaV);
if (aDeflection > maxDeflection)
maxDeflection = aDeflection;
// Upper bound (U-isoline)
aDeflection = ComputeBorderDeflection<SurfaceType, SurfaceTool>(theSurface,
theU1,
theV0,
theV1,
true,
theNbDeltaV);
if (aDeflection > maxDeflection)
maxDeflection = aDeflection;
// Lower bound (V-isoline)
aDeflection = ComputeBorderDeflection<SurfaceType, SurfaceTool>(theSurface,
theV0,
theU0,
theU1,
false,
theNbDeltaU);
if (aDeflection > maxDeflection)
maxDeflection = aDeflection;
// Upper bound (V-isoline)
aDeflection = ComputeBorderDeflection<SurfaceType, SurfaceTool>(theSurface,
theV1,
theU0,
theU1,
false,
theNbDeltaU);
if (aDeflection > maxDeflection)
maxDeflection = aDeflection;
return maxDeflection;
}
//! Check if an edge between two points lies on the boundary.
//! @param[in] theIndex1 First point index
//! @param[in] theIndex2 Second point index
//! @param[in] theIsOnBounds Array of boundary flags
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @return True if edge is on boundary
inline bool IsOnBound(const int theIndex1,
const int theIndex2,
const Standard_Boolean* theIsOnBounds,
const int theNbDeltaU,
const int theNbDeltaV)
{
const int aDiff = std::abs(theIndex1 - theIndex2);
if (aDiff != 1 && aDiff != theNbDeltaV + 1)
return false;
for (int i = 0; i <= theNbDeltaU; ++i)
{
if ((theIndex1 == 1 + i * (theNbDeltaV + 1)) && (theIndex2 == theIndex1 - 1))
return false;
if ((theIndex1 == (1 + i) * (theNbDeltaV + 1)) && (theIndex2 == theIndex1 + 1))
return false;
}
return (theIsOnBounds[theIndex1] && theIsOnBounds[theIndex2]);
}
//! Deallocate polyhedron arrays.
//! @param[in,out] thePnts Points array to delete and nullify
//! @param[in,out] theU U parameters array to delete and nullify
//! @param[in,out] theV V parameters array to delete and nullify
//! @param[in,out] theIsOnBounds Boundary flags array to delete and nullify
inline void Destroy(Standard_Address& thePnts,
Standard_Address& theU,
Standard_Address& theV,
Standard_Address& theIsOnBounds)
{
if (thePnts)
delete[] static_cast<gp_Pnt*>(thePnts);
if (theU)
delete[] static_cast<Standard_Real*>(theU);
if (theV)
delete[] static_cast<Standard_Real*>(theV);
if (theIsOnBounds)
delete[] static_cast<Standard_Boolean*>(theIsOnBounds);
thePnts = theU = theV = theIsOnBounds = NULL;
}
//! Allocate polyhedron arrays.
//! @param[in] theNbDeltaU Number of U subdivisions
//! @param[in] theNbDeltaV Number of V subdivisions
//! @param[out] thePnts Points array
//! @param[out] theU U parameters array
//! @param[out] theV V parameters array
//! @param[out] theIsOnBounds Boundary flags array
inline void AllocateArrays(const int theNbDeltaU,
const int theNbDeltaV,
Standard_Address& thePnts,
Standard_Address& theU,
Standard_Address& theV,
Standard_Address& theIsOnBounds)
{
const int t = (theNbDeltaU + 1) * (theNbDeltaV + 1) + 1;
thePnts = new gp_Pnt[t];
theU = new Standard_Real[t];
theV = new Standard_Real[t];
theIsOnBounds = new Standard_Boolean[t];
}
//! Set deflection over-estimation with minimum threshold.
//! @param[in] theFlec Deflection value
//! @param[out] theDeflection Stored deflection value
//! @param[in,out] theBnd Bounding box to enlarge
inline void SetDeflectionOverEstimation(const double theFlec,
double& theDeflection,
Bnd_Box& theBnd)
{
constexpr double THE_MIN_DEFLECTION = 0.0001;
if (theFlec < THE_MIN_DEFLECTION)
{
theDeflection = THE_MIN_DEFLECTION;
theBnd.Enlarge(THE_MIN_DEFLECTION);
}
else
{
theDeflection = theFlec;
theBnd.Enlarge(theFlec);
}
}
//! Get UV parameters at point index.
//! @param[in] theIndex Index of the point
//! @param[in] theU U parameters array
//! @param[in] theV V parameters array
//! @param[out] theOutU Output U parameter
//! @param[out] theOutV Output V parameter
inline void Parameters(const int theIndex,
const Standard_Address theU,
const Standard_Address theV,
double& theOutU,
double& theOutV)
{
const Standard_Real* aU = static_cast<const Standard_Real*>(theU);
const Standard_Real* aV = static_cast<const Standard_Real*>(theV);
theOutU = aU[theIndex];
theOutV = aV[theIndex];
}
//! Get point with UV parameters.
//! @param[in] theIndex Index of the point
//! @param[in] thePnts Points array
//! @param[in] theU U parameters array
//! @param[in] theV V parameters array
//! @param[out] theOutU Output U parameter
//! @param[out] theOutV Output V parameter
//! @return Reference to the point
inline const gp_Pnt& Point(const int theIndex,
const Standard_Address thePnts,
const Standard_Address theU,
const Standard_Address theV,
double& theOutU,
double& theOutV)
{
const gp_Pnt* aPnts = static_cast<const gp_Pnt*>(thePnts);
const Standard_Real* aU = static_cast<const Standard_Real*>(theU);
const Standard_Real* aV = static_cast<const Standard_Real*>(theV);
theOutU = aU[theIndex];
theOutV = aV[theIndex];
return aPnts[theIndex];
}
//! Get point by index.
//! @param[in] theIndex Index of the point
//! @param[in] thePnts Points array
//! @return Reference to the point
inline const gp_Pnt& Point(const int theIndex, const Standard_Address thePnts)
{
const gp_Pnt* aPnts = static_cast<const gp_Pnt*>(thePnts);
return aPnts[theIndex];
}
//! Get point by index (output parameter version).
//! @param[in] theIndex Index of the point
//! @param[in] thePnts Points array
//! @param[out] thePoint Output point
inline void Point(const int theIndex, const Standard_Address thePnts, gp_Pnt& thePoint)
{
const gp_Pnt* aPnts = static_cast<const gp_Pnt*>(thePnts);
thePoint = aPnts[theIndex];
}
} // namespace IntCurveSurface_PolyhedronUtils
#endif // IntCurveSurface_PolyhedronUtils_pxx_HeaderFile

View File

@@ -28,7 +28,8 @@
#include "IntCurveSurface_PolyhedronUtils.pxx"
#define LONGUEUR_MINI_EDGE_TRIANGLE 1e-15
// Namespace alias for brevity
namespace PolyUtils = IntCurveSurface_PolyhedronUtils;
//==================================================================================================
@@ -48,11 +49,7 @@ IntCurveSurface_ThePolyhedronOfHInter::IntCurveSurface_ThePolyhedronOfHInter(
C_MyV(NULL),
C_MyIsOnBounds(NULL)
{
Standard_Integer t = (nbdeltaU + 1) * (nbdeltaV + 1) + 1;
C_MyPnts = new gp_Pnt[t];
C_MyU = new Standard_Real[t];
C_MyV = new Standard_Real[t];
C_MyIsOnBounds = new Standard_Boolean[t];
PolyUtils::AllocateArrays(nbdeltaU, nbdeltaV, C_MyPnts, C_MyU, C_MyV, C_MyIsOnBounds);
Init(Surface, u1, v1, u2, v2);
}
@@ -70,11 +67,7 @@ IntCurveSurface_ThePolyhedronOfHInter::IntCurveSurface_ThePolyhedronOfHInter(
C_MyV(NULL),
C_MyIsOnBounds(NULL)
{
Standard_Integer t = (nbdeltaU + 1) * (nbdeltaV + 1) + 1;
C_MyPnts = new gp_Pnt[t];
C_MyU = new Standard_Real[t];
C_MyV = new Standard_Real[t];
C_MyIsOnBounds = new Standard_Boolean[t];
PolyUtils::AllocateArrays(nbdeltaU, nbdeltaV, C_MyPnts, C_MyU, C_MyV, C_MyIsOnBounds);
Init(Surface, Upars, Vpars);
}
@@ -82,20 +75,7 @@ IntCurveSurface_ThePolyhedronOfHInter::IntCurveSurface_ThePolyhedronOfHInter(
void IntCurveSurface_ThePolyhedronOfHInter::Destroy()
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
if (C_MyPnts)
delete[] CMyPnts;
Standard_Real* CMyU = (Standard_Real*)C_MyU;
if (C_MyU)
delete[] CMyU;
Standard_Real* CMyV = (Standard_Real*)C_MyV;
if (C_MyV)
delete[] CMyV;
Standard_Boolean* CMyIsOnBounds = (Standard_Boolean*)C_MyIsOnBounds;
if (C_MyIsOnBounds)
delete[] CMyIsOnBounds;
C_MyPnts = C_MyU = C_MyV = C_MyIsOnBounds = NULL;
PolyUtils::Destroy(C_MyPnts, C_MyU, C_MyV, C_MyIsOnBounds);
}
//==================================================================================================
@@ -106,7 +86,7 @@ void IntCurveSurface_ThePolyhedronOfHInter::Init(const Handle(Adaptor3d_Surface)
const Standard_Real U1,
const Standard_Real V1)
{
IntCurveSurface_PolyhedronUtils::InitUniform<Handle(Adaptor3d_Surface), Adaptor3d_HSurfaceTool>(
PolyUtils::InitUniform<Handle(Adaptor3d_Surface), Adaptor3d_HSurfaceTool>(
Surface,
U0,
V0,
@@ -114,44 +94,30 @@ void IntCurveSurface_ThePolyhedronOfHInter::Init(const Handle(Adaptor3d_Surface)
V1,
nbdeltaU,
nbdeltaV,
(gp_Pnt*)C_MyPnts,
(Standard_Real*)C_MyU,
(Standard_Real*)C_MyV,
(Standard_Boolean*)C_MyIsOnBounds,
static_cast<gp_Pnt*>(C_MyPnts),
static_cast<Standard_Real*>(C_MyU),
static_cast<Standard_Real*>(C_MyV),
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
// Calculate triangle deflections
Standard_Real tol = 0.0;
Standard_Integer nbtriangles = NbTriangles();
for (Standard_Integer i1 = 1; i1 <= nbtriangles; i1++)
{
Standard_Real tol1 = DeflectionOnTriangle(Surface, i1);
if (tol1 > tol)
tol = tol1;
}
Standard_Real tol =
PolyUtils::ComputeMaxDeflection<Handle(Adaptor3d_Surface),
Adaptor3d_HSurfaceTool,
IntCurveSurface_ThePolyhedronOfHInter>(Surface,
*this,
NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
// Compute border deflection
TheBorderDeflection = RealFirst();
Standard_Real aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U0, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U1, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V0, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V1, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
TheBorderDeflection =
PolyUtils::ComputeMaxBorderDeflection<Handle(Adaptor3d_Surface), Adaptor3d_HSurfaceTool>(
Surface,
U0,
V0,
U1,
V1,
nbdeltaU,
nbdeltaV);
}
//==================================================================================================
@@ -160,57 +126,36 @@ void IntCurveSurface_ThePolyhedronOfHInter::Init(const Handle(Adaptor3d_Surface)
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars)
{
IntCurveSurface_PolyhedronUtils::InitWithParams<Handle(Adaptor3d_Surface),
Adaptor3d_HSurfaceTool>(
PolyUtils::InitWithParams<Handle(Adaptor3d_Surface), Adaptor3d_HSurfaceTool>(
Surface,
Upars,
Vpars,
nbdeltaU,
nbdeltaV,
(gp_Pnt*)C_MyPnts,
(Standard_Real*)C_MyU,
(Standard_Real*)C_MyV,
(Standard_Boolean*)C_MyIsOnBounds,
static_cast<gp_Pnt*>(C_MyPnts),
static_cast<Standard_Real*>(C_MyU),
static_cast<Standard_Real*>(C_MyV),
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
// Calculate triangle deflections
Standard_Real tol = 0.0;
Standard_Integer nbtriangles = NbTriangles();
for (Standard_Integer i1 = 1; i1 <= nbtriangles; i1++)
{
Standard_Real tol1 = DeflectionOnTriangle(Surface, i1);
if (tol1 > tol)
tol = tol1;
}
Standard_Real tol =
PolyUtils::ComputeMaxDeflection<Handle(Adaptor3d_Surface),
Adaptor3d_HSurfaceTool,
IntCurveSurface_ThePolyhedronOfHInter>(Surface,
*this,
NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
// Compute border deflection
TheBorderDeflection = RealFirst();
Standard_Integer i0 = Upars.Lower();
Standard_Integer j0 = Vpars.Lower();
Standard_Real U0 = Upars(i0);
Standard_Real V0 = Vpars(j0);
Standard_Real U1 = Upars(Upars.Upper());
Standard_Real V1 = Vpars(Vpars.Upper());
Standard_Real aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U0, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U1, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V0, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V1, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
TheBorderDeflection =
PolyUtils::ComputeMaxBorderDeflection<Handle(Adaptor3d_Surface), Adaptor3d_HSurfaceTool>(
Surface,
Upars(Upars.Lower()),
Vpars(Vpars.Lower()),
Upars(Upars.Upper()),
Vpars(Vpars.Upper()),
nbdeltaU,
nbdeltaV);
}
//==================================================================================================
@@ -221,36 +166,18 @@ Standard_Real IntCurveSurface_ThePolyhedronOfHInter::DeflectionOnTriangle(
{
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);
gp_Pnt P2 = Point(i2, u2, v2);
gp_Pnt P3 = Point(i3, u3, v3);
return IntCurveSurface_PolyhedronUtils::DeflectionOnTriangle<
Handle(Adaptor3d_Surface),
Adaptor3d_HSurfaceTool>(Surface, P1, P2, P3, u1, v1, u2, v2, u3, v3);
}
//==================================================================================================
Standard_Real IntCurveSurface_ThePolyhedronOfHInter::ComputeBorderDeflection(
const Handle(Adaptor3d_Surface)& Surface,
const Standard_Real Parameter,
const Standard_Real PMin,
const Standard_Real PMax,
const Standard_Boolean isUIso) const
{
Standard_Integer aNbSamples = isUIso ? nbdeltaV : nbdeltaU;
return IntCurveSurface_PolyhedronUtils::ComputeBorderDeflection<Handle(Adaptor3d_Surface),
Adaptor3d_HSurfaceTool>(
Surface,
Parameter,
PMin,
PMax,
isUIso,
aNbSamples);
gp_Pnt P1 = Point(i1, u1, v1), P2 = Point(i2, u2, v2), P3 = Point(i3, u3, v3);
return PolyUtils::DeflectionOnTriangle<Handle(Adaptor3d_Surface), Adaptor3d_HSurfaceTool>(Surface,
P1,
P2,
P3,
u1,
v1,
u2,
v2,
u3,
v3);
}
//==================================================================================================
@@ -259,26 +186,14 @@ void IntCurveSurface_ThePolyhedronOfHInter::Parameters(const Standard_Integer In
Standard_Real& U,
Standard_Real& V) const
{
Standard_Real* CMyU = (Standard_Real*)C_MyU;
U = CMyU[Index];
Standard_Real* CMyV = (Standard_Real*)C_MyV;
V = CMyV[Index];
PolyUtils::Parameters(Index, C_MyU, C_MyV, U, V);
}
//==================================================================================================
void IntCurveSurface_ThePolyhedronOfHInter::DeflectionOverEstimation(const Standard_Real flec)
{
if (flec < 0.0001)
{
TheDeflection = 0.0001;
TheBnd.Enlarge(0.0001);
}
else
{
TheDeflection = flec;
TheBnd.Enlarge(flec);
}
PolyUtils::SetDeflectionOverEstimation(flec, TheDeflection, TheBnd);
}
//==================================================================================================
@@ -300,32 +215,11 @@ const Bnd_Box& IntCurveSurface_ThePolyhedronOfHInter::Bounding() const
void IntCurveSurface_ThePolyhedronOfHInter::FillBounding()
{
TheComponentsBnd = new Bnd_HArray1OfBox(1, NbTriangles());
Bnd_Box Boite;
Standard_Integer np1, np2, np3;
Standard_Integer nbtriangles = NbTriangles();
for (Standard_Integer iTri = 1; iTri <= nbtriangles; iTri++)
{
Triangle(iTri, np1, np2, np3);
gp_Pnt p1(Point(np1));
gp_Pnt p2(Point(np2));
gp_Pnt p3(Point(np3));
Boite.SetVoid();
if (p1.SquareDistance(p2) > LONGUEUR_MINI_EDGE_TRIANGLE)
{
if (p1.SquareDistance(p3) > LONGUEUR_MINI_EDGE_TRIANGLE)
{
if (p2.SquareDistance(p3) > LONGUEUR_MINI_EDGE_TRIANGLE)
{
Boite.Add(p1);
Boite.Add(p2);
Boite.Add(p3);
Boite.Enlarge(TheDeflection);
}
}
}
Boite.Enlarge(TheDeflection);
TheComponentsBnd->SetValue(iTri, Boite);
}
PolyUtils::FillBounding(static_cast<gp_Pnt*>(C_MyPnts),
nbdeltaU,
nbdeltaV,
TheDeflection,
TheComponentsBnd);
}
//==================================================================================================
@@ -339,14 +233,14 @@ const Handle(Bnd_HArray1OfBox)& IntCurveSurface_ThePolyhedronOfHInter::Component
Standard_Integer IntCurveSurface_ThePolyhedronOfHInter::NbTriangles() const
{
return nbdeltaU * nbdeltaV * 2;
return PolyUtils::NbTriangles(nbdeltaU, nbdeltaV);
}
//==================================================================================================
Standard_Integer IntCurveSurface_ThePolyhedronOfHInter::NbPoints() const
{
return (nbdeltaU + 1) * (nbdeltaV + 1);
return PolyUtils::NbPoints(nbdeltaU, nbdeltaV);
}
//==================================================================================================
@@ -357,216 +251,7 @@ Standard_Integer IntCurveSurface_ThePolyhedronOfHInter::TriConnex(const Standard
Standard_Integer& TriCon,
Standard_Integer& OtherP) const
{
Standard_Integer Pivotm1 = Pivot - 1;
Standard_Integer nbdeltaVp1 = nbdeltaV + 1;
Standard_Integer nbdeltaVm2 = nbdeltaV + nbdeltaV;
Standard_Integer ligP = Pivotm1 / nbdeltaVp1;
Standard_Integer colP = Pivotm1 - ligP * nbdeltaVp1;
Standard_Integer ligE = 0, colE = 0, typE = 0;
if (Pedge != 0)
{
ligE = (Pedge - 1) / nbdeltaVp1;
colE = (Pedge - 1) - (ligE * nbdeltaVp1);
if (ligP == ligE)
typE = 1;
else if (colP == colE)
typE = 2;
else
typE = 3;
}
Standard_Integer linT = 0, colT = 0;
Standard_Integer linO = 0, colO = 0;
Standard_Integer t = 0, tt = 0;
if (Triang != 0)
{
t = (Triang - 1) / nbdeltaVm2;
tt = (Triang - 1) - t * nbdeltaVm2;
linT = 1 + t;
colT = 1 + tt;
if (typE == 0)
{
if (ligP == linT)
{
ligE = ligP - 1;
colE = colP - 1;
typE = 3;
}
else
{
if (colT == ligP + ligP)
{
ligE = ligP;
colE = colP - 1;
typE = 1;
}
else
{
ligE = ligP + 1;
colE = colP + 1;
typE = 3;
}
}
}
switch (typE)
{
case 1:
if (linT == ligP)
{
linT++;
linO = ligP + 1;
colO = (colP > colE) ? colP : colE;
}
else
{
linT--;
linO = ligP - 1;
colO = (colP < colE) ? colP : colE;
}
break;
case 2:
if (colT == (colP + colP))
{
colT++;
linO = (ligP > ligE) ? ligP : ligE;
colO = colP + 1;
}
else
{
colT--;
linO = (ligP < ligE) ? ligP : ligE;
colO = colP - 1;
}
break;
case 3:
if ((colT & 1) == 0)
{
colT--;
linO = (ligP > ligE) ? ligP : ligE;
colO = (colP < colE) ? colP : colE;
}
else
{
colT++;
linO = (ligP < ligE) ? ligP : ligE;
colO = (colP > colE) ? colP : colE;
}
break;
}
}
else
{
if (Pedge == 0)
{
linT = (1 > ligP) ? 1 : ligP;
colT = (1 > (colP + colP)) ? 1 : (colP + colP);
if (ligP == 0)
linO = ligP + 1;
else
linO = ligP - 1;
colO = colP;
}
else
{
switch (typE)
{
case 1:
linT = ligP + 1;
colT = (colP > colE) ? colP : colE;
colT += colT;
linO = ligP + 1;
colO = (colP > colE) ? colP : colE;
break;
case 2:
linT = (ligP > ligE) ? ligP : ligE;
colT = colP + colP;
linO = (ligP < ligE) ? ligP : ligE;
colO = colP - 1;
break;
case 3:
linT = (ligP > ligE) ? ligP : ligE;
colT = colP + colE;
linO = (ligP > ligE) ? ligP : ligE;
colO = (colP < colE) ? colP : colE;
break;
}
}
}
TriCon = (linT - 1) * nbdeltaVm2 + colT;
if (linT < 1)
{
linO = 0;
colO = colP + colP - colE;
if (colO < 0)
{
colO = 0;
linO = 1;
}
else if (colO > nbdeltaV)
{
colO = nbdeltaV;
linO = 1;
}
TriCon = 0;
}
else if (linT > nbdeltaU)
{
linO = nbdeltaU;
colO = colP + colP - colE;
if (colO < 0)
{
colO = 0;
linO = nbdeltaU - 1;
}
else if (colO > nbdeltaV)
{
colO = nbdeltaV;
linO = nbdeltaU - 1;
}
TriCon = 0;
}
if (colT < 1)
{
colO = 0;
linO = ligP + ligP - ligE;
if (linO < 0)
{
linO = 0;
colO = 1;
}
else if (linO > nbdeltaU)
{
linO = nbdeltaU;
colO = 1;
}
TriCon = 0;
}
else if (colT > nbdeltaV)
{
colO = nbdeltaV;
linO = ligP + ligP - ligE;
if (linO < 0)
{
linO = 0;
colO = nbdeltaV - 1;
}
else if (linO > nbdeltaU)
{
linO = nbdeltaU;
colO = nbdeltaV - 1;
}
TriCon = 0;
}
OtherP = linO * nbdeltaVp1 + colO + 1;
return TriCon;
return PolyUtils::TriConnex(Triang, Pivot, Pedge, TriCon, OtherP, nbdeltaU, nbdeltaV);
}
//==================================================================================================
@@ -577,42 +262,7 @@ void IntCurveSurface_ThePolyhedronOfHInter::PlaneEquation(const Standard_Integer
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
gp_XYZ Pointi1(Point(i1).XYZ());
gp_XYZ Pointi2(Point(i2).XYZ());
gp_XYZ Pointi3(Point(i3).XYZ());
gp_XYZ v1 = Pointi2 - Pointi1;
gp_XYZ v2 = Pointi3 - Pointi2;
gp_XYZ v3 = Pointi1 - Pointi3;
if (v1.SquareModulus() <= LONGUEUR_MINI_EDGE_TRIANGLE)
{
NormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
if (v2.SquareModulus() <= LONGUEUR_MINI_EDGE_TRIANGLE)
{
NormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
if (v3.SquareModulus() <= LONGUEUR_MINI_EDGE_TRIANGLE)
{
NormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
NormalVector = (v1 ^ v2) + (v2 ^ v3) + (v3 ^ v1);
Standard_Real aNormLen = NormalVector.Modulus();
if (aNormLen < gp::Resolution())
{
PolarDistance = 0.;
}
else
{
NormalVector.Divide(aNormLen);
PolarDistance = NormalVector * Point(i1).XYZ();
}
PolyUtils::PlaneEquation(Point(i1), Point(i2), Point(i3), NormalVector, PolarDistance);
}
//==================================================================================================
@@ -622,17 +272,7 @@ Standard_Boolean IntCurveSurface_ThePolyhedronOfHInter::Contain(const Standard_I
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
gp_XYZ Pointi1(Point(i1).XYZ());
gp_XYZ Pointi2(Point(i2).XYZ());
gp_XYZ Pointi3(Point(i3).XYZ());
gp_XYZ v1 = (Pointi2 - Pointi1) ^ (ThePnt.XYZ() - Pointi1);
gp_XYZ v2 = (Pointi3 - Pointi2) ^ (ThePnt.XYZ() - Pointi2);
gp_XYZ v3 = (Pointi1 - Pointi3) ^ (ThePnt.XYZ() - Pointi3);
if (v1 * v2 >= 0. && v2 * v3 >= 0. && v3 * v1 >= 0.)
return Standard_True;
else
return Standard_False;
return PolyUtils::Contain(Point(i1), Point(i2), Point(i3), ThePnt);
}
//==================================================================================================
@@ -655,13 +295,7 @@ void IntCurveSurface_ThePolyhedronOfHInter::Triangle(const Standard_Integer Inde
Standard_Integer& P2,
Standard_Integer& P3) const
{
Standard_Integer line = 1 + ((Index - 1) / (nbdeltaV * 2));
Standard_Integer colon = 1 + ((Index - 1) % (nbdeltaV * 2));
Standard_Integer colpnt = (colon + 1) / 2;
P1 = (line - 1) * (nbdeltaV + 1) + colpnt;
P2 = line * (nbdeltaV + 1) + colpnt + ((colon - 1) % 2);
P3 = (line - 1 + (colon % 2)) * (nbdeltaV + 1) + colpnt + 1;
PolyUtils::Triangle(Index, P1, P2, P3, nbdeltaV);
}
//==================================================================================================
@@ -670,20 +304,14 @@ const gp_Pnt& IntCurveSurface_ThePolyhedronOfHInter::Point(const Standard_Intege
Standard_Real& U,
Standard_Real& V) const
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
Standard_Real* CMyU = (Standard_Real*)C_MyU;
Standard_Real* CMyV = (Standard_Real*)C_MyV;
U = CMyU[Index];
V = CMyV[Index];
return CMyPnts[Index];
return PolyUtils::Point(Index, C_MyPnts, C_MyU, C_MyV, U, V);
}
//==================================================================================================
const gp_Pnt& IntCurveSurface_ThePolyhedronOfHInter::Point(const Standard_Integer Index) const
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
return CMyPnts[Index];
return PolyUtils::Point(Index, C_MyPnts);
}
//==================================================================================================
@@ -694,15 +322,13 @@ void IntCurveSurface_ThePolyhedronOfHInter::Point(const gp_Pnt&,
const Standard_Real,
const Standard_Real)
{
// Should not be called
}
//==================================================================================================
void IntCurveSurface_ThePolyhedronOfHInter::Point(const Standard_Integer Index, gp_Pnt& P) const
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
P = CMyPnts[Index];
PolyUtils::Point(Index, C_MyPnts, P);
}
//==================================================================================================
@@ -711,22 +337,11 @@ Standard_Boolean IntCurveSurface_ThePolyhedronOfHInter::IsOnBound(
const Standard_Integer Index1,
const Standard_Integer Index2) const
{
Standard_Boolean* CMyIsOnBounds = (Standard_Boolean*)C_MyIsOnBounds;
Standard_Integer aDiff = std::abs(Index1 - Index2);
if (aDiff != 1 && aDiff != nbdeltaV + 1)
return Standard_False;
for (Standard_Integer i = 0; i <= nbdeltaU; i++)
{
if ((Index1 == 1 + i * (nbdeltaV + 1)) && (Index2 == Index1 - 1))
return Standard_False;
if ((Index1 == (1 + i) * (nbdeltaV + 1)) && (Index2 == Index1 + 1))
return Standard_False;
}
return (CMyIsOnBounds[Index1] && CMyIsOnBounds[Index2]);
return PolyUtils::IsOnBound(Index1,
Index2,
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
nbdeltaU,
nbdeltaV);
}
//==================================================================================================

View File

@@ -164,14 +164,6 @@ protected:
const TColStd_Array1OfReal& Vpars);
private:
//! This method computes and returns a deflection of isoline
//! of given parameter on Surface.
Standard_EXPORT Standard_Real ComputeBorderDeflection(const Handle(Adaptor3d_Surface)& Surface,
const Standard_Real Parameter,
const Standard_Real PMin,
const Standard_Real PMax,
const Standard_Boolean isUIso) const;
Standard_Integer nbdeltaU;
Standard_Integer nbdeltaV;
Bnd_Box TheBnd;

View File

@@ -27,7 +27,8 @@
#include "../../TKGeomAlgo/IntCurveSurface/IntCurveSurface_PolyhedronUtils.pxx"
#define LONGUEUR_MINI_EDGE_TRIANGLE 1e-15
// Namespace alias for brevity
namespace PolyUtils = IntCurveSurface_PolyhedronUtils;
//==================================================================================================
@@ -47,11 +48,7 @@ HLRBRep_ThePolyhedronOfInterCSurf::HLRBRep_ThePolyhedronOfInterCSurf(
C_MyV(NULL),
C_MyIsOnBounds(NULL)
{
Standard_Integer t = (nbdeltaU + 1) * (nbdeltaV + 1) + 1;
C_MyPnts = new gp_Pnt[t];
C_MyU = new Standard_Real[t];
C_MyV = new Standard_Real[t];
C_MyIsOnBounds = new Standard_Boolean[t];
PolyUtils::AllocateArrays(nbdeltaU, nbdeltaV, C_MyPnts, C_MyU, C_MyV, C_MyIsOnBounds);
Init(Surface, u1, v1, u2, v2);
}
@@ -69,11 +66,7 @@ HLRBRep_ThePolyhedronOfInterCSurf::HLRBRep_ThePolyhedronOfInterCSurf(
C_MyV(NULL),
C_MyIsOnBounds(NULL)
{
Standard_Integer t = (nbdeltaU + 1) * (nbdeltaV + 1) + 1;
C_MyPnts = new gp_Pnt[t];
C_MyU = new Standard_Real[t];
C_MyV = new Standard_Real[t];
C_MyIsOnBounds = new Standard_Boolean[t];
PolyUtils::AllocateArrays(nbdeltaU, nbdeltaV, C_MyPnts, C_MyU, C_MyV, C_MyIsOnBounds);
Init(Surface, Upars, Vpars);
}
@@ -81,20 +74,7 @@ HLRBRep_ThePolyhedronOfInterCSurf::HLRBRep_ThePolyhedronOfInterCSurf(
void HLRBRep_ThePolyhedronOfInterCSurf::Destroy()
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
if (C_MyPnts)
delete[] CMyPnts;
Standard_Real* CMyU = (Standard_Real*)C_MyU;
if (C_MyU)
delete[] CMyU;
Standard_Real* CMyV = (Standard_Real*)C_MyV;
if (C_MyV)
delete[] CMyV;
Standard_Boolean* CMyIsOnBounds = (Standard_Boolean*)C_MyIsOnBounds;
if (C_MyIsOnBounds)
delete[] CMyIsOnBounds;
C_MyPnts = C_MyU = C_MyV = C_MyIsOnBounds = NULL;
PolyUtils::Destroy(C_MyPnts, C_MyU, C_MyV, C_MyIsOnBounds);
}
//==================================================================================================
@@ -105,7 +85,7 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Init(const Standard_Address& Surface,
const Standard_Real U1,
const Standard_Real V1)
{
IntCurveSurface_PolyhedronUtils::InitUniform<Standard_Address, HLRBRep_SurfaceTool>(
PolyUtils::InitUniform<Standard_Address, HLRBRep_SurfaceTool>(
Surface,
U0,
V0,
@@ -113,44 +93,29 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Init(const Standard_Address& Surface,
V1,
nbdeltaU,
nbdeltaV,
(gp_Pnt*)C_MyPnts,
(Standard_Real*)C_MyU,
(Standard_Real*)C_MyV,
(Standard_Boolean*)C_MyIsOnBounds,
static_cast<gp_Pnt*>(C_MyPnts),
static_cast<Standard_Real*>(C_MyU),
static_cast<Standard_Real*>(C_MyV),
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
// Calculate triangle deflections
Standard_Real tol = 0.0;
Standard_Integer nbtriangles = NbTriangles();
for (Standard_Integer i1 = 1; i1 <= nbtriangles; i1++)
{
Standard_Real tol1 = DeflectionOnTriangle(Surface, i1);
if (tol1 > tol)
tol = tol1;
}
Standard_Real tol =
PolyUtils::ComputeMaxDeflection<Standard_Address,
HLRBRep_SurfaceTool,
HLRBRep_ThePolyhedronOfInterCSurf>(Surface,
*this,
NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
// Compute border deflection
TheBorderDeflection = RealFirst();
Standard_Real aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U0, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U1, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V0, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V1, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
TheBorderDeflection =
PolyUtils::ComputeMaxBorderDeflection<Standard_Address, HLRBRep_SurfaceTool>(Surface,
U0,
V0,
U1,
V1,
nbdeltaU,
nbdeltaV);
}
//==================================================================================================
@@ -159,56 +124,36 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Init(const Standard_Address& Surface
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars)
{
IntCurveSurface_PolyhedronUtils::InitWithParams<Standard_Address, HLRBRep_SurfaceTool>(
PolyUtils::InitWithParams<Standard_Address, HLRBRep_SurfaceTool>(
Surface,
Upars,
Vpars,
nbdeltaU,
nbdeltaV,
(gp_Pnt*)C_MyPnts,
(Standard_Real*)C_MyU,
(Standard_Real*)C_MyV,
(Standard_Boolean*)C_MyIsOnBounds,
static_cast<gp_Pnt*>(C_MyPnts),
static_cast<Standard_Real*>(C_MyU),
static_cast<Standard_Real*>(C_MyV),
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
TheBnd);
// Calculate triangle deflections
Standard_Real tol = 0.0;
Standard_Integer nbtriangles = NbTriangles();
for (Standard_Integer i1 = 1; i1 <= nbtriangles; i1++)
{
Standard_Real tol1 = DeflectionOnTriangle(Surface, i1);
if (tol1 > tol)
tol = tol1;
}
Standard_Real tol =
PolyUtils::ComputeMaxDeflection<Standard_Address,
HLRBRep_SurfaceTool,
HLRBRep_ThePolyhedronOfInterCSurf>(Surface,
*this,
NbTriangles());
DeflectionOverEstimation(tol * 1.2);
FillBounding();
// Compute border deflection
TheBorderDeflection = RealFirst();
Standard_Integer i0 = Upars.Lower();
Standard_Integer j0 = Vpars.Lower();
Standard_Real U0 = Upars(i0);
Standard_Real V0 = Vpars(j0);
Standard_Real U1 = Upars(Upars.Upper());
Standard_Real V1 = Vpars(Vpars.Upper());
Standard_Real aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U0, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, U1, V0, V1, Standard_True);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V0, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
aDeflection = ComputeBorderDeflection(Surface, V1, U0, U1, Standard_False);
if (aDeflection > TheBorderDeflection)
TheBorderDeflection = aDeflection;
TheBorderDeflection =
PolyUtils::ComputeMaxBorderDeflection<Standard_Address, HLRBRep_SurfaceTool>(
Surface,
Upars(Upars.Lower()),
Vpars(Vpars.Lower()),
Upars(Upars.Upper()),
Vpars(Vpars.Upper()),
nbdeltaU,
nbdeltaV);
}
//==================================================================================================
@@ -219,35 +164,18 @@ Standard_Real HLRBRep_ThePolyhedronOfInterCSurf::DeflectionOnTriangle(
{
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);
gp_Pnt P2 = Point(i2, u2, v2);
gp_Pnt P3 = Point(i3, u3, v3);
return IntCurveSurface_PolyhedronUtils::DeflectionOnTriangle<
Standard_Address,
HLRBRep_SurfaceTool>(Surface, P1, P2, P3, u1, v1, u2, v2, u3, v3);
}
//==================================================================================================
Standard_Real HLRBRep_ThePolyhedronOfInterCSurf::ComputeBorderDeflection(
const Standard_Address& Surface,
const Standard_Real Parameter,
const Standard_Real PMin,
const Standard_Real PMax,
const Standard_Boolean isUIso) const
{
Standard_Integer aNbSamples = isUIso ? nbdeltaV : nbdeltaU;
return IntCurveSurface_PolyhedronUtils::ComputeBorderDeflection<Standard_Address,
HLRBRep_SurfaceTool>(Surface,
Parameter,
PMin,
PMax,
isUIso,
aNbSamples);
gp_Pnt P1 = Point(i1, u1, v1), P2 = Point(i2, u2, v2), P3 = Point(i3, u3, v3);
return PolyUtils::DeflectionOnTriangle<Standard_Address, HLRBRep_SurfaceTool>(Surface,
P1,
P2,
P3,
u1,
v1,
u2,
v2,
u3,
v3);
}
//==================================================================================================
@@ -256,26 +184,14 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Parameters(const Standard_Integer Index,
Standard_Real& U,
Standard_Real& V) const
{
Standard_Real* CMyU = (Standard_Real*)C_MyU;
U = CMyU[Index];
Standard_Real* CMyV = (Standard_Real*)C_MyV;
V = CMyV[Index];
PolyUtils::Parameters(Index, C_MyU, C_MyV, U, V);
}
//==================================================================================================
void HLRBRep_ThePolyhedronOfInterCSurf::DeflectionOverEstimation(const Standard_Real flec)
{
if (flec < 0.0001)
{
TheDeflection = 0.0001;
TheBnd.Enlarge(0.0001);
}
else
{
TheDeflection = flec;
TheBnd.Enlarge(flec);
}
PolyUtils::SetDeflectionOverEstimation(flec, TheDeflection, TheBnd);
}
//==================================================================================================
@@ -297,32 +213,11 @@ const Bnd_Box& HLRBRep_ThePolyhedronOfInterCSurf::Bounding() const
void HLRBRep_ThePolyhedronOfInterCSurf::FillBounding()
{
TheComponentsBnd = new Bnd_HArray1OfBox(1, NbTriangles());
Bnd_Box Boite;
Standard_Integer np1, np2, np3;
Standard_Integer nbtriangles = NbTriangles();
for (Standard_Integer iTri = 1; iTri <= nbtriangles; iTri++)
{
Triangle(iTri, np1, np2, np3);
gp_Pnt p1(Point(np1));
gp_Pnt p2(Point(np2));
gp_Pnt p3(Point(np3));
Boite.SetVoid();
if (p1.SquareDistance(p2) > LONGUEUR_MINI_EDGE_TRIANGLE)
{
if (p1.SquareDistance(p3) > LONGUEUR_MINI_EDGE_TRIANGLE)
{
if (p2.SquareDistance(p3) > LONGUEUR_MINI_EDGE_TRIANGLE)
{
Boite.Add(p1);
Boite.Add(p2);
Boite.Add(p3);
Boite.Enlarge(TheDeflection);
}
}
}
Boite.Enlarge(TheDeflection);
TheComponentsBnd->SetValue(iTri, Boite);
}
PolyUtils::FillBounding(static_cast<gp_Pnt*>(C_MyPnts),
nbdeltaU,
nbdeltaV,
TheDeflection,
TheComponentsBnd);
}
//==================================================================================================
@@ -336,14 +231,14 @@ const Handle(Bnd_HArray1OfBox)& HLRBRep_ThePolyhedronOfInterCSurf::ComponentsBou
Standard_Integer HLRBRep_ThePolyhedronOfInterCSurf::NbTriangles() const
{
return nbdeltaU * nbdeltaV * 2;
return PolyUtils::NbTriangles(nbdeltaU, nbdeltaV);
}
//==================================================================================================
Standard_Integer HLRBRep_ThePolyhedronOfInterCSurf::NbPoints() const
{
return (nbdeltaU + 1) * (nbdeltaV + 1);
return PolyUtils::NbPoints(nbdeltaU, nbdeltaV);
}
//==================================================================================================
@@ -354,216 +249,7 @@ Standard_Integer HLRBRep_ThePolyhedronOfInterCSurf::TriConnex(const Standard_Int
Standard_Integer& TriCon,
Standard_Integer& OtherP) const
{
Standard_Integer Pivotm1 = Pivot - 1;
Standard_Integer nbdeltaVp1 = nbdeltaV + 1;
Standard_Integer nbdeltaVm2 = nbdeltaV + nbdeltaV;
Standard_Integer ligP = Pivotm1 / nbdeltaVp1;
Standard_Integer colP = Pivotm1 - ligP * nbdeltaVp1;
Standard_Integer ligE = 0, colE = 0, typE = 0;
if (Pedge != 0)
{
ligE = (Pedge - 1) / nbdeltaVp1;
colE = (Pedge - 1) - (ligE * nbdeltaVp1);
if (ligP == ligE)
typE = 1;
else if (colP == colE)
typE = 2;
else
typE = 3;
}
Standard_Integer linT = 0, colT = 0;
Standard_Integer linO = 0, colO = 0;
Standard_Integer t = 0, tt = 0;
if (Triang != 0)
{
t = (Triang - 1) / nbdeltaVm2;
tt = (Triang - 1) - t * nbdeltaVm2;
linT = 1 + t;
colT = 1 + tt;
if (typE == 0)
{
if (ligP == linT)
{
ligE = ligP - 1;
colE = colP - 1;
typE = 3;
}
else
{
if (colT == ligP + ligP)
{
ligE = ligP;
colE = colP - 1;
typE = 1;
}
else
{
ligE = ligP + 1;
colE = colP + 1;
typE = 3;
}
}
}
switch (typE)
{
case 1:
if (linT == ligP)
{
linT++;
linO = ligP + 1;
colO = (colP > colE) ? colP : colE;
}
else
{
linT--;
linO = ligP - 1;
colO = (colP < colE) ? colP : colE;
}
break;
case 2:
if (colT == (colP + colP))
{
colT++;
linO = (ligP > ligE) ? ligP : ligE;
colO = colP + 1;
}
else
{
colT--;
linO = (ligP < ligE) ? ligP : ligE;
colO = colP - 1;
}
break;
case 3:
if ((colT & 1) == 0)
{
colT--;
linO = (ligP > ligE) ? ligP : ligE;
colO = (colP < colE) ? colP : colE;
}
else
{
colT++;
linO = (ligP < ligE) ? ligP : ligE;
colO = (colP > colE) ? colP : colE;
}
break;
}
}
else
{
if (Pedge == 0)
{
linT = (1 > ligP) ? 1 : ligP;
colT = (1 > (colP + colP)) ? 1 : (colP + colP);
if (ligP == 0)
linO = ligP + 1;
else
linO = ligP - 1;
colO = colP;
}
else
{
switch (typE)
{
case 1:
linT = ligP + 1;
colT = (colP > colE) ? colP : colE;
colT += colT;
linO = ligP + 1;
colO = (colP > colE) ? colP : colE;
break;
case 2:
linT = (ligP > ligE) ? ligP : ligE;
colT = colP + colP;
linO = (ligP < ligE) ? ligP : ligE;
colO = colP - 1;
break;
case 3:
linT = (ligP > ligE) ? ligP : ligE;
colT = colP + colE;
linO = (ligP > ligE) ? ligP : ligE;
colO = (colP < colE) ? colP : colE;
break;
}
}
}
TriCon = (linT - 1) * nbdeltaVm2 + colT;
if (linT < 1)
{
linO = 0;
colO = colP + colP - colE;
if (colO < 0)
{
colO = 0;
linO = 1;
}
else if (colO > nbdeltaV)
{
colO = nbdeltaV;
linO = 1;
}
TriCon = 0;
}
else if (linT > nbdeltaU)
{
linO = nbdeltaU;
colO = colP + colP - colE;
if (colO < 0)
{
colO = 0;
linO = nbdeltaU - 1;
}
else if (colO > nbdeltaV)
{
colO = nbdeltaV;
linO = nbdeltaU - 1;
}
TriCon = 0;
}
if (colT < 1)
{
colO = 0;
linO = ligP + ligP - ligE;
if (linO < 0)
{
linO = 0;
colO = 1;
}
else if (linO > nbdeltaU)
{
linO = nbdeltaU;
colO = 1;
}
TriCon = 0;
}
else if (colT > nbdeltaV)
{
colO = nbdeltaV;
linO = ligP + ligP - ligE;
if (linO < 0)
{
linO = 0;
colO = nbdeltaV - 1;
}
else if (linO > nbdeltaU)
{
linO = nbdeltaU;
colO = nbdeltaV - 1;
}
TriCon = 0;
}
OtherP = linO * nbdeltaVp1 + colO + 1;
return TriCon;
return PolyUtils::TriConnex(Triang, Pivot, Pedge, TriCon, OtherP, nbdeltaU, nbdeltaV);
}
//==================================================================================================
@@ -574,42 +260,7 @@ void HLRBRep_ThePolyhedronOfInterCSurf::PlaneEquation(const Standard_Integer Tri
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
gp_XYZ Pointi1(Point(i1).XYZ());
gp_XYZ Pointi2(Point(i2).XYZ());
gp_XYZ Pointi3(Point(i3).XYZ());
gp_XYZ v1 = Pointi2 - Pointi1;
gp_XYZ v2 = Pointi3 - Pointi2;
gp_XYZ v3 = Pointi1 - Pointi3;
if (v1.SquareModulus() <= LONGUEUR_MINI_EDGE_TRIANGLE)
{
NormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
if (v2.SquareModulus() <= LONGUEUR_MINI_EDGE_TRIANGLE)
{
NormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
if (v3.SquareModulus() <= LONGUEUR_MINI_EDGE_TRIANGLE)
{
NormalVector.SetCoord(1.0, 0.0, 0.0);
return;
}
NormalVector = (v1 ^ v2) + (v2 ^ v3) + (v3 ^ v1);
Standard_Real aNormLen = NormalVector.Modulus();
if (aNormLen < gp::Resolution())
{
PolarDistance = 0.;
}
else
{
NormalVector.Divide(aNormLen);
PolarDistance = NormalVector * Point(i1).XYZ();
}
PolyUtils::PlaneEquation(Point(i1), Point(i2), Point(i3), NormalVector, PolarDistance);
}
//==================================================================================================
@@ -619,17 +270,7 @@ Standard_Boolean HLRBRep_ThePolyhedronOfInterCSurf::Contain(const Standard_Integ
{
Standard_Integer i1, i2, i3;
Triangle(Triang, i1, i2, i3);
gp_XYZ Pointi1(Point(i1).XYZ());
gp_XYZ Pointi2(Point(i2).XYZ());
gp_XYZ Pointi3(Point(i3).XYZ());
gp_XYZ v1 = (Pointi2 - Pointi1) ^ (ThePnt.XYZ() - Pointi1);
gp_XYZ v2 = (Pointi3 - Pointi2) ^ (ThePnt.XYZ() - Pointi2);
gp_XYZ v3 = (Pointi1 - Pointi3) ^ (ThePnt.XYZ() - Pointi3);
if (v1 * v2 >= 0. && v2 * v3 >= 0. && v3 * v1 >= 0.)
return Standard_True;
else
return Standard_False;
return PolyUtils::Contain(Point(i1), Point(i2), Point(i3), ThePnt);
}
//==================================================================================================
@@ -651,13 +292,7 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Triangle(const Standard_Integer Index,
Standard_Integer& P2,
Standard_Integer& P3) const
{
Standard_Integer line = 1 + ((Index - 1) / (nbdeltaV * 2));
Standard_Integer colon = 1 + ((Index - 1) % (nbdeltaV * 2));
Standard_Integer colpnt = (colon + 1) / 2;
P1 = (line - 1) * (nbdeltaV + 1) + colpnt;
P2 = line * (nbdeltaV + 1) + colpnt + ((colon - 1) % 2);
P3 = (line - 1 + (colon % 2)) * (nbdeltaV + 1) + colpnt + 1;
PolyUtils::Triangle(Index, P1, P2, P3, nbdeltaV);
}
//==================================================================================================
@@ -666,20 +301,14 @@ const gp_Pnt& HLRBRep_ThePolyhedronOfInterCSurf::Point(const Standard_Integer In
Standard_Real& U,
Standard_Real& V) const
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
Standard_Real* CMyU = (Standard_Real*)C_MyU;
Standard_Real* CMyV = (Standard_Real*)C_MyV;
U = CMyU[Index];
V = CMyV[Index];
return CMyPnts[Index];
return PolyUtils::Point(Index, C_MyPnts, C_MyU, C_MyV, U, V);
}
//==================================================================================================
const gp_Pnt& HLRBRep_ThePolyhedronOfInterCSurf::Point(const Standard_Integer Index) const
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
return CMyPnts[Index];
return PolyUtils::Point(Index, C_MyPnts);
}
//==================================================================================================
@@ -690,15 +319,13 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Point(const gp_Pnt&,
const Standard_Real,
const Standard_Real)
{
// Should not be called
}
//==================================================================================================
void HLRBRep_ThePolyhedronOfInterCSurf::Point(const Standard_Integer Index, gp_Pnt& P) const
{
gp_Pnt* CMyPnts = (gp_Pnt*)C_MyPnts;
P = CMyPnts[Index];
PolyUtils::Point(Index, C_MyPnts, P);
}
//==================================================================================================
@@ -706,22 +333,11 @@ void HLRBRep_ThePolyhedronOfInterCSurf::Point(const Standard_Integer Index, gp_P
Standard_Boolean HLRBRep_ThePolyhedronOfInterCSurf::IsOnBound(const Standard_Integer Index1,
const Standard_Integer Index2) const
{
Standard_Boolean* CMyIsOnBounds = (Standard_Boolean*)C_MyIsOnBounds;
Standard_Integer aDiff = std::abs(Index1 - Index2);
if (aDiff != 1 && aDiff != nbdeltaV + 1)
return Standard_False;
for (Standard_Integer i = 0; i <= nbdeltaU; i++)
{
if ((Index1 == 1 + i * (nbdeltaV + 1)) && (Index2 == Index1 - 1))
return Standard_False;
if ((Index1 == (1 + i) * (nbdeltaV + 1)) && (Index2 == Index1 + 1))
return Standard_False;
}
return (CMyIsOnBounds[Index1] && CMyIsOnBounds[Index2]);
return PolyUtils::IsOnBound(Index1,
Index2,
static_cast<Standard_Boolean*>(C_MyIsOnBounds),
nbdeltaU,
nbdeltaV);
}
//==================================================================================================

View File

@@ -170,15 +170,6 @@ protected:
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars);
private:
//! This method computes and returns a deflection of isoline
//! of given parameter on Surface.
Standard_EXPORT Standard_Real ComputeBorderDeflection(const Standard_Address& Surface,
const Standard_Real Parameter,
const Standard_Real PMin,
const Standard_Real PMax,
const Standard_Boolean isUIso) const;
private:
Standard_Integer nbdeltaU;
Standard_Integer nbdeltaV;