Compare commits

...

3 Commits

Author SHA1 Message Date
Riccardo Elitropi 37aaa98df6 EgtGeomKernel 3.1e3 :
- in CalcPocketing aggiunta gestione per ToolCompensation.
2026-05-14 15:24:47 +02:00
Dario Sassi 2dcaa57aa3 EgtGeomKernel :
- modifiche a RMF per avere la tangente media sul punto di calcolo (utile solo se la curva non è G1)
- modifiche a GetSurfTriMeshSwept per avere RMF anche con curve piane garantendo la retrocompatibilità.
2026-05-14 13:02:47 +02:00
Riccardo Elitropi ba7379e752 EgtGeomKernel :
- In CalcPocketing aggiunto flag per Conventional Milling.
2026-05-12 09:34:56 +02:00
4 changed files with 185 additions and 79 deletions
+172 -73
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
//----------------------------------------------------------------------------
// File : EGkCalcPocketing.h Data : 16.11.23 Versione : 2.5j1
// File : EGkCalcPocketing.cpp Data : 16.11.23 Versione : 2.5j1
// Contenuto : Dichiarazione della funzione per calcolare le curve base di Pocketing
//
//
@@ -66,6 +66,7 @@ struct PocketParams {
bool bSmooth = false ; // curve smussate
bool bInvert = false ; // inversione dei percorsi
bool bAvoidOpt = false ; // flag per evitare casi ottimizzati
bool bConventionalMilling = true ; // flag per Conventional Milling Vs Climb Milling per svuotature a curva singola
bool bAllowZigZagOneWayBorders = false ; // flag per abilitare le curve di bordo per ZigZag/OneWay
Point3d ptStart = P_INVALID ; // punto d'inizio
Point3d ptEnd = P_INVALID ; // punto di fine
@@ -84,9 +85,12 @@ struct PocketParams {
bool bPolishing = false ; // flag per lucidatura
double dEpicyclesRad = 0. ; // raggio degli epicicli
double dEpicyclesDist = 0. ; // distanza degli epicicli
// --------------------------------------------------------
bool bToolCompensation = false ; // flag aggiungere un percorso di contornatura
} ;
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
static double TOL_COMPENSATION_MIN_RAD = 100. * EPS_SMALL ; // tolleranza per creazione archi per angoli interni se richiesto il contorno
typedef vector<ICRVCOMPOPOVECTOR> VICRVCOMPOPOVECTOR ;
//---------------------------------------------------------------------------
@@ -1020,7 +1024,9 @@ GetIndOfHypoteticalChunk( const ICRVCOMPOPOVECTOR& vCrv, const ICurveComposite*
static double
GetExtendPathLen( const PocketParams& PockParam)
{
return ( Clamp( 2. * PockParam.dRad - PockParam.dOpenEdgeRad, 0., PockParam.dRad) + PockParam.dOpenMinSafe) ;
double dDistToolCenterWithMaterial = PockParam.dOpenEdgeRad - PockParam.dRad - PockParam.dRadialOffset ;
double dOutDist = Clamp( PockParam.dRad - dDistToolCenterWithMaterial, 0., PockParam.dRad) ;
return dOutDist + PockParam.dOpenMinSafe ;
}
//----------------------------------------------------------------------------
@@ -1061,7 +1067,7 @@ ExtendPath( ICurveComposite* pCompo, const ISurfFlatRegion* pSfr, const PocketPa
const array vAngles{ 0., ANG_RIGHT, 3 * ANG_RIGHT, ANG_45, 3 * ANG_45, 5 * ANG_45, 7 * ANG_45} ;
// ruoto il versore di uscita cercando un'entrata valida
double dMinDist = PockParams.dRad + PockParams.dRadialOffset ;
double dMinDist = 0. ;
for ( int i = 0 ; i < ssize( vAngles) ; ++ i) {
// ruoto il versore d'uscita
Vector3d vtRotOut = GetRotate( vtFirstOut, Z_AX, - vAngles[i]) ;
@@ -2114,7 +2120,7 @@ GetSinglePocketingCurves( ISurfFlatRegion* pSfr, PocketParams& PockParams,
return false ;
// imposto le Feed e inverto i percorsi per tali curve se richiesto
bool bAllowInvert = ( PockParams.nType == POCKET_ZIGZAG || PockParams.nType == POCKET_CONFORMAL_ZIGZAG) ;
bool bAllowInvert = ( ! PockParams.bConventionalMilling) ;
for ( int i = 0 ; i < ssize( vCrvSingleCurves) ; ++ i) {
/*
Idea : Feed proporzionale al minimo Offset per annullare la regione
@@ -2719,7 +2725,7 @@ IsForcedStepTrapezoid( const ICurveComposite* pCrvTrap, const PocketParams& Pock
break ;
}
}
bForced = ( dLenOpen < dDiam + TOL_TRAPEZOID) ;
bForced = ( dLenOpen < dDiam + 2. * PockParam.dRadialOffset + TOL_TRAPEZOID) ;
}
// se alternate, non forzo
else
@@ -2752,7 +2758,7 @@ IsForcedStepTrapezoid( const ICurveComposite* pCrvTrap, const PocketParams& Pock
break ;
}
}
bForced = ( dLenOpen < dDiam + TOL_TRAPEZOID) ;
bForced = ( dLenOpen < dDiam + 2. * PockParam.dRadialOffset + TOL_TRAPEZOID) ;
}
break ;
// se tutto chiuso, è forzato
@@ -3761,9 +3767,9 @@ AdjustTrapeziodLeadIn( ICurveComposite* pCrvRes, const PocketParams& PockParam,
// se esiste almeno un aperto
if ( nTmpProp > 0) {
// se solo lato3 aperto
bool bCheckHead = ( nTmpProp != 8 && nTmpProp != 2) ;
if ( nTmpProp == 2)
pCrvRes->Invert() ; // entro dall'unico aperto
bool bCheckHead = ( nTmpProp != 8 && nTmpProp != 2) ;
if ( bCheckHead) {
// recupero gli estremi della curva corrente e la inverto in base alla Testa
Point3d ptS ; pCrvRes->GetStartPoint( ptS) ;
@@ -3775,9 +3781,15 @@ AdjustTrapeziodLeadIn( ICurveComposite* pCrvRes, const PocketParams& PockParam,
pCrvRes->Invert() ;
}
}
else if ( ! PockParam.bConventionalMilling) { // per sgrossature
Point3d ptS ; pCrvRes->GetStartPoint( ptS) ;
Point3d ptE ; pCrvRes->GetEndPoint( ptE) ;
if ( SqDist( ptE, PockParam.ptEnd) < SqDist( ptE, PockParam.ptEnd) + EPS_SMALL)
pCrvRes->Invert() ;
}
// Assegno la Feed
AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ;
AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ;
// Se curva da invertire, inverto
if ( PockParam.bInvert)
pCrvRes->Invert() ;
@@ -3859,8 +3871,7 @@ GetZigZagOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
//----------------------------------------------------------------------------
static bool
GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams& PockParam,
ICurveComposite* pCrvRes)
GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, PocketParams& PockParam, ICurveComposite* pCrvRes)
{
// controllo dei parametri
if ( pSfrChunk == nullptr || ! pSfrChunk->IsValid())
@@ -3940,6 +3951,7 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
- E' richiesto che una dimensione del box della curva sia compatibile con il primo Offset, il
quale sarebbe una singola curva aperta
*/
bool bOkForToolCompensation = false ;
PtrOwner<ICurveComposite> pCrvTrap( CreateCurveComposite()) ;
if ( IsNull( pCrvTrap))
return false ;
@@ -3947,6 +3959,12 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
double dPocketSize ;
int nBase, nSecondBase ;
bool bOkTrap = GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) ;
// se è un percorso di Tool Compensation ed è un trapezio ma non svuotabile, provo normalmente
if ( PockParam.bToolCompensation && bOkTrap && ! pCrvTrap->IsValid()) {
PockParam.dRadialOffset -= PockParam.dSideStep ;
bOkTrap = GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) ;
bOkForToolCompensation = true ;
}
if ( bOkTrap && pCrvTrap->IsValid()) {
// verifico se il trapezio ottenuto deve o meno rispettare il SideStep
bool bForcedTrap = false ;
@@ -3977,14 +3995,15 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
}
}
}
if ( bOkForToolCompensation)
PockParam.dRadialOffset += PockParam.dSideStep ;
return true ;
}
//----------------------------------------------------------------------------
static bool
GetPocketingOptimizedCurves( ISurfFlatRegion* pSfr, const PocketParams& PockParam,
ICRVCOMPOPOVECTOR& vCrvOptCurves)
GetPocketingOptimizedCurves( ISurfFlatRegion* pSfr, PocketParams& PockParam, ICRVCOMPOPOVECTOR& vCrvOptCurves)
{
// controllo dei parametri
if ( pSfr == nullptr || ! pSfr->IsValid())
@@ -7341,10 +7360,14 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegio
if ( IsNull( pSfrLimit))
return false ;
if ( PockParams.SfrLimit.IsValid()) {
const double TOL_LIMIT = 50. * EPS_SMALL ;
pSfrLimit.Set( PockParams.SfrLimit.Clone()) ;
if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid())
return false ;
pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset - 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
double dOffs = PockParams.dRad + PockParams.dRadialOffset ;
if ( PockParams.bToolCompensation)
dOffs -= PockParams.dSideStep ;
pSfrLimit->Offset( dOffs - TOL_LIMIT, ICurve::OFF_FILLET) ;
}
// vettore delle curve chiuse Offsettate
@@ -7353,7 +7376,7 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegio
// scorro i Chunk e i Loop della regione ( se OneWay potrei avere più Chunks)
for ( int nC = 0 ; nC < pSfrPock->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrPock->GetLoopCount( nC) ; ++ nL) {
ICRVCOMPOPOVECTOR vClosedOffs_nC ;
ICRVCOMPOPOVECTOR vCrvChunk ;
// loop come curva composita
PtrOwner<ICurveComposite> pCrvLoop( ConvertCurveToComposite( pSfrPock->GetLoop( nC, nL))) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
@@ -7371,37 +7394,46 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegio
}
}
// le isole aperte vanno percorse
bool bOpenIsland = ( nL > 0 && int( vpCrvs.size()) == 1 &&
bool bOpenIsland = ( nL > 0 && ssize( vpCrvs) == 1 &&
vpCrvs[0]->GetTempProp() == TEMP_PROP_OPEN_EDGE) ;
// scorro tutti i tratti omogenei
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
// 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 ;
if ( PockParams.bToolCompensation)
dOffs += PockParams.dSideStep - TOL_COMPENSATION_MIN_RAD ;
// se isola aperta, allora l'offset è verso il suo interno
if ( bOpenIsland)
dOffs *= -1 ;
if ( OffsCrv.Make( vpCrvs[i], dOffs, ICurve::OFF_FILLET)) {
PtrOwner<ICurve> pOffLongestCrv( OffsCrv.GetLongerCurve()) ;
while ( ! IsNull( pOffLongestCrv)) {
while ( ! IsNull( pOffLongestCrv) && pOffLongestCrv->IsValid()) {
// se tool compensation effettuo un ulteriore controOffset
if ( PockParams.bToolCompensation) {
OffsetCurve OffsCrv1 ;
if ( ! OffsCrv1.Make( pOffLongestCrv, TOL_COMPENSATION_MIN_RAD, ICurve::OFF_FILLET) ||
! pOffLongestCrv.Set( OffsCrv1.GetLongerCurve()))
return true ;
}
// recupero solo i tratti di curva al di fuori della superficie limite
if ( pSfrLimit->IsValid()) {
CRVCVECTOR ccClass ;
if ( pSfrLimit->GetCurveClassification( *pOffLongestCrv, EPS_SMALL, ccClass)) {
for ( int j = 0 ; j < int( ccClass.size()) ; ++ j) {
for ( int j = 0 ; j < ssize( ccClass) ; ++ j) {
if ( ccClass[j].nClass == CRVC_OUT) {
// recupero il tratto di curva
PtrOwner<ICurve> pCrv( pOffLongestCrv->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ;
if ( ! IsNull( pCrv) && pCrv->IsValid())
vClosedOffs_nC.emplace_back( ConvertCurveToComposite( Release( pCrv))) ;
vCrvChunk.emplace_back( ConvertCurveToComposite( Release( pCrv))) ;
}
}
}
}
else
vClosedOffs_nC.emplace_back( ConvertCurveToComposite( Release( pOffLongestCrv))) ;
vCrvChunk.emplace_back( ConvertCurveToComposite( Release( pOffLongestCrv))) ;
// passo alla successiva
pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ;
@@ -7410,26 +7442,26 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegio
}
}
// se non ho ricavato curve dal Loop nL-esimo, passo al successivo
if ( vClosedOffs_nC.empty())
if ( vCrvChunk.empty())
continue ;
// concateno eventuali percorsi
if ( ! ChainCompoCurves( vClosedOffs_nC))
if ( ! ChainCompoCurves( vCrvChunk))
return false ;
// miglioro le curve
for ( auto& crv : vClosedOffs_nC)
crv->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
for ( auto& Crv : vCrvChunk)
Crv->MergeCurves( 10. * EPS_SMALL, ANG_TOL_STD_DEG) ;
// determino ora il punto di inizio, il tratto per il LeadIn
bool bIsChunkClosed = false ;
bool bIsChunkAllOpen = false ;
if ( ! IsChunkAllHomogeneous( pSfrPock, nC, bIsChunkClosed, bIsChunkAllOpen))
return false ;
if ( ! AdvanceExtendCurves( vClosedOffs_nC, pSfrOrig, PockParams, true))
if ( ! AdvanceExtendCurves( vCrvChunk, pSfrOrig, PockParams, false))
return false ;
// aggiungo le curve ottenute al vettore
for ( int i = 0 ; i < int( vClosedOffs_nC.size()) ; ++ i)
vClosedOffs.emplace_back( Release( vClosedOffs_nC[i])) ;
for ( int i = 0 ; i < ssize( vCrvChunk) ; ++ i)
vClosedOffs.emplace_back( Release( vCrvChunk[i])) ;
}
}
// se non ho percorsi ho finito
@@ -7437,15 +7469,30 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegio
return true ;
// Calcolo ora le Feed e restituisco le curve ottenute
for ( int i = 0 ; i < int( vClosedOffs.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vClosedOffs) ; ++ i) {
// se ZigZag -> ho percorso i tratti a ZigZag, quindi posso andare a Feed massima
if ( PockParams.nType == POCKET_ZIGZAG)
if ( PockParams.nType == POCKET_ZIGZAG) {
AssignMaxFeed( vClosedOffs[i], PockParams) ;
vClosedOffs[i]->SetTempProp( PockParams.bToolCompensation ? TEMP_PROP_CONTOUR_BORDER : TEMP_PROP_BORDER_CURVE, 0) ;
}
// se OneWay -> prima percorro queste curva, quindi la Feed è minima
if ( PockParams.nType == POCKET_ONEWAY)
else if ( PockParams.nType == POCKET_ONEWAY) {
AssignMinFeed( vClosedOffs[i], PockParams) ;
// assegno la proprità alla curva composita
vClosedOffs[i]->SetTempProp( TEMP_PROP_BORDER_CURVE, 0) ;
vClosedOffs[i]->SetTempProp( PockParams.bToolCompensation ? TEMP_PROP_CONTOUR_BORDER : TEMP_PROP_BORDER_CURVE, 0) ;
}
// se Percorso di Contornatura
else if ( PockParams.bToolCompensation) {
double dFeed = GetMinFeed( PockParams) ;
GetFeedForParam( PockParams.dSideStep, PockParams, dFeed) ;
AssignCustomFeed( vClosedOffs[i], PockParams, dFeed) ;
vClosedOffs[i]->SetTempProp( TEMP_PROP_CONTOUR_BORDER, 0) ;
// se Svuotatura in SpiralOut il contorno esterno deve essere eseguito al contrario ( invert di SpiralIn)
if ( PockParams.nType == POCKET_SPIRALOUT)
vClosedOffs[i]->Invert() ;
}
// se presente flag di inversione, inverto le curve
if ( PockParams.bInvert)
vClosedOffs[i]->Invert() ;
// restituisco le curve ottenute
vCrvRes.emplace_back( Release( vClosedOffs[i])) ;
}
@@ -7553,7 +7600,7 @@ AddZigZag( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
}
// se richiesto, aggiungo le curve chiuse di Bordo
if ( PockParams.bAllowZigZagOneWayBorders && ! PockParams.bPolishing) {
if ( PockParams.bAllowZigZagOneWayBorders && ! PockParams.bPolishing && ! PockParams.bToolCompensation) {
// recupero il Chunk nC-esimo
PtrOwner<ISurfFlatRegion> pSfrChunk( pSrfPock->CloneChunk( nChunkInd)) ;
if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid() ||
@@ -7656,15 +7703,15 @@ AddOneWay( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
return false ;
// scorro le regioni ideali
for ( int nIs = 0 ; nIs < int( vSrfFlat.size()) ; ++ nIs) {
for ( int nIs = 0 ; nIs < ssize( vSrfFlat) ; ++ nIs) {
// copio la superficie ideale ed effettuo il primo Offset
PtrOwner<ISurfFlatRegion> pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIs])) ;
if ( IsNull( pSrfIdeal) || ! pSrfIdeal->Offset( - dOffs, ICurve::OFF_FILLET))
if ( IsNull( pSrfIdeal) || ! pSrfIdeal->Offset( - dOffs - dExtra, ICurve::OFF_FILLET))
return false ;
// se sono richieste le curve di Bordo, le aggiungo
if ( PockParams.bAllowZigZagOneWayBorders) {
if ( ( PockParams.bAllowZigZagOneWayBorders || PockParams.bToolCompensation) && ! PockParams.bPolishing) {
if ( ! GetZigZagOneWayBorderCrvs( vSrfFlat[nIs], pSfrOrig, PockParams, vCrvCompoRes))
return false ;
}
@@ -7709,10 +7756,9 @@ AddOneWay( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
// riempio il vettore di segmenti
CRVCVECTOR ccClassSeg ;
pSrfIdeal->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ;
for ( int w = 0 ; w < int( ccClassSeg.size()) ; ++ w) {
if ( ccClassSeg[w].nClass == CRVC_IN) {
PtrOwner<ICurveLine> pCrvSeg( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ;
for ( int j = 0 ; j < ssize( ccClassSeg) ; ++ j) {
if ( ccClassSeg[j].nClass == CRVC_IN) {
PtrOwner<ICurveLine> pCrvSeg( GetCurveLine( pLine->CopyParamRange( ccClassSeg[j].dParS, ccClassSeg[j].dParE))) ;
double duF, dLen ;
// accorcio leggermente il segmento per non toccare la prima curva di Offset
if ( ! pCrvSeg->GetLength( dLen) ||
@@ -7720,7 +7766,7 @@ AddOneWay( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
! pCrvSeg->GetParamAtLength( dLen - dExtra, duF) ||
! pCrvSeg->TrimStartAtLen( dExtra) ||
! pCrvSeg->TrimEndAtParam( duF))
pCrvSeg.Set( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ;
pCrvSeg.Set( GetCurveLine( pLine->CopyParamRange( ccClassSeg[j].dParS, ccClassSeg[j].dParE))) ;
// aggiungo il segmento al vettore dei tratti correnti
vAddedLines.emplace_back( pCrvSeg->Clone()) ;
@@ -7732,24 +7778,13 @@ AddOneWay( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
pCrvSegCompo->AddCurve( Release( pCrvSeg)) ;
// calcolo la Feed
AssignFeedZigZagOneWay( pCrvSegCompo, false, vCrvNull, vLineUnder, vCrvCompoNull, PockParams) ;
// estendo presso lati aperti se richiesto
if ( ! PockParams.bAllClosed) {
Vector3d vtRef ; pCrvSegCompo->GetStartDir( vtRef) ;
vtRef.Invert() ;
bool bIsExtended = false ;
if ( ! ExtendPath( pCrvSegCompo, pSfrOrig, PockParams, vtRef, false, GetExtendPathLen( PockParams), bIsExtended))
return false ;
pCrvSegCompo->GetEndDir( vtRef) ;
if ( ! ExtendPath( pCrvSegCompo, pSfrOrig, PockParams, vtRef, true, GetExtendPathLen( PockParams), bIsExtended))
return false ;
}
vCrvCompoRes.emplace_back( Release( pCrvSegCompo)) ;
}
}
// i tratti lineari correnti diventano i precedenti
vLineUnder.clear() ;
for ( int u = 0 ; u < int( vAddedLines.size()) ; ++ u)
vLineUnder.emplace_back( Release( vAddedLines[u])) ;
for ( int k = 0 ; k < ssize( vAddedLines) ; ++ k)
vLineUnder.emplace_back( Release( vAddedLines[k])) ;
}
}
@@ -9409,10 +9444,11 @@ CalcSpiralPocketing( const ISurfFlatRegion* pSfr, int nType, const PocketParams&
return ( CalcPocketing( pSfr, PockParams.dRad, PockParams.dRadialOffset, PockParams.dSideStep,
PockParams.dAngle, PockParams.dOpenMinSafe, nType, PockParams.bSmooth,
PockParams.bCalcUnclearedRegs, PockParams.bInvert, PockParams.bAvoidOpt,
PockParams.bAllowZigZagOneWayBorders, PockParams.bCalcFeed, PockParams.ptStart,
PockParams.bConventionalMilling, PockParams.bAllowZigZagOneWayBorders, PockParams.bCalcFeed, PockParams.ptStart,
pSfrLimit, PockParams.bAvoidOpt, PockParams.dMaxOptSize,
PockParams.nLiType, PockParams.dLiTang, PockParams.dLiElev, PockParams.nLoType, PockParams.dLoTang,
PockParams.bPolishing, PockParams.dEpicyclesRad, PockParams.dEpicyclesDist, vCrvCompoRes)) ;
PockParams.bPolishing, PockParams.dEpicyclesRad, PockParams.dEpicyclesDist, PockParams.bToolCompensation,
vCrvCompoRes)) ;
}
//----------------------------------------------------------------------------
@@ -9704,18 +9740,59 @@ SmoothExtensionLinesByIntersection( ICRVCOMPOPOVECTOR& vCrvPaths, const PocketPa
return true ;
}
//----------------------------------------------------------------------------
static bool
AddContours( const ISurfFlatRegion* pSfrOrig, PocketParams& PockParams, ICRVCOMPOPOVECTOR& vCrvCompoRes)
{
// se contorni non abilitati, non faccio nulla
if ( ! PockParams.bToolCompensation)
return true ;
// rimuovo tutti i contorni che non sono validi
vCrvCompoRes.erase(
remove_if( vCrvCompoRes.begin(), vCrvCompoRes.end(), []( ICurveComposite* pCrvContour) {
return ( pCrvContour == nullptr || ! pCrvContour->IsValid()) ; }), vCrvCompoRes.end()) ;
// riporto tutti i contorni nel frame Locale per i conti
for ( auto Iter = vCrvCompoRes.begin() ; Iter != vCrvCompoRes.end() ; ++ Iter)
( *Iter)->ToLoc( PockParams.frLocXY) ;
// se devo ripassare i contorni chiusi, tengo una regione di riferimento ( le funzioni successive
// rimuovo i chunk da tale regione se riescono a trovare dei percorsi)
// NB. La regione successivamente verrà estesa presso gli aperti, ma i chiusi non sono mai ricostruiti !
// se ho dei percorsi, recupero il punto finale di riferimento ( camberà solo l'inizio delle curve di bordo chiuso,
// le curve di bordo aperte devono mantenere il classico orientamento intrinseco)
if ( ! vCrvCompoRes.empty())
vCrvCompoRes.back()->GetEndPoint( PockParams.ptEnd) ;
ICRVCOMPOPOVECTOR vCrvContour ;
if ( ! GetZigZagOneWayBorderCrvs( pSfrOrig, pSfrOrig, PockParams, vCrvContour))
return false ;
vCrvContour.erase(
remove_if( vCrvContour.begin(), vCrvContour.end(), []( ICurveComposite* pCrvContour) {
return ( pCrvContour == nullptr || ! pCrvContour->IsValid()) ; }), vCrvContour.end()) ;
for ( int i = 0 ; i < ssize( vCrvContour) ; ++ i)
vCrvCompoRes.emplace_back( Release( vCrvContour[i])) ;
// riporto tutte le curve nel frame Globale
for ( auto Iter = vCrvCompoRes.begin() ; Iter != vCrvCompoRes.end() ; ++ Iter)
( *Iter)->ToGlob( PockParams.frLocXY) ;
return true ;
}
//----------------------------------------------------------------------------
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,
bool bConventionalMilling, bool bAllowZigZagOneWayBorders, bool bCalcFeed, const Point3d& ptEndPrec,
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)
bool bPolishing, double dEpicyclesRad, double dEpicyclesDist, bool bContour, ICRVCOMPOPOVECTOR& vCrvCompoRes)
{
// controllo dei parametri
if ( pSfr == nullptr || ! pSfr->IsValid() ||
dStep < 10 * EPS_SMALL ||
dStep < 10. * EPS_SMALL ||
( nType != POCKET_ZIGZAG && nType != POCKET_ONEWAY && nType != POCKET_SPIRALIN &&
nType != POCKET_SPIRALOUT && nType != POCKET_CONFORMAL_ZIGZAG && nType != POCKET_CONFORMAL_ONEWAY))
return false ;
@@ -9725,9 +9802,10 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
// assegno dati di modulo
PocketParams myParams ;
myParams.bToolCompensation = bContour ;
myParams.nType = nType ;
myParams.dRad = dRad ;
myParams.dRadialOffset = dRadOffs ;
myParams.dRadialOffset = dRadOffs + ( myParams.bToolCompensation ? dStep : 0.0) ;
myParams.bSmooth = bSmooth ;
myParams.dAngle = dAngle ;
myParams.dSideStep = dStep ;
@@ -9736,6 +9814,7 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
myParams.bInvert = bInvert ;
myParams.bAvoidOpt = bAvoidOpt ;
myParams.bCalcFeed = bCalcFeed ;
myParams.bConventionalMilling = bConventionalMilling ;
myParams.bAllowZigZagOneWayBorders = bAllowZigZagOneWayBorders ;
myParams.bOptOffsets = ( ! bAllOffs) ;
myParams.dMaxOptSize = dMaxOptSize ;
@@ -9770,62 +9849,76 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
if ( ! IsSfrAllHomogeneous( pSfr, myParams.bAllClosed, myParams.bAllOpen))
return false ;
// Se richiesti contorni tengo una copia della supericie attuale ( le funzioni sotto potrebbero rimuoverne dei Chunks)
PtrOwner<ISurfFlatRegion> pSfrContour( nullptr) ;
if ( myParams.bToolCompensation) {
if ( ! pSfrContour.Set( CloneSurfFlatRegion( pSfrAdj)) || ! pSfrAdj->IsValid())
return false ;
}
// ------------ casi ottimizzati ------------------------------------------
ICRVCOMPOPOVECTOR vCrvOptCurves ;
if ( ! GetPocketingOptimizedCurves( pSfrAdj, myParams, vCrvOptCurves))
return false ;
for ( int i = 0 ; i < int( vCrvOptCurves.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vCrvOptCurves) ; ++ i) {
vCrvOptCurves[i]->ToGlob( myParams.frLocXY) ;
vCrvCompoRes.emplace_back( Release( vCrvOptCurves[i])) ;
}
// se ho svuotato tutta la superficie, allora ho finito
if ( IsNull( pSfrAdj) || ! pSfrAdj->IsValid() || pSfrAdj->GetChunkCount() == 0)
if ( IsNull( pSfrAdj) || ! pSfrAdj->IsValid() || pSfrAdj->GetChunkCount() == 0) {
// se necessario aggiungo i bordi ed esco
if ( myParams.bToolCompensation)
return AddContours( pSfrContour, myParams, vCrvCompoRes) ;
return true ;
}
// ------------ recupero le singole curve di svuotatura -------------------
ICRVCOMPOPOVECTOR vCrvSingleCurves ;
if ( ! GetSinglePocketingCurves( pSfrAdj, myParams, vCrvSingleCurves))
return false ;
for ( int i = 0 ; i < int( vCrvSingleCurves.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vCrvSingleCurves) ; ++ i) {
vCrvSingleCurves[i]->ToGlob( myParams.frLocXY) ;
vCrvCompoRes.emplace_back( Release( vCrvSingleCurves[i])) ;
}
// se ho svuotato tutta la superficie, allora ho finito
if ( IsNull( pSfrAdj) || ! pSfrAdj->IsValid() || pSfrAdj->GetChunkCount() == 0)
if ( IsNull( pSfrAdj) || ! pSfrAdj->IsValid() || pSfrAdj->GetChunkCount() == 0) {
// se necessario aggiunfo i bordi ed esco
if ( myParams.bToolCompensation)
return AddContours( pSfrContour, myParams, vCrvCompoRes) ;
return true ;
}
// ------------ estensione lati aperti ------------------------------------
if ( ! ModifySurfByOpenEdges( pSfrAdj, myParams))
return false ;
// 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))
PtrOwner<ISurfFlatRegion> pSfrLoc( CloneSurfFlatRegion( pSfr)) ;
if ( IsNull( pSfrLoc) || ! pSfrLoc->IsValid() || ! pSfrLoc->ToLoc( myParams.frLocXY))
return false ;
// ------------ calcolo delle curve elementari della superficie -------------------
ICRVCOMPOPOVECTOR vCrvCompoPock ;
switch ( nType) {
case POCKET_ZIGZAG :
if ( ! AddZigZag( pSfrAdj, pSfr_Loc, myParams, vCrvCompoPock))
if ( ! AddZigZag( pSfrAdj, pSfrLoc, myParams, vCrvCompoPock))
return false ;
break ;
case POCKET_ONEWAY :
if ( ! AddOneWay( pSfrAdj, pSfr_Loc, myParams, vCrvCompoPock))
if ( ! AddOneWay( pSfrAdj, pSfrLoc, myParams, vCrvCompoPock))
return false ;
break ;
case POCKET_SPIRALIN :
if ( ! AddSpiralIn( pSfrAdj, pSfr_Loc, myParams, vCrvCompoPock))
if ( ! AddSpiralIn( pSfrAdj, pSfrLoc, myParams, vCrvCompoPock))
return false ;
break ;
case POCKET_SPIRALOUT :
if ( ! AddSpiralOut( pSfrAdj, pSfr_Loc, myParams, vCrvCompoPock))
if ( ! AddSpiralOut( pSfrAdj, pSfrLoc, myParams, vCrvCompoPock))
return false ;
break ;
case POCKET_CONFORMAL_ZIGZAG :
case POCKET_CONFORMAL_ONEWAY :
if ( ! AddConformal( pSfrAdj, pSfr_Loc, myParams, vCrvCompoPock))
if ( ! AddConformal( pSfrAdj, pSfrLoc, myParams, vCrvCompoPock))
return false ;
break ;
}
@@ -9837,11 +9930,17 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
}
// riporto tutte le curve ottenute in globale
for ( int i = 0 ; i < int( vCrvCompoPock.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vCrvCompoPock) ; ++ i) {
vCrvCompoPock[i]->ToGlob( myParams.frLocXY) ;
vCrvCompoRes.emplace_back( Release( vCrvCompoPock[i])) ;
}
// ------------ aggiunta dei contorni ( se richiesto) --------------------
if ( myParams.bToolCompensation && nType != POCKET_ONEWAY) {
if ( ! AddContours( pSfrContour, myParams, vCrvCompoRes))
return false ;
}
return true ;
}
BIN
View File
Binary file not shown.
+10 -3
View File
@@ -92,11 +92,18 @@ RotationMinimizingFrame::GetFrameAtParam( const Frame3d& frAct, const double dPa
Vector3d vtCurrR = frAct.VersX() ;
Vector3d vtCurrT = frAct.VersZ() ;
// punto i-esimo sulla curva e suo vettore tangente
// punto i-esimo sulla curva e suo vettore tangente medio
Point3d ptNextM, ptNextP ;
Vector3d vtNextM, vtNextP ;
if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNextM, &vtNextM) ||
! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_PLUS, ptNextP, &vtNextP) ||
! vtNextM.Normalize() || ! vtNextP.Normalize())
return false ;
Point3d ptNext ;
Vector3d vtNextT ;
if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNextT) ||
! vtNextT.Normalize())
ptNext = Media( ptNextM, ptNextP) ;
vtNextT = Media( vtNextM, vtNextP) ;
if ( ! vtNextT.Normalize())
return false ;
// controllo per casi degeneri
+3 -3
View File
@@ -1095,7 +1095,7 @@ GetSurfTriMeshSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// determino algoritmo da usare per calcolare i riferimenti lungo la curva
bool bRMF = vtAx.IsSmall() ;
bool bRMF = ( ! vtAx.IsValid() || vtAx.IsSmall()) ;
// riferimento all'inizio della linea guida
Point3d ptStart ;
@@ -1242,9 +1242,9 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, const Vector3d&
if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
bIsLine = true ;
}
// se la guida è piana
// se la guida è piana e il vettore di riferimento è non definito oppure non nullo
Plane3d plGuide ;
if ( pGuide->IsFlat( plGuide, bIsLine, 10 * EPS_SMALL))
if ( pGuide->IsFlat( plGuide, bIsLine, 10 * EPS_SMALL) && ( ! vtAx.IsValid() || ! vtAx.IsSmall()))
return GetSurfTriMeshSweptInPlane( pSect, pGuide, plGuide.GetVersN(), bCapEnds, dLinTol) ;
// altrimenti swept 3d