This commit is contained in:
Daniele Bariletti
2026-04-02 15:14:38 +02:00
3 changed files with 137 additions and 176 deletions
+137 -107
View File
@@ -1608,6 +1608,8 @@ AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvI
double dDiamJ = 1.05 * ( dDiam) + 2 * dOffR ;
if ( abs( PockParams.dMaxOpenEdgeRad) > 0)
dDiamJ = 100 * EPS_SMALL ;
else if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG || PockParams.nType == POCKET_CONFORMAL_ONEWAY)
dDiamJ = 1.05 * ( PockParams.dRad + dRad) + dOffR ;
// NB. 1.05 serve per eccedere leggermente, in modo che il contro-offset della prima curva di svuotatura presenti
// dei piccoli archi tra i chiusi e gli aperti ( in modo da svuotare bene lungo il chiuso)
@@ -1669,33 +1671,34 @@ AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvI
static bool
ChainCompoCurves( ICRVCOMPOPOVECTOR& vCrvCompo)
{
/* concatenamento delle curve composite */
if ( int( vCrvCompo.size() < 2))
// concatenamento delle curve composite
if ( ssize( vCrvCompo) < 2)
return true ;
// controllo validità delle curve
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i)
for ( int i = 0 ; i < ssize( vCrvCompo) ; ++ i) {
if ( IsNull( vCrvCompo[i]) || ! vCrvCompo[i]->IsValid())
return false ;
}
// preparo i dati per il concatenamento
bool bFirst = true ;
Point3d ptNear = ORIG ;
double dToler = 500 * EPS_SMALL ; // leggermente maggiore della tolleranza sulla superficie limite
double dToler = 500. * EPS_SMALL ; // leggermente maggiore della tolleranza sulla superficie limite
ChainCurves chainC ;
chainC.Init( false, dToler, int( vCrvCompo.size())) ;
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
chainC.Init( false, dToler, ssize( vCrvCompo)) ; // evito inversioni, le curve devono essere coerenti
for ( int i = 0 ; i < ssize( vCrvCompo) ; ++ i) {
// recupero i dati della curva necessari al concatenamento e li assegno
Point3d ptStart, ptEnd ;
Vector3d vtStart, vtEnd ;
if ( ! vCrvCompo[i]->GetStartPoint( ptStart) || ! vCrvCompo[i]->GetStartDir( vtStart) ||
! vCrvCompo[i]->GetEndPoint( ptEnd) || ! vCrvCompo[i]->GetEndDir( vtEnd))
return false ;
if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd))
if ( ! chainC.AddCurve( i + 1, ptStart, vtStart, ptEnd, vtEnd))
return false ;
// se prima curva, assegno inizio della ricerca
if ( bFirst) {
ptNear = ptStart + 10 * EPS_SMALL * vtStart ;
ptNear = ptStart + 10. * EPS_SMALL * vtStart ;
bFirst = false ;
}
}
@@ -1711,14 +1714,14 @@ ChainCompoCurves( ICRVCOMPOPOVECTOR& vCrvCompo)
if ( IsNull( pCrvCompo))
return false ;
// recupero le curve semplici e le inserisco nella curva composita
for ( size_t i = 0 ; i < vnInd.size() ; ++ i) {
for ( int i = 0 ; i < ssize( vnInd) ; ++ i) {
int nId = abs( vnInd[i]) - 1 ;
bool bInvert = ( vnInd[i] < 0) ;
// se necessario, la inverto
if ( bInvert)
vCrvCompo[nId]->Invert() ;
// la aggiungo alla curva composta
if ( ! pCrvCompo->AddCurve( ::Release( vCrvCompo[nId]), true, dToler))
if ( ! pCrvCompo->AddCurve( Release( vCrvCompo[nId]), true, dToler))
return false ;
}
// aggiorno il nuovo punto vicino
@@ -1742,15 +1745,18 @@ ChangePtStartForSinglePocketCurve( ICurveComposite* pCrvCompo, const PocketParam
return false ;
// se la curva è aperta
if ( ! pCrvCompo->IsClosed() && bInvertOpenCrv) {
// se non ho un punto di riferimento, allora non faccio nulla
if ( ! ptRef.IsValid())
return true ;
// se ho un punto di riferimento controllo quale estremo è più vicino
Point3d ptStart ; pCrvCompo->GetStartPoint( ptStart) ;
Point3d ptEnd ; pCrvCompo->GetEndPoint( ptEnd) ;
if ( SqDist( ptRef, ptEnd) < SqDist( ptRef, ptStart))
pCrvCompo->Invert() ;
if ( ! pCrvCompo->IsClosed()) {
// se richiesta inversione
if ( bInvertOpenCrv) {
// se non ho un punto di riferimento, non faccio nulla
if ( ! ptRef.IsValid())
return true ;
// se ho un punto di riferimento controllo quale estremo è più vicino
Point3d ptStart ; pCrvCompo->GetStartPoint( ptStart) ;
Point3d ptEnd ; pCrvCompo->GetEndPoint( ptEnd) ;
if ( SqDist( ptRef, ptEnd) < SqDist( ptRef, ptStart))
pCrvCompo->Invert() ;
}
}
// se la curva è chiusa
else {
@@ -1779,13 +1785,12 @@ static bool
AdvanceExtendCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const ISurfFlatRegion* pSfr,
const PocketParams& PockParams, bool bInvertOpenCrv)
{
// se non ho curve, allora non faccio nulla
if ( vCrvCompo.empty())
return true ;
// per ogni curva composita...
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
// per ogni curva
for ( int i = 0 ; i < ssize( vCrvCompo) ; ++ i) {
// controllo validità della curva
if ( IsNull( vCrvCompo[i]) || ! vCrvCompo[i]->IsValid())
return false ;
@@ -1807,7 +1812,7 @@ AdvanceExtendCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const ISurfFlatRegion* pSfr,
// scorro ogni singola curva composita
const int MAX_ITER = 4 ;
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vCrvCompo) ; ++ i) {
// controllo se la curva è chiusa o aperta
bool bIsClosed = vCrvCompo[i]->IsClosed() ;
// calcolo il numero massimo di punti in cui testare l'entrata da fuori
@@ -1858,10 +1863,10 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
// controllo se la superficie si annulla con un controOffset del raggio utensile
double dMaxOffs ;
pSfrChunk->GetMaxOffset( dMaxOffs) ;
if ( dMaxOffs > PockParams.dRad + 200 * EPS_SMALL)
if ( dMaxOffs > PockParams.dRad + 200. * EPS_SMALL)
return true ;
// controllo che il MaxOptSize sia coerente
if ( 2 * dMaxOffs > PockParams.dMaxOptSize + 10 * EPS_SMALL)
if ( 2. * dMaxOffs > PockParams.dMaxOptSize + 10. * EPS_SMALL)
return true ;
/*
@@ -1881,8 +1886,8 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
// recupero i tratti con proprietà uniformi
ICRVCOMPOPOVECTOR vpCrvs ;
GetHomogeneousParts( pCrvExtLoop, PockParams, vpCrvs) ;
if ( vpCrvs.size() > 1) { // unisco il primo e l'ultimo se estremi compatibili
// NB. GetHomogeneousParts() cambia il punto di inizio nel lato chiuso più lungo ( se presente)
// unisco il primo e l'ultimo se estremi compatibili
if ( ssize( vpCrvs) > 1) {
Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ;
Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ;
if ( AreSamePointApprox( ptS, ptE)) {
@@ -1896,15 +1901,15 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
// controllo se il loop Esterno è uniforme ( quindi tutto chiuso o tutto aperto)
bool bExtAllClose = false ;
bool bExtAllOpen = false ;
if ( int( vpCrvs.size()) == 1) {
if ( ssize( vpCrvs) == 1) {
if ( vpCrvs[0]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
bExtAllClose = true ;
else
bExtAllOpen = true ;
}
// NB. Se regione estena tutta chiusa o aperta e senza isole... allora non faccio nulla ( es caso trapezi)
// NB. Se regione estena tutta chiusa o aperta e senza isole, non faccio nulla ( es. caso trapezi)
// Se tutta chiusa -> Chunk non svuotabile, il contro-offset del raggio utensile annulla la regione
// Se tutta aperta -> La regione è definita mediante Offset esterno del contorno aperto
// Se tutta aperta -> La regione è definita mediante Offset esterno del contorno aperto
if ( ( bExtAllClose || bExtAllOpen) && ! bHasIslands)
return true ;
// Se il contorno esterno è misto -> non devo avere isole
@@ -1916,9 +1921,9 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
// scorro i chiusi e sottraggo la regione da loro creata mediante l'utensile
// NB. Queste curve sono orientate in maniera corretta
ICRVCOMPOPOVECTOR vCrvCompoRes_tmp ; // salvo il vettore di curve offsettate del raggio utensile
ICRVCOMPOPOVECTOR vCrvCompoResTmp ; // salvo il vettore di curve offsettate del raggio utensile
Voronoi myVRONI ;
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
// se tratto chiuso
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
myVRONI.AddCurve( vpCrvs[i]) ;
@@ -1926,8 +1931,8 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
// offset delle parti chiuse
ICURVEPOVECTOR vCrvVroniOffs ;
myVRONI.CalcOffset( vCrvVroniOffs, - PockParams.dRad - PockParams.dRadialOffset + EPS_SMALL, ICurve::OFF_FILLET) ;
for ( int i = 0 ; i < int( vCrvVroniOffs.size()) ; ++ i)
vCrvCompoRes_tmp.emplace_back( ConvertCurveToComposite( Release( vCrvVroniOffs[i]))) ;
for ( int i = 0 ; i < ssize( vCrvVroniOffs) ; ++ i)
vCrvCompoResTmp.emplace_back( ConvertCurveToComposite( Release( vCrvVroniOffs[i]))) ;
/*
Casi gestiti :
@@ -1944,22 +1949,22 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
bool bValidIslands = true ; // flag per isole tutte uniformi
for ( int i = 1 ; i < pSfrChunk->GetLoopCount( 0) && bValidIslands ; ++ i) {
// controllo uniformità dell'isola
int nCurrTmpProp = -1 ;
int nPrecTmpProp = -1 ;
int nCurrTmpProp = TEMP_PROP_INVALID ;
int nPrecTmpProp = TEMP_PROP_INVALID ;
bool bIsMixed = false ;
PtrOwner<ICurveComposite> pCrvIsl( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, i))) ;
if ( IsNull( pCrvIsl) || ! pCrvIsl->IsValid())
return false ;
for ( int u = 0 ; u < pCrvIsl->GetCurveCount() && ! bIsMixed ; ++ u) {
pCrvIsl->GetCurveTempProp( u, nCurrTmpProp, 0) ;
bIsMixed = ( u != 0 && nCurrTmpProp != nPrecTmpProp) ;
for ( int nU = 0 ; nU < pCrvIsl->GetCurveCount() && ! bIsMixed ; ++ nU) {
pCrvIsl->GetCurveTempProp( nU, nCurrTmpProp, 0) ;
bIsMixed = ( nU != 0 && nCurrTmpProp != nPrecTmpProp) ;
nPrecTmpProp = nCurrTmpProp ;
}
// se proprità non uniformi -> tutta chiusa ( isole non uniformi non sono definite)
if ( bIsMixed) {
for ( int u = 0 ; u < pCrvIsl->GetCurveCount() ; ++ u)
pCrvIsl->SetTempProp( u, TEMP_PROP_CLOSE_EDGE) ;
nCurrTmpProp = 0 ; // aggiorno il Flag
for ( int nU = 0 ; nU < pCrvIsl->GetCurveCount() ; ++ nU)
pCrvIsl->SetTempProp( nU, TEMP_PROP_CLOSE_EDGE) ;
nCurrTmpProp = TEMP_PROP_CLOSE_EDGE ; // aggiorno il Flag
}
// 2) e 3)
bValidIslands = ( ( nCurrTmpProp == TEMP_PROP_CLOSE_EDGE && bExtAllOpen) ||
@@ -1973,44 +1978,46 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
PtrOwner<ISurfFlatRegion> pSrfIslands( CreateSurfFlatRegion()) ;
if ( IsNull( pSrfIslands))
return false ;
for ( int i = 1 ; i < pSfrChunk->GetLoopCount( 0) ; ++ i) {
pSrfIslands->AddExtLoop( pSfrChunk->GetLoop( 0, i)) ;
vpCrvs.emplace_back( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, i))) ;
for ( int nL = 1 ; nL < pSfrChunk->GetLoopCount( 0) ; ++ nL) {
pSrfIslands->AddExtLoop( pSfrChunk->GetLoop( 0, nL)) ;
vpCrvs.emplace_back( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, nL))) ;
}
pSrfIslands->Offset( PockParams.dRad + PockParams.dRadialOffset, ICurve::OFF_FILLET) ;
for ( int nC = 0 ; nC < pSrfIslands->GetChunkCount() ; ++ nC)
for ( int nC = 0 ; nC < pSrfIslands->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSrfIslands->GetLoopCount( nL) ; ++ nL)
vCrvCompoRes_tmp.emplace_back( ConvertCurveToComposite( pSrfIslands->GetLoop( nC, nL))) ;
vCrvCompoResTmp.emplace_back( ConvertCurveToComposite( pSrfIslands->GetLoop( nC, nL))) ;
}
}
}
// se non ho ottenuto curve, allora ho finito
if ( vCrvCompoRes_tmp.empty())
if ( vCrvCompoResTmp.empty())
return true ;
// controllo che effettivamente l'utensile svuoti la regione
PtrOwner<ISurfFlatRegion> pSfrNoRemoved( CloneSurfFlatRegion( pSfrChunk)) ;
if ( IsNull( pSfrNoRemoved) || ! pSfrNoRemoved->IsValid())
PtrOwner<ISurfFlatRegion> pSfrNotRemoved( CloneSurfFlatRegion( pSfrChunk)) ;
if ( IsNull( pSfrNotRemoved) || ! pSfrNotRemoved->IsValid())
return false ;
for ( int i = 0 ; i < int( vCrvCompoRes_tmp.size()) ; ++ i) {
PtrOwner<ISurfFlatRegion> pSfrRemoved( GetSurfFlatRegionFromFatCurve( CloneCurveComposite( vCrvCompoRes_tmp[i]), PockParams.dRad + PockParams.dRadialOffset + 50 * EPS_SMALL, false, false)) ;
double dOffs = PockParams.dRad + PockParams.dRadialOffset + 50. * EPS_SMALL ;
double dTol = 25. * EPS_SMALL ;
for ( int i = 0 ; i < ssize( vCrvCompoResTmp) ; ++ i) {
PtrOwner<ISurfFlatRegion> pSfrRemoved( GetSurfFlatRegionFromFatCurve( CloneCurveComposite( vCrvCompoResTmp[i]), dOffs, false, false)) ;
if ( ! IsNull( pSfrRemoved) && pSfrRemoved->IsValid()) {
if ( AreOppositeVectorEpsilon( pSfrRemoved->GetNormVersor(), pSfrNoRemoved->GetNormVersor(), 25. * EPS_SMALL))
if ( AreOppositeVectorEpsilon( pSfrRemoved->GetNormVersor(), pSfrNotRemoved->GetNormVersor(), dTol))
pSfrRemoved->Invert() ;
pSfrNoRemoved->Subtract( *pSfrRemoved) ;
pSfrNotRemoved->Subtract( *pSfrRemoved) ;
}
}
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) {
PtrOwner<ISurfFlatRegion> pSfrRemoved( GetSurfFlatRegionFromFatCurve( CloneCurveComposite( vpCrvs[i]), PockParams.dRad + PockParams.dRadialOffset + 50 * EPS_SMALL, false, false)) ;
PtrOwner<ISurfFlatRegion> pSfrRemoved( GetSurfFlatRegionFromFatCurve( CloneCurveComposite( vpCrvs[i]), dOffs, false, false)) ;
if ( ! IsNull( pSfrRemoved) && pSfrRemoved->IsValid()) {
if ( AreOppositeVectorEpsilon( pSfrRemoved->GetNormVersor(), pSfrNoRemoved->GetNormVersor(), 25. * EPS_SMALL))
if ( AreOppositeVectorEpsilon( pSfrRemoved->GetNormVersor(), pSfrNotRemoved->GetNormVersor(), dTol))
pSfrRemoved->Invert() ;
pSfrNoRemoved->Subtract( *pSfrRemoved) ;
pSfrNotRemoved->Subtract( *pSfrRemoved) ;
}
}
}
if ( pSfrNoRemoved->IsValid() && pSfrNoRemoved->GetChunkCount() > 0)
if ( pSfrNotRemoved->IsValid() && pSfrNotRemoved->GetChunkCount() > 0)
return true ;
bAllRemoved = true ;
@@ -2019,42 +2026,41 @@ GetPocketCurvesByClosedEdges( const ISurfFlatRegion* pSfrChunk, const PocketPara
PtrOwner<ISurfFlatRegion> pSfrLimit( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrLimit))
return false ;
// per tutte le curve inserite, devo tenere solamente quelle esterne alla superficie limite
if ( PockParams.SfrLimit.IsValid()) { // se esiste, allora classifico
if ( PockParams.SfrLimit.IsValid()) {
// recupero la superficie limite
pSfrLimit.Set( PockParams.SfrLimit.Clone()) ;
if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid())
return false ;
// effettuo un Offset della regione, tutto ciò che dista più del raggio utensile non la rovina
pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset - 25 * EPS_SMALL, ICurve::OFF_FILLET) ; // c'è un offset radiale, quindi tengo tolleranza alta
ICRVCOMPOPOVECTOR vCrvCompoRes_tmp_Splitted ;
for ( int i = 0 ; i < int( vCrvCompoRes_tmp.size()) ; ++ i) {
pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset - dTol, ICurve::OFF_FILLET) ; // c'è un offset radiale, quindi tengo tolleranza alta
ICRVCOMPOPOVECTOR vCrvCompoResTmpSplitted ;
for ( int i = 0 ; i < ssize( vCrvCompoResTmp) ; ++ i) {
CRVCVECTOR ccClass ;
if ( pSfrLimit->GetCurveClassification( *vCrvCompoRes_tmp[i], EPS_SMALL, ccClass)) {
for ( int j = 0 ; j < int( ccClass.size()) ; ++ j) {
if ( pSfrLimit->GetCurveClassification( *vCrvCompoResTmp[i], EPS_SMALL, ccClass)) {
for ( int j = 0 ; j < ssize( ccClass) ; ++ j) {
if ( ccClass[j].nClass == CRVC_OUT) {
PtrOwner<ICurveComposite> pCrvRes( ConvertCurveToComposite( vCrvCompoRes_tmp[i]->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) ;
PtrOwner<ICurveComposite> pCrvRes( ConvertCurveToComposite( vCrvCompoResTmp[i]->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) ;
if ( ! IsNull( pCrvRes) && pCrvRes->IsValid())
vCrvCompoRes_tmp_Splitted.emplace_back( Release( pCrvRes)) ;
vCrvCompoResTmpSplitted.emplace_back( Release( pCrvRes)) ;
}
}
}
}
// se non ho curve, allora esco
if ( vCrvCompoRes_tmp_Splitted.empty())
if ( vCrvCompoResTmpSplitted.empty())
return true ;
// altrimenti aggiorno il vettore di curve con quelle solo esterne alla regione limite
swap( vCrvCompoRes_tmp, vCrvCompoRes_tmp_Splitted) ;
swap( vCrvCompoResTmp, vCrvCompoResTmpSplitted) ;
}
// salvo come primo tempParam l'offset massimo della regione ( servirà per la Feed)
for ( int i = 0 ; i < int( vCrvCompoRes_tmp.size()) ; ++ i) {
vCrvCompoRes_tmp[i]->SetTempParam( dMaxOffs, 0) ;
for ( int i = 0 ; i < ssize( vCrvCompoResTmp) ; ++ i) {
vCrvCompoResTmp[i]->SetTempParam( dMaxOffs, 0) ;
// se richiesta inversione della curva, allora inverto
if ( PockParams.bInvert)
vCrvCompoRes_tmp[i]->Invert() ;
vCrvCompoRes.emplace_back( Release( vCrvCompoRes_tmp[i])) ; // aggiungo la curva al vettore
vCrvCompoResTmp[i]->Invert() ;
vCrvCompoRes.emplace_back( Release( vCrvCompoResTmp[i])) ;
}
return true ;
@@ -2071,8 +2077,8 @@ GetSinglePocketingCurves( ISurfFlatRegion* pSfr, PocketParams& PockParams,
vCrvSingleCurves.clear() ;
// tengo una copia della superficie ( serve per l'estensione dei percorsi fuori dal grezzo)
PtrOwner<ISurfFlatRegion> pSfr_clone( CloneSurfFlatRegion( pSfr)) ;
if ( IsNull( pSfr_clone) || ! pSfr_clone->IsValid())
PtrOwner<ISurfFlatRegion> pSfrClone( CloneSurfFlatRegion( pSfr)) ;
if ( IsNull( pSfrClone) || ! pSfrClone->IsValid())
return false ;
// scorro i Chunk della superficie
@@ -2097,35 +2103,38 @@ GetSinglePocketingCurves( ISurfFlatRegion* pSfr, PocketParams& PockParams,
// potrei doverle riconcatenare
if ( ! ChainCompoCurves( vCrvSingleCurves))
return false ;
// estendo le curve, definendo ptStart e calcolando le Feeds (non inverto le curve aperte)
if ( ! AdvanceExtendCurves( vCrvSingleCurves, pSfr_clone, PockParams, false))
// estendo le curve, definendo ptStart e calcolando le Feeds
if ( ! AdvanceExtendCurves( vCrvSingleCurves, pSfrClone, PockParams, false))
return false ;
// imposto le Feed per tali curve se richiesto
for ( int i = 0 ; i < int( vCrvSingleCurves.size()) ; ++ i) {
// imposto le Feed e inverto i percorsi per tali curve se richiesto
bool bAllowInvert = ( PockParams.nType == POCKET_ZIGZAG || PockParams.nType == POCKET_CONFORMAL_ZIGZAG) ;
for ( int i = 0 ; i < ssize( vCrvSingleCurves) ; ++ i) {
/*
Idea : Feed proporzionale al minimo Offset per annullare la regione
-> Massimo parametro sui bisettori di VORONOI
se le curve risultano aperte, cambio il loro punto iniziale a seconda dell'estensione fatta
*/
if ( vCrvSingleCurves[i]->IsValid() && vCrvSingleCurves[i]->GetCurveCount() != 0 &&
! vCrvSingleCurves[i]->IsClosed()) {
int nTempProp_firstCrv = vCrvSingleCurves[i]->GetFirstCurve()->GetTempProp( 0) ;
int nTempProp_lastCrv = vCrvSingleCurves[i]->GetLastCurve()->GetTempProp( 0) ;
if ( vCrvSingleCurves[i]->IsValid() && vCrvSingleCurves[i]->GetCurveCount() > 0 && ! vCrvSingleCurves[i]->IsClosed()) {
int nFirstTempProp = vCrvSingleCurves[i]->GetFirstCurve()->GetTempProp( 0) ;
int nLastTempProp = vCrvSingleCurves[i]->GetLastCurve()->GetTempProp( 0) ;
// se estremi entrambi estesi
if ( nTempProp_firstCrv == TEMP_PROP_OUT_START && nTempProp_lastCrv == TEMP_PROP_OUT_START) {
// !!! ---> cancellare se si vuole evitare inversione delle curve <--- !!!
if ( PockParams.ptStart.IsValid()) {
Point3d ptStart ; vCrvSingleCurves[i]->GetStartPoint( ptStart) ;
double dSqDist_first = SqDist( PockParams.ptStart, ptStart) ;
Point3d ptEnd ; vCrvSingleCurves[i]->GetEndPoint( ptEnd) ;
double dSqDist_last = SqDist( PockParams.ptStart, ptEnd) ;
if ( dSqDist_last < dSqDist_first)
vCrvSingleCurves[i]->Invert() ;
vCrvSingleCurves[i]->GetEndPoint( PockParams.ptStart) ;
if ( nFirstTempProp == TEMP_PROP_OUT_START && nLastTempProp == TEMP_PROP_OUT_START) {
// se inversione delle curve accettata
if ( bAllowInvert) {
if ( PockParams.ptStart.IsValid()) {
Point3d ptStart ; vCrvSingleCurves[i]->GetStartPoint( ptStart) ;
double dSqStartDist = SqDist( PockParams.ptStart, ptStart) ;
Point3d ptEnd ; vCrvSingleCurves[i]->GetEndPoint( ptEnd) ;
double dSqEndDist = SqDist( PockParams.ptStart, ptEnd) ;
if ( dSqEndDist < dSqStartDist)
vCrvSingleCurves[i]->Invert() ;
}
}
vCrvSingleCurves[i]->GetEndPoint( PockParams.ptStart) ;
}
// se invece l'estensione è alla fine
else if ( nTempProp_lastCrv == TEMP_PROP_OUT_START)
// se invece l'estensione è alla fine, sono forzato ad invertila per entrare presso il lato aperto
else if ( nLastTempProp == TEMP_PROP_OUT_START)
vCrvSingleCurves[i]->Invert() ;
}
// recupero il MaxOffset per la curva
@@ -8523,17 +8532,38 @@ ExtendConformalOffsAndSetFeed( const ISurfFlatRegion* pSfrPock, const ISurfFlatR
return false ;
}
}
ICRVCOMPOPOVECTOR vCrvBorder ;
if ( ! GetSfrCrvCompoLoops( pSfrBorder, vCrvBorder))
return false ;
// determino eventuale regioni con parti non svuotate e imposto la Feed alle curve
PtrOwner<ISurfFlatRegion> pSfrUncleared( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrUncleared))
return false ;
if ( GetUnclearedRegionAndSetFeed( vCrvBorder, vCrvOffs, vCrvLinks, pSfrOrig, PockParams, pSfrUncleared)) {
// estendo i percorsi di Offset se richiesto
if ( ! RemoveUnclearedRegions( pSfrUncleared, vCrvOffs, vCrvBorder, PockParams))
// se non ho nessuna superficie di bordo, allora vuol dire che la regione è più stretta del diametro utensile
// ( capita soprattutto se ho un SideStep da rispettare presso gli aperti)
// non controllo le regioni rimosse ( dovrebbero essere rimosse dalle passate)
if ( pSfrBorder->IsValid()) {
ICRVCOMPOPOVECTOR vCrvBorder ;
if ( ! GetSfrCrvCompoLoops( pSfrBorder, vCrvBorder))
return false ;
// determino eventuale regioni con parti non svuotate e imposto la Feed alle curve
PtrOwner<ISurfFlatRegion> pSfrUncleared( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrUncleared))
return false ;
if ( GetUnclearedRegionAndSetFeed( vCrvBorder, vCrvOffs, vCrvLinks, pSfrOrig, PockParams, pSfrUncleared)) {
// estendo i percorsi di Offset se richiesto
if ( ! RemoveUnclearedRegions( pSfrUncleared, vCrvOffs, vCrvBorder, PockParams))
return false ;
}
}
else {
for ( int i = 0 ; i < ssize( vCrvOffs) ; ++ i) {
if ( ! IsNull( vCrvOffs[i]) && vCrvOffs[i]->IsValid())
AssignMaxFeed( vCrvOffs[i], PockParams) ;
}
for ( int i = 0 ; i < ssize( vCrvLinks) ; ++ i) {
if ( ! IsNull( vCrvLinks[i]) && vCrvLinks[i]->IsValid()) {
PtrOwner<ICurveComposite> pCompoLink( CreateCurveComposite()) ;
if ( IsNull( pCompoLink))
return false ;
pCompoLink->AddCurve( Release( vCrvLinks[i])) ;
AssignMaxFeed( pCompoLink, PockParams) ;
vCrvLinks[i].Set( pCompoLink) ;
}
}
}
return true ;
-69
View File
@@ -1,69 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2018
//----------------------------------------------------------------------------
// File : EGkCAvSurfFrMove.h Data : 26.03.2026 Versione : 3.1c6
// Contenuto : Dichiarazione classe per movimento di superfici flat region
// nel loro piano evitando collisioni
//
// Modifiche : 26.03.26 RE Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
//----------------------- Macro per import/export ----------------------------
#undef EGK_EXPORT
#if defined( I_AM_EGK) // da definirsi solo nella DLL
#define EGK_EXPORT __declspec( dllexport)
#else
#define EGK_EXPORT __declspec( dllimport)
#endif
//----------------------------------------------------------------------------
// Costanti per info su tipo di Collisione tra regioni piane
const int CI_NONE = 0 ; // non definito
const int CI_PNT_PNT = 1 ; // tra punto di mobile e punto di fissa
const int CI_PNT_LINE = 2 ; // tra punto di mobile e linea di fissa
const int CI_LINE_PNT = 3 ; // tra linea di mobile e punto di fissa
const int CI_LINE_LINE = 4 ; // tra linea di mobile e linea di fissa
//----------------------------------------------------------------------------
struct CollInfo
{
int nType ; // tipo di collisione
int nChunkM ; // indice del chunk della regione mobile
int nCrvM ; // indice della curva nel loop esterno del chunk
int nChunkF ; // indice del chunk della regione fissa
int nCrvF ; // indice della curva nel loop esterno del chunk
Point3d ptP1 ; // punto di contatto
Point3d ptP2 ; // se contatto linea-linea, secondo punto di contatto
Vector3d vtDirM ; // se contatto del mobile con linea, sua direzione
Vector3d vtDirF ; // se contatto del fisso con linea, sua direzione
// costruttori
CollInfo() : nType( CI_NONE), nChunkM( -1), nCrvM( -1), nChunkF( -1), nCrvF( -1),
ptP1(), ptP2(), vtDirM(), vtDirF() {}
CollInfo( const CollInfo& Sou) : nType( Sou.nType), nChunkM( Sou.nChunkM), nCrvM( Sou.nCrvM),
nChunkF( Sou.nChunkF), nCrvF( Sou.nCrvF), ptP1( Sou.ptP1),
ptP2( Sou.ptP2), vtDirM( Sou.vtDirM), vtDirF( Sou.vtDirF) {}
} ;
//----------------------------------------------------------------------------
class CAvSurfFrMove
{
public :
EGK_EXPORT CAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) ;
public :
EGK_EXPORT bool Translate( const Vector3d& vtDir, double& dLen) ;
EGK_EXPORT bool Rotate( const Point3d& ptCen, double& dAng) ;
EGK_EXPORT const CollInfo& GetCollInfo()
{ return m_CollInfo ; }
private :
const ISurfFlatRegion* m_pRegM ;
const ISurfFlatRegion* m_pRegF ;
CollInfo m_CollInfo ;
} ;
BIN
View File
Binary file not shown.