EgtExecutor :

- aggiunte funzioni per l'approssimaizone di curve di bezier
- aggiunta la possibilità di scegliere il grado nella conversione da curva generica a curva di bezier.
This commit is contained in:
Daniele Bariletti
2024-08-26 16:52:12 +02:00
parent e463ba5500
commit ea83cb985d
6 changed files with 226 additions and 7 deletions
+181
View File
@@ -2990,5 +2990,186 @@ ExeCurveBezierDecreaseDegree( int nCrvId, double dTol)
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExeCurveBezierApproxToNonRat( int nCrvId, double dTol)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
// recupero la curva
const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ;
if ( pCrv == nullptr)
return false ;
//// recupero il riferimento della curva
//Frame3d frCrv ;
//if ( ! pGeomDB->GetGlobFrame( nCrvId, frCrv))
// return GDB_ID_NULL ;
// controllo che il tipo sia giusto
if( pCrv->GetType() != CRV_BEZIER) {
if( pCrv->GetType() != CRV_COMPO)
return false ;
else {
const ICurveComposite* pCC = GetCurveComposite( pCrv) ;
for ( int i = 0 ; i < pCC->GetCurveCount() ; ++i) {
const ICurve* pSubCrv = pCC->GetCurve( i) ;
if( pSubCrv->GetType() != CRV_BEZIER)
return false ;
}
}
}
bool bOk = true ;
if( pCrv->GetType() == CRV_BEZIER) {
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
if( ! pCrvBez->IsRational())
return true ;
// approssimo la curva con una corrispettiva non razionale
PtrOwner<ICurveBezier> pCrvBezierNew ( pCrvBez->Clone()) ;
bOk = bOk && pCrvBezierNew->MakeNonRational( dTol) ;
PtrOwner<ICurve> pCrvNew ;
if ( ! bOk) {
pCrvNew.Set( ApproxBezierWithCubics( pCrvBezierNew, dTol)) ;
bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ;
}
else
pCrvNew.Set( Release( pCrvBezierNew)) ;
bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ;
Vector3d vtExtr ;
if ( bOk && pCrv->GetExtrusion( vtExtr))
pCrvNew->SetExtrusion( vtExtr) ;
double dThick = 0 ;
if ( bOk && pCrv->GetThickness( dThick))
pCrvNew->SetThickness(dThick) ;
// sostituisco la vecchia curva con la nuova
bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCrvNew)) ;
}
else {
const ICurveComposite* pCC = GetCurveComposite( pCrv) ;
PtrOwner<ICurveComposite> pCCNew( CreateCurveComposite()) ;
for( int i = 0 ; i < pCC->GetCurveCount() ; ++i) {
const ICurveBezier* pCrvBez = GetCurveBezier( pCC->GetCurve( i)) ;
if( ! pCrvBez->IsRational()) {
continue ;
}
// approssimo la curva con una corrispettiva non razionale
PtrOwner<ICurveBezier> pCrvBezierNew ( pCrvBez->Clone()) ;
bOk = bOk && pCrvBezierNew->MakeNonRational( dTol) ;
PtrOwner<ICurve> pCrvNew ;
if ( ! bOk) {
pCrvNew.Set( ApproxBezierWithCubics( pCrvBezierNew, dTol)) ;
bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ;
}
else
pCrvNew.Set( Release( pCrvBezierNew)) ;
bOk = bOk && ! IsNull( pCrvNew) && pCrvNew->IsValid() ;
Vector3d vtExtr ;
if ( bOk && pCrv->GetExtrusion( vtExtr))
pCrvNew->SetExtrusion( vtExtr) ;
double dThick = 0 ;
if ( bOk && pCrv->GetThickness( dThick))
pCrvNew->SetThickness(dThick) ;
if( bOk)
pCCNew->AddCurve( Release(pCrvNew)) ;
else
break ;
}
// sostituisco la vecchia curva con la nuova
bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCCNew)) ;
}
ExeSetModified() ;
if ( IsCmdLog()) {
string sLua = "EgtCurveBezierApproxToNonRat(" + ToString( nCrvId) + ", "
+ ToString( dTol) + ")"
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExeCurveBezierApproxWithCubicBeziers( int nCrvId, double dTol)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
// recupero la curva
const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ;
if ( pCrv == nullptr)
return false ;
// controllo che il tipo sia giusto
if( pCrv->GetType() != CRV_BEZIER) {
if( pCrv->GetType() != CRV_COMPO)
return false ;
else {
const ICurveComposite* pCC = GetCurveComposite( pCrv) ;
for ( int i = 0 ; i < pCC->GetCurveCount() ; ++i) {
const ICurve* pSubCrv = pCC->GetCurve( i) ;
if( pSubCrv->GetType() != CRV_BEZIER)
return false ;
}
}
}
// converto in bezier cubiche
bool bOk = true ;
if( pCrv->GetType() == CRV_BEZIER) {
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
// approssimo la curva con una serie di bezier
PtrOwner<ICurve> pCrvBezierNew ( ApproxBezierWithCubics( pCrvBez, dTol)) ;
bOk = bOk && ! IsNull( pCrvBezierNew) && pCrvBezierNew->IsValid() ;
Vector3d vtExtr ;
if ( bOk && pCrv->GetExtrusion( vtExtr))
pCrvBezierNew->SetExtrusion( vtExtr) ;
double dThick = 0 ;
if ( bOk && pCrv->GetThickness( dThick))
pCrvBezierNew->SetThickness(dThick) ;
// sostituisco la vecchia curva con la nuova
bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCrvBezierNew)) ;
}
else {
const ICurveComposite* pCC = GetCurveComposite( pCrv) ;
PtrOwner<ICurveComposite> pCCNew( CreateCurveComposite()) ;
for( int i = 0 ; i < pCC->GetCurveCount() ; ++i) {
const ICurveBezier* pCrvBez = GetCurveBezier( pCC->GetCurve( i)) ;
if( ! pCrvBez->IsRational()) {
continue ;
}
// approssimo la curva con una serie di bezier
PtrOwner<ICurve> pCrvBezierNew ( ApproxBezierWithCubics( pCrvBez, dTol)) ;
bOk = bOk && ! IsNull( pCrvBezierNew) && pCrvBezierNew->IsValid() ;
Vector3d vtExtr ;
if ( bOk && pCrv->GetExtrusion( vtExtr))
pCrvBezierNew->SetExtrusion( vtExtr) ;
double dThick = 0 ;
if ( bOk && pCrv->GetThickness( dThick))
pCrvBezierNew->SetThickness(dThick) ;
if( bOk)
pCCNew->AddCurve( Release(pCrvBezierNew)) ;
else
break ;
}
// sostituisco la vecchia curva con la nuova
bOk = bOk && pGeomDB->ReplaceGeoObj( nCrvId, Release( pCCNew)) ;
}
ExeSetModified() ;
if ( IsCmdLog()) {
string sLua = "EgtCurveBezierApproxWithCubicBeziers(" + ToString( nCrvId) + ", "
+ ToString( dTol) + ")"
" -- Ok=" + ToString( bOk) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
return bOk ;
}