EgtGeomKernel :

- in CalcPocketing aggiunto un frame Locale XY per semplificazione conti e migliorata la gestione della svuotature a trapezio.
This commit is contained in:
Riccardo Elitropi
2024-07-23 11:52:43 +02:00
parent cba9c253e1
commit 5375752609
+109 -169
View File
@@ -69,12 +69,10 @@ struct PocketParams {
double dToolFeed = 1000 ; // feed del tool
// -------------------------------------------------------
bool bAllClosed = true ; // flag per indicare se tutti i bordi sono chiusi
Frame3d frLocXY ; // frame per conti nel piano XY
} ;
static double TOL_TRAPEZOID = 50 * EPS_SMALL ; // tolleranza per casi a trapezio SpiralPocket
static int TMP_PROP_SINGLE_CURVE = 3 ; // percorso singola curva aperta ( seguendo i chiusi)
static int TMP_PROP_CRV_OPEN_SIDE = 2 ; // segmento per entrata da fuori
static int TMP_PROP_OPT_TRAPEZOID = 4 ; // caso ottimizzato Trapezio
//---------------------------------------------------------------------------
@@ -1066,8 +1064,8 @@ AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite* pCompo, const PocketPara
//----------------------------------------------------------------------------
static bool
ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, const Vector3d& vtN,
Vector3d& vtMidOut, bool bEndOrStart)
ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, Vector3d& vtMidOut,
bool bEndOrStart)
{
// controllo dei parametri
if ( pCrvPath == nullptr || ! pCrvPath->IsValid())
@@ -1088,7 +1086,7 @@ ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams,
if ( ! PockParams.SfrLimit.IsValid()) {
// aggiungo al ritorno l'uscita
pCrvPath->AddLine( ptOut, bEndOrStart) ;
pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out
pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TEMP_PROP_OUT_START, 0) ; // nProp 2 per le curve LeadIn/Out
pCrvPath->SetCurveTempParam( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), GetMinFeed( PockParams) , 0) ; // Feed minima
return true ;
}
@@ -1099,14 +1097,6 @@ ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams,
// Offset della regione
pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset, ICurve::OFF_FILLET) ;
// creo sistema di riferimento locale per piano XY
Point3d ptFr ; pCrvPath->GetStartPoint( ptFr) ;
Frame3d frLoc ;
if ( ! frLoc.Set( ptFr, vtN))
return false ;
// porto la superficie limite in questo frame
pSfrLimit->ToLoc( frLoc) ;
// ruoto il versore di uscita cercando un'entrata valida
Vector3d vtRotMidOut = vtMidOut ;
@@ -1115,19 +1105,17 @@ ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams,
PtrOwner<ICurveArc> pCrvToolShape( CreateCurveArc()) ;
if ( IsNull( pCrvToolShape) || ! pCrvToolShape->Set( ptOut, Z_AX, PockParams.dRad))
return false ;
// porto la curva nel frame locale
pCrvToolShape->ToLoc( frLoc) ;
// controllo l'intersezione ( pSfrLimit e pCrvToolShape sono nel piano XY)
CRVCVECTOR ccClass ;
if ( pSfrLimit->GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) &&
int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) {
// aggiungo al ritorno l'uscita
pCrvPath->AddLine( ptOut, bEndOrStart) ;
pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out
pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TEMP_PROP_OUT_START, 0) ; // nProp 2 per le curve LeadIn/Out
pCrvPath->SetCurveTempParam( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), GetMinFeed( PockParams) , 0) ; // Feed minima
return true ;
}
vtRotMidOut.Rotate( vtN, - ANG_RIGHT) ;
vtRotMidOut.Rotate( Z_AX, - ANG_RIGHT) ;
ptOut = ptMidOpen + vtRotMidOut * ( PockParams.dRad + PockParams.dOpenMinSafe) ;
}
@@ -1814,13 +1802,17 @@ ChainCompoCurves( ICRVCOMPOPOVECTOR& vCrvCompo)
//----------------------------------------------------------------------------
static bool
AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, bool bCalcFeed)
AdjustBorderCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, bool bCalcFeed)
{
/*
sistemazione punto di inizio, segmento per LeadIn, e Feed
( Se la curva è chiusa, allora si può cambiare il punto d'inizio)
*/
// se non ho curve, allora non faccio nulla
if ( vCrvCompo.empty())
return true ;
// controllo validità delle curve
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i)
if ( IsNull( vCrvCompo[i]) || ! vCrvCompo[i]->IsValid())
@@ -1835,8 +1827,6 @@ AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams,
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 - 250 * EPS_SMALL, ICurve::OFF_FILLET) ; // c'è un offset radiale, quindi tengo tolleranza alta
}
// per ogni curva signola, aggiungo l'entrata da fuori se ammissibile
@@ -1882,7 +1872,7 @@ AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams,
}
if ( bAllowLeadIn) { // se ammessa entrata da fuori
vCrvCompo[i]->AddLine( ptFall, false) ;
vCrvCompo[i]->SetCurveTempProp( 0, TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out
vCrvCompo[i]->SetCurveTempProp( 0, TEMP_PROP_OUT_START, 0) ; // nProp 2 per le curve LeadIn/Out
vCrvCompo[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed massima
break ; // interrompo a prescindere l'iterazione per i punti iniziali
}
@@ -1904,7 +1894,7 @@ AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams,
GetFeedForParam( 2 * dMaxOffs, PockParams, dFeed) ;
AssignCustomFeed( vCrvCompo[i], PockParams, dFeed) ;
// imposto il flag di curva singola
vCrvCompo[i]->SetTempProp( TMP_PROP_SINGLE_CURVE, 0) ; //nProp per curva singola
vCrvCompo[i]->SetTempProp( TEMP_PROP_SINGLE_CURVE, 0) ; //nProp per curva singola
}
}
@@ -2264,7 +2254,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams, ICRVCOMP
if ( ! ChainCompoCurves( vCrvCompoRes))
return false ;
// determino ora il punto di inizio, il tratto per il LeadIn e la Feed delle curve singole
if ( ! AdjustOpenCurves( vCrvCompoRes, PockParams, true))
if ( ! AdjustBorderCurves( vCrvCompoRes, PockParams, true))
return false ;
// se ho rimosso tutti i Chunk con una singola curva, allora ho terminato la svuotatura
@@ -2289,7 +2279,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams, ICRVCOMP
//----------------------------------------------------------------------------
static bool
GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOtherCrv,
const Frame3d& frPocket, const PocketParams& PockParams, Point3d& ptMid, Vector3d& vtMidOrt)
const PocketParams& PockParams, Point3d& ptMid, Vector3d& vtMidOrt)
{
// recupero il vettore estrusione
Vector3d vtExtr = Z_AX ;
@@ -2386,14 +2376,6 @@ GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOth
ptFirstOpenValid = ptMid ;
vtFirstOpenValid = vtMidOrt ;
}
// controllo se questa quantità è effettivamente fuori dal grezzo
// ( privilegio i lati aperti che sono effettivamente sul bordo del grezzo)
// punto iniziale nel sistema di riferimento globale
Point3d ptStart ; pCompoClone->GetStartPoint( ptStart) ;
ptStart.ToGlob( frPocket) ;
// vettore d'uscita nel sistema di riferimento globale
Vector3d vtMidOut = vtMidOrt ;
vtMidOut.ToGlob( frPocket) ;
}
}
dLenPrev = dLen ;
@@ -2419,13 +2401,12 @@ GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOth
//----------------------------------------------------------------------------
static bool
SetSpecialPtStartForOpenEdges( const ICurveComposite* pCrvOrig, const Frame3d& frPocket,
const PocketParams& PockParams, ICurveComposite* pCrvCompo, Point3d& ptStart,
SetSpecialPtStartForOpenEdges( const ICurveComposite* pCrvOrig, const PocketParams& PockParams,
ICurveComposite* pCrvCompo, Point3d& ptStart,
Vector3d& vtMidOut, bool& bMidOut)
{
// controllo dei parametri
if ( pCrvOrig == nullptr || ! pCrvOrig->IsValid() ||
! frPocket.IsValid() ||
pCrvCompo == nullptr || ! pCrvCompo->IsValid())
return false ;
@@ -2559,8 +2540,8 @@ AssignOpenCloseTmpPropToFirstOffsCurve( ICurveComposite* pCrv, const PocketParam
//----------------------------------------------------------------------------
static bool
SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams, const ISurfFlatRegion* pSrfToWork,
const Point3d& ptEndPrec, const Frame3d& frPocket, Point3d& ptStart,
Vector3d& vtMidOut, bool& bMidOut, int nOffs, const ICurveComposite* pCrvOrig)
const Point3d& ptEndPrec, Point3d& ptStart, Vector3d& vtMidOut, bool& bMidOut,
int nOffs, const ICurveComposite* pCrvOrig)
{
// ============================= INFO ==============================================================
// pCrvOffsAct -> Curva di Offset su cui cercare ptStart, vtMidOut, bMidOpen
@@ -2678,10 +2659,10 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
if ( nOffs == 1 && pCrvOrig != nullptr && pCrvOrig->IsValid()) {
// in questo caso le curve a fagiolo dei lati aperti a sinistra e a destra potrebbero
// intersecarsi tra loro -> risulta difficile calcolare il versore direzione d'uscita
bOK = SetSpecialPtStartForOpenEdges( pCrvOrig, frPocket, PockParams, pCrv, ptStart, vtMidOut, bMidOut) ;
bOK = SetSpecialPtStartForOpenEdges( pCrvOrig, PockParams, pCrv, ptStart, vtMidOut, bMidOut) ;
}
if ( ! bOK) /* ( 2.2 ) */
bMidOut = GetParamOnOpenSide( pCrv, vOtherCrv, frPocket, PockParams, ptStart, vtMidOut) ;
bMidOut = GetParamOnOpenSide( pCrv, vOtherCrv, PockParams, ptStart, vtMidOut) ;
}
if ( bMidOut) { // se ho trovato e valido, allora imposto il punto inziale trovato
const double LEN_OUT = 5 ;
@@ -2705,9 +2686,8 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
//----------------------------------------------------------------------------
static bool
SetAdvancedPtStartForPath( ICRVCOMPOPOVECTOR& vCrvOffsAct, const PocketParams& PockParams, const ISurfFlatRegion* pSrfToWork,
const Point3d& ptEndPrec, const Frame3d& frPocket, Point3d& ptStart,
Vector3d& vtMidOut, bool& bMidOut, int& nIndex, int nOffs,
ICRVCOMPOPOVECTOR& vCrvOrigChunkLoops)
const Point3d& ptEndPrec, Point3d& ptStart, Vector3d& vtMidOut,
bool& bMidOut, int& nIndex, int nOffs, ICRVCOMPOPOVECTOR& vCrvOrigChunkLoops)
{
// controllo dei parametri
for ( int i = 0 ; i < int( vCrvOffsAct.size()) ; ++ i)
@@ -2725,9 +2705,8 @@ SetAdvancedPtStartForPath( ICRVCOMPOPOVECTOR& vCrvOffsAct, const PocketParams& P
Point3d ptStart_first ;
for ( int i = 0 ; i < int( vCrvOffsAct.size()) ; ++ i) {
// cambio il suo punto d'inizio dell'Offset attuale
if ( SetPtStartForPath( vCrvOffsAct[i], PockParams, pSrfToWork, ptEndPrec, frPocket, ptStart,
vtMidOut, bMidOut, nOffs,
( int( vCrvOrigChunkLoops.size()) < i) ? Get( vCrvOrigChunkLoops[i]) : nullptr))
if ( SetPtStartForPath( vCrvOffsAct[i], PockParams, pSrfToWork, ptEndPrec, ptStart, vtMidOut,
bMidOut, nOffs, ( int( vCrvOrigChunkLoops.size()) < i) ? Get( vCrvOrigChunkLoops[i]) : nullptr))
vCrvOffsAct[i]->GetStartPoint( ptStart) ;
else
return false ;
@@ -2776,7 +2755,7 @@ GetOptCrvIndex( const ISurfFlatRegion* pSfrOrig, const ISurfFlatRegion* pSfrChun
// se la superficie originale ha un solo Chunk, allora le curve originali sono già trovate
for ( int l = 0 ; l < pSfrOrig->GetLoopCount( 0) ; ++ l)
vCrvOrig.emplace_back( ConvertCurveToComposite( pSfrOrig->GetLoop( 0, l))) ; // sono inizializzate...
vCrvOrig.emplace_back( ConvertCurveToComposite( pSfrOrig->GetLoop( 0, l))) ;
if ( pSfrOrig->GetChunkCount() == 1)
return true ;
@@ -3227,7 +3206,12 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr
// se la curva è già un trapezio, non sempre devo adattarla...
Point3d pt ; Vector3d vtDir, vtB2, vtOtherDir ;
if ( pCrvCompo->IsATrapezoid( 100 * EPS_SMALL, pt, vtDir, vtOtherDir, vtB2)) {
pCrvTrap->AddCurve( pCrvCompo->Clone()) ;
// data la tolleranza, creo la curva a trapezio dai 4 punti
pCrvTrap->AddPoint( pt) ;
pCrvTrap->AddLine( pt + vtDir) ;
pCrvTrap->AddLine( pt + vtOtherDir + vtB2) ;
pCrvTrap->AddLine( pt + vtOtherDir) ;
pCrvTrap->Close() ;
// se parallelogramma scelgo come base i lati lunghi
Vector3d vtL2( - vtDir + vtOtherDir + vtB2) ;
if ( AreSameOrOppositeVectorApprox( vtOtherDir, vtL2)) {
@@ -3237,13 +3221,6 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr
vtDir.Normalize() ;
Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir) ;
dPocketSize = vtOrtho.Len() ;
// eventuale approssimazione della curva con polyline per ottenere la stessa curva calcolata in ICurveComposite::IsATrapezoid
if ( pCrvCompo->GetCurveCount() > 4) {
PolyLine PL ;
if ( ! pCrvCompo->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return false ;
pCrvTrap->FromPolyLine( PL) ;
}
if ( ! CalcTrapezoidSpiralLocalFrame( pCrvTrap, vtDir, frTrap))
return false ;
bool bBaseOpen = false ;
@@ -6064,7 +6041,7 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con
//----------------------------------------------------------------------------
static bool
CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, const int nOffsCount,
const int nIter, const Vector3d& vtN, const PocketParams& PockParams, bool& bInsert)
const int nIter, const PocketParams& PockParams, bool& bInsert)
{
// controllo dei parametri
@@ -6124,7 +6101,7 @@ CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, c
return true ;
// frame locale, recupero DimX e DimY
Frame3d frLoc ; frLoc.Set( ptC, vtN, vtX) ;
Frame3d frLoc ; frLoc.Set( ptC, Z_AX, vtX) ;
if ( ! frLoc.IsValid())
return true ;
BBox3d bBox ;
@@ -6163,18 +6140,11 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
if ( IsNull( pSrfToWork) || pSrfToWork->GetChunkCount() == 0)
return false;
// porto il Chunk c-esimo nel sistema di riferimento locale
Vector3d vtExtr = pSrfToWork->GetNormVersor() ;
Point3d ptCen ; pSrfToWork->GetCentroid( ptCen) ;
Frame3d frPocket ; frPocket.Set( ptCen, vtExtr) ;
// CONTROLLO PER CASI OTTIMIZZATI
// ---------------------------------- Casi ottimizzati ----------------------------------
bool bHasIsland = ( pSrfPock->GetLoopCount( 0) > 1) ;
// se non ho isole e curva valida allora controllo casi ottimizzati
if ( ! PockParams.bAvoidOpt && ! bHasIsland &&
( ! vCrvOrigChunkLoops.empty()) && ! IsNull( vCrvOrigChunkLoops[0])) {
// --------------------------- caso spirale ---------------------------------------
PtrOwner<ICurveComposite> pCrvBorder( ConvertCurveToComposite( pSrfPock->GetLoop( 0, 0))) ;
if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid())
@@ -6209,7 +6179,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
else
return true ;
}
// -------------------------- caso trapezoide ---------------------------------------
PtrOwner<ICurveComposite> pCrvTrap( CreateCurveComposite()) ;
if ( IsNull( pCrvTrap))
@@ -6217,17 +6186,13 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
Frame3d frTrap ;
double dPocketSize ;
int nBase, nSecondBase ;
vCrvOrigChunkLoops[0]->ToLoc( frPocket) ;
if ( ! GetTrapezoidFromShape( vCrvOrigChunkLoops[0], pCrvTrap, frTrap, PockParams, dPocketSize, nBase, nSecondBase))
return false ;
vCrvOrigChunkLoops[0]->ToGlob( frPocket) ;
if ( pCrvTrap->IsValid()) {
pCrvTrap->SetExtrusion( vtExtr) ;
pCrvTrap->SetExtrusion( Z_AX) ;
if ( nReg == 0) {
CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, PockParams, pMCrv, pRCrv, bOptimizedTrap) ;
if ( bOptimizedTrap) {
pMCrv->ToGlob( frPocket) ;
pRCrv->ToGlob( frPocket) ;
nReg = 1 ;
return true ;
}
@@ -6238,9 +6203,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
}
// porto la superficie nel frame corrente
pSrfToWork->ToLoc( frPocket) ;
// ciclo di offset verso l'interno
const int MAX_ITER = 1000 ;
int nIter = 0 ;
@@ -6294,7 +6256,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
pCrvCompoBorder->Invert() ;
// controllo quali regioni di Offset possono essere sostituite
bool bInsert = true ;
if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, int( vOffs.size()), nIter, vtExtr, PockParams, bInsert))
if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, int( vOffs.size()), nIter, PockParams, bInsert))
return false ;
if ( bInsert)
vOffs.emplace_back( Release( pCrvCompoBorder)) ;
@@ -6335,29 +6297,25 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
return true ;
// cambio il punto iniziale della prima Curva di Offset
Point3d ptRef = PockParams.ptEnd ; ptRef.ToLoc( frPocket) ;
Point3d ptRef = PockParams.ptEnd ;
Point3d ptNewStart ;
if ( ! IsNull( vCrvOrigChunkLoops[0]))
vCrvOrigChunkLoops[0]->ToLoc( frPocket) ;
// Se ho come lavorazione uno SpiralIn posso poter entrare dalle isole aperte...
int nIndexSwap = 0 ; // indice del vettore di curve per identificare la curva su cui entrare
if ( PockParams.nType == POCKET_SPIRALIN) {
if ( SetAdvancedPtStartForPath( vOffsFirstCurve, PockParams, pSrfToWork, ptRef, frPocket,
ptStart, vtMidOut, bMidOut, nIndexSwap, int( vOffs.size()), vCrvOrigChunkLoops))
if ( SetAdvancedPtStartForPath( vOffsFirstCurve, PockParams, pSrfToWork, ptRef, ptStart,
vtMidOut, bMidOut, nIndexSwap, int( vOffs.size()), vCrvOrigChunkLoops))
vOffsFirstCurve[nIndexSwap]->GetStartPoint( ptNewStart) ;
else
return false ;
}
else {
if ( SetPtStartForPath( vOffs[0], PockParams, pSrfToWork, ptRef, frPocket, ptStart, vtMidOut, bMidOut,
if ( SetPtStartForPath( vOffs[0], PockParams, pSrfToWork, ptRef, ptStart, vtMidOut, bMidOut,
int( vOffs.size()), vCrvOrigChunkLoops[0]))
vOffs[0]->GetStartPoint( ptNewStart) ;
else
return false ;
}
if ( ! IsNull( vCrvOrigChunkLoops[0]))
vCrvOrigChunkLoops[0]->ToGlob( frPocket) ;
// se richiesta inversione
for ( int i = 0 ; i < int( vOffs.size()) && PockParams.bInvert ; ++ i)
@@ -6387,8 +6345,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
return false ;
// controllo eventuali parti non svuotate...
if ( ! IsNull( vCrvOrigChunkLoops[0]))
vCrvOrigChunkLoops[0]->ToLoc( frPocket) ;
PtrOwner<ISurfFlatRegion> pSrfToCut( CreateSurfFlatRegion()) ;
if ( GetUnclearedRegion( vOffsFirstCurve, vOffs, vLinks, vCrvOrigChunkLoops[0], PockParams, pSrfToCut)) {
// Modifico i percorsi
@@ -6422,15 +6378,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
}
// setto estrusione
pMCrv->SetExtrusion( vtExtr) ;
// riporto tutto nel sistema di riferimento originale
pMCrv->ToGlob( frPocket) ;
ptStart.ToGlob( frPocket) ;
vtMidOut.ToGlob( frPocket) ;
if ( ! IsNull( vCrvOrigChunkLoops[0]))
vCrvOrigChunkLoops[0]->ToGlob( frPocket) ;
pMCrv->SetExtrusion( Z_AX) ;
return true ;
}
@@ -6960,10 +6908,10 @@ AddSpiralIn( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig,
if ( bOptimizedTrap) { // se caso a trapezio
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, PockParams) ;
AssignFeedSpiralOpt( 1, PockParams, pMCrv) ;
pMCrv->SetTempProp( TMP_PROP_OPT_TRAPEZOID, 0) ;
pMCrv->SetTempProp( TEMP_PROP_OPT_TRAPEZOID, 0) ;
}
else if ( bSomeOpen) { // se presenza di lati aperti validi
if ( ! ExtendPathOnOpenEdge( pMCrv, PockParams, pSrfChunk->GetNormVersor(), vtMidOut, false))
if ( ! ExtendPathOnOpenEdge( pMCrv, PockParams, vtMidOut, false))
return false ;
}
@@ -7026,7 +6974,7 @@ AddSpiralOut( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig,
if ( bOptimizedTrap) { // se caso a trapezio
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, PockParams) ;
AssignFeedSpiralOpt( 1, PockParams, pMCrv) ;
pMCrv->SetTempProp( TMP_PROP_OPT_TRAPEZOID, 0) ;
pMCrv->SetTempProp( TEMP_PROP_OPT_TRAPEZOID, 0) ;
}
// inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato)
@@ -7064,7 +7012,7 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams&
pSfrLimit.Set( PockParams.SfrLimit.Clone()) ;
if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid())
return false ;
pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset, ICurve::OFF_FILLET) ;
pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset - 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
}
// vettore delle curve chiuse Offsettate
@@ -7080,8 +7028,8 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams&
// recupero i tratti con proprietà uniformi
ICRVCOMPOPOVECTOR vpCrvs ;
GetHomogeneousParts( pCrvLoop, 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)
if ( vpCrvs.size() > 1) {
// unisco il primo e l'ultimo se estremi compatibili
Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ;
Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ;
if ( AreSamePointApprox( ptS, ptE)) {
@@ -7089,11 +7037,20 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams&
vpCrvs.erase( vpCrvs.end() - 1) ;
}
}
// le isole aperte vanno percorse
bool bOpenIsland = ( nL > 0 && int( vpCrvs.size()) == 1 &&
vpCrvs[0]->GetTempProp() == TEMP_PROP_OPEN_EDGE) ;
// scorro tutti i tratti chiusi e calcolo l'Offset
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
if ( vpCrvs[i]->GetTempProp( 0) == 0) { // se tratto chiuso...
OffsetCurve OffsCrv ; // con offset verso l'interno
if ( OffsCrv.Make( vpCrvs[i], - PockParams.dRad - PockParams.dRadialOffset, ICurve::OFF_FILLET)) {
// se tratto chiuso o isola aperta
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE || bOpenIsland) {
// Offset per le curve
OffsetCurve OffsCrv ;
double dOffs = - PockParams.dRad - PockParams.dRadialOffset ;
// se isole, l'Offset è di segno opposto
if ( nL > 0)
dOffs *= -1 ;
if ( OffsCrv.Make( vpCrvs[i], dOffs, ICurve::OFF_FILLET)) {
PtrOwner<ICurve> pOffLongestCrv( OffsCrv.GetLongerCurve()) ;
while ( ! IsNull( pOffLongestCrv)) {
// recupero solo i tratti di curva al di fuori della superficie limite
@@ -7129,7 +7086,7 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams&
if ( ! ChainCompoCurves( vClosedOffs))
return false ;
// determino ora il punto di inizio, il tratto per il LeadIn
if ( ! AdjustOpenCurves( vClosedOffs, PockParams, false))
if ( ! AdjustBorderCurves( vClosedOffs, PockParams, false))
return false ;
// Calcolo ora le Feed e restituisco le curve ottenute
@@ -7149,25 +7106,19 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams&
//----------------------------------------------------------------------------
static bool
AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams, ICRVCOMPOPOVECTOR& vCrvCompoRes)
AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams,
ICRVCOMPOPOVECTOR& vCrvCompoRes)
{
// Offset della regione per curva ZigZag
double dOffs = PockParams.dRad + PockParams.dRadialOffset ;
// determino il sistema di riferimento in base alla svuotatura
Frame3d frPocket ;
Point3d ptCen ; pSrfPock->GetCentroid( ptCen) ;
if ( ! frPocket.Set( ptCen, pSrfPock->GetNormVersor()) ||
! frPocket.Rotate( ptCen, pSrfPock->GetNormVersor(), PockParams.dAngle))
return false ;
// ciclo su tutti i chunks della superficie originale
for ( int nC = 0 ; nC < pSrfPock->GetChunkCount() ; ++ nC) {
// creo la regione per il percorso a ZigZag ( mediante primo Offset) portandola
// nel sistema di riferimento creato
PtrOwner<ISurfFlatRegion> pSrfZigZag( pSrfPock->CloneChunk( nC)) ;
if ( ! pSrfZigZag->ToLoc( frPocket) || ! pSrfZigZag->Offset( - dOffs, ICurve::OFF_FILLET))
if ( ! pSrfZigZag->Offset( - dOffs, ICurve::OFF_FILLET))
return false ;
// vettore con i percorsi a ZigZag relativi al Chunk nC-esimo
ICRVCOMPOPOVECTOR vpCrvs ;
@@ -7193,8 +7144,6 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con
for ( int nU = 0 ; nU < int( vpCrvs.size()) ; ++ nU) {
// pulisco le tempProp
ResetCurveTempProps( vpCrvs[nU]) ;
// porto la curva in globale
vpCrvs[nU]->ToGlob( frPocket) ;
// se il Chunk originale aveva lati aperti, estendo il percorso a ZigZag
if ( ! bIsChunkClosed) {
bool bIsInside = false ;
@@ -7205,13 +7154,13 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con
ptStart.Translate( 0.25 * PockParams.dRad * vtStart) ;
double dMinDist = max( 0., - PockParams.dRadialOffset) ;
if ( IsPointInsideSurfFr( ptStart, pSfrOrig, dMinDist, bIsInside) && ! bIsInside)
ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, pSrfPock->GetNormVersor(), vtStart, false) ;
ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, vtStart, false) ;
// controllo se il punto finale è esterno alla superficie originale
Point3d ptEnd ; vpCrvs[nU]->GetEndPoint( ptEnd) ;
Vector3d vtEnd ; vpCrvs[nU]->GetEndDir( vtEnd) ;
ptEnd.Translate( ( 0.25 * PockParams.dRad) * vtEnd) ;
ptEnd.Translate( 0.25 * PockParams.dRad * vtEnd) ;
if ( IsPointInsideSurfFr( ptEnd, pSfrOrig, dMinDist, bIsInside) && ! bIsInside)
ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, pSrfPock->GetNormVersor(), vtEnd, true) ;
ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, vtEnd, true) ;
}
// inserisco le curve nel vettore risultante
vCrvCompoRes.emplace_back( Release( vpCrvs[nU])) ;
@@ -7220,9 +7169,8 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con
vpCrvs.clear() ;
}
// se richiesto, aggiungo le curve chiuso di Bordo
// se richiesto, aggiungo le curve chiuse di Bordo
if ( PockParams.bAllowZigZagOneWayBorders) {
ICRVCOMPOPOVECTOR vCrvOffs ;
// recupero il Chunk nC-esimo
PtrOwner<ISurfFlatRegion> pSfrChunk( pSrfPock->CloneChunk( nC)) ;
if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid() ||
@@ -7319,42 +7267,21 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con
PtrOwner<ISurfFlatRegion> pSrfToPock( pSrfPock->Clone()) ;
if ( IsNull( pSrfToPock))
return false ;
// creo le regioni ideali --------------------------------------------
// creo un frame di riferimento della svuotatura
Frame3d frLoc ;
Point3d ptC ; pSrfToPock->GetCentroid( ptC) ;
Vector3d vtN = pSrfToPock->GetNormVersor() ;
frLoc.Set( ptC, vtN) ;
pSrfToPock->ToLoc( frLoc) ;
ISURFFRPOVECTOR vSrfFlat ; // vettore delle regioni ideali
// vettore delle regioni ideali
ISURFFRPOVECTOR vSrfFlat ;
if ( ! OptimizeChunkOneWay( pSrfToPock, vSrfFlat))
return false ;
// riporto le superfici ideali nel sistema di riferimento globale ( Ogni chunk verrà poi messo nel suo frame)
for ( int i = 0 ; i < int( vSrfFlat.size()) ; ++ i)
vSrfFlat[i]->ToGlob( frLoc) ;
// ------------------------------------------------------------------
// scorro le regioni ideali
for ( int nIs = 0 ; nIs < int( vSrfFlat.size()) ; ++ nIs) {
// copio la superficie ideale
PtrOwner<ISurfFlatRegion> pSrfIdeal( vSrfFlat[nIs]->Clone()) ;
if ( IsNull( pSrfIdeal))
// copio la superficie ideale ed effettuo il primo Offset
PtrOwner<ISurfFlatRegion> pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIs])) ;
if ( IsNull( pSrfIdeal) || ! pSrfIdeal->Offset( - dOffs, ICurve::OFF_FILLET))
return false ;
// effettuo Offset interno
if ( ! pSrfIdeal->Offset( - dOffs, ICurve::OFF_FILLET))
return false ;
// creo un frame coerente con i parametri
Frame3d frPocket ;
Point3d ptCen ; pSrfIdeal->GetCentroid( ptCen) ;
frPocket.Set( ptCen, pSrfIdeal->GetNormVersor()) ;
frPocket.Rotate ( ptCen, pSrfIdeal->GetNormVersor(), PockParams.dAngle) ;
pSrfIdeal->ToLoc( frPocket) ;
// recupero il Box della superficie attuale da svuotare
BBox3d b3Pocket ; pSrfIdeal->GetLocalBBox( b3Pocket) ;
Point3d ptMin ; double dDimX, dDimY, dDimZ ;
b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
@@ -7417,7 +7344,6 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con
pCrvSegCompo->AddCurve( Release( pCrvSeg)) ;
// calcolo la Feed
AssignFeedZigZagOneWay( pCrvSegCompo, false, vCrvNull, vLineUnder, vCrvCompoNull, PockParams) ;
pCrvSegCompo->ToGlob( frPocket) ;
vCrvCompoRes.emplace_back( Release( pCrvSegCompo)) ;
}
}
@@ -7457,47 +7383,61 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
myParams.bAvoidOpt = bAvoidOpt ;
if ( pSfrLimit != nullptr && pSfrLimit->IsValid())
myParams.SfrLimit.CopyFrom( pSfrLimit) ;
// ------------ gestione dei lati aperti -------------------
// creo un sistema di riferimento locale
Point3d ptCenter ; pSfr->GetCentroid( ptCenter) ;
Vector3d vtN = pSfr->GetNormVersor() ;
Frame3d frLoc ;
if ( ! frLoc.Set( ptCenter, vtN))
if ( ! myParams.frLocXY.Set( ptCenter, pSfr->GetNormVersor()) ||
! myParams.frLocXY.Rotate( ptCenter, pSfr->GetNormVersor() , myParams.dAngle))
return false ;
// porto la superficie da svuotare in tale sistema
PtrOwner<ISurfFlatRegion> pSfrAdj( pSfr->Clone()) ;
if ( IsNull( pSfrAdj) || ! pSfrAdj->ToLoc( frLoc))
if ( IsNull( pSfrAdj) || ! pSfrAdj->ToLoc( myParams.frLocXY))
return false ;
// porto la superficie limite ( se valida) in tale sistema
if ( myParams.SfrLimit.IsValid())
myParams.SfrLimit.ToLoc( frLoc) ;
myParams.SfrLimit.ToLoc( myParams.frLocXY) ;
// ------------ gestione dei lati aperti -------------------
// modifico la superficie da svuotare estendendo i lati aperti
bool bSkipPocket = false ; // se la superficie si svuota mediante curve singole di primo Offset dei chiusi
if ( ! ModifySurfByOpenEdges( pSfrAdj, myParams, vCrvCompoRes, bSkipPocket))
return false ;
// se ottengo delle curve si svuotatura di primo Offset, le riporto in globale
for ( int i = 0 ; i < int( vCrvCompoRes.size()) ; ++ i)
vCrvCompoRes[i]->ToGlob( frLoc) ;
if ( bSkipPocket) // se tali curva rimuovono tutta la regione, allora non faccio nulla
// se le curve di primo offset che ho ottenuto, svuotano tutta la superficie, allora ho finito
if ( bSkipPocket) {
// riporto le curve in Globale
for ( int i = 0 ; i < int( vCrvCompoRes.size()) ; ++ i)
vCrvCompoRes[i]->ToGlob( myParams.frLocXY) ;
return true ;
// riporto tutto nel frame originale
pSfrAdj->ToGlob( frLoc) ;
if ( myParams.SfrLimit.IsValid())
myParams.SfrLimit.ToGlob( frLoc) ;
}
// porto una copia della superficie originale nel frame creato
PtrOwner<ISurfFlatRegion> pSfr_Loc( CloneSurfFlatRegion( pSfr)) ;
if ( IsNull( pSfr_Loc) || ! pSfr_Loc->IsValid() || ! pSfr_Loc->ToLoc( myParams.frLocXY))
return false ;
// ------------ calcolo delle curve elementari della superficie -------------------
switch ( nType) {
case POCKET_ZIGZAG :
return AddZigZag( pSfrAdj, pSfr, myParams, vCrvCompoRes) ;
if ( ! AddZigZag( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes))
return false ;
break ;
case POCKET_ONEWAY :
return AddOneWay( pSfrAdj, pSfr, myParams, vCrvCompoRes) ;
if ( ! AddOneWay( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes))
return false ;
break ;
case POCKET_SPIRALIN :
return AddSpiralIn( pSfrAdj, pSfr, myParams, vCrvCompoRes) ;
if ( ! AddSpiralIn( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes))
return false ;
break ;
case POCKET_SPIRALOUT :
return AddSpiralOut( pSfrAdj, pSfr, myParams, vCrvCompoRes) ;
if ( ! AddSpiralOut( pSfrAdj, pSfr, myParams, vCrvCompoRes))
return false ;
break ;
}
return false ;
// riporto tutte le curve ottenute in globale
for ( int i = 0 ; i < int( vCrvCompoRes.size()) ; ++ i)
vCrvCompoRes[i]->ToGlob( myParams.frLocXY) ;
return true ;
}
//----------------------------------------------------------------------------