EgtGeomKernel :

- migliorie a CalcPocketing.
This commit is contained in:
Riccardo Elitropi
2024-06-14 16:46:56 +02:00
parent 4fd03a78de
commit 5841c9cae0
+230 -49
View File
@@ -584,6 +584,94 @@ ExistOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParam, bool& bExi
return true ;
}
//----------------------------------------------------
static bool
ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const Vector3d& vtMainDir, bool bLeadIn,
PocketParams PockParams, bool& bIsOutsideRaw)
{
// inizializzazione come interno al grezzo
bIsOutsideRaw = false ;
Point3d ptP ;
Vector3d vtDir ;
if ( bLeadIn) {
pCompo->GetStartPoint( ptP) ;
pCompo->GetStartDir( vtDir) ;
}
else {
pCompo->GetEndPoint( ptP) ;
pCompo->GetEndDir( vtDir) ;
}
// recupero estrusione della curva
Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ;
// recupero info sui lati aperti
int nPropOpen = pCompo->GetTempProp( 0) ;
bool bEdgeOpen = (( nPropOpen & ( bLeadIn ? 8 : 2)) > 0) ;
bool bBase0Open = (( nPropOpen & 1) > 0) ;
bool bBase1Open = (( nPropOpen & 4) > 0) ;
// recupero info per capire se sto considerando un lato aggiuntivo per pulire angoli
int nIdCrv = ( bLeadIn ? 0 : pCompo->GetCurveCount() - 1) ;
int nExtraEdge ;
pCompo->GetCurveTempProp( nIdCrv, nExtraEdge) ;
// tento con allungamento se lato inclinato è aperto oppure se sto considerando un lato aggiuntivo per pulire angoli
if ( bEdgeOpen || nExtraEdge == 1) {
Vector3d vtDirP = ( bLeadIn ? -vtDir : vtDir) ;
Point3d ptNewStart = ptP + vtDirP * ( PockParams.dRad + PockParams.dOpenMinSafe) ;
pCompo->AddLine( ptNewStart, ! bLeadIn) ;
pCompo->SetCurveTempProp( bLeadIn ? 0 : pCompo->GetCurveCount() - 1, 2) ;
bIsOutsideRaw = true ;
}
// tento con attacco ruotato di 90° se non sto considerando un tratto aggiuntivo per pulire angoli
else if (( bBase0Open || bBase1Open) && ! bIsOutsideRaw && nExtraEdge == 0) {
Vector3d vtDirO = bBase0Open ? vtDir : - vtDir ;
vtDirO.Rotate( vtExtr, ( PockParams.bInvert ? -90 : 90)) ;
// se vicino al bordo del grezzo
Point3d ptNewStart = ptP + vtDirO * ( PockParams.dRad + PockParams.dOpenMinSafe) ;
pCompo->AddLine( ptNewStart, ! bLeadIn) ;
pCompo->SetCurveTempProp( bLeadIn ? 0 : pCompo->GetCurveCount() - 1, 2) ;
bIsOutsideRaw = true ;
}
return true ;
}
//----------------------------------------------------
static bool
AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite* pCompo, PocketParams PockParams)
{
// recupero la direzione principale della svuotatura
Vector3d vtMainDir ;
for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) {
int nProp ;
if ( pCompo->GetCurveTempProp( i, nProp) && nProp == 0) {
// se non è lato aggiuntivo per la pulitura angoli recupero la sua direzione
pCompo->GetCurve( i)->GetStartDir( vtMainDir) ;
break ;
}
}
// start point
bool bStartOutside = false ;
ComputeTrapezoidSpiralLeadInLeadOut( pCompo, vtMainDir, true, PockParams, bStartOutside) ;
// end point
bool bEndOutside = false ;
ComputeTrapezoidSpiralLeadInLeadOut( pCompo, vtMainDir, false, PockParams, bEndOutside) ;
// eventuale inversione della curva per partire sempre dall'esterno del grezzo
if ( bEndOutside && ! bStartOutside)
pCompo->Invert() ;
return true ;
}
//----------------------------------------------------------------------------
static bool
ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, const Vector3d& vtN,
@@ -1148,13 +1236,17 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
//----------------------------------------------------------------------------
static bool
AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvIsl, const double dDiam,
const double dOffR, const double dStep, const PocketParams& PockParams)
AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvIsl, const PocketParams& PockParams)
{
// controllo dei parametri
if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid())
return false ;
// recupero i parametri di lavorazione correnti
double dDiam = PockParams.dRad * 2 ;
double dOffR = PockParams.dRadialOffset ;
double dStep = PockParams.dSideStep ;
// raggio di riferimento per offset
double dOutEdge = 0.5 * dDiam ;
if ( PockParams.nType == POCKET_SPIRALIN || PockParams.nType == POCKET_ZIGZAG)
@@ -1311,10 +1403,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams)
bSomeOpen = true ;
if ( bSomeOpen) { // se trovo dei lati aperti
// 3.1) sistemo la superificie
if ( ! AdjustContourWithOpenEdges( pCrvEL, vCrvIsl, PockParams.dRad_prec > 0 ? 2 * PockParams.dRadialOffset_prec : 2 * PockParams.dRad,
PockParams.dRadialOffset_prec > 0 ? PockParams.dRadialOffset_prec : PockParams.dRadialOffset,
PockParams.dRad_prec > 0 ? PockParams.dSideStep_prec : PockParams.dSideStep,
PockParams))
if ( ! AdjustContourWithOpenEdges( pCrvEL, vCrvIsl, PockParams))
return false ;
bIsChunkModified = true ; // la curva è stata modificata
}
@@ -1397,7 +1486,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams)
pSfr->Clear() ;
pSfr->CopyFrom( pSrfFinal) ;
return pSrfFinal->IsValid() && pSrfFinal->GetChunkCount() > 0 ;
return ( pSrfFinal->IsValid() && pSrfFinal->GetChunkCount() > 0) ;
}
@@ -1519,17 +1608,6 @@ GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOth
// ricavo il punto fuori
Point3d ptOut = ptStart + vtMidOut * ( PockParams.dRad + PockParams.dRadialOffset +
( PockParams.dRad + PockParams.dOpenMinSafe)) ;
// controllo l'elevazione sopra a quel punto ( qui è un bel mistero...)
// double dElev = 0. ;
// if ( ! GetElevation( m_nPhase, ptOut, frPocket.VersZ(), m_TParams.m_dDiam, m_TParams.m_dLen,
// frPocket.VersZ(), dElev))
// return false ;
// se non vi è elevazione, il lato aperto trovato è il privilegiato
//if ( dElev < EPS_SMALL) {
// bFound = true ;
// if ( nPriorityOpenEdge > -1)
// return true ;
//}
}
}
dLenPrev = dLen ;
@@ -1566,7 +1644,7 @@ SetSpecialPtStartForOpenEdges( const ICurveComposite* pCrvOrig, const Frame3d& f
return false ;
// cerco il lato aperto più lungo
double dLenRef = ( 2 * PockParams.dRad) - 50 * EPS_SMALL ;
double dLenRef = ( 2 * PockParams.dRad) - 50 * EPS_SMALL ; // almeno di questa lunghezza
for ( int u = 0 ; u < pCrvOrig->GetCurveCount() ; ++ u) {
if ( pCrvOrig->GetCurve( u)->GetTempProp( 0) == 0)
continue ; // escludo le chiuse
@@ -1577,12 +1655,38 @@ SetSpecialPtStartForOpenEdges( const ICurveComposite* pCrvOrig, const Frame3d& f
// ricavo la lunghezza di tale curva
double dLen = 0. ;
pCrvOpen->GetLength( dLen) ;
if ( dLen > dLenRef) {
if ( dLen > dLenRef) { // se lunghezza accettabile o maggiore della massima trovata
Point3d ptSTmp ;
Vector3d vtMidOutTmp ;
// ricavo il punto medio e il versore tangente associato
if ( pCrvOpen->GetPointD1D2( 0.5, ICurve::FROM_MINUS, ptSTmp, &vtMidOutTmp)) {
int nFlag ;
if ( DistPointCurve( ptSTmp, *pCrvCompo).GetMinDistPoint( EPS_SMALL, ptStart, nFlag)) {
// controllo se il punto iniziale sta effettivaente su un lato aperto della curva attuale
// di primo Offset
double dU_check ;
if ( pCrvCompo->GetParamAtPoint( ptStart, dU_check)) {
// se il punto trovato è a cavallo tra due curve...
if ( abs( dU_check - floor( dU_check)) < EPS_PARAM ||
abs( dU_check - ceil( dU_check)) < EPS_PARAM) {
const ICurve* pCrvA = pCrvCompo->GetCurve( floor( dU_check)) ;
if ( pCrvA == nullptr)
return false ;
const ICurve* pCrvB = pCrvCompo->GetCurve( ceil( dU_check)) ;
if ( pCrvB == nullptr)
return false ;
if ( pCrvA->GetTempProp( 0) == 0 || pCrvB->GetTempProp( 0) == 1)
continue ; // se una delle due è chiusa, salto tale punto
}
// se invece tocca una sola curva, controllo che sia aperta
else {
const ICurve* pCrvA = pCrvCompo->GetCurve( floor( dU_check)) ;
if ( pCrvA == nullptr)
return false ;
if ( pCrvA->GetTempProp( 0) == 0)
continue ; // se chiusa, salto tale punto
}
}
vtMidOutTmp.Normalize() ;
vtMidOutTmp.Rotate( Z_AX, - 90) ;
vtMidOut = vtMidOutTmp ;
@@ -1606,6 +1710,33 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
// ( questa superificie ha i flag di lati aperti/chiusi settati nei loops)
// =================================================================================================
/*
1) Come prima cosa ricavo i lati aperti equivalenti dal primo Offset ; Facendo l'Offset di una curva
chiusa ho all'interno delle temp prop delle sottcurve due informazioni :
// nTmpProp0 -> #curva il cui Offset ha generato la curva i-esima attuale
// nTmpProp1 -> #loop che contiene la curva espressa in nTmpProp0
Quindi dal mio contorno con i lati aperti impostati, posso settare i lati aperti "equivalenti"
anche sulla curva di primo Offset.
NB. Il tool entra dalla curva di primo Offset, non dal bordo della regione da svuotare; quindi
l'entrata va calcolata sul primo Offset, non sulla curva di bordo della FlatRegion di Pocketing.
2) Verifico l'esistenza di lati aperti :
- Se esistono lati aperti -> cerco il lato più sensato su cui entrare
- 2.1) Guardo la curva originale ( senza estensione degli aperti) che delimita la regione di
svuotatura e cerco i lati aperti presenti in essa ; se mi posiziono a metà del lato aperto
e cerco il punto più vicino sulla curva di primo offset. Se quest'ultima è anch'essa aperta
e di lunghezza adeguata, l'entrata è valida
- 2.2) ( se 2.1 non accettabile ) Scorro tutte le curve di lato aperto sulla curva di primo
Offset e per ogni curva di lunghezza accettabile controllo la precedente e la successiva.
Ad ogni curva aperta viene assegnato uno "score", in base alla sua Lenght, alle Lenghts
delle curve adiacenti ( se aperte ) e ai loro angoli di adiacenza.
Se la curva aperta corrente ha uno "score" sufficiente, viene scelta come curva per l'entrata
- 2.3) ( se 2.2 non accettabile ) Considero le curve come tutte chiuse ( vedi sotto )
- Se non esistono dei lati aperti -> entro presso il lato chiuso più lungo
- 2.4)
*/
// controllo dei parametri
if ( pCrvOffsAct == nullptr || ! pCrvOffsAct->IsValid() || pCrvOffsAct->GetCurveCount() == 0 ||
pSrfToWork == nullptr || ! pSrfToWork->IsValid() || pSrfToWork->GetChunkCount() != 1)
@@ -1616,6 +1747,8 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
if ( IsNull( pCrv))
return false ;
// 1) *********************************************************************
bool bSomeOpen = false ; // flag per presenza di lati aperti
// creo un vettore di Loops della superificie, ordinati
@@ -1683,6 +1816,8 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
}
}
// *********************************************************************
// se ho dei lati aperti...
double dLenMax = EPS_SMALL ;
int nCrvForMax = 0 ;
@@ -1736,13 +1871,14 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
// cerchiamo un punto valido per l'entrata ...
bMidOut = false ;
if ( bSomeOpen) { // se ho dei lati aperti, cerco un parametro ideale per entrare
/* ( 2.1 ) */
bool bOK = false ;
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, pCrvOffsAct, ptStart, vtMidOut, bMidOut) ;
bOK = SetSpecialPtStartForOpenEdges( pCrvOrig, frPocket, PockParams, pCrv, ptStart, vtMidOut, bMidOut) ;
}
if ( ! bOK)
if ( ! bOK) /* ( 2.2 ) */
bMidOut = GetParamOnOpenSide( pCrv, vOtherCrv, frPocket, PockParams, ptStart, vtMidOut) ;
}
if ( bMidOut) { // se ho trovato e valido, allora imposto il punto inziale trovato
@@ -1751,6 +1887,8 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
bMidOut = ( DistPointCurve( ptStart + LEN_OUT * vtMidOut, *pCrv).GetParamAtMinDistPoint( 0, dPar, nFlag)
&& pCrv->ChangeStartPoint( dPar)) ;
}
/* ( 2.3 | 2.4 ) */
if ( ! bMidOut) // alla peggio, ordino i lati lunghi per lunghezza e cerco un'entrata valida
AdjustContourStart( pCrv, PockParams, vOtherCrv, true, ptEndPrec) ;
@@ -1762,42 +1900,83 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams,
return true ;
}
// ***************************************************************************
//---------------------------- CASI OTTIMIZZATI ------------------------------
// ***************************************************************************
//----------------------------------------------------------------------------
static bool
GetOptCrvIndex( const ICRVCOMPOPOVECTOR& vCrvOEWithFlags, ISurfFlatRegion* pSrfChunkFinal,
int& nIndex)
GetOptCrvIndex( const ICRVCOMPOPOVECTOR& vCrvOEWithFlags, const ISurfFlatRegion* pSrfChunkFinal,
const PocketParams& PockParams, int nReg, int& nIndex)
{
// controllo dei parametri
if ( int( vCrvOEWithFlags.size()) == 0 || pSrfChunkFinal == nullptr || ! pSrfChunkFinal->IsValid())
if ( vCrvOEWithFlags.empty() || pSrfChunkFinal == nullptr || ! pSrfChunkFinal->IsValid())
return false ;
nIndex = 0 ;
// cerco la curva originale del chunk (cc)-esimo ( per casi ottimizzati)
if ( int( vCrvOEWithFlags.size()) == 1)
return true ;
// vettore di indici delle curve candidate
INTVECTOR vInds ;
// scorro tutte le curve originali
for ( int k = 0 ; k < int( vCrvOEWithFlags.size()) ; ++ k) {
CRVCVECTOR ccClass ;
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[k], EPS_SMALL, ccClass)) {
bool bIsThis = true ;
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++kk) {
if ( ccClass[kk].nClass == CRVC_OUT)
bIsThis = false ;
}
if ( bIsThis)
vInds.push_back( k) ;
}
}
// se ho un solo indice allora ho già identificato la curva
if ( int( vInds.size()) == 1) {
nIndex = vInds[0] ;
return true ;
}
// IN QUESTO CASO, I LATI APERTI DI CHUNK VICINI SI SONO UNITI RIDUCENDO IL NUMERO DI CHUNK
// COMPLESSIVI DELLA REGIONE DI SVUOTATURA
// effettuo un Offset del Chunk per simulare la creazione delle nReg
double dOffs = PockParams.dRad + PockParams.dRadialOffset ;
PtrOwner<ISurfFlatRegion> pSfrRefChunk( CloneSurfFlatRegion( pSrfChunkFinal)) ;
if ( IsNull( pSfrRefChunk) ||
! pSfrRefChunk->Offset( - dOffs, ICurve::OFF_FILLET))
return false ;
// cerco la curva originale del chunk (cc)-esimo ( per casi ottimizzati)
if ( int( vCrvOEWithFlags.size()) == 1)
nIndex = 0 ;
else {
for ( int k = 0 ; k < ( int)vCrvOEWithFlags.size() ; ++k) {
CRVCVECTOR ccClass ;
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[k], EPS_SMALL, ccClass)) {
bool bIsThis = true ;
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++kk) {
if ( ccClass[kk].nClass == CRVC_OUT)
bIsThis = false ;
}
if ( bIsThis) {
nIndex = k ;
break ;
}
}
}
}
// clono il Chunk nReg-esimo se esiste
pSfrRefChunk.Set( pSfrRefChunk->CloneChunk( nReg)) ;
if ( IsNull( pSfrRefChunk))
return true ; // bisogna passare al ( pSrfChunkFinal + 1)-esimo
// scorro tutte le curve originali
for ( int k = 0 ; k < int( vCrvOEWithFlags.size()) ; ++ k) {
CRVCVECTOR ccClass ;
if ( pSfrRefChunk->GetCurveClassification( *vCrvOEWithFlags[k], EPS_SMALL, ccClass)) {
bool bIsThis = true ;
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++kk) {
if ( ccClass[kk].nClass == CRVC_OUT)
bIsThis = false ;
}
if ( bIsThis) {
nIndex = k ;
return true ;
}
}
}
return true ;
return true ;
}
//----------------------------------------------------------------------------
static bool
OptimizedSpiralCirle( const ICurveComposite* pCrvCompo, const double dToll, double& dRad,
@@ -5909,9 +6088,9 @@ AddSpiralIn( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams,
Point3d ptStart ;
bool bOptimizedTrap = false ;
// cerco la curva originale del chunk cc-esimo ( per casi ottimizzati)
// cerco la curva originale del chunk cc-esimo ( per casi ottimizzati)
int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk cc-esimo
if ( ! GetOptCrvIndex( vCrvOrig, pSrfChunk, nInd))
if ( ! GetOptCrvIndex( vCrvOrig, pSrfChunk, PockParams, nReg, nInd))
return false ;
// calcolo il percorso di svuotatura
@@ -5926,7 +6105,9 @@ AddSpiralIn( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams,
break ; // passo al chunk originale successivo
// se il chunk presenta dei lati aperti, estendo la curva che ho trovato per un LeadIn
if ( bSomeOpen) {
if ( bOptimizedTrap) // se caso a trapezio
AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, PockParams) ;
else if ( bSomeOpen) { // se presenza di lati aperti
if ( ! ExtendPathOnOpenEdge( pMCrv, PockParams, pSrfChunk->GetNormVersor(), vtMidOut, false))
return false ;
}
@@ -5973,7 +6154,7 @@ AddSpiralOut( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams,
// cerco la curva originale del chunk cc-esimo ( per casi ottimizzati)
int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk cc-esimo
if ( ! GetOptCrvIndex( vCrvOrig, pSrfChunk, nInd))
if ( ! GetOptCrvIndex( vCrvOrig, pSrfChunk, PockParams, nReg, nInd))
return false ;
// calcolo il percorso di svuotatura