Compare commits

...

50 Commits

Author SHA1 Message Date
Daniele Bariletti a3d44261bb Merge branch 'master' into NewRuled 2026-04-10 18:20:44 +02:00
Daniele Bariletti 9220fd568f EgtGeomKernel :
- aggiunte funzioni per la creazione delle smooth ruled bezier.
2026-04-10 18:20:22 +02:00
Daniele Bariletti 17346e1b42 EgtGeomKernel :
- correzione alla triangolazione bezier.
2026-04-10 15:23:28 +02:00
Daniele Bariletti c95ef6764d EgtGeomKernel :
- correzione alla triangolazione bezier.
2026-04-10 15:22:44 +02:00
Daniele Bariletti d0f2d56bdb EgtGeomKernel :
- correzione per split vicini a joint in RuledByIsoParamSet.
2026-04-10 12:35:22 +02:00
Daniele Bariletti fb037f2f2a EgtGeomKernel :
- correzione per split vicini a joint in RuledByIsoParamSet.
2026-04-10 12:35:07 +02:00
Daniele Bariletti 2d94dddccb EgtGeomKernel :
- correzioni alla RuledByIsoParamSet.
2026-04-10 10:25:04 +02:00
Daniele Bariletti d2d025a594 EgtGeomKernel :
- correzioni alla RuledByIsoParamSet.
2026-04-10 10:23:32 +02:00
Daniele Bariletti 64abf640f6 Merge remote-tracking branch 'origin/HEAD' into NewRuled 2026-04-10 09:34:02 +02:00
Daniele Bariletti cb2b63320a EgtGeomKernel :
- nuovo paradigma per la bezier ruled.
2026-04-10 09:20:02 +02:00
Riccardo Elitropi 951d3781d6 EgtGeomKernel :
- in IntersCurvePlane aggiunta implementazione funzione GetIntCrvPlnInfo.
2026-04-09 19:20:59 +02:00
Daniele Bariletti 27bd0e579e EgtGeomKernel :
- correzione al VM a 5 assi.
2026-04-08 17:08:37 +02:00
Daniele Bariletti ff7d564de8 Merge branch 'NewRuled' 2026-04-08 13:42:01 +02:00
Daniele Bariletti a27b9e871a EgtGeomKernel :
- piccola correzione alle rigate.
2026-04-08 13:41:43 +02:00
Daniele Bariletti eb497cbd39 Merge branch 'master' into NewRuled 2026-04-03 17:27:31 +02:00
Daniele Bariletti dd3091fc13 EgtGeomKernel :
- miglioramento delle rigate con bezier.
2026-04-03 17:27:13 +02:00
Daniele Bariletti 69d463713c EgtGeomKernel 3.1d2 :
- cambio versione.
2026-04-03 16:21:20 +02:00
Daniele Bariletti 5e918ff3aa Merge branch 'master' of https://gitlab.steamware.net/egalware-cadcam/libreriebase/EgtGeomKernel 2026-04-03 16:19:47 +02:00
Daniele Bariletti b4522c712d EgtGeomKernel :
- correzione alla IntersCrvCompoCrvCompo.
2026-04-03 16:19:39 +02:00
Riccardo Elitropi fa9a9e89cb EgtGeomKernel :
- in CalcPocketing aggiunte considerazioni per Lucidature su SmallRad.
2026-04-03 12:52:39 +02:00
Riccardo Elitropi d51a0d2258 EgtGeomKernel :
- in CalcPocketing correzione parametro Invert per Epicicli.
2026-04-03 08:23:13 +02:00
Daniele Bariletti 580230b38b Merge branch 'master' of https://gitlab.steamware.net/egalware-cadcam/libreriebase/EgtGeomKernel 2026-04-02 18:03:34 +02:00
Daniele Bariletti 4b24906d2e Merge branch 'NewRuled' 2026-04-02 18:03:26 +02:00
Daniele Bariletti 2094a1cc0d EgtGeomKernel :
- tolto flag di debug.
2026-04-02 18:03:05 +02:00
Daniele Bariletti b8b639699a EgtGeomKernel :
- correzione alla nuova versione rigate (riconoscimento automtico mismatch).
2026-04-02 18:02:20 +02:00
Riccardo Elitropi 0b86c4f72b EgtGeomKernel :
- in Trimming piccola correzione
2026-04-02 17:29:41 +02:00
Daniele Bariletti 5c93384690 Merge branch 'master' into NewRuled 2026-04-02 16:09:45 +02:00
Daniele Bariletti b77db4a5bc Merge branch 'master' of https://gitlab.steamware.net/egalware-cadcam/libreriebase/EgtGeomKernel 2026-04-02 15:14:38 +02:00
Daniele Bariletti c704d94829 EgtGeomKernel :
- piccola aggiunta per la gestione di spike nelle categorizzazioni tra curve.
2026-04-02 15:14:29 +02:00
Riccardo Elitropi 0373021b7a EgtGeomKernel :
- In CalcPocketing piccole correzioni alle curve singole e modifiche stilistiche.
2026-04-02 10:43:37 +02:00
Riccardo Elitropi 6de856b3e1 EgtGeomKernel 3.1d1 :
- In CalcPocketing piccola correzione per casi Conformal.
2026-04-01 18:06:00 +02:00
Dario Sassi a231d8f26c EgtGeomKernel :
- eliminato file inutile.
2026-04-01 10:19:56 +02:00
Riccardo Elitropi 745a7eb38c EgtGeomKernel :
- In PocketingNT ggiunta gestione per Lucidatura.
2026-03-31 18:53:52 +02:00
Daniele Bariletti 78c40ebca7 EgtGeomKernel :
- tolto bypass di debug.
2026-03-31 17:26:43 +02:00
Daniele Bariletti a39af1c3a3 EgtGeomKernel :
- gestite superfici con trim molto piccoli rispetto al totale.
2026-03-31 16:19:42 +02:00
Riccardo Elitropi c2a0f9dff1 Merge commit '6be67258d2ac30e94ee2ed5af4e648ffb62d842d' 2026-03-31 14:27:26 +02:00
Daniele Bariletti 98c576afe0 Merge branch 'master' into NewRuled 2026-02-23 09:12:05 +01:00
Daniele Bariletti ae8f80d6e9 EgtGeomKernel :
- miglioria alla bezier ruled guided.
2026-02-20 14:54:50 +01:00
Daniele Bariletti 9b933bd26d EgtGeomKernel :
- miglioramento dell'approssimazione con curve di bezier.
2026-02-19 18:15:58 +01:00
Daniele Bariletti baa8736276 Merge branch 'master' into NewRuled 2026-02-19 15:41:12 +01:00
Daniele Bariletti c75a7e9514 EgtGeomKernel :
- migliorie alla rigata bezier.
- correzioni alle tolleranze di triangolazione
- aggiunta di un parametro alla funzione GetLeaves delle surf bezier.
2026-02-19 11:49:28 +01:00
Daniele Bariletti 233f64e68f EgtGeomKernel :
- correzioni alle rigate bezier.
2026-02-17 14:41:37 +01:00
Daniele Bariletti da7ebd6f61 EgtGeomKernel :
- miglioramenti e correzioni alle rigate con le bezier.
2026-02-16 12:45:50 +01:00
Daniele Bariletti 8db1765505 Merge remote-tracking branch 'origin/master' into NewRuled 2026-02-12 17:00:02 +01:00
Daniele Bariletti 5d2e1ff608 EgtGeomKernel :
- tolto un argomento alla funzione ApproxCurveWithBezier.
2026-02-11 16:47:01 +01:00
Daniele Bariletti a9f8ef2ff3 Merge branch 'master' into NewRuled 2026-02-11 15:58:21 +01:00
Daniele Bariletti a1c448d8dd EgtGeomKernel :
- tentativo di miglioria alle ruled. Da debuggare.
2026-02-03 16:13:07 +01:00
Daniele Bariletti 25d53338c2 Merge branch 'master' into NewRuled 2026-01-28 15:24:09 +01:00
Daniele Bariletti 1ad96ce8ca EgtGeomKernel :
- tentativo di miglioramento delle ruled nei punti di mismatch.
2025-12-15 15:08:53 +01:00
Daniele Bariletti 36422c43b3 Merge branch 'master' into NewRuled 2025-12-15 15:07:21 +01:00
12 changed files with 1818 additions and 508 deletions
+390 -118
View File
@@ -45,6 +45,7 @@ using namespace std ;
struct PocketParams {
int nType = POCKET_SPIRALIN ; // tipo di lavorazione
int nLiType = LEAD_IN_NONE ; // tipo di ingresso (LeadIn)
int nLoType = LEAD_OUT_NONE ; // tipo di uscita (LeadOut)
double dRad = 0. ; // raggio utensile
double dRad_prec = -1. ; // raggio utensile della lavorazione precedente
double dSideStep = 0. ; // step
@@ -55,8 +56,10 @@ struct PocketParams {
double dOpenMinSafe = 5. ; // estensione minima di sicurezza
double dMaxOptSize = 0. ; // dimensione per ottimizzazione
double dAngle = 0. ; // angolo per orientare le passate OneWay e ZigZag
double dSmooth = 5. ; // parametro di smusso per link ( raccordo )
double dLiTang = INFINITO ; // valore di LeadIn in ingresso
double dSmooth = 5. ; // parametro di smusso per link (raccordo)
double dLiTang = INFINITO ; // valore tangente di LeadIn
double dLiElev = INFINITO ; // valore elevazione di LeadIn (usato anche per LeadOut)
double dLoTang = INFINITO ; // valore di LeadOut
bool bCalcUnclearedRegs = true ; // flag per calcolare o meno le regioni non svuotate
bool bOptOffsets = true ; // flag per evitare Offset non necessari
bool bAboveHead = true ; // flag per testa da sopra ( Z+)
@@ -77,6 +80,10 @@ struct PocketParams {
Frame3d frLocXY ; // frame per conti nel piano XY
int nOffsType = ICurve::OFF_FILLET ; // tipologia di Offset per estensione degli aperti
double dOpenEdgeRad = 0. ; // raggio effettivo di estensione degli aperti
// --------------------------------------------------------
bool bPolishing = false ; // flag per lucidatura
double dEpicyclesRad = 0. ; // raggio degli epicicli
double dEpicyclesDist = 0. ; // distanza degli epicicli
} ;
static double TOL_TRAPEZOID = 50 * EPS_SMALL ; // tolleranza per casi a trapezio SpiralPocket
static double TOL_REMOVE_OFFSET = 2. ; // tolleranza per controllo materiale lasciato da un Offset
@@ -1601,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)
@@ -1662,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 ;
}
}
@@ -1704,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
@@ -1735,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 {
@@ -1772,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 ;
@@ -1800,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
@@ -1851,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 ;
/*
@@ -1874,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)) {
@@ -1889,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
@@ -1909,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]) ;
@@ -1919,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 :
@@ -1937,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) ||
@@ -1966,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 ;
@@ -2012,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 ;
@@ -2064,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
@@ -2090,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
@@ -6212,6 +6228,198 @@ CalcInversionForSpiralOffset( const ISurfFlatRegion* pSfrChunk)
return -1 ;
}
//----------------------------------------------------------------------------
static bool
AddEpicycles( const PocketParams& PockParam, ICurveComposite* pCompo, ICurveComposite* pCrv, ICurveComposite* pCrvBound)
{
// verifico che la curva sia valida
if ( pCompo == nullptr || ! pCompo->IsValid())
return false ;
// calcolo l'Offset definito dal valore dell'raggio dell'epiciclo
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCompo, PockParam.dEpicyclesRad, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() > 1)
return false ;
PtrOwner<ICurveComposite> pCrvOffs( GetCurveComposite( OffsCrv.GetCurve())) ;
if ( IsNull( pCrvOffs))
return false ;
// verifico se devo resitituire la curva offsettata
if ( pCrvBound != nullptr)
pCrvBound->AddCurve( pCrvOffs->Clone()) ;
pCrv->Clear() ;
double dParPrec = 0. ;
for ( int i = 0 ; i < pCompo->GetCurveCount() ; ++ i) {
// calcolo distanza epicili specifica per quel tratto
double dLen ;
pCompo->GetCurve( i)->GetLength( dLen) ;
int nStep = max( 1, static_cast<int>( ceil( ( dLen) / PockParam.dEpicyclesDist))) ;
double dStep = 1.0 / nStep ;
for ( int k = 1 ; k <= nStep ; ++ k) {
// creo epiciclo
Point3d ptCen ;
Vector3d vtDir ;
pCompo->GetCurve( i)->GetPointD1D2( k * dStep, ICurve::FROM_MINUS, ptCen, &vtDir) ;
vtDir.Normalize() ;
vtDir.Rotate( Z_AX, - 90.) ;
Point3d pt = ptCen + vtDir * PockParam.dEpicyclesRad ;
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
pCrvArc->Set( ptCen, Z_AX, PockParam.dEpicyclesRad) ;
double dU ;
pCrvArc->GetParamAtPoint( pt, dU) ;
pCrvArc->ChangeStartPoint( dU) ;
// aggiungo tratto della curva offsettata
double dPar ;
pCrvOffs->GetParamAtPoint( pt, dPar) ;
bool bAdd = ( pCrv->AddCurve( pCrvOffs->CopyParamRange( dParPrec, dPar))) ;
// aggiungo epiciclo
if ( ! pCrv->AddCurve( Release( pCrvArc))) {
// se fallisco nell'aggiungere l'epiciclo tento nuovamente spostandolo di EPS_SMALL
if ( bAdd)
PtrOwner<ICurve> pCrvErased( pCrv->RemoveFirstOrLastCurve( true)) ;
k -- ;
dStep -= EPS_SMALL ;
if ( dStep < EPS_SMALL)
return false ;
}
else
dParPrec = dPar ;
}
}
// se necessario ripristino orientamento originale
if ( PockParam.bInvert)
pCrv->Invert() ;
return true ;
}
//------------------------------------------------------------------------------
static bool
CalcBoundedPolishingLink( const Point3d& ptStart, const Vector3d& vtStart, const Point3d& ptEnd, const Vector3d& vtEnd,
const ICurve* pCrvBound, ICurveComposite* pCrvLink)
{
double dAngStart, dAngEnd ;
vtStart.GetAngleXY( X_AX, dAngStart) ;
vtEnd.GetAngleXY( X_AX, dAngEnd) ;
PtrOwner<ICurve> pBiArcLink( GetBiArc( ptStart, -dAngStart, ptEnd, -dAngEnd, 0.5)) ;
if ( IsNull( pBiArcLink))
return false ;
// verifico se esce dalla svuotatura
CRVCVECTOR ccClass ;
IntersCurveCurve intCC( *pBiArcLink, *pCrvBound) ;
intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ;
// se nessuno o un solo tratto e interno, il biarco è il collegamento
if ( ccClass.empty() || ( ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_IN)) {
pCrvLink->AddCurve( Release( pBiArcLink)) ;
}
// altrimenti creo un percorso con biarchi e opportuni tratti della curva di contenimento
else {
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo))
return false ;
double dPar1, dPar2 ;
Point3d ptMinDist1, ptMinDist2 ;
Vector3d vtDir1, vtDir2 ;
double dAng1, dAng2 ;
int nFlag ;
DistPointCurve distPtSCrv( ptStart, *pCrvBound) ;
distPtSCrv.GetParamAtMinDistPoint( 0, dPar1, nFlag) ;
pCrvBound->GetPointTang( dPar1, ICurve::FROM_MINUS, ptMinDist1, vtDir1) ;
vtDir1.GetAngleXY( X_AX, dAng1) ;
DistPointCurve distPtECrv( ptEnd, *pCrvBound) ;
distPtECrv.GetParamAtMinDistPoint( 0, dPar2, nFlag) ;
pCrvBound->GetPointTang( dPar2, ICurve::FROM_MINUS, ptMinDist2, vtDir2) ;
vtDir2.GetAngleXY( X_AX, dAng2) ;
pCompo->AddCurve( GetBiArc( ptStart, -dAngStart, ptMinDist1, -dAng1, 0.5)) ; // primo biarco
pCompo->AddCurve( pCrvBound->CopyParamRange( dPar1, dPar2)) ; // tratto di pCrvBound
pCompo->AddCurve( GetBiArc( ptMinDist2, -dAng2, ptEnd, -dAngEnd, 0.5)) ; // secondo biarco
pCrvLink->AddCurve( Release( pCompo)) ;
}
return true ;
}
//----------------------------------------------------------------------------
static bool
ComputePolishingPath( const PocketParams& PockParam, ICRVCOMPOPOVECTOR& vOffs, ICurveComposite* pMCrv)
{
// controllo dei parametri
if ( vOffs.empty() || pMCrv == nullptr)
return false ;
pMCrv->Clear() ;
// Offset con epicicli
ICRVCOMPOPOVECTOR vpCrvsEp ; vpCrvsEp.reserve( vOffs.size()) ;
// definisco la curva di bordo
PtrOwner<ICurveComposite> pCrvBound( CreateCurveComposite()) ;
if ( IsNull( pCrvBound))
return false ;
// recupero il punto iniziale
Point3d ptStartRef ;
GetPtStartOnGenericEdge( vOffs[0], PockParam, ptStartRef) ;
// scorro le curve di Offset
for ( int i = 0 ; i < ssize( vOffs) ; ++ i) {
PtrOwner<ICurveComposite> pCrvEp( CreateCurveComposite()) ;
if ( IsNull( pCrvEp))
return false ;
double dUStart = 0. ;
int nFlag = 0 ;
DistPointCurve( ptStartRef, *vOffs[i]).GetParamAtMinDistPoint( 0., dUStart, nFlag) ;
vOffs[i]->ChangeStartPoint( dUStart) ;
// la curva di bound è l'offset che calcolo in AddEpicycles per la prima curva compo trovata in pMCrv
if ( ! AddEpicycles( PockParam, vOffs[i], pCrvEp, ( i == 0 ? pCrvBound : nullptr)))
return false ;
vpCrvsEp.emplace_back( Release( pCrvEp)) ;
}
// calcolo i collegamenti
ICURVEPOVECTOR vLinks( vpCrvsEp.size()) ;
for ( int i = 1 ; i < ssize( vpCrvsEp) ; ++ i) {
// punti e direzioni di inizio e fine
Point3d ptStart ; Vector3d vtStart ;
vpCrvsEp[i-1]->GetEndPoint( ptStart) ;
vpCrvsEp[i-1]->GetEndDir( vtStart) ;
Point3d ptEnd ; Vector3d vtEnd ;
vpCrvsEp[i]->GetStartPoint( ptEnd) ;
vpCrvsEp[i]->GetStartDir( vtEnd) ;
// calcolo il collegamento con biarchi (garantendo che non esca dalla svuotatura)
PtrOwner<ICurveComposite> pCrvLink( CreateCurveComposite()) ;
if ( IsNull( pCrvLink))
return false ;
if ( ! CalcBoundedPolishingLink( ptStart, vtStart, ptEnd, vtEnd, pCrvBound, pCrvLink))
return false ;
vLinks[i].Set( pCrvLink) ;
}
// creo il percorso di lavoro a partire dalla raccolta delle curve con epicicli e dei collegamenti
for ( int i = 0 ; i < int( vpCrvsEp.size()) ; ++ i) {
// se collegamento da aggiungere
if ( ! IsNull( vLinks[i])) {
// accodo nel percorso di lavorazione
pMCrv->AddCurve( Release( vLinks[i])) ;
}
// aggiungo la curva
pMCrv->AddCurve( Release( vpCrvsEp[i])) ;
}
return true ;
}
//----------------------------------------------------------------------------
static bool
CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams, int& nReg, Point3d& ptStart,
@@ -6222,6 +6430,9 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
// Offset corrente ( il primo è definito dal raggio utensile)
double dOffs = PockParams.dRad + PockParams.dRadialOffset ;
// se lucidatura
if ( PockParams.bPolishing && nReg == 0)
dOffs += PockParams.dEpicyclesRad ;
// ciclo di offset verso l'interno
const int MAX_ITER = 1000 ;
@@ -6330,7 +6541,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
}
// se non ho Chunks e devo usare un Offset più piccolo...
else if ( ! bSmallRad) {
if ( PockParams.dRad < EPS_SMALL)
if ( PockParams.dRad < EPS_SMALL || PockParams.bPolishing)
break ;
dOffs = dOffsPrec + ( nIter == 0 ? PockParams.dRad + PockParams.dRadialOffset : PockParams.dRad) ;
}
@@ -6345,6 +6556,13 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
if ( vOffs.empty())
return true ;
// se lucidatura
if ( PockParams.bPolishing && nReg == 1) {
// si suppone che gli offset siano tutti concentrici ( già ordinati dall'esterno all'interno)
bMidOut = false ; // per definizione di lucidatura
return ( ComputePolishingPath( PockParams, vOffs, pMCrv)) ;
}
// cambio il punto iniziale della prima Curva di Offset
Point3d ptRef = PockParams.ptStart ;
Point3d ptNewStart ;
@@ -7212,7 +7430,7 @@ AddZigZag( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
// offset della regione per curva ZigZag
double dOffs = PockParams.dRad + PockParams.dRadialOffset ;
if ( PockParams.bAllowZigZagOneWayBorders)
if ( PockParams.bAllowZigZagOneWayBorders && ! PockParams.bPolishing)
dOffs += PockParams.dOffsExtra ;
// ciclo su tutti i chunks della superficie originale
@@ -7250,7 +7468,7 @@ AddZigZag( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
// controllo esistenza di lati aperti per il Chunk attuale
bool bIsChunkClosed = true ;
bool bIsChunkAllOpen = true ;
if ( ! PockParams.bAllClosed) {
if ( ! PockParams.bAllClosed && ! PockParams.bPolishing) {
if ( ! IsChunkAllHomogeneous( pSrfPock, nChunkInd, bIsChunkClosed, bIsChunkAllOpen))
return false ;
// se il Chunk originale aveva lati aperti, estendo il percorso a ZigZag
@@ -7265,6 +7483,31 @@ AddZigZag( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
return false ;
}
}
// se lucidatura
if ( PockParams.bPolishing) {
// ciclo sui percorsi
for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) {
// se attacco a scivolo
if ( PockParams.nLiType == LEAD_IN_GLIDE) {
double dU ;
vpCrvs[k]->GetParamAtLength( PockParams.dLiTang, dU) ;
vpCrvs[k]->AddJoint( dU) ;
Point3d ptStart ;
vpCrvs[k]->GetStartPoint( ptStart) ;
vpCrvs[k]->ModifyStart( ptStart + Z_AX * PockParams.dLiElev) ;
}
// se uscita a scivolo
if ( PockParams.nLoType == LEAD_OUT_GLIDE) {
double dLen, dU ;
vpCrvs[k]->GetLength( dLen) ;
vpCrvs[k]->GetParamAtLength( dLen - PockParams.dLoTang, dU) ;
vpCrvs[k]->AddJoint( dU) ;
Point3d ptEnd ;
vpCrvs[k]->GetEndPoint( ptEnd) ;
vpCrvs[k]->ModifyEnd( ptEnd + Z_AX * PockParams.dLiElev) ;
}
}
}
// inserisco le curve nel vettore risultante
for ( int nU = 0 ; nU < int( vpCrvs.size()) ; ++ nU)
@@ -7275,7 +7518,7 @@ AddZigZag( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
}
// se richiesto, aggiungo le curve chiuse di Bordo
if ( PockParams.bAllowZigZagOneWayBorders) {
if ( PockParams.bAllowZigZagOneWayBorders && ! PockParams.bPolishing) {
// recupero il Chunk nC-esimo
PtrOwner<ISurfFlatRegion> pSfrChunk( pSrfPock->CloneChunk( nChunkInd)) ;
if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid() ||
@@ -8286,17 +8529,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 ;
@@ -9111,8 +9375,9 @@ CalcSpiralPocketing( const ISurfFlatRegion* pSfr, int nType, const PocketParams&
PockParams.dAngle, PockParams.dOpenMinSafe, nType, PockParams.bSmooth,
PockParams.bCalcUnclearedRegs, PockParams.bInvert, PockParams.bAvoidOpt,
PockParams.bAllowZigZagOneWayBorders, PockParams.bCalcFeed, PockParams.ptStart,
pSfrLimit, PockParams.bAvoidOpt, PockParams.dMaxOptSize, PockParams.dLiTang,
PockParams.nLiType, vCrvCompoRes)) ;
pSfrLimit, PockParams.bAvoidOpt, PockParams.dMaxOptSize,
PockParams.nLiType, PockParams.dLiTang, PockParams.dLiElev, PockParams.nLoType, PockParams.dLoTang,
PockParams.bPolishing, PockParams.dEpicyclesRad, PockParams.dEpicyclesDist, vCrvCompoRes)) ;
}
//----------------------------------------------------------------------------
@@ -9409,8 +9674,9 @@ bool
CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double dStep, double dAngle,
double dOpenMinSafe, int nType, bool bSmooth, bool bCalcUnclReg, bool bInvert, bool bAvoidOpt,
bool bAllowZigZagOneWayBorders, bool bCalcFeed, const Point3d& ptEndPrec,
const ISurfFlatRegion* pSfrLimit, bool bAllOffs, double dMaxOptSize, double dLiTang,
int nLiType, ICRVCOMPOPOVECTOR& vCrvCompoRes)
const ISurfFlatRegion* pSfrLimit, bool bAllOffs, double dMaxOptSize,
int nLiType, double dLiTang, double dLiElev, int nLoType, double dLoTang,
bool bPolishing, double dEpicyclesRad, double dEpicyclesDist, ICRVCOMPOPOVECTOR& vCrvCompoRes)
{
// controllo dei parametri
if ( pSfr == nullptr || ! pSfr->IsValid() ||
@@ -9438,8 +9704,14 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
myParams.bAllowZigZagOneWayBorders = bAllowZigZagOneWayBorders ;
myParams.bOptOffsets = ( ! bAllOffs) ;
myParams.dMaxOptSize = dMaxOptSize ;
myParams.dLiTang = dLiTang ;
myParams.nLiType = nLiType ;
myParams.dLiTang = dLiTang ;
myParams.dLiElev = dLiElev ;
myParams.nLoType = nLoType ;
myParams.dLoTang = dLoTang ;
myParams.bPolishing = bPolishing ;
myParams.dEpicyclesRad = dEpicyclesRad ;
myParams.dEpicyclesDist = dEpicyclesDist ;
if ( ptEndPrec.IsValid())
myParams.ptStart = ptEndPrec ;
if ( pSfrLimit != nullptr && pSfrLimit->IsValid())
-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.
+79 -32
View File
@@ -802,19 +802,36 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
INTVECTOR vNewOverlap ;
// salvo eventuali incoerenze col precedente
for ( int i = bCrvAClosed ? 0 : 1 ; i < m_nNumInters ; ++i) {
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
int kj = m_Info[j].bOverlap ? 1 : 0 ;
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
int kj = ( m_Info[j].bOverlap ? 1 : 0) ;
bool bSpike = m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq ;
if ( bSpike) {
bSpike = abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ||
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ;
}
if ( (m_Info[j].IciA[kj].nNextTy == ICCT_NULL || m_Info[i].IciA[0].nPrevTy == ICCT_NULL || m_Info[j].IciA[kj].nNextTy != m_Info[i].IciA[0].nPrevTy) &&
m_Info[j].IciA[kj].nNextTy != ICCT_SPK && m_Info[i].IciA[0].nPrevTy != ICCT_SPK) {
vIncoherenceWithPrev.push_back( i) ;
if ( vIncoherenceWithPrev.empty() || vIncoherenceWithPrev.back() != i)
vIncoherenceWithPrev.push_back( i) ;
if ( bSpike) {
// se ho uno spike sistemo anche il successivo
int k = i == m_nNumInters - 1 ? -1 : i + 1 ;
if ( k == -1 && bCrvAClosed)
k = 0 ;
if ( k != -1)
vIncoherenceWithPrev.push_back( k) ;
}
bCoherent = false ;
}
}
// incoerenze sulla curva A
if ( ! bCoherent) {
for ( int i : vIncoherenceWithPrev) {
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
int kj = m_Info[j].bOverlap ? 1 : 0 ;
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
int kj = ( m_Info[j].bOverlap ? 1 : 0) ;
int nType = 0 ;
CalcSide( j, i, &CCompoA, &CCompoB, true, nType) ;
if ( nType != ICCT_ON) {
@@ -836,21 +853,38 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
vIncoherenceWithPrev.clear() ;
// salvo eventuali incoerenze col precedente
for ( int i = bCrvBClosed ? 0 : 1 ; i < m_nNumInters ; ++i) {
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
int ki = m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0 ;
int kj = m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0 ;
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ;
int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
bool bSpike = m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq ;
if ( bSpike) {
bSpike = abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ||
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ;
}
if ( ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL || m_Info[i].IciB[ki].nPrevTy == ICCT_NULL || m_Info[j].IciB[kj].nNextTy != m_Info[i].IciB[ki].nPrevTy) &&
m_Info[j].IciB[kj].nNextTy != ICCT_SPK && m_Info[i].IciB[ki].nPrevTy != ICCT_SPK) {
vIncoherenceWithPrev.push_back( i) ;
if ( vIncoherenceWithPrev.empty() || vIncoherenceWithPrev.back() != i)
vIncoherenceWithPrev.push_back( i) ;
if ( bSpike) {
// se ho uno spike sistemo anche il successivo
int k = ( i == m_nNumInters - 1 ? -1 : i + 1) ;
if ( k == -1 && bCrvBClosed)
k = 0 ;
if ( k != -1)
vIncoherenceWithPrev.push_back( k) ;
}
bCoherent = false ;
}
}
// incoerenze sulla curva B
if ( ! bCoherent) {
for ( int i : vIncoherenceWithPrev) {
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
int ki = m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0 ;
int kj = m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0 ;
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
int ki = ( m_Info[i].bOverlap && !m_Info[i].bCBOverEq ? 1 : 0) ;
int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
int nType = 0 ;
CalcSide( j, i, &CCompoB, &CCompoA, false, nType) ;
if ( nType != ICCT_ON) {
@@ -882,13 +916,19 @@ IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICu
const IntCrvCrvInfo& Icci1 = m_Info[j] ;
const IntCrvCrvInfo& Icci2 = m_Info[i] ;
// calcolo tra l'intersezione 1 e 2 se la curva sta dentro o fuori
int kj = Icci1.bOverlap ? 1 : 0 ;
int ki = 0 ;
int kj = ( Icci1.bOverlap ? 1 : 0) ;
if ( ! bCrvAOrB) {
ki = ( m_Info[i].bOverlap && !m_Info[i].bCBOverEq ? 1 : 0) ;
kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
}
double dU = 0 ;
bool bPrevIsBefore = true ;
if ( bCrvAOrB) {
// se precedente minore del successivo faccio la media
if ( Icci1.IciA[kj].dU < Icci2.IciA[0].dU)
dU = ( Icci2.IciA[0].dU + Icci1.IciA[kj].dU) / 2 ;
if ( Icci1.IciA[kj].dU < Icci2.IciA[ki].dU)
dU = ( Icci2.IciA[ki].dU + Icci1.IciA[kj].dU) / 2 ;
// altrimenti guardo tra lo start e il successivo
else {
bPrevIsBefore = false ;
@@ -904,8 +944,8 @@ IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICu
}
else {
// se precedente minore del successivo faccio la media
if ( Icci1.IciB[kj].dU < Icci2.IciB[0].dU)
dU = ( Icci2.IciB[0].dU + Icci1.IciB[kj].dU) / 2 ;
if ( Icci1.IciB[kj].dU < Icci2.IciB[ki].dU)
dU = ( Icci2.IciB[ki].dU + Icci1.IciB[kj].dU) / 2 ;
// altrimenti guardi tra lo start e il successivo
else {
bPrevIsBefore = false ;
@@ -933,24 +973,24 @@ IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICu
bool bIsOn = false ;
if ( bCrvAOrB) {
if ( bPrevIsBefore) {
vdU[0] = ( 1 - dFactor) * Icci2.IciA[0].dU + dFactor * Icci1.IciA[kj].dU ;
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciA[0].dU + 2 * dFactor * Icci1.IciA[kj].dU ;
vdU[0] = ( 1 - dFactor) * Icci2.IciA[ki].dU + dFactor * Icci1.IciA[kj].dU ;
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciA[ki].dU + 2 * dFactor * Icci1.IciA[kj].dU ;
}
else if ( Icci2.IciA[0].dU > 2 * EPS_SMALL){
vdU[0] = ( Icci2.IciA[0].dU + 0.) * dFactor ;
vdU[1] = ( Icci2.IciA[0].dU + 0.) * 2 * dFactor ;
else if ( Icci2.IciA[ki].dU > 2 * EPS_SMALL){
vdU[0] = ( Icci2.IciA[ki].dU + 0.) * dFactor ;
vdU[1] = ( Icci2.IciA[ki].dU + 0.) * 2 * dFactor ;
}
else
bIsOn = true ;
}
else {
if ( bPrevIsBefore) {
vdU[0] = ( 1 - dFactor) * Icci2.IciB[0].dU + dFactor * Icci1.IciB[kj].dU ;
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciB[0].dU + 2 * dFactor * Icci1.IciB[kj].dU ;
vdU[0] = ( 1 - dFactor) * Icci2.IciB[ki].dU + dFactor * Icci1.IciB[kj].dU ;
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciB[ki].dU + 2 * dFactor * Icci1.IciB[kj].dU ;
}
else if ( Icci2.IciB[0].dU > 2 * EPS_SMALL) {
vdU[0] = ( Icci2.IciB[0].dU + 0.) * dFactor ;
vdU[1] = ( Icci2.IciB[0].dU + 0.) * 2 * dFactor ;
else if ( Icci2.IciB[ki].dU > 2 * EPS_SMALL) {
vdU[0] = ( Icci2.IciB[ki].dU + 0.) * dFactor ;
vdU[1] = ( Icci2.IciB[ki].dU + 0.) * 2 * dFactor ;
}
else
bIsOn = true ;
@@ -1019,8 +1059,11 @@ IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICu
bool
IntersCrvCompoCrvCompo::MergeNewOverlap( int i, bool bCrvAOrB)
{
if ( i >= ssize(m_Info))
return false ;
// faccio il merge col precedente
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
if ( m_Info[j].bOverlap) {
m_Info[i].IciA[0] = m_Info[j].IciA[0] ;
m_Info[i].IciB[0] = m_Info[j].IciB[0] ;
@@ -1159,21 +1202,25 @@ SortGreaterB( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
dU1 = aInfo1.IciB[0].dU ;
if ( aInfo1.bOverlap) {
// caso normale
if ( aInfo1.IciB[0].dU < aInfo1.IciB[1].dU)
if ( ( aInfo1.bCBOverEq && aInfo1.IciB[0].dU < aInfo1.IciB[1].dU) || ( ! aInfo1.bCBOverEq && aInfo1.IciB[0].dU > aInfo1.IciB[1].dU))
dU1 = 0.5 * ( aInfo1.IciB[0].dU + aInfo1.IciB[1].dU) ;
// a cavallo di fine / inizio
else
else if ( aInfo1.bCBOverEq)
dU1 = aInfo1.IciB[0].dU + SPAN_PARAM ;
else
dU1 = aInfo1.IciB[1].dU + SPAN_PARAM ;
}
// determino il secondo termine del confronto
dU2 = aInfo2.IciB[0].dU ;
if ( aInfo2.bOverlap) {
// caso normale
if ( aInfo2.IciB[0].dU < aInfo2.IciB[1].dU)
if ( ( aInfo2.bCBOverEq && aInfo2.IciB[0].dU < aInfo2.IciB[1].dU) || ( ! aInfo2.bCBOverEq && aInfo2.IciB[0].dU > aInfo2.IciB[1].dU))
dU2 = 0.5 * ( aInfo2.IciB[0].dU + aInfo2.IciB[1].dU) ;
// a cavallo di fine / inizio
else
else if ( aInfo2.bCBOverEq)
dU2 = aInfo2.IciB[0].dU + SPAN_PARAM ;
else
dU2 = aInfo2.IciB[1].dU + SPAN_PARAM ;
}
return ( dU2 > dU1 + EPS_PARAM) ;
+22 -2
View File
@@ -576,9 +576,25 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
}
}
// costruisco il vettore delle classificazioni
for ( int i = 0 ; i < nNumInters ; ++ i) {
for ( int i = 0 ; i < nNumInters ; ++ i) {
// se è definito un tratto precedente
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
/*int j = i < nNumInters - 1 ? i + 1 : -1 ;
if ( pCurve->IsClosed() && j == - 1)
j = 0 ;*/
int j = i == 0 ? -1 : i - 1 ;
if ( pCurve->IsClosed() && j == - 1)
j = nNumInters - 1 ;
bool bSpike = false ;
if ( j != -1) {
bSpike = InfoCorr[i].bOverlap && InfoCorr[j].bOverlap && InfoCorr[i].bCBOverEq != InfoCorr[j].bCBOverEq ;
if ( bSpike) {
bSpike = abs( InfoCorr[i].IciA[0].dU - InfoCorr[j].IciA[0].dU) < EPS_PARAM ||
abs( InfoCorr[i].IciA[0].dU - InfoCorr[j].IciA[1].dU) < EPS_PARAM ||
abs( InfoCorr[i].IciA[1].dU - InfoCorr[j].IciA[0].dU) < EPS_PARAM ||
abs( InfoCorr[i].IciA[1].dU - InfoCorr[j].IciA[1].dU) < EPS_PARAM ;
}
}
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
// verifico che la definizione sul tratto sia omogenea e valida
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
@@ -610,7 +626,11 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
// salvo dati correnti
dCurrPar = InfoCorr[i].IciA[1].dU ;
dCurrLen = dLenU ;
nLastTy = InfoCorr[i].IciA[1].nNextTy ;
// se sono in un caso di spike devo trattare l'overlap in modo diverso
if ( ! bSpike)
nLastTy = InfoCorr[i].IciA[1].nNextTy ;
else
nLastTy = InfoCorr[i].IciA[0].nPrevTy ;
}
}
// eventuale tratto finale rimasto
+10
View File
@@ -235,6 +235,16 @@ IntersCurvePlane::GetIntersCount( void)
return m_nIntersCount ;
}
//----------------------------------------------------------------------------
bool
IntersCurvePlane::GetIntCrvPlnInfo( int nInd, IntCrvPlnInfo& aInfo)
{
if ( nInd < 0 || nInd >= m_nIntersCount)
return false ;
aInfo = m_Info[nInd] ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurvePlane::GetIntersPointNearTo( const Point3d& ptNear, Point3d& ptI, double& dParam)
+36
View File
@@ -733,6 +733,42 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
return Release( pSbz) ;
}
//-------------------------------------------------------------------------------
ISurfBezier*
GetSurfBezierRuledSmooth( const ICurve* pCurve1, const ICurve* pCurve2, double dSampleLen)
{
// verifica parametri
if ( pCurve1 == nullptr || pCurve2 == nullptr)
return nullptr ;
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
// se la curva è già una bezier singola la tengo, sennò la converto
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
if ( pCurve1->GetType() != CRV_BEZIER)
pCC1->AddCurve( CurveToBezierCurve( pCurve1, 3, false)) ;
else
pCC1->AddCurve( pCurve1->Clone()) ;
if ( IsNull( pCC1) || ! pCC1->IsValid())
return nullptr ;
// se la curva è già una bezier singola la tengo, sennò la converto
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
if ( pCurve2->GetType() != CRV_BEZIER)
pCC2->AddCurve( CurveToBezierCurve( pCurve2, 3, false)) ;
else
pCC2->AddCurve( pCurve2->Clone()) ;
if ( IsNull( pCC2) || ! pCC2->IsValid())
return nullptr ;
// creo e setto la superficie trimesh
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
if ( IsNull( pSbz) || ! pSbz->CreateSmoothRuledByTwoCurves( pCC1, pCC2, dSampleLen))
return nullptr ;
// restituisco la superficie
return Release( pSbz) ;
}
//-------------------------------------------------------------------------------
ISurfBezier*
GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const BIPNTVECTOR& vCrv, double dLinTol)
+1126 -258
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -153,6 +153,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
bool CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const BIPNTVECTOR& vCrv) ;
bool RemoveCollapsedSpans( void) override ;
bool SwapParameters( void) ;
bool LimitSurfToTrimmedRegion( void) override ;
bool CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen) override ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
-4
View File
@@ -352,10 +352,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const Point3d& ptMin, const Point3d& pt
}
// se ho fatto solo 1 split orizzontale e ho due celle foglie nId = 0 e nId = 1
if ( m_mTree.size() == 3 && ! m_mTree.at(-1).IsSplitVert()) {
m_mTree[0].m_nLeft = -1 ;
m_mTree[0].m_nRight = -1 ;
m_mTree[1].m_nLeft = -1 ;
m_mTree[1].m_nRight = -1 ;
m_mTree[0].SetSplitDirVert( true) ;
Split( 0) ;
m_mTree[1].SetSplitDirVert( true) ;
+111 -2
View File
@@ -284,6 +284,115 @@ GetPointSetByAngTol( const PolyLine& PL, double dAngTol, POLYLINEVECTOR& vPL)
return true ;
}
//-----------------------------------------------------------------------------
// Funzione per spezzare una curva compo in diversi tratti in corrispondenza
// di cambi di direzione maggiori della tolleranza angolare passata
static bool
SplitCurveCompoByAngTol( const ICurveComposite* pCC, double dAngTol, ICRVCOMPOPOVECTOR& vCC)
{
int nCurves = pCC->GetCurveCount() ;
vCC.emplace_back( CreateCurveComposite()) ;
vCC.back()->AddCurve( pCC->GetCurve(0)->Clone()) ;
// Cos della tolleranza angolare massima
double dCosTol = cos( dAngTol * DEGTORAD) ;
for ( int nC = 0 ; nC < nCurves - 2; ++ nC) {
// Recupero l'angolo tra la fine della curva corrente e l'inizio della successiva
const ICurve* pCrvCurr = pCC->GetCurve( nC) ;
const ICurve* pCrvNext = pCC->GetCurve( nC + 1) ;
Vector3d vtCurrEnd ; pCrvCurr->GetEndDir( vtCurrEnd) ;
Vector3d vtNextStart ; pCrvNext->GetStartDir( vtNextStart) ;
// Calcolo il Coseno tra i due versori
double dCos = vtCurrEnd * vtNextStart ;
// Se dentro alla tolleranza, allora i punti apparterranno alla stessa curva
if ( dCos > dCosTol) {
// Aggiungo la curva
vCC.back()->AddCurve( pCrvNext->Clone()) ;
}
// Se tratto al di fuori della tolleranza, devo definire una nuova curva
else {
vCC.emplace_back( CreateCurveComposite()) ;
vCC.back()->AddCurve( pCrvNext->Clone()) ;
}
}
// Se curva originale chiusa
if ( pCC->IsClosed() && ssize( vCC) > 1) {
// Se ho più tratti, potrei riunire il primo con l'ultimo
const ICurve* pCrvFirst = pCC->GetCurve( 0) ;
const ICurve* pCrvLast = pCC->GetCurve( nCurves - 1) ;
Vector3d vtFirstStart ; pCrvFirst->GetEndDir( vtFirstStart) ;
Vector3d vtLastEnd ; pCrvLast->GetStartDir( vtLastEnd) ;
// Calcolo il Coseno tra i due versori
double dCos = vtFirstStart * vtLastEnd ;
// Se dentro alla tolleranza, allora i punti appartengono alla stessa curva
if ( dCos > dCosTol) {
// Aggiungo la curva
vCC.back()->AddCurve( Release( vCC.front())) ;
vCC.erase( vCC.begin()) ;
}
}
return true ;
}
////-----------------------------------------------------------------------------
//// Funzione che approssima la curva di bordo per la costruzione della Bezier Ruled mediante
//// Patches di curve di Bezier
//static bool
//ApproxBorder( ICurveComposite* pCrvCompo, double dLinTol, double dAngTol, double dAngTolSplit)
//{
// // N.B.:in futuro bisognerebbe fare l'approssimazione direttamente con le bezier.
//
// // Controllo dei parametri
// if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid())
// return false ;
//
// // splitto la curva considerando la tolleranza angolare
// ICRVCOMPOPOVECTOR vCC ;
// SplitCurveCompoByAngTol( pCrvCompo, dAngTolSplit, vCC) ;
// #if DEBUG_BEZIER_INTERP
// VT.clear() ;
// for( int i = 0 ; i < ssize(vCC) ; ++i)
// VT.push_back( vCC[i]->Clone()) ;
// SaveGeoObj( VT, "D:\\Temp\\trimming\\AngBorderApprox.nge") ;
// VT.clear() ;
// #endif
//
// pCrvCompo->Clear() ;
//
// // Ogni PolyLine ricavata viene approssimata con un tratto di Bezier
// const double MAXLEN = 1.5 ;
// for ( ICurveComposite* pCC : vCC) {
// // Se meno di due curve, non la considero ( non dovrebbe mai capitare )
// if ( pCC->GetCurveCount() < 2)
// continue ;
// PolyArc PA ;
// if ( ! pCC->ApproxWithArcs( dLinTol, dAngTol, PA))
// return false ;
// CurveComposite CrvTemp ;
// if ( ! CrvTemp.FromPolyArc( PA) || ! CrvTemp.MergeCurves( dLinTol, dAngTol))
// return false ;
// #if DEBUG_BEZIER_INTERP
// VT.emplace_back( CrvTemp->Clone()) ;
// #endif
// // Converto in Bezier
// PtrOwner<ICurve> pCrvBz( CurveToBezierCurve( &CrvTemp)) ;
// if ( IsNull( pCrvBz) || ! pCrvBz->IsValid()) {
// LOG_ERROR( GetEGkLogger(), "Error : converrting curve to bezier") ;
// return false ;
// }
// // Aggiungo il tratto approssimato alla curva finale complessiva
// if ( ! pCrvCompo->AddCurve( Release( pCrvBz)))
// return false ;
// }
// #if DEBUG_BEZIER_INTERP
// SaveGeoObj( VT, VC, "D:\\Temp\\trimming\\bezier_edge.nge") ;
// #endif
//
// return ( pCrvCompo->IsValid()) ;
//}
//-----------------------------------------------------------------------------
// Funzione che approssima la curva di bordo per la costruzione della Bezier Ruled mediante
// Patches di curve di Bezier
@@ -4110,7 +4219,7 @@ GetTrimmingRuledBezier( const CISURFPVECTOR& vSurf, const ICurve* pCrvEdge1,
// Se non ho punti di controllo forzati
if ( vSyncPoints.empty()) {
pSurfBz.Set( GetSurfBezierRuled( pCompoEdge1, pCompoEdge2, ISurfBezier::RLT_B_MINDIST_PLUS, dMyLinTol)) ;
pSurfBz.Set( GetSurfBezierRuledSmooth( pCompoEdge1, pCompoEdge2, 10)) ;
if ( IsNull( pSurfBz) || ! pSurfBz->IsValid()) {
LOG_ERROR( GetEGkLogger(), "Error in Trimming : Ruled Bezier invalid") ;
return nullptr ;
@@ -4746,7 +4855,7 @@ GetTrimmingHoleBorders( const CISURFPVECTOR& vpSurf, const Point3d& ptRef, doubl
// Scorro le curve successive
for ( int j = i + 1 ; nIndJ == -1 && j < ssize( vHoles) ; ++ j) {
// Recupero la curva corrente, se non presente allora passo alla successiva
if ( IsNull( vHoles[i].pCompoHole))
if ( IsNull( vHoles[j].pCompoHole))
continue ;
// Se il tipo è differente non possono essere in coppia
if ( vHoles[i].nType != vHoles[j].nType)
+42 -23
View File
@@ -1765,6 +1765,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
Vector3d vtDirTip = ptP2T - ptP1T ;
bool bTopIsPivot = vtDirTop.IsSmall() ;
bool bTipIsPivot = vtDirTip.IsSmall() ;
bool bSmallMovement = vtDirTop.Len() < 10 * EPS_SMALL && vtDirTip.Len() < 10 * EPS_SMALL ;
bool bInverse = ! (bTopIsPivot || bTipIsPivot) && vtDirTop * vtDirTip < 0 ;
if ( bInverse)
@@ -1857,26 +1858,44 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
}
vector<PNTVECTOR> vvPtCtrl ;
// superficie laterale sinistra
CurveLine cLineLeftBottom ; cLineLeftBottom.Set( vPntTipEndFront.back(), vPntTipStartFront.back()) ;
if ( bInverse)
cLineLeftBottom.Invert() ;
PtrOwner<CurveBezier> cBezLeftBottom( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftBottom, nDegU, bRat))) ;
CurveLine cLineLeftTop ; cLineLeftTop.Set( vPntTopEndFront.back(), vPntTopStartFront.back()) ;
PtrOwner<CurveBezier> cBezLeftTop( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftTop, nDegU, bRat))) ;
vvPtCtrl.emplace_back( cBezLeftBottom->GetAllControlPoints()) ;
PNTVECTOR vPntLeft = cBezLeftTop->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntLeft.begin(), vPntLeft.end()) ;
// superficie laterale destra
CurveLine cLineRightBottom ; cLineRightBottom.Set( vPntTipStartFront.front(), vPntTipEndFront.front()) ;
if ( bInverse)
cLineRightBottom.Invert() ;
PtrOwner<CurveBezier> cBezRightBottom( GetBasicCurveBezier( LineToBezierCurve( &cLineRightBottom, nDegU, bRat))) ;
CurveLine cLineRightTop ; cLineRightTop.Set( vPntTopStartFront.front(), vPntTopEndFront.front()) ;
PtrOwner<CurveBezier> cBezRightTop( GetBasicCurveBezier( LineToBezierCurve( &cLineRightTop, nDegU, bRat))) ;
vvPtCtrl.emplace_back( cBezRightBottom->GetAllControlPoints()) ;
PNTVECTOR vPntRight = cBezRightTop->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntRight.begin(), vPntRight.end()) ;
if ( ! bSmallMovement) {
// superficie laterale sinistra
CurveLine cLineLeftBottom ; cLineLeftBottom.Set( vPntTipEndFront.back(), vPntTipStartFront.back()) ;
if ( ! cLineLeftBottom.IsValid())
return false ;
if ( bInverse)
cLineLeftBottom.Invert() ;
PtrOwner<CurveBezier> cBezLeftBottom( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftBottom, nDegU, bRat))) ;
if ( IsNull( cBezLeftBottom))
return false ;
CurveLine cLineLeftTop ; cLineLeftTop.Set( vPntTopEndFront.back(), vPntTopStartFront.back()) ;
if ( ! cLineLeftTop.IsValid())
return false ;
PtrOwner<CurveBezier> cBezLeftTop( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftTop, nDegU, bRat))) ;
if ( IsNull( cBezLeftTop))
return false ;
vvPtCtrl.emplace_back( cBezLeftBottom->GetAllControlPoints()) ;
PNTVECTOR vPntLeft = cBezLeftTop->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntLeft.begin(), vPntLeft.end()) ;
// superficie laterale destra
CurveLine cLineRightBottom ; cLineRightBottom.Set( vPntTipStartFront.front(), vPntTipEndFront.front()) ;
if ( ! cLineRightBottom.IsValid())
return false ;
if ( bInverse)
cLineRightBottom.Invert() ;
PtrOwner<CurveBezier> cBezRightBottom( GetBasicCurveBezier( LineToBezierCurve( &cLineRightBottom, nDegU, bRat))) ;
if ( IsNull( cBezRightBottom))
return false ;
CurveLine cLineRightTop ; cLineRightTop.Set( vPntTopStartFront.front(), vPntTopEndFront.front()) ;
if ( ! cLineRightTop.IsValid())
return false ;
PtrOwner<CurveBezier> cBezRightTop( GetBasicCurveBezier( LineToBezierCurve( &cLineRightTop, nDegU, bRat))) ;
if ( IsNull( cBezRightTop))
return false ;
vvPtCtrl.emplace_back( cBezRightBottom->GetAllControlPoints()) ;
PNTVECTOR vPntRight = cBezRightTop->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntRight.begin(), vPntRight.end()) ;
}
if ( nSub == 1) {
// superficie inferiore
vvPtCtrl.emplace_back( PNTVECTOR( { vPntTipStartFront.front(), vPntTipStartFront.back(), vPntTipEndFront.front(), vPntTipEndFront.back() })) ;
@@ -2116,7 +2135,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
vvPtCtrl.emplace_back( cBezTipEndF2->GetAllControlPoints()) ;
PNTVECTOR vPntEndF2 = cBezTopEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntEndF2.begin(), vPntEndF2.end()) ;
if ( bInverse) {
if ( bInverse || bSmallMovement) {
// chiudo il volume con le superici verticali end back 1
vvPtCtrl.emplace_back( cBezTipEndB1->GetAllControlPoints()) ;
PNTVECTOR vPntEndB1 = cBezTopEndB1->GetAllControlPoints() ;
@@ -2135,7 +2154,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
vvPtCtrl.emplace_back( cBezTipStartB2->GetAllControlPoints()) ;
PNTVECTOR vPntStartB2 = cBezTopStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntStartB2.begin(), vPntStartB2.end()) ;
if ( bInverse) {
if ( bInverse || bSmallMovement) {
// chiudo il volume con le superici verticali start front 1
vvPtCtrl.emplace_back( cBezTipStartF1->GetAllControlPoints()) ;
PNTVECTOR vPntStartF1 = cBezTopStartF1->GetAllControlPoints() ;
@@ -2215,7 +2234,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
}
// inizializzo le superfici bilineari e i parametri per le intersezioni
for ( int z = 0 ; z < int( vvPtCtrl.size()) ; ++z) {
for ( int z = 0 ; z < ssize( vvPtCtrl) ; ++z) {
vSurfBez[nSurfInd].sBez.Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 0, vvPtCtrl[z][0]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 1, vvPtCtrl[z][1]) ;