diff --git a/Pocketing.cpp b/Pocketing.cpp index 78b95e2..db3a63c 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -51,6 +51,7 @@ #include "/EgtDev/Include/EGkIntersPlaneSurfTm.h" #include "/EgtDev/Include/EGkDistPointSurfTm.h" #include "/EgtDev/Include/EGkStmFromCurves.h" +#include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include using namespace std ; @@ -4411,7 +4412,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, nStep, vtTool, dElev, dDepth, dStep)) return false ; - return false ; + //return false ; Point3d ptP1 ; // per LeadIn // ciclo su tutti gli step @@ -9051,7 +9052,7 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons if ( pStmRaw != nullptr) { bool bIsChanged ; if ( m_bIntersRaw) - IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false) ; + IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false, false) ; } if ( bInVsOut) { @@ -9409,7 +9410,7 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl 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) ; @@ -9418,12 +9419,17 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl const ICurveComposite* pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ; for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ; + int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ; int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ; - m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; + if ( nProp1 != -99) + m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; + else + m_pGeomDB->SetMaterial( aaa, Color( 1.0, 0.5, 0.0)) ; } } - }*/ + } } + // 2) PROIEZIONE CON GREZZO if ( m_bProjectRaw) { // recupero la Trimesh di partenza @@ -9482,71 +9488,230 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl //---------------------------------------------------------------------------- bool -Pocketing::AdjustFakeOpenEdges( ISurfFlatRegion* pSrf, const ISurfFlatRegion* pSrfOrig, const Vector3d vtTrasl) +Pocketing::AdjustFakeOpenEdges( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSfrOrig, const ISurfTriMesh* pStmRaw, + const Vector3d vtTrasl) { // controllo dei parametri - if ( pSrf == nullptr || ! pSrf->IsValid() || pSrf->GetChunkCount() == 0 || - pSrfOrig == nullptr || ! pSrfOrig->IsValid() || pSrfOrig->GetChunkCount() == 0 || - vtTrasl.IsSmall()) + if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) return false ; + if ( pStmRaw == nullptr) // se non c'è grezzo... + return true ; - // creo un frame Locale - Frame3d frPock ; - Vector3d vtN = pSrf->GetNormVersor() ; - Point3d ptC ; - if ( ! pSrf->GetCentroid( ptC)) - if ( ! pSrf->GetLoop( 0, 0)->GetStartPoint( ptC)) + + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->Clone()) ; + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrOrig->Clone()) ; + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRaw->Clone()) ; + + // recupero le tmpProp, vettore estrusione e spessore + int nTmpProp0 = pCrvCompo->GetTempProp() ; + int nTmpProp1 = pCrvCompo->GetTempProp( 1) ; + Vector3d vtExtr ; pCrvCompo->GetExtrusion( vtExtr) ; + double dThick ; pCrvCompo->GetThickness( dThick) ; + + // -------------------- TAGLIO IL GREZZO CON IL PIANO DEFINITO ALLO STEP ATTUALE ------------- + // 1) CREAZIONE DEL PIANO + Plane3d plProj ; + Point3d ptCen ; + if ( ! pCrvCompo->GetCentroid( ptCen)) // punto + if ( ! pCrvCompo->GetStartPoint( ptCen)) return false ; - frPock.Set( ptC, vtN) ; - if ( ! frPock.IsValid()) + Vector3d vtNorm = pSfrOrig->GetNormVersor() ; // normale + if ( vtNorm.IsSmall()) 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) + plProj.Set( ptCen + vtTrasl, -vtNorm) ; // così taglio tutto cià che sta nel semipiano negativo dello step attuale + if ( ! plProj.IsValid()) return false ; + // 2) TAGLIO DEL GREZZO + PtrOwner pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ; + if ( IsNull( pSrfRaw_clone)) + return false ; + if ( ! pSrfRaw_clone->Cut( plProj, true)) + return false ; + if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0) + return true ; + // ------------------------------------------------------------------------------------------- - // traslo la superificie da svuotare in modo da sovrapporla con la superificie originale - pSrfAct->Translate( - vtTrasl) ; + // ------- PROIEZIONE DELLE CURVE DI OGNI FACCIA DEL GREZZO RICAVATO SUL PIANO DELLA SVUOTATURA -------------- + // Proietto ora le curve, delle facce della superificie ottenuta, sul piano della svuotatura + ICRVCOMPOPVECTOR vCrvExtProj ; + PtrOwner pCrvCompo_Clone_Trasl( CloneCurveComposite( pCrvCompo)) ; + if ( IsNull( pCrvCompo_Clone_Trasl) || ! pCrvCompo_Clone_Trasl->IsValid()) + return false ; + pCrvCompo_Clone_Trasl->Translate( vtTrasl) ; + vCrvExtProj.emplace_back( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; // come indice 0 - // 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) + for ( int f = 0 ; f < pSrfRaw_clone->GetFacetCount() ; ++ f) { + // controllo se la faccia è quasi perpendicolare, nel caso la salto + Vector3d vtN_check ; pSrfRaw_clone->GetFacetNormal( f, vtN_check) ; + if ( abs( vtN_check * vtNorm) < EPS_ZERO) + continue ; + POLYLINEVECTOR vPL ; + pSrfRaw_clone->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])) 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 ; - - } - } + PtrOwner pCrvProjFacef( ProjectCurveOnPlane( *pCrvBorder, plProj)) ; + if ( IsNull( pCrvProjFacef) || ! pCrvProjFacef->IsValid()) + return false ; + // 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) + continue ; + // creo la curva composita associata + PtrOwner pCrvBorderProj_f( CreateCurveComposite()) ; + pCrvBorderProj_f->AddCurve( Release( pCrvProjFacef)) ; + vCrvExtProj.emplace_back( Release( pCrvBorderProj_f)) ; } } + //for ( int i = 0 ; i < vCrvExtProj.size() ; ++ i) + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvExtProj[i]->Clone()) ; + //------------------------------------------------------------------------------------------------------------- + + // ---------------- CREAZIONE DELLA VERA A PROPRIA REGIONE DI INCIDENZA, COME SOMMA DELLE + // ----------------------------- SINGOLE FLATREGIONS DI PROIEZIONE ----------------------------- + PtrOwner pSrf_Proj_Ext( CreateSurfFlatRegion()) ; + if ( IsNull( pSrf_Proj_Ext)) + return false ; + + for ( int i = 1 ; i < ( int)vCrvExtProj.size() ; ++ i) { + PtrOwner pSrf_H( CreateSurfFlatRegion()) ; + 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() , pSfrOrig->GetNormVersor())) + pSrf_H->Invert() ; + } + if ( pSrf_Proj_Ext->GetChunkCount() == 0) + pSrf_Proj_Ext.Set( Release( pSrf_H)) ; + else + pSrf_Proj_Ext->Add( *Release( pSrf_H)) ; + } + // 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)) ; + PtrOwner pSrf_ind0( CreateSurfFlatRegion()) ; + if ( IsNull( pSrf_Proj) || ! pSrf_Proj->IsValid() || IsNull( pSrf_ind0)) + return false ; + pSrf_ind0->AddExtLoop( vCrvExtProj[0]->Clone()) ; + if ( AreOppositeVectorApprox( pSrf_ind0->GetNormVersor(), pSfrOrig->GetNormVersor())) + pSrf_ind0->Invert() ; + pSrf_Proj->Add( *pSrf_ind0) ; + + int ooo = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_Proj->Clone()) ; + m_pGeomDB->SetMaterial( ooo, Color( 0.0, 1.0, 0.0, 0.3)) ; + // =============================================================================================================== + + // Creo la nuova curva che dovrò restiturire alla fine della proiezione ( settando le rispettive proprietà) + PtrOwner pCrvCompo_Final( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo_Final)) + return false ; + pCrvCompo_Final->SetExtrusion( vtExtr) ; + pCrvCompo_Final->SetThickness( dThick) ; + pCrvCompo_Final->SetTempProp( nTmpProp0, 0) ; + pCrvCompo_Final->SetTempProp( nTmpProp1, 1) ; + + // Clono la superificie originaria, portandola allo step corrente + PtrOwner pSrfOrig_clone( CloneSurfFlatRegion( pSfrOrig)) ; + if ( IsNull( pSrfOrig_clone) || ! pSrfOrig_clone->IsValid()) + return false ; + pSrfOrig_clone->Translate( vtTrasl) ; + + int oooo = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfOrig_clone->Clone()) ; + m_pGeomDB->SetMaterial( oooo, Color( 0.0, 0.0, 0.0, 0.3)) ; + + // controllo le curve della composita + bool bLoopL_isChanged = false ; + for ( int u = 0 ; u < pCrvCompo_Clone_Trasl->GetCurveCount() ; ++ u) { + PtrOwner pCrv_u( pCrvCompo_Clone_Trasl->GetCurve( u)->Clone()) ; + if ( IsNull( pCrv_u) || ! pCrv_u->IsValid()) + return false ; + // ricavo la temp prop + int nTmpProp = pCrv_u->GetTempProp( 0) ; + if ( nTmpProp == 1) { + // 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 ; + pCrv_uOpen_clone->SetExtrusion( vtExtr) ; + // 2) effettuo l'Offset + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( pCrv_uOpen_clone, m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec + m_dOffsetR_Prec : + 0.5 * m_TParams.m_dDiam + GetOffsR(), ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0) + return false ; + // 3) ricavo la curva di Offset + PtrOwner pCrv_uOpen_Offs( OffsCrv.GetLongerCurve()) ; + if ( IsNull( pCrv_uOpen_Offs) || ! pCrv_uOpen_Offs->IsValid()) + return false ; - return true ; + // TOGLIEREEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE--- + PtrOwner hhhhhh( pCrv_uOpen_Offs->Clone()) ; + int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, hhhhhh->Clone()) ; + m_pGeomDB->SetMaterial( aaa, YELLOW) ; + // ------------------------------------------------------------------------------------------------- + + + // 4) classifico la curva di offset ricavata con la supericie originale + // NB. Tutti tratti di curva che sono esterni alla superificie originale e che si trovano all'interno della + // superificie di proeizione del grezzo lo rovineranno al di fuori della superficie originale, quindi + // vanno impostati come chiusi + CRVCVECTOR ccClass ; + if ( pSrfOrig_clone->GetCurveClassification( *pCrv_uOpen_Offs, 10 * EPS_SMALL, ccClass)) { + for ( int j = 0 ; j < ( int)ccClass.size() ; ++ j) { + // 5) scorro tutti i tratti di curva della classificazione + // NB. I parametri sulla curva di Offset e sulla curva originale sono in proporizione ( la curva + // è singola, quindi non ci sono raccordi). Posso quindi sfruttare i parametri della classificazione + // della curva Offsettata e utilizzarli per spezzare in sottocurve la curva originaria + PtrOwner pCrv_j_Offs( pCrv_uOpen_Offs->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; + PtrOwner pCrv_uj( pCrv_u->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; + if ( IsNull( pCrv_j_Offs) || ! pCrv_j_Offs->IsValid() || IsNull( pCrv_uj) || ! pCrv_uj->IsValid()) + continue ; + if ( ccClass[j].nClass == CRVC_OUT) { + CRVCVECTOR ccClass1 ; + bool bSetClose = false ; + if ( pSrf_Proj->GetCurveClassification( *pCrv_j_Offs, EPS_SMALL, ccClass1)) { + for ( int jj = 0 ; jj < ( int)ccClass1.size() && !bSetClose ; ++ jj) { + if ( ccClass1[jj].nClass == CRVC_IN) { + bLoopL_isChanged = true ; + bSetClose = true ; + //int ff = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_uj->Clone()) ; + //m_pGeomDB->SetMaterial( ff, Color( 0.95, 0.0, 0.63)) ; + } + } + } + pCrv_uj->SetTempProp( !bSetClose, 0) ; + pCrv_uj->SetTempProp( bSetClose ? -99 : 0, 1) ; + } + pCrvCompo_Final->AddCurve( pCrv_uj->Clone()) ; + } // chiusura ciclo for sui tratti di classificazione... + } + else // se classificazione errata -> lascio la curva invariata + pCrvCompo_Final->AddCurve( pCrv_u->Clone()) ; + } + else // se curva chiusa, la aggiungo + pCrvCompo_Final->AddCurve( pCrv_u->Clone()) ; + + //m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo_Final->Clone()) ; + } + + // se ci sono stati cambiamenti nella curva ... + if ( ! bLoopL_isChanged) + return true ; + // altrimenti sotituisco la curva originale, traslo e miglioro... + if ( pCrvCompo_Final != nullptr && pCrvCompo_Final->IsValid() && pCrvCompo_Final->IsClosed()) { + pCrvCompo_Final->Translate( - vtTrasl) ; + pCrvCompo_Final->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; + pCrvCompo->Clear() ; + pCrvCompo->CopyFrom( pCrvCompo_Final) ; + } + + return pCrvCompo != nullptr && pCrvCompo->IsValid() && pCrvCompo->GetCurveCount() > 0 ; } //---------------------------------------------------------------------------- @@ -9685,7 +9850,8 @@ Pocketing::ModifySurfByOpenEdge( ISurfFlatRegion* pSrf, ICRVCOMPOPOVECTOR& vCrvO //---------------------------------------------------------------------------- bool Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pStmRaw, const Vector3d& vtTrasl, - bool& bIsChanged, double dAreaToll, bool bInVsOut, bool bRemoveSmallRawParts) + bool& bIsChanged, double dAreaToll, bool bInVsOut, bool bRemoveSmallRawParts, + bool bComputeOpenEdge) { // se funzione non necessaria, esco subito @@ -9760,9 +9926,14 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt // essendo una curva derivante da un'intersezione di Trimesh ho una composita derivante da una polyLine, // devo recuperare gli archi PolyArc PA ; + Frame3d frPock ; frPock.Set( ptC, vtN) ; + if ( ! frPock.IsValid()) + return false ; + pCrv->ToLoc( frPock) ; pCrv->ApproxWithArcsEx( 5 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; // 500 * EPS_SMALL pCrv->Clear() ; pCrv->FromPolyArc( PA) ; + pCrv->ToGlob( frPock) ; pCrv->SetExtrusion( vtExtr) ; pCrv->SetThickness( dThick) ; @@ -9825,9 +9996,12 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt // riporto la superificie tagliata alla quota originale pSrfByCurves->Translate( - vtTrasl) ; - // ricalcolo i lati aperti - if ( ! SetOpenOrCloseEdge( pSrfByCurves, pSfrPock)) - return false ; + // ricalcolo i lati aperti ( se richisto) + if ( bComputeOpenEdge) { + PtrOwner pStmRaw_clone( CloneSurfTriMesh( pStmRaw)) ; + if ( IsNull( pStmRaw_clone) || ! SetOpenOrCloseEdge( pSrfByCurves, pSfrPock, false, pStmRaw_clone, vtTrasl)) + return false ; + } // modifico la superficie da svuotare pSfrPock->Clear() ; @@ -9838,7 +10012,8 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt //---------------------------------------------------------------------------- bool -Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfOrig, bool bFromProj) +Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfOrig, bool bFromProj, + ISurfTriMesh* pStmRaw, Vector3d vtTrasl) { // controllo parametri if ( pSrfTP == nullptr || pSrfTP->GetChunkCount() == 0 || pSrfOrig == nullptr || pSrfOrig->GetChunkCount() == 0) @@ -9867,13 +10042,15 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p for ( int c = 0 ; c < pSrfTP->GetChunkCount() ; ++ c) { // per ogni loop ... for ( int l = 0 ; l < pSrfTP->GetLoopCount( c) ; ++ l) { + // ricavo il loop come curva composita PtrOwner pCrv( GetCurveComposite( pSrfTP->GetLoop( c, l))) ; if ( IsNull( pCrv)) return false ; + // sistemazioni varie pCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - for ( int i = 0 ; i < pCrv->GetCurveCount() ; ++ i) { - pCrv->SetCurveTempProp( i, -1, 0) ; // setto proprietà da definire di default + if ( !bFromProj) // se non derivo da una proiezione, setto di Defualt le tmp prop della curva a -1 + pCrv->SetCurveTempProp( i, -1, 0) ; // setto proprietà da definire di default for ( int j = 0 ; j < ( int)vCrvAll.size() ; ++ j) { int nStat = 0 ; if ( ! SetTmpPropByOverlap( pCrv, i, vCrvAll[j], nStat, 1500 * EPS_SMALL)) @@ -9882,15 +10059,9 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p break ; } } - /*for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { - int nProp0 ; pCrv->GetCurveTempProp( u, nProp0, 0) ; - int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->GetCurve( u)->Clone()) ; - m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? AQUA : ORANGE) ; - }*/ - + // sistemo gli errori dovuti alle tolleranze if ( ! CheckSmallPartsForOpenEdge( pCrv)) return false ; - // controllo che le isole definite sulla superificie originale siano coerenti con le nuove isole ricavate ICRVCOMPOPOVECTOR vAllCrv_Isl ; for ( int i = nExtLoop ; i < ( int)vCrvAll.size() ; ++ i) { @@ -9924,8 +10095,8 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p } } - // controllo le sottocurve non definite ( non se sono nel caso di una proeizione) - for ( int i = 0 ; i < pCrv->GetCurveCount() && !bFromProj ; ++ i) { // nei casi di curve nuove ma senza overlap con isole ... + // controllo le sottocurve non definite con TmpProp = -1 ( non se sono nel caso di una proeizione) + for ( int i = 0 ; i < pCrv->GetCurveCount() && !bFromProj ; ++ i) { int nProp ; if ( pCrv->GetCurveTempProp( i, nProp) && nProp == -1) { // controllo che quel lato non abbia un estremo in comune con un'isola @@ -9939,16 +10110,13 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p pCrv->SetTempProp( nProp0, 0) ; pCrv->SetTempProp( nProp1, 1) ; - - //for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { - // int nProp0 ; pCrv->GetCurveTempProp( u, nProp0, 0) ; - // int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->GetCurve( u)->Clone()) ; - // m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : ( nProp0 == 1) ? RED : GREEN) ; - //} + // controllo se i lati aperti impostati sono effettivamente aperti ( se non sono nella proieizone) + if ( ! bFromProj) + if ( ! AdjustFakeOpenEdges( pCrv, pSrfOrig, pStmRaw, vtTrasl)) + return false ; // aggiungo la curva alla nuova superificie pSrfMod.AddCurve( pCrv->Clone()) ; - } } @@ -10747,7 +10915,7 @@ Pocketing::GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pSt } } - return false ; + return true ; } @@ -10986,7 +11154,7 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, if ( IsNull( pSrfOnPlPlus) || ! GetProjStmOnSfr( pSrf_clone_ChunkC, pStmRaw, pSrfOrig, pSrfOnPlPlus)) return false ; if ( IsNull( pSrfOnPlPlus) || ! pSrfOnPlPlus->IsValid() || pSrfOnPlPlus->GetChunkCount() == 0) - continue ; + pSrfOnPlPlus.Set( pSrf_clone_ChunkC) ; // inseirsco nel vettore vSfr_gained.emplace_back( pSrfOnPlPlus->Clone()) ; @@ -10994,8 +11162,59 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, // 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)) ; + else { + if ( ! pSrf_Final->Add( *pSrfOnPlPlus->Clone())) { + // ricavo il piano di svuotatura, estrusione e spessore + Plane3d plPock ; + PtrOwner pCrvH( pSrf->GetLoop( 0, 0)) ; + if ( IsNull( pCrvH) || ! pCrvH->IsValid()) + return false ; + Point3d ptC ; + if ( ! pCrvH->GetCentroid( ptC)) + if ( ! pCrvH->GetStartPoint( ptC)) + return false ; + Vector3d vtN = pSrf->GetNormVersor() ; + plPock.Set( ptC, vtN) ; + if ( ! plPock.IsValid()) + return false ; + plPock.Translate( vtTrasl) ; + Vector3d vtExtr ; pCrvH->GetExtrusion( vtExtr) ; + double dThick ; pCrvH->GetThickness( dThick) ; + // converto le due regioni in Trimesh + PtrOwner pStm1( CloneSurfTriMesh( pSrf_Final->GetAuxSurf())) ; + PtrOwner pStm2( CloneSurfTriMesh( pSrfOnPlPlus->GetAuxSurf())) ; + int rr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStm1->Clone()) ; + int rrr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStm2->Clone()) ; + m_pGeomDB->SetMaterial( rr, RED) ; + m_pGeomDB->SetMaterial( rrr, ORANGE) ; + if ( ! IsNull( pStm1) && ! IsNull( pStm2) && pStm1->IsValid() && pStm2->IsValid()) { + // controllo validità delle normali + Vector3d vtN1, vtN2 ; + if ( pStm1->GetFacetNormal( 0, vtN1) && pStm2->GetFacetNormal( 0, vtN2) && + AreOppositeVectorApprox( vtN1, vtN2)) + pStm2->Invert() ; + // creo la Zuppa di triangoli + StmFromTriangleSoup sTM_TSoup ; + sTM_TSoup.Start() ; + sTM_TSoup.AddSurfTriMesh( *Release( pStm1)) ; + sTM_TSoup.AddSurfTriMesh( *Release( pStm2)) ; + sTM_TSoup.End() ; + // ricavo la Trimesh della zuppa di triangoli + PtrOwner pStmResult( sTM_TSoup.GetSurf()) ; + //pStm1->Add( *Release( pStm2)) ; + m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmResult->Clone()) ; + if ( ! IsNull( pStmResult) && pStmResult->IsValid()) { + // dalla TriMesh ricavata ne estraggo la FlatRegion + PtrOwner pSfrResult( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrResult)) + return false ; + if ( GetSfrByStm( pStmResult, pSfrResult, plPock, vtExtr, dThick)) + pSrf_Final.Set( Release( pSfrResult)) ; + } + return false ; + } + } + } } // può capitare che da due Chunk distinti, mediante la proeizione questi si uniscano formandone uno solo... @@ -11012,12 +11231,12 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, SetOpenOrCloseEdge( pSrfChunk_c, vSfr_gained[i], true) ; if ( pSrf_Final_WithOCEdge->GetChunkCount() == 0) - pSrf_Final_WithOCEdge.Set( Release( pSrfChunk_c)) ; + pSrf_Final.Set( Release( pSrfChunk_c)) ; else pSrf_Final->Add( *Release( pSrfChunk_c)) ; } } - // aggiungo tutte le isole... <---------- !!! + // aggiungo tutte le isole... for ( int is = 0 ; is < ( int)vCrvIsl.size() ; ++ is) pSrf_Final->AddIntLoop( Release( vCrvIsl[is])) ; @@ -12738,4 +12957,69 @@ Pocketing::GetDynamicClearedRegion( ISurfFlatRegion* pSrfPrec, const ICurveCompo } return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const Plane3d plPock, const Vector3d& vtExtr, + const double dThick, double dToll) +{ + + // controllo validità dei parametri + if ( pStm == nullptr || ! pStm->IsValid() || + ! plPock.IsValid()) + return false ; + + // creo un Frame per il sistema di Riferimento Locale + Frame3d frPock ; frPock.Set( plPock.GetPoint(), plPock.GetVersN()) ; + if ( ! frPock.IsValid()) + return false ; + + // creo la FlatRegion da resitutiure + SurfFlatRegionByContours SrfChunkDef ; + + // recupero i Loop della TriMesh salvandoli in un vettore di PolyLine + POLYLINEVECTOR vPl ; + pStm->GetLoops( vPl) ; + + // per ogni PolyLine... + for ( int i = 0 ; i < ( int)vPl.size() ; ++ i) { + // recupero la curva composita + PolyLine PL = vPl[i] ; + PtrOwner pCrv( CreateCurveComposite()) ; + pCrv->FromPolyLine( PL) ; + int yy = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; + m_pGeomDB->SetMaterial( yy, GREEN) ; + // essendo una curva derivante da un'intersezione di Trimesh ho una composita derivante da una polyLine, + // devo recuperare gli archi + PolyArc PA ; + pCrv->ToLoc( frPock) ; + pCrv->ApproxWithArcsEx( 5 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; // 500 * EPS_SMALL + pCrv->Clear() ; + pCrv->FromPolyArc( PA) ; + pCrv->ToGlob( frPock) ; + pCrv->SetExtrusion( vtExtr) ; + pCrv->SetThickness( dThick) ; + int yyy = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; + m_pGeomDB->SetMaterial( yyy, BLACK) ; + // la converto in una semplice cruva per proiettarla su piano della svuotatura + // dato che le curve sono prese da una trimesh, le proietto sul piano 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, plPock)) ; + int y = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_proj->Clone()) ; + m_pGeomDB->SetMaterial( y, YELLOW) ; + SrfChunkDef.AddCurve( Release( pCrv_proj)) ; // aggiungo le curve proiettate + } + // recupero la FlatRegion + PtrOwner pSrfByCurves( SrfChunkDef.GetSurf()) ; + if ( IsNull( pSrfByCurves) || pSrfByCurves->GetChunkCount() == 0) // controllo validità della FlatRegion + return false ; + // restituisco la FlatRegion + pSfr->Clear() ; + pSfr->CopyFrom( pSrfByCurves) ; + return pSfr != nullptr && pSfr->IsValid() ; } \ No newline at end of file diff --git a/Pocketing.h b/Pocketing.h index d1aed64..0fcb94d 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -88,6 +88,8 @@ class Pocketing : public Machining // =================================================================== // =========================== GREZZO e GEOMETRIE ==================== + bool GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const Plane3d plPock, const Vector3d& vtExtr, + const double dThick, double dToll = 5 * EPS_SMALL) ; bool ProjectEdgesOnSelFace( const ISurfFlatRegion* pSfrFacet, const ISurfTriMesh* pStmEdge, INTVECTOR& vBannedId , int nFacet, ISurfFlatRegion* pSfrProj) ; bool GetSurfByAdj( const ISurfTriMesh* pSrfOri, INTVECTOR& vBannedId, int idCurrFace) ; @@ -97,18 +99,20 @@ 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 AdjustFakeOpenEdges( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSrfOrig, const ISurfTriMesh* pStmRaw, + 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, 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 bRemoveSmallRawParts = false, bool bComputeOpenEdge = true) ; bool ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrals, const ISurfTriMesh* pSrfProjRaw, int nId, 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 SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfOrig, bool bFromProj = false, + ISurfTriMesh* pStmRaw = nullptr, Vector3d vtTrasl = V_NULL) ; bool GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSrfOrig, ISurfFlatRegion* pSfrRawBoxProj) ; bool CutProjectionToFitShape( ISurfFlatRegion* pSrfProjected, const ISurfFlatRegion* pSrfOrig) ; @@ -325,7 +329,7 @@ class Pocketing : public Machining bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo 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 + bool m_bProjectRaw = false ; // flag di proiezione del grezzo 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