EgtGeomKernel :

- corretta la ruled con bezier in modalità MinDistPlus.
This commit is contained in:
Daniele Bariletti
2024-07-09 13:04:48 +02:00
parent 7a66ad27d8
commit bc3c1e377e
+91 -58
View File
@@ -3943,7 +3943,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
}
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 il match del punto della U1 è uguale al punto a cui ero arrivato sulla U0 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 ) {
@@ -4192,7 +4192,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
++c ;
continue ;
}
else if ( dParam > nSpanU1 + EPS_SMALL ) {
else if ( dParam > nSpanU1 - EPS_SMALL ) {
vbRep0[c] = nAtEnd1 == 0 ? false : true ;
vbRep0.back() = true ;
++ nAtEnd1 ;
@@ -4210,8 +4210,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
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 ;
@@ -4223,24 +4221,33 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
int nCase = 0 ;
for ( int j = 0 ; j < int( vMatch1.size()) ; ++j) {
if ( abs(vMatch1[j].second - (c + 1)) < EPS_SMALL) {
++nRep1 ;
// capisco se il punto è rep o se lo è il suo successivo
if( j + 1 < dParam)
nCase = 1 ;
else
nCase = 2 ;
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
bool bFoundMatch = false ;
for ( int z = int( vMatch1[j].second) ; z < int( vdMatch0.size()) ; ++z) {
if ( abs( vdMatch0[z] - ( j + 1 )) < EPS_SMALL ) {
bFoundMatch = true ;
break ;
}
}
if ( ! bFoundMatch) {
++nRep1 ;
// capisco se il punto è rep o se lo è il suo successivo
if( j + 1 < 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) ;
plU1.GetFirstPoint( ptP1) ;
c = 0 ;
dLastParamMatch = 0 ;
ptLastPointMatch = ptP1 ;
@@ -4248,7 +4255,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
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 ;
@@ -4278,11 +4284,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
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 ;
@@ -4290,45 +4291,39 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
}
vdSplit1.push_back( dParam) ;
// verifico se ho un match per questo punto
// in tal caso vuol dire che sto creando una ripetizione nRep1
// in tal caso vuol dire che sto creando una ripetizione nRep0
int nCase = 0 ;
for ( int j = 0 ; j < int( vdMatch0.size()) ; ++j) {
if ( abs(vdMatch0[j] - (c + 1)) < EPS_SMALL) {
++nRep0 ;
// capisco se il punto è rep o se lo è il suo successivo
if( j + 1 < dParam)
nCase = 1 ;
else
nCase = 2 ;
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
bool bFoundMatch = false ;
for ( int z = int( vdMatch0[j]) ; z < int( vMatch1.size()) ; ++z) {
if ( abs( vMatch1[z].second - ( j + 1 )) < EPS_SMALL ) {
bFoundMatch = true ;
break ;
}
}
if ( ! bFoundMatch) {
++nRep0 ;
// capisco se il punto è rep o se lo è il suo successivo
if( j + 1 < dParam)
nCase = 1 ;
else
nCase = 2 ;
}
break ;
}
}
vnAddedOrNextIsRep1.push_back( nCase) ;
}
//nSpanU0 = pCrvU0->GetCurveCount() ;
++c ;
}
//// 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 ;
//}
// applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep
int nUnit = int( vdSplit0.back()) ;
int nUnit = 0 ;
if ( ! vdSplit0.empty())
nUnit = int( vdSplit0.back()) ;
for ( int z = int( vdSplit0.size() - 1) ; z >= 0 ; --z) {
double dSplit = vdSplit0[z] ;
int nSplit = int( dSplit) ;
@@ -4340,13 +4335,19 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
nUnit = nSplit ;
pCrvU1->AddJoint( dSplit) ;
switch( vnAddedOrNextIsRep0[z]) {
case 0 : vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ;
case 0 : if( vbRep1[nSplit])
++ nRep1 ;
vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ; break ; // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
case 1 : vbRep1.insert( vbRep1.begin() + nSplit, true) ; break ;
case 2 : vbRep1[nSplit] = true ;
case 2 : if ( vbRep1[nSplit])
--nRep1 ;
else
vbRep1[nSplit] = true ;
vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ;
}
}
nUnit = int( vdSplit1.back()) ;
if( ! vdSplit1.empty())
nUnit = int( vdSplit1.back()) ;
for ( int z = int( vdSplit1.size() - 1) ; z >= 0 ; --z) {
double dSplit = vdSplit1[z] ;
int nSplit = int( dSplit) ;
@@ -4358,16 +4359,47 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
nUnit = nSplit ;
pCrvU0->AddJoint( dSplit) ;
switch( vnAddedOrNextIsRep1[z]) {
case 0 : vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ;
case 0 : if( vbRep0[nSplit])
++ nRep0 ;
vbRep0.insert( vbRep0.begin() + nSplit, vbRep0[nSplit]) ; break ; // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
case 1 : vbRep0.insert( vbRep0.begin() + nSplit, true) ; break ;
case 2 : vbRep0[nSplit] = true ;
vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ;
case 2 : if( vbRep0[nSplit])
-- nRep0 ;
else
vbRep0[nSplit] = true ;
vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ;
}
}
nSpanU0 = pCrvU0->GetCurveCount() ;
nSpanU1 = pCrvU1->GetCurveCount() ;
//aggiusto i vettori delle ripetizioni in modo in modo che non arrivino mai ad essere contemporaneamente true
int nAddedSpan = 0 ;
int nCrv0 = 0 ;
int nCrv1 = 0 ;
while ( nAddedSpan < nSpanU0 + nAtStart0 + nAtEnd0 + nRep1) {
if ( nCrv0 >= nSpanU0)
nCrv0 = nSpanU0 - 1;
if ( nCrv1 >= nSpanU1)
nCrv1 = nSpanU1 - 1;
bool bRep0 = vbRep0[nCrv0] ;
bool bRep1 = vbRep1[nCrv1] ;
if ( bRep0 && bRep1 ) {
vbRep0[nCrv0] = false ;
bRep0 = false ;
vbRep1[nCrv1] = false ;
bRep1 = false ;
-- nRep0 ;
-- nRep1 ;
}
if ( ! bRep0)
++ nCrv1 ;
if ( ! bRep1)
++ nCrv0 ;
++nAddedSpan ;
}
// 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 ;
@@ -4377,9 +4409,9 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
// aggiungo i punti di controllo scorrendo in contemporanea le due curve
int nAddedSpan = 0 ;
int nCrv0 = 0 ;
int nCrv1 = 0 ;
nAddedSpan = 0 ;
nCrv0 = 0 ;
nCrv1 = 0 ;
bool bLast0 = false ;
bool bLast1 = false ;
while ( nAddedSpan < nSpanU) {
@@ -4392,24 +4424,25 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
bLast1 = true ;
}
bool bRep0 = vbRep0[nCrv0] ;
bool bRep1 = vbRep1[nCrv1] ;
const ICurveBezier* pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( nCrv0)) ;
for( int i = nAddedSpan == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) {
int nInd = i ;
// 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])
if ( bRep1 || bLast0)
nInd = ! bLast0 ? 0 : nDegU ;
if ( ! bRat)
SetControlPoint( nAddedSpan * nDegU + i, pSubCrv0->GetControlPoint( nInd)) ;
else
SetControlPoint( nAddedSpan * nDegU + i, pSubCrv0->GetControlPoint( nInd), pSubCrv0->GetControlWeight( nInd)) ;
}
if ( ! vbRep1[nCrv1])
if ( ! bRep1)
++ nCrv0 ;
const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nCrv1)) ;
for( int i = nAddedSpan == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) {
int nInd = i ;
// 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)
if ( bRep0 || bLast1)
nInd = ! bLast1 ? 0 : nDegU ;
if ( ! bRat)
SetControlPoint( nSecondRowInd + nAddedSpan * nDegU + i, pSubCrv1->GetControlPoint( nInd)) ;