- aggiunta del membro statico per tenere in cache i polinomi di bernstein

- allocazione della memoria per il calcolo di bernstein fatto solo una volta per superficie.
This commit is contained in:
Daniele Bariletti
2025-03-11 14:48:34 +01:00
parent 5bc7036e98
commit 1cdae73b24
3 changed files with 201 additions and 40 deletions
+128
View File
@@ -51,6 +51,8 @@ static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposit
static bool ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam) ;
static bool BuildCommonParam( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam) ;
static unordered_map<pair<int,double>, DBLVECTOR, PairHash> m_mBernCache ; // mappa dei polinomi di bernstein
//----------------------------------------------------------------------------
SurfBezier::SurfBezier( void)
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_nSpanU(), m_nSpanV(), m_bRat( false),
@@ -92,6 +94,20 @@ SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational
m_nStatus = TO_VERIFY ;
m_nIsPlanar = NOT_CALCULATED ;
// setto la dimensione dei vettori
m_vBernU.resize( m_nDegU + 1) ;
m_vBernV.resize( m_nDegV + 1) ;
if (! m_bRat)
m_ptTemp.resize(m_nDegV + 1, ORIG) ;
else {
m_ptTempW.resize(m_nDegV + 1, ORIG) ;
m_dTempW.resize( m_nDegV + 1, 0) ;
m_vPtWCtrlLoc.resize( GetLocDim()) ;
m_vWeCtrlLoc.resize( GetLocDim()) ;
}
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
@@ -299,6 +315,118 @@ SurfBezier::GetCentroid( Point3d& ptCen) const
return m_pSTM->GetCentroid( ptCen) ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const
{
pair<int, double> key = std::make_pair(nDegU, dU);
if (m_mBernCache.find(key) == m_mBernCache.end()) {
DBLVECTOR vBern(nDegU + 1);
GetAllBernstein(dU, nDegU, vBern);
m_mBernCache[key] = vBern;
}
vBernU = m_mBernCache[key] ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::GetPoint( double dU, double dV, Side nUs, Side nVs,Point3d& ptPos) const
{
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// i parametri U e V devono essere compresi tra 0 e il corrispondente numero di Span
dU = Clamp( dU, 0., double( m_nSpanU)) ;
dV = Clamp( dV, 0., double( m_nSpanV)) ;
// determino gli intervalli di span e riduco i parametri in essi
int nBsU = min( int( dU), m_nSpanU - 1) ;
double dLocU = dU - nBsU ;
if ( abs( dLocU) < 5 * EPS_PARAM && nBsU > 0 && nUs == ISurfBezier::FROM_MINUS) {
-- nBsU ;
dLocU = 1 ;
}
else if ( abs( dLocU) > 1 - 5 * EPS_PARAM && nBsU < m_nSpanU - 1 && nUs == ISurfBezier::FROM_PLUS) {
++ nBsU ;
dLocU = 0 ;
}
int nOffsU = nBsU * m_nDegU ;
int nBsV = min( int( dV), m_nSpanV - 1) ;
double dLocV = dV - nBsV ;
if ( abs( dLocV) < 5 * EPS_PARAM && nBsV > 0 && nVs == ISurfBezier::FROM_MINUS) {
-- nBsV ;
dLocV = 1 ;
}
else if ( abs( dLocV) > 1 - 5 * EPS_PARAM && nBsV < m_nSpanV - 1 && nVs == ISurfBezier::FROM_PLUS) {
++ nBsV ;
dLocV = 0 ;
}
int nOffsV = nBsV * m_nDegV ;
// se forma polinomiale (o integrale)
if ( ! m_bRat) {
// calcolo dei polinomi di Bernstein per U di grado opportuno
GetBernstein( dLocU, m_nDegU, m_vBernU) ;
// calcolo dei punti intermedi
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
for ( int i = 0 ; i <= m_nDegU ; ++ i)
m_ptTemp[j] += m_vBernU[i] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ;
}
// calcolo dei polinomi di Bernstein per V di grado opportuno
GetBernstein( dLocV, m_nDegV, m_vBernV) ;
// calcolo del punto
ptPos = ORIG ;
for ( int j = 0 ; j <= m_nDegV ; ++ j)
ptPos += m_vBernV[j] * m_ptTemp[j] ;
}
// altrimenti forma razionale
else {
// recupero punti di controllo e pesi della patch in questione
// porto i punti in forma omogenea moltiplicandoli per i pesi
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
for ( int i = 0 ; i <= m_nDegU ; ++ i) {
m_vPtWCtrlLoc[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ;
m_vWeCtrlLoc[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] ;
}
}
// calcolo dei polinomi di Bernstein di grado opportuno
GetBernstein( dLocU, m_nDegU, m_vBernU) ;
// calcolo dei punti e pesi intermedi
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
for ( int i = 0 ; i <= m_nDegU ; ++ i) {
m_ptTempW[j] += m_vBernU[i] * m_vPtWCtrlLoc[GetLocInd( i, j)] ;
m_dTempW[j] += m_vBernU[i] * m_vWeCtrlLoc[GetLocInd( i, j)] ;
}
}
// calcolo dei polinomi di Bernstein per V di grado opportuno
GetBernstein( dLocV, m_nDegV, m_vBernV) ;
// calcolo del punto
double dW = 0 ;
ptPos = ORIG ;
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
ptPos += m_vBernV[j] * m_ptTempW[j] ;
dW += m_vBernV[j] * m_dTempW[j] ;
}
// ritrasformo da forma omogenea a forma standard
double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ;
ptPos *= dInvW ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::GetPointD1D2( double dU, double dV, Side nUs, Side nVs,
+18
View File
@@ -25,6 +25,14 @@
using namespace std ;
class Tree ;
struct PairHash {
std::size_t operator()(const std::pair<int, double>& key) const {
std::size_t h1 = std::hash<int>{}(key.first);
std::size_t h2 = std::hash<double>{}(key.second);
return h1 ^ (h2 << 1); // Combine hashes
}
};
//----------------------------------------------------------------------------
class SurfBezier : public ISurfBezier, public IGeoObjRW
{
@@ -103,6 +111,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
{ return GetControlWeight( GetInd( nIndU, nIndV), pbOk) ; }
double GetControlWeight( int nInd, bool* pbOk) const override ;
bool IsAPoint( void) const override ;
bool GetPoint( double dU, double dV, Side nUs, Side nVs, Point3d& ptPos) const override ;
bool GetPointD1D2( double dU, double dV, Side nUs, Side nVs,
Point3d& ptPos,
Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr,
@@ -209,6 +218,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ;
bool ReorderPntVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
bool ReorderPntEnhancedVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
bool GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
@@ -231,6 +241,14 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
mutable vector<ICRVCOMPOPOVECTOR> m_mCCEdge ;// vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
mutable int m_nIsPlanar ; // enum che indica se la superficie è piana ( -1, non è stato calcolato)
//static unordered_map<pair<int,double>, DBLVECTOR, PairHash> m_mBernCache ; // mappa dei polinomi di bernstein
mutable DBLVECTOR m_vBernU ;
mutable PNTVECTOR m_ptTemp ;
mutable DBLVECTOR m_vBernV ;
mutable PNTVECTOR m_ptTempW ;
mutable DBLVECTOR m_dTempW ;
mutable PNTVECTOR m_vPtWCtrlLoc ;
mutable DBLVECTOR m_vWeCtrlLoc ;
} ;
//-----------------------------------------------------------------------------
+55 -40
View File
@@ -269,10 +269,17 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
ptP01 = m_pSrfBz->GetControlPoint( ( nDegU * nSpanU + 1) * ( nDegV * nSpanV), &bOk) ;
}
else {
m_pSrfBz->GetPointD1D2( ptMin.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ;
m_pSrfBz->GetPointD1D2( ptMax.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ;
m_pSrfBz->GetPointD1D2( ptMax.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11) ;
m_pSrfBz->GetPointD1D2( ptMin.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ;
m_pSrfBz->GetPoint( ptMin.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ;
m_pSrfBz->GetPoint( ptMax.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ;
m_pSrfBz->GetPoint( ptMax.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11) ;
m_pSrfBz->GetPoint( ptMin.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ;
Point3d pt1, pt2, pt3, pt4 ;
m_pSrfBz->GetPointD1D2( ptMin.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt1) ;
m_pSrfBz->GetPointD1D2( ptMax.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt2) ;
m_pSrfBz->GetPointD1D2( ptMax.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3) ;
m_pSrfBz->GetPointD1D2( ptMin.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt4) ;
}
PNTVECTOR vVert ;
vVert.push_back( ptP00) ;
@@ -580,8 +587,8 @@ Tree::Split( int nId, double dSplitValue)
cChild2.m_nRight = cToSplit.m_nRight ;
// metto i corrispondenti 3d dei punti dello split nella mappa m_mVert
// per ogni cella i punti devono essere nell'ordine ptP00, ptP10, ptP11, ptP01
m_pSrfBz->GetPointD1D2( cToSplit.GetBottomLeft().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ;
m_pSrfBz->GetPointD1D2( cToSplit.GetTopRight().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ;
m_pSrfBz->GetPoint( cToSplit.GetBottomLeft().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ;
m_pSrfBz->GetPoint( cToSplit.GetTopRight().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ;
vVert1.push_back( ptVert1) ;
vVert1.push_back( ptVert2) ;
vVert1.push_back( m_mVert[nId][2]) ;
@@ -609,8 +616,8 @@ Tree::Split( int nId, double dSplitValue)
cChild2.m_nRight = cToSplit.m_nRight ;
// metto i corrispondenti 3d dei punti dello split nella mappa m_mVert
// per ogni cella i punti devono essere nell'ordine ptP00, ptP10, ptP11, ptP01
m_pSrfBz->GetPointD1D2( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ;
m_pSrfBz->GetPointD1D2( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ;
m_pSrfBz->GetPoint( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ;
m_pSrfBz->GetPoint( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ;
vVert1.push_back( m_mVert[nId][0]) ;
vVert1.push_back( ptVert2) ;
vVert1.push_back( ptVert1) ;
@@ -733,11 +740,11 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ;
double dULoc = 0.5, dVLoc = 0.5 ;
Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00 ;
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
m_pSrfBz->GetPointD1D2( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
m_pSrfBz->GetPointD1D2( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPoint( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
m_pSrfBz->GetPoint( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
m_pSrfBz->GetPoint( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
m_pSrfBz->GetPoint( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ;
Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ;
dCurvV = Dist( ptV, ptPSrf) ;
@@ -751,11 +758,11 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
for ( double k = dStep ; k < 1 + EPS_SMALL ; k = k + dStep) {
double dU = ( k * pcToSplit->GetTopRight().x + ( 1 - k) * pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ;
double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ;
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
if ( k == 0.5)
ptPSrfMid = ptPSrf ;
m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
m_pSrfBz->GetPoint( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
m_pSrfBz->GetPoint( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
CurveLine clV ;
clV.Set( ptP00P10, ptP11P01) ;
DistPointCurve dpc( ptPSrf, clV) ;
@@ -770,9 +777,9 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
if ( k == 0.5 && ! AreSamePointApprox( ORIG, ptPSrfMid))
ptPSrf = ptPSrfMid ;
else
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPointD1D2( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
m_pSrfBz->GetPointD1D2( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPoint( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
m_pSrfBz->GetPoint( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
CurveLine clU ;
clU.Set( ptP01P00, ptP10P11) ;
DistPointCurve dpc( ptPSrf, clU) ;
@@ -813,7 +820,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
plCell.AddUPoint(2,ptP11) ;
double dU = (pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / (SBZ_TREG_COEFF * 2) ;
double dV = (pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / (SBZ_TREG_COEFF * 2) ;
Point3d ptCen ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptCen) ;
Point3d ptCen ; m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptCen) ;
plCell.AddUPoint(3,ptCen) ;
plCell.AddUPoint(4,ptP01) ;
plCell.Close() ;
@@ -922,8 +929,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
for ( int u = 0 ; u < nStepsU && ! bSplit ; ++ u) {
double dU = double ( u) / double ( nStepsU - 1) ;
double dULoc = ( ( 1 - dU) * pcToSplit->GetBottomLeft().x + dU * pcToSplit->GetTopRight().x) / SBZ_TREG_COEFF ;
if ( ! m_pSrfBz->GetPointD1D2( dULoc, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) ||
! m_pSrfBz->GetPointD1D2( dULoc, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1))
if ( ! m_pSrfBz->GetPoint( dULoc, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) ||
! m_pSrfBz->GetPoint( dULoc, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1))
return false ;
// verifico che la cella non sia uno spicchio in verticale, cioè con ptP00 == ptP01 && ptP10 == ptP11
// ( vedi disegno sotto per uno spicchio verticale)
@@ -945,7 +952,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
for ( int v = 0 ; v < nStepsV ; ++ v) {
double dV = double ( v) / double ( nStepsV - 1) ;
double dVLoc = ( ( 1 - dV) * pcToSplit->GetBottomLeft().y + dV * pcToSplit->GetTopRight().y) / SBZ_TREG_COEFF ;
if ( ! m_pSrfBz->GetPointD1D2( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV))
if ( ! m_pSrfBz->GetPoint( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV))
return false ;
DistPointCurve dpc( ptBzV, clV) ;
// distanza di approssimazione locale
@@ -1077,7 +1084,11 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
for ( double j = 0.25 ; j < 1 ; j = j + 0.25) {
double dU = ( ( 1 - i) * pcToSplit->GetTopRight().x + i * pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ;
double dV = ( ( 1 - j) * pcToSplit->GetTopRight().y + j * pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ;
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
//debug
Point3d ptPSrf_old ;
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf_old) ;
//debug
dErr = max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ;
}
}
@@ -1599,6 +1610,8 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM
GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ;
else
GetPolygonsBasic( vPolygonsBasic) ;
if (vPolygonsBasic.empty())
return false ;
int c = 0;
if( bForTriangulation) {
for ( PolyLine pl : vPolygonsCorrected) {
@@ -1630,6 +1643,8 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM
GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ;
else
GetPolygonsBasic( vPolygonsBasic) ;
if (vPolygonsBasic.empty())
return false ;
// aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim
m_vCEdge2D.clear() ;
for ( int i = 0 ; i < 4 ; ++i) {
@@ -2013,7 +2028,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
double dU, dV ;
dU = ( cell.GetBottomLeft().x + cell.GetTopRight().x) / 2 / SBZ_TREG_COEFF ;
dV = ( cell.GetBottomLeft().y + cell.GetTopRight().y) / 2 / SBZ_TREG_COEFF ;
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
ptP00 = m_mVert.at( nId).at( 0) ;
ptP10 = m_mVert.at( nId).at( 1) ;
ptP11 = m_mVert.at( nId).at( 2) ;
@@ -3403,7 +3418,7 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR
for ( Point3d ptInt : inA.vpt) {
plInLoop.AddUPoint( k, ptInt) ;
if ( bForTriangulation) {
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptInt.x / SBZ_TREG_COEFF, ptInt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
Point3d pt3d ; m_pSrfBz->GetPoint( ptInt.x / SBZ_TREG_COEFF, ptInt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plInLoop3d.AddUPoint( k, pt3d) ;
}
++ k ;
@@ -3628,7 +3643,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
if ( bForTriangulation) {
Point3d pt3d ;
m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
}
++ c ;
@@ -3676,7 +3691,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
if ( nVert != -1)
pt3d = m_mVert.at(nId)[nVert] ;
else
m_pSrfBz->GetPointD1D2( ptVert.x, ptVert.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( ptVert.x, ptVert.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
}
++ c ;
@@ -3704,7 +3719,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
if( bForTriangulation){
Point3d pt3d ;
if( ! bVert)
m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
else
pt3d = vEdgeVertex3d[1][0] ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
@@ -3729,7 +3744,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
if( bForTriangulation) {
Point3d pt3d ;
if( ! bVert)
m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
else
pt3d = vEdgeVertex3d[2][0] ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
@@ -3754,7 +3769,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
if( bForTriangulation){
Point3d pt3d ;
if( ! bVert)
m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
else
pt3d = vEdgeVertex3d[3][0] ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
@@ -3779,7 +3794,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
if( bForTriangulation) {
Point3d pt3d ;
if( ! bVert)
m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
else
pt3d = vEdgeVertex3d[0][0] ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
@@ -3792,7 +3807,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
else {
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
if( bForTriangulation) {
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
Point3d pt3d ; m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
}
++ c ;
@@ -3802,7 +3817,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
else {
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
if( bForTriangulation) {
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
Point3d pt3d ; m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
}
++ c ;
@@ -4302,7 +4317,7 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[0][c]).GetTopLeft())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
@@ -4317,7 +4332,7 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[1][c]).GetBottomLeft())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
@@ -4332,7 +4347,7 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomRight())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
@@ -4347,7 +4362,7 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[3][c]).GetTopRight())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
@@ -4368,13 +4383,13 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
PolyLine pl3D ;
int nInd = abs( vId[0]) - 1 ;
Point3d pt2D = m_vCEdge2D[i].first[nInd].first ;
Point3d pt3D ; m_pSrfBz->GetPointD1D2( pt2D.x / SBZ_TREG_COEFF, pt2D.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
Point3d pt3D ; m_pSrfBz->GetPoint( pt2D.x / SBZ_TREG_COEFF, pt2D.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
pl3D.AddUPoint( 0, pt3D) ;
int nCount = 1 ;
for ( int j = 1 ; j < int( vId.size()) ; ++j) {
nInd = abs( vId[j]) - 1 ;
pt2D = m_vCEdge2D[i].first[nInd].second ;
m_pSrfBz->GetPointD1D2( pt2D.x / SBZ_TREG_COEFF, pt2D.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
m_pSrfBz->GetPoint( pt2D.x / SBZ_TREG_COEFF, pt2D.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
if ( pl3D.AddUPoint( nCount, pt3D))
++ nCount ;
}