EgtGeomKernel :

- correzioni e migliorie alle rigate con le bezier MINDISTPLUS.
This commit is contained in:
Daniele Bariletti
2024-07-05 17:12:08 +02:00
parent 6df0cf3203
commit b4878f1ac0
+217 -133
View File
@@ -3910,7 +3910,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
nSecondRowInd = nDegU * nSpanU + 1 ;
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
// come riferimento tengo i match identificati dalla curva 0
// numero di span aggiunte su U0 e U1
nCount0 = 0 ;
nCount1 = 0 ;
@@ -3942,11 +3942,28 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
++nCount1 ;
}
else {
// qui devo capire se aggiungere la nuova sottocurva prima o dopo la ripetizione dei punti
// se il match del punto della seconda curva è uguale al punto a cui ero arrivato sulla prima curva allora prima aggiungo la ripetizione di punti
// se invece il match è più avanti allora aggiuno prima la curva e poi la ripetzione di punti
bool bSubCurveAddedFirst = false ;
if ( vPnt1Match[vPnt0Match[i+1].second].second != i+1 ) {
bSubCurveAddedFirst = true ;
// aggiungo una sottocurva dalla prima curva
pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( i)) ;
for ( int j = nCount0 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
if ( ! bRat0)
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j)) ;
else
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j), pSubCrv0->GetControlWeight( j)) ;
}
++ nCount0 ;
}
// ripeto l'ultimo punto aggiunto per il numero di curve balzate della seconda curva - 1
for( int k = 0 ; k < nIndMatchNext - nIndMatch - 1 ; ++k) {
pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( i != 0 ? i - 1 : i)) ;
for ( int j = nCount0 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
int nPoint = nCount0 == 0 ? 0 : nDegU ;
int nPoint = nCount0 == 0 && ! bSubCurveAddedFirst ? 0 : nDegU ;
if ( ! bRat0)
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( nPoint)) ;
else
@@ -3954,15 +3971,18 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
}
++ nCount0 ;
}
// aggiungo una sottocurva dalla prima curva
pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( i)) ;
for ( int j = nCount0 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
if ( ! bRat0)
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j)) ;
else
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j), pSubCrv0->GetControlWeight( j)) ;
// se non l'ho già aggiunta prima aggiungo una sottocurva della prima curva
if( ! bSubCurveAddedFirst) {
// aggiungo una sottocurva dalla prima curva
pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( i)) ;
for ( int j = nCount0 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
if ( ! bRat0)
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j)) ;
else
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j), pSubCrv0->GetControlWeight( j)) ;
}
++ nCount0 ;
}
++ nCount0 ;
// aggiungo tutte le sottocurve che ho balzato della seconda
@@ -4008,72 +4028,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
++ nCrv1 ;
}
}
////////////////// ORA SI PUò CANCELLARE
//// // QUESTO PEZZO E' DA SISTEMARE
//// controllo di aver aggiunto anche gli ultimi punti
//int nInd = nIndMatchNext < nSpanU0 ? nIndMatchNext : nIndMatchNext - 1 ;
//while ( nCount0 < nSpanU) {
// const ICurveBezier* pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( nInd)) ;
// for ( int j = 1 ; j < nLastPoint ; ++j) {
// int nPoint = nInd < nSpanU0 - 1 ? j : nDegU ;
// if ( ! bRat0)
// SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( nPoint)) ;
// else
// SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( nPoint), pSubCrv0->GetControlWeight( nPoint)) ;
// }
// ++ nCount0 ;
// if ( nInd < nSpanU0 - 1)
// ++ nInd ;
//}
//for ( int i = 0 ; i < int( vPnt0Match.size() - 1) ; ++i) {
// nIndMatch = vPnt0Match[i].second ;
// nIndMatchNext = vPnt0Match[i+1].second ;
// if ( nIndMatch == nSpanU1)
// break ;
// const ICurveBezier* pSubCrv1 ;
// if ( nIndMatch == nIndMatchNext) {
// pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nIndMatch)) ;
// for ( int j = nCount1 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
// if( ! bRat1)
// SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv1->GetControlPoint( 0)) ;
// else
// SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv1->GetControlPoint( 0), pSubCrv1->GetControlWeight( 0)) ;
// }
// ++ nCount1 ;
// }
// else {
// for( int k = 0 ; k < nIndMatchNext - nIndMatch ; ++k) {
// pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nIndMatch + k)) ;
// for ( int j = nCount1 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
// if( ! bRat1)
// SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv1->GetControlPoint( j)) ;
// else
// SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv1->GetControlPoint( j), pSubCrv1->GetControlWeight( j)) ;
// }
// ++ nCount1 ;
// }
// }
//}
//// controllo di aver aggiunto anche gli ultimi punti
//nInd = nIndMatchNext < nSpanU1 ? nIndMatchNext : nIndMatchNext - 1 ;
//while ( nCount1 < nSpanU) {
// const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nInd)) ;
// for ( int j = 1 ; j < nLastPoint ; ++j) {
// int nPoint = nInd < nSpanU1 - 1 ? j : nDegU ;
// if( ! bRat1)
// SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv1->GetControlPoint( nPoint)) ;
// else
// SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv1->GetControlPoint( nPoint), pSubCrv1->GetControlWeight( nPoint)) ;
// }
// ++ nCount1 ;
// if ( nInd < nSpanU1 - 1)
// ++ nInd ;
//}
}
if ( nRuledType == RLT_B_ISOPAR) {
@@ -4200,111 +4154,241 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
// scorro la prima curva e per ogni punto di fine sottocurva cerco il minDistPoint sull'altra curva
// in quel punto la curva verrà spezzata, a meno che non si trovi una joint già sufficientemente vicina
int nAtStart1 = 0 ;
// prima trovo le associazioni senza aggiunte di punti
PNTIVECTOR vPnt0Match, vPnt1Match ;
bool bCommonPoint = false ;
AssociatePolyLinesMinDistPoints( plU0, plU1, vPnt0Match, vPnt1Match, bCommonPoint) ;
int nAtStart1 = 0 ; // match ripetuti dalla curva U0 allo start della curva U1
int nAtEnd1 = 0 ;
Point3d ptP0 ; plU0.GetFirstPoint( ptP0) ;
int c = 0 ; // debug
int c = 0 ;
int nCrvCount = 0 ;
int nRep0 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1
int nRep1 = 0 ;
double dLastParamMatch = 0 ;
Point3d ptLastPointMatch = ptP0 ;
BOOLVECTOR vbRep0( nSpanU0) ;
INTVECTOR vnAddedOrNextIsRep0 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
DBLVECTOR vdSplit0 ;
fill( vbRep0.begin(), vbRep0.end(), false) ;
while ( plU0.GetNextPoint( ptP0, true)) {
// devo salvarmi se matcho più punti con lo start o l'end della curva totale
DistPointCurve dpc( ptP0, *pCrvU1, false) ;
int nFlag = 0 ;
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
if ( dParam < EPS_SMALL ) {
++nAtStart1 ;
vbRep0[c] = true ;
++c ;
continue ;
}
else if ( dParam > nSpanU1 + EPS_SMALL ) {
++ nAtEnd1 ;
vbRep0[c] = true ;
++c ;
continue ;
}
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ; // devo verificare se ho già un punto di start/end nelle vicinanze
nCrvCount = pCrvU1->GetCurveCount() ; //debug
pCrvU1->AddJoint( dParam) ;
if( nCrvCount == pCrvU1->GetCurveCount())//debug
int a = 0 ; //debug
nSpanU1 = pCrvU1->GetCurveCount() ;
// devo aggiungere un controllo in modo che i parametri trovati siano sempre crescenti
++c ;// debug
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
dParam = dLastParamMatch ;
vbRep0[c] = true ;
++ nRep0 ;
++c ;
continue ;
}
else {
dLastParamMatch = dParam ;
ptLastPointMatch = ptJoint ;
nCrvCount = pCrvU1->GetCurveCount() ;
//pCrvU1->AddJoint( dParam) ;
// se sono già troppo vicino ad un split esistente allora non faccio nulla
if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
++c ;
continue ;
}
vdSplit0.push_back( dParam) ;
// verifico se ho un match per questo punto
// in tal caso vuol dire che sto creando una ripetizione nRep1
int nCase = 0 ;
for ( int j = 0 ; j < int( vPnt1Match.size()) ; ++j) {
if ( vPnt1Match[j].second == c + 1) {
++nRep1 ;
// capisco se il punto è rep o se lo è il suo successivo
if( j < dParam)
nCase = 1 ;
else
nCase = 2 ;
break ;
}
}
vnAddedOrNextIsRep0.push_back( nCase) ;
}
//nSpanU1 = pCrvU1->GetCurveCount() ;
++c ;
}
int nAtStart0 = 0 ;
int nAtEnd0 = 0 ;
Point3d ptP1 ; plU1.GetFirstPoint( ptP1) ;
c = 0 ;// debug
c = 0 ;
dLastParamMatch = 0 ;
ptLastPointMatch = ptP1 ;
INTVECTOR vnAddedOrNextIsRep1 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
DBLVECTOR vdSplit1 ;
BOOLVECTOR vbRep1( plU1.GetPointNbr() - 1) ;
fill( vbRep1.begin(), vbRep1.end(), false) ;
bool bPrevWasRep = false ;
while ( plU1.GetNextPoint( ptP1, true)) {
DistPointCurve dpc( ptP1, *pCrvU0, false) ;
int nFlag = 0 ;
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
if ( dParam < EPS_SMALL ) {
++nAtStart0 ;
vbRep1[c] = true ;
++c ;
continue ;
}
else if ( dParam > nSpanU0 - EPS_SMALL ) {
++ nAtEnd0 ;
vbRep1[c] = true ;
++c ;
continue ;
}
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ; // devo verificare se ho già un punto di start/end nelle vicinanze
nCrvCount = pCrvU0->GetCurveCount() ; // debug
pCrvU0->AddJoint( dParam) ;
if( nCrvCount == pCrvU0->GetCurveCount())
int a = 0 ;
nSpanU0 = pCrvU0->GetCurveCount() ;
++c ;// debug
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
dParam = dLastParamMatch ;
vbRep1[c] = true ;
++ nRep1 ;
++c ;
continue ;
}
else {
dLastParamMatch = dParam ;
ptLastPointMatch = ptJoint ;
nCrvCount = pCrvU0->GetCurveCount() ;
//pCrvU0->AddJoint( dParam) ;
//// se ho aggiunto un nuovo punto alla curva U0 allora devo allungare coerentemente il vettore vbRep0
//if( nCrvCount != pCrvU0->GetCurveCount())
// vbRep0.insert( vbRep0.begin() + int(round( dParam - 0.5)), false) ;
//se sono troppo vicino ad uno split esistente allora non faccio nulla
if( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
++c ;
continue ;
}
vdSplit1.push_back( dParam) ;
// verifico se ho un match per questo punto
// in tal caso vuol dire che sto creando una ripetizione nRep1
int nCase = 0 ;
for ( int j = 0 ; j < int( vPnt0Match.size()) ; ++j) {
if ( vPnt0Match[j].second == c + 1) {
++nRep0 ;
// capisco se il punto è rep o se lo è il suo successivo
if( j < dParam)
nCase = 1 ;
else
nCase = 2 ;
break ;
}
}
vnAddedOrNextIsRep1.push_back( nCase) ;
}
//nSpanU0 = pCrvU0->GetCurveCount() ;
++c ;
}
nSpanU = max( nSpanU0, nSpanU1) ;
//// correggo il vettore vbRep1 aggiungendo gli elementi corrispondenti ai punti che ho aggiunto
//plU1.GetFirstPoint( ptP1) ;
//bool bAdvance = true ;
//for ( int i = 0 ; i < int( pCrvU1->GetCurveCount()) ; ++i) {
// if ( bAdvance)
// plU1.GetNextPoint( ptP1) ;
// const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( i)) ;
// Point3d ptSubEnd ; pSubCrv1->GetEndPoint( ptSubEnd) ;
// if ( ! AreSamePointApprox( ptP1, ptSubEnd)) {
// vbRep1.insert( vbRep1.begin() + i, false) ;
// bAdvance = false ;
// }
// else
// bAdvance = true ;
//}
// questo controllo SERVE??? è da cambiare per tenere dentro anche il caso di mismatch??
//// se la differenza tra il numero di span delle due curve non è colmata dalla ripetizione dello start o dell'end allora devo tenere conto anche
//// delle addJoint che non hanno fatto nulla ( perché chieste di splittare la curva troppo vicino ad un punto già esistente di split, magari in un caso anche di multimatch per lo stesso punto)
//if ( (nSpanU0 > nSpanU1 && nSpanU0 != nSpanU1 + nAtStart1 + nAtEnd1) ||
// (nSpanU0 < nSpanU1 && nSpanU1 != nSpanU0 + nAtStart0 + nAtEnd0))
// return false ;
// applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep
for ( int z = int( vdSplit0.size() - 1) ; z >= 0 ; --z) {
double dSplit = vdSplit0[z] ;
pCrvU1->AddJoint( dSplit) ;
int nSplit = int( dSplit) ;
switch( vnAddedOrNextIsRep0[z]) {
case 0 : vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ;
case 1 : vbRep1.insert( vbRep1.begin() + nSplit, true) ; break ;
case 2 : vbRep1[nSplit] = true ;
vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ;
}
}
for ( int z = int( vdSplit1.size() - 1) ; z >= 0 ; --z) {
double dSplit = vdSplit1[z] ;
pCrvU0->AddJoint( dSplit) ;
int nSplit = int( dSplit) ;
switch( vnAddedOrNextIsRep1[z]) {
case 0 : vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ;
case 1 : vbRep0.insert( vbRep0.begin() + nSplit, true) ; break ;
case 2 : vbRep0[nSplit] = true ;
vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ;
}
}
nSpanU0 = pCrvU0->GetCurveCount() ;
nSpanU1 = pCrvU1->GetCurveCount() ;
// trovo il numero di span che dovrà avere la superficie
// ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0)
nSpanU = nSpanU0 + nAtStart0 + nAtEnd0 + nRep1 ;
nSecondRowInd = nDegU * nSpanU + 1 ;
// inizializzo la superficie
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
// costruisco la matrice dei punti di controllo aggiungendo i punti delle due curve appena modificate
for ( int j = 0 ; j < nSpanU ; ++j) {
//int nCrv = nAtStart0 != 0 ? j - ( nAtStart0 - 1) : j ;
int nCrv = j - nAtStart0 ;
if ( j < nAtStart0)
nCrv = 0 ;
else if ( j >= nSpanU - 1 - nAtEnd0)
nCrv = nSpanU0 -1 ;
const ICurveBezier* pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( nCrv)) ;
for( int i = j == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) {
// aggiungo i punti di controllo scorrendo in contemporanea le due curve
int nAddedSpan = 0 ;
int nCrv0 = 0 ;
int nCrv1 = 0 ;
while ( nAddedSpan < nSpanU) {
if ( nCrv0 >= nSpanU0)
nCrv0 = nSpanU0 - 1;
if ( nCrv1 >= nSpanU1)
nCrv1 = nSpanU1 - 1;
bool bRep0 = vbRep0[nCrv0] ;
const ICurveBezier* pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( nCrv0)) ;
for( int i = nAddedSpan == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) {
int nInd = i ;
if ( j < nAtStart0)
nInd = 0 ;
//else if ( j >= nSpanU - 1 - nAtEnd0 && ((nAtStart0 != 0 ? j - ( nAtStart0 - 1) : j) != nSpanU0 - 1))
else if ( j >= nSpanU - 1 - nAtEnd0 && j - nAtStart0 != nSpanU0 - 1)
nInd = nDegU ;
// se ho una ripetizione allora riaggiungo l'ultimo punto. Se sono ancora alla curva 0 invece devo aggiungere lo start della curva U0
if ( vbRep1[nCrv1])
nInd = nCrv0 < nSpanU0 ? 0 : nDegU ;
if ( ! bRat)
SetControlPoint( j * nDegU + i, pSubCrv0->GetControlPoint( nInd)) ;
SetControlPoint( nAddedSpan * nDegU + i, pSubCrv0->GetControlPoint( nInd)) ;
else
SetControlPoint( j * nDegU + i, pSubCrv0->GetControlPoint( nInd), pSubCrv0->GetControlWeight( nInd)) ;
SetControlPoint( nAddedSpan * nDegU + i, pSubCrv0->GetControlPoint( nInd), pSubCrv0->GetControlWeight( nInd)) ;
}
}
for ( int j = 0 ; j < nSpanU ; ++j) {
int nCrv = j - nAtStart1 ;
if ( j < nAtStart1)
nCrv = 0 ;
else if ( j >= nSpanU - 1 - nAtEnd1)
nCrv = nSpanU1 -1 ;
const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nCrv)) ;
for( int i = j == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) {
if ( ! vbRep1[nCrv1])
++ nCrv0 ;
const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nCrv1)) ;
for( int i = nAddedSpan == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) {
int nInd = i ;
if ( j < nAtStart1)
nInd = 0 ;
else if ( j >= nSpanU - 1 - nAtEnd1 && j - nAtStart1 != nSpanU1 - 1)
nInd = nDegU ;
// se ho una ripetizione allora riaggiungo l'ultimo punto. Se sono ancora alla curva 0 invece devo aggiungere lo start della curva U0
if ( bRep0)
nInd = nCrv1 < nSpanU1 ? 0 : nDegU ;
if ( ! bRat)
SetControlPoint( nSecondRowInd + j * nDegU + i, pSubCrv1->GetControlPoint( nInd)) ;
SetControlPoint( nSecondRowInd + nAddedSpan * nDegU + i, pSubCrv1->GetControlPoint( nInd)) ;
else
SetControlPoint( nSecondRowInd + j * nDegU + i, pSubCrv1->GetControlPoint( nInd), pSubCrv1->GetControlWeight( nInd)) ;
SetControlPoint( nSecondRowInd + nAddedSpan * nDegU + i, pSubCrv1->GetControlPoint( nInd), pSubCrv1->GetControlWeight( nInd)) ;
}
if ( ! bRep0)
++ nCrv1 ;
++ nAddedSpan ;
}
}