diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 23431f6..fd107be 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -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, 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 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, diff --git a/SurfBezier.h b/SurfBezier.h index 53b0e86..1df2ad0 100644 --- a/SurfBezier.h +++ b/SurfBezier.h @@ -25,6 +25,14 @@ using namespace std ; class Tree ; +struct PairHash { + std::size_t operator()(const std::pair& key) const { + std::size_t h1 = std::hash{}(key.first); + std::size_t h2 = std::hash{}(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 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, 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 ; } ; //----------------------------------------------------------------------------- diff --git a/Tree.cpp b/Tree.cpp index 5addbcf..c8dc7bf 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -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 ; }