Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2eb219c5a | |||
| e44b08d669 | |||
| 9b34154a16 | |||
| 10dd5828ce | |||
| bf2a3f0e22 | |||
| 38146c6294 | |||
| eccf683ef4 | |||
| 381a137604 | |||
| e5ed9efdd1 | |||
| 1ec38952ed |
@@ -362,6 +362,8 @@ Attribs::GetAllInfo( STRVECTOR& vsInfo) const
|
||||
{
|
||||
// riservo spazio opportuno per il vettore delle stringhe
|
||||
vsInfo.clear() ;
|
||||
if ( (int) m_slInfo.size() == 0)
|
||||
return true ;
|
||||
vsInfo.reserve( m_slInfo.size()) ;
|
||||
// recupero tutte le info tranne il nome (se presente sempre al primo posto)
|
||||
auto iIter = m_slInfo.cbegin() ;
|
||||
|
||||
+195
-9
@@ -510,14 +510,7 @@ CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg)
|
||||
bool
|
||||
NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
{
|
||||
// se periodica
|
||||
if ( cnData.bPeriodic) {
|
||||
// va trasformata in non-periodica (clamped)
|
||||
// vedere The NurbsBook di Les Piegl e Tiller
|
||||
// mancano esempi per testare
|
||||
return false ;
|
||||
}
|
||||
// se con nodi extra
|
||||
// se con nodi extra
|
||||
if ( cnData.bExtraKnotes) {
|
||||
int nKnotesNbr = int( cnData.vU.size()) ;
|
||||
if ( nKnotesNbr < 4)
|
||||
@@ -526,7 +519,176 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i)
|
||||
cnData.vU[i] = cnData.vU[i+1] ;
|
||||
cnData.vU.resize( nKnotesNbr - 2) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// se periodica
|
||||
if ( cnData.bPeriodic) {
|
||||
// va trasformata in non-periodica (clamped)
|
||||
// bisogna aumentare la molteplicità dei nodi u_p-1 e u_(m-p+1) fino ad arrivare al grado della nurbs
|
||||
// e poi scartare nodi e punti fuori dalla regione clamped ( al di fuori della regione u_p-1 -> u_(m-p+1))
|
||||
|
||||
// l'agoritmo per l'inserimento dei nodi l' A5.1 del libro delle Nurbs ( Piegl e Tiller), con qualche modifica
|
||||
// agli indici perché uso u_p-1 e u_(m-p+1), anziché u_p e u_m-p
|
||||
|
||||
// comincio ad aumentare la molteplictià del nodo u_m-p+1
|
||||
int nCP = int( cnData.vCP.size()) ;
|
||||
int nU = nCP + cnData.nDeg - 1 ;
|
||||
int nDeg = cnData.nDeg ;
|
||||
PNTVECTOR vBC ;
|
||||
vBC.resize( nDeg + 1) ;
|
||||
DBLVECTOR vBW ;
|
||||
vBW.resize( nDeg + 1) ;
|
||||
|
||||
// trovo il nodo di cui aumentare la molteplicità e ne calcolo la molteplicità
|
||||
int b = nU - nDeg - 1 +1;
|
||||
int i = b ;
|
||||
while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO)
|
||||
-- b ;
|
||||
int mult = min( i - b + 1, nDeg) ; // mi aspetto che sia 1, ma comunque sarà < nDeg
|
||||
// recupero i punti da modificare
|
||||
if ( ! cnData.bRat) {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i)
|
||||
vBC[i] = cnData.vCP[b - nDeg + 1 + i] ;
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i) {
|
||||
vBC[i] = cnData.vCP[b - nDeg + 1 + i] * cnData.vW[b - nDeg + 1 + i] ;
|
||||
vBW[i] = cnData.vW[b - nDeg + 1 + i] ;
|
||||
}
|
||||
}
|
||||
|
||||
// salvo i punti inalterati
|
||||
int r = nDeg - mult ; // numero di volte che dovrò inserire il nodo
|
||||
cnData.vCP.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vCP[r + p] = cnData.vCP[p] ;
|
||||
}
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vW[r + p] = cnData.vW[p] ;
|
||||
}
|
||||
}
|
||||
|
||||
// procedo all'inserimento
|
||||
int L = 0 ;
|
||||
double alpha ;
|
||||
double num, den ;
|
||||
if ( mult < nDeg) {
|
||||
// inserisco il nodo r volte
|
||||
for ( int j = 1 ; j <= r ; ++ j) {
|
||||
L = b - nDeg + j ;
|
||||
for ( int i = 0; i <= r - j ; ++i) {
|
||||
num = (cnData.vU[b] - cnData.vU[L + i]) ;
|
||||
den = ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
|
||||
alpha = (cnData.vU[b] - cnData.vU[L + i])/ ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
|
||||
vBC[i] = alpha * vBC[i +1 ] + ( 1 - alpha) * vBC[i] ;
|
||||
if ( cnData.bRat) {
|
||||
vBW[i] = alpha * vBW[i + 1] + ( 1 - alpha) * vBW[i] ;
|
||||
}
|
||||
}
|
||||
cnData.vCP[L + 1] = vBC[0] ;
|
||||
cnData.vCP[b + nDeg - j - mult] = vBC[r - j] ;
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW[L + 1] = vBW[0] ;
|
||||
cnData.vW[b + nDeg - j - mult] = vBW[r-j] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allungo il vettore dei nodi e sposto gli ultimi nodi
|
||||
cnData.vU.resize(nU + r) ;
|
||||
for ( int p = nU - 1 ; p > b ; --p)
|
||||
cnData.vU[p + r] = cnData.vU[p] ;
|
||||
// aggiungo i nodi nuovi
|
||||
for ( int p = 0 ; p < r ; ++p)
|
||||
cnData.vU[b + 1 + p] = cnData.vU[b] ;
|
||||
nU = nU + r ;
|
||||
nCP = nCP + r ;
|
||||
|
||||
// aumento la molteplicità del punto u_p-1
|
||||
b = nDeg -1;
|
||||
i = b ;
|
||||
while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO)
|
||||
-- b ;
|
||||
mult = min( i - b + 1, nDeg) ; // mi aspetto che sia 1, ma comunque sarà < cnData.nDeg
|
||||
// recupero i punti da modificare
|
||||
if ( ! cnData.bRat) {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i)
|
||||
vBC[i] = cnData.vCP[i] ;
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i) {
|
||||
vBC[i] = cnData.vCP[i] * cnData.vW[i] ;
|
||||
vBW[i] = cnData.vW[i] ;
|
||||
}
|
||||
}
|
||||
|
||||
r = nDeg - mult ;
|
||||
// salvo i punti inalterati
|
||||
cnData.vCP.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vCP[r + p] = cnData.vCP[p] ;
|
||||
}
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vW[r + p] = cnData.vW[p] ;
|
||||
}
|
||||
}
|
||||
|
||||
// procedo all'inserimento
|
||||
L = 0 ;
|
||||
if ( mult < nDeg) {
|
||||
// inserisco il nodo r volte
|
||||
for ( int j = 1 ; j <= r ; ++ j) {
|
||||
L = b - nDeg + j ;
|
||||
for ( int i = 0; i <= r - j ; ++i) {
|
||||
alpha = (cnData.vU[b] - cnData.vU[L + i])/ ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
|
||||
vBC[i] = alpha * vBC[i + 1] + ( 1 - alpha) * vBC[i] ;
|
||||
if ( cnData.bRat) {
|
||||
vBW[i] = alpha * vBW[i + 1] + ( 1 - alpha) * vBW[i] ;
|
||||
}
|
||||
}
|
||||
cnData.vCP[L + 1] = vBC[0] ;
|
||||
cnData.vCP[b + nDeg - j - mult] = vBC[r - j] ;
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW[L + 1] = vBW[0] ;
|
||||
cnData.vW[b + nDeg - j - mult] = vBW[r - j] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allungo il vettore dei nodi e sposto gli ultimi nodi
|
||||
cnData.vU.resize(nU + r) ;
|
||||
for ( int p = nU - 1 ; p > b ; --p)
|
||||
cnData.vU[p+r] = cnData.vU[p] ;
|
||||
// aggiungo i nodi nuovi
|
||||
for ( int p = 0 ; p < r ; ++p)
|
||||
cnData.vU[b + 1 + p] = cnData.vU[b] ;
|
||||
nU = nU + r ;
|
||||
nCP = nCP + r ;
|
||||
|
||||
// rendo la curva chiusa e non periodica eliminando i primi e gli ultimi nDeg punti e nodi
|
||||
cnData.bPeriodic = false ;
|
||||
nCP = nCP - 2 * ( nDeg - 1);
|
||||
nU = nU - 2 * ( nDeg - 1);
|
||||
PNTVECTOR vCP_clamped ;
|
||||
vCP_clamped.resize( nCP) ;
|
||||
DBLVECTOR vU_clamped ;
|
||||
vU_clamped.resize( nU) ;
|
||||
for ( int i = 0 ; i < nCP ; ++i) {
|
||||
if ( ! cnData.bRat)
|
||||
vCP_clamped[i] = cnData.vCP[i + nDeg - 1] ;
|
||||
else
|
||||
vCP_clamped[i] = cnData.vCP[i + nDeg - 1] / cnData.vW[i + nDeg - 1] ;
|
||||
}
|
||||
cnData.vCP = vCP_clamped ;
|
||||
for ( int i = 0 ; i < nU ; ++i) {
|
||||
vU_clamped[i] = cnData.vU[i + nDeg - 1] ;
|
||||
}
|
||||
cnData.vU = vU_clamped ;
|
||||
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -710,6 +872,30 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
}
|
||||
}
|
||||
|
||||
// se la curva ha grado 1, manca da aggiungere l'ultimo tratto
|
||||
if ( cnData.nDeg == 1 ) {
|
||||
// costruisco la curva di Bezier e la inserisco nella curva composita
|
||||
PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||
if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat))
|
||||
return nullptr ;
|
||||
if ( ! cnData.bRat) {
|
||||
for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
if ( ! pCrvBez->SetControlPoint( i, vBC[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
if ( ! pCrvBez->SetControlPoint( i, vBC[i] / vBW[i], vBW[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
if ( ! pCrvBez->IsAPoint()) {
|
||||
if ( ! pCrvCompo->AddCurve( Release( pCrvBez)))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
// restituisco la curva composita
|
||||
return Release( pCrvCompo) ;
|
||||
}
|
||||
|
||||
+13
-12
@@ -76,37 +76,38 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2)
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2,
|
||||
const double dU0, const double dV0,const double dU1, const double dV1,const double dU2, const double dV2)
|
||||
{
|
||||
// verifico inizializzazione
|
||||
// verifico inizializzazione
|
||||
if ( m_pSTM == nullptr)
|
||||
return false ;
|
||||
// ciclo sui tre vertici
|
||||
// ciclo sui tre vertici
|
||||
int nIdV[3] ;
|
||||
if ( ( nIdV[0] = AddVertex( ptP0)) == SVT_NULL)
|
||||
if ( ( nIdV[0] = AddVertex( ptP0, dU0, dV0)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[1] = AddVertex( ptP1)) == SVT_NULL)
|
||||
if ( ( nIdV[1] = AddVertex( ptP1, dU1, dV1)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[2] = AddVertex( ptP2)) == SVT_NULL)
|
||||
if ( ( nIdV[2] = AddVertex( ptP2, dU2, dV2)) == SVT_NULL)
|
||||
return false ;
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) {
|
||||
if ( m_pSTM->AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP)
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP, const double dU, const double dV)
|
||||
{
|
||||
// verifico se già presente
|
||||
// verifico se già presente
|
||||
int nId ;
|
||||
if ( m_VertGrid.Find( ptP, 2 * EPS_SMALL, nId))
|
||||
return nId ;
|
||||
// aggiungo il vertice
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP)) == SVT_NULL)
|
||||
// aggiungo il vertice
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP, dU, dV)) == SVT_NULL)
|
||||
return SVT_NULL ;
|
||||
m_VertGrid.InsertPoint( ptP, nId) ;
|
||||
return nId ;
|
||||
|
||||
+251
-283
@@ -2,7 +2,7 @@
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfAux.cpp Data : 09.08.23 Versione :
|
||||
// Contenuto : Implementazione di alcune funzioni di utilità per le Superfici.
|
||||
// Contenuto : Implementazione di alcune funzioni di utilit? per le Superfici.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -26,9 +26,92 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
bool
|
||||
NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
{
|
||||
// per rendere una superficie non periodica devo recuperare i punti di controllo, suddivisi in isoparametriche lungo una direzione
|
||||
// e applicare la trasformazione ad ogni isoparametrica, sostituendola poi a quella originale. ( si mantiene il numero di punti)
|
||||
if ( snData.bPeriodicU ) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vU ;
|
||||
int nKnot = (int) snData.vU.size() ;
|
||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||
double dKnot = snData.vU[k] ;
|
||||
vU.push_back( dKnot) ;
|
||||
}
|
||||
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.nDeg = snData.nDegU ;
|
||||
nuCurve.vU = vU ;
|
||||
// vettore dei punti di controllo
|
||||
PNTVECTOR vPtCtrl ;
|
||||
// vettore dei pesi
|
||||
DBLVECTOR vWeCtrl ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i ) {
|
||||
if ( bIsRational) {
|
||||
vPtCtrl.push_back( snData.mCP[i][j] / snData.mW[i][j]) ;
|
||||
vWeCtrl.push_back( snData.mW[i][j]) ;
|
||||
}
|
||||
else
|
||||
vPtCtrl.push_back( snData.mCP[i][j]) ;
|
||||
}
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||
}
|
||||
snData.vU = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicU = false ;
|
||||
}
|
||||
if ( snData.bPeriodicV ) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vV ;
|
||||
int nKnot = (int) snData.vV.size() ;
|
||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||
double dKnot = snData.vV[k] ;
|
||||
vV.push_back( dKnot) ;
|
||||
}
|
||||
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.nDeg = snData.nDegV ;
|
||||
nuCurve.vU = vV ;
|
||||
// vettore dei punti di controllo
|
||||
PNTVECTOR vPtCtrl ;
|
||||
// vettore dei pesi
|
||||
DBLVECTOR vWeCtrl ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
if ( bIsRational) {
|
||||
vPtCtrl.push_back( snData.mCP[i][j] / snData.mW[i][j]) ;
|
||||
vWeCtrl.push_back( snData.mW[i][j]) ;
|
||||
}
|
||||
else
|
||||
vPtCtrl.push_back( snData.mCP[i][j]) ;
|
||||
}
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
||||
}
|
||||
snData.vV = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicV = false ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ISurf*
|
||||
NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
NurbsToBezierSurface(const SNurbsSurfData& snData)
|
||||
{
|
||||
//INTVECTOR vInt_sub( 10) ;
|
||||
//INTMATRIX vInt( 10, vInt_sub) ;
|
||||
@@ -45,64 +128,64 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
|
||||
|
||||
// la superficie Nurbs deve essere in forma canonica
|
||||
if ( cnData.bPeriodicU || cnData.bPeriodicV || cnData.bExtraKnotes )
|
||||
if ( snData.bPeriodicU || snData.bPeriodicV || snData.bExtraKnotes )
|
||||
return nullptr ;
|
||||
// controllo sul numero dei nodi
|
||||
int nU = cnData.nCPU + cnData.nDegU - 1 ;
|
||||
int nV = cnData.nCPV + cnData.nDegV - 1 ;
|
||||
int nU = snData.nCPU + snData.nDegU - 1 ;
|
||||
int nV = snData.nCPV + snData.nDegV - 1 ;
|
||||
// controllo nodi e punti di controllo
|
||||
//if ( nU != int( cnData.vU.size()) || nV != int( cnData.vV.size()) || cnData.nCPU * cnData.nCPV != int( cnData.vCP.size()))
|
||||
if ( nU != int(cnData.vU.size()) || nV != int(cnData.vV.size())) {
|
||||
//if ( nU != int( snData.vU.size()) || nV != int( snData.vV.size()) || snData.nCPU * snData.nCPV != int( snData.vCP.size()))
|
||||
if ( nU != int(snData.vU.size()) || nV != int(snData.vV.size())) {
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
|
||||
//// numero degli intervalli
|
||||
//int nInt = nU - 2 * cnData.nDeg + 1 ;
|
||||
//int nInt = nU - 2 * snData.nDeg + 1 ;
|
||||
// verifico le condizioni agli estremi sui nodi (i primi nDeg nodi e gli ultimi nDeg nodi devono essere uguali tra loro)
|
||||
bool bOk = true ;
|
||||
// direzione U
|
||||
for ( int i = 1 ; i < cnData.nDegU ; ++ i) {
|
||||
if ( abs( cnData.vU[i] - cnData.vU[0]) >= EPS_ZERO)
|
||||
for ( int i = 1 ; i < snData.nDegU ; ++ i) {
|
||||
if ( abs( snData.vU[i] - snData.vU[0]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
for ( int i = 1 ; i < cnData.nDegU ; ++ i) {
|
||||
if ( abs( cnData.vU[nU - 1 - i] - cnData.vU[nU - 1]) >= EPS_ZERO)
|
||||
for ( int i = 1 ; i < snData.nDegU ; ++ i) {
|
||||
if ( abs( snData.vU[nU - 1 - i] - snData.vU[nU - 1]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
// direzione V
|
||||
for ( int i = 1 ; i < cnData.nDegV ; ++ i) {
|
||||
if ( abs( cnData.vV[i] - cnData.vV[0]) >= EPS_ZERO)
|
||||
for ( int i = 1 ; i < snData.nDegV ; ++ i) {
|
||||
if ( abs( snData.vV[i] - snData.vV[0]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
for ( int i = 1 ; i < cnData.nDegV ; ++ i) {
|
||||
if ( abs( cnData.vV[nV - 1 - i] - cnData.vV[nV - 1]) >= EPS_ZERO)
|
||||
for ( int i = 1 ; i < snData.nDegV ; ++ i) {
|
||||
if ( abs( snData.vV[nV - 1 - i] - snData.vV[nV - 1]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
if ( ! bOk)
|
||||
return nullptr ;
|
||||
|
||||
//// se 1 solo intervallo, la Nurbs è già una curva di Bezier
|
||||
//// se 1 solo intervallo, la Nurbs ? gi? una curva di Bezier
|
||||
//if ( nInt == 1) {
|
||||
// // creo la curva di Bezier
|
||||
// PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||
// if ( IsNull( pCrvBez))
|
||||
// return nullptr ;
|
||||
// // la inizializzo
|
||||
// if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat))
|
||||
// if ( ! pCrvBez->Init( snData.nDeg, snData.bRat))
|
||||
// return nullptr ;
|
||||
// for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
// if ( ! cnData.bRat) {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, cnData.vCP[i]))
|
||||
// for ( int i = 0 ; i <= snData.nDeg ; ++ i) {
|
||||
// if ( ! snData.bRat) {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, snData.vCP[i]))
|
||||
// return nullptr ;
|
||||
// }
|
||||
// else {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, cnData.vCP[i], cnData.vW[i]))
|
||||
// if ( ! pCrvBez->SetControlPoint( i, snData.vCP[i], snData.vW[i]))
|
||||
// return nullptr ;
|
||||
// }
|
||||
// }
|
||||
// // se non è una curva ma un punto, la invalido
|
||||
// // se non ? una curva ma un punto, la invalido
|
||||
// if ( pCrvBez->IsAPoint())
|
||||
// pCrvBez->Init( cnData.nDeg, cnData.bRat) ;
|
||||
// pCrvBez->Init( snData.nDeg, snData.bRat) ;
|
||||
// // restituisco la curva
|
||||
// return Release( pCrvBez) ;
|
||||
//}
|
||||
@@ -110,73 +193,77 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
|
||||
// algoritmo 5.7 del libro "The NURBS book"//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// creazione delle strips nella direzione U ( trasformo le curve iso con U costante in bezier)
|
||||
int a = cnData.nDegU - 1 ;
|
||||
int b = cnData.nDegU ;
|
||||
int a = snData.nDegU - 1 ;
|
||||
int b = snData.nDegU ;
|
||||
int nb = 0 ; // numero di strisce in U ( lunghezza con U costante)
|
||||
//PNTVECTOR vBC ;
|
||||
//vBC.resize( cnData.nCPV * cnData.nDegU) ;
|
||||
//for (int row = 0 ; row < cnData.nCPV ; ++row ) {
|
||||
// for ( int i = 0 ; i <= cnData.nDegU ; ++i ) {
|
||||
// vBC[nDegU*row + i] = ( cnData.vCP[nCPU*row + i]) ;
|
||||
//vBC.resize( snData.nCPV * snData.nDegU) ;
|
||||
//for (int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
// for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
// vBC[nDegU*row + i] = ( snData.vCP[nCPU*row + i]) ;
|
||||
// }
|
||||
//}
|
||||
vector<Point3d> vCPV( cnData.nCPV) ;
|
||||
vector< vector<Point3d>> mBC (cnData.nDegU + 1,vCPV ) ;
|
||||
vector< vector<Point3d>> mBC_next (cnData.nDegU - 1, vCPV) ;
|
||||
vector< vector<Point3d>> mPC_strip(cnData.nDegU + 1, vCPV) ; // matrice che verrà ingrandita e conterrà la superficie metà bezier e metà NURBS
|
||||
DBLVECTOR vV_W( cnData.nCPV) ;
|
||||
vector<DBLVECTOR> mW( cnData.nDegU + 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_next( cnData.nDegU - 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_strip( cnData.nDegU + 1, vV_W) ;
|
||||
vector<Point3d> vCPV( snData.nCPV) ;
|
||||
vector< vector<Point3d>> mBC (snData.nDegU + 1,vCPV ) ;
|
||||
vector< vector<Point3d>> mBC_next (snData.nDegU - 1, vCPV) ;
|
||||
vector< vector<Point3d>> mPC_strip(snData.nDegU + 1, vCPV) ; // matrice che verr? ingrandita e conterr? la superficie met? bezier e met? NURBS
|
||||
DBLVECTOR vV_W( snData.nCPV) ;
|
||||
vector<DBLVECTOR> mW( snData.nDegU + 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_next( snData.nDegU - 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_strip( snData.nDegU + 1, vV_W) ;
|
||||
DBLVECTOR vAlpha ;
|
||||
vAlpha.resize( cnData.nDegU - 1) ;
|
||||
if ( ! cnData.bRat ) {
|
||||
for ( int i = 0 ; i <= cnData.nDegU ; ++i ) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row ) {
|
||||
mBC[i][row] = cnData.mCP[i][row] ;
|
||||
vAlpha.resize( snData.nDegU - 1) ;
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mBC[i][row] = snData.mCP[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= cnData.nDegU ; ++i ) {
|
||||
for (int row = 0 ; row < cnData.nCPV ; ++ row) {
|
||||
mW[i][row] = cnData.mW[i][row] ;
|
||||
mBC[i][row] = cnData.mCP[i][row] * cnData.mW[i][row] ;
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mW[i][row] = snData.mW[i][row] ;
|
||||
mBC[i][row] = snData.mCP[i][row] * snData.mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool bRef = false ;
|
||||
while ( b < nU - 1) { // qui correggo un probabile errore, mettendo nU anziché nCPV, come indicato nell'algoritmo
|
||||
// se la superficie ? lineare nel parametro U allora ? gi? in forma di Bezier in questo parametro
|
||||
if ( b == nU - 1 ) {
|
||||
nb = 1 ;
|
||||
}
|
||||
while ( b < nU - 1) { // qui correggo un probabile errore, mettendo nU anzich? nCPV, come indicato nell'algoritmo
|
||||
int i = b ;
|
||||
while ( b < nU - 1 && abs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO)
|
||||
while ( b < nU - 1 && abs( snData.vU[b+1] - snData.vU[b]) < EPS_ZERO)
|
||||
++ b ;
|
||||
int mult = b - i + 1 ;
|
||||
if ( mult < cnData.nDegU ) {
|
||||
if ( mult < snData.nDegU ) {
|
||||
bRef = true ;
|
||||
// calcolo numeratore e alpha
|
||||
double numer = cnData.vU[b] - cnData.vU[a] ;
|
||||
for ( int j = cnData.nDegU ; j > mult ; -- j)
|
||||
vAlpha[j-mult-1] = numer / ( cnData.vU[a+j] - cnData.vU[a]) ;
|
||||
int r = cnData.nDegU - mult ;
|
||||
for ( int j = 1 ; j <= cnData.nDegU - mult ; ++j ) {
|
||||
double numer = snData.vU[b] - snData.vU[a] ;
|
||||
for ( int j = snData.nDegU ; j > mult ; -- j)
|
||||
vAlpha[j-mult-1] = numer / ( snData.vU[a+j] - snData.vU[a]) ;
|
||||
int r = snData.nDegU - mult ;
|
||||
for ( int j = 1 ; j <= snData.nDegU - mult ; ++j ) {
|
||||
int save = r - j ;
|
||||
int s = mult + j ;
|
||||
//for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
// for ( int k = cnData.nDegU ; k >= s ; --k ) {
|
||||
//for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
// for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
// vBC[nCPU*row + k] = vAlpha[k-s]*vBC[nCPU*row + k] + ( 1 - vAlfa[k-s]) * vBC[nCPU*row + k - 1]
|
||||
// }
|
||||
//}
|
||||
if ( ! cnData.bRat ) {
|
||||
for ( int k = cnData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[k][row] = vAlpha[k-s] * mBC[k][row] + ( 1 - vAlpha[k-s]) * mBC[k-1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int k = cnData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[k][row] = vAlpha[k-s] * mBC[k][row] + ( 1 - vAlpha[k-s]) * mBC[k-1][row] ;
|
||||
mW[k][row] = vAlpha[k-s] * mW[k][row] + ( 1 - vAlpha[k-s]) * mW[k-1][row] ;
|
||||
}
|
||||
@@ -184,46 +271,46 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
|
||||
if ( b < nU - 1 ) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
mBC_next[save][row] = mBC[cnData.nDegU][row] ;
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC_next[save][row] = mBC[snData.nDegU][row] ;
|
||||
}
|
||||
if ( cnData.bRat )
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
mW_next[save][row] = mW[cnData.nDegU][row] ;
|
||||
if ( snData.bRat )
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mW_next[save][row] = mW[snData.nDegU][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
mPC_strip.resize( cnData.nDegU * ( nb + 1) + 1 , vCPV) ;
|
||||
mW_strip.resize( cnData.nDegU * ( nb + 1) + 1, vV_W) ;
|
||||
if ( ! cnData.bRat)
|
||||
for ( int i = 0 ; i <= cnData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * cnData.nDegU][row] = mBC[i][row] ;
|
||||
}
|
||||
}
|
||||
mPC_strip.resize( snData.nDegU * ( nb + 1) + 1 , vCPV) ;
|
||||
mW_strip.resize( snData.nDegU * ( nb + 1) + 1, vV_W) ;
|
||||
if ( ! snData.bRat)
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * snData.nDegU][row] = mBC[i][row] ;
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= cnData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * cnData.nDegU][row] = mBC[i][row]/mW[i][row] ;
|
||||
mW_strip[i+ nb * cnData.nDegU][row] = mW[i][row] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * snData.nDegU][row] = mBC[i][row]/mW[i][row] ;
|
||||
mW_strip[i+ nb * snData.nDegU][row] = mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
++ nb ;
|
||||
// ho finito di definire la patch di Bezier attuale e passo alla successiva
|
||||
|
||||
|
||||
// aggiorno mBC con i valori della prossima pezza di Bezier // corrisponde a nb = nb + 1
|
||||
if ( ! cnData.bRat){
|
||||
for (int i = 0 ; i < cnData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
if ( ! snData.bRat){
|
||||
for (int i = 0 ; i < snData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[i][row] = mBC_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < cnData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
for (int i = 0 ; i < snData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[i][row] = mBC_next[i][row] ;
|
||||
mW[i][row] = mW_next[i][row] ;
|
||||
}
|
||||
@@ -231,15 +318,15 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
|
||||
if ( b < nU - 1 ) {
|
||||
for ( int i = cnData.nDegU - mult ; i <= cnData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < cnData.nCPV ; ++ row ) {
|
||||
mBC[i][row] = cnData.mCP[b - cnData.nDegU + i + 1][row] ;
|
||||
for ( int i = snData.nDegU - mult ; i <= snData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row ) {
|
||||
mBC[i][row] = snData.mCP[b - snData.nDegU + i + 1][row] ;
|
||||
}
|
||||
}
|
||||
if ( cnData.bRat ) {
|
||||
for ( int i = cnData.nDegU - mult ; i <= cnData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < cnData.nCPV ; ++ row ) {
|
||||
mW[i][row] = cnData.mW[b - cnData.nDegU + i + 1][row] ;
|
||||
if ( snData.bRat ) {
|
||||
for ( int i = snData.nDegU - mult ; i <= snData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row ) {
|
||||
mW[i][row] = snData.mW[b - snData.nDegU + i + 1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,59 +335,59 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
}
|
||||
|
||||
// se non ho raffinato allora tutti i nodi avevano già molteplicità massima. Converto direttamente in Bezier la dir U
|
||||
// se non ho raffinato allora tutti i nodi avevano gi? molteplicit? massima. Converto direttamente in Bezier la dir U
|
||||
int nCPU_ref ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
if ( ! bRef ) {
|
||||
nCPU_ref = cnData.nCPU ;
|
||||
mPC_strip.resize( cnData.nCPU, vCPV) ;
|
||||
mW_strip.resize( cnData.nCPU, vV_W) ;
|
||||
if ( ! cnData.bRat) {
|
||||
nCPU_ref = snData.nCPU ;
|
||||
mPC_strip.resize( snData.nCPU, vCPV) ;
|
||||
mW_strip.resize( snData.nCPU, vV_W) ;
|
||||
if ( ! snData.bRat) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = cnData.mCP[i][row] ;
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = snData.mCP[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < cnData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = cnData.mCP[i][row] ;
|
||||
mW_strip[i][row] = cnData.mW[i][row] ;
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = snData.mCP[i][row] ;
|
||||
mW_strip[i][row] = snData.mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// devo vedere quante patch ci stanno prendendo i punti che ci sono
|
||||
nb = (cnData.nCPU - 1) / cnData.nDegU ;
|
||||
//nb = (snData.nCPU - 1) / snData.nDegU ;
|
||||
}
|
||||
else
|
||||
nCPU_ref = cnData.nDegU * nb + 1 ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
nCPU_ref = snData.nDegU * nb + 1 ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
|
||||
// ora ho ottenuto le strisce nDegU x nCPV
|
||||
// devo ripetere la procedura, sulla dir V, per ottenere le patch nDegU x nDegV
|
||||
a = cnData.nDegV - 1 ;
|
||||
b = cnData.nDegV ;
|
||||
a = snData.nDegV - 1 ;
|
||||
b = snData.nDegV ;
|
||||
int nc = 0 ; // numero di strisce in V ( lunghezza con V costante)
|
||||
vector<Point3d> vDegV(cnData.nDegV + 1) ;
|
||||
vector<Point3d> vDegV_1(cnData.nDegV - 1) ;
|
||||
vector<Point3d> vDegV(snData.nDegV + 1) ;
|
||||
vector<Point3d> vDegV_1(snData.nDegV - 1) ;
|
||||
vector< vector<Point3d>> m_BC1( nCPU_ref, vDegV) ;
|
||||
vector< vector<Point3d>> m_BC1_next( nCPU_ref, vDegV_1) ;
|
||||
DBLVECTOR vV1_W(cnData.nDegV + 1) ;
|
||||
DBLVECTOR vV2_W(cnData.nDegV - 1) ;
|
||||
DBLVECTOR vV1_W(snData.nDegV + 1) ;
|
||||
DBLVECTOR vV2_W(snData.nDegV - 1) ;
|
||||
vector<DBLVECTOR> mW1( nCPU_ref, vV1_W) ;
|
||||
vector<DBLVECTOR> mW1_next( nCPU_ref, vV2_W) ;
|
||||
DBLVECTOR vAlpha1( cnData.nDegV - 1) ;
|
||||
DBLVECTOR vAlpha1( snData.nDegV - 1) ;
|
||||
vector<vector<Point3d>> mPC_tot( nCPU_ref, vDegV) ;
|
||||
vector<DBLVECTOR> mW_tot( nCPU_ref, vV1_W) ;
|
||||
if ( ! cnData.bRat ) {
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i ) {
|
||||
for ( int row = 0 ; row <= cnData.nDegV ; ++row ) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
m_BC1[i][row] = mPC_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i ) {
|
||||
for (int row = 0 ; row <= cnData.nDegV ; ++ row) {
|
||||
for (int row = 0 ; row <= snData.nDegV ; ++ row) {
|
||||
mW1[i][row] = mW_strip[i][row] ;
|
||||
m_BC1[i][row] = mPC_strip[i][row] * mW_strip[i][row] ;
|
||||
}
|
||||
@@ -308,36 +395,40 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
|
||||
bRef = false ;
|
||||
while ( b < nV - 1) { // qui correggo un probabile errore, mettendo nU anziché nCPV, come indicato nell'algoritmo
|
||||
// se la superficie ? lineare nel parametro V allora ? gi? in forma di Bezier in questo parametro
|
||||
if ( b == nV - 1 ) {
|
||||
nc = 1 ;
|
||||
}
|
||||
while ( b < nV - 1) {
|
||||
int i = b ;
|
||||
while ( b < nV - 1 && abs( cnData.vV[b+1] - cnData.vV[b]) < EPS_ZERO)
|
||||
while ( b < nV - 1 && abs( snData.vV[b+1] - snData.vV[b]) < EPS_ZERO)
|
||||
++ b ;
|
||||
int mult = b - i + 1 ;
|
||||
if ( mult < cnData.nDegV ) {
|
||||
if ( mult < snData.nDegV ) {
|
||||
bRef = true ;
|
||||
// calcolo numeratore e alpha
|
||||
double numer = cnData.vV[b] - cnData.vV[a] ;
|
||||
for ( int j = cnData.nDegV ; j > mult ; -- j)
|
||||
vAlpha1[j-mult-1] = numer / ( cnData.vV[a+j] - cnData.vV[a]) ;
|
||||
int r = cnData.nDegV - mult ;
|
||||
for ( int j = 1 ; j <= cnData.nDegV - mult ; ++j ) {
|
||||
double numer = snData.vV[b] - snData.vV[a] ;
|
||||
for ( int j = snData.nDegV ; j > mult ; -- j)
|
||||
vAlpha1[j-mult-1] = numer / ( snData.vV[a+j] - snData.vV[a]) ;
|
||||
int r = snData.nDegV - mult ;
|
||||
for ( int j = 1 ; j <= snData.nDegV - mult ; ++j ) {
|
||||
int save = r - j ;
|
||||
int s = mult + j ;
|
||||
//for ( int row = 0 ; row < cnData.nCPV ; ++row) {
|
||||
// for ( int k = cnData.nDegU ; k >= s ; --k ) {
|
||||
//for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
// for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
// vBC[nCPU*row + k] = vAlpha1[k-s]*vBC[nCPU*row + k] + ( 1 - vAlpha1[k-s]) * vBC[nCPU*row + k - 1]
|
||||
// }
|
||||
//}
|
||||
if ( ! cnData.bRat) {
|
||||
if ( ! snData.bRat) {
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k) {
|
||||
for ( int row = cnData.nDegV ; row >= s ; --row ) {
|
||||
for ( int row = snData.nDegV ; row >= s ; --row ) {
|
||||
m_BC1[k][row] = vAlpha1[row-s] * m_BC1[k][row] + ( 1 - vAlpha1[row-s]) * m_BC1[k][row-1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k) {
|
||||
for ( int row = cnData.nDegV ; row >= s ; --row ) {
|
||||
for ( int row = snData.nDegV ; row >= s ; --row ) {
|
||||
m_BC1[k][row] = vAlpha1[row-s] * m_BC1[k][row] + ( 1 - vAlpha1[row-s]) * m_BC1[k][row-1] ;
|
||||
mW1[k][row] = vAlpha1[row-s] * mW1[k][row] + ( 1 - vAlpha1[row-s]) * mW1[k][row-1] ;
|
||||
}
|
||||
@@ -345,36 +436,36 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
|
||||
if ( b < nV - 1 ) {
|
||||
if ( !cnData.bRat ){
|
||||
if ( !snData.bRat ){
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
m_BC1_next[i][save] = m_BC1[i][cnData.nDegV] ;
|
||||
m_BC1_next[i][save] = m_BC1[i][snData.nDegV] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
m_BC1_next[i][save] = m_BC1[i][cnData.nDegV] ;
|
||||
mW1_next[save] = mW1[cnData.nDegV] ;
|
||||
m_BC1_next[i][save] = m_BC1[i][snData.nDegV] ;
|
||||
mW1_next[save] = mW1[snData.nDegV] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int nRef = cnData.nDegV * ( nc + 1) + 1 ;
|
||||
int nRef = snData.nDegV * ( nc + 1) + 1 ;
|
||||
for ( int k = 0 ; k < nCPU_ref; ++k){
|
||||
mPC_tot[k].resize( nRef) ;
|
||||
mW_tot[k].resize( nRef) ;
|
||||
}
|
||||
if ( ! cnData.bRat)
|
||||
if ( ! snData.bRat)
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row <= cnData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * cnData.nDegV] = m_BC1[i][row] ;
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * snData.nDegV] = m_BC1[i][row] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row <= cnData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * cnData.nDegV] = m_BC1[i][row]/mW1[i][row] ;
|
||||
mW_tot[i][row + nc * cnData.nDegV] = mW1[i][row] ;
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * snData.nDegV] = m_BC1[i][row]/mW1[i][row] ;
|
||||
mW_tot[i][row + nc * snData.nDegV] = mW1[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,16 +473,16 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
// ho finito di definire la patch di Bezier attuale e passo alla successiva
|
||||
|
||||
// aggiorno mBC con i valori della prossima pezza di Bezier // corrisponde a nc = nc + 1
|
||||
if ( ! cnData.bRat){
|
||||
if ( ! snData.bRat){
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i) {
|
||||
for ( int row = 0 ; row < cnData.nDegV - 1 ; ++row) {
|
||||
for ( int row = 0 ; row < snData.nDegV - 1 ; ++row) {
|
||||
m_BC1[i][row] = m_BC1_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i) {
|
||||
for ( int row = 0 ; row < cnData.nDegV - 1 ; ++row) {
|
||||
for ( int row = 0 ; row < snData.nDegV - 1 ; ++row) {
|
||||
m_BC1[i][row] = m_BC1_next[i][row] ;
|
||||
mW1[i][row] = mW1_next[i][row] ;
|
||||
}
|
||||
@@ -400,14 +491,16 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
|
||||
if ( b < nV - 1) {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i ) {
|
||||
for ( int row = cnData.nDegV - mult ; row <= cnData.nDegV ; ++ row) {
|
||||
m_BC1[i][row] = cnData.mCP[i][b - cnData.nDegV + row + 1] ;
|
||||
for ( int row = snData.nDegV - mult ; row <= snData.nDegV ; ++ row) {
|
||||
//m_BC1[i][row] = snData.mCP[i][b - snData.nDegV + row + 1] ;
|
||||
m_BC1[i][row] = mPC_strip[i][b - snData.nDegV + row + 1] ;
|
||||
}
|
||||
}
|
||||
if ( cnData.bRat ) {
|
||||
if ( snData.bRat ) {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i ) {
|
||||
for ( int row = cnData.nDegV - mult ; row <= cnData.nDegV ; ++ row) {
|
||||
mW1[i][row] = cnData.mW[i][b - cnData.nDegV + row + 1] ;
|
||||
for ( int row = snData.nDegV - mult ; row <= snData.nDegV ; ++ row) {
|
||||
//mW1[i][row] = snData.mW[i][b - snData.nDegV + row + 1] ;
|
||||
mW1[i][row] = mW_strip[i][b - snData.nDegV + row + 1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,12 +512,12 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
// se non ho raffinato allora aggiungo direttamente alle matrici della superficie totale
|
||||
int nCPV_ref ; // numero dei punti di controllo in V dopo il raffinamento
|
||||
if ( ! bRef) {
|
||||
nCPV_ref = cnData.nCPV ;
|
||||
nCPV_ref = snData.nCPV ;
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k){
|
||||
mPC_tot[k].resize( cnData.nCPV) ;
|
||||
mW_tot[k].resize( cnData.nCPV) ;
|
||||
mPC_tot[k].resize( snData.nCPV) ;
|
||||
mW_tot[k].resize( snData.nCPV) ;
|
||||
}
|
||||
if ( ! cnData.bRat) {
|
||||
if ( ! snData.bRat) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < nCPV_ref ; ++ row) {
|
||||
mPC_tot[i][row] = mPC_strip[i][row] ;
|
||||
@@ -440,17 +533,17 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
}
|
||||
// devo vedere quante patch ci stanno prendendo i punti che ci sono
|
||||
nc = (cnData.nCPV - 1) / cnData.nDegV ;
|
||||
//nc = (snData.nCPV - 1) / snData.nDegV ;
|
||||
}
|
||||
else
|
||||
nCPV_ref = cnData.nDegV * nc + 1 ;
|
||||
nCPV_ref = snData.nDegV * nc + 1 ;
|
||||
|
||||
// finalmente setto la superficie di bezier totale divisa in nb patch in U e nc patch in V
|
||||
PtrOwner<ISurfBezier> pSrfBz( CreateSurfBezier()) ;
|
||||
if ( IsNull( pSrfBz))
|
||||
return nullptr ;
|
||||
pSrfBz->Init(cnData.nDegU, cnData.nDegV, nb, nc, cnData.bRat) ;
|
||||
if ( !cnData.bRat ) {
|
||||
pSrfBz->Init(snData.nDegU, snData.nDegV, nb, nc, snData.bRat) ;
|
||||
if ( !snData.bRat ) {
|
||||
for ( int i = 0 ; i < nCPU_ref; ++ i) {
|
||||
for (int j = 0 ; j < nCPV_ref; ++j) {
|
||||
pSrfBz->SetControlPoint( i + nCPU_ref * j, mPC_tot[i][j]) ;
|
||||
@@ -465,129 +558,4 @@ NurbsToBezierSurface(const CNurbsSurfData& cnData)
|
||||
}
|
||||
}
|
||||
return Release( pSrfBz) ;
|
||||
}
|
||||
|
||||
//// algoritmo per le curve, da usare come reference///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// // vettore dei punti di controllo della curva di Bezier
|
||||
// PNTVECTOR vBC ;
|
||||
// vBC.resize( cnData.nDeg + 1) ;
|
||||
// DBLVECTOR vBW ;
|
||||
// vBW.resize( cnData.nDeg + 1) ;
|
||||
// if ( ! cnData.bRat) {
|
||||
// for ( int i = 0 ; i <= cnData.nDeg ; ++ i)
|
||||
// vBC[i] = cnData.vCP[i] ;
|
||||
// }
|
||||
// else {
|
||||
// for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
// vBC[i] = cnData.vCP[i] * cnData.vW[i] ;
|
||||
// vBW[i] = cnData.vW[i] ;
|
||||
// }
|
||||
// }
|
||||
// // primi coefficienti della successiva
|
||||
// PNTVECTOR vNextBC ;
|
||||
// vNextBC.resize( cnData.nDeg - 1) ;
|
||||
// DBLVECTOR vNextBW ;
|
||||
// vNextBW.resize( cnData.nDeg - 1) ;
|
||||
// // ...
|
||||
// DBLVECTOR vAlfa ;
|
||||
// vAlfa.resize( cnData.nDeg - 1) ;
|
||||
// int a = cnData.nDeg - 1 ;
|
||||
// int b = cnData.nDeg ;
|
||||
// bool bPrevRejected = false ;
|
||||
// // ciclo
|
||||
// while ( b < nU - 1) {
|
||||
// int i = b ;
|
||||
// while ( b < nU - 1 && abs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO)
|
||||
// ++ b ;
|
||||
// int mult = min( b - i + 1, cnData.nDeg) ;
|
||||
// if ( mult < cnData.nDeg) {
|
||||
// // numeratore di alfa
|
||||
// double numer = cnData.vU[b] - cnData.vU[a] ;
|
||||
// // calcola e salva gli alfa
|
||||
// for ( int j = cnData.nDeg ; j > mult ; -- j)
|
||||
// vAlfa[j-mult-1] = numer / ( cnData.vU[a+j] - cnData.vU[a]) ;
|
||||
// // inserisco il nodo r volte
|
||||
// int r = cnData.nDeg - mult ;
|
||||
// for ( int j = 1 ; j <= r ; ++ j) {
|
||||
// int save = r - j ;
|
||||
// int s = mult + j ;
|
||||
// for ( int k = cnData.nDeg ; k >= s ; -- k)
|
||||
// vBC[k] = vAlfa[k-s] * vBC[k] + ( 1 - vAlfa[k-s]) * vBC[k-1] ;
|
||||
// if ( cnData.bRat) {
|
||||
// for ( int k = cnData.nDeg ; k >= s ; -- k)
|
||||
// vBW[k] = vAlfa[k-s] * vBW[k] + ( 1 - vAlfa[k-s]) * vBW[k-1] ;
|
||||
// }
|
||||
// if ( b < nU - 1) {
|
||||
// vNextBC[save] = vBC[cnData.nDeg] ;
|
||||
// if ( cnData.bRat)
|
||||
// vNextBW[save] = vBW[cnData.nDeg] ;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // costruisco la curva di Bezier e la inserisco nella curva composita
|
||||
// PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||
// if ( IsNull( pCrvBez))
|
||||
// return nullptr ;
|
||||
// // se precedente saltata
|
||||
// if ( bPrevRejected) {
|
||||
// // prendo l'ultimo punto della curva composita per garantire la continuità
|
||||
// Point3d ptEnd ;
|
||||
// if ( pCrvCompo->GetEndPoint( ptEnd))
|
||||
// vBC[0] = ptEnd ;
|
||||
// }
|
||||
// // la inizializzo
|
||||
// if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat))
|
||||
// return nullptr ;
|
||||
// if ( ! cnData.bRat) {
|
||||
// for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, vBC[i]))
|
||||
// return nullptr ;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
// if ( ! pCrvBez->SetControlPoint( i, vBC[i] / vBW[i], vBW[i]))
|
||||
// return nullptr ;
|
||||
// }
|
||||
// }
|
||||
// // se è una vera curva, la aggiungo alla curva composita
|
||||
// if ( ! pCrvBez->IsAPoint()) {
|
||||
// if ( ! pCrvCompo->AddCurve( Release( pCrvBez)))
|
||||
// return nullptr ;
|
||||
// bPrevRejected = false ;
|
||||
// }
|
||||
// // altrimenti è un punto, la cancello
|
||||
// else {
|
||||
// pCrvBez.Reset() ;
|
||||
// bPrevRejected = true ;
|
||||
// }
|
||||
//
|
||||
// // inizializzazioni per la prossima curva di Bezier
|
||||
// if ( b < nU - 1) {
|
||||
// if ( ! cnData.bRat) {
|
||||
// for ( int i = 0 ; i < cnData.nDeg - 1 ; ++ i)
|
||||
// vBC[i] = vNextBC[i] ;
|
||||
// for ( int i = cnData.nDeg - mult ; i <= cnData.nDeg ; ++ i)
|
||||
// vBC[i] = cnData.vCP[b-cnData.nDeg+i+1] ;
|
||||
// }
|
||||
// else {
|
||||
// for ( int i = 0 ; i < cnData.nDeg - 1 ; ++ i) {
|
||||
// vBC[i] = vNextBC[i] ;
|
||||
// vBW[i] = vNextBW[i] ;
|
||||
// }
|
||||
// for ( int i = cnData.nDeg - mult ; i <= cnData.nDeg ; ++ i) {
|
||||
// vBC[i] = cnData.vCP[b-cnData.nDeg+i+1] * cnData.vW[b-cnData.nDeg+i+1] ;
|
||||
// vBW[i] = cnData.vW[b-cnData.nDeg+i+1] ;
|
||||
// }
|
||||
// }
|
||||
// a = b ;
|
||||
// ++ b ;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // restituisco la curva composita
|
||||
// return Release( pCrvCompo) ;
|
||||
//}
|
||||
}
|
||||
+48
-5
@@ -107,18 +107,22 @@ SurfTriMesh::Clear( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::AddVertex( const Point3d& ptVert)
|
||||
SurfTriMesh::AddVertex( const Point3d& ptVert, const double dU, const double dV)
|
||||
{
|
||||
// imposto ricalcolo
|
||||
// imposto ricalcolo
|
||||
m_nStatus = TO_VERIFY ;
|
||||
m_nParts = - 1 ;
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
// inserisco il vertice
|
||||
// inserisco il vertice
|
||||
try { m_vVert.emplace_back( ptVert) ;}
|
||||
catch(...) { return SVT_NULL ;}
|
||||
// ne determino l'indice
|
||||
return int( m_vVert.size() - 1) ;
|
||||
// ne determino l'indice
|
||||
int nId = int( m_vVert.size() - 1) ;
|
||||
// aggiugo le coordinate corrispondenti allo spazio parametrico
|
||||
m_vVert[nId].dU = dU ;
|
||||
m_vVert[nId].dV = dV ;
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -475,6 +479,20 @@ SurfTriMesh::GetVertex( int nId, Point3d& ptP) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
// verifico esistenza del vertice
|
||||
if ( nId < 0 || nId >= GetVertexSize() || m_vVert[nId].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// recupero i dati
|
||||
dU = m_vVert[nId].dU ;
|
||||
dV = m_vVert[nId].dV ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFirstVertex( Point3d& ptP) const
|
||||
@@ -482,6 +500,13 @@ SurfTriMesh::GetFirstVertex( Point3d& ptP) const
|
||||
return GetNextVertex( SVT_NULL, ptP) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFirstVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
return GetNextVertexParam( SVT_NULL, dU, dV) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
|
||||
@@ -499,6 +524,24 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetNextVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
// cerco il primo successivo valido
|
||||
do {
|
||||
nId ++ ;
|
||||
} while ( nId < GetVertexSize() && m_vVert[nId].nIdTria == SVT_DEL) ;
|
||||
// se oltrepassata fine
|
||||
if ( nId >= GetVertexSize())
|
||||
return SVT_NULL ;
|
||||
// recupero i dati
|
||||
dU = m_vVert[nId].dU ;
|
||||
dV = m_vVert[nId].dV ;
|
||||
// ritorno indice triangolo corrente
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetTriangle( int nId, int nIdVert[3]) const
|
||||
|
||||
+17
-10
@@ -27,15 +27,19 @@ class SurfFlatRegion ;
|
||||
// Classe Vertice
|
||||
class StmVert
|
||||
{
|
||||
public :
|
||||
StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
|
||||
public :
|
||||
Point3d ptP ;
|
||||
int nIdTria ;
|
||||
int nFlag ;
|
||||
mutable int nTemp ;
|
||||
public :
|
||||
StmVert( void) : ptP(), dU( -1), dV( -1), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ) : ptP( ptQ), dU( -1), dV( -1), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), dU( -1), dV( -1), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
|
||||
public :
|
||||
Point3d ptP ;
|
||||
double dU ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000)
|
||||
// della sup di Bezier // -1 se non definito
|
||||
double dV ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000)
|
||||
// della sup di Bezier // -1 se non definito
|
||||
int nIdTria ;
|
||||
int nFlag ;
|
||||
mutable int nTemp ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -215,7 +219,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
{ m_dSmoothAng = std::max( dSmoothAngDeg, EPS_ANG_SMALL) ;
|
||||
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
|
||||
m_OGrMgr.Reset() ; }
|
||||
int AddVertex( const Point3d& ptVert) override ;
|
||||
int AddVertex( const Point3d& ptVert, const double dU = -1 , const double dV = -1) override ;
|
||||
bool MoveVertex( int nInd, const Point3d& ptNewVert) override ;
|
||||
int AddTriangle( const int nIdVert[3], int nTFlag = 0) override ;
|
||||
bool RemoveTriangle( int nId) override ;
|
||||
@@ -244,8 +248,11 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
double GetSmoothAngle( void) const override
|
||||
{ return m_dSmoothAng ; }
|
||||
bool GetVertex( int nId, Point3d& ptP) const override ;
|
||||
bool GetVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
int GetFirstVertex( Point3d& ptP) const override ;
|
||||
int GetFirstVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
int GetNextVertex( int nId, Point3d& ptP) const override ;
|
||||
int GetNextVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
bool GetTriangle( int nId, int nIdVert[3]) const override ;
|
||||
int GetFirstTriangle( int nIdVert[3]) const override ;
|
||||
int GetNextTriangle( int nId, int nIdVert[3]) const override ;
|
||||
|
||||
Reference in New Issue
Block a user