EgtGeomKernel :

- funzioni MakeUniform e OnWhichEdge per Bezier spostate da converter e exch3dm a metodi della classe Bezier.
This commit is contained in:
Daniele Bariletti
2024-04-10 16:17:39 +02:00
parent 32a0e1d2b5
commit 5013fc2b6c
2 changed files with 174 additions and 0 deletions
+172
View File
@@ -3176,4 +3176,176 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
}
}
return pCrvCompo ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::MakeUniform( ISurfFlatRegion** sfr, DBLVECTOR& vU0, DBLVECTOR& vV0, double dScaleU, double dScaleV, bool& bRescaled, bool bRetry) const
{
// la superficie in input arriva già scalata
bool bRescaledU = false ;
bool bRescaledV = false ;
int nSpanU = 1, nSpanV = 1 ;
PtrOwner<ISurfFlatRegion> sfr_rescaled( CreateSurfFlatRegion()) ;
for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
// vettore dei nodi
DBLVECTOR vU ;
int nExtraKnots = 0 ;
if ( nDir == 0) {
if ( m_nDegU > 1) {
nExtraKnots = m_nDegU - 1 ;
}
for ( int i = nExtraKnots ; i < int( vU0.size()) - nExtraKnots ; ++i ) {
double dKnot = vU0[i] * SBZ_TREG_COEFF ;
// lo aggiungo solo se è diverso dal precedente
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
vU.push_back( dKnot) ;
}
}
else if ( nDir == 1 ) {
if ( m_nDegV > 1) {
nExtraKnots = m_nDegV - 1 ;
}
for ( int i = nExtraKnots ; i < int( vV0.size()) - nExtraKnots ; ++i ) {
double dKnot = vV0[i] * SBZ_TREG_COEFF ;
// lo aggiungo solo se è diverso dal precedente
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
vU.push_back( dKnot) ;
}
}
nDir == 0 ? nSpanU = (int)vU.size() - 1 : nSpanV = (int)vU.size() - 1 ;
// controllo se il vettore dei nodi è uniforme
int a = 0, b = 1 ;
double d0 = abs( vU[b] - vU[a]), d1 = d0 ;
// il vettore è uniforme quando la distanza tra nodi consecutivi è sempre zero o un valore costante
while ( b < (int)vU.size() && ( ( d1 < d0 + EPS_SMALL && d1 > d0 - EPS_SMALL) || d1 < EPS_SMALL)) {
a = b ;
++b ;
if ( b < (int)vU.size())
d1 = abs( vU[b] - vU[a]) ;
}
if ( b != (int)vU.size()) {
nDir == 0 ? bRescaledU = true : bRescaledV = true ;
sfr_rescaled.Set( CreateSurfFlatRegion()) ;
if ( IsNull( sfr_rescaled))
return false ;
for ( int p = 0 ; p < (int)vU.size() - 1 ; ++p) {
PtrOwner<ISurfFlatRegion> pSfr_copy( (*sfr)->Clone()) ;
if ( IsNull( pSfr_copy))
return false ;
double dLenStrip = abs( vU[p+1] - vU[p]) ;
if ( dLenStrip < EPS_SMALL)
continue ;
// creo la maschera per tagliare la superficie originale e ottenere una striscia
PtrOwner<ISurfFlatRegion> pSfrTrim( CreateSurfFlatRegion()) ;
// ricavo la maschera del trim, con cui poi farò l'intersezione con la sfr iniziale
Vector3d vtTrim ;
if ( nDir == 0) {
pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenStrip, dScaleV + 2)) ;
vtTrim.Set( abs(vU[p] - vU.front()), - 1, 0) ;
}
else{
pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU + 2, dLenStrip)) ;
vtTrim.Set( - 1, abs(vU[p] - vU.front()), 0) ;
}
pSfrTrim->Translate( vtTrim) ;
if ( ! pSfr_copy->Intersect( *pSfrTrim))
return false ;
// aggiungo la nuova striscia solo se è valida
if ( pSfr_copy->IsValid() ) {
if ( nDir == 0)
pSfr_copy->Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
else
pSfr_copy->Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
// prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo
Point3d pt ;
nDir == 0 ? pt.Set( abs(vU[p] - vU.front()), 0, 0) : pt.Set( 0,abs(vU[p] - vU.front()), 0) ;
if ( nDir == 0)
pt.Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
else
pt.Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
Vector3d vtJoin ;
if ( nDir == 0)
vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ;
else
vtJoin.Set( 0, p * SBZ_TREG_COEFF - pt.y, 0) ;
pSfr_copy->Translate( vtJoin) ;
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
if ( bRetry)
pSfr_copy->Offset( 10*EPS_SMALL,ICurve::OFF_FILLET) ; // OFFSET
if ( sfr_rescaled->IsValid()) {
if ( ! sfr_rescaled->Add( *pSfr_copy))
return false ;
}
else
sfr_rescaled.Set( pSfr_copy) ;
}
}
if ( nDir == 0) {
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
if ( sfr_rescaled->IsValid()) {
if ( bRetry)
sfr_rescaled->Offset( -10*EPS_SMALL,ICurve::OFF_FILLET) ; //contro OFFSET
*sfr = Release( sfr_rescaled) ;
}
}
else
dScaleV = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
}
}
if ( ! IsNull( sfr_rescaled) && sfr_rescaled->IsValid()) {
if ( bRetry)
sfr_rescaled->Offset( -10*EPS_SMALL,ICurve::OFF_FILLET) ; // contro OFFSET
*sfr = Release( sfr_rescaled) ;
}
if ( ! bRescaledU && ! bRescaledV)
( *sfr)->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;
else if ( bRescaledU && ! bRescaledV)
( *sfr)->Scale( GLOB_FRM, 1, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;
else if ( ! bRescaledU && bRescaledV)
( *sfr)->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, 1, 1) ;
bRescaled = bRescaledU || bRescaledV ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::OnWhichEdge( double u0, double u1, double v0, double v1, int& nEdge, Point3d ptToAssign) const
{
Point3d ptTR( u1, v1) ;
Point3d ptTl( u0, v1) ;
Point3d ptBL( u0, v0) ;
Point3d ptBr( u1, v0) ;
double dEps = 0.1 ;
if ( AreSamePointEpsilon( ptToAssign, ptTR, dEps))
nEdge = 7 ;
else if ( AreSamePointEpsilon( ptToAssign, ptTl, dEps))
nEdge = 4 ;
else if ( AreSamePointEpsilon( ptToAssign, ptBL, dEps))
nEdge = 5 ;
else if ( AreSamePointEpsilon( ptToAssign, ptBr, dEps))
nEdge = 6 ;
else if ( ptToAssign.x > ptBL.x - dEps && ptToAssign.x < ptTR.x + dEps && abs( ptToAssign.y - ptTR.y) < dEps)
nEdge = 0 ;
else if ( ptToAssign.y > ptBL.y - dEps && ptToAssign.y < ptTR.y + dEps && abs( ptToAssign.x - ptBL.x) < dEps)
nEdge = 1 ;
else if ( ptToAssign.x > ptBL.x - dEps && ptToAssign.x < ptTR.x + dEps && abs( ptToAssign.y - ptBL.y) < dEps)
nEdge = 2 ;
else if ( ptToAssign.y > ptBL.y - dEps && ptToAssign.y < ptTR.y + dEps && abs( ptToAssign.x - ptTR.x) < dEps)
nEdge = 3 ;
else
return false ;
return true ;
}
+2
View File
@@ -138,6 +138,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ;
bool MakeUniform( ISurfFlatRegion** sfr, DBLVECTOR& vU, DBLVECTOR& vV, double dScaleU, double dScaleV, bool& bRescaled, bool bRetry) const override ;
bool OnWhichEdge( double u0, double u1, double v0, double v1, int& nEdge, Point3d ptToAssign) const override ;
public : // IGeoObjRW
int GetNgeId( void) const override ;