Compare commits
50 Commits
Nst_SurfFr
...
NewRuled
| Author | SHA1 | Date | |
|---|---|---|---|
| a3d44261bb | |||
| 9220fd568f | |||
| 17346e1b42 | |||
| c95ef6764d | |||
| d0f2d56bdb | |||
| fb037f2f2a | |||
| 2d94dddccb | |||
| d2d025a594 | |||
| 64abf640f6 | |||
| cb2b63320a | |||
| 951d3781d6 | |||
| 27bd0e579e | |||
| ff7d564de8 | |||
| a27b9e871a | |||
| eb497cbd39 | |||
| dd3091fc13 | |||
| 69d463713c | |||
| 5e918ff3aa | |||
| b4522c712d | |||
| fa9a9e89cb | |||
| d51a0d2258 | |||
| 580230b38b | |||
| 4b24906d2e | |||
| 2094a1cc0d | |||
| b8b639699a | |||
| 0b86c4f72b | |||
| 5c93384690 | |||
| b77db4a5bc | |||
| c704d94829 | |||
| 0373021b7a | |||
| 6de856b3e1 | |||
| a231d8f26c | |||
| 745a7eb38c | |||
| 78c40ebca7 | |||
| a39af1c3a3 | |||
| c2a0f9dff1 | |||
| 98c576afe0 | |||
| ae8f80d6e9 | |||
| 9b933bd26d | |||
| baa8736276 | |||
| c75a7e9514 | |||
| 233f64e68f | |||
| da7ebd6f61 | |||
| 8db1765505 | |||
| 5d2e1ff608 | |||
| a9f8ef2ff3 | |||
| a1c448d8dd | |||
| 25d53338c2 | |||
| 1ad96ce8ca | |||
| 36422c43b3 |
+390
-118
@@ -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())
|
||||
|
||||
@@ -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 ;
|
||||
} ;
|
||||
Binary file not shown.
+79
-32
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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 ;
|
||||
|
||||
@@ -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
@@ -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
@@ -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]) ;
|
||||
|
||||
Reference in New Issue
Block a user