diff --git a/Pocketing.cpp b/Pocketing.cpp index c4379ad..91b0b2a 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -3508,11 +3508,11 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl if ( pSrfIslandsOff2->IsValid() || pSrfIslandsOff2->GetChunkCount() > 0) { if ( AreOppositeVectorApprox( pSrfZigZag->GetNormVersor(), pSrfIslandsOff2->GetNormVersor())) pSrfIslandsOff2->Invert() ; - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfZigZag->Clone()) ; - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfIslandsOff2->Clone()) ; + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfZigZag->Clone()) ; + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfIslandsOff2->Clone()) ; if ( ! pSrfZigZag->Subtract( *pSrfIslandsOff2)) return false ; - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfZigZag->Clone()) ; + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfZigZag->Clone()) ; // aggiungo le curve della superficie delle isole alle curve da percorrere ( se necessario) if ( nLoopAft != nLoopBef) { if ( AreSameVectorApprox( pSrfZigZag->GetNormVersor(), pSrfIslandsOff2->GetNormVersor())) @@ -9019,7 +9019,27 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, ICRVCOMPOPOVECTO } // aggiungo la curva pCompo->AddCurve( ::Release( vpCrvs[i]), true, 10 * EPS_SMALL) ; - //pCompo->AddCurve( vpCrvs[i]->Clone(), true, 10 * EPS_SMALL) ; + // NB. Se ho solo una curva esterna e all'interno ho almeno un'isola chiusa più vicina del raggio del tool, + // non andrò mai a creare regioni di incidenza, quindi genererei 0 o più chunks dove il Tool non riesce a passare... + if ( i == 0 && ( int)vpCrvs.size() > 0 && ( int)vCrvIsl.size() > 0) { + Point3d ptS ; pCompo->GetEndPoint( ptS) ; + Point3d ptE ; pCompo->GetStartPoint( ptE) ; + bool bIsAllOpen = true ; + for ( int u = 0 ; u < pCompo->GetCurveCount() && bIsAllOpen ; ++ u) { + int nP = 0 ; + if ( pCompo->GetCurveTempProp( u, nP, 0) && nP == 0) + bIsAllOpen = false ; + } + if ( bIsAllOpen) { + PtrOwner pCrvNew( CreateCurveComposite()) ; + if ( ! bInVsOut && + AdjustPathOutsideRawForOpenEdges( pCompo_clone, vCrvIsl, pCompo, ptS, ptE, dRad, dDiam, + pCrvNew, vtTrasl, pStmRaw, bInVsOut)) { + pCompo->Clear() ; + pCompo->CopyFrom( pCrvNew) ; + } + } + } } // non dovrebbe esserci un gap, ma meglio prevenire problemi @@ -9168,16 +9188,29 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons // -------------- RECUPERO DELLA CURVA ESTERNA PRIMA E DOPO IL LATO APERTO CORRENTE -------------- double dUTrimS, dUTrimE ; PtrOwner pCompo_Prec( CloneCurveComposite( pCompo)) ; - pCompo_Prec->GetParamAtPoint( ptCrvOpenS, dUTrimS) ; - if ( ! pCompo_Prec->TrimEndAtParam( dUTrimS)) - pCompo_Prec->Clear() ; PtrOwner pCompo_Succ( CloneCurveComposite( pCompo)) ; - pCompo_Succ->GetParamAtPoint( ptCrvOpenE, dUTrimE) ; - if ( ! pCompo_Succ->TrimStartAtParam( dUTrimE)) - pCompo_Succ->Clear() ; PtrOwner pCrvOpen( CloneCurveComposite( pCompo)) ; - if ( ! pCrvOpen->TrimStartEndAtParam( dUTrimS, dUTrimE)) - pCrvOpen->Clear() ; + if ( ! AreSamePointApprox( ptCrvOpenS, ptCrvOpenE)) { + // se inizio e fine diversi... + pCompo_Prec->GetParamAtPoint( ptCrvOpenS, dUTrimS) ; + if ( ! pCompo_Prec->TrimEndAtParam( dUTrimS)) + pCompo_Prec->Clear() ; + + pCompo_Succ->GetParamAtPoint( ptCrvOpenE, dUTrimE) ; + if ( ! pCompo_Succ->TrimStartAtParam( dUTrimE)) + pCompo_Succ->Clear() ; + + if ( ! pCrvOpen->TrimStartEndAtParam( dUTrimS, dUTrimE)) + pCrvOpen->Clear() ; + + } + else { + // se l'inizio coincide con la fine, allora la curva è tutta aperta + pCrvOpen.Set( pCompo->Clone()) ; + pCompo_Prec->Clear() ; + pCompo_Succ->Clear() ; + } + PtrOwner pCompo_noOpenCrv( CloneCurveComposite( pCompo_Succ)) ; pCompo_noOpenCrv->AddCurve( pCompo_Prec->Clone()) ; @@ -9205,7 +9238,7 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons pCrvOpen->Clear() ; bool bOk = true ; // 4) Creo regione squadrata da questa curva - PtrOwner pSfrInc( GetSurfFlatRegionFromFatCurve( Release( pCrvOpen_clone), dRad, true, false)) ; + PtrOwner pSfrInc( GetSurfFlatRegionFromFatCurve( Release( pCrvOpen_clone), dRad , true, false)) ; if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) { Point3d ptE ; pCrvOpenOffs->GetEndPoint( ptE) ; @@ -9236,7 +9269,7 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons // 1) recupero la curva corrente PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ; if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) - return false ; + continue ; CRVCVECTOR ccClass ; if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) { @@ -9317,6 +9350,7 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons if ( pSfrExpan->IsValid()) { if ( AreOppositeVectorApprox( pSfrExpan->GetNormVersor(), vtExtr)) pSfrExpan->Invert() ; + // ----------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA ---------- PtrOwner pSfrInc_c( CloneSurfFlatRegion( pSfrInc)) ; if ( IsNull( pSfrInc_c)) @@ -9371,27 +9405,32 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons if ( IsNull( pCrvNewBorder)) return false ; - double dUSTART ; - if ( ! pCrvNewBorder->GetParamAtPoint( ptSTART, dUSTART, 5000 * EPS_SMALL)) { - int nFlag ; - if ( ! DistPointCurve( ptSTART, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUSTART, nFlag)) + if ( ! AreSamePointApprox( ptCrvOpenE, ptCrvOpenS)) { + double dUSTART ; + if ( ! pCrvNewBorder->GetParamAtPoint( ptSTART, dUSTART, 5000 * EPS_SMALL)) { + int nFlag ; + if ( ! DistPointCurve( ptSTART, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUSTART, nFlag)) + return false ; + } + pCrvNewBorder->ChangeStartPoint( dUSTART) ; + double dUEND ; + if ( ! pCrvNewBorder->GetParamAtPoint( ptEND, dUEND, 5000 * EPS_SMALL)) { + int nFlag ; + if ( ! DistPointCurve( ptEND, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUEND, nFlag)) return false ; + } + if ( ! pCrvNewBorder->TrimEndAtParam( dUEND)) + pCrvNewBorder->Clear() ; } - pCrvNewBorder->ChangeStartPoint( dUSTART) ; - double dUEND ; - if ( ! pCrvNewBorder->GetParamAtPoint( ptEND, dUEND, 5000 * EPS_SMALL)) { - int nFlag ; - if ( ! DistPointCurve( ptEND, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUEND, nFlag)) - return false ; - } - if ( ! pCrvNewBorder->TrimEndAtParam( dUEND)) - pCrvNewBorder->Clear() ; pNewCrv->Clear() ; pNewCrv->AddCurve( Release( pCrvNewBorder)) ; for ( int u = 0 ; u < pNewCrv->GetCurveCount() ; ++ u) pNewCrv->SetCurveTempProp( u, 1, 0) ; + int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrInc->Clone()) ; + m_pGeomDB->SetMaterial( r, RED) ; + return true ; } @@ -9610,6 +9649,7 @@ Pocketing::GetParamsAtEachStep( ISURFFRPOVECTOR& vSrfSliced, vector pSrfChunk_c( CloneSurfFlatRegion( pSrfChunk)) ; if ( IsNull( pSrfChunk_c) || ! pSrfChunk_c->IsValid() || pSrfChunk_c->GetChunkCount() == 0) return false ; + vVtTrasl.clear() ; // creazione di un vettore con gli step ( caso base) for ( int j = 1 ; j <= nStep ; ++ j) @@ -9720,7 +9760,7 @@ Pocketing::GetParamsAtEachStep( ISURFFRPOVECTOR& vSrfSliced, vectorIsValid()) return false ; - int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRef->Clone()) ; - m_pGeomDB->SetMaterial( b, BLUE) ; + //int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRef->Clone()) ; + //m_pGeomDB->SetMaterial( b, BLUE) ; // 2.1) Per semplicità rimuovo dalla superficie tutti i triangoli che sono perpendicolari al piano di svuotatura StmFromTriangleSoup TriaSoupEasy ; TriaSoupEasy.Start() ; @@ -10173,8 +10213,8 @@ Pocketing::ProjectStmOnPlane( const ISurfTriMesh* pStmAbove, const Plane3d plPoc return true ; // non ho nulla da proiettare pStmRef.Set( pStmRef_Easy->Clone()) ; - int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRef->Clone()) ; - m_pGeomDB->SetMaterial( a, AQUA) ; + //int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRef->Clone()) ; + //m_pGeomDB->SetMaterial( a, AQUA) ; // 3) scalo la superficie rispetto al sistema di riferimento ( mettendo a 0 la componente vtN) pStmRef->ToLoc( frPlane) ; @@ -10182,8 +10222,8 @@ Pocketing::ProjectStmOnPlane( const ISurfTriMesh* pStmAbove, const Plane3d plPoc return false ; pStmRef->ToGlob( frPlane) ; - int P = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRef->Clone()) ; - m_pGeomDB->SetMaterial( P, PURPLE) ; + //int P = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRef->Clone()) ; + //m_pGeomDB->SetMaterial( P, PURPLE) ; // 4) controllo la validità della superficie ottenuta if ( IsNull( pStmRef) || ! pStmRef->IsValid() || pStmRef->GetTriangleCount() == 0) @@ -10210,10 +10250,10 @@ Pocketing::ProjectStmOnPlane( const ISurfTriMesh* pStmAbove, const Plane3d plPoc return true ; pStmUp->Repair() ; pStmDown->Repair() ; - int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmUp->Clone()) ; - int o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmDown->Clone()) ; - m_pGeomDB->SetMaterial( r, RED) ; - m_pGeomDB->SetMaterial( o, ORANGE) ; + //int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmUp->Clone()) ; + //int o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmDown->Clone()) ; + //m_pGeomDB->SetMaterial( r, RED) ; + //m_pGeomDB->SetMaterial( o, ORANGE) ; //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrProj->Clone()) ; // 6) Essendo due Trimesh piane e sullo stesso piano, converto in FlatRegion prima di unirle @@ -10375,6 +10415,7 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ISurfTriMes if ( ! ModifySurfByOpenEdge( pSrf, vCrvOEFlags, vtTrasl, pStmRaw)) return false ; + // 4) SE SUPERIFICIE PRECEDENTEMENTE GIA' LAVORATA... if ( m_dDiam_Prec > 0) return GetNewSrfByAnotherPocketing( pSrf, pSrf_noOpenEdge, vtTrasl) ; @@ -11160,40 +11201,6 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt if ( IsNull( pSrfByCurves) || pSrfByCurves->GetChunkCount() == 0) // controllo validità della FlatRegion return false ; - // ------------- aggiunta delle piccole parti del grezzo ------------- - // controllo se ho rimosso piccole regioni di grezzo... - // queste regioni possono creare problemi nella definizione di lati aperti - //if ( bRemoveSmallRawParts) { - // PtrOwner pSrf_RawPartsRemoved( CloneSurfFlatRegion( pSrfByCurves)) ; - // PtrOwner pSrf_Pock_orig( CloneSurfFlatRegion( pSfrPock)) ; - // if ( IsNull( pSrf_RawPartsRemoved) || ! pSrf_RawPartsRemoved->IsValid() || - // IsNull( pSrf_Pock_orig) || ! pSrf_Pock_orig->IsValid()) - // return false ; - // pSrf_Pock_orig->Translate( vtTrasl) ; - // if ( pSrf_Pock_orig->Subtract( *pSrf_RawPartsRemoved)) { - // for ( int cc_ = 0 ; cc_ < pSrf_Pock_orig->GetChunkCount() ; ++ cc_) { - // // clono dil Chunk cc_ esimo - // PtrOwner pSrfCcc_( pSrf_Pock_orig->CloneChunk( cc_)) ; - // if ( IsNull( pSrfCcc_) || ! pSrfCcc_->IsValid()) - // return false ; - // if ( ! pSrfCcc_->Offset( m_dDiam_Prec > 0 ? - // - 0.1 * m_dDiam_Prec - m_dOffsetR_Prec : - 0.1 * m_TParams.m_dDiam + GetOffsR(), - // ICurve::OFF_FILLET) || pSrfCcc_->GetChunkCount() == 0) { - // // se Offset interno sparisce, allora aggiungo il chunk cc_ esimo alla superificie da svuotare - // PtrOwner pSrf_Chunck_cc_( pSrf_Pock_orig->CloneChunk( cc_)) ; - // if ( IsNull( pSrf_Chunck_cc_) || ! pSrf_Chunck_cc_->IsValid()) - // return false ; - // pSrfByCurves->Add( *pSrf_Chunck_cc_) ; - // } - // } - // } - //} - - // rincontrollo ancora le aree, nel caso siano circa uguali lascio la superificie invariata - //if ( pSrfByCurves->GetArea( dAreaAfter) && pSfrPock->GetArea( dAreaBefore) && - // abs( dAreaBefore - dAreaAfter) < dAreaBefore * 0.00125) - // return true ; // se la superificie non è cambiata, allora lascio tutto inviariato... - // riporto la superificie tagliata alla quota originale pSrfByCurves->Translate( - vtTrasl) ; @@ -11228,7 +11235,7 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p int nProp0 = pCrvEL->GetTempProp( 0) ; int nProp1 = pCrvEL->GetTempProp( 1) ; - // creo un vettore contenente tutti i loop esterni ed Interni della superificie originaria + // creo un vettore contenente tutti i loop Esterni ed Interni della superificie originaria int nExtLoop = pSrfForCrvs->GetChunkCount() ; ICRVCOMPOPOVECTOR vCrvAll ; @@ -11257,10 +11264,25 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p pCrv->SetCurveTempProp( i, -1, 0) ; // setto proprietà da definire di default for ( int j = 0 ; j < ( int)vCrvAll.size() ; ++ j) { int nStat = 0 ; + int nCrv = pCrv->GetCurveCount() ; // # curve attuali if ( ! SetTmpPropByOverlap( pCrv, i, vCrvAll[j], nStat, 1500 * EPS_SMALL)) return false ; - if ( nStat == 1) // se overlap Trovato, non controllo overlap su altri loops - break ; + if ( nStat == 1) { // se overlap Trovato + // se ho inserito solo curve chiuse, allora evito di controllare gli altri loops, + // se ho inserito curve aperte, allora controllo con gli altri loops + // potrebbero esserci delle isole chiuse molto vicine ad un lato aperto ; + // dato che le curve in vCrvAll sono ordinate sempre dalle esterne alle interne, rischio di importare + // aperto il lato chiuso di un'isola vicina al bordo aperto + // NB. Escludo il loop esterno ( altrimenti effetto domino) + bool bAllClosed = true ; + for ( int u = i ; u <= i + pCrv->GetCurveCount() - nCrv && bAllClosed && l != 0; ++ u) { + int nP = 0 ; + if ( pCrv->GetCurveTempProp( u, nP, 0) && nP == 1) + bAllClosed = false ; + } + if ( bAllClosed) + break ; + } } } // sistemo gli errori dovuti alle tolleranze @@ -14201,13 +14223,13 @@ Pocketing::GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const P PolyArc PA ; // 1) Mergiamo per uniformità pCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; - m_pGeomDB->SetMaterial( b, BLUE) ; + //int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; + //m_pGeomDB->SetMaterial( b, BLUE) ; // 2) Rimuoviamo Spikes o Curve a Z if ( ! pCrv->RemoveSmallDefects( 150 * EPS_SMALL, 2 * ANG_TOL_STD_DEG, true)) return false ; - int c = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; - m_pGeomDB->SetMaterial( c, AQUA) ; + //int c = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; + //m_pGeomDB->SetMaterial( c, AQUA) ; // 3) Interpoliamo mediante Linee ed Archi pCrv->ToLoc( frPock) ; pCrv->ApproxWithArcsEx( 500 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; // 5 * EPS_SMALL @@ -14224,8 +14246,8 @@ Pocketing::GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const P PtrOwner pCrv_c( pCrv->CopyParamRange( dS, dE)) ; if ( IsNull( pCrv_c) || ! pCrv_c->IsValid()) return false ; - int p = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; - m_pGeomDB->SetMaterial( p, PURPLE) ; + //int p = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; + //m_pGeomDB->SetMaterial( p, PURPLE) ; // se la curva è "stretta" la trascuro, rende solo difficili i conti senza dare valore aggiunto PtrOwner pCrv_proj( ProjectCurveOnPlane( *pCrv_c, plPock)) ;