From 98fe4b7ba178ae6e6cb19b63a451002ecdae94e7 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 12 Aug 2020 08:27:46 +0000 Subject: [PATCH] EgtGeomKernel 2.2h2 : - le superfici di Bezier sono state estese per essere multipatch. --- CurveComposite.cpp | 47 ++++ CurveComposite.h | 2 + EgtGeomKernel.rc | Bin 11710 -> 11710 bytes EgtGeomKernel.vcxproj | 2 + SurfBezier.cpp | 491 +++++++++++++++++++++++++++--------------- SurfBezier.h | 36 ++-- 6 files changed, 392 insertions(+), 186 deletions(-) diff --git a/CurveComposite.cpp b/CurveComposite.cpp index f044ea9..90bdf03 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -1096,6 +1096,53 @@ CurveComposite::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtD return m_CrvSmplS[nC]->GetPointD1D2( dUc, ICurve::FROM_MINUS, ptPos, pvtDer1, pvtDer2) ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::IsAPoint( void) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // ciclo di verifica + for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + if ( (*Iter)->GetType() != CRV_BEZIER || + ! GetBasicCurveBezier(*Iter)->IsAPoint()) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::GetApproxLength( double& dLen) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // ciclo di calcolo + dLen = 0 ; + for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + double dLenCrvSmpl ; + if ( (*Iter)->GetType() == CRV_BEZIER) { + if ( GetBasicCurveBezier(*Iter)->GetApproxLength( dLenCrvSmpl)) + dLen += dLenCrvSmpl ; + else + return false ; + } + else { + if ( (*Iter)->GetLength( dLenCrvSmpl)) + dLen += dLenCrvSmpl ; + else + return false ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool CurveComposite::GetLength( double& dLen) const diff --git a/CurveComposite.h b/CurveComposite.h index 73d9132..4cb240c 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -152,6 +152,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) override ; bool MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd = true, bool bNeedSameProp = false) override ; bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ; + bool IsAPoint( void) const override ; bool IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const override ; bool SetCurveTempProp( int nCrv, int nProp) override ; bool GetCurveTempProp( int nCrv, int& nProp) const override ; @@ -171,6 +172,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW LOG_ERROR( GetEGkLogger(), "CurveComposite : copy error") return *this ; } bool RelocateFrom( CurveComposite& ccSrc) ; + bool GetApproxLength( double& dLen) const ; private : bool CopyFrom( const CurveComposite& ccSrc) ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index cf92b40a870443ec88cd4bca5c0281b4a74407a5..f98b638a577e854b3a6297fc51ac9d3a2ef149f3 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&P_&A-_cnHh~HD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-Vf-5U delta 94 zcmdlNy)SyhFE&QQ&A-_cnHdcyD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-U|t&X diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 159da36..69fcd7e 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -38,6 +38,7 @@ Unicode false v142 + false DynamicLibrary @@ -146,6 +147,7 @@ copy $(TargetPath) \EgtProg\DllD32 CompileAsCpp false true + ProgramDatabase Windows diff --git a/SurfBezier.cpp b/SurfBezier.cpp index a81f98c..93df313 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- -// File : SurfBezier.cpp Data : 22.03.20 Versione : 2.2c3 +// File : SurfBezier.cpp Data : 11.08.20 Versione : 2.2h2 // Contenuto : Implementazione della classe Superfici Bezier. // // // // Modifiche : 22.03.20 DS Creazione modulo. -// +// 11.08.20 DS Trasformata in MultiPatch. // //---------------------------------------------------------------------------- @@ -33,7 +33,7 @@ GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ; //---------------------------------------------------------------------------- SurfBezier::SurfBezier(void) - : m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_bRat( false), m_bTrimmed( false), m_nTempProp( 0) + : m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_nSpanU(), m_nSpanV(), m_bRat( false), m_bTrimmed( false), m_nTempProp( 0) { } @@ -46,15 +46,17 @@ SurfBezier::~SurfBezier( void) //---------------------------------------------------------------------------- bool -SurfBezier::Init( int nDegU, int nDegV, bool bIsRational) +SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational) { // verifico validità grado - if ( nDegU < 1 || nDegU > MAXDEG || nDegV < 1 || nDegV > MAXDEG) + if ( nDegU < 1 || nDegU > MAXDEG || nDegV < 1 || nDegV > MAXDEG || nSpanU < 1 || nSpanV < 1) return false ; // imposto gradi e flag di razionale m_nDegU = nDegU ; m_nDegV = nDegV ; + m_nSpanU = nSpanU ; + m_nSpanV = nSpanV ; m_bRat = bIsRational ; m_bTrimmed = false ; @@ -120,7 +122,7 @@ SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) //---------------------------------------------------------------------------- bool -SurfBezier::GetInfo( int& nDegU, int& nDegV, bool& bIsRat, bool& bTrimmed) const +SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const { // verifico validità superficie if ( m_nStatus != OK) @@ -128,6 +130,8 @@ SurfBezier::GetInfo( int& nDegU, int& nDegV, bool& bIsRat, bool& bTrimmed) const // restituisco gradi e flag di razionale nDegU = m_nDegU ; nDegV = m_nDegV ; + nSpanU = m_nSpanU ; + nSpanV = m_nSpanV ; bIsRat = m_bRat ; bTrimmed = m_bTrimmed ; return true ; @@ -200,12 +204,12 @@ SurfBezier::GetArea( double& dArea) const bool SurfBezier::GetCentroid( Point3d& ptCen) const { - // controllo parametro di ritorno + // controllo parametro di ritorno if ( &ptCen == nullptr) return false ; - // inizio con centro nell'origine + // inizio con centro nell'origine ptCen = ORIG ; - // calcolo il baricentro + // calcolo il baricentro if ( ! GetAuxSurf()) return false ; return m_pSTM->GetCentroid( ptCen) ; @@ -213,23 +217,48 @@ SurfBezier::GetCentroid( Point3d& ptCen) const //---------------------------------------------------------------------------- bool -SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, +SurfBezier::GetPointD1D2( double dU, double dV, Side nUs, Side nVs, + Point3d& ptPos, Vector3d* pvtDerU, Vector3d* pvtDerV, Vector3d* pvtDerUU, Vector3d* pvtDerVV, Vector3d* pvtDerUV) const { // la curva deve essere validata if ( m_nStatus != OK) return false ; - // i parametri U e V devono essere compresi tra 0 e 1 - dU = Clamp( dU, 0., 1.) ; - dV = Clamp( dV, 0., 1.) ; + // 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 DBLVECTOR vBernU( m_nDegU + 1) ; - GetAllBernstein( dU, m_nDegU - 2, vBernU) ; + GetAllBernstein( dLocU, m_nDegU - 2, vBernU) ; //// se richiesto, calcolo della derivata seconda // if ( pvtDer2 != nullptr && pvtDer1 != nullptr) { @@ -241,31 +270,31 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, // } // aumento il grado - IncreaseAllBernsteinOneDegree( dU, m_nDegU - 1, vBernU) ; + IncreaseAllBernsteinOneDegree( dLocU, m_nDegU - 1, vBernU) ; // se richiesto, calcolo dei vettori intermedi per la derivata prima rispetto ad U VCT3DVECTOR vtTemp1( m_nDegV + 1, V_NULL) ; if ( pvtDerU != nullptr) { for ( int j = 0 ; j <= m_nDegV ; ++ j) { for ( int i = 0 ; i <= m_nDegU - 1 ; ++ i) - vtTemp1[j] += vBernU[i] * ( m_vPtCtrl[GetInd( i+1, j)] - m_vPtCtrl[GetInd( i, j)]) ; + vtTemp1[j] += vBernU[i] * ( m_vPtCtrl[GetInd( nOffsU + i + 1, nOffsV + j)] - m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)]) ; vtTemp1[j] *= m_nDegU ; } } // aumento il grado - IncreaseAllBernsteinOneDegree( dU, m_nDegU, vBernU) ; + IncreaseAllBernsteinOneDegree( dLocU, m_nDegU, vBernU) ; // calcolo dei punti intermedi PNTVECTOR ptTemp( m_nDegV + 1, ORIG) ; for ( int j = 0 ; j <= m_nDegV ; ++ j) { for ( int i = 0 ; i <= m_nDegU ; ++ i) - ptTemp[j] += vBernU[i] * m_vPtCtrl[GetInd( i, j)] ; + ptTemp[j] += vBernU[i] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ; } // calcolo dei polinomi di Bernstein per V di grado opportuno DBLVECTOR vBernV( m_nDegV + 1) ; - GetAllBernstein( dV, m_nDegV - 1, vBernV) ; + GetAllBernstein( dLocV, m_nDegV - 1, vBernV) ; // se richiesto, calcolo della derivata prima rispetto a V if ( pvtDerV != nullptr) { @@ -276,7 +305,7 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, } // aumento il grado - IncreaseAllBernsteinOneDegree( dV, m_nDegV, vBernV) ; + IncreaseAllBernsteinOneDegree( dLocV, m_nDegV, vBernV) ; // calcolo del punto ptPos = ORIG ; @@ -295,13 +324,18 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, else { // porto i punti in forma omogenea moltiplicandoli per i pesi - PNTVECTOR vPtWCtrl( GetDim()) ; - for ( int i = 0 ; i < GetDim() ; ++ i) - vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ; + PNTVECTOR vPtWCtrl( GetLocDim()) ; + DBLVECTOR vWeCtrl( GetLocDim()) ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + vPtWCtrl[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + vWeCtrl[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + } + } // calcolo dei polinomi di Bernstein di grado opportuno DBLVECTOR vBernU( m_nDegU + 1) ; - GetAllBernstein( dU, m_nDegU - 2, vBernU) ; + GetAllBernstein( dLocU, m_nDegU - 2, vBernU) ; //// se richiesto, calcolo della derivata seconda // double dW2 = 0 ; @@ -316,7 +350,7 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, // } // aumento il grado - IncreaseAllBernsteinOneDegree( dU, m_nDegU - 1, vBernU) ; + IncreaseAllBernsteinOneDegree( dLocU, m_nDegU - 1, vBernU) ; // se richiesto, calcolo dei vettori intermedi per la derivata prima rispetto ad U VCT3DVECTOR vtTemp1( m_nDegV + 1, V_NULL) ; @@ -324,8 +358,8 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, if ( pvtDerU != nullptr) { for ( int j = 0 ; j <= m_nDegV ; ++ j) { for ( int i = 0 ; i <= m_nDegU - 1 ; ++ i) { - vtTemp1[j] += vBernU[i] * ( vPtWCtrl[GetInd( i+1, j)] - vPtWCtrl[GetInd( i, j)]) ; - dTemp1[j] += vBernU[i] * ( m_vWeCtrl[GetInd( i+1, j)] - m_vWeCtrl[GetInd( i, j)]) ; + vtTemp1[j] += vBernU[i] * ( vPtWCtrl[GetLocInd( i + 1, j)] - vPtWCtrl[GetLocInd( i, j)]) ; + dTemp1[j] += vBernU[i] * ( vWeCtrl[GetLocInd( i + 1, j)] - vWeCtrl[GetLocInd( i, j)]) ; } vtTemp1[j] *= m_nDegU ; dTemp1[j] *= m_nDegU ; @@ -333,21 +367,21 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, } // aumento il grado - IncreaseAllBernsteinOneDegree( dU, m_nDegU, vBernU) ; + IncreaseAllBernsteinOneDegree( dLocU, m_nDegU, vBernU) ; // calcolo dei punti e pesi intermedi PNTVECTOR ptTempW( m_nDegV + 1, ORIG) ; DBLVECTOR dTempW( m_nDegV + 1, 0) ; for ( int j = 0 ; j <= m_nDegV ; ++ j) { for ( int i = 0 ; i <= m_nDegU ; ++ i) { - ptTempW[j] += vBernU[i] * vPtWCtrl[GetInd( i, j)] ; - dTempW[j] += vBernU[i] * m_vWeCtrl[GetInd( i, j)] ; + ptTempW[j] += vBernU[i] * vPtWCtrl[GetLocInd( i, j)] ; + dTempW[j] += vBernU[i] * vWeCtrl[GetLocInd( i, j)] ; } } // calcolo dei polinomi di Bernstein per V di grado opportuno DBLVECTOR vBernV( m_nDegV + 1) ; - GetAllBernstein( dV, m_nDegV - 1, vBernV) ; + GetAllBernstein( dLocV, m_nDegV - 1, vBernV) ; // se richiesto, calcolo della derivata prima rispetto a V double dW1v = 0 ; @@ -362,7 +396,7 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, } // aumento il grado - IncreaseAllBernsteinOneDegree( dV, m_nDegV, vBernV) ; + IncreaseAllBernsteinOneDegree( dLocV, m_nDegV, vBernV) ; // calcolo del punto double dW = 0 ; @@ -407,16 +441,17 @@ SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, //---------------------------------------------------------------------------- bool -SurfBezier::GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN, +SurfBezier::GetPointNrmD1D2( double dU, double dV, Side nUs, Side nVs, + Point3d& ptPos, Vector3d& vtN, Vector3d* pvtDerU, Vector3d* pvtDerV, Vector3d* pvtDerUU, Vector3d* pvtDerVV, Vector3d* pvtDerUV) const { - // la curva deve essere validata + // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // i parametri U e V devono essere compresi tra 0 e 1 - dU = Clamp( dU, 0., 1.) ; - dV = Clamp( dV, 0., 1.) ; + // 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)) ; // eseguo calcolo del punto con le derivate prime Vector3d vtDerU ; @@ -425,7 +460,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN Vector3d vtDerV ; if ( pvtDerV == nullptr) pvtDerV = &vtDerV ; - GetPointD1D2( dU, dV, ptPos, pvtDerU, pvtDerV) ; + GetPointD1D2( dU, dV, nUs, nVs, ptPos, pvtDerU, pvtDerV) ; // calcolo la normale e la verifico vtN = *pvtDerU ^ *pvtDerV ; @@ -438,7 +473,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN double dUm = dU + 1000 * EPS_PARAM * dCoeff ; Point3d ptTmp ; Vector3d vtTmpU, vtTmpV ; - GetPointD1D2( dUm, dV, ptTmp, &vtTmpU, &vtTmpV) ; + GetPointD1D2( dUm, dV, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ; vtN = ( *pvtDerV ^ vtTmpV) * dCoeff ; if ( vtN.Normalize()) return true ; @@ -448,7 +483,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN double dVm = dV + 1000 * EPS_PARAM * dCoeff ; Point3d ptTmp ; Vector3d vtTmpU, vtTmpV ; - GetPointD1D2( dU, dVm, ptTmp, &vtTmpU, &vtTmpV) ; + GetPointD1D2( dU, dVm, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ; vtN = ( vtTmpU ^ *pvtDerU) * dCoeff ; if ( vtN.Normalize()) return true ; @@ -466,7 +501,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN else dVm = dV - 100 * EPS_PARAM ; Point3d ptTmp ; - GetPointD1D2( dUm, dVm, ptTmp, pvtDerU, pvtDerV) ; + GetPointD1D2( dUm, dVm, nUs, nVs, ptTmp, pvtDerU, pvtDerV) ; vtN = *pvtDerU ^ *pvtDerV ; return vtN.Normalize() ; } @@ -503,7 +538,7 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc) { if ( &sbSrc == this) return true ; - if ( ! Init( sbSrc.m_nDegU, sbSrc.m_nDegV, sbSrc.m_bRat)) + if ( ! Init( sbSrc.m_nDegU, sbSrc.m_nDegV, sbSrc.m_nSpanU, sbSrc.m_nSpanV, sbSrc.m_bRat)) return false ; m_nStatus = sbSrc.m_nStatus ; m_vPtCtrl = sbSrc.m_vPtCtrl ; @@ -540,11 +575,13 @@ SurfBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const GetArea( dArea) ; sOut += "Area=" + ToString( GetAreaInUiUnits( dArea, bMM),1) + szNewLine ; // parametri : flag razionale - sOut += ( m_bRat ? "Rat " : "Int ") ; + sOut += ( m_bRat ? "Rat" : "Int") ; // flag trimmata - sOut += ( m_bTrimmed ? "Trim " : "Full ") ; + sOut += ( m_bTrimmed ? " Trim " : " Full") ; // gradi in U e V - sOut += "DegU=" + ToString( m_nDegU) + " DegV=" + ToString( m_nDegV) + szNewLine ; + sOut += " DegU=" + ToString( m_nDegU) + " DegV=" + ToString( m_nDegV) ; + // pezze in U e V + sOut += " SpanU=" + ToString( m_nSpanU) + " SpanV=" + ToString( m_nSpanV) + szNewLine ; // ciclo sui punti di controllo ( con pesi se razionale) for ( int i = 0 ; i < GetDim() ; ++ i) { sOut += "PC(" + ToString( GetInUiUnits( m_vPtCtrl[i], bMM), 3) ; @@ -575,7 +612,11 @@ SurfBezier::Save( NgeWriter& ngeOut) const return false ; // gradi if ( ! ngeOut.WriteInt( m_nDegU, ",") || - ! ngeOut.WriteInt( m_nDegV, ";", true)) + ! ngeOut.WriteInt( m_nDegV, ";", false)) + return false ; + // pezze + if ( ! ngeOut.WriteInt( m_nSpanU, ",") || + ! ngeOut.WriteInt( m_nSpanV, ";", true)) return false ; // ciclo sui punti di controllo ( con pesi se razionale) for ( int i = 0 ; i < GetDim() ; ++ i) { @@ -611,10 +652,15 @@ SurfBezier::Load( NgeReader& ngeIn) // recupero i gradi int nDegU, nDegV ; if ( ! ngeIn.ReadInt( nDegU, ",") || - ! ngeIn.ReadInt( nDegV, ";", true)) + ! ngeIn.ReadInt( nDegV, ";")) + return false ; + // recupero le pezze + int nSpanU, nSpanV ; + if ( ! ngeIn.ReadInt( nSpanU, ",") || + ! ngeIn.ReadInt( nSpanV, ";", true)) return false ; // inizializzo la superficie di Bezier - if ( ! Init( nDegU, nDegV, bIsRat)) + if ( ! Init( nDegU, nDegV, nSpanU, nSpanV, bIsRat)) return false ; // se integrale if ( ! bIsRat) { @@ -940,125 +986,188 @@ SurfBezier::Invert( void) //---------------------------------------------------------------------------- int -SurfBezier::GetSteps( int nDeg, double dLen, int nQuality) const +SurfBezier::GetSteps( int nDeg, int nSpan, double dLen, int nQuality) const { const double dCoeff[] = { 0, 1, 2, 2.4, 2.8, 3, 3, 3, 3, 3, 3, 3} ; nDeg = Clamp( nDeg, 0, MAXDEG) ; + nSpan = max( nSpan, 1) ; nQuality = Clamp( nQuality, 1, 3) ; - double dMult = sqrt( max( dLen, 10.)) ; - return int( nQuality * dMult * dCoeff[nDeg]) ; + double dMult = sqrt( max( dLen / nSpan, 10.)) ; + return nSpan * int( nQuality * dMult * dCoeff[nDeg]) ; } //---------------------------------------------------------------------------- -CurveBezier* +CurveComposite* SurfBezier::GetCurveOnU( double dV) const { // controlli - if ( dV < - EPS_PARAM || dV > 1 + EPS_PARAM) + if ( dV < - EPS_PARAM || dV > m_nSpanV + EPS_PARAM) return false ; - dV = Clamp( dV, 0., 1.) ; + dV = Clamp( dV, 0., double( m_nSpanV)) ; + + // determino l'intervallo di span in V e riduco i parametri in essi + int nBsV = min( int( dV), m_nSpanV - 1) ; + double dLocV = dV - nBsV ; + int nOffsV = nBsV * m_nDegV ; // se forma polinomiale (o integrale) if ( ! m_bRat) { - // preparazione della curva di Bezier - PtrOwner pCbz( CreateBasicCurveBezier()) ; - if ( IsNull( pCbz) || ! pCbz->Init( m_nDegU, false)) - return nullptr ; - // calcolo dei polinomi di Bernstein per V di grado opportuno - DBLVECTOR vBernV( m_nDegV + 1) ; - GetAllBernstein( dV, m_nDegV, vBernV) ; - // calcolo dei punti di controllo della curva - for ( int i = 0 ; i <= m_nDegU ; ++ i) { - Point3d ptP = ORIG ; - for ( int j = 0 ; j <= m_nDegV ; ++ j) - ptP += vBernV[j] * m_vPtCtrl[GetInd( i, j)] ; - pCbz->SetControlPoint( i, ptP) ; + // preparazione della curva composita + PtrOwner pCrvCo( CreateBasicCurveComposite()) ; + // ciclo sugli intervalli + for ( int k = 0 ; k < m_nSpanU ; ++ k) { + // preparazione della curva di Bezier + PtrOwner pCbz( CreateBasicCurveBezier()) ; + if ( IsNull( pCbz) || ! pCbz->Init( m_nDegU, false)) + return nullptr ; + // calcolo dei polinomi di Bernstein per V di grado opportuno + DBLVECTOR vBernV( m_nDegV + 1) ; + GetAllBernstein( dLocV, m_nDegV, vBernV) ; + // calcolo offset in U + int nOffsU = k * m_nDegU ; + // calcolo dei punti di controllo della curva + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + Point3d ptP = ORIG ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) + ptP += vBernV[j] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + pCbz->SetControlPoint( i, ptP) ; + } + // inserisco la curva della pezza in quella complessiva + if ( ! IsNull( pCbz)) + pCrvCo->AddCurve( Release( pCbz)) ; } - return Release( pCbz) ; + return Release( pCrvCo) ; } // altrimenti forma razionale else { - // preparazione della curva di Bezier - PtrOwner pCbz( CreateBasicCurveBezier()) ; - if ( IsNull( pCbz) || ! pCbz->Init( m_nDegU, true)) - return nullptr ; - // calcolo dei polinomi di Bernstein per V di grado opportuno - DBLVECTOR vBernV( m_nDegV + 1) ; - GetAllBernstein( dV, m_nDegV, vBernV) ; - // calcolo dei punti di controllo della curva - PNTVECTOR vPtWCtrl( GetDim()) ; - for ( int i = 0 ; i < GetDim() ; ++ i) - vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ; - for ( int i = 0 ; i <= m_nDegU ; ++ i) { - Point3d ptP = ORIG ; - double dW = 0 ; + // preparazione della curva composita + PtrOwner pCrvCo( CreateBasicCurveComposite()) ; + // ciclo sugli intervalli + for ( int k = 0 ; k < m_nSpanU ; ++ k) { + // preparazione della curva di Bezier + PtrOwner pCbz( CreateBasicCurveBezier()) ; + if ( IsNull( pCbz) || ! pCbz->Init( m_nDegU, true)) + return nullptr ; + // calcolo dei polinomi di Bernstein per V di grado opportuno + DBLVECTOR vBernV( m_nDegV + 1) ; + GetAllBernstein( dLocV, m_nDegV, vBernV) ; + // calcolo offset in U + int nOffsU = k * m_nDegU ; + // porto i punti in forma omogenea moltiplicandoli per i pesi + PNTVECTOR vPtWCtrl( GetLocDim()) ; + DBLVECTOR vWeCtrl( GetLocDim()) ; for ( int j = 0 ; j <= m_nDegV ; ++ j) { - ptP += vBernV[j] * vPtWCtrl[GetInd( i, j)] ; - dW += vBernV[j] * m_vWeCtrl[GetInd( i, j)] ; + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + vPtWCtrl[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + vWeCtrl[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + } } - double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; - pCbz->SetControlPoint( i, ptP * dInvW, dW) ; + // calcolo dei punti di controllo della curva + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + Point3d ptP = ORIG ; + double dW = 0 ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + ptP += vBernV[j] * vPtWCtrl[GetLocInd( i, j)] ; + dW += vBernV[j] * vWeCtrl[GetLocInd( i, j)] ; + } + double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; + pCbz->SetControlPoint( i, ptP * dInvW, dW) ; + } + // inserisco la curva della pezza in quella complessiva + if ( ! IsNull( pCbz)) + pCrvCo->AddCurve( Release( pCbz)) ; } - return Release( pCbz) ; + return Release( pCrvCo) ; } } //---------------------------------------------------------------------------- -CurveBezier* +CurveComposite* SurfBezier::GetCurveOnV( double dU) const { // controlli - if ( dU < - EPS_PARAM || dU > 1 + EPS_PARAM) + if ( dU < - EPS_PARAM || dU > m_nSpanU + EPS_PARAM) return false ; - dU = Clamp( dU, 0., 1.) ; + dU = Clamp( dU, 0., double( m_nSpanU)) ; + + // determino l'intervallo di span in U e riduco i parametri in essi + int nBsU = min( int( dU), m_nSpanU - 1) ; + double dLocU = dU - nBsU ; + int nOffsU = nBsU * m_nDegU ; // se forma polinomiale (o integrale) if ( ! m_bRat) { - // preparazione della curva di Bezier - PtrOwner pCbz( CreateBasicCurveBezier()) ; - if ( IsNull( pCbz) || ! pCbz->Init( m_nDegV, false)) - return nullptr ; - // calcolo dei polinomi di Bernstein per U di grado opportuno - DBLVECTOR vBernU( m_nDegU + 1) ; - GetAllBernstein( dU, m_nDegU, vBernU) ; - // calcolo dei punti di controllo della curva - for ( int j = 0 ; j <= m_nDegV ; ++ j) { - Point3d ptP = ORIG ; - for ( int i = 0 ; i <= m_nDegU ; ++ i) - ptP += vBernU[i] * m_vPtCtrl[GetInd( i, j)] ; - pCbz->SetControlPoint( j, ptP) ; + // preparazione della curva composita + PtrOwner pCrvCo( CreateBasicCurveComposite()) ; + // ciclo sugli intervalli + for ( int k = 0 ; k < m_nSpanV ; ++ k) { + // preparazione della curva di Bezier + PtrOwner pCbz( CreateBasicCurveBezier()) ; + if ( IsNull( pCbz) || ! pCbz->Init( m_nDegV, false)) + return nullptr ; + // calcolo dei polinomi di Bernstein per U di grado opportuno + DBLVECTOR vBernU( m_nDegU + 1) ; + GetAllBernstein( dLocU, m_nDegU, vBernU) ; + // calcolo offset in V + int nOffsV = k * m_nDegV ; + // calcolo dei punti di controllo della curva + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + Point3d ptP = ORIG ; + for ( int i = 0 ; i <= m_nDegU ; ++ i) + ptP += vBernU[i] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + pCbz->SetControlPoint( j, ptP) ; + } + // inserisco la curva della pezza in quella complessiva + if ( ! IsNull( pCbz)) + pCrvCo->AddCurve( Release( pCbz)) ; } - return Release( pCbz) ; + return Release( pCrvCo) ; } // altrimenti forma razionale else { - // preparazione della curva di Bezier - PtrOwner pCbz( CreateBasicCurveBezier()) ; - if ( IsNull( pCbz) || ! pCbz->Init( m_nDegV, true)) - return nullptr ; - // calcolo dei polinomi di Bernstein per U di grado opportuno - DBLVECTOR vBernU( m_nDegU + 1) ; - GetAllBernstein( dU, m_nDegU, vBernU) ; - // calcolo dei punti di controllo della curva - PNTVECTOR vPtWCtrl( GetDim()) ; - for ( int i = 0 ; i < GetDim() ; ++ i) - vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ; - for ( int j = 0 ; j <= m_nDegV ; ++ j) { - Point3d ptP = ORIG ; - double dW = 0 ; - for ( int i = 0 ; i <= m_nDegU ; ++ i) { - ptP += vBernU[i] * vPtWCtrl[GetInd( i, j)] ; - dW += vBernU[i] * m_vWeCtrl[GetInd( i, j)] ; + // preparazione della curva composita + PtrOwner pCrvCo( CreateBasicCurveComposite()) ; + // ciclo sugli intervalli + for ( int k = 0 ; k < m_nSpanV ; ++ k) { + // preparazione della curva di Bezier + PtrOwner pCbz( CreateBasicCurveBezier()) ; + if ( IsNull( pCbz) || ! pCbz->Init( m_nDegV, true)) + return nullptr ; + // calcolo dei polinomi di Bernstein per U di grado opportuno + DBLVECTOR vBernU( m_nDegU + 1) ; + GetAllBernstein( dLocU, m_nDegU, vBernU) ; + // calcolo offset in V + int nOffsV = k * m_nDegV ; + // porto i punti in forma omogenea moltiplicandoli per i pesi + PNTVECTOR vPtWCtrl( GetLocDim()) ; + DBLVECTOR vWeCtrl( GetLocDim()) ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + vPtWCtrl[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] * m_vPtCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + vWeCtrl[GetLocInd( i, j)] = m_vWeCtrl[GetInd( nOffsU + i, nOffsV + j)] ; + } } - double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; - pCbz->SetControlPoint( j, ptP * dInvW, dW) ; + // calcolo dei punti di controllo della curva + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + Point3d ptP = ORIG ; + double dW = 0 ; + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + ptP += vBernU[i] * vPtWCtrl[GetLocInd( i, j)] ; + dW += vBernU[i] * vWeCtrl[GetLocInd( i, j)] ; + } + double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; + pCbz->SetControlPoint( j, ptP * dInvW, dW) ; + } + // inserisco la curva della pezza in quella complessiva + if ( ! IsNull( pCbz)) + pCrvCo->AddCurve( Release( pCbz)) ; } - return Release( pCbz) ; + return Release( pCrvCo) ; } } //---------------------------------------------------------------------------- -ICurve* +CurveComposite* SurfBezier::GetLoop( int nLoop) const { // Se superficie completa, basta concatenare le 4 isoparametriche di bordo @@ -1068,25 +1177,25 @@ SurfBezier::GetLoop( int nLoop) const return nullptr ; // Loop PtrOwner pLoop( CreateBasicCurveComposite()) ; - // prima curva U=0 - PtrOwner pCbzU0( GetCurveOnU( 0)) ; - if ( ! IsNull( pCbzU0) && ! pCbzU0->IsAPoint()) - pLoop->AddCurve( Release( pCbzU0)) ; - // seconda curva V=1 - PtrOwner pCbzV1( GetCurveOnV( 1)) ; - if ( ! IsNull( pCbzV1) && ! pCbzV1->IsAPoint()) - pLoop->AddCurve( Release( pCbzV1)) ; - // terza curva U=1 invertita - PtrOwner pCbzU1( GetCurveOnU( 1)) ; - if ( ! IsNull( pCbzU1) && ! pCbzU1->IsAPoint()) { - pCbzU1->Invert() ; - pLoop->AddCurve( Release( pCbzU1)) ; + // prima curva isoparametrica in U con V=0 + PtrOwner pCrvCoU0( GetCurveOnU( 0)) ; + if ( ! IsNull( pCrvCoU0) && ! pCrvCoU0->IsAPoint()) + pLoop->AddCurve( Release( pCrvCoU0)) ; + // seconda curva isoparametrica in V con U=m_nSpanU + PtrOwner pCrvCoV1( GetCurveOnV( m_nSpanU)) ; + if ( ! IsNull( pCrvCoV1) && ! pCrvCoV1->IsAPoint()) + pLoop->AddCurve( Release( pCrvCoV1)) ; + // terza curva isoparametrica in U con V=m_nSpanV invertita + PtrOwner pCrvCoU1( GetCurveOnU( m_nSpanV)) ; + if ( ! IsNull( pCrvCoU1) && ! pCrvCoU1->IsAPoint()) { + pCrvCoU1->Invert() ; + pLoop->AddCurve( Release( pCrvCoU1)) ; } - // quarta curva V=0 invertita - PtrOwner pCbzV0( GetCurveOnV( 0)) ; - if ( ! IsNull( pCbzV0) && ! pCbzV0->IsAPoint()) { - pCbzV0->Invert() ; - pLoop->AddCurve( Release( pCbzV0)) ; + // quarta curva isoparametrica in V con U=0 invertita + PtrOwner pCrvCoV0( GetCurveOnV( 0)) ; + if ( ! IsNull( pCrvCoV0) && ! pCrvCoV0->IsAPoint()) { + pCrvCoV0->Invert() ; + pLoop->AddCurve( Release( pCrvCoV0)) ; } // se loop chiuso lo restituisco, altrimenti errore return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ; @@ -1100,38 +1209,72 @@ SurfBezier::GetLoop( int nLoop) const bool SurfBezier::GetCurveOnU( double dV, int nStep, PolyLine& plCrvU) const { + // controlli plCrvU.Clear() ; - if ( dV < - EPS_PARAM || dV > 1 + EPS_PARAM) + if ( dV < - EPS_PARAM || dV > m_nSpanV + EPS_PARAM) return false ; - dV = Clamp( dV, 0., 1.) ; - PtrOwner pCbz( GetCurveOnU( dV)) ; - if ( IsNull( pCbz)) + dV = Clamp( dV, 0., double( m_nSpanV)) ; + // recupero la curva + PtrOwner pCrvCo( GetCurveOnU( dV)) ; + if ( IsNull( pCrvCo)) return false ; - if ( nStep <= 0) { - double dLenU = 0 ; - pCbz->GetApproxLength( dLenU) ; - nStep = GetSteps( m_nDegU, dLenU, 2) ; + // ciclo sulle curve componenti (tutte curve di Bezier) + int i = 0 ; + const ICurve* pSCrv = pCrvCo->GetFirstCurve() ; + while ( pSCrv != nullptr) { + const CurveBezier* pCbz = GetBasicCurveBezier( pSCrv) ; + if ( pCbz == NULL) + return false ; + int nCurrSpanStep = nStep / m_nSpanU ; + if ( nCurrSpanStep <= 0) { + double dLenU = 0 ; + pCbz->GetApproxLength( dLenU) ; + nCurrSpanStep = GetSteps( m_nDegU, 1, dLenU, 2) ; + } + PolyLine plCurr ; + if ( ! pCbz->ApproxWithLines( nStep, plCurr)) + return false ; + plCrvU.Join( plCurr, i) ; + ++ i ; + pSCrv = pCrvCo->GetNextCurve() ; } - return pCbz->ApproxWithLines( nStep, plCrvU) ; + return true ; } //---------------------------------------------------------------------------- bool SurfBezier::GetCurveOnV( double dU, int nStep, PolyLine& plCrvV) const { + // controlli plCrvV.Clear() ; - if ( dU < - EPS_PARAM || dU > 1 + EPS_PARAM) + if ( dU < - EPS_PARAM || dU > m_nSpanU + EPS_PARAM) return false ; - dU = Clamp( dU, 0., 1.) ; - PtrOwner pCbz( GetCurveOnV( dU)) ; - if ( IsNull( pCbz)) + dU = Clamp( dU, 0., double( m_nSpanU)) ; + // recupero la curva + PtrOwner pCrvCo( GetCurveOnV( dU)) ; + if ( IsNull( pCrvCo)) return false ; - if ( nStep <= 0) { - double dLenV = 0 ; - pCbz->GetApproxLength( dLenV) ; - nStep = GetSteps( m_nDegV, dLenV, 2) ; + // ciclo sulle curve componenti (tutte curve di Bezier) + int i = 0 ; + const ICurve* pSCrv = pCrvCo->GetFirstCurve() ; + while ( pSCrv != nullptr) { + const CurveBezier* pCbz = GetBasicCurveBezier( pSCrv) ; + if ( pCbz == NULL) + return false ; + int nCurrSpanStep = nStep / m_nSpanU ; + if ( nCurrSpanStep <= 0) { + double dLenV = 0 ; + pCbz->GetApproxLength( dLenV) ; + nCurrSpanStep = GetSteps( m_nDegV, 1, dLenV, 2) ; + } + PolyLine plCurr ; + if ( ! pCbz->ApproxWithLines( nStep, plCurr)) + return false ; + plCrvV.Join( plCurr, i) ; + ++ i ; + pSCrv = pCrvCo->GetNextCurve() ; } - return pCbz->ApproxWithLines( nStep, plCrvV) ; + return true ; } //---------------------------------------------------------------------------- @@ -1139,9 +1282,9 @@ bool SurfBezier::GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const { plCtrlU.Clear() ; - if ( nIndV < 0 || nIndV > m_nDegV) + if ( nIndV < 0 || nIndV > m_nDegV * m_nSpanV) return false ; - for ( int i = 0 ; i <= m_nDegU ; ++ i) + for ( int i = 0 ; i <= m_nDegU * m_nSpanU ; ++ i) plCtrlU.AddUPoint( double( i) / m_nDegU, m_vPtCtrl[GetInd( i, nIndV)]) ; return true ; @@ -1152,9 +1295,9 @@ bool SurfBezier::GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const { plCtrlV.Clear() ; - if ( nIndU < 0 || nIndU > m_nDegU) + if ( nIndU < 0 || nIndU > m_nDegU * m_nSpanU) return false ; - for ( int j = 0 ; j <= m_nDegV ; ++ j) + for ( int j = 0 ; j <= m_nDegV * m_nSpanV ; ++ j) plCtrlV.AddUPoint( double( j) / m_nDegV, m_vPtCtrl[GetInd( nIndU, j)]) ; return true ; @@ -1164,9 +1307,9 @@ SurfBezier::GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const double SurfBezier::GetCurveOnUApproxLen( double dV) const { - PtrOwner pCbz( GetCurveOnU( dV)) ; + PtrOwner pCrvCo( GetCurveOnU( dV)) ; double dLen ; - if ( IsNull( pCbz) || ! pCbz->GetApproxLength( dLen)) + if ( IsNull( pCrvCo) || ! pCrvCo->GetApproxLength( dLen)) return 0 ; return dLen ; } @@ -1175,9 +1318,9 @@ SurfBezier::GetCurveOnUApproxLen( double dV) const double SurfBezier::GetCurveOnVApproxLen( double dU) const { - PtrOwner pCbz( GetCurveOnV( dU)) ; + PtrOwner pCrvCo( GetCurveOnV( dU)) ; double dLen ; - if ( IsNull( pCbz) || ! pCbz->GetApproxLength( dLen)) + if ( IsNull( pCrvCo) || ! pCrvCo->GetApproxLength( dLen)) return 0 ; return dLen ; } @@ -1199,13 +1342,13 @@ SurfBezier::GetAuxSurf( void) const stmSoup.Start() ; // definisco il numero degli step in U e in V double dMaxLenU = 0 ; - for ( int j = 0 ; j <= m_nDegV ; ++ j) + for ( int j = 0 ; j <= m_nDegV * m_nSpanV ; ++ j) dMaxLenU = max( dMaxLenU, GetCurveOnUApproxLen( double( j) / m_nDegV)) ; - int nStepU = GetSteps( m_nDegU, dMaxLenU, 2) ; + int nStepU = GetSteps( m_nDegU, m_nSpanU, dMaxLenU, 2) ; double dMaxLenV = 0 ; - for ( int i = 0 ; i <= m_nDegU ; ++ i) + for ( int i = 0 ; i <= m_nDegU * m_nSpanU ; ++ i) dMaxLenV = max( dMaxLenV, GetCurveOnVApproxLen( double( i) / m_nDegU)) ; - int nStepV = GetSteps( m_nDegV, dMaxLenV, 2) ; + int nStepV = GetSteps( m_nDegV, m_nSpanV, dMaxLenV, 2) ; // prima curva isoparametrica (potrebbe essere un solo punto) PolyLine PL1 ; GetCurveOnU( 0, nStepU, PL1) ; @@ -1213,7 +1356,7 @@ SurfBezier::GetAuxSurf( void) const // ciclo sulle isoparametriche for ( int i = 1 ; i <= nStepV ; ++ i) { // seconda curva isoparametrica (con tanti punti quanti la prima, oppure uno solo) - double dV = double( i) / nStepV ; + double dV = double( i) * m_nSpanV / nStepV ; PolyLine PL2 ; GetCurveOnU( dV, nStepU, PL2) ; bool bSingle2 = ( PL2.GetPointNbr() == 1) ; diff --git a/SurfBezier.h b/SurfBezier.h index a50bfb8..fa97e68 100644 --- a/SurfBezier.h +++ b/SurfBezier.h @@ -16,7 +16,7 @@ #include "ObjGraphicsMgr.h" #include "DllMain.h" #include "GeoObjRW.h" -#include "CurveBezier.h" +#include "CurveComposite.h" #include "SurfTriMesh.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkGeoCollection.h" @@ -73,14 +73,14 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW public : // ISurfBezier bool CopyFrom( const IGeoObj* pGObjSrc) override ; - bool Init( int nDegU, int nDegV, bool bIsRational) override ; + bool Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational) override ; bool SetControlPoint( int nIndU, int nIndV, const Point3d& ptCtrl) override { return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl) ; } bool SetControlPoint( int nInd, const Point3d& ptCtrl) override ; bool SetControlPoint( int nIndU, int nIndV, const Point3d& ptCtrl, double dW) override { return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl, dW) ; } bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ; - bool GetInfo( int& nDegU, int& nDegV, bool& bIsRat, bool& bTrimmed) const override ; + bool GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const override ; const Point3d& GetControlPoint( int nIndU, int nIndV, bool* pbOk) const override { return GetControlPoint( GetInd( nIndU, nIndV), pbOk) ; } const Point3d& GetControlPoint( int nInd, bool* pbOk) const override ; @@ -88,15 +88,17 @@ 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 GetPointD1D2( double dU, double dV, Point3d& ptPos, + bool GetPointD1D2( double dU, double dV, Side nUs, Side nVs, + Point3d& ptPos, Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr, Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ; - bool GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN, + bool GetPointNrmD1D2( double dU, double dV, Side nUs, Side nVs, + Point3d& ptPos, Vector3d& vtN, Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr, Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ; - CurveBezier* GetCurveOnU( double dV) const override ; - CurveBezier* GetCurveOnV( double dU) const override ; - ICurve* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni) + CurveComposite* GetCurveOnU( double dV) const override ; + CurveComposite* GetCurveOnV( double dU) const override ; + CurveComposite* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni) bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ; bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ; const ISurfTriMesh* GetAuxSurf( void) const override ; @@ -125,15 +127,23 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW bool CopyFrom( const SurfBezier& sbSrc) ; bool Validate( void) ; int GetInd( int nIndU, int nIndV) const - { return ( nIndV * ( m_nDegU + 1) + nIndU) ; } + { return ( nIndV * ( m_nDegU * m_nSpanU + 1) + nIndU) ; } int GetIndU( int nInd) const - { return ( nInd % ( m_nDegU + 1)) ; } + { return ( nInd % ( m_nDegU * m_nSpanU + 1)) ; } int GetIndV( int nInd) const - { return ( nInd / ( m_nDegU + 1)) ; } + { return ( nInd / ( m_nDegU * m_nSpanU + 1)) ; } int GetDim( void) const + { return ( m_nDegU * m_nSpanU + 1) * ( m_nDegV * m_nSpanV + 1) ; } + int GetLocInd( int nIndU, int nIndV) const + { return ( nIndV * ( m_nDegU + 1) + nIndU) ; } + int GetLocIndU( int nInd) const + { return ( nInd % ( m_nDegU + 1)) ; } + int GetLocIndV( int nInd) const + { return ( nInd / ( m_nDegU + 1)) ; } + int GetLocDim( void) const { return ( m_nDegU + 1) * ( m_nDegV + 1) ; } void ResetAuxSurf( void) const ; - int GetSteps( int nDeg, double dLen, int nQuality) const ; + int GetSteps( int nDeg, int nSpan, double dLen, int nQuality) const ; bool GetCurveOnU( double dV, int nStep, PolyLine& plCrvU) const ; bool GetCurveOnV( double dU, int nStep, PolyLine& plCrvV) const ; double GetCurveOnUApproxLen( double dV) const ; @@ -145,6 +155,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW Status m_nStatus ; // stato int m_nDegU ; // grado in U int m_nDegV ; // grado in V + int m_nSpanU ; // numero di pezze in U + int m_nSpanV ; // numero di pezze in V bool m_bRat ; // flag di razionale/polinomiale bool m_bTrimmed ; // flag per presenza regione di trim PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo