EgtMachKernel :
- entrate rese coerenti tra i vari step ( SpiralIn/Out) - rimozione del ricalcolo dei percorsi nel caso di geometria uguale tra gli step (SpiralIn/Out).
This commit is contained in:
Binary file not shown.
+323
-246
@@ -2492,7 +2492,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
|
||||
bool bUhAboveRaw = ! m_bAboveHead &&
|
||||
GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
|
||||
m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
|
||||
if ( bAhUnderRaw || bUhAboveRaw)
|
||||
if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab)
|
||||
dStElev = max( dStElev, j * dStep) ;
|
||||
dStElev -= ( ptP1 - ptStart) * vtExtr ;
|
||||
// se ottimizzata e attacco nel grezzo
|
||||
@@ -4357,8 +4357,8 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
|
||||
bool bUhAboveRaw = ! m_bAboveHead &&
|
||||
GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
|
||||
m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
|
||||
//if ( bAhUnderRaw || bUhAboveRaw)
|
||||
dStElev = max( dStElev, j * dStep) ;
|
||||
if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab)
|
||||
dStElev = max( dStElev, j * dStep) ;
|
||||
dStElev -= ( ptP1 - ptStart) * vtExtr ;
|
||||
// se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
|
||||
if ( GetLeadInType() == POCKET_LI_ZIGZAG ||
|
||||
@@ -4665,25 +4665,41 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
|
||||
|
||||
Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente
|
||||
Vector3d vtMidOutPrec ; // vettore direzione di uscite precedente
|
||||
bool bMidOutPrec ; // flag per entrata da fuori dal grezzo precedente
|
||||
bool bMidOutPrec ; // flag per entrata precedente da fuori dal grezzo
|
||||
BOOLVECTOR vbOutStartPrec ; // flags per effettiva entrata precedente da fuori dal grezzo
|
||||
BOOLVECTOR vbForceOutStartPrec ; // flags per forzatura dell'entrata precedente da fuori dal grezzo
|
||||
ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente
|
||||
ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
|
||||
INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
|
||||
int nOffs_act = 0 ;
|
||||
|
||||
// ciclo su tutti gli step
|
||||
for ( int j = 1 ; j <= nStep ; ++ j) {
|
||||
|
||||
// se superificie non valida, salto allo step successivo
|
||||
if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) {
|
||||
if ( IsNull( vSrfSliced[j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) {
|
||||
vSrfSliced[j-1].Set( pSrfChunk->Clone()) ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
// la superificie che lavoro è quella ottenuta in precedenza allo step j-esimo
|
||||
PtrOwner<ISurfFlatRegion> pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j - 1])) ;
|
||||
PtrOwner<ISurfFlatRegion> pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j-1])) ;
|
||||
if ( IsNull( pSrfFinal))
|
||||
return false ;
|
||||
|
||||
nOffs_act = 0 ; // reset indice dei vettori per step precedenti
|
||||
if ( vbChangedPrec[j-1]) {
|
||||
// se lo step attuale è cambiato rispetto al precedente -> Flush info step precedente
|
||||
vMCrv_step_prec.clear() ;
|
||||
vRCrv_step_prec.clear() ;
|
||||
vnRegTot_prec.clear() ;
|
||||
vbOutStartPrec.clear() ;
|
||||
vbForceOutStartPrec.clear() ;
|
||||
}
|
||||
|
||||
for ( int cc = 0 ; cc < ( int)pSrfFinal->GetChunkCount() ; ++ cc) { // per ogni suo chunk cc-esimo...
|
||||
// il numero di chunk dopo aver intersecato e proiettato con/il grezzo può cambiare
|
||||
|
||||
// il numero di chunk dopo aver intersecato e proiettato può cambiare
|
||||
|
||||
// essendo una svuotatura a spirale, facendo il primo offset del chunk cc-esimo potrei ottenere
|
||||
// ulteriori chunks ( ad esempio se la superificie presenta delle parti molto strette)
|
||||
// MAX_REGS = 50 -> # massimo di Chunks nuovi accettati
|
||||
@@ -4699,7 +4715,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
|
||||
PtrOwner<ISurfFlatRegion> pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunkFinal)) ;
|
||||
if ( IsNull( pSrfLeanInOut))
|
||||
return false ;
|
||||
|
||||
|
||||
// calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine
|
||||
PtrOwner<ICurveComposite> pMCrv( CreateCurveComposite()) ; // percorso di svuotatura
|
||||
PtrOwner<ICurveComposite> pRCrv( CreateCurveComposite()) ; // percorso di ritorno
|
||||
@@ -4707,142 +4723,165 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
|
||||
m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se lucidatura con epicicli
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// verifico che i parametri lucidatura siano sensati
|
||||
if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
// modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli
|
||||
m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
|
||||
|
||||
int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale
|
||||
bool bOutStart ; // flag per entrata da fuori per lo step attuale
|
||||
bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale
|
||||
|
||||
// NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente
|
||||
// ( non c'è bisogno di ricalcolare tutti i percorsi)
|
||||
if ( ! vbChangedPrec[j-1] && j != 1) {
|
||||
if ( nOffs_act > ( int)vMCrv_step_prec.size() - 1)
|
||||
break ;
|
||||
pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ;
|
||||
pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ;
|
||||
nRegTot = vnRegTot_prec[nOffs_act] ;
|
||||
bOutStart = vbOutStartPrec[nOffs_act] ;
|
||||
bForcedOutStart = vbForceOutStartPrec[nOffs_act] ;
|
||||
}
|
||||
|
||||
bool bOptimizedTrap = false ;
|
||||
|
||||
// cerco la curva originale del chunk cc-esimo ( PER CASI OTTIMIZZATI)
|
||||
int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk cc-esimo
|
||||
|
||||
// cerco la curva originale del chunk cc-esimo
|
||||
if (( int)vCrvOEWithFlags[j-1].size() == 1)
|
||||
nInd = 0 ;
|
||||
else {
|
||||
for ( int k = 0 ; k < ( int)vCrvOEWithFlags[j-1].size() ; ++ k) {
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[j-1][k], EPS_SMALL, ccClass)) {
|
||||
bool bIsThis = true ;
|
||||
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++ kk) {
|
||||
if ( ccClass[kk].nClass == CRVC_OUT)
|
||||
bIsThis = false ;
|
||||
}
|
||||
if ( bIsThis) {
|
||||
nInd = k ;
|
||||
break ;
|
||||
// se lucidatura con epicicli
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// verifico che i parametri lucidatura siano sensati
|
||||
if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
// modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli
|
||||
m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
|
||||
}
|
||||
|
||||
bool bOptimizedTrap = false ;
|
||||
|
||||
// cerco la curva originale del chunk cc-esimo ( PER CASI OTTIMIZZATI)
|
||||
int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk cc-esimo
|
||||
|
||||
// cerco la curva originale del chunk cc-esimo
|
||||
if (( int)vCrvOEWithFlags[j-1].size() == 1)
|
||||
nInd = 0 ;
|
||||
else {
|
||||
for ( int k = 0 ; k < ( int)vCrvOEWithFlags[j-1].size() ; ++ k) {
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[j-1][k], EPS_SMALL, ccClass)) {
|
||||
bool bIsThis = true ;
|
||||
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++ kk) {
|
||||
if ( ccClass[kk].nClass == CRVC_OUT)
|
||||
bIsThis = false ;
|
||||
}
|
||||
if ( bIsThis) {
|
||||
nInd = k ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
Point3d ptStart ; // punto iniziale del percorso
|
||||
Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile
|
||||
bool bMidOut ; // ammissibilità entrata da fuori
|
||||
nRegTot = nReg ;
|
||||
|
||||
// calcolo il percorso di svuotatura
|
||||
if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
|
||||
vCrvOEWithFlags[j-1][nInd], j == 1 ? true : vbChangedPrec[j-1],
|
||||
bOptimizedTrap))
|
||||
return false ;
|
||||
|
||||
// se terminate le regioni, esco
|
||||
if ( pMCrv->GetCurveCount() == 0)
|
||||
break ; // passo al chunk originale successivo
|
||||
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// riporto il diametro dell'utensile al valore originale
|
||||
m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
|
||||
// aggiorno i percorsi di svuotatura con epicicli
|
||||
if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// controlli per entrate da fuori al grezzo
|
||||
bOutStart = bMidOut ;
|
||||
if ( bOutStart && ! bOptimizedTrap) {
|
||||
if ( j != 1 && ! vbChangedPrec[j-1]) {
|
||||
vtMidOut = vtMidOutPrec ;
|
||||
bMidOut = bMidOutPrec ;
|
||||
ptStart = ptStartPrec ;
|
||||
}
|
||||
// calcolo il punto fuori per il LeadIn
|
||||
Point3d ptOut = ptStart + vtMidOut * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ;
|
||||
// memorizzo nel caso lo step successivo presenti la stessa geometria
|
||||
ptStartPrec = ptStart ;
|
||||
vtMidOutPrec = vtMidOut ;
|
||||
bMidOutPrec = bMidOut ;
|
||||
ptOut.Translate( vVtTrasl[j-1]) ; // lo traslo allo step corrente
|
||||
|
||||
double dStElev ;
|
||||
// controllo l'elevazione
|
||||
bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ;
|
||||
if ( bOutStart || m_bOpenOutRaw) {
|
||||
// aggiungo al ritorno l'uscita
|
||||
if ( pRCrv->GetCurveCount() == 0) {
|
||||
Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ;
|
||||
pRCrv->AddPoint( ptStart) ;
|
||||
}
|
||||
ptOut.Translate( -vVtTrasl[j-1]) ; // lo ritraslo sulla curva
|
||||
// aggiungo un tratto lineare all'inizio del percorso di svuotatura
|
||||
pMCrv->AddLine( ptOut, false) ;
|
||||
// assegno la sua Feed
|
||||
AssignFeedForLineInOut( pMCrv, true) ;
|
||||
// aggiungo un tratto lineare alla fine del percorso di svuotatura
|
||||
pRCrv->AddLine( ptOut, true) ;
|
||||
// assegno la sua Feed
|
||||
AssignFeedForLineInOut( pRCrv, false) ;
|
||||
}
|
||||
}
|
||||
|
||||
// calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato
|
||||
int nOutsideRaw = 0 ;
|
||||
if ( bOptimizedTrap) {
|
||||
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
|
||||
bOutStart = ( nOutsideRaw > 0) ;
|
||||
// imposto la Feed
|
||||
AssignFeedSpiralOpt( 1, pMCrv) ;
|
||||
AssignFeedForReturnPath( pRCrv) ;
|
||||
}
|
||||
|
||||
// verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro
|
||||
bForcedOutStart = ( bMidOut && m_bOpenOutRaw) ;
|
||||
|
||||
// se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
|
||||
if ( m_TParams.m_nType == TT_MILL_NOTIP && ! ( bOutStart || bForcedOutStart)) {
|
||||
if ( ! LeadInRawIsOk()) {
|
||||
m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo,
|
||||
// ad ogni step pari inverto la direzione della curva solamente se ho un solo chunk e la superificie successiva
|
||||
// non è cambiata
|
||||
if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1 && vSrfSliced[j-2]->GetChunkCount() == 1 && ! vbChangedPrec[j-1]
|
||||
&& ( j % 2 == 0))
|
||||
pMCrv->Invert() ;
|
||||
|
||||
// memorizzo le curve create e modificate per lo step successivo
|
||||
vMCrv_step_prec.emplace_back( pMCrv->Clone()) ;
|
||||
vRCrv_step_prec.emplace_back( pRCrv->Clone()) ;
|
||||
// memorizzo i Flag per le entrate
|
||||
vbOutStartPrec.push_back( bOutStart) ;
|
||||
vbForceOutStartPrec.push_back( bForcedOutStart) ;
|
||||
// memorizzo il numero delle regioni create dal primo Offset
|
||||
vnRegTot_prec.push_back( nRegTot) ;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
Point3d ptStart ; // punto iniziale del percorso
|
||||
Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile
|
||||
bool bMidOut ; // ammissibilità entrata da fuori
|
||||
int nRegTot = nReg ;
|
||||
|
||||
// calcolo il percorso di svuotatura
|
||||
if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
|
||||
vCrvOEWithFlags[j-1][nInd], j == 1 ? true : vbChangedPrec[j-1] , ptStartPrec,
|
||||
bOptimizedTrap))
|
||||
return false ;
|
||||
|
||||
// se terminate le regioni, esco
|
||||
if ( pMCrv->GetCurveCount() == 0)
|
||||
break ; // passo al chunk originale successivo
|
||||
++nReg ;
|
||||
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// riporto il diametro dell'utensile al valore originale
|
||||
m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
|
||||
// aggiorno i percorsi di svuotatura con epicicli
|
||||
if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// controlli per entrate da fuori al grezzo
|
||||
bool bOutStart = bMidOut ;
|
||||
if ( bOutStart && ! bOptimizedTrap) {
|
||||
if ( j != 1 && ! vbChangedPrec[j-1]) {
|
||||
vtMidOut = vtMidOutPrec ;
|
||||
bMidOut = bMidOutPrec ;
|
||||
ptStart = ptStartPrec ;
|
||||
}
|
||||
// calcolo il punto fuori per il LeadIn
|
||||
Point3d ptOut = ptStart + vtMidOut * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ;
|
||||
// memorizzo nel caso lo step successivo presenti la stessa geometria
|
||||
ptStartPrec = ptStart ;
|
||||
vtMidOutPrec = vtMidOut ;
|
||||
bMidOutPrec = bMidOut ;
|
||||
ptOut.Translate( vVtTrasl[j-1]) ; // lo traslo allo step corrente
|
||||
|
||||
//IGeoPoint3d* ptSSS( CreateGeoPoint3d()) ; ptSSS->Set( ptOut) ;
|
||||
//m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ptSSS) ;
|
||||
|
||||
double dStElev ;
|
||||
// controllo l'elevazione
|
||||
bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ;
|
||||
if ( bOutStart || m_bOpenOutRaw) {
|
||||
// aggiungo al ritorno l'uscita
|
||||
if ( pRCrv->GetCurveCount() == 0) {
|
||||
Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ;
|
||||
pRCrv->AddPoint( ptStart) ;
|
||||
}
|
||||
ptOut.Translate( -vVtTrasl[j-1]) ; // lo ritraslo sulla curva
|
||||
// aggiungo un tratto lineare all'inizio del percorso di svuotatura
|
||||
pMCrv->AddLine( ptOut, false) ;
|
||||
// assegno la sua Feed
|
||||
AssignFeedForLineInOut( pMCrv, true) ;
|
||||
// aggiungo un tratto lineare alla fine del percorso di svuotatura
|
||||
pRCrv->AddLine( ptOut, true) ;
|
||||
// assegno la sua Feed
|
||||
AssignFeedForLineInOut( pRCrv, false) ;
|
||||
}
|
||||
}
|
||||
|
||||
// calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato
|
||||
int nOutsideRaw = 0 ;
|
||||
if ( bOptimizedTrap) {
|
||||
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
|
||||
bOutStart = ( nOutsideRaw > 0) ;
|
||||
// imposto la Feed
|
||||
AssignFeedSpiralOpt( 1, pMCrv) ;
|
||||
AssignFeedForReturnPath( pRCrv) ;
|
||||
}
|
||||
|
||||
// verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro
|
||||
bool bForcedOutStart = ( bMidOut && m_bOpenOutRaw) ;
|
||||
|
||||
// se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
|
||||
if ( m_TParams.m_nType == TT_MILL_NOTIP && ! ( bOutStart || bForcedOutStart)) {
|
||||
if ( ! LeadInRawIsOk()) {
|
||||
m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
++ nOffs_act ;
|
||||
int nMaxInd = pMCrv->GetCurveCount() - 1 ;
|
||||
int nMaxRInd = pRCrv->GetCurveCount() - 1 ;
|
||||
|
||||
// se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo,
|
||||
// ad ogni step pari inverto la direzione della curva solamente se ho un solo chunk e la superificie successiva
|
||||
// non è cambiata
|
||||
if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1 && vSrfSliced[j-2]->GetChunkCount() == 1 && ! vbChangedPrec[j-1]
|
||||
&& ( j % 2 == 0))
|
||||
pMCrv->Invert() ;
|
||||
|
||||
double dCurrAffondamento = dDepth - dElev - vVtTrasl[j-1].Len() ;
|
||||
|
||||
// ciclo sulle curve elementari
|
||||
@@ -4884,7 +4923,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
|
||||
bool bUhAboveRaw = ! m_bAboveHead &&
|
||||
GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
|
||||
m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
|
||||
//if ( bAhUnderRaw || bUhAboveRaw )
|
||||
//if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab)
|
||||
//dStElev = max( dStElev, dCurrAffondamento) ;
|
||||
dStElev = max( dStElev, j * dStep) ;
|
||||
dStElev -= ( ptP1 - ptStart) * vtExtr ;
|
||||
@@ -5045,6 +5084,14 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
return false ;
|
||||
|
||||
Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente
|
||||
Vector3d vtMidOutPrec ; // vettore direzione di uscite precedente
|
||||
bool bMidOutPrec ; // flag per entrata precedente da fuori dal grezzo
|
||||
BOOLVECTOR vbOutStartPrec ; // flags per effettiva entrata precedente da fuori dal grezzo
|
||||
BOOLVECTOR vbForceOutStartPrec ; // flags per forzatura dell'entrata precedente da fuori dal grezzo
|
||||
ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente
|
||||
ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
|
||||
INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
|
||||
int nOffs_act = 0 ;
|
||||
|
||||
// ciclo su tutti gli step
|
||||
for ( int j = 1 ; j <= nStep ; ++ j) {
|
||||
@@ -5060,7 +5107,17 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
if( IsNull( pSrfFinal))
|
||||
return false ;
|
||||
|
||||
for( int cc = 0 ; cc < ( int)pSrfFinal->GetChunkCount() ; ++ cc) { // per ogni suo chunk cc-esimo...
|
||||
nOffs_act = 0 ; // reset indice dei vettori per step precedenti
|
||||
if ( vbChangedPrec[j-1]) {
|
||||
// se lo step attuale è cambiato rispetto al precedente -> Flush info step precedente
|
||||
vMCrv_step_prec.clear() ;
|
||||
vRCrv_step_prec.clear() ;
|
||||
vnRegTot_prec.clear() ;
|
||||
vbOutStartPrec.clear() ;
|
||||
vbForceOutStartPrec.clear() ;
|
||||
}
|
||||
|
||||
for ( int cc = 0 ; cc < ( int)pSrfFinal->GetChunkCount() ; ++ cc) { // per ogni suo chunk cc-esimo...
|
||||
|
||||
const int MAX_REGS = 50 ;
|
||||
int nReg = 0 ;
|
||||
@@ -5081,96 +5138,125 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se lucidatura con epicicli
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// verifico che parametri lucidatura siano sensati
|
||||
if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
// modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli
|
||||
m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
|
||||
|
||||
int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale
|
||||
bool bOutStart ; // flag per entrata da fuori per lo step attuale
|
||||
bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale
|
||||
|
||||
// NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente
|
||||
// ( non c'è bisogno di ricalcolare tutti i percorsi)
|
||||
if ( ! vbChangedPrec[j-1] && j != 1) {
|
||||
if ( nOffs_act > ( int)vMCrv_step_prec.size() - 1)
|
||||
break ;
|
||||
pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ;
|
||||
pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ;
|
||||
nRegTot = vnRegTot_prec[nOffs_act] ;
|
||||
bOutStart = vbOutStartPrec[nOffs_act] ;
|
||||
bForcedOutStart = vbForceOutStartPrec[nOffs_act] ;
|
||||
}
|
||||
|
||||
bool bOptimizedTrap = false ;
|
||||
|
||||
int nInd = 0 ;
|
||||
|
||||
// cerco la curva originale del chunk cc-esimo ( PER CASI OTTIMIZZATI)
|
||||
if (( int)vCrvOEWithFlags[j-1].size() == 1)
|
||||
nInd = 0 ;
|
||||
else {
|
||||
for ( int k = 0 ; k < ( int)vCrvOEWithFlags[j-1].size() ; ++ k) {
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[j-1][k], EPS_SMALL, ccClass)) {
|
||||
bool bIsThis = true ;
|
||||
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++ kk) {
|
||||
if ( ccClass[kk].nClass == CRVC_OUT)
|
||||
bIsThis = false ;
|
||||
}
|
||||
if ( bIsThis) {
|
||||
nInd = k ;
|
||||
break ;
|
||||
// se lucidatura con epicicli
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// verifico che parametri lucidatura siano sensati
|
||||
if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
// modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli
|
||||
m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
|
||||
}
|
||||
|
||||
bool bOptimizedTrap = false ;
|
||||
|
||||
int nInd = 0 ;
|
||||
|
||||
// cerco la curva originale del chunk cc-esimo ( PER CASI OTTIMIZZATI)
|
||||
if (( int)vCrvOEWithFlags[j-1].size() == 1)
|
||||
nInd = 0 ;
|
||||
else {
|
||||
for ( int k = 0 ; k < ( int)vCrvOEWithFlags[j-1].size() ; ++ k) {
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[j-1][k], EPS_SMALL, ccClass)) {
|
||||
bool bIsThis = true ;
|
||||
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++ kk) {
|
||||
if ( ccClass[kk].nClass == CRVC_OUT)
|
||||
bIsThis = false ;
|
||||
}
|
||||
if ( bIsThis) {
|
||||
nInd = k ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point3d ptStart ;
|
||||
Vector3d vtMidOut ;
|
||||
bool bMidOut ;
|
||||
int nRegToT = nReg ;
|
||||
Point3d ptStart ;
|
||||
Vector3d vtMidOut ;
|
||||
bool bMidOut ;
|
||||
nRegTot = nReg ;
|
||||
|
||||
if ( ! CalcSpiral( pSrfChunkFinal, nRegToT, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
|
||||
vCrvOEWithFlags[j-1][nInd], vbChangedPrec[j-1], ptStartPrec, bOptimizedTrap))
|
||||
return false ;
|
||||
|
||||
// se terminate le regioni, esco
|
||||
if ( pMCrv->GetCurveCount() == 0)
|
||||
break ;
|
||||
++nReg ;
|
||||
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// riporto il diametro dell'utensile al valore originale
|
||||
m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
|
||||
// aggiorno i percorsi di svuotatura con epicicli
|
||||
if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
|
||||
vCrvOEWithFlags[j-1][nInd], vbChangedPrec[j-1], bOptimizedTrap))
|
||||
return false ;
|
||||
|
||||
// se terminate le regioni, esco
|
||||
if ( pMCrv->GetCurveCount() == 0)
|
||||
break ;
|
||||
|
||||
if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
|
||||
// riporto il diametro dell'utensile al valore originale
|
||||
m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
|
||||
// aggiorno i percorsi di svuotatura con epicicli
|
||||
if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo
|
||||
bool bOutStart = false ;
|
||||
int nOutsideRaw = 0 ;
|
||||
if ( bOptimizedTrap) {
|
||||
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
|
||||
bOutStart = ( nOutsideRaw > 0) ;
|
||||
AssignFeedSpiralOpt( 1, pMCrv) ;
|
||||
AssignFeedForReturnPath( pRCrv) ;
|
||||
}
|
||||
|
||||
// se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
|
||||
if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) {
|
||||
if ( ! LeadInRawIsOk()) {
|
||||
m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
|
||||
return false ;
|
||||
// nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo
|
||||
bOutStart = false ;
|
||||
int nOutsideRaw = 0 ;
|
||||
if ( bOptimizedTrap) {
|
||||
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
|
||||
bOutStart = ( nOutsideRaw > 0) ;
|
||||
AssignFeedSpiralOpt( 1, pMCrv) ;
|
||||
AssignFeedForReturnPath( pRCrv) ;
|
||||
}
|
||||
|
||||
// se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
|
||||
if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) {
|
||||
if ( ! LeadInRawIsOk()) {
|
||||
m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato)
|
||||
if ( ! bOptimizedTrap) {
|
||||
pMCrv->Invert() ;
|
||||
pRCrv->Invert() ;
|
||||
}
|
||||
|
||||
// inversione per caso ottimizzato
|
||||
if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1)
|
||||
pMCrv->Invert() ;
|
||||
|
||||
// memorizzo le curve create e modificate per lo step successivo
|
||||
vMCrv_step_prec.emplace_back( pMCrv->Clone()) ;
|
||||
vRCrv_step_prec.emplace_back( pRCrv->Clone()) ;
|
||||
// memorizzo i Flag per le entrate
|
||||
vbOutStartPrec.push_back( bOutStart) ;
|
||||
vbForceOutStartPrec.push_back( bForcedOutStart) ;
|
||||
// memorizzo il numero delle regioni create dal primo Offset
|
||||
vnRegTot_prec.push_back( nRegTot) ;
|
||||
|
||||
}
|
||||
|
||||
// inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato)
|
||||
if ( ! bOptimizedTrap) {
|
||||
pMCrv->Invert() ;
|
||||
pRCrv->Invert() ;
|
||||
}
|
||||
|
||||
++ nReg ;
|
||||
++ nOffs_act ;
|
||||
int nMaxInd = pMCrv->GetCurveCount() - 1 ;
|
||||
int nMaxRInd = pRCrv->GetCurveCount() - 1 ;
|
||||
|
||||
// ciclo sugli step
|
||||
if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1)
|
||||
pMCrv->Invert() ;
|
||||
// ciclo sulle curve elementari
|
||||
for ( int i = 0 ; i <= nMaxInd ; ++ i) {
|
||||
// curva corrente
|
||||
@@ -5189,7 +5275,7 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
Vector3d vtStart ;
|
||||
pCurve->GetStartDir( vtStart) ;
|
||||
// se primo step, approccio e affondo
|
||||
if ( j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1 || nRegToT > 1) {
|
||||
if ( j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1 || nRegTot > 1) {
|
||||
// determino inizio attacco
|
||||
if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) {
|
||||
m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
|
||||
@@ -5205,7 +5291,7 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
bool bUhAboveRaw = ! m_bAboveHead &&
|
||||
GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
|
||||
m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
|
||||
//if ( bAhUnderRaw || bUhAboveRaw || ( bOutStart && !m_bAboveHead))
|
||||
//if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab)
|
||||
dStElev = max( dStElev, j * dStep) ;
|
||||
dStElev -= ( ptP1 - ptStart) * vtExtr ;
|
||||
// se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
|
||||
@@ -5266,7 +5352,7 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
// se ultima entità
|
||||
if ( i == nMaxInd) {
|
||||
// se step intermedio
|
||||
if ( j < nStep && vSrfSliced[j-1]->GetChunkCount() == 1 && !vbChangedPrec[j] && nRegToT == 1) {
|
||||
if ( j < nStep && vSrfSliced[j-1]->GetChunkCount() == 1 && !vbChangedPrec[j] && nRegTot == 1) {
|
||||
// se necessario ritorno all'inizio
|
||||
if ( nMaxRInd >= 0) {
|
||||
// copio la curva di ritorno
|
||||
@@ -5324,7 +5410,7 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
|
||||
bool
|
||||
Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptStart, Vector3d& vtMidOut , bool& bMidOut,
|
||||
bool bSplitArcs,ICurveComposite* pMCrv, ICurveComposite* pRCrv, ICurveComposite* pCrvOEWithFlags,
|
||||
bool bChangedPrec, Point3d& ptStartPrec, bool& bOptimizedTrap)
|
||||
bool bChangedPrec, bool& bOptimizedTrap)
|
||||
{
|
||||
|
||||
// inizializzo i risultati
|
||||
@@ -5497,20 +5583,10 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
|
||||
else
|
||||
dOffR = dOffs ;
|
||||
|
||||
if ( bChangedPrec) {
|
||||
if ( SetBetterPtStartForSubChunks( vOffs[0], pSrfToWork, ptStart, vtMidOut, bMidOut, dOffR))
|
||||
vOffs[0]->GetStartPoint( ptNewStart) ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
double dULastStart ;
|
||||
Point3d ptStartPrec_Loc = ptStartPrec ;
|
||||
ptStartPrec_Loc.ToLoc( frPocket) ;
|
||||
vOffs[0]->GetParamAtPoint( ptStartPrec_Loc, dULastStart, 100 * EPS_SMALL) ;
|
||||
vOffs[0]->ChangeStartPoint( dULastStart) ;
|
||||
if ( SetBetterPtStartForSubChunks( vOffs[0], pSrfToWork, ptStart, vtMidOut, bMidOut, dOffR))
|
||||
vOffs[0]->GetStartPoint( ptNewStart) ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
|
||||
// se richiesta inversione
|
||||
for ( int i = 0 ; i < ( int)vOffs.size() && m_Params.m_bInvert ; ++ i)
|
||||
@@ -9911,27 +9987,28 @@ Pocketing::GetParamsAtEachStep( ISURFFRPOVECTOR& vSrfSliced, vector<ICRVCOMPOPOV
|
||||
pSrfToPock.Set( Release( pSrfNewChunk_c)) ;
|
||||
}
|
||||
}
|
||||
// 8) DISEGNO =========== TOGLIEREEEEEEEEEEEEEEEEEEEEEEEE ================================
|
||||
// PtrOwner<ISurfFlatRegion> pSrf_toDraw( CloneSurfFlatRegion( pSrfToPock)) ;
|
||||
// pSrf_toDraw->Translate( vtTrasl) ;
|
||||
// int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ;
|
||||
// m_pGeomDB->SetMaterial( a, Color( 0.0, 0.0, 1.0, 0.45)) ;
|
||||
// for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) {
|
||||
// for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) {
|
||||
// PtrOwner<ICurveComposite> pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ;
|
||||
// for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
|
||||
// int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ;
|
||||
// int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ;
|
||||
// int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ;
|
||||
// m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//// ===================================================================
|
||||
// continue ;
|
||||
|
||||
// adatto la superficie dello step corrente con la geometria del grezzo
|
||||
if ( AdaptSfrWithRaw( pSrfToPock, vtTrasl, pStmRaw, vCrvOEF, bChanged, j, dStep, 500 * EPS_SMALL, m_pStmShape)) {
|
||||
// // 8) DISEGNO =========== TOGLIEREEEEEEEEEEEEEEEEEEEEEEEE ================================
|
||||
//PtrOwner<ISurfFlatRegion> pSrf_toDraw( CloneSurfFlatRegion( pSrfToPock)) ;
|
||||
//pSrf_toDraw->Translate( vtTrasl) ;
|
||||
//int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ;
|
||||
//m_pGeomDB->SetMaterial( a, Color( 0.0, 0.0, 1.0, 0.45)) ;
|
||||
//for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) {
|
||||
// for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) {
|
||||
// PtrOwner<ICurveComposite> pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ;
|
||||
// for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
|
||||
// int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ;
|
||||
// int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ;
|
||||
// int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ;
|
||||
// m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//// ===================================================================
|
||||
|
||||
|
||||
vSrfSliced[j-1].Set( pSrfToPock->Clone()) ;
|
||||
// la superificie potrebbe non essere valida ( ad esempio se già svuotata tutta con un Tool in precedenza...)
|
||||
if ( ! IsNull( vSrfSliced[j-1])) {
|
||||
|
||||
+1
-1
@@ -207,7 +207,7 @@ class Pocketing : public Machining
|
||||
double dElev, double dOkStep, bool bSplitArcs) ;
|
||||
bool CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptStart, Vector3d& vtMidOut , bool& bMidOut,
|
||||
bool bSplitArcs,ICurveComposite* pMCrv, ICurveComposite* pRCrv, ICurveComposite* pCrvOEWithFlags,
|
||||
bool vbChangedPrec, Point3d& ptStartPrec, bool& bOptimizedTrap) ;
|
||||
bool vbChangedPrec, bool& bOptimizedTrap) ;
|
||||
bool CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, const int nIter,
|
||||
const int nOffsCount, const Vector3d& vtN, bool& bInsert) ;
|
||||
bool GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICURVEPOVECTOR& vLinks,
|
||||
|
||||
Reference in New Issue
Block a user