From 1fef9786ac10bc26b5cbb7dc2a75969251cdcc1d Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 11 Jul 2023 16:29:48 +0200 Subject: [PATCH] EgtMachKernel : - Intersezioni e proiezioni, gestione dei nuovi lati aperti. --- Pocketing.cpp | 535 ++++++++++++++++++++++++++++++++++++++------------ Pocketing.h | 11 +- 2 files changed, 419 insertions(+), 127 deletions(-) diff --git a/Pocketing.cpp b/Pocketing.cpp index 39c4e44..78b95e2 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -9140,12 +9140,10 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& double dPar ; if ( GetParamForPtStartOnEdge( pCrvClone, pCompo, vCrvIsl, dPar)) pCompo->ChangeStartPoint( nMax + dPar) ; - else { + else // sposto inizio a metà if ( nMax >= 0) pCompo->ChangeStartPoint( nMax + 0.5) ; - } - } // se invece sto cercando di entrare da un lato chiuso per una svuotatura, allora riordino i lati // chiusi a seconda della lunghezza, e a partire dal più lungo cerco un parametro su tale curva che mi consenta @@ -9168,7 +9166,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& int nProp_i ; // se la curva i-esima non è già stata considerata ed è aperta... - if( find( vIndUsed.begin(), vIndUsed.end(), i) == vIndUsed.end() && + if ( find( vIndUsed.begin(), vIndUsed.end(), i) == vIndUsed.end() && pCompo->GetCurveTempProp( i, nProp_i, 0) && nProp_i == 0) { // creo la curva i-esima @@ -9180,9 +9178,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& nCurrInd = i ; bStop = false ; } - } - } vIndUsed.push_back( nCurrInd) ; vInd.push_back( nCurrInd) ; @@ -9191,7 +9187,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& if (( int)vInd.size() == 0) { // se questa condizione fosse vera allora non sono riuscito ad entrare da nessun lato aperto in precedenza e non - // ho nemmeno un lato chiuso disponibile per entrare... + // ho nemmeno un lato chiuso disponibile per entrare... pCompo->ChangeStartPoint( 0.5) ; return true ; } @@ -9207,7 +9203,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& } } - if ( !bOk) { + if ( ! bOk) { // se non riesco ad entrare da nessun lato chiuso, considerando che in precedenza ho già provato ad // entrare da tutti i lati aperti... pCompo->ChangeStartPoint( 0.5) ; @@ -9403,13 +9399,17 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl // se il grezzo è stato trovato, allora controllo intersezioni e proiezioni per lati aperti if ( pStmRaw->IsValid() || pStmRaw->GetTriangleCount() > 0) { + // tengo una copia della superificie prima dell'intersezione con il grezzo + PtrOwner pSrfOrig( CloneSurfFlatRegion( pSrf)) ; + if ( IsNull( pSrfOrig) || ! pSrfOrig->IsValid()) + return false ; // 1) INTERSEZIONE CON GREZZO if ( m_bIntersRaw) { // proporzionale all'area ? 95 %? if ( ! IntersSurfWithRaw( pSrf, pStmRaw, vtTrasl, bChanged, 500 * EPS_SMALL, true, m_dDiam_Prec < EPS_SMALL)) return false ; if ( pSrf->GetChunkCount() == 0 || ! pSrf->IsValid()) return true ; - PtrOwner pSrf_toDraw( CloneSurfFlatRegion( pSrf)) ; + /*PtrOwner pSrf_toDraw( CloneSurfFlatRegion( pSrf)) ; pSrf_toDraw->Translate( vtTrasl) ; int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ; m_pGeomDB->SetMaterial( a, AQUA) ; @@ -9422,19 +9422,19 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; } } - } + }*/ } // 2) PROIEZIONE CON GREZZO if ( m_bProjectRaw) { // recupero la Trimesh di partenza - if ( ! ProjectRaw( pSrf, vtTrasl, pStmRaw, nProp0, dRawSecLen, 500 * EPS_SMALL)) + if ( ! ProjectRaw( pSrf, vtTrasl, pStmRaw, nProp0, dRawSecLen, pSrfOrig, 500 * EPS_SMALL)) return false ; if ( pSrf->GetChunkCount() == 0 || ! pSrf->IsValid()) return true ; PtrOwner pSrf_toDraw( CloneSurfFlatRegion( pSrf)) ; pSrf_toDraw->Translate( vtTrasl) ; - //int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ; - //m_pGeomDB->SetMaterial( a, BLUE) ; + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ; + m_pGeomDB->SetMaterial( a, BLUE) ; for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) { for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) { const ICurveComposite* pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ; @@ -9480,6 +9480,75 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl return pSrf->IsValid() && pSrf->GetChunkCount() != 0 ; } +//---------------------------------------------------------------------------- +bool +Pocketing::AdjustFakeOpenEdges( ISurfFlatRegion* pSrf, const ISurfFlatRegion* pSrfOrig, const Vector3d vtTrasl) +{ + // controllo dei parametri + if ( pSrf == nullptr || ! pSrf->IsValid() || pSrf->GetChunkCount() == 0 || + pSrfOrig == nullptr || ! pSrfOrig->IsValid() || pSrfOrig->GetChunkCount() == 0 || + vtTrasl.IsSmall()) + return false ; + + // creo un frame Locale + Frame3d frPock ; + Vector3d vtN = pSrf->GetNormVersor() ; + Point3d ptC ; + if ( ! pSrf->GetCentroid( ptC)) + if ( ! pSrf->GetLoop( 0, 0)->GetStartPoint( ptC)) + return false ; + frPock.Set( ptC, vtN) ; + if ( ! frPock.IsValid()) + return false ; + + // clono le superifici + PtrOwner pSrfAct( CloneSurfFlatRegion( pSrf)) ; + PtrOwner pSrfOrig_c( CloneSurfFlatRegion( pSrfOrig)) ; + if ( IsNull( pSrfAct) || ! pSrfAct->IsValid() || pSrfAct->GetChunkCount() == 0 || + IsNull( pSrfOrig_c) || ! pSrfOrig_c->IsValid() || pSrfOrig_c->GetChunkCount() == 0) + return false ; + + // traslo la superificie da svuotare in modo da sovrapporla con la superificie originale + pSrfAct->Translate( - vtTrasl) ; + + // porto le due superifici nel frame locale + pSrfAct->ToLoc( frPock) ; + pSrfOrig_c->ToLoc( frPock) ; + + // per ogni chunk c... + for ( int c = 0 ; c < pSrfAct->GetChunkCount() ; ++ c) { + // per ogni loop l... + for ( int l = 0 ; l < pSrfAct->GetLoopCount( c) ; ++ l) { + // ricavo la curva composita del loop + PtrOwner pCrvCompo( GetCurveComposite( pSrfAct->GetLoop( c, l ))) ; + if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) + return false ; + // per ogni sottocurva della composita + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + PtrOwner pCrv_u( pCrvCompo->GetCurve( u)->Clone()) ; + if ( IsNull( pCrv_u) || ! pCrv_u->IsValid()) + return false ; + // ricavo la temp prop + int nTmpProp ; pCrv_u->GetTempProp( 0) ; + if ( nTmpProp == 0) { + // se si tratta di un lato aperto... + // 1) clono il lato + PtrOwner pCrv_uOpen_clone( pCrv_u->Clone()) ; + if ( IsNull( pCrv_uOpen_clone) || ! pCrv_uOpen_clone->IsValid()) + return false ; + // 2) effettuo l'Offset + OffsetCurve OffsCrv ; + + } + } + } + } + + + + return true ; +} + //---------------------------------------------------------------------------- bool Pocketing::ModifySurfByOpenEdge( ISurfFlatRegion* pSrf, ICRVCOMPOPOVECTOR& vCrvOEFlags, const Vector3d& vtTrasl, @@ -10349,46 +10418,55 @@ Pocketing::GetSurfByAdj( const ISurfTriMesh* pSrfOri, INTVECTOR& vBannedId, int //---------------------------------------------------------------------------- bool -Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, ISurfFlatRegion* pSfrRawBoxProj) +Pocketing::GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSrfOrig, + ISurfFlatRegion* pSfrRawBoxProj) { // controllo dei parametri if ( pSfr == nullptr || ! pSfr->IsValid() || pSfr->GetChunkCount() == 0 || pStmRaw == nullptr || ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0) return false ; - //int OOOOO = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pSfr->Clone()) ; - //m_pGeomDB->SetMaterial( OOOOO, AQUA); - + // ---------- CREAZIONE DI UN VETTORE CONTENENTI TUTTI I TRATTI APERTI APERTE -------------------- ICRVCOMPOPOVECTOR vCrvOpen ; ICRVCOMPOPOVECTOR vCrvNULL ; PtrOwner pCrvCompo( GetCurveComposite( pSfr->GetLoop( 0, 0))) ; - // sposto l'inizio a metà del tratto più lungo - AdjustContourStart( pCrvCompo, vCrvNULL) ; - // estraggo parti con proprietà uniforme in un vettore - int nCurrTempProp ; - int nParStart = 0 ; - for ( int i = 0 ; i < pCrvCompo->GetCurveCount() ; ++ i) { - int nTempProp ; - pCrvCompo->GetCurveTempProp( i, nTempProp) ; - if ( i == 0) { - nCurrTempProp = nTempProp ; - nParStart = i ; - } - else if ( nCurrTempProp != nTempProp) { - PtrOwner pCrv( pCrvCompo->CopyParamRange( nParStart, i)) ; - if ( IsNull( pCrv)) - return false ; - pCrv->SetTempProp( nCurrTempProp) ; - PtrOwner pCrvSameTmpProp( CreateCurveComposite()) ; - pCrvSameTmpProp->AddCurve( Release( pCrv)) ; - if ( nCurrTempProp == 1) { - pCrvSameTmpProp->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - //int r = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCrvSameTmpProp->Clone()) ; - //m_pGeomDB->SetMaterial( r, RED) ; - vCrvOpen.emplace_back( Release( pCrvSameTmpProp)) ; + // controllo se la curva ha tutti i lati aperti + bool bIsAllOpen = true ; + int nCurrTempProp_ ; + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && bIsAllOpen ; ++ u) { + pCrvCompo->GetCurveTempProp( u, nCurrTempProp_, 0) ; + bIsAllOpen = nCurrTempProp_ == 1 ; + } + if ( bIsAllOpen) + // se tutti lati aperti... + vCrvOpen.emplace_back( pCrvCompo->Clone()) ; + else { + // ... altrimenti sposto l'inizio a metà del tratto più lungo + AdjustContourStart( pCrvCompo, vCrvNULL) ; + // estraggo parti con proprietà uniforme in un vettore + int nCurrTempProp ; + int nParStart = 0 ; + for ( int i = 0 ; i < pCrvCompo->GetCurveCount() ; ++ i) { + int nTempProp ; + pCrvCompo->GetCurveTempProp( i, nTempProp) ; + if ( i == 0) { + nCurrTempProp = nTempProp ; + nParStart = i ; + } + else if ( nCurrTempProp != nTempProp) { + PtrOwner pCrv( pCrvCompo->CopyParamRange( nParStart, i)) ; + if ( IsNull( pCrv)) + return false ; + pCrv->SetTempProp( nCurrTempProp) ; + PtrOwner pCrvSameTmpProp( CreateCurveComposite()) ; + pCrvSameTmpProp->AddCurve( Release( pCrv)) ; + if ( nCurrTempProp == 1) { + pCrvSameTmpProp->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + vCrvOpen.emplace_back( Release( pCrvSameTmpProp)) ; // se aperta + } + nCurrTempProp = nTempProp ; + nParStart = i ; } - nCurrTempProp = nTempProp ; - nParStart = i ; } } @@ -10396,7 +10474,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* PtrOwner pSfrPock( CloneSurfFlatRegion( pSfr)) ; if( IsNull( pSfrPock)) return false ; - + // ------------------------- CREAZIONE DEL PIANO DI TAGLIO -------------------------------------- // recupero il piano di proiezione ( piano che contiene la flatRegion) PtrOwner pCrv( GetCurveComposite( pSfrPock->GetLoop( 0, 0))) ; if ( IsNull( pCrv)) @@ -10413,6 +10491,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* if ( ! plProj.IsValid()) return false ; + // ---------------------- RICERCA DELLA REGIONE DI INCIDENZA DI PROIEZIONE -------------------------- // offsetto la regione della quantità richiesta PtrOwner pSrf_Pock_Clone(CloneSurfFlatRegion( pSfrPock)) ; if ( ! pSrf_Pock_Clone->Offset( m_dMaxLenRawProj, ICurve::OFF_CHAMFER)) @@ -10423,6 +10502,8 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* vCrv.emplace_back( pSrf_Pock_Clone->GetLoop( c, l)) ; PtrOwner pSrf_ForCuttingRaw( GetSurfTriMeshByRegionExtrusion( vCrv, vtNorm * 1000)) ; + // --------------------- CREAZIONE PARTE DI GREZZO AL DI SOPRA DELLA REGIONE SI SVUOTATURA + // -----------------------------------NELLA REGIONE DI INCIDENZA ----------------------------- // creo la Trimesh del grezzo e la taglio con il piano PtrOwner pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ; if ( IsNull( pSrfRaw_clone)) @@ -10434,6 +10515,8 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* return true ; } + // --------------------- RIMOZIONE DELLE PARTI NON ESSENZIALI --------------------------------- + // ( Serve ancora questo controllo ? ) // Recupero solo la parte di TriMesh contente la superificie da svuotare // Tagliando il grezzo posso ottenere diverse Parts, tengo solo quelle che influenzano la mia regione di svuotatura PtrOwner pStr_real( CreateSurfTriMesh()) ; @@ -10461,10 +10544,12 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* } } + // ------- PROIEZIONE DI OGNI FACCIA DEL GREZZO RICAVATO SUL PIANO DELLA SVUOTATURA -------------- // creo un vettore con le curve esterne // in posizione 0 metto la curva esterna della superificie da svuoatre originale // nelle posizioni successive inserisco le curve esterne dei chunk creati ( aperti per definizione) - ICRVCOMPOPOVECTOR vCrvExtProj ; + ICRVCOMPOPOVECTOR vCrvExtProj ; // <---- questo vettore contiene il bordo della superificie ricavata dall'interzione + // quindi in posizione 0 ho una curva con i lati aperti/chiusi già settati vCrvExtProj.emplace_back( GetCurveComposite( pSfr->GetLoop( 0, 0))) ; // Proietto ora le curve, delle facce della superificie ottenuta, sul piano della svuotatura @@ -10475,6 +10560,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* continue ; POLYLINEVECTOR vPL ; pStr_real->GetFacetLoops( f, vPL) ; + // per ogni Loop l della faccia f for ( int l = 0 ; l < ( int) vPL.size() ; ++ l) { PtrOwner pCrvBorder( CreateCurveComposite()) ; if ( IsNull( pCrvBorder) || ! pCrvBorder->FromPolyLine( vPL[l])) @@ -10482,7 +10568,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* PtrOwner pCrvProjFacef( ProjectCurveOnPlane( *pCrvBorder, plProj)) ; if ( IsNull( pCrvProjFacef) || ! pCrvProjFacef->IsValid()) return false ; - // controllo validità della curva + // controllo validità della curva ( che sia chiusa e non degenere) double dArea = EPS_SMALL ; Plane3d plCheck ; if ( ! pCrvProjFacef->IsClosed() || ! pCrvProjFacef->GetArea( plCheck, dArea) || dArea <= EPS_SMALL) @@ -10490,11 +10576,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* // creo la curva composita associata PtrOwner pCrvBorderProj_f( CreateCurveComposite()) ; pCrvBorderProj_f->AddCurve( Release( pCrvProjFacef)) ; - int g = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvBorderProj_f->Clone()) ; - m_pGeomDB->SetMaterial( g, PURPLE) ; - if ( g == 151138) - int a = 19 ; - // controllo se una sottocurva della curva composita del bordo è sufficientemente vicina ad una curva aperta + // 1) controllo se una sottocurva della curva composita del bordo è sufficientemente vicina ad una curva aperta // della curva originale di bordo della superificie esterna bool bNeedProj = false ; for ( int i = 0 ; i < pCrvBorderProj_f->GetCurveCount() && !bNeedProj; ++ i) { @@ -10513,7 +10595,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* } } if ( ! bNeedProj) { - // controllo se un tratto aperto è sufficientemente vicino ad una sottocurva della curva composita del bordo + // 2) controllo se un tratto aperto è sufficientemente vicino ad una sottocurva della curva composita del bordo // della proiezione for ( int j = 0 ; j < ( int)vCrvOpen.size() && !bNeedProj ; ++ j) { for ( int u = 0 ; u < ( int)vCrvOpen[j]->GetCurveCount() && !bNeedProj ; ++ u) { @@ -10526,7 +10608,7 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* } } } - if ( ! bNeedProj) + if ( ! bNeedProj) // se non devo proiettare passo alla prossima continue ; // 3) Setto tutte le sottocurve aperte @@ -10534,24 +10616,28 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pCrvBorderProj_f->SetCurveTempProp( uu, 1, 0) ; // inserisco nel vettore delle curve di bordo - vCrvExtProj.emplace_back( Release( pCrvBorderProj_f)) ; + vCrvExtProj.emplace_back( Release( pCrvBorderProj_f)) ; // <---- dall'indice 1 in poi ho solo curve aperte e + // sono le curve di bordo delle proeizioni } } - // Clono la superificie di partenza + // Clono la superificie di partenza ( per sicurezza lascio invariata quella passata alla funzione) PtrOwner pSrf_Clone( CloneSurfFlatRegion( pSfr)) ; if ( IsNull( pSrf_Clone) || ! pSrf_Clone->IsValid()) return false ; + // Creo la superficie che dovrò restiturire alla fine della proiezione PtrOwner pSrf_Proj_Ext( CreateSurfFlatRegion()) ; if ( IsNull( pSrf_Proj_Ext)) return false ; - for ( int p = 1 ; p < ( int)vCrvExtProj.size() ; ++ p) { - int g = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvExtProj[p]->Clone()) ; - m_pGeomDB->SetMaterial( g, BLACK) ; - } + //for ( int p = 1 ; p < ( int)vCrvExtProj.size() ; ++ p) { + //int g = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvExtProj[p]->Clone()) ; + //m_pGeomDB->SetMaterial( g, BLACK) ; + //} + // ---------------- CREAZIONE DELLA VERA A PROPRIA REGIONE DI INCIDENZA, COME SOMMA DELLE + // ----------------------------- SINGOLE FLATREGIONS DI PROIEZIONE ----------------------------- for ( int i = 1 ; i < ( int)vCrvExtProj.size() ; ++ i) { CRVCVECTOR ccClass ; if ( pSrf_Clone->GetCurveClassification( *vCrvExtProj[i], 150 * EPS_SMALL, ccClass)) { @@ -10563,11 +10649,11 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* if ( IsNull( pSrf_H)) return false ; pSrf_H->AddExtLoop( vCrvExtProj[i]->Clone()) ; + // inverto se le normali risultano opposte if ( pSrf_H->IsValid()) { if ( AreOppositeVectorApprox( pSrf_H->GetNormVersor() , pSrf_Clone->GetNormVersor())) pSrf_H->Invert() ; } - //m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pSrf_H->Clone()) ; if ( pSrf_Proj_Ext->GetChunkCount() == 0) pSrf_Proj_Ext.Set( Release( pSrf_H)) ; else @@ -10575,25 +10661,33 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* } } } - // creo la vera e propria regione di proiezione, sommando la proiezione esterna con la superifcie originale da svuotare PtrOwner pSrf_Proj( CloneSurfFlatRegion( pSrf_Proj_Ext)) ; if ( IsNull( pSrf_Proj) || ! pSrf_Proj->IsValid()) return false ; pSrf_Proj->Add( *pSfr) ; - // ----------------------------------------------------------------------------------------- + + + // --------- LA PROIEZIONE DEL GREZZO DEVE ESTENDERE LA MIA SUPERIFCIE ORIGINARIA ( DERIVANTE DALL'INTERSEZIONE) PRESSO + // I LATI APERTI DI ESSA. USO LA FUNZIONE AdjustContourWithOpenEdges FORZADO COME COLLEGAMENTI DELLE RETTE CHIUSE ------ PtrOwner pCrvExt( CloneCurveComposite( vCrvExtProj[0])) ; if ( IsNull( pCrvExt) || ! pCrvExt->IsValid()) return false ; ICRVCOMPOPOVECTOR vCrvNull ; // allargo la copia della superificie iniziale estendendola presso i lati aperti - // ( semplice AdjustContourWithOpenEdges, senza grezzo e senza regione di incidenza, verrà tutto fatto in seguito) + // ( semplice AdjustContourWithOpenEdges, senza grezzo e senza isole, verrà tutto fatto in seguito) if ( AdjustContourWithOpenEdges( pCrvExt, vCrvNull, m_dMaxLenRawProj, 0.0, 0.0, V_NULL, nullptr, true)) { + // la curva restitutita presenta i lati aperti/chiusi impostati ( all'originale si lasciano invariati i chiusi, + // gli aperrti vengono Offsettati e i raccordi sono lineari mediante rette chiuse + // ( NB. Se le rette di raccordo fossero settate aperte, rischierei di rovinare parti di grezzo al + // di fuori di lati chiusi ( tutto dipende dell'angolo di inclinazione della superificie originale rispetto + // ad ogni singola faccia del grezzo ). PtrOwner pSrfWithOEModified( CreateSurfFlatRegion()) ; if ( IsNull( pSrfWithOEModified)) return false ; - pSrfWithOEModified->AddExtLoop( Release( pCrvExt)) ; // la modifico con la curva appena restituita ( allargata dai lati aperti) + pSrfWithOEModified->AddExtLoop( Release( pCrvExt)) ; // la modifico con la curva appena restituita + // ( allargata dai lati aperti) if ( pSrfWithOEModified->IsValid()) { // se la superificie ottenuta è valida... // ... la clono... PtrOwner pSfrProj_Clone( CloneSurfFlatRegion( pSrf_Proj)) ; @@ -10607,9 +10701,20 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* //int gaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfWithOEModified->Clone()) ; //m_pGeomDB->SetMaterial( gaa, PURPLE) ; // ... e Interseco la superificie di proiezione con questa nuova superificie + // NB. L'intersezione mi permette di tenere solo le parti che sono sia nella regione di incidenza che nella + // estensione della superificie originali presso i lati aperti if ( pSfrProj_Clone->Intersect( *pSrfWithOEModified) && ! IsNull( pSfrProj_Clone) && pSfrProj_Clone->IsValid()) { //int g = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrProj_Clone->Clone()) ; //m_pGeomDB->SetMaterial( g, GREEN) ; + // adatto la FlatRegion con la superificie iniziale per non sbordare dai chiusi + // La superficie che ottengo rischia comunque di essere esterna a dei lati chiusi originali ( questo + // accade quando si generano dei lati aperti mediante l'intersezione con il grezzo e la regione di incidenza + // ha un raggio di ricerca molto grande... oppure quando semplicemente il grezzo contiene un'isola in cui + // una faccia è diretta verso un pezzo di chiuso della curva esterna ( infatti le rette di raccordo chiuse + // seguono la tangenza dei lati chiusi adiancenti ai tratti aperti + PtrOwner pSrfProj_Clone_Clone( CloneSurfFlatRegion( pSfrProj_Clone)) ; + if ( ! CutProjectionToFitShape( pSfrProj_Clone, pSrfOrig)) + return false ; // Recupero le TmpProp e creo la nuova superificie mediante questo loop esterno PtrOwner pCrv_NewExt( pSfrProj_Clone->GetLoop( 0, 0)) ; if ( IsNull( pCrv_NewExt) || ! pCrv_NewExt->IsValid()) @@ -10618,9 +10723,9 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* if ( IsNull( pCrvCompo_NewExt)) return false ; pCrvCompo_NewExt->AddCurve( Release( pCrv_NewExt)) ; - //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo_NewExt->Clone()) ; + // Imposto le temp prop if ( pCrvCompo_NewExt->IsValid()) { - if ( ! SetTmpPropWithRawProjectedFaces( pCrvCompo_NewExt, vCrvExtProj) || + if ( ! SetTmpPropWithRawProjectedFaces( pCrvCompo_NewExt, vCrvExtProj, pSfr->GetNormVersor()) || ! CheckSmallPartsForOpenEdge( pCrvCompo)) return false ; // creo la superificie finale @@ -10628,22 +10733,14 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* if ( IsNull( pSrfProj_Final)) return false ; pSrfProj_Final->AddExtLoop( Release( pCrvCompo_NewExt)) ; + // aggiusto la normale se necessario if ( pSrfProj_Final->IsValid()) { if ( AreOppositeVectorApprox( pSrfProj_Final->GetNormVersor(), pSfr->GetNormVersor())) pSrfProj_Final->Invert() ; } + // sostituisco questa superficie a quella passata dalla funzione ed esco pSfrRawBoxProj->Clear() ; pSfrRawBoxProj->CopyFrom( pSrfProj_Final) ; - for ( int c = 0 ; c < pSfrRawBoxProj->GetChunkCount() ; ++ c) { - for ( int l = 0 ; l < pSfrRawBoxProj->GetLoopCount( c) ; ++ l) { - const ICurveComposite* pCrvCompo( GetCurveComposite( pSfrRawBoxProj->GetLoop( c, l))) ; - for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { - int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ; - //int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ; - //m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; - } - } - } return pSfrRawBoxProj->IsValid() ; } } @@ -10656,8 +10753,166 @@ Pocketing::GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* //---------------------------------------------------------------------------- bool -Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, - const ISurfTriMesh* pStmRaw, int nId, const double& dRawSecLen, double dAreaToll) +Pocketing::CutProjectionToFitShape( ISurfFlatRegion* pSrfProjected, const ISurfFlatRegion* pSrfOrig) +{ + // controllo validità dei parametri + if ( pSrfProjected == nullptr || ! pSrfProjected->IsValid() || pSrfProjected->GetChunkCount() == 0 || + pSrfOrig == nullptr || ! pSrfOrig->IsValid() || pSrfOrig->GetChunkCount() == 0) + return false ; + + ICRVCOMPOPOVECTOR vCrvNULL ; + ICRVCOMPOPOVECTOR vCrvClose ; + for ( int c = 0 ; c < pSrfOrig->GetChunkCount() ; ++ c) { // per ogni Chunk c + for ( int l = 0 ; l < pSrfOrig->GetLoopCount( c) ; ++ l) { // per ogni Loop l + // estraggo la curva di bordo + PtrOwner pCrvCompo( GetCurveComposite( pSrfOrig->GetLoop( c, l ))) ; + if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) + return false ; + // controllo se la curva ha tutti i lati aperti + bool bIsAllOpen = true ; + int nCurrTempProp_ ; + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && bIsAllOpen ; ++ u) { + pCrvCompo->GetCurveTempProp( u, nCurrTempProp_, 0) ; + bIsAllOpen = nCurrTempProp_ == 1 ; + } + if ( bIsAllOpen) + // se tutti lati aperti... + continue ; + else { + AdjustContourStart( pCrvCompo, vCrvNULL) ; + for ( int u = 1 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + int nTmpProp0 ; pCrvCompo->GetCurveTempProp( u, nTmpProp0, 0) ; + if ( nTmpProp0 == 1) { + pCrvCompo->ChangeStartPoint( u + 1) ; + break ; + } + } + PtrOwner pCrvClosed( CreateCurveComposite()) ; + if ( IsNull( pCrvClosed)) + return false ; + int nCrv = 0 ; + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + int nCurrTmpProp ; pCrvCompo->GetCurveTempProp( u, nCurrTmpProp, 0) ; + if ( nCurrTmpProp == 0) { // se chiusa + if ( nCrv == 0) + pCrvClosed->Clear() ; + pCrvClosed->AddCurve( pCrvCompo->GetCurve( u)->Clone()) ; + ++ nCrv ; + } + else { // se aperta + if ( nCrv != 0) + vCrvClose.emplace_back( pCrvClosed->Clone()) ; + nCrv = 0 ; + } + } + // l'ultima curva è sempre chiusa... + vCrvClose.emplace_back( Release( pCrvClosed)) ; + } + } + } + + // se nessun lato aperto, esco + if (( int)vCrvClose.size() == 0) + return true ; + + // trasformo la superificie di proiezione in Trimesh + PtrOwner pStmProj( CloneSurfTriMesh( pSrfProjected->GetAuxSurf())) ; + if ( IsNull( pStmProj) || ! pStmProj->IsValid() || pStmProj->GetTriangleCount() == 0) + return false ; + + // recupero il centroide della superificie ( o un punto generico sulla superificie) + Point3d ptC ; pSrfProjected->GetCentroid( ptC) ; + + // creo una Frame con questo vettore + Frame3d frPock ; frPock.Set( ptC, pSrfOrig->GetNormVersor()) ; + if ( ! frPock.IsValid()) + return true ; + + // porto tutto in questo frame + ICRVCOMPOPOVECTOR vCrvClose_c ; + for ( int i = 0 ; i < ( int)vCrvClose.size() ; ++ i) { + PtrOwner pCrvClose_i( CloneCurveComposite( vCrvClose[i])) ; + if ( IsNull( pCrvClose_i) || ! pCrvClose_i->IsValid() || pCrvClose_i->GetCurveCount() == 0) + return false ; + pCrvClose_i->ToLoc( frPock) ; + vCrvClose_c.emplace_back( Release( pCrvClose_i)) ; + } + pStmProj->ToLoc( frPock) ; + + // abbasso leggermente ls superificie di proiezione per evitatare triangoli sovrapposti + pStmProj->Translate( Z_AX * 10 * EPS_SMALL) ; + + // per ogni curva chiusa di bordo + for ( int i = 0 ; i < ( int)vCrvClose_c.size() ; ++ i) { + // creo la sua estrusione + PtrOwner pStmClosedEdge( GetSurfTriMeshByExtrusion( vCrvClose_c[i], Z_AX * 1000, false)) ; + // controllo la validità dell'estrusione + if ( IsNull( pStmClosedEdge) || ! pStmClosedEdge->IsValid() || pStmClosedEdge->GetTriangleCount() == 0) + continue ; + //int OOOOOOOOOOO = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmClosedEdge->Clone()) ; // --- + //m_pGeomDB->SetMaterial( OOOOOOOOOOO, RED) ; // --- + // tengo una copia della trimesh della proiezione per sicurezza, nel caso il taglio non funzioni + PtrOwner pStmProj_clone( CloneSurfTriMesh( pStmProj)) ; + if ( IsNull( pStmProj_clone) || ! pStmProj_clone->IsValid() || pStmProj_clone->GetTriangleCount() == 0) + return false ; + // taglio la supericie con questo lato + if ( pStmProj_clone->CutWithOtherSurf( *pStmClosedEdge, true, true) && + ! IsNull( pStmProj_clone) && pStmProj_clone->IsValid() && pStmProj_clone->GetTriangleCount() != 0) + // se il taglio funziona, sostituisco la superificie + pStmProj.Set( Release( pStmProj_clone)) ; + //int OOOOOOOOOOOt = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmProj->Clone()) ; // --- + //m_pGeomDB->SetMaterial( OOOOOOOOOOOt, PURPLE) ; // --- + + } + + // se la superificie finale è valida... + if ( IsNull( pStmProj) || ! pStmProj->IsValid()) + return true ; + // ... ricoverto La Trimesh in FlatRegione + SurfFlatRegionByContours SrfProj_H ; + POLYLINEVECTOR vPl ; + pStmProj->GetLoops( vPl) ; + Plane3d plPlane ; plPlane.Set( ORIG, Z_AX) ; + for ( int i = 0 ; i < ( int)vPl.size() ; ++ i) { + // recupero la curva composita + PolyLine PL = vPl[i] ; + PtrOwner pCrv( CreateCurveComposite()) ; + pCrv->FromPolyLine( PL) ; + PolyArc PA ; + pCrv->ApproxWithArcsEx( 5 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; + pCrv->Clear() ; + pCrv->FromPolyArc( PA) ; + // la converto in una semplice cruva per proiettarla su piano XY + // dato che le curve sono prese da una trimesh, le riproietto per sicurezza e per evitare approssimazioni + double dS, dE ; + pCrv->GetDomain( dS, dE) ; + PtrOwner pCrv_c( pCrv->CopyParamRange( dS, dE)) ; + if ( IsNull( pCrv_c) || ! pCrv_c->IsValid()) + return false ; + PtrOwner pCrv_proj( ProjectCurveOnPlane( *pCrv_c, plPlane)) ; + if ( IsNull( pCrv_proj) || ! pCrv_proj->IsValid()) + return false ; + SrfProj_H.AddCurve( Release( pCrv_proj)) ; // aggiungo le curve proiettate + } + + // recupero la Flat region di prozione e controllo la validità + PtrOwner pStmProj_HH( SrfProj_H.GetSurf()) ; + if ( IsNull( pStmProj_HH) || ! pStmProj_HH->IsValid() || pStmProj_HH->GetChunkCount() == 0) + return true ; + + // la risporto in globale e sostituisco + pStmProj_HH->ToGlob( frPock) ; + pSrfProjected->Clear() ; + pSrfProjected->CopyFrom( pStmProj_HH) ; + + return pSrfProjected != nullptr && pSrfProjected->IsValid() && pSrfProjected->GetChunkCount() > 0 ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, + const ISurfTriMesh* pStmRaw, int nId, const double& dRawSecLen, const ISurfFlatRegion* pSrfOrig, + double dAreaToll) { // controllo se funzione necessaria if ( ! m_bProjectRaw) @@ -10670,8 +10925,7 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, // NB. La proiezione è fatta allargando la superificie attuale di svuotatura. // Come bordo esterno limite si utlizza la curva della FlatRegion della proiezione della parte di grezzo nel - // semipiano positivo sopra allo step attuale della svuoatura. - // NB. La proiezione modifica solo il bordo esterno della svuotatura, le isole aperte non sono modificate. + // semipiano positivo sopra allo step attuale della svuotatura. // 1) se un chunk non ha lati aperti, allora non serve proiettare nulla per tale chunk BOOLVECTOR vbSkip ; // vettore di Flag per capire se un chunk va modificato o meno @@ -10703,20 +10957,20 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, // traslo la superificie allo step corrente pSrf_clone->Translate( vtTrasl) ; - // superificie finale da ottenere - //SurfFlatRegionByContours pSrf_Help ; + // superificie finale della proizione ( per tutti i chunk) PtrOwner pSrf_Final( CreateSurfFlatRegion()) ; if ( IsNull( pSrf_Final)) return false ; - // vettore delle superificie ricavate + // vettore delle superificie ricavate da ogni chunk ISURFFRPOVECTOR vSfr_gained ; + // vettore delle isole in ogni Chunk per lo step corrente + ICRVCOMPOPOVECTOR vCrvIsl ; // per ogni chunk della superificie originaria da svuotare for ( int c = 0 ; c < pSrf_clone->GetChunkCount() ; ++ c) { - // salvo le isole - ICRVCOMPOPOVECTOR vCrvIsl ; + // inserisco l'isola nel vettore for ( int l = 1 ; l < pSrf_clone->GetLoopCount( c) ; ++ l) vCrvIsl.emplace_back( GetCurveComposite( pSrf_clone->GetLoop( c, l))) ; @@ -10729,30 +10983,23 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, // ricavo la FlatRegion della proiezione di ogni faccia del grezzo tagliato dal // semipiano positivo definito dal chunk c allo step attuale ( vtTrasl) PtrOwner pSrfOnPlPlus( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfOnPlPlus) || ! GetProjStmBoxOnSfr( pSrf_clone_ChunkC, pStmRaw, pSrfOnPlPlus)) + if ( IsNull( pSrfOnPlPlus) || ! GetProjStmOnSfr( pSrf_clone_ChunkC, pStmRaw, pSrfOrig, pSrfOnPlPlus)) return false ; if ( IsNull( pSrfOnPlPlus) || ! pSrfOnPlPlus->IsValid() || pSrfOnPlPlus->GetChunkCount() == 0) continue ; - //return false ; // OCCHIO ! - // recupero la curva esterna - int OR = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfOnPlPlus->Clone()) ; - m_pGeomDB->SetMaterial( OR, ORANGE) ; // inseirsco nel vettore vSfr_gained.emplace_back( pSrfOnPlPlus->Clone()) ; + // sommo il nuovo chunk ottenuto alla regione finale di proiezione if ( pSrf_Final->GetChunkCount() == 0) pSrf_Final.Set( Release( pSrfOnPlPlus)) ; else pSrf_Final->Add( *Release( pSrfOnPlPlus)) ; - - //PtrOwner pNewCrvExt( GetCurveComposite( pSrfOnPlPlus->GetLoop( 0, 0))) ; - // recupero la nuova superificie con la curva esterna modificata e le isole originali - //pSrf_Help.AddCurve( Release( pNewCrvExt)) ; - //for ( int i = 0 ; i < ( int)vCrvIsl.size() ; ++ i) - // pSrf_Help.AddCurve( Release( vCrvIsl[i])) ; } + // può capitare che da due Chunk distinti, mediante la proeizione questi si uniscano formandone uno solo... + // Imposto nuovamente le Temp Prop PtrOwner pSrf_Final_WithOCEdge( CreateSurfFlatRegion()) ; if ( IsNull( pSrf_Final_WithOCEdge)) return false ; @@ -10770,18 +11017,16 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, pSrf_Final->Add( *Release( pSrfChunk_c)) ; } } - - - //PtrOwner pSrf_Final( pSrf_Help.GetSurf()) ; - int RE = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_Final->Clone()) ; - m_pGeomDB->SetMaterial( RE, RED) ; + // aggiungo tutte le isole... <---------- !!! + for ( int is = 0 ; is < ( int)vCrvIsl.size() ; ++ is) + pSrf_Final->AddIntLoop( Release( vCrvIsl[is])) ; if ( ! IsNull( pSrf_Final) && pSrf_Final->IsValid()) { // Controllo delle aree, se alla fine di tutto sono ancora uguali, allora esco double dArea_orig = 0 ; double dArea_finale = 0 ; if ( pSrf_Final->GetArea( dArea_finale) && pSrf->GetArea( dArea_orig) && abs( dArea_orig - dArea_finale) < dAreaToll) - return true ; // Esco, alla fine non ho modificato la superificie originale mediante la proiezione con il grezzo + return true ; // esco, alla fine non ho modificato la superificie originale mediante la proiezione con il grezzo pSrf->Clear() ; pSrf->CopyFrom( Release( pSrf_Final)) ; pSrf->Translate( - vtTrasl) ; // ritraslo la superificie come in origine @@ -11410,18 +11655,40 @@ Pocketing::SetTmpPropByOverlap( ICurveComposite* pCrv_, int nInd, const ICurveCo //---------------------------------------------------------------------------- bool -Pocketing::SetTmpPropWithRawProjectedFaces( ICurveComposite* pCrvCompo_NewExt, ICRVCOMPOPOVECTOR& vCrvExtProj, double dToll) +Pocketing::SetTmpPropWithRawProjectedFaces( ICurveComposite* pCrvCompo_NewExt, ICRVCOMPOPOVECTOR& vCrvExtProj, + const Vector3d& vtN, double dToll) { // controllo validità parametri - if ( pCrvCompo_NewExt == nullptr || dToll < EPS_SMALL) + if ( pCrvCompo_NewExt == nullptr || dToll < EPS_SMALL || vtN.IsSmall()) return false ; - // imposto le proprietà temporanee delle curve + // creo un frame Locale alla regione di svuotatura + Frame3d frLoc ; + Point3d ptC ; + if ( ! pCrvCompo_NewExt->GetCentroid( ptC)) + if ( ! pCrvCompo_NewExt->GetStartPoint( ptC)) + return false ; + frLoc.Set( ptC, vtN) ; + if ( ! frLoc.IsValid()) + return false ; + + // inizialmente imposto tutte le curve come chiuse + for ( int u = 0 ; u < pCrvCompo_NewExt->GetCurveCount() ; ++ u) + pCrvCompo_NewExt->SetCurveTempProp( u, 0, 0) ; + + //int ww = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo_NewExt->Clone()) ; + //m_pGeomDB->SetMaterial( ww, WHITE) ; + //for ( int i = 0 ; i < ( int)vCrvExtProj.size() ; ++ i) { + // int ww2 = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvExtProj[i]->Clone()) ; + // m_pGeomDB->SetMaterial( ww2, BLACK) ; + //} + + // imposto le proprietà temporanee delle curve for ( int u = 0 ; u < pCrvCompo_NewExt->GetCurveCount() ; ++ u) { bool bFound = false ; for ( int i = 0 ; i < ( int)vCrvExtProj.size() && !bFound ; ++ i) { int nStat = -1 ; - if ( SetTmpPropByOverlap( pCrvCompo_NewExt, u, vCrvExtProj[i], nStat, 150 * EPS_SMALL) && nStat == 1) + if ( SetTmpPropByOverlap( pCrvCompo_NewExt, u, vCrvExtProj[i], nStat, dToll) && nStat == 1) bFound = true ; } if ( ! bFound) { @@ -11432,45 +11699,70 @@ Pocketing::SetTmpPropWithRawProjectedFaces( ICurveComposite* pCrvCompo_NewExt, I pCrvCompoCurr->AddCurve( *pCrvCompo_NewExt->GetCurve( u)) ; if ( IsNull( pCrvCompoCurr) || ! pCrvCompoCurr->IsValid()) return false ; + // scorro il vettore delle curve aperte di proiezione for ( int i = 0 ; i < ( int)vCrvExtProj.size() ; ++ i) { PtrOwner pCrvCompoH( CreateCurveComposite()) ; if ( IsNull( pCrvCompoH)) return false ; + // per ogni sottocurva creata dalla singola curva originale... for ( int uu = 0 ; uu < pCrvCompoCurr->GetCurveCount() ; ++ uu) { int nProp_Check = -1 ; + // se la curva non è già stata impostata aperta in un passaggio precedente... if ( pCrvCompoCurr->GetCurveTempProp( uu, nProp_Check, 0) && nProp_Check == 0) { PtrOwner pCrvCurr_Close( pCrvCompoCurr->GetCurve( uu)->Clone()) ; if ( IsNull( pCrvCurr_Close) || ! pCrvCurr_Close->IsValid()) return false ; + // controllo se il pezzo chiuso fa Overlap con la curva della proiezione i-esima + // porto in locale... + pCrvCurr_Close->ToLoc( frLoc) ; + vCrvExtProj[i]->ToLoc( frLoc) ; + // intersezione... IntersCurveCurve IntCC( *pCrvCurr_Close, *vCrvExtProj[i]) ; + // riporto in globale... + pCrvCurr_Close->ToGlob( frLoc) ; + vCrvExtProj[i]->ToGlob( frLoc) ; CRVCVECTOR ccClass ; + // se riesco a classificare... if ( IntCC.GetCurveClassification( 0, dToll, ccClass)) { + // se questa curva non fa overlap, ma è semplicemente o tutta interna o tutta esterna alla curva + // do bordo della proiezione i-esima, allor apasso a controllare la successiva + if (( int)ccClass.size() == 1 && + ( ccClass[0].nClass == CRVC_IN || ccClass[0].nClass == CRVC_OUT)) + continue ; + // altrimenti... for ( int j = 0 ; j < ( int)ccClass.size() ; ++ j) { PtrOwner pCrv_Step( pCrvCurr_Close->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; if ( IsNull( pCrv_Step) || ! pCrv_Step->IsValid()) continue ; - - pCrv_Step->SetTempProp( 0, 0) ; - if ( ccClass[j].nClass == CRVC_ON_P || ccClass[j].nClass == CRVC_ON_M) - pCrv_Step->SetTempProp( 1, 0) ; - - pCrvCompoH->AddCurve( Release( pCrv_Step)) ; + // chiusa per default... + PtrOwner pCrvCompo_Step( CreateCurveComposite()) ; + pCrvCompo_Step->AddCurve( pCrv_Step->Clone()) ; + int nStat1 = -1 ; + // richiamo la SetTmpPropByOverlap in quanto potrebbe fare overlap con l'indice 0 di vCrvExtProj. + // L'indice 0 contiene il bordo con i lati aperti/chiusi settati della intersezione con il grezzo + if ( SetTmpPropByOverlap( pCrvCompo_Step, 0, vCrvExtProj[i], nStat1, dToll) && nStat1 != -1) + pCrvCompo_Step->SetCurveTempProp( 0, 0, 0) ; // chiusa se non c'è Overlap + pCrvCompoH->AddCurve( Release( pCrvCompo_Step)) ; } } - } + } // se la curva è aperta la riaggiungo come sottocurva aperta alla composita pCrvCompoH->AddCurve( pCrvCompoCurr->GetCurve( uu)->Clone()) ; } - pCrvCompoCurr.Set( Release( pCrvCompoH)) ; + // finite le sottocurve, restiruisco la composita finale con il valore delle sottocurve impostate + // la curva originale u-esima è stata scomposta in sottocurve aperte/chiuse a seconda di quali e quanti + // overlap ha fatto con le curve esterne delle proiezioni + if ( pCrvCompoH->GetCurveCount() > 1) + pCrvCompoCurr.Set( Release( pCrvCompoH)) ; } - // sostituisco la curva composita creata con la curva originaria - - PtrOwner pCrv_Bef( CloneCurveComposite( pCrvCompo_NewExt)) ; - PtrOwner pCrv_Aft( CloneCurveComposite( pCrvCompo_NewExt)) ; + // sostituisco la CURVA COMPOSITA creata con alla CURVA SEMPLICE originaria + PtrOwner pCrv_Bef( CloneCurveComposite( pCrvCompo_NewExt)) ; // tratto precente + PtrOwner pCrv_Aft( CloneCurveComposite( pCrvCompo_NewExt)) ; // tratto successivo PtrOwner pCrv_New( CreateCurveComposite()) ; if ( IsNull( pCrv_Bef) || IsNull( pCrv_Aft) || IsNull( pCrv_New) || ! pCrv_Bef->IsValid() || ! pCrv_Aft->IsValid()) return false ; + // ricomposizione con tagli per non perdere le proprietà appena impostate pCrv_Bef->TrimEndAtParam( u) ; pCrv_Aft->TrimStartAtParam( u + 1) ; if ( ! IsNull( pCrv_Bef) && pCrv_Bef->IsValid()) @@ -11482,18 +11774,15 @@ Pocketing::SetTmpPropWithRawProjectedFaces( ICurveComposite* pCrvCompo_NewExt, I } if ( ! IsNull( pCrv_Aft) && pCrv_Aft->IsValid()) pCrv_New->AddCurve( Release( pCrv_Aft)) ; - - // controllo vcalidità della curva, altrimenti non modifico nulla ed esco ( Avrò un chiuso) + // controllo validità della curva, altrimenti non modifico nulla ed esco ( Avrò un chiuso) if ( ! IsNull( pCrv_New) && pCrv_New->IsValid() && pCrv_New->IsClosed()) { pCrvCompo_NewExt->Clear() ; pCrvCompo_NewExt->AddCurve( Release( pCrv_New)) ; - u += nCrv ; + u += nCrv - 1 ; // " ++u " } } } - return true ; - } diff --git a/Pocketing.h b/Pocketing.h index e4a92df..d1aed64 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -97,18 +97,21 @@ class Pocketing : public Machining const double& dDepth, const double& dStep) ; bool AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const double& dRawSecLen, ICRVCOMPOPOVECTOR& vCrvOEFlags, bool& bChanged, double dAreaToll = 500 * EPS_SMALL) ; + bool AdjustFakeOpenEdges( ISurfFlatRegion* pSrf, const ISurfFlatRegion* pSrfOrig, const Vector3d vtTrasl) ; bool GetStmRawPart( int nId, ISurfTriMesh* pSrfTMRaw, Frame3d frPocket = GLOB_FRM) ; bool CheckSmallPartsForOpenEdge( ICurveComposite* pCrvCompo, double dToll = 1500 * EPS_SMALL) ; bool SetTmpPropWithRawProjectedFaces( ICurveComposite* pCrvCompo_NewExt, ICRVCOMPOPOVECTOR& vCrvExtProj, - double dToll = 150 * EPS_SMALL) ; + const Vector3d& vtN, double dToll = 150 * EPS_SMALL) ; bool IntersSurfWithRaw( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm, const Vector3d& vtTrasl, bool& bIsChanged, double dAreaToll = 500 * EPS_SMALL, bool bInVsOut = true, bool bRemoveSmallRawParts = false) ; bool ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrals, const ISurfTriMesh* pSrfProjRaw, int nId, - const double& dRawSecLen, double dAreaToll = 500 * EPS_SMALL) ; + const double& dRawSecLen, const ISurfFlatRegion* pSrfOrig, double dAreaToll = 500 * EPS_SMALL) ; bool AdjustAngleForProjectedFace( const ISurfFlatRegion* pSrfFaceT, ICurveComposite* pCrvEdgeBorder, double dAngle) ; bool SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfO, bool bFromProj = false) ; - bool GetProjStmBoxOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, ISurfFlatRegion* pSfrRawBoxProj) ; + bool GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSrfOrig, + ISurfFlatRegion* pSfrRawBoxProj) ; + bool CutProjectionToFitShape( ISurfFlatRegion* pSrfProjected, const ISurfFlatRegion* pSrfOrig) ; bool AjustCurveForProjRawOnFace( const ICurveLine* pL1, ICurveLine* pL2, const ICurveComposite* pCrvBorder, ICurveComposite* pCompo, int nStat, PNTVECTOR vPtTan, ISurfFlatRegion* pSrfProjRaw) ; bool GetCurveByOverlap( const ICurve* pCrv, const ICurveComposite* pCrvCompo, int& nInd, @@ -323,7 +326,7 @@ class Pocketing : public Machining double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto bool m_bIntersRaw = true ; // flag per intersezione con grezzo bool m_bProjectRaw = true ; // flag di proiezione del grezzo - double m_dMaxLenRawProj = 20 ; // lunghezza massima per contatto di proiezione + double m_dMaxLenRawProj = 100 ; // lunghezza massima per contatto di proiezione bool m_bOptOffset = true ; // flag per ottimizzazione numero di Offset necessari bool m_bOptOffsetCM = false ; // flag per ottimizzazione numero di Offset necessari con centroidi e medial Axis bool m_bAssignFeed = true ; // flag per controllo della Feed