From d60cec01efc668ba7348af4d078a827bac0258f3 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Fri, 15 Dec 2023 19:31:11 +0100 Subject: [PATCH] EgtMachKernel : - primo codice di Test Volumi di svuotatura. --- EgtMachKernel.vcxproj | 2 +- Pocketing.cpp | 6461 ++++++++++++++++++++++------------------- Pocketing.h | 64 +- 3 files changed, 3503 insertions(+), 3024 deletions(-) diff --git a/EgtMachKernel.vcxproj b/EgtMachKernel.vcxproj index 1fcec9e..fbdcd73 100644 --- a/EgtMachKernel.vcxproj +++ b/EgtMachKernel.vcxproj @@ -100,7 +100,7 @@ Disabled ProgramDatabase true - WIN32;_WINDOWS;I_AM_EMK;_DEBUG;%(PreprocessorDefinitions) + WIN32;_WINDOWS;I_AM_EMK;_VRONI;_DEBUG;%(PreprocessorDefinitions) false false Use diff --git a/Pocketing.cpp b/Pocketing.cpp index 7e3ab2a..2998865 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -44,6 +44,7 @@ #include "/EgtDev/Include/EGkFilletChamfer.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" +#include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkLinePntTgCurve.h" #include "/EgtDev/Include/EGkSfrCreate.h" @@ -99,6 +100,7 @@ using namespace std ; //---------------------------------------------------------------------------- static string KEY_OPEN = "OPEN" ; +static string KEY_TOOL = "VTTOOL" ; static int LINK_CURVE_PROP = -3 ; static double FEED_DIVISOR = 1000.0 ; static double TOLL_TRAPEZOID = 50 * EPS_SMALL ; @@ -710,8 +712,12 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) // lavoro ogni singola catena bool bOk = true ; - if ( ! ProcessPath( nAuxId, GDB_ID_NULL, nClId)) - bOk = false ; + int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; + while ( nPathId != GDB_ID_NULL) { + if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) + bOk = false ; + nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + } if ( ! bOk) return false ; @@ -1094,8 +1100,9 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) //---------------------------------------------------------------------------- bool -Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) +Pocketing::GetCurvesAndPartialVolume( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp, Vector3d& vtN) { + // ammessi : curve, testi, facce di trimesh o regioni const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; if ( pGObj == nullptr) @@ -1106,6 +1113,8 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) return false ; // se curva if (( pGObj->GetType() & GEO_CURVE) != 0) { + // Thickness + double dThick = 0. ; PtrOwner pCurve ; // se direttamente curva if ( Id.nSub == SEL_SUB_ALL) { @@ -1113,6 +1122,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) const ICurve* pOriCurve = ::GetCurve( pGObj) ; if ( pOriCurve == nullptr) return false ; + pOriCurve->GetThickness( dThick) ; pCurve.Set( pOriCurve->Clone()) ; } // altrimenti sottocurva di composita @@ -1121,6 +1131,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) const ICurveComposite* pCompo = GetCurveComposite( pGObj) ; if ( pCompo == nullptr) return false ; + pCompo->GetThickness( dThick) ; // recupero la curva semplice const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ; if ( pOriCurve == nullptr) @@ -1140,9 +1151,9 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) if ( ! pCurve->GetExtrusion( vtExtr) || vtExtr.IsSmall()) pCurve->SetExtrusion( Z_AX) ; // corenza con vtTool - if ( ! m_vtNormal.IsValid()) - m_vtNormal = vtExtr ; - else if ( ! AreSameVectorApprox( vtExtr, m_vtNormal)) + if ( ! vtN.IsValid()) + vtN = vtExtr ; + else if ( ! AreSameVectorApprox( vtExtr, vtN)) return false ; // verifico sia piana e se necessario la appiattisco PtrOwner pFlatCrv( FlattenCurve( *pCurve, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ; @@ -1154,8 +1165,14 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) m_pMchMgr->SetLastError( 2404, "Error in Pocketing : Tool Not Perpendicular to Flat Area") ; return false ; } + // ricavo la Depth + double dDepth = 0. ; + if ( ! CalcDepth( Id.nId, vtExtr, dThick, dDepth)) + return false ; + // affondo + pFlatCrv->Translate(( m_Params.m_bToolInvert ? 1. : -1.) * dDepth * vtExtr) ; // aggiungo alla lista - lstPC.emplace_back( Release( pCurve)) ; + lstPC.emplace_back( Release( pFlatCrv)) ; return true ; } // se altrimenti testo @@ -1177,19 +1194,28 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) if ( ! pCrv->GetExtrusion( vtExtr) || vtExtr.IsSmall()) pCrv->SetExtrusion( Z_AX) ; // corenza con vtTool - if ( ! m_vtNormal.IsValid()) - m_vtNormal = vtExtr ; - else if ( ! AreSameVectorApprox( vtExtr, m_vtNormal)) + if ( ! vtN.IsValid()) + vtN = vtExtr ; + else if ( ! AreSameVectorApprox( vtExtr, vtN)) return false ; // tutte le curve sono chiuse ResetCurveAllTempProp( pCrv) ; + // ricavo la Depth + double dDepth = 0. ; + if ( ! CalcDepth( Id.nId, vtExtr, 0., dDepth)) + return false ; + // affondo + pCrv->Translate(( m_Params.m_bToolInvert ? 1. : -1.) * dDepth * vtExtr) ; lstPC.push_back( pCrv) ; } return true ; } // se altrimenti superficie else if ( pGObj->GetType() == SRF_TRIMESH) { - // recupero la trimesh + // inversione del tool non ammessa + if ( m_Params.m_bToolInvert) + return false ; + // recupero la trimesh const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ; if ( pSurf == nullptr) return false ; @@ -1200,19 +1226,38 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) pStm->ToGlob( frGlob) ; // recupero l'indice della faccia int nFacet = (( Id.nSub == SEL_SUB_ALL) ? 0 : Id.nSub) ; - // recupero la normale esterna della faccia - Vector3d vtN ; - if ( ! pStm->GetFacetNormal( nFacet, vtN)) + // recupero la normale esterna della faccia e il suo punto centrale + Vector3d vtN_tm ; + Point3d ptCenter ; + if ( ! pStm->GetFacetCenter( nFacet, ptCenter, vtN_tm)) return false ; - if ( ! m_vtNormal.IsValid()) - m_vtNormal = vtN ; - else if ( ! AreSameVectorApprox( vtN, m_vtNormal)) + if ( ! vtN.IsValid()) + vtN = vtN_tm ; + else if ( ! AreSameVectorEpsilon( vtN, vtN_tm, 5 * EPS_SMALL)) return false ; // inverto per definire il volume di pocketing pStm->Invert() ; + // la superficie diventa il suo volume di svuotatura + if ( ! SetPocketingVolume( ptCenter, pStm)) + return false ; + // ricavo la Depth + double dDepth = 0. ; + if ( ! CalcDepth( Id.nId, vtN_tm, 0., dDepth)) + return false ; + // creo il piano di taglio alla quota della faccia + Plane3d plCut ; plCut.Set( ptCenter + vtN_tm * ( - dDepth) , - vtN_tm) ; + if ( ! plCut.IsValid()) + return false ; + // taglio il volume alla quota di taglio + if ( ! pStm->Cut( plCut, true)) + return false ; + // chiudo + if ( ! SewingMissingFacesOnPlanes( pStm, plCut)) + return false ; // aggiungo la Trimesh if ( ! pStmTmp->Add( *pStm)) return false ; + return true ; } // se altrimenti regione @@ -1227,12 +1272,12 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) // porto in globale pSfr->ToGlob( frGlob) ; // recupero la normale della regione - Vector3d vtN = pSfr->GetNormVersor() ; - if ( vtN.IsSmall()) + Vector3d vtN_fr = pSfr->GetNormVersor() ; + if ( vtN_fr.IsSmall()) return false ; - if ( ! m_vtNormal.IsValid()) - m_vtNormal = vtN ; - else if ( ! AreSameVectorApprox( vtN, m_vtNormal)) + if ( ! vtN.IsValid()) + vtN = vtN_fr ; + else if ( ! AreSameVectorApprox( vtN, vtN_fr)) return false ; // determino intervallo di chunk int nCstart = 0 ; @@ -1254,6 +1299,12 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) AdjustCurveFromSurf( pCrvLoop, TOOL_ORTHO, FACE_CONT, 0) ; // tutte le curve sono chiuse ResetCurveAllTempProp( pCrvLoop) ; + // ricavo la Depth + double dDepth = 0. ; + if ( ! CalcDepth( Id.nId, vtN_fr, 0., dDepth)) + return false ; + // affondo + pCrvLoop->Translate(( m_Params.m_bToolInvert ? 1. : -1.) * dDepth * vtN_fr) ; // aggiungo il loop al vettore di curve lstPC.emplace_back( Release( pCrvLoop)) ; } @@ -1327,11 +1378,38 @@ Pocketing::ResetCurveAllTempProp( ICurve* pCurve) return true ; } +//---------------------------------------------------------------------------- +bool +Pocketing::CalcDepth( const int nId, const Vector3d& vtExtr, double dThick, double& dDepth) +{ + // recupero distanza da fondo dei grezzi interessati dal percorso + double dRbDist = 0. ; + if ( AreSameVectorApprox( vtExtr, Z_AX)) { + if ( ! GetDistanceFromRawBottom( m_nPhase, nId, m_TParams.m_dTDiam, dRbDist)) + return false ; + } + // se inversione del Tool + if ( m_Params.m_bToolInvert) + dThick = - dThick ; + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", abs( dThick)) ; + ExeLuaSetGlobNumVar( "RB", dRbDist) ; + string sMyDepth = m_Params.m_sDepth ; + if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) { + m_pMchMgr->SetLastError( 2406, "Error in Pocketing : Depth not computable") ; + return false ; + } + // se spessore positivo, lo sottraggo dal risultato + if ( dThick > 0) + dDepth -= dThick ; + + return true ; +} + //---------------------------------------------------------------------------- bool Pocketing::Chain( int nGrpDestId) { - // vettore puntatori alle curve ICURVEPOVECTOR vpCrvs ; vpCrvs.reserve( m_vId.size()) ; @@ -1341,12 +1419,14 @@ Pocketing::Chain( int nGrpDestId) PtrOwner pStm_tmp( CreateSurfTriMesh()) ; if ( IsNull( pStm_tmp) || ! pStm_tmp->AdjustTopology()) return false ; + // estrusione e spessore + Vector3d vtExtr = V_INVALID ; // scorro tutti gli id for ( const auto& Id : m_vId) { // vettore contente tutte le curve selezionate ICURVEPLIST lstPC ; - // prendo le curve e aggiorno la TriMesh di pocketing originale - if ( ! GetCurves( Id, lstPC, pStm_tmp)) { + // prendo le curve e/o aggiorno la TriMesh di pocketing originale + if ( ! GetCurvesAndPartialVolume( Id, lstPC, pStm_tmp, vtExtr)) { string sInfo = "Warning in Pocketing : Skipped entity " + ToString( Id) ; m_pMchMgr->SetWarning( 2451, sInfo) ; } @@ -1356,9 +1436,69 @@ Pocketing::Chain( int nGrpDestId) } } - // vettore di curve composite concatenate - ICRVCOMPOPOVECTOR vCrvCompo ; + // se inversione del Tool, allora inversione dell'estrusione + if ( m_Params.m_bToolInvert) + vtExtr.Invert() ; + // se ho trovato delle curve... + if ( int( vpCrvs.size()) > 0) { + + // concateno le curve se necessario + ICRVCOMPOPOVECTOR vCrvCompo ; + if ( ! ChainCurveArray( vInds, vpCrvs, vCrvCompo)) + return false ; + + // verifico che siano curve chiuse ( devono delimitare l'area da svuotare) + for ( int u = 0 ; u < int( vCrvCompo.size()) ; ++ u) { + if ( ! vCrvCompo[u]->IsClosed()) { + m_pMchMgr->SetLastError( 2402, "Error in Pocketing : Open Contour") ; + return false ; + } + } + + // ricavo il centro della prima curva + Point3d ptInside ; + if ( ! vCrvCompo[0]->GetCentroid( ptInside)) + return false ; + + // creazione della TriMesh di pocketing + PtrOwner pStmCurve_Volume( CreateSurfTriMesh()) ; + if ( IsNull( pStmCurve_Volume) || + ! pStmCurve_Volume->AdjustTopology() || + ! CreateStmForIntersection( pStmCurve_Volume, vCrvCompo, vtExtr)) + return false ; + + // intersezione della Trimesh con il finito -> rivavo il volume di svuotatura + if ( ! SetPocketingVolume( ptInside, pStmCurve_Volume)) + return false ; + + if ( pStm_tmp->IsValid()) + if ( ! pStm_tmp->Add( *pStmCurve_Volume)) + return false ; + } + + // per ogni part rivata dal volume di svuotatura... + for ( int p = 0 ; p < pStm_tmp->GetPartCount() ; ++ p) { + // creo nuovo gruppo + int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDestId, Frame3d()) ; + if ( nPathId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( p + 1)) ; + // inserisco la Part (p)-esima nel gruppo destinazione + int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, pStm_tmp->ClonePart( p)) ; + if ( nNewId == GDB_ID_NULL) + return false ; + // memorizzo la direzione di estrusione + m_pGeomDB->SetInfo( nPathId, KEY_TOOL, vtExtr) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::ChainCurveArray( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) +{ // preparo i dati per il concatenamento bool bFirst = true ; Point3d ptNear = ORIG ; @@ -1431,45 +1571,17 @@ Pocketing::Chain( int nGrpDestId) pCrvCompo->SetThickness( dThick) ; // aggiorno il nuovo punto vicino pCrvCompo->GetEndPoint( ptNear) ; - // se utile, approssimo con archi - //if ( ! ApproxWithArcsIfUseful( pCrvCompo, true)) - // return false ; - // recupero eventuali lati aperti - INTVECTOR vOpen ; - for ( int i = 0 ; i < int( pCrvCompo->GetCurveCount()) ; ++ i) { - int nProp = 0 ; - if ( pCrvCompo->GetCurveTempProp( i, nProp) && nProp == 1) - vOpen.emplace_back( i) ; - } // aggiungo la curva al vettore di curve composite concatenate vCrvCompo.emplace_back( Release( pCrvCompo)) ; } - // ricavo un punto interno per il finito corrente - Point3d ptInside ; - if ( pStm_tmp->GetTriangleCount() > 0) - pStm_tmp->GetCentroid( ptInside) ; - else if ( int( vCrvCompo.size() > 0)) - vCrvCompo[0]->GetCentroid( ptInside) ; - else - return false ; - - // creazione della TriMesh di pocketing - if ( ! CreateStmForIntersection( pStm_tmp, vCrvCompo)) - return false ; - - // intersezione della Trimesh con il finito -> rivavo il volume di svuotatura - if ( ! SetPocketingVolume( ptInside, pStm_tmp)) - return false ; - - // QUIIIIIIIIIIIIIII - return false ; return true ; + } //---------------------------------------------------------------------------- bool -Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo) +Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo, const Vector3d& vtN) { // se non ho entità esco if ( int( vCrvCompo.size()) == 0) @@ -1480,7 +1592,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv if ( ! vCrvCompo[0]->GetCentroid( ptOrig)) if ( ! vCrvCompo[0]->GetStartPoint( ptOrig)) return false ; - Frame3d frHeight ; frHeight.Set( ptOrig, m_vtNormal) ; + Frame3d frHeight ; frHeight.Set( ptOrig, vtN) ; if ( ! frHeight.IsValid()) return false ; @@ -1532,7 +1644,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv PtrOwner pSfrCurr( sfrBC.GetSurf()) ; while ( ! IsNull( pSfrCurr) && pSfrCurr->IsValid()) { // inverto se necessario - if ( AreOppositeVectorApprox( m_vtNormal, pSfrCurr->GetNormVersor())) + if ( AreOppositeVectorApprox( vtN, pSfrCurr->GetNormVersor())) pSfrCurr->Invert() ; if ( ! pSfrFinal->IsValid()) pSfrFinal.Set( Release( pSfrCurr)) ; @@ -1557,7 +1669,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv if ( IsNull( pCrvLoopExt) || ! pCrvLoopExt->IsValid()) return false ; // allargo il loop esterno presso i chiusi - if ( ! GetExtendedLoopToFitStmVolume( pCrvLoopExt)) + if ( ! GetExtendedLoopToFitStmVolume( pCrvLoopExt, vtN)) return false ; // inserisco la curva nel vettore vCrv.emplace_back( Release( pCrvLoopExt)) ; @@ -1565,12 +1677,15 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv for ( int l = 1 ; l < vSfrByQuotes[s]->GetLoopCount( c) ; ++ l) vCrv.emplace_back( vSfrByQuotes[s]->GetLoop( c, l)) ; // creo la TriMesh per l'intersezione con il finito - PtrOwner pStmTmp( GetSurfTriMeshByRegionExtrusion( vCrv, 3000 * m_vtNormal)) ; + PtrOwner pStmTmp( GetSurfTriMeshByRegionExtrusion( vCrv, 3000 * vtN)) ; + for ( int m = 0 ; m < int( vCrv.size()) ; ++ m) + delete( vCrv[m]) ; if ( IsNull( pStmTmp) || ! pStmTmp->IsValid()) return false ; // aggiungo questa regione a quella passata come parametro alla funzione if ( ! pStm->Add( *pStmTmp)) return false ; + } } @@ -1579,7 +1694,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv //---------------------------------------------------------------------------- bool -Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) +Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop, const Vector3d& vtN) { // controllo del parametro if ( pCrvLoop == nullptr || ! pCrvLoop->IsValid()) @@ -1591,15 +1706,16 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) int nTmpProp1 = pCrvLoop->GetTempProp( 1) ; // ricavo i tratti omogenei ( campio il punto iniziale della curva nel punto medio del chiuso più lungo se presente) - ICURVEPOVECTOR vCrvOpen, vCrvClose ; - if ( ! GetHomogeneousParts( pCrvLoop, vCrvOpen, vCrvClose, true)) + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! GetHomogeneousParts( pCrvLoop, vpCrvs)) return false ; - // se curva tutta chiusa -> non devo estendere - if ( int( vCrvOpen.size()) == 0) - return true ; - // se curva tutta aperta -> Offset ed esco - else if ( int( vCrvClose.size()) == 0) { + // se curva tutta omogonea + if ( int( vpCrvs.size()) == 1 ) { + // se tutta chiusa, non devo estendere nulla + if ( vpCrvs[0]->GetTempProp() == 0) + return true ; + // se tutta aperta -> Offset OffsetCurve OffsCrv ; if ( ! OffsCrv.Make( pCrvLoop, 3000, ICurve::OFF_EXTEND)) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; @@ -1611,26 +1727,32 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) // porto tutto nel piano XY ( per le intersezioni in futuro) Point3d ptOrig ; pCrvLoop->GetCentroid( ptOrig) ; - Frame3d frZ ; frZ.Set( ptOrig, m_vtNormal) ; + Frame3d frZ ; frZ.Set( ptOrig, vtN) ; if ( ! frZ.IsValid()) return false ; - pCrvLoop->ToLoc( frZ) ; - for ( int i = 0 ; i < int( vCrvOpen.size()) ; ++ i) - vCrvOpen[i]->ToLoc( frZ) ; - for ( int i = 0 ; i < int( vCrvClose.size()) ; ++ i) - vCrvClose[i]->ToLoc( frZ) ; + for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) + vpCrvs[i]->ToLoc( frZ) ; - // scorro i tratti chusi ( se presenti sono almeno due) - for ( int cl = 0 ; cl < int( vCrvClose.size()) - 1 ; ++ cl) { + // pulisco la curva + pCrvLoop->Clear() ; + + // scorro i tratti + for ( int i = 0 ; i < int( vpCrvs.size()); ++ i) { + // determino se il tratto è chiuso o aperto + int nCurrTmpProp = vpCrvs[i]->GetTempProp() ; + if ( nCurrTmpProp == 0) { + pCrvLoop->AddCurve( vpCrvs[i]->Clone()) ; + continue ; + } // linea di estensione sulla parte finale - Point3d ptSL1 ; vCrvClose[cl]->GetEndPoint( ptSL1) ; - Vector3d vtSL1 ; vCrvClose[cl]->GetEndDir( vtSL1) ; + Point3d ptSL1 ; vpCrvs[i-1]->GetEndPoint( ptSL1) ; + Vector3d vtSL1 ; vpCrvs[i-1]->GetEndDir( vtSL1) ; PtrOwner pLineS( CreateCurveLine()) ; if ( IsNull( pLineS) || ! pLineS->SetPVL( ptSL1, vtSL1, 30000)) return false ; // linea di estensione sulla parte finale - Point3d ptSL2 ; vCrvClose[cl+1]->GetStartPoint( ptSL2) ; - Vector3d vtSL2 ; vCrvClose[cl+1]->GetStartDir( vtSL2) ; vtSL2.Invert() ; + Point3d ptSL2 ; vpCrvs[i+1]->GetStartPoint( ptSL2) ; + Vector3d vtSL2 ; vpCrvs[i+1]->GetStartDir( vtSL2) ; vtSL2.Invert() ; PtrOwner pLineE( CreateCurveLine()) ; if ( IsNull( pLineE) || ! pLineE->SetPVL( ptSL2, vtSL2, 30000)) return false ; @@ -1642,30 +1764,16 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) if ( ! IntCC.GetIntCrvCrvInfo( 0, aInfo)) return false ; Point3d ptInters( aInfo.IciA[0].ptI) ; - // modifico la curva inzile, raccordandola linearmente al punto di intersezione - double dUS, dUE ; - pCrvLoop->GetParamAtPoint( ptSL1, dUS) ; - pCrvLoop->GetParamAtPoint( ptSL2, dUE) ; - // tratto precedente - PtrOwner pCrvPrec( CloneCurveComposite( pCrvLoop)) ; - if ( IsNull( pCrvPrec) || ! pCrvPrec->TrimEndAtParam( dUS)) - return false ; - // tratto successivo - PtrOwner pCrvSucc( CloneCurveComposite( pCrvLoop)) ; - if ( IsNull( pCrvSucc) || ! pCrvSucc->TrimStartAtParam( dUE)) - return false ; - pCrvLoop->Clear() ; - if ( ! pCrvLoop->AddCurve( Release( pCrvPrec)) || - ! pCrvLoop->AddLine( ptInters) || - ! pCrvLoop->AddLine( ptSL2) || - ! pCrvLoop->AddCurve( Release( pCrvSucc))) + // aggiungo il tratto nuovo + if ( ! pCrvLoop->AddLine( ptInters) || + ! pCrvLoop->AddLine( ptSL2)) return false ; } // se invece non ci sono intersezioni tra le linee else if ( IntCC.GetIntersCount() == 0) { // estendo il tratto aperto con un Offset OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( vCrvOpen[cl], 300, ICurve::OFF_EXTEND)) { + if ( ! OffsCrv.Make( vpCrvs[i], 300, ICurve::OFF_EXTEND)) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; } @@ -1676,7 +1784,7 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) if ( ! pCrvOffs->ExtendStartByLen( 30000) || ! pCrvOffs->ExtendEndByLen( 30000)) return false ; - // intersecon questa curva con le rette + // interseco con questa curva con le rette IntersCurveCurve IntCC_S( *pLineS, *pCrvOffs) ; IntersCurveCurve IntCC_E( *pLineE, *pCrvOffs) ; Point3d ptInters_S, ptInters_E ; @@ -1702,27 +1810,10 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) pCrvOffs->GetParamAtPoint( ptInters_E, dUE) ; if ( ! pCrvOffs->TrimStartEndAtParam( dUS, dUE)) return false ; - // modifico la curva inzile, raccordandola linearmente al trim dell'Offset - pCrvLoop->GetParamAtPoint( ptSL1, dUS) ; - pCrvLoop->GetParamAtPoint( ptSL2, dUE) ; - // tratto precedente - PtrOwner pCrvPrec( CloneCurveComposite( pCrvLoop)) ; - if ( IsNull( pCrvPrec) || ! pCrvPrec->TrimEndAtParam( dUS)) - return false ; - // tratto successivo - PtrOwner pCrvSucc( CloneCurveComposite( pCrvLoop)) ; - if ( IsNull( pCrvSucc) || ! pCrvSucc->TrimStartAtParam( dUE)) - return false ; - pCrvLoop->Clear() ; - if ( ! pCrvLoop->AddCurve( Release( pCrvPrec))) - return false ; - if ( ! pCrvLoop->AddLine( ptInters_S)) - return false ; - if ( ! pCrvLoop->AddCurve( Release( pCrvOffs))) - return false ; - if ( ! pCrvLoop->AddLine( ptSL2)) - return false ; - if ( ! pCrvLoop->AddCurve( Release( pCrvSucc))) + // aggiungo il tratto nuovo + if ( ! pCrvLoop->AddLine( ptInters_S) || + ! pCrvLoop->AddCurve( Release( pCrvOffs)) || + ! pCrvLoop->AddLine( ptSL2)) return false ; } else // non definito @@ -1736,37 +1827,25 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) //---------------------------------------------------------------------------- bool -Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm) +Pocketing::GetCurrentPart( const Point3d& ptInside, ISurfTriMesh* pStmPart) { - // controllo parametro - if ( pStm == nullptr || ! pStm->IsValid()) - return false ; - - // controllo MachManager e database geometrico + // controllo MachManager e database geometrico if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; - // TriMesh del finito - PtrOwner pStmCurrRawPart( CreateSurfTriMesh()) ; - if ( IsNull( pStmCurrRawPart)) - return false ; - - // flag per RawPart trovata - bool bFound = false ; - // considero tutte le superfici dei pezzi nei grezzi attivi della fase int nRawId = m_pMchMgr->GetFirstRawPart() ; - while ( nRawId != GDB_ID_NULL && !bFound) { + while ( nRawId != GDB_ID_NULL) { if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) { // ciclo sui pezzi del grezzo int nPartId = m_pMchMgr->GetFirstPartInRawPart( nRawId) ; - while ( nPartId != GDB_ID_NULL && !bFound) { + while ( nPartId != GDB_ID_NULL) { // ciclo sui layer dei pezzi int nLayId = m_pGeomDB->GetFirstGroupInGroup( nPartId) ; - while ( nLayId != GDB_ID_NULL && !bFound) { + while ( nLayId != GDB_ID_NULL) { // ciclo sulle entità del layer int nEntId = m_pGeomDB->GetFirstInGroup( nLayId) ; - while ( nEntId != GDB_ID_NULL && !bFound) { + while ( nEntId != GDB_ID_NULL) { // se entità superficie e visibile, la aggiungo int nStat ; if ( m_pGeomDB->GetGeoType( nEntId) == SRF_TRIMESH) { @@ -1788,12 +1867,10 @@ Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm) // controllo se il punto è interno a tale Part double dElev = 0. ; DistPointSurfTm DistPtStm( ptInside, *pStmRawPart) ; - if ( DistPtStm.IsPointInside()) { - pStmCurrRawPart->CopyFrom( pStmRawPart) ; - if ( ! pStmCurrRawPart->IsValid()) - return false ; - bFound = true ; - break ; + double dDist ; DistPtStm.GetDist( dDist) ; + if ( DistPtStm.IsPointInside() || DistPtStm.IsSmall()) { + pStmPart->CopyFrom( pStmRawPart) ; + return pStmPart->IsValid() && pStmPart->GetTriangleCount() > 0 ; } } } @@ -1808,28 +1885,124 @@ Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm) nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; } - // parte non trovata - if ( ! bFound) - return false ; - - // interseco la TriMesh complessiva di pocketing con il finito, ottenendo il volume di svuotatura - m_pStmVolPocket.Set( Release( pStmCurrRawPart)) ; - if ( IsNull( m_pStmVolPocket) || ! m_pStmVolPocket->IsValid()) - return false ; - if ( ! m_pStmVolPocket->Intersect( *pStm)) // intersezione - return false ; - int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, m_pStmVolPocket->Clone()) ; - m_pGeomDB->SetMaterial( b, BLUE) ; - - return m_pStmVolPocket->IsValid() && m_pStmVolPocket->GetTriangleCount() > 0 ; + return false ; } //---------------------------------------------------------------------------- bool -Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) +Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm) { - // ========= GRUPPO TMP =================== - // recupero gruppo per geometria temporanea ( Gruppo TMP ) + // controllo parametro + if ( pStm == nullptr || ! pStm->IsValid()) + return false ; + + // recupero il Current Part + PtrOwner pStmCurrRawPart( CreateSurfTriMesh()) ; + if ( IsNull( pStmCurrRawPart) || + ! GetCurrentPart( ptInside, pStmCurrRawPart)) + return false ; + + // interseco la TriMesh complessiva di pocketing con il finito, ottenendo il volume di svuotatura + if ( ! pStmCurrRawPart->Intersect( *pStm)) // intersezione + return false ; + + // aggiorno la superficie + pStm->CopyFrom( pStmCurrRawPart) ; + return pStm->IsValid() && pStm->GetTriangleCount() > 0 ; +} + +//--------------------------------------------------------------------------- +bool +Pocketing::AdjustPocketingSideForVolumePart( ISurfTriMesh* pStmVolPart, const Vector3d& vtTool) +{ + // controllo dei parametri + if ( pStmVolPart == nullptr || ! pStmVolPart->IsValid()) + return false ; + + // NB. Il controllo delle normali delle entitità che sono state selezionate presenta una laggera tolleranza; + // Questa tolleranza potrebbe rendere la superficie da svuotare non completamente piana ( ma come sovrapposizione + // di superfici piane leggermente inclinate tra loro; + const double TOLL = 500 * EPS_SMALL ; + + // creo un frame centrato nel centroide della parte + Frame3d frElevation ; + Point3d ptC ; pStmVolPart->GetCentroid( ptC) ; + frElevation.Set( ptC, vtTool) ; + if ( ! frElevation.IsValid()) + return false ; + + // porto il la parte di volume in questo frame + pStmVolPart->ToLoc( frElevation) ; + + // ricavo quindi il Box + BBox3d BBox ; pStmVolPart->GetLocalBBox( BBox) ; + // il su cui iniziare a svuotare è quello che si trova a Z minima + double dZ_min = BBox.GetMin().z ; + + // riporto il volume nel suo frame Originario + pStmVolPart->ToGlob( frElevation) ; + + // porto il frame alla minima Z ( sarà negativa) di svuotatura + frElevation.Set( ptC + vtTool * dZ_min, vtTool) ; + if ( ! frElevation.IsValid()) + return false ; + + // porto il volume in questo frame + pStmVolPart->ToLoc( frElevation) ; + // NB. ora il nostro volume è appoggiato al piano Z = 0 centrato sopra all'Origine + + // devo controllare se ci sono delle facce contenute tra il piano Z = 0 e Z = TOLL + // 1) creo i due piani + Plane3d plZ0 ; + plZ0.Set( ORIG, -Z_AX) ; + if ( ! plZ0.IsValid()) + return false ; + + Plane3d plZTOLL ; + plZTOLL.Set( ORIG + Z_AX * TOLL, Z_AX) ; + if ( ! plZTOLL.IsValid()) + return false ; + + // 2) taglio una copia del volume tra i due piani + PtrOwner pStmVolPart_between( CloneSurfTriMesh( pStmVolPart)) ; + if ( IsNull( pStmVolPart_between) || ! pStmVolPart_between->IsValid()) + return false ; + if ( ! pStmVolPart_between->Cut( plZ0, false) || // tolgo la faccia a Z = 0 + ! pStmVolPart_between->Cut( plZTOLL, false)) + return false ; + + // 3) controllo tutte le facce che ho attenuto ; se ho ottenuto almeno una faccia con normale simile a Z_AX + // allora traslo il piano di svuotatura a Z = TOLL + bool bExistFaces = false ; + for ( int f = 0 ; f < pStmVolPart_between->GetFacetCount() && !bExistFaces ; ++ f) { + Point3d ptC ; Vector3d vtC ; + if ( ! pStmVolPart_between->GetFacetCenter( f, ptC, vtC)) + return false ; + bExistFaces = AreSameVectorEpsilon( vtC, - Z_AX, 5 * EPS_SMALL) ; + } + + // se non ho trovato nessuna faccia, allora il volume andava già bene + if ( ! bExistFaces) { + pStmVolPart->ToGlob( frElevation) ; // riportato in posizione originale + return true ; + } + + // dato che ho trovato almeno una faccia, il mio nuovo volume si restringe leggermente su Z = TOLL + plZTOLL.Invert() ; + if ( ! pStmVolPart->Cut( plZTOLL, false) || + ! SewingMissingFacesOnPlanes( pStmVolPart, plZTOLL)) + return false ; + + pStmVolPart->ToGlob( frElevation) ; // riportato in posizione originale + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) +{ + + // recupero gruppo per geometria temporanea ( Gruppo Temp) const string GRP_TEMP = "Temp" ; int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; // se non c'è, lo aggiungo @@ -1845,194 +2018,55 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) // in ogni caso lo dichiaro temporaneo e non visibile m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; - // ======================================= - // recupero eventuale flag di lato aperto forzato fuori dal grezzo - int nOpenOutRaw ; - m_bOpenOutRaw = ( FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ; - - // creo una superificie temporanea generata da tutte le curve ( curve modificate se valide ) - SurfFlatRegionByContours SrfByC ; // superificie totale generata da tutte le curve concatenate - Plane3d plAux ; bool bFirstPlane = true ; // piano Ausiliario per verificare che le curve siano complanari - Vector3d vtExtr ; - double dThick = -INFINITO ; // spessore più grande tra le curve - int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; - - // indici da associare alla SurfFlatRegion da svuotare : - // Ogni curva che definirà un loop nella flat Region avrà la seguente struttura : - // { nProp0, nProp1 } = { Id elemento selezionato, Id faccia adiacente (solo per Trimesh) } - // Per ogni curva di questi loop ( CurveCompo) avrò : - // { nProp0, nProp1 } = { (0 -> chiuso, 1 -> aperto) , id faccia adiacente ( solo per Trimesh)} - - int nProp0 = -1 ; - int nProp1 = -1 ; - - while ( nPathId != GDB_ID_NULL) { // Scorro tutte le curve concatenate per creare la superficie da lavorare - - int nPi = m_pGeomDB->GetFirstInGroup( nPathId) ; - if ( m_pGeomDB->GetGeoType( nPi) != CRV_COMPO) - return false ; - const ICurve* pOriCurve = ::GetCurve( m_pGeomDB->GetGeoObj( nPi)) ; - if ( pOriCurve == nullptr) - return false ; - PtrOwner pCompoOriCrv( GetCurveComposite( pOriCurve->Clone())) ; - if ( IsNull( pCompoOriCrv)) - return false ; - - // ricavo le proprietà della curva - nProp0 = pCompoOriCrv->GetTempProp( 0) ; // Id selezionato - nProp1 = pCompoOriCrv->GetTempProp( 1) ; // lato adiancente per Trimesh - - // annullo i flag di tratto aperto - for ( int i = 0 ; i < int( pCompoOriCrv->GetCurveCount()) ; ++i) - pCompoOriCrv->SetCurveTempProp( i, 0, 0) ; // alla sottocurva - - bool bSomeOpen ; // = m_pGeomDB->ExistsInfo( nPi, KEY_OPEN) ; - SetCurveAllTempProp( nPi, GetForcedClosed(), pCompoOriCrv, &bSomeOpen) ; - // unisco le parti allineate (tranne inizio-fine se chiusa) - if ( ! pCompoOriCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false, true)) - return false ; - - // recupero estrusione e spessore - Vector3d vtExtr_p = Z_AX ; - pCompoOriCrv->GetExtrusion( vtExtr_p) ; - double dThick_p ; - pCompoOriCrv->GetThickness( dThick_p) ; - - // verifico sia piana e se necessario la appiattisco - PtrOwner pFlatCrv( FlattenCurve( *pCompoOriCrv, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ; - if ( IsNull( pFlatCrv)) { - Plane3d plPlane ; - if ( ! pCompoOriCrv->IsFlat( plPlane, true, 50 * EPS_SMALL)) - m_pMchMgr->SetLastError( 2403, "Error in Pocketing : Contour Not Flat") ; - else - m_pMchMgr->SetLastError( 2404, "Error in Pocketing : Tool Not Perpendicular to Flat Area") ; - return false; - } - pFlatCrv->GetExtrusion( vtExtr_p) ; - pCompoOriCrv->Clear() ; - pCompoOriCrv->AddCurve( Release( pFlatCrv)) ; - pCompoOriCrv->SetExtrusion( vtExtr_p) ; - pCompoOriCrv->SetThickness( dThick_p) ; - - // setto come proprietà temperanea il suo Id - pCompoOriCrv->SetTempProp( nProp0, 0) ; // a tutta la curva ( id selezionato) - pCompoOriCrv->SetTempProp( nProp1, 1) ; // a tutta la curva ( se Trimesh, faccia adiacente) - - // controllo che le curve siano complanari e con stessa estrusione ( la prima come riferimento) - Plane3d plAct ; - pCompoOriCrv->IsFlat( plAct) ; - if ( bFirstPlane) { - plAux = plAct ; - bFirstPlane = false ; - pCompoOriCrv->GetThickness( dThick_p) ; - dThick = dThick_p ; // prima come riferimento - vtExtr = vtExtr_p ; // prima come riferimento - SrfByC.AddCurve( pCompoOriCrv->Clone()) ; - } - else { - Vector3d vtN1, vtN2 ; - if ( abs( plAct.GetDist() - plAux.GetDist()) < 5 * EPS_SMALL - && AreSameOrOppositeVectorApprox( plAct.GetVersN(), plAux.GetVersN()) // se stessa normale - && AreSameVectorApprox( vtExtr, vtExtr_p)) { // se stessa estrusione - PtrOwner pCrvProjected( ProjectCurveOnPlane( *pCompoOriCrv, plAux)) ; - pCrvProjected->SetExtrusion( vtExtr) ; - // prendo Thickness Massima tra tutte le curve dei chunks - double dCurrThick ; - pCompoOriCrv->GetThickness( dCurrThick) ; - if ( dCurrThick > dThick) - dThick = dCurrThick ; - pCrvProjected->SetThickness( dCurrThick) ; - SrfByC.AddCurve( pCrvProjected->Clone()) ; - } - } - - nPathId = m_pGeomDB->GetNextGroup( nPathId) ; // aggiorno il PathId con il successivo nel gruppo - } - - // creazione della superficie da lavorare completa ( dall'unione di tutte le curve concatenate) - PtrOwner pSrfPock( SrfByC.GetSurf()) ; - if ( IsNull( pSrfPock) || pSrfPock->GetChunkCount() == 0) + // recupero l'entità ( Part del volume di svuotatura) + double dDepth = 0. ; + Vector3d vtTool ; m_pGeomDB->GetInfo( nPathId, KEY_TOOL, vtTool) ; + PtrOwner pStm_PartVolume( CreateSurfTriMesh()) ; + if ( IsNull( pStm_PartVolume)) + return false ; + int nId = m_pGeomDB->GetFirstInGroup( nPathId) ; + if ( m_pGeomDB->GetGeoType( nId) != SRF_TRIMESH) + return false ; + pStm_PartVolume.Set( CloneSurfTriMesh( m_pGeomDB->GetGeoObj( nId))) ; + if ( IsNull( pStm_PartVolume) || ! pStm_PartVolume->IsValid()) return false ; - // normale della superifice finale || extrusione prima curva selezionata - if ( AreOppositeVectorApprox( vtExtr, pSrfPock->GetNormVersor())) - pSrfPock->Invert() ; + // recupero nome del path + string sPathName ; + m_pGeomDB->GetName( nPathId, sPathName) ; - if ( m_Params.m_bToolInvert) { - // eventuale inversione direzione utensile - vtExtr.Invert() ; - pSrfPock->Invert() ; - dThick = - dThick ; - } - - // controllo se la superificie contiene lati aperti interni al grezzo - #if 0 - // 1) recupero la Trimesh del grezzo - PtrOwner pStmRaw( CreateSurfTriMesh()) ; - if ( IsNull( pStmRaw)) - return false ; - pStmRaw->DoCompacting() ; - if ( ! GetStmRawPart( nProp0, pStmRaw)) - return false ; - // 2) Imposto TmpProp1 = -2 a tutti i lati aperti ( TmpProp0 = 1 ) interno al grezzo - if ( ! DetectOpenEdgeInsideRaw ( pSrfPock, pStmRaw)) - return false ; - #endif - - // recupero il box del grezzo in globale + // recupero il Box del grezzo globale BBox3d b3Raw ; - BBox3d b3Chunk ; pSrfPock->GetBBox( GLOB_FRM, b3Chunk) ; - if ( ! GetRawGlobBox( m_nPhase, b3Chunk, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { + if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { m_pMchMgr->SetLastError( 2405, "Error in Pocketing : Empty RawBox") ; return false ; } - // recupero distanza da fondo dei grezzi interessati dal percorso - double dRbDist = 0 ; double dAllRbDist = 0 ; - if ( AreSameVectorApprox( vtExtr, Z_AX)) { - if ( ! GetDistanceFromRawBottom( m_nPhase, b3Chunk, m_TParams.m_dTDiam, dRbDist, dAllRbDist)) - return false ; - } - - // valuto l'espressione dell'affondamento - ExeLuaSetGlobNumVar( "TH", abs( dThick)) ; - ExeLuaSetGlobNumVar( "RB", dRbDist) ; - double dDepth ; - string sMyDepth = m_Params.m_sDepth ; - if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) { - m_pMchMgr->SetLastError( 2406, "Error in Pocketing : Depth not computable") ; + // recupero la Part in cui è contenuto il volume + Point3d ptC ; pStm_PartVolume->GetCentroid( ptC) ; + PtrOwner pStm_Part( CreateSurfTriMesh()) ; + if ( IsNull( pStm_Part) || + ! GetCurrentPart( ptC, pStm_Part)) return false ; - } - // se spessore positivo, lo sottraggo dal risultato - if ( dThick > 0) - dDepth -= dThick ; - // sottraggo eventuale offset longitudinale - dDepth -= GetOffsL() ; - // assegno il versore fresa - Vector3d vtTool = vtExtr ; - - m_bAggrBottom = false ; - - // calcolo l'elevazione massima - double dElev = -INFINITO ; - for ( int c = 0; c < pSrfPock->GetChunkCount() ; c++) { - double dCurrElev ; - PtrOwner pCvrCompo( GetCurveComposite( pSrfPock->GetLoop( c,0))) ; - if ( CalcRegionElevation( pCvrCompo, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dCurrElev)) { - if ( dCurrElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { - BBox3d b3Crv ; - pSrfPock->GetLoop( c, 0)->GetLocalBBox( b3Crv) ; - dCurrElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min(0., dThick) + dDepth) ; - } - if ( dCurrElev > dElev) - dElev = dCurrElev ; - } - else - return false ; - } + // rendo il volume accettabile per la svuotatura... + if ( ! AdjustPocketingSideForVolumePart( pStm_PartVolume, vtTool)) + return false ; + // devo calcolare l'Elevazione... + Frame3d frElevation ; + frElevation.Set( ptC, vtTool) ; + if ( ! frElevation.IsValid()) + return false ; + pStm_PartVolume->ToLoc( frElevation) ; + // ricavo quindi il Box + BBox3d BBox ; pStm_PartVolume->GetLocalBBox( BBox) ; + // il su cui iniziare a svuotare è quello che si trova a Z minima + double dZ_min = BBox.GetMin().z ; + pStm_PartVolume->ToGlob( frElevation) ; + // calcolo l'elevazione massima ( è la lunghezza Z del Box con asse Z uguale a vtTool) + double dElev = BBox.GetDimZ() ; // eventuale imposizione massima elevazione da note utente double dMaxElev ; if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) @@ -2049,26 +2083,26 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) // verifico che il massimo materiale dell'utensile sia sensato const double MIN_MAXMAT = 1.0 ; - if ( m_TParams.m_dMaxMat < dElev && m_TParams.m_dMaxMat < MIN_MAXMAT) { - string sInfo = "Error in Pocketing : Tool MaxMaterial too small (" + ToString(m_TParams.m_dMaxMat, 2) + ")" ; + if ( m_TParams.m_dMaxMat < dElev && m_TParams.m_dMaxMat < MIN_MAXMAT) { + string sInfo = "Error in Pocketing : Tool MaxMaterial too small (" + ToString( m_TParams.m_dMaxMat, 2) + ")" ; m_pMchMgr->SetLastError( 2422, sInfo) ; return false ; } - // verifico di non superare il massimo materiale - // se lo step supera la capacità dell'utensile + // verifico di non superare il massimo materiale se lo step supera la capacità dell'utensile if ( m_Params.m_dStep > m_TParams.m_dMaxMat + EPS_SMALL) { dOkStep = m_TParams.m_dMaxMat + EPS_SMALL ; - string sInfo = "Warning in Pocketing : machining step (" + ToString( m_Params.m_dStep, 1) + ") bigger than MaxMaterial (" - + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + string sInfo = "Warning in Pocketing : machining step (" + ToString( m_Params.m_dStep, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; m_pMchMgr->SetWarning( 2457, sInfo) ; } - // se lavorazione singola + + // se lavorazione singola if ( dOkStep < EPS_SMALL || dOkStep > dElev) { - // se l'elevazione supera la capacità dell'utensile - if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL ) { - string sInfo = "Warning in Pocketing : machining depth (" + ToString(dElev, 1) + - ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + // se l'elevazione supera la capacità dell'utensile + if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL) { + string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; m_pMchMgr->SetWarning( 2458, sInfo) ; dDepth -= dElev - m_TParams.m_dMaxMat ; dElev = m_TParams.m_dMaxMat ; @@ -2082,7 +2116,7 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) if ( dElev > dMaxDepth + EPS_SMALL) { // segnalo, riduco e continuo string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) + - ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; + ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; m_pMchMgr->SetWarning( 2458, sInfo) ; dDepth -= dElev - dMaxDepth ; dElev = dMaxDepth ; @@ -2091,18 +2125,20 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) // verifico se tavola basculante bool bTiltTab = false ; - m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab, m_vtTiltingAx) && bTiltTab) ; + m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab, m_vtTiltingAx) && bTiltTab) ; // verifico se testa da sopra (Z+) m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ; // verifiche per svuotature dal basso - m_bAggrBottom = false ; - if ( ! VerifyPathFromBottom( pSrfPock, vtTool)) - return false ; + m_bAggrBottom = false ; + //if ( ! VerifyPathFromBottom( pCompo, vtTool)) { + // return false ; + //} - // recupero nome del path - string sPathName = "P1" ; + // recupero eventuale flag di lato aperto forzato fuori dal grezzo + int nOpenOutRaw ; + m_bOpenOutRaw = ( FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ; // recupero eventuale minima lunghezza di attacco su lato aperto FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenMinSafe="), m_dOpenMinSafe) ; @@ -2116,8 +2152,8 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) m_pGeomDB->SetName( nPxId, sPathName) ; m_pGeomDB->SetMaterial( nPxId, GREEN) ; // creo l'anteprima del percorso - if ( ! GeneratePocketingPv( nPxId, pSrfPock)) - return false ; + //if ( ! GeneratePocketingPv( nPxId, pCompo)) + // return false ; } // se richiesta lavorazione @@ -2131,9 +2167,9 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) // verifico se archi vanno approssimati con segmenti di retta int nSplitArcs = m_pMchMgr->GetCurrMachiningsMgr()->GetSplitArcs() ; - bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS || - ( nSplitArcs == SPLAR_NO_XY_PLANE && !vtExtr.IsZplus()) || - ( nSplitArcs == SPLAR_GEN_PLANE && vtExtr.IsGeneric())) ; + bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS || + ( nSplitArcs == SPLAR_NO_XY_PLANE && ! vtTool.IsZplus()) || + ( nSplitArcs == SPLAR_GEN_PLANE && vtTool.IsGeneric())) ; // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; @@ -2144,33 +2180,775 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId) SetPathId( nPxId) ; SetToolDir( vtTool) ; - // Eseguo la lavorazione della superificie finale + // determino numero e affondamento degli step + int nStep = 1 ; + nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; + double dStep = dElev / nStep ; + + // porto il frame alla minima Z ( sarà negativa) di svuotatura + frElevation.Set( ptC + vtTool * dZ_min, vtTool) ; + if ( ! frElevation.IsValid()) + return false ; + + // porto il volume e la Part che lo contiene in questo frame + pStm_PartVolume->ToLoc( frElevation) ; + pStm_Part->ToLoc( frElevation) ; + + // creo i parametri utili per la svuotatura + ISURFFRPOVECTOR vSrfSliced ; // vettore delle superficie ricavate ( per ogni step) + vector vCrvOEWithFlags; // vettore delle relative curve originali ( per ogni step) + BOOLVECTOR vbChangedPrec( nStep, false) ; // vettore di Flag per superfici uguali tra steps consecutivi + VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; // vettore contenente le quote per le passate di svuotature + + // ricavo le superfici di svuotatura + if ( ! SliceVolume( pStm_PartVolume, pStm_Part, vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, nStep, vtTool, dElev, dDepth, dStep)) + return false ; + + // riporto il volume nel frame globale + pStm_PartVolume->ToGlob( frElevation) ; + + // riporto le superfici nel frame globale + for ( int s = 0 ; s < int( vSrfSliced.size()) ; ++ s) + vSrfSliced[s]->ToGlob( frElevation) ; + + for ( int s = 0 ; s < int( vSrfSliced.size()) ; ++ s) { + PtrOwner pSrf_toDraw( CloneSurfFlatRegion( vSrfSliced[s])) ; + //int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ; + //m_pGeomDB->SetMaterial( a, Color( 0.0, 0.0, 1.0, 0.45)) ; + for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) { + for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) { + PtrOwner 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) ; + } + } + } + } + + //return false ; + + // riporto le curve per i casi ottimizzati nel frame globale + for ( int u = 0 ; u < int( vCrvOEWithFlags.size()) ; ++ u) + for ( int uu = 0 ; uu < int( vCrvOEWithFlags[u].size()) ; ++ uu) + vCrvOEWithFlags[u][uu]->ToGlob( frElevation) ; + + // riporto i vettori di traslazione nel frame globale + for ( int v = 0 ; v < int( vVtTrasl.size()) ; ++ v) + vVtTrasl[v].ToGlob( frElevation) ; + + // Eseguo la lavorazione a seconda del tipo switch ( m_Params.m_nSubType) { - case POCKET_SUB_ZIGZAG: - if ( ! AddZigZag( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs)) + case POCKET_SUB_ZIGZAG : + if ( ! AddZigZag( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev, + dMaxElev, dOkStep, bSplitArcs)) return false ; break ; - case POCKET_SUB_ONEWAY: - if ( ! AddOneWay( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs)) - return false ; - break ; - case POCKET_SUB_SPIRALIN: - if ( ! AddSpiralIn( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs)) - return false ; - break ; - case POCKET_SUB_SPIRALOUT: - if ( ! AddSpiralOut( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs)) - return false ; + case POCKET_SUB_ONEWAY : + if ( ! AddOneWay( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev, + dMaxElev, dOkStep, bSplitArcs)) + return false ; + break ; + case POCKET_SUB_SPIRALIN : + if ( ! AddSpiralIn( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev, + dMaxElev, dOkStep, bSplitArcs)) + return false ; + break ; + case POCKET_SUB_SPIRALOUT : + if ( ! AddSpiralOut( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev, + dMaxElev, dOkStep, bSplitArcs)) + return false ; break ; } } - m_nPockets++ ; + // incremento numero di svuotature + ++ m_nPockets ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::GetProjectionOfStmToNotPocket( const ISurfTriMesh* pStmPart, const ISurfTriMesh* pStmVol, ISurfFlatRegion* pSfrProj) +{ + // controllo i parametri + if ( pStmPart == nullptr || ! pStmPart->IsValid() || + pStmVol == nullptr || ! pStmVol->IsValid()) + return false ; + + // ricavo la parte di grezzo da non rovinare + PtrOwner pStmToNotRuin( CloneSurfTriMesh( pStmPart)) ; + if ( IsNull( pStmToNotRuin) || + ! pStmToNotRuin->IsValid() || + ! pStmToNotRuin->Subtract( *pStmVol) || + ! pStmToNotRuin->IsValid()) + return false ; + + // NB. La parte vera a propria di interesse è quella sopra la piano Z = 0 + // creo il piano Z = 0 + Plane3d plZ0 ; + plZ0.Set( ORIG, - Z_AX) ; + if ( ! plZ0.IsValid()) + return false ; + + // taglio la supericie + if ( ! pStmToNotRuin->Cut( plZ0, true)) + return false ; + + // se non ho ottenuto nulla, esco + if ( ! pStmToNotRuin->IsValid() || pStmToNotRuin->GetTriangleCount() == 0) + return true ; + + // Proietto la TriMesh + plZ0.Invert() ; + PtrOwner pSfrLimitH( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrLimitH) || + ! ProjectStmOnPlane( pStmToNotRuin, plZ0, pSfrLimitH)) + return false ; + + // controllo per estrema sicurezza la coerenza con le normali + if ( AreOppositeVectorApprox( pSfrLimitH->GetNormVersor(), Z_AX)) + pSfrLimitH->Invert() ; + + // ritorno la superficie + pSfrProj->CopyFrom( pSfrLimitH) ; + return pSfrProj->IsValid() && pSfrProj->GetChunkCount() > 0 ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, ISURFFRPOVECTOR& vSrfSliced, + std::vector& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool, + const double dElev, const double dDepth, const double dStep) +{ + // controllo dei parametri + if ( pStmVol == nullptr || ! pStmVol->IsValid() || + pStm_Part == nullptr || ! pStm_Part->IsValid()) + return false ; + + // NB. Ogni volta che esco dal volume di svuotura rischio con il Tool di rovinare delle parti al di fuori del volume + // di svuotatura... + // -> quando proeitto la parte di volume compresa tra lo step attuale e lo step precedente ( ProjectVolume) + // -> quando mi estendo presso i lati aperti ( ModifySurfByOpenEdges) + // Devo limitare la mia regione si svuotatura estesa mediante la proeizione della parte di grezzo che non voglio + // svuotare + PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; + if ( ! GetProjectionOfStmToNotPocket( pStm_Part, pStmVol, pSfrLimit)) + return false ; + + vVtTrasl.clear() ; + // creazione di un vettore con gli step ( caso base) + for ( int j = 1 ; j <= nStep ; ++ j) + vVtTrasl.push_back( -Z_AX * ( dDepth - dElev + j * dStep)) ; + + // calcolo di eventuali Step Extra + // W.I.P + + // aggirno le dimensioni dei vettori da restituire in base agli step calcolati + vCrvOEWithFlags.clear() ; + vCrvOEWithFlags.resize( int( vVtTrasl.size())) ; + vbChangedPrec.clear() ; + vbChangedPrec.resize( int( vVtTrasl.size())) ; + + // per ogni step ricavato... + for ( int j = 1 ; j <= int( vVtTrasl.size()) ; ++ j) { + // porto la regione limite allo step attuale + if ( pSfrLimit->IsValid()) + pSfrLimit->Translate( vVtTrasl[j-1]) ; + // taglio il volume con il piano di svuotatura attuale + PtrOwner pSfrCurr( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrCurr) || + ! CutVolumeByPlane( pStmVol, pStm_Part, vVtTrasl[j-1], pSfrCurr)) + return false ; + // tolgo/aggiungo eventuali proiezioni + if ( ! ProjectVolume( pStmVol, pStm_Part, vVtTrasl[j-1], j == 1 ? V_INVALID : vVtTrasl[j-2], pSfrLimit, pSfrCurr)) + return false ; + // ricavo le proprietà di lato aperto/chiuso + if ( ! ChooseCloseOrOpenEdge( pSfrCurr, pStm_Part)) + return false ; + // salvo le curve originali per casi ottimizzati + if ( ! GetCurvesForOptimizedPocketing( pSfrCurr, vCrvOEWithFlags[j-1])) + return false ; + // modifico la supericie in base alle proprietà di lato aperto/chiuso + if ( ! ModifySurfByOpenEdges( pSfrCurr, pSfrLimit)) + return false ; + // inserisco la superficie nel vettore + vSrfSliced.emplace_back( Release( pSfrCurr)) ; + + // controllo se la superficie è uguale a quella inserita nello step precedente + // ... W.I.P ... + vbChangedPrec[j-1] = true ; + // ... + + // controllo se la superficie deriva da una lavorazione precedente + // ... W.I.P + // ... + // ... + + // porto la regione limite nel piano Z = 0 + if ( pSfrLimit->IsValid()) + pSfrLimit->Translate( -vVtTrasl[j-1]) ; + + + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlane) +{ + // controllo dei parametri + if ( pStm == nullptr || ! pStm->IsValid() || + ! plPlane.IsValid()) + return false ; + + // recupero tutti i Loop ( se presenti) + POLYLINEVECTOR vPL ; + pStm->GetLoops( vPL) ; + for ( int p = 0 ; p < ( int)vPL.size() ; ++ p) { + // controllo la PolyLine è contenuta nel piano dove svuoto, altrimenti non la considero + Plane3d plCheck ; double dArea ; Point3d ptCheck ; + if ( vPL[p].IsClosedAndFlat( plCheck, dArea)) { + if ( vPL[p].GetPointNbr() > 0) { + if ( vPL[p].GetFirstPoint( ptCheck)) { + double dDist = DistPointPlane( ptCheck, plPlane) ; + if ( abs( dDist) > 50 * EPS_SMALL) + continue ; + } + } + } + // recupero la curva + PtrOwner pCrvLoop( CreateCurveComposite()) ; + if ( IsNull( pCrvLoop) || + ! pCrvLoop->FromPolyLine( vPL[p]) || + ! pCrvLoop->IsValid()) + return false ; + // creo la TriMesh della faccia mancante + PtrOwner pStmMissingFace( GetSurfTriMeshByFlatContour( pCrvLoop)) ; + if ( IsNull( pStmMissingFace) || ! pStmMissingFace->IsValid()) + return false ; + // controllo che sia orintata correttamente ( il volume deve essere interno) + Vector3d vtN_f ; pStmMissingFace->GetFacetNormal( 0, vtN_f) ; + if ( AreOppositeVectorApprox( plPlane.GetVersN(), vtN_f)) + pStmMissingFace->Invert() ; + // unisco + if ( ! pStm->DoSewing( *pStmMissingFace)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, + ISurfFlatRegion* pSfrResult) +{ + // controllo dei parametri + if ( pStmVol == nullptr || ! pStmVol->IsValid() || + pStm_Part == nullptr || ! pStm_Part->IsValid()) + return false ; + pSfrResult->Clear() ; + + // creo un piano allo step attuale + Point3d ptCenter = ORIG + vtTrasl ; + Vector3d vtN = vtTrasl.IsSmall() ? Z_AX : vtTrasl ; vtN.Normalize() ; + Plane3d plCut ; plCut.Set( ptCenter, -vtN) ; + if ( ! plCut.IsValid()) + return false ; + + // taglio il volume con il piano attuale + PtrOwner pStmSlice( CloneSurfTriMesh( pStmVol)) ; + if ( IsNull( pStmSlice) || + ! pStmSlice->IsValid() || + ! pStmSlice->Cut( plCut, false)) // non salvo quelli sullo stesso livello del piano ! + return false ; + + // se non ho ricavato nulla, esco + if ( ! pStmSlice->IsValid() || pStmSlice->GetTriangleCount() == 0) + return true ; + + // aggiungo le facce mancanti dovute al taglio + if ( ! SewingMissingFacesOnPlanes( pStmSlice, plCut)) + return false ; + + // FlatRegion con lati flag di lato Aperto/Chiuso + SurfFlatRegionByContours SfrBC_final ; + + // scorro tutte le facce della TriMesh ricavata + for ( int f = 0 ; f < pStmSlice->GetFacetCount() ; ++ f) { + // le facce che formeranno la FlatRegion di svuotatura sono quelle alla quota definita da vtTrasl + Point3d ptCentroid ; Vector3d vtNormal ; + if ( ! pStmSlice->GetFacetCenter( f, ptCentroid, vtNormal) || + abs( ptCentroid.z - ptCenter.z) > 300 * EPS_SMALL || // se faccia non sul piano di taglio... + ! AreOppositeVectorApprox( Z_AX, vtNormal)) // ... o con diversa normale.... + continue ; // ... controllo la successiva + + // recupero i contorni della faccia + POLYLINEVECTOR vPL ; + pStmSlice->GetFacetLoops( f, vPL) ; + if ( vPL.empty()) + return false ; + + // scorro i loop trovati + for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { + // creo la curva a partire dalla PolyLine + PtrOwner pCrvCompo( CreateCurveComposite()) ; + pCrvCompo->FromPolyLine( vPL[i]) ; + if ( ! pCrvCompo->IsValid()) + return false ; + // reset proprietà temporanee + ResetCurveAllTempProp( pCrvCompo) ; + // la proietto sul piano per maggiore sicurezza + PtrOwner pCrvProj( ProjectCurveOnPlane( *pCrvCompo, plCut)) ; + if ( IsNull( pCrvProj)) + return false ; + if ( pCrvProj->IsValid()) + pCrvCompo.Set( ConvertCurveToComposite( Release( pCrvProj))) ; + // abbellisco + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + // aggiorno la curva alla FlatRegion finale + SfrBC_final.AddCurve( Release( pCrvCompo)) ; + } + } + + // recupero la FlatRegion da restituire ( per approssimazione potrei avere piccoli sfalsamenti lungo Z_AX) + PtrOwner pSfr_Final( SfrBC_final.GetSurf()) ; + while( ! IsNull( pSfr_Final) && pSfr_Final->IsValid()) { + // controllo che sia orientata come Z_AX + if ( AreOppositeVectorApprox( Z_AX, pSfr_Final->GetNormVersor())) + pSfr_Final->Invert() ; + // prendo la supercicie e aggiorno quella da restituire + if ( ! pSfrResult->IsValid()) + pSfrResult->CopyFrom( pSfr_Final) ; + else + if ( ! pSfrResult->Add( * pSfr_Final)) + return false ; + pSfr_Final.Set( SfrBC_final.GetSurf()) ; + } + + // restituisco + return ! ( pSfrResult == nullptr || ! pSfrResult->IsValid()) ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, + const Vector3d& vtTrasl1, ISurfFlatRegion* pSfrLimit, ISurfFlatRegion* pSfr) +{ + // controllo dei parametri + if ( pStmVol == nullptr || ! pStmVol->IsValid() || + pStm_Part == nullptr || ! pStm_Part->IsValid() || + pSfr == nullptr || ! pSfr->IsValid()) + return false ; + + // controllo se il tool ha un SideAngle + if ( m_TParams.m_dSideAng != 0) { + // ... controllo che gli angoli delle facce siano coerenti al tool selezionato + // ... + // ... + // ... + return true ; + } + + /* + Vengono creati due piano di Taglio : plNear e plFar + 1) plNear : piano di taglio allo step attuale con normale Z_AX + 2) plFar : piano di taglio riferito allo step successivo ( se lo step è il primo allora è impostato ad una quota alta) + + Ogni faccia del volume di svuotatura ( stm) è classificata come Aperta ( A) o Chiusa ( C) + A : questa faccia corrisponde ad una faccia della Part + C : questa faccia deriva dalla TriMesh selezionata ( o curve, vedi funzione GetCurvesAndPartialVolume()) + + * le facce C vanno proiettate sul piano di svuotatura attuale e sottratte alla *pSfr + -> si usa solo il plNear + + * le facce A sono quelle che verranno utilizzate per la proiezione della Part sul piano di svuotatura attuale + -> si usa sia il plNear che il plFar + * il volume di svuotatura viene tagliato dal plNear e plFar, ottenendo la parte compresa tra i due piani + * ( in questo modo la proiezione sul piano di svuotatura considera svuotato tutto ciò che è sopra + allo step precedente, quindi con quota Z maggiore di esso ) + * la proiezione consiste quindi nel proiettare le facce A di questa parte di Volume di Pocketing. + */ + + // plNear + Point3d ptNear = ORIG + vtTrasl ; + Vector3d vtN = Z_AX ; + Plane3d plNear ; plNear.Set( ptNear, -vtN) ; + if ( ! plNear.IsValid()) + return false ; + + // plFar + Point3d ptFar = ORIG + ( vtTrasl1.IsValid() ? vtTrasl1 : 5000 * Z_AX) ; + Plane3d plFar ; plFar.Set( ptFar, vtN) ; + if ( ! plFar.IsValid()) + return false ; + + // ricavo il volume di svuotatura sopra al piano plNear + PtrOwner pStmAbove_Near( CloneSurfTriMesh( pStmVol)) ; + if ( IsNull( pStmAbove_Near) || + ! pStmAbove_Near->IsValid() || + ! pStmAbove_Near->Cut( plNear, false)) // non salvo quelli sullo stesso livello del piano ! + return false ; + + // se non ho ricavato nulla, esco + if ( ! pStmAbove_Near->IsValid() || pStmAbove_Near->GetTriangleCount() == 0) + return true ; + + // ricavo il volume di svuotatura tra plNear e PlFar + PtrOwner pStmBetween_Planes( CloneSurfTriMesh( pStmAbove_Near)) ; + if ( IsNull( pStmBetween_Planes) || + ! pStmBetween_Planes->IsValid() || + ! pStmBetween_Planes->Cut( plFar, false)) + return false ; + + // se non ho ricavato nulla, esco + if ( ! pStmAbove_Near->IsValid() || pStmBetween_Planes->GetTriangleCount() == 0) + return true ; + + // -------------------------------------------------------------------------------------------------- + + // per la superficie tra i due piani ricavo gli indici dei triangoli delle facce C ( tutti questi triangoli andranno + // rimossi lasciando quindi solo le facce A) + // NB. sul piano far la TriMesh non presenta facce, bisogna riaggiungerle + if ( ! SewingMissingFacesOnPlanes( pStmBetween_Planes, plFar) || + ! SewingMissingFacesOnPlanes( pStmBetween_Planes, plNear)) + return false ; + + INTVECTOR vAllTria_C_between ; + for ( int f = 0 ; f < pStmBetween_Planes->GetFacetCount() ; ++ f) { + // ricavo i parametri della faccia + Point3d ptC_f ; Vector3d vtN_f ; + if ( ! pStmBetween_Planes->GetFacetCenter( f, ptC_f, vtN_f)) + return false ; + // controllo se si tratta di una faccia interna alla Part + DistPointSurfTm distPtStm( ptC_f, *pStm_Part) ; + if ( distPtStm.IsPointInside()) { + // se faccia interna, prendo tutti i suoi tringoli ... + INTVECTOR vT ; + if ( ! pStmBetween_Planes->GetAllTriaInFacet( f, vT)) + return false ; + // ... e li aggiungo i loro indici al vettore + for ( int t = 0 ; t < int( vT.size()) ; ++ t) + vAllTria_C_between.push_back( vT[t]) ; + } + } + // dalla superficie tra i due piani rimouovo i triangoli ottenuti + for ( int t = 0 ; t < int( vAllTria_C_between.size()) ; ++ t) + if ( ! pStmBetween_Planes->RemoveTriangle( vAllTria_C_between[t])) + return false ; + pStmBetween_Planes->DoCompacting() ; + + // se non ho ricavato nulla, allora significa che tutte le facce del volume di svuotatura comprese tra plNear e + // plFar sono chiuse, quindi non ho nulla da proiettare + PtrOwner pSfr_ExtendProjection( CreateSurfFlatRegion()) ; + if ( IsNull( pSfr_ExtendProjection)) + return false ; + if ( pStmBetween_Planes->IsValid() || pStmBetween_Planes->GetTriangleCount() > 0) { + // tutta questa superficie contiene solo facce A, le proietto sul piano plNear + if ( ! ProjectStmOnPlane( pStmBetween_Planes, plNear, pSfr_ExtendProjection)) + return false ; + // controllo ( per estrema sicurezza) la coerenza con le normali + if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfr_ExtendProjection->GetNormVersor())) + pSfr_ExtendProjection->Invert() ; + // NB. Questa superficie esce dal volume definito, devo stare attento a non rovinare parti di grezzo + if ( pSfrLimit->IsValid() && pSfr_ExtendProjection->IsValid()) { + if ( ! pSfr_ExtendProjection->Subtract( *pSfrLimit)) + return false ; + } + } + + // ------------------------------------------------------------------------------------------------- + + // per pStmAbove_Near ricavo gli indici dei triangoli delle facce A ( tutti questi triangoli andranno rimossi + // lasciando quindi solo le facce C) + INTVECTOR vAllTria_A ; + for ( int f = 0 ; f < pStmAbove_Near->GetFacetCount() ; ++ f) { + // ricavo i parametri della faccia + Point3d ptC_f ; Vector3d vtN_f ; + if ( ! pStmAbove_Near->GetFacetCenter( f, ptC_f, vtN_f)) + return false ; + // controllo se si tratta di una faccia interna alla Part + DistPointSurfTm distPtStm( ptC_f, *pStm_Part) ; + if ( ! distPtStm.IsPointInside()) { + // se faccia interna, prendo tutti i suoi tringoli ... + INTVECTOR vT ; + if ( ! pStmAbove_Near->GetAllTriaInFacet( f, vT)) + return false ; + // ... e li aggiungo i loro indici al vettore + for ( int t = 0 ; t < int( vT.size()) ; ++ t) + vAllTria_A.push_back( vT[t]) ; + } + } + // dalla superficie sopra al piano di svuotatura rimouovo i triangoli ottenuti + for ( int t = 0 ; t < int( vAllTria_A.size()) ; ++ t) + if ( ! pStmAbove_Near->RemoveTriangle( vAllTria_A[t])) + return false ; + pStmAbove_Near->DoCompacting() ; + + // se non ho ricavato nulla, significa che il volume di svuotatura ( tagliato con il piano, e quindi senza le + // facce da svuotare) descrive la stessa geometria della Part ( quindi ogni faccia è sulla Part) + // ---> non c'è nulla da proiettare + PtrOwner pSfrProjection( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrProjection)) + return false ; + if ( pStmAbove_Near->IsValid() && pStmAbove_Near->GetTriangleCount() > 0) { + // tutta questa superficie contiene solo facce C, le proietto sul piano plNear + if ( ! ProjectStmOnPlane( pStmAbove_Near, plNear, pSfrProjection)) + return false ; + // controllo ( per estrema sicurezza) la coerenza con le normali + if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfrProjection->GetNormVersor())) + pSfrProjection->Invert() ; + } + + // ------------------------------------------------------------------------------------------------- + + // 1) La superficie con le facce A tra i due piani plNear e plFar indentificano una proeizione che estende la + // superficie attuale da svuotare + // 2) La superficie con le facce C al di sopra del piano plNear identificano una proeizione che riduce la + // superficie attuale da svuotare + + // 1) ricavo la superificie da svuotare come addizione tra la ( *Sfr) e la ( *pSfr_ExtendProjection) + if ( pSfr_ExtendProjection->IsValid()) + if ( ! pSfr->Add( *pSfr_ExtendProjection)) + return false ; + // 2) ricavo la superficie da svuotare come sottrazione tra la ( *pSfr) e la ( *pSfrProjection) + if ( pSfr->IsValid() && pSfrProjection->IsValid()) + if ( ! pSfr->Subtract( *pSfrProjection)) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm_Part) +{ + // controllo parametri : + if ( pSfr == nullptr || ! pSfr->IsValid()) + return true ; // <- se superficie non valida, allora non ho niente da impostare sui suoi lati + if ( pStm_Part == nullptr || ! pStm_Part->IsValid()) + return false ; + + // per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti. + // se tali punti risultano TUTTI non interni alla Part, allora il lato viene considerato aperto + // NB. Aggiungendo delle aree proiettando le parti aperte del volume di Pocketing, alcuni tratti possono risultare + // in parte interni ed in parte esterni alla Part... ( questi lati rimangono chiusi, infatti lasciandoli aperti + // rischierei di rovinare la part al di fuori del volume di svuotatura. + const int NUM_POINTS = 4 ; + PtrOwner pSfrWithTmpProps( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrWithTmpProps)) + return false ; + + // scorro tutti i loop + for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) { + for ( int l = 0 ; l < pSfr->GetLoopCount( c) ; ++l) { + // recupero la curva composita del Loop + PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ; + if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) + return false ; + // abbellisco + pCrvCompoLoop->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + // scorro ogni sua sottocurva + for ( int u = 0 ; u < pCrvCompoLoop->GetCurveCount() ; ++ u) { + // recupero la sottocurva + const ICurve* pCrv = pCrvCompoLoop->GetCurve( u) ; + if ( pCrv == nullptr) + return false ; + // recupero i 4 punti + bool bIsClosed = false ; // <-- assumo che la curva sia Aperta + for ( int p = 0 ; p < NUM_POINTS + 1 && ! bIsClosed ; ++ p) { + double dPar = ( 1. / ( 1. * NUM_POINTS)) * p ; + Point3d ptPar ; + if ( ! pCrv->GetPointD1D2( dPar, ICurve::FROM_PLUS, ptPar)) + return false ; + DistPointSurfTm distPtStm( ptPar, *pStm_Part) ; + bIsClosed = distPtStm.IsPointInside() ; + } + pCrvCompoLoop->SetCurveTempProp( u, int( ! bIsClosed), 0) ; + } + // aggiungo il Loop con Flag di lato Aperto/Chiuso alla superficie + if ( l == 0) { + if ( ! pSfrWithTmpProps->AddExtLoop( *pCrvCompoLoop)) + return false ; + } + else + if ( ! pSfrWithTmpProps->AddIntLoop( *pCrvCompoLoop)) + return false ; + } + } + + // sostituisco la superficie da restituire + if ( ! pSfrWithTmpProps->IsValid() || + ! pSfr->Clear() || + ! pSfr->CopyFrom( pSfrWithTmpProps)) + return false ; + + return pSfr->IsValid() && pSfr->GetChunkCount() != 0 ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::GetCurvesForOptimizedPocketing( ISurfFlatRegion* pSfr, ICRVCOMPOPOVECTOR& vCrvOEWithFlags) +{ + vCrvOEWithFlags.clear() ; + + // controllo parametri : + if ( pSfr == nullptr || ! pSfr->IsValid()) { + vCrvOEWithFlags.emplace_back( CreateCurveComposite()) ; + return true ; // <- se superficie non valida, allora non ho curve da salvare + } + + // ricavo tutti i Loop esterni della superficie con i lati Aperti/Chiusi + for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) { + PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( c, 0))) ; + if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) + return false ; + vCrvOEWithFlags.emplace_back( Release( pCrvCompoLoop)) ; + } return true ; } + +//---------------------------------------------------------------------------- +bool +Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrLimit) +{ + // controllo parametri : + if ( pSfr == nullptr || ! pSfr->IsValid()) + return true ; // <- se superficie non valida, allora non ho niente da impostare sui suoi lati + + // NB. Tutti i Loop che presentano dei lati aperti possono essere estesi ; sia per loop esterni che per isole... + // I lati aperti vanno estesi seguendo lo geometria dei lati chiusi adiacenti e tenendo conto delle isole chiuse + // vicine ad essi + + // creo la superifcie da restituire... ( questa superficie sarà estesa presso i lati aperti) + PtrOwner pSrfFinal( CreateSurfFlatRegion()) ; + if ( IsNull( pSrfFinal)) + return false ; + + // per ogni Chunck della superificie ottenuta... + for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) { + + // vettore delle isole che userò ( le isole aperte piccole sono trascurate) + ICRVCOMPOPOVECTOR vCrvToTIsland ; + // Flag per sapere se c'è stata almeno una modifica in un loop + bool bIsChunkModified = false ; + + // 1) ricavo il Loop esterno + PtrOwner pCrvEL( ConvertCurveToComposite( pSfr->GetLoop( c, 0))) ; + if ( IsNull( pCrvEL) || ! pCrvEL->IsValid()) + return false ; + + // 2) creo un vettore di curve con le isole del Chunk + ICRVCOMPOPOVECTOR vCrvIsl ; + for ( int l = 1 ; l < pSfr->GetLoopCount( c) ; ++ l) { + PtrOwner pCrvIL( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ; + if ( IsNull( pCrvIL) || ! pCrvIL->IsValid()) + return false ; + vCrvIsl.emplace_back( Release( pCrvIL)) ; + } + + // 3) se la curva esterna presenta dei lati aperti -> devo modificarla + bool bSomeOpen = false ; + int nProp0 = -1 ; + for ( int u = 0 ; u < pCrvEL->GetCurveCount() && ! bSomeOpen ; ++ u) + if ( pCrvEL->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) + bSomeOpen = true ; + if ( bSomeOpen) { // se trovo dei lati aperti + // 3.1) sistemo la superificie + if ( ! AdjustContourWithOpenEdges( pCrvEL, vCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, + m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), + m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), + pSfrLimit)) { + m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + return false ; + } + bIsChunkModified = true ; // la curva è stata modificata + } + + // 4) Controllo i bordi delle isole ottenute e modifico quelli in cui sono presenti lati aperti + for ( int i = 0 ; i < ( int)vCrvIsl.size() ; ++ i) { + bSomeOpen = false ; + nProp0 = -1 ; + PtrOwner pCrvIsl( ConvertCurveToComposite( vCrvIsl[i]->Clone())) ; + for ( int u = 0 ; u < pCrvIsl->GetCurveCount() && ! bSomeOpen ; ++ u) { + if ( pCrvIsl->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) + bSomeOpen = true ; + } + if ( bSomeOpen) { // se trovo dei lati aperti ... + // 4.1) se l'isola è tutta aperta e "trascurabile" la talgo + bool bRemove = false ; + if ( ! CheckForRemovingIsland( pCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam, + bRemove)) + return false ; + if ( bRemove) // se si può trascurare passo alla successiva + continue ; + // 4.2) sistemo la superificie + ICRVCOMPOPOVECTOR vCrvNULL ; + if ( ! AdjustContourWithOpenEdges( pCrvIsl, vCrvNULL, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, + m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), + m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), + pSfrLimit)) { + m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + return false ; + } + bIsChunkModified = true ; // la curva è stata modificata + } + vCrvToTIsland.emplace_back( pCrvIsl->Clone()) ; + } + + // 6) Se c'è stata almeno una modifica di lato aperto al chunk (c-esimo), devo ricreare il Chunk + // nuovi loop ricavati ( Chunk dopo Chunk creo la superficie finale) + if ( bIsChunkModified) { + + SurfFlatRegionByContours SfrBC ; // per sicurezza analizzo ancora i Loop + pCrvEL->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; + SfrBC.AddCurve( Release( pCrvEL)) ; // <--- Loop esterno + for ( int i = 0 ; i < ( int)vCrvToTIsland.size() ; ++ i) { + vCrvToTIsland[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; + SfrBC.AddCurve( Release( vCrvToTIsland[i])) ; // <--- isole "valide" + } + + // ricavo il nuovo Chunk + PtrOwner pNewChunk( SfrBC.GetSurf()) ; + if ( IsNull( pNewChunk) || ! pNewChunk->IsValid()) + return false ; + + // aggiungo il Chunk alla superficie finale + if ( pSrfFinal->GetChunkCount() == 0) + pSrfFinal.Set( pNewChunk) ; + else + if ( ! pSrfFinal->Add( *pNewChunk)) + return false ; + } + // se il Chunk c-esimo non è mai stato modificato... + else { + // aggiungo il Chunk alla superficie finale + if ( pSrfFinal->GetChunkCount() == 0) + pSrfFinal.Set( pSfr->CloneChunk( c)) ; + else + if ( ! pSrfFinal->Add( *pSfr->CloneChunk( c))) + return false ; + } + } + + // restituisco la superficie aggiornata ricavata + if ( ! pSrfFinal->IsValid()) + return false ; + pSfr->Clear() ; + pSfr->CopyFrom( pSrfFinal) ; + + return pSrfFinal->IsValid() && pSrfFinal->GetChunkCount() > 0 ; +} + //---------------------------------------------------------------------------- bool Pocketing::DetectOpenEdgeInsideRaw( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw) @@ -2572,24 +3350,19 @@ GetCurveRadius( const ICurve* pCrv) //---------------------------------------------------------------------------- bool -Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, +Pocketing::AddZigZag( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) { - // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - - // determino numero e affondamento degli step - int nStep = 1 ; - nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; - double dStep = dElev / nStep ; - + // ricavo il numero degli step + int nStep = int( vSfr.size()) ; // raggio utensile double dTRad = m_TParams.m_dDiam / 2 ; - // Offset della regione per curva ZigZag double dOffs = dTRad + GetOffsR() ; double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ; @@ -2611,260 +3384,226 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c Frame3d frFrame = GLOB_FRM ; double dOptZigZagOffs = 0. ; } ; + // dichiarazione vettori info per steps + vector vCrvInfo ; + vector vChunkInfo ; - // ciclo su tutti i chunks della superificie originale - for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) { - - // copio il chunk c-esimo - PtrOwner pSrfChunk(( pSrfPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) + // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo) + for ( int j = 1 ; j <= nStep ; ++ j) { + // se superficie non valida, passo alla prossima + if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid()) + continue ; + // superficie per ingressi ed uscite + PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ; + if ( IsNull( pSrfLeanInOut)) return false ; - ISURFFRPOVECTOR vSrfSliced( nStep) ; // vettore delle superficie ricavate ( per ogni step) - vector vCrvOEWithFlags( nStep) ; // vettore delle relative curve originali ( per ogni step) - BOOLVECTOR vbChangedPrec( nStep, false) ; // vettore di Flag per superfici uguali tra steps consecutivi - VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; // vettore contenente le quote per le passate di svuotature + // se la superficie è cambiata ( o sono al primo step), reset dei parametri step precedente e ricalcolo + if ( vbChangedPrec[j-1] || j == 1) { + vCrvInfo.clear() ; + vChunkInfo.clear() ; + vChunkInfo.resize( vSfr[j-1]->GetChunkCount()) ; - // modifico il Chunk (c)-esimo in base alla geometria - if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfChunk, - nStep, vtTool, dElev, dDepth, dStep)) - return false ; + // ciclo sui chunk della superificie da svuotare + for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) { + // copio il chunk c-esimo + PtrOwner pSrfChunk(( vSfr[j-1]->CloneChunk( c))) ; + if ( IsNull( pSrfChunk)) + return false ; - // dichiarazione vettori info per steps - vector vCrvInfo ; - vector vChunkInfo ; + // 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, j, pSrfChunk, nInd)) + return false ; - // ciclo su tutti gli step - for ( int j = 1 ; j <= nStep ; ++j) { + // determino il riferimento in base alla svuotatura ( per poter orientare il frame per m_dSideAngle) + Frame3d frPocket ; + Point3d ptCen ; pSrfChunk->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtExtr) ; + frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - // se superificie non valida, salto allo step successivo - if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) { - vSrfSliced[j-1].Set( pSrfChunk->Clone()) ; - continue ; - } + // porto la superificie nel nuovo sistema di riferimento + pSrfChunk->ToLoc( frPocket) ; - PtrOwner pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j - 1])) ; - if ( IsNull( pSrfFinal)) - return false ; + // verifico se si tratta di caso ottimizzato + bool bOptimizedZigZag = false ; + ICRVCOMPOPOVECTOR vpCrvs ; // vettore con i paths a ZigZag per il Chunk (cc)-esimo allo step (j)-esimo + ICRVCOMPOPOVECTOR vCrvIslMergeBorders ; // vettore delle possibili isole mergiate per il Chunk (cc)-esimo allo step (j)-esimo + double dOptZigZagOffs = 0. ; // Offset per uscita dal grezzo nel caso di ottimizzazione + int nClosedSides = 0 ; // se caso ottimizzato, numero di lati chiusi + bool bTwoOpposite = false ; // se caso otimizzato, flag per lati chiusi opposti + if ( ! OptimizedZigZag( pSrfChunk, vtTool, dDepth, dSafeZ, frPocket, vCrvOrig[j-1][nInd], + bOptimizedZigZag, vpCrvs, vCrvIslMergeBorders, dOptZigZagOffs, nClosedSides, + bTwoOpposite)) + return false ; - // superficie per ingressi ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfFinal)) ; - if ( IsNull( pSrfLeanInOut)) - return false ; + // aggiorno le informazioni sul chunk attuale ( potrebbero essere usate per il successivo) + vChunkInfo[c].bOptZigZag = bOptimizedZigZag ; + vChunkInfo[c].nOptClosedSides = nClosedSides ; + vChunkInfo[c].bOptTwoOpposite = bTwoOpposite ; + vChunkInfo[c].frFrame = frPocket ; + vChunkInfo[c].dOptZigZagOffs = dOptZigZagOffs ; - // se la superficie è cambiata ( o sono al primo step), reset dei parametri step precedente e ricalcolo - if ( vbChangedPrec[j-1] || j == 1) { - vCrvInfo.clear() ; - vChunkInfo.clear() ; - vChunkInfo.resize( vSrfSliced[j-1]->GetChunkCount()) ; - - // ciclo su tutti i chunk della superificie ( chunk (cc)-esimo per lo step (j)-esimo) - for ( int cc = 0 ; cc < vSrfSliced[j-1]->GetChunkCount() ; ++cc) { - - // copio il Chunk (cc)-esimo allo step (j)-esimo - PtrOwner pSrfChunkFinal(( vSrfSliced[j-1]->CloneChunk( cc))) ; - if ( IsNull( pSrfChunkFinal)) - return false ; - - // 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( vCrvOEWithFlags, j, pSrfChunkFinal, nInd)) - return false ; - - // determino il riferimento in base alla svuotatura ( per poter orientare il frame per m_dSideAngle) - Frame3d frPocket ; - Point3d ptCen ; pSrfChunkFinal->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - - // porto la superificie nel nuovo sistema di riferimento - pSrfChunkFinal->ToLoc( frPocket) ; - - // verifico se si tratta di caso ottimizzato - bool bOptimizedZigZag = false ; - ICRVCOMPOPOVECTOR vpCrvs ; // vettore con i paths a ZigZag per il Chunk (cc)-esimo allo step (j)-esimo - ICRVCOMPOPOVECTOR vCrvIslMergeBorders ; // vettore delle possibili isole mergiate per il Chunk (cc)-esimo allo step (j)-esimo - double dOptZigZagOffs = 0. ; // Offset per uscita dal grezzo nel caso di ottimizzazione - int nClosedSides = 0 ; // se caso ottimizzato, numero di lati chiusi - bool bTwoOpposite = false ; // se caso otimizzato, flag per lati chiusi opposti - if ( ! OptimizedZigZag( pSrfChunkFinal, vtTool, dDepth, dSafeZ, frPocket, vCrvOEWithFlags[j-1][nInd], - bOptimizedZigZag, vpCrvs, vCrvIslMergeBorders, dOptZigZagOffs, nClosedSides, - bTwoOpposite)) - return false ; - - // aggiorno le informazioni sul chunk attuale ( potrebbero essere usate per il successivo) - vChunkInfo[cc].bOptZigZag = bOptimizedZigZag ; - vChunkInfo[cc].nOptClosedSides = nClosedSides ; - vChunkInfo[cc].bOptTwoOpposite = bTwoOpposite ; - vChunkInfo[cc].frFrame = frPocket ; - vChunkInfo[cc].dOptZigZagOffs = dOptZigZagOffs ; - - // se caso ottimizzato e vettore di curve ZigZag valido - if ( bOptimizedZigZag) { - vCrvInfo.resize( int( vpCrvs.size()) + int( vCrvIslMergeBorders.size())) ; - // aggiorno le curve per lo step attuale ( potrebbero essere usate per il successivo) - for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) { - vCrvInfo[x].pCrvCompo.Set( vpCrvs[x]->Clone()) ; - Point3d ptS ; - vCrvInfo[x].pCrvCompo->GetStartPoint( ptS) ; - vCrvInfo[x].ptStart = ptS ; - vCrvInfo[x].nChunk = cc ; + // se CASO OTTIMIZZATO e vettore di curve ZigZag valido + if ( bOptimizedZigZag) { + vCrvInfo.resize( int( vpCrvs.size()) + int( vCrvIslMergeBorders.size())) ; + // aggiorno le curve per lo step attuale ( potrebbero essere usate per il successivo) + for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) { + vCrvInfo[x].pCrvCompo.Set( vpCrvs[x]->Clone()) ; + Point3d ptS ; + vCrvInfo[x].pCrvCompo->GetStartPoint( ptS) ; + vCrvInfo[x].ptStart = ptS ; + vCrvInfo[x].nChunk = c ; + } + // creo localmente i parametri della funzione + VCT3DVECTOR vVtMidOut(( int)vCrvIslMergeBorders.size()) ; + BOOLVECTOR vbMidOut(( int)vCrvIslMergeBorders.size()) ; + PNTVECTOR vPtStart(( int)vCrvIslMergeBorders.size()) ; + // se la superficie è cambiata, allora ricalcolo i parametri + for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) { + // se richisto, inverto + if ( m_Params.m_bInvert) + vCrvIslMergeBorders[x]->Invert() ; + // setto la Feed per la curva di contorno + //AssignFeedForEdgeCleaning( vCrvIslMergeBorders[x], vCrvOEWithFlags[j-1], nInd) ; + if ( vCrvIslMergeBorders[x]->IsClosed()) { + bool bOutTmp = false ; + if ( ! SetBetterPtStartForSubChunks( vCrvIslMergeBorders[x], pSrfChunk, + vPtStart[x], vVtMidOut[x], bOutTmp)) + return false ; + vbMidOut[x] = bOutTmp ; // vector::reference da Bit a Bool } - // creo localmente i parametri della funzione - VCT3DVECTOR vVtMidOut(( int)vCrvIslMergeBorders.size()) ; - BOOLVECTOR vbMidOut(( int)vCrvIslMergeBorders.size()) ; - PNTVECTOR vPtStart(( int)vCrvIslMergeBorders.size()) ; + else { + vCrvIslMergeBorders[x]->GetStartPoint( vPtStart[x]) ; + vbMidOut[x] = false ; // ... migliorabile + vVtMidOut[x] = V_NULL ; // ... migliorabile + } + } + // guardo il punto finale in cui si trova la fresa dopo al percorso a ZigZag + // e riordino le curve ( e i relativi vettori) in base alla vicinanza + // ( piccola ottimizzazione per l'ordine dei percorsi sui bordi ) + Point3d ptEnd ; + if ( vpCrvs.size() > 0) + vpCrvs.back()->GetEndPoint( ptEnd) ; - // se la superficie è cambiata, allora ricalcolo i parametri - for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) { + if ( int( vCrvIslMergeBorders.size()) != 0 && + ! OrderCurvesByLastPntOfPath( vCrvIslMergeBorders, ptEnd, vPtStart, vVtMidOut, vbMidOut)) + return false ; - // se richisto, inverto - if ( m_Params.m_bInvert) - vCrvIslMergeBorders[x]->Invert() ; - - // setto la Feed per la curva di contorno - AssignFeedForEdgeCleaning( vCrvIslMergeBorders[x], vCrvOEWithFlags[j-1], nInd) ; - - if ( vCrvIslMergeBorders[x]->IsClosed()) { - bool bOutTmp = false ; - if ( ! SetBetterPtStartForSubChunks( vCrvIslMergeBorders[x], pSrfChunkFinal, - vPtStart[x], vVtMidOut[x], bOutTmp)) + int nOff_index = int( vpCrvs.size()) ; + for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) { + vCrvInfo[nOff_index + x].pCrvCompo.Set( Release( vCrvIslMergeBorders[x])) ; + vCrvInfo[nOff_index + x].nCrvType = CRV_BORDER ; + vCrvInfo[nOff_index + x].ptStart = vPtStart[x] ; + vCrvInfo[nOff_index + x].bMidOut = vbMidOut[x] ; + vCrvInfo[nOff_index + x].vtMidOut = vVtMidOut[x] ; + vCrvInfo[nOff_index + x].nChunk = c ; + } + } + // se CASO NON OTTIMIZZATO + else { + // effettuo il primo Offset della regione e controllo quanti Chunks ottengo... + // l'Offset contiene una quantità Extra, per stare leggermente più staccato dal bordo + PtrOwner pSrfZigZag( CloneSurfFlatRegion( pSrfChunk)) ; + if ( ! pSrfZigZag->Offset( - dOffs - dExtra, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + // effettuo un secondo Offset per ottenere le curve di contorno per ripulire la svuotatura a ZigZag + // Questo offset serve per ricavare le curve che l'utensile dovrà percorrere dopo aver svuotato a ZigZag + // Curva esterna ( non percorsa nel caso a ZigZag ottimizzato) + // Curve interne ( le isole, queste vanno percorse anche nei casi ottimizzati) + // Per le curve interne, questo Offset viene sempre fatto ( a prescindere dai casi ottimizzati ) + PtrOwner pSrfForCrv( CloneSurfFlatRegion( pSrfChunk)) ; + if ( ! pSrfForCrv->Offset( - dOffs, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + if ( ! pSrfForCrv->IsValid()) { + pSrfForCrv.Set( CloneSurfFlatRegion( pSrfChunk)) ; + if ( ! pSrfForCrv->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + } + // Avendo effettuato due Offsets ( -dOffs-dExtra e -dOffs ) non è detto che il numero di Chunks tra le nuove + // superifici sia uguale... Inizio a scorre i chunks della superficie per le curve di contorno e, + // per ognuna di esse, cerco il/i Chunck per il percorso a ZigZag contenuti. + for ( int cfc = 0 ; cfc < pSrfForCrv->GetChunkCount() ; ++ cfc) { // scorro i chunk della superificie per i bordi + for ( int cfz = 0 ; cfz < pSrfZigZag->GetChunkCount() ; ++ cfz) { // scorro i chunk della superificie per i percorsi ZigZag + // e la regione è dentro al Chunk per i contorni + if ( pSrfZigZag->GetChunkSimpleClassification( cfz, *pSrfForCrv, cfc) == REGC_IN1) { + // svuoto il vettore delle curve ( potrebbe essere riempito dal percorso precedente + vpCrvs.clear() ; + // Calcolo il percorso a ZigZag + PtrOwner pSrfZigZagChunk( pSrfZigZag->CloneChunk( cfz)) ; + if ( ! CalcZigZag( pSrfZigZagChunk, vpCrvs)) return false ; - vbMidOut[x] = bOutTmp ; // vector::reference da Bit a Bool - } - else { - vCrvIslMergeBorders[x]->GetStartPoint( vPtStart[x]) ; - vbMidOut[x] = false ; // migliorabile - vVtMidOut[x] = V_NULL ; // migliorabile + // memorizzo le curve ( per lo step successivo) + int nIndex_offs = int( vCrvInfo.size()) ; + vCrvInfo.resize( int( vpCrvs.size()) + nIndex_offs) ; + for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) { + vCrvInfo[ nIndex_offs + x].pCrvCompo.Set( Release( vpCrvs[x])) ; + vCrvInfo[ nIndex_offs + x].nChunk = c ; + } } + // se la regione non è dentro alla curva esterna allora la ignoro + // ( la ritroverò interna ad un'altra curva per i bordi successivamante o l'ho già considerata in precedenza) + else + continue ; + } + + // se lucidatura non aggiungo contorno + if ( m_TParams.m_nType == TT_MILL_POLISHING) + continue ; + + // Una volta percorse le curve di ZigZag devo aggiungere le curve per il bordo + // creo un vettore con tutti i loop formati, aggiustando i loro punti iniziali + // e portandoli nel frame della svuotatura + ICRVCOMPOPOVECTOR vAllCrv ; + VCT3DVECTOR vVtMidOut( pSrfForCrv->GetLoopCount( cfc)) ; + BOOLVECTOR vbMidOut( pSrfForCrv->GetLoopCount( cfc)) ; + PNTVECTOR vPtStart( pSrfForCrv->GetLoopCount( cfc)) ; + for ( int l = 0 ; l < pSrfForCrv->GetLoopCount( cfc) ; ++ l) { + PtrOwner pCrvLoop( ConvertCurveToComposite( pSrfForCrv->GetLoop( cfc, l))) ; + if ( IsNull( pCrvLoop)) + return false ; + + bool bOutTmp = false ; + + if ( ! SetBetterPtStartForSubChunks( pCrvLoop, pSrfChunk, vPtStart[l], vVtMidOut[l], bOutTmp)) + return false ; + vbMidOut[l] = bOutTmp ; // vector::reference da Bit a Bool + + // se richiesto, la inverto + if ( m_Params.m_bInvert) + pCrvLoop->Invert() ; + + // setto la Feed per la curva di contorno + //AssignFeedForEdgeCleaning( pCrvLoop, vCrvOEWithFlags[j-1], nInd) ; + + // inserisco la curva nel vettore + vAllCrv.emplace_back( Release( pCrvLoop)) ; } // guardo il punto finale in cui si trova la fresa dopo al percorso a ZigZag - // e riordino le curve ( e i relativi vettori) in base alla vicinanza + // e le riordino le curve ( e i relativi vettori ) in base alla vicinanza // ( piccola ottimizzazione per l'ordine dei percorsi sui bordi ) Point3d ptEnd ; if ( vpCrvs.size() > 0) - vpCrvs.back()->GetEndPoint( ptEnd) ; + vCrvInfo.back().pCrvCompo->GetEndPoint( ptEnd) ; - if ( int( vCrvIslMergeBorders.size()) != 0 && - ! OrderCurvesByLastPntOfPath( vCrvIslMergeBorders, ptEnd, vPtStart, vVtMidOut, vbMidOut)) + // riordino le curve + if ( ! OrderCurvesByLastPntOfPath( vAllCrv, ptEnd, vPtStart, vVtMidOut, vbMidOut)) return false ; - int nOff_index = int( vpCrvs.size()) ; - for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) { - vCrvInfo[nOff_index + x].pCrvCompo.Set( Release( vCrvIslMergeBorders[x])) ; - vCrvInfo[nOff_index + x].nCrvType = CRV_BORDER ; - vCrvInfo[nOff_index + x].ptStart = vPtStart[x] ; - vCrvInfo[nOff_index + x].bMidOut = vbMidOut[x] ; - vCrvInfo[nOff_index + x].vtMidOut = vVtMidOut[x] ; - vCrvInfo[nOff_index + x].nChunk = cc ; - } - } - // se caso non ottimizzato - else { - // effettuo il primo Offset della regione e controllo quanti Chunks ottengo... - // l'Offset contiene una quantità Extra, per stare leggermente più staccato dal bordo - PtrOwner pSrfZigZag( CloneSurfFlatRegion( pSrfChunkFinal)) ; - if ( ! pSrfZigZag->Offset( - dOffs - dExtra, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - // effettuo un secondo Offset per ottenere le curve di contorno per ripulire la svuotatura a ZigZag - // Questo offset serve per ricavare le curve che l'utensile dovrà percorrere dopo aver svuotato a ZigZag - // Curva esterna ( non percorsa nel caso a ZigZag ottimizzato) - // Curve interne ( le isole, queste vanno percorse anche nei casi ottimizzati) - // Per le curve interne, questo Offset viene sempre fatto ( a prescindere dai casi ottimizzati ) - PtrOwner pSrfForCrv( CloneSurfFlatRegion( pSrfChunkFinal)) ; - if ( ! pSrfForCrv->Offset( - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - if ( ! pSrfForCrv->IsValid()) { - pSrfForCrv.Set( CloneSurfFlatRegion( pSrfChunkFinal)) ; - if ( ! pSrfForCrv->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - } - // Avendo effettuato due Offsets ( -dOffs-dExtra e -dOffs ) non è detto che il numero di Chunks tra le nuove - // superifici sia uguale... Inizio a scorre i chunks della superficie per le curve di contorno e, - // per ognuna di esse, cerco il/i Chunck per il percorso a ZigZag contenuti. - for ( int cfc = 0 ; cfc < pSrfForCrv->GetChunkCount() ; ++ cfc) { // scorro i chunk della superificie per i bordi - for ( int cfz = 0 ; cfz < pSrfZigZag->GetChunkCount() ; ++ cfz) { // scorro i chunk della superificie per i percorsi ZigZag - // e la regione è dentro al Chunk per i contorni - if ( pSrfZigZag->GetChunkSimpleClassification( cfz, *pSrfForCrv, cfc) == REGC_IN1) { - // svuoto il vettore delle curve ( potrebbe essere riempito dal percorso precedente - vpCrvs.clear() ; - // Calcolo il percorso a ZigZag - PtrOwner pSrfZigZagChunk( pSrfZigZag->CloneChunk( cfz)) ; - if ( ! CalcZigZag( pSrfZigZagChunk, vpCrvs)) - return false ; - // memorizzo le curve ( per lo step successivo) - int nIndex_offs = int( vCrvInfo.size()) ; - vCrvInfo.resize( int( vpCrvs.size()) + nIndex_offs) ; - for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) { - vCrvInfo[ nIndex_offs + x].pCrvCompo.Set( Release( vpCrvs[x])) ; - vCrvInfo[ nIndex_offs + x].nChunk = cc ; - } - } - // se la regione non è dentro alla curva esterna allora la ignoro - // ( la ritroverò interna ad un'altra curva per i bordi successivamante o l'ho già considerata in precedenza) - else - continue ; - } - - // se lucidatura non aggiungo contorno - if ( m_TParams.m_nType == TT_MILL_POLISHING) - continue ; - - // Una volta percorse le curve di ZigZag devo aggiungere le curve per il bordo - // creo un vettore con tutti i loop formati, aggiustando i loro punti iniziali - // e portandoli nel frame della svuotatura - ICRVCOMPOPOVECTOR vAllCrv ; - VCT3DVECTOR vVtMidOut( pSrfForCrv->GetLoopCount( cfc)) ; - BOOLVECTOR vbMidOut( pSrfForCrv->GetLoopCount( cfc)) ; - PNTVECTOR vPtStart( pSrfForCrv->GetLoopCount( cfc)) ; - for ( int l = 0 ; l < pSrfForCrv->GetLoopCount( cfc) ; ++ l) { - PtrOwner pCrvLoop( ConvertCurveToComposite( pSrfForCrv->GetLoop( cfc, l))) ; - if ( IsNull( pCrvLoop)) - return false ; - - bool bOutTmp = false ; - - if ( ! SetBetterPtStartForSubChunks( pCrvLoop, pSrfChunkFinal, - vPtStart[l], vVtMidOut[l], bOutTmp)) - return false ; - vbMidOut[l] = bOutTmp ; // vector::reference da Bit a Bool - - // se richiesto, la inverto - if ( m_Params.m_bInvert) - pCrvLoop->Invert() ; - - // setto la Feed per la curva di contorno - AssignFeedForEdgeCleaning( pCrvLoop, vCrvOEWithFlags[j-1], nInd) ; - - // inserisco la curva nel vettore - vAllCrv.emplace_back( Release( pCrvLoop)) ; - } - // guardo il punto finale in cui si trova la fresa dopo al percorso a ZigZag - // e le riordino le curve ( e i relativi vettori ) in base alla vicinanza - // ( piccola ottimizzazione per l'ordine dei percorsi sui bordi ) - Point3d ptEnd ; - if ( vpCrvs.size() > 0) - vCrvInfo.back().pCrvCompo->GetEndPoint( ptEnd) ; - - // riordino le curve - if ( ! OrderCurvesByLastPntOfPath( vAllCrv, ptEnd, vPtStart, vVtMidOut, vbMidOut)) - return false ; - - int nIndex_offs = int( vCrvInfo.size()) ; - vCrvInfo.resize( int( vAllCrv.size()) + nIndex_offs) ; - for ( int x = 0 ; x < int( vAllCrv.size()) ; ++ x) { - vCrvInfo[ nIndex_offs + x].pCrvCompo.Set( Release( vAllCrv[x])) ; - vCrvInfo[ nIndex_offs + x].nCrvType = CRV_BORDER ; - vCrvInfo[ nIndex_offs + x].bMidOut = vbMidOut[x] ; - vCrvInfo[ nIndex_offs + x].ptStart = vPtStart[x] ; - vCrvInfo[ nIndex_offs + x].vtMidOut = vVtMidOut[x] ; - } + int nIndex_offs = int( vCrvInfo.size()) ; + vCrvInfo.resize( int( vAllCrv.size()) + nIndex_offs) ; + for ( int x = 0 ; x < int( vAllCrv.size()) ; ++ x) { + vCrvInfo[nIndex_offs + x].pCrvCompo.Set( Release( vAllCrv[x])) ; + vCrvInfo[nIndex_offs + x].nCrvType = CRV_BORDER ; + vCrvInfo[nIndex_offs + x].bMidOut = vbMidOut[x] ; + vCrvInfo[nIndex_offs + x].ptStart = vPtStart[x] ; + vCrvInfo[nIndex_offs + x].vtMidOut = vVtMidOut[x] ; } } } @@ -2930,7 +3669,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } } } - // Spostare dentro caso ottimizzato (?) // se due lati chiusi consecutivi o tre lati chiusi... else if (( nClosedSide == 2 || nClosedSide == 3) && ! bOptTwoOpposite) { // inverto il percorso @@ -2950,7 +3688,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } // estendo la fine del percorso - //if ( ! ( nClosedSide == 3 && bOptTwoOpposite)) if (( nClosedSide == 2 && ! bOptTwoOpposite) || ( nClosedSide == 3 && ! bOptTwoOpposite)) pCrvCurr->ExtendEndByLen( max( m_TParams.m_dDiam / 4 - dOffsOpt, 0.0)) ; @@ -3006,7 +3743,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false; - pCurve->Translate( vVtTrasl[j-1]) ; // --- se PRIMA ENTITA' --- if ( i == 0) { // dati inizio entità @@ -3151,8 +3887,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; - // traslo nello step richiesto - pCurve->Translate( vVtTrasl[j-1]) ; // --- se PRIMA ENTITA' --- if ( i == 0) { // dati inizio entità @@ -3187,8 +3921,9 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c m_pMchMgr->SetLastError(2415, "Error in Pocketing : LeadIn not computable"); return false; } - } - // elaborazioni sulla curva corrente + } + + // elaborazioni sulla curva corrente double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; @@ -3241,9 +3976,9 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } } } - } // fine ciclo sulle curve da disegnare - } // fine ciclo sugli step - } // fine ciclo sui chunk della superficie originale ( prima di operazioni con il grezzo + } + } + } return true ; } @@ -4418,15 +5153,17 @@ Pocketing::CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB) //---------------------------------------------------------------------------- bool -Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, +Pocketing::AddOneWay( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) { - // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; + // ricavo il numero di Step + int nStep = int( vSfr.size()) ; // se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP) { @@ -4436,83 +5173,34 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } } - // determino numero e affondamento degli step - int nStep = 1 ; - nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; - double dStep = dElev / nStep ; - + // determino i paramtri per la lavorazione double dTRad = 0.5 * m_TParams.m_dDiam ; double dOffs = dTRad + GetOffsR() ; double dExtra = min( 0.1 * m_TParams.m_dDiam, 1.0) ; - // copio la regione da svuotare - PtrOwner pSrfToPock( pSrfPock->Clone()) ; - if ( IsNull( pSrfToPock)) - return false ; - - // creo le regioni ideali -------------------------------------------- - // creo un frame di riferimento della svuotatura - Frame3d frLoc ; - Point3d ptC ; pSrfToPock->GetCentroid( ptC) ; - Vector3d vtN = pSrfPock->GetNormVersor() ; - frLoc.Set( ptC, vtN) ; - pSrfToPock->ToLoc( frLoc) ; - - ISURFFRPOVECTOR vSrfFlat ; // vettore delle regioni ideali - if ( ! OptimizeChunkOneWay( pSrfToPock, vSrfFlat)) - return false ; - - // riporto le superifici ideali nel sistema di riferimento globale ( Ogni chunk verrà poi messo nel suo frame) - for ( int i = 0 ; i < (int )vSrfFlat.size() ; ++ i) - vSrfFlat[i]->ToGlob( frLoc) ; - // ------------------------------------------------------------------ - - // scorro le regioni ideali - for ( int nIs = 0 ; nIs < int( vSrfFlat.size()) ; ++ nIs) { - - // copio la superificie ideale - PtrOwner pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIs])) ; - if ( IsNull( pSrfIdeal)) - return false ; - - // adatto la superficie alla sua geometria e al grezzo - ISURFFRPOVECTOR vSrfSliced( nStep) ; - vector vCrvOEWithFlags( nStep) ; - BOOLVECTOR vbChangedPrec( nStep, false) ; - VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; - if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfIdeal, - nStep, vtTool, dElev, dDepth, dStep)) - return false ; - - Point3d ptP1 ; // per LeadIn - for ( int j = 1 ; j <= nStep ; ++ j) { // ... per ogni step - - // se superificie non valida, salto allo step successivo - if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) { - vSrfSliced[j-1].Set( vSrfFlat[nIs]->Clone()) ; - continue ; - } - - // per entrate ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSrfSliced[j-1])) ; + // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo) + for ( int j = 1 ; j <= nStep ; ++ j) { + // se superficie non valida, passo alla prossima + if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid()) + continue ; + // ciclo sui chunk della superificie da svuotare + for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) { + // copio il chunk c-esimo + PtrOwner pSrfChunk( GetSurfFlatRegion( vSfr[j-1]->CloneChunk( c))) ; + if ( IsNull( pSrfChunk)) + return false ; + + // per entrate ed uscite + PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ; if ( IsNull( pSrfLeanInOut) || pSrfLeanInOut->GetChunkCount() == 0) return false ; - // NB. Effettuando il primo Offset, il numero di chunk qui potrebbe cambiare... - PtrOwner pSrfFirstOffs( CloneSurfFlatRegion( vSrfSliced[j-1])) ; - if ( IsNull( pSrfFirstOffs) || ! pSrfFirstOffs->IsValid()) - return false ; - if ( ! pSrfFirstOffs->Offset( - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - // creo un frame di riferimento per ogni superificie da svuotare Frame3d frLocI ; - Point3d ptC ; pSrfToPock->GetCentroid( ptC) ; - Vector3d vtN = pSrfToPock->GetNormVersor() ; + Point3d ptC ; pSrfChunk->GetCentroid( ptC) ; + Vector3d vtN = pSrfChunk->GetNormVersor() ; frLocI.Set( ptC, vtN) ; - vSrfSliced[j-1]->ToLoc( frLocI) ; + pSrfChunk->ToLoc( frLocI) ; // salvo tutte le curve di Offset in un vettore per poi ordinarle e sistemare i punti iniziali ICRVCOMPOPOVECTOR vAllCrv ; @@ -4524,25 +5212,18 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c // regioni non svuotate ( come soluzione interseco ogni segmento di OneWay con questa superificie Offsettata di // -dOffs e tagliando ogni segmento, lo accorcio sia all'inizio che alla fine della quantità dExtra - // organizzo i Chunck ( MIGLIORABILE AVENDO UNA TEMP_PROP3 CHE MI DICE L'OFFSET DA QUALE CHUNK DISCENDE) - for ( int c = 0 ; c < vSrfSliced[j-1]->GetChunkCount() ; ++ c) { - PtrOwner pSrfChuck_c( vSrfSliced[j-1]->CloneChunk( c)) ; - if ( IsNull( pSrfChuck_c)) - return false ; - - if ( ! pSrfChuck_c->Offset( - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - - for ( int cc = 0 ; cc < pSrfChuck_c->GetChunkCount() ; ++ cc) { - for ( int l = 0 ; l < pSrfChuck_c->GetLoopCount( cc) ; ++ l) { - PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSrfChuck_c->GetLoop( cc, l))) ; - if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) - return false ; - vAllCrv.emplace_back( Release( pCrvCompoLoop)) ; - vInd.emplace_back( c) ; - } + PtrOwner pSfrBorder( pSrfChunk->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ; + if ( IsNull( pSfrBorder)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + for ( int cc = 0 ; cc < pSfrBorder->GetChunkCount() ; ++ cc) { + for ( int l = 0 ; l < pSfrBorder->GetLoopCount( cc) ; ++ l) { + PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfrBorder->GetLoop( cc, l))) ; + if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) + return false ; + vAllCrv.emplace_back( Release( pCrvCompoLoop)) ; + vInd.emplace_back( c) ; } } @@ -4562,7 +5243,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c bool bOutTmp = false ; // ricavo il chunk da vui deriva -> vInd - PtrOwner pSrfCurrChunk( vSrfSliced[j-1]->CloneChunk( vInd[u])) ; + PtrOwner pSrfCurrChunk( vSfr[j-1]->CloneChunk( vInd[u])) ; if ( IsNull( pSrfCurrChunk)) return false ; // imposto un punto valido per l'entrata @@ -4571,12 +5252,6 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c return false ; vbMidOut[u] = bOutTmp ; // vector::reference da Bit a Bool - PtrOwner pOffs( CreateCurveComposite()) ; // copio la curva ... - if ( IsNull( pOffs) || ! pOffs->AddCurve( vAllCrv[u]->Clone())) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - // riporto i valori nel sistema di riferimento corretto vPtStart[u].ToGlob( frLocI) ; vVtMidOut[u].ToGlob( frLocI) ; @@ -4587,7 +5262,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c vAllCrv[u]->Invert() ; // setto la Feed per la curva di contorno - AssignFeedForEdgeCleaning( vAllCrv[u], vCrvOEWithFlags[j-1]) ; + //AssignFeedForEdgeCleaning( vAllCrv[u], vCrvOEWithFlags[j-1]) ; // se la curva è valida per entrata da fuori, aggiungo un piccolo tratto lineare if ( vbMidOut[u]) { @@ -4627,7 +5302,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ; // ---------------------------- Disegno le curve di contorno ---------------------- - for ( int u = 0 ; u < int( vAllCrv.size()) ; ++ u) { // percorro tutte le curve ( ordinate ) + for ( int u = 0 ; u < int( vAllCrv.size()) ; ++ u) { // percorro tutte le curve ( ordinate) // recupero la prima curva di offset disponibile PtrOwner pOffs( CreateCurveComposite()); @@ -4638,7 +5313,6 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c // aggiungo la lavorazione di questa curva Point3d ptP1 ; - double dStElev ; // ciclo sulle curve elementari int nMaxInd = pOffs->GetCurveCount() - 1 ; for ( int i = 0 ; i <= nMaxInd ; ++i) { @@ -4648,8 +5322,6 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; - // aggiungo affondamento - pCurve->Translate( vVtTrasl[j-1]) ; // SE PRIMA ENTITA' if ( i == 0) { // dati inizio entità @@ -4658,28 +5330,14 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c pCurve->GetStartPoint( ptStart) ; pCurve->GetStartDir( vtStart) ; Point3d ptForElev = ptStart ; - if( vbMidOut[u] || vbForcedOutStart[u]) + if ( vbMidOut[u] || vbForcedOutStart[u]) pCurve->GetEndPoint( ptForElev) ; - // se primo step o la superificie rispetto allo step prima non è cambiata o il numero - // di chunk è maggiore di 1, approccio e affondo - //if ( true || j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1) { - // determino inizio attacco + // determino inizio attacco if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) return false ; // determino elevazione su inizio attacco - //double dStElev ; - dStElev = dSink ; - /*if ( ! GetElevation( m_nPhase, ptForElev - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = j * dStep ; - bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - bool bUhAboveRaw = ! m_bAboveHead && - GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab) - dStElev = max( dStElev, j * dStep) ; - dStElev -= ( ptP1 - ptStart) * vtExtr ;*/ + double dStElev = dSink ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco if ( GetLeadInType() == POCKET_LI_ZIGZAG || GetLeadInType() == POCKET_LI_HELIX || @@ -4687,7 +5345,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ; dStElev = -LIO_ELEV_TOL ; } - // approccio al punto iniziale // false sempre ? + // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, vbMidOut[u] || vbForcedOutStart[u])) { m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; return false ; @@ -4700,7 +5358,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } } // elaborazioni sulla curva corrente - // elaborazioni sulla curva corrente + // elaborazioni sulla curva corrente double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; @@ -4725,52 +5383,42 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c // SE ULTIMA ENTITA' if ( i == nMaxInd) { // se ultimo step, uscita e retrazione di collegamento - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - double dEndElev = dSink ; - /*if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = j * dStep ; - dEndElev = max( dEndElev, j * dStep) ;*/ - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, false, ptP1, dEndElev, false)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false ; - } - // aggiungo retrazione - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } - // } + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + double dEndElev = dSink ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, false, ptP1, dEndElev, false)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } } } - - } // fine ciclo sulle curve di Offset i-esime // ===== SEGMENTI ========= - // determino il riferimento in base alla svuotatura ( Serve per Orientare i segmenti in base al m_dSideAngle ) - Frame3d frPocket ; - Point3d ptCen ; pSrfFirstOffs->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate ( ptCen, vtExtr, m_Params.m_dSideAngle) ; - pSrfFirstOffs->ToLoc( frPocket) ; - BBox3d b3Pocket ; pSrfFirstOffs->GetLocalBBox( b3Pocket) ; - Point3d ptMin ; double dDimX, dDimY, dDimZ ; + // determino il riferimento in base alla svuotatura ( Serve per Orientare i segmenti in base al m_dSideAngle) + BBox3d b3Pocket ; pSfrBorder->GetLocalBBox( b3Pocket) ; + Point3d ptMin ; + double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; // passi in Y int nYStep = static_cast( ceil(( dDimY + 2 * dExtra) / GetSideStep())) ; double dYStep = ( nYStep > 0 ? ( dDimY + 2 * dExtra) / nYStep : 0) ; - --nYStep ; + -- nYStep ; // vettore dei segmenti al di sotto della linea corrente ( per la Feed) ICURVEPOVECTOR vLineUnder ; - ICURVEPOVECTOR vLineAbove ; // in questo caso sempre vuoto + ICURVEPOVECTOR vLineAbove ; // in questo caso sempre vuoto ICRVCOMPOPOVECTOR vCrvLink ; // in questo caso sempre vuoto // calcolo le linee di svuotatura @@ -4785,7 +5433,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c return false ; } - // linea come composita per Feed ( la dovrò spezzare) + // linea come composita per Feed ( la dovrò spezzare a seconda dei tratti di Feed differenti) PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo)) return false ; @@ -4795,13 +5443,14 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c // riempio il vettore di segmenti CRVCVECTOR ccClassSeg ; - pSrfFirstOffs->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ; + pSfrBorder->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ; for ( int w = 0 ; w < int( ccClassSeg.size()) ; ++w) { if ( ccClassSeg[w].nClass == CRVC_IN) { + // creo la Linea tra i bordi PtrOwner pCrvSeg( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ; double duF, dLen ; - // accorcio leggermente il segmento per non toccare la prima curva di Offset + // accorcio leggermente il segmento per non toccare la prima curva di Offset ( di dExtra) if ( ! pCrvSeg->GetLength( dLen) || dLen < 2 * dExtra || ! pCrvSeg->GetParamAtLength( dLen - dExtra, duF) || @@ -4809,37 +5458,27 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c ! pCrvSeg->TrimEndAtParam( duF)) pCrvSeg.Set( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ; - Point3d ptS, ptE ; + // punto iniziale + Point3d ptS ; pCrvSeg->GetStartPoint( ptS) ; // imposto la Feed pCrvCompo->Clear() ; pCrvCompo->AddCurve( pCrvSeg->Clone()) ; vAddedLines.emplace_back( pCrvCompo->Clone()) ; - if ( ! AssignFeedZigZagOneWay( pCrvCompo, false, vLineAbove, vLineUnder, vCrvLink)) - return false ; + //if ( ! AssignFeedZigZagOneWay( pCrvCompo, false, vLineAbove, vLineUnder, vCrvLink)) + // return false ; // INIZIO - ptS.ToGlob( frPocket) ; - ptS.Translate( vVtTrasl[j-1]) ; + ptS.ToGlob( frLocI) ; + //ptS.Translate( vVtTrasl[j-1]) ; // determino inizio attacco Point3d ptP ; - if ( ! CalcLeadInStart( ptS, frPocket.VersX(), vtExtr, nullptr, ptP)) + if ( ! CalcLeadInStart( ptS, frLocI.VersX(), vtExtr, nullptr, ptP)) return false ; // determino elevazione su inizio attacco double dStElev = dSink ; - /*double dStElev ; - if ( ! GetElevation( m_nPhase, ptS - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = j * dStep ; - bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetAhPointUnderRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - bool bUhAboveRaw = ! m_bAboveHead && - GetUhPointAboveRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if( bAhUnderRaw || bUhAboveRaw || ( i == 1 && w == 1)) - dStElev = max( dStElev, j * dStep) ; - dStElev -= ( ptP - ptS) * vtExtr ;*/ + dStElev -= ( ptP - ptS) * vtExtr ; // sempre approccio di collegamento if ( ! AddLinkApproach( ptP, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; @@ -4847,17 +5486,21 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } // aggiungo attacco (forzato ad essere lineare) SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP, ptS, frPocket.VersX(), vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs, true)) { + if ( ! AddLeadIn( ptP, ptS, frLocI.VersX(), vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs, true)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } - for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + // punto finale + Point3d ptE ; + // per ogni sotto-tratto ( della feed) del tratto lineare ( per ora sempre 1) + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + // ricavo la singola entità curva const ICurve* pCurve( pCrvCompo->GetCurve( u)) ; pCurve->GetEndPoint( ptE) ; - ptE.ToGlob( frPocket) ; - ptE.Translate( vVtTrasl[j-1]) ; + ptE.ToGlob( frLocI) ; + //ptE.Translate( vVtTrasl[j-1]) ; // movimento al punto finale // elaborazioni sulla curva corrente @@ -4867,22 +5510,17 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c SetFeed( dFeed) ; if ( AddLinearMove( ptE) == GDB_ID_NULL) return false ; - } // FINE Point3d ptQ ; - //double dEndElev = dElev ; double dEndElev = dSink ; - /*if ( ! GetElevation( m_nPhase, ptE - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = j * dStep ; - dEndElev = max( dEndElev, j * dStep) ;*/ SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptE, frPocket.VersX(), vtExtr, nullptr, bSplitArcs, true, ptQ, dEndElev)) { + if ( ! AddLeadOut( ptE, frLocI.VersX(), vtExtr, nullptr, bSplitArcs, true, ptQ, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } - + dEndElev -= ( ptE - ptQ) * vtExtr ; // se ultimo movimento di ultima area, aggiungo retrazione globale if ( j == nStep && i == nYStep && w == ( int)ccClassSeg.size() - 2) { if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { @@ -4892,6 +5530,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } // altrimenti aggiungo retrazione di collegamento else { + dEndElev = dSink ; if ( ! AddLinkRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; @@ -4903,8 +5542,8 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c for ( int u = 0 ; u < ( int)vAddedLines.size() ; ++ u) vLineUnder.emplace_back( vAddedLines[u]->Clone()) ; } - } // fine ciclo sugli step - } // fine ciclo sulle superifici ideali + } + } return true ; } @@ -4912,63 +5551,40 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c //---------------------------------------------------------------------------- bool -Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, +Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) { - // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; + // ricavo il numero di Step + int nStep = int( vSfr.size()) ; - // determino numero e affondamento degli step - int nStep = 1 ; - nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; - double dStep = dElev / nStep ; - - // ciclo sui chunk della superificie da svuotare - for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) { - - // copio il chunk c-esimo - PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) - return false ; - - - // modifico le superifici in base alla geometria del grezzo e alla geometria dell'entità selezionata - ISURFFRPOVECTOR vSrfSliced( nStep) ; - vector vCrvOEWithFlags( nStep) ; - BOOLVECTOR vbChangedPrec( nStep, false) ; - VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; - if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfChunk, - nStep, vtTool, dElev, dDepth, dStep)) - return false ; - - Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente - BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo - ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente - ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente - vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente - INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente - BOOLVECTOR vbOptTrap_prec ; // flags per caso ottimizzato svuotratura dello step precedente - int nOffs_act = 0 ; // Shift indice dei vettori causato da nReg - - // ciclo su tutti gli step - for ( int j = 1 ; j <= nStep ; ++ j) { - - // se superificie non valida, salto allo step successivo - if ( IsNull( vSrfSliced[j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) { - vSrfSliced[j-1].Set( pSrfChunk->Clone()) ; - continue ; - } - - // la superificie che lavoro è quella ottenuta in precedenza allo step j-esimo - PtrOwner pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j-1])) ; - if ( IsNull( pSrfFinal)) + // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo) + for ( int j = 1 ; j <= nStep ; ++ j) { + // se superficie non valida, passo alla prossima + if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid()) + continue ; + // ciclo sui chunk della superificie da svuotare + for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) { + // copio il chunk c-esimo + PtrOwner pSrfChunk( GetSurfFlatRegion( vSfr[j-1]->CloneChunk( c))) ; + if ( IsNull( pSrfChunk)) return false ; - nOffs_act = 0 ; // reset indice dei vettori per step precedenti + Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente + BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo + ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente + ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente + vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente + INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente + BOOLVECTOR vbOptTrap_prec ; // flags per caso ottimizzato svuotratura dello step precedente + int nOffs_act = 0 ; // Shift indice dei vettori causato da nReg + nOffs_act = 0 ; // reset indice dei vettori per step precedenti + if ( vbChangedPrec[j-1]) { // se lo step attuale è cambiato rispetto al precedente -> Flush info step precedente vMCrv_step_prec.clear() ; @@ -4979,310 +5595,302 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, vbOptTrap_prec.clear() ; } - for ( int cc = 0 ; cc < pSrfFinal->GetChunkCount() ; ++cc) { // per ogni suo chunk cc-esimo... - // il numero di chunk dopo aver intersecato e proiettato può cambiare + const int MAX_REGS = 50 ; + int nReg = 0 ; // chunk nuovo corrente da svuotare - // essendo una svuotatura a spirale, facendo il primo offset del chunk cc-esimo potrei ottenere - // ulteriori chunks ( ad esempio se la superificie presenta delle parti molto strette) - // MAX_REGS = 50 -> numero massimo di Chunks nuovi accettati - const int MAX_REGS = 50 ; - int nReg = 0 ; // chunk nuovo corrente da svuotare + // ciclo su tutte le regioni che posso ottenere col primo Offset del chunk cc-esimo + while ( nReg < MAX_REGS) { - PtrOwner pSrfChunkFinal( pSrfFinal->CloneChunk( cc)) ; + // superifice per ingressi ed uscite + PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ; + if ( IsNull( pSrfLeanInOut)) + return false ; - // ciclo su tutte le regioni che posso ottenere col primo Offset del chunk cc-esimo - while ( nReg < MAX_REGS) { - - // superifice per ingressi ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunkFinal)) ; - if ( IsNull( pSrfLeanInOut)) + // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine + PtrOwner pMCrv( CreateCurveComposite()) ; // percorso di svuotatura + PtrOwner pRCrv( CreateCurveComposite()) ; // percorso di ritorno + if ( IsNull( pMCrv) || IsNull( pRCrv)) { + m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; + return false ; + } + + int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale + bool bOutStart ; // flag per entrata da fuori per lo step attuale + bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale + + Point3d ptStart ; // punto iniziale del percorso + Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral) + bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step) + + bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio + + // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente + // ( non c'è bisogno di ricalcolare tutti i percorsi) + if ( ! vbChangedPrec[j-1] && j != 1) { + if ( nOffs_act > int( vMCrv_step_prec.size()) - 1) + break ; + pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ; + pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ; + nRegTot = vnRegTot_prec[nOffs_act] ; + bMidOut = vbMidOutPrec[nOffs_act] ; + vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ; + vtMidOut = vvtMidOutPrec[nOffs_act] ; + bOptimizedTrap = vbOptTrap_prec[nOffs_act] ; + } + else { + // se lucidatura con epicicli + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { + // verifico che i parametri lucidatura siano sensati + if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + // modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli + m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; + } + + // 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, j, pSrfChunk, nInd)) return false ; - // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine - PtrOwner pMCrv( CreateCurveComposite()) ; // percorso di svuotatura - PtrOwner pRCrv( CreateCurveComposite()) ; // percorso di ritorno - if ( IsNull( pMCrv) || IsNull( pRCrv)) { - m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; + nRegTot = nReg ; + // calcolo il percorso di svuotatura + if ( ! CalcSpiral( pSrfChunk, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv, + vCrvOrig[j-1][nInd], j == 1 ? true : vbChangedPrec[j-1], bOptimizedTrap)) + return false ; + + // se terminate le regioni, esco + if ( pMCrv->GetCurveCount() == 0) + break ; // passo al chunk originale successivo + + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { + // riporto il diametro dell'utensile al valore originale + m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; + // aggiorno i percorsi di svuotatura con epicicli + if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + } + + // memorizzo le curve create e modificate per lo step successivo + vMCrv_step_prec.emplace_back( pMCrv->Clone()) ; + vRCrv_step_prec.emplace_back( pRCrv->Clone()) ; + // memorizzo i Flag per le entrate + vbMidOutPrec.push_back( bMidOut) ; + // memorizzo il numero delle regioni create dal primo Offset + vnRegTot_prec.push_back( nRegTot) ; + // memorizzo il versore di uscita calcolato + vvtMidOutPrec.push_back( vtMidOut) ; + // memorizzo caso ottimizzato + vbOptTrap_prec.push_back( bOptimizedTrap) ; + } + + // controlli per entrate da fuori al grezzo + // NB. Anche se la superficie è rimasta invariata le entrate vanno controllate caso per caso + bOutStart = bMidOut ; + if ( bOutStart && ! bOptimizedTrap) { + // calcolo il punto fuori per il LeadIn + Point3d ptOut = ptStart + vtMidOut * ( 0.5 * m_TParams.m_dDiam + max( dSafeZ, m_dOpenMinSafe)) ; + ptOut.Translate( vVtTrasl[j-1]) ; // lo traslo allo step corrente + double dStElev ; + // controllo l'elevazione + bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ; + if ( bOutStart || m_bOpenOutRaw) { + // aggiungo al ritorno l'uscita + if ( pRCrv->GetCurveCount() == 0) { + Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ; + pRCrv->AddPoint( ptStart) ; + } + ptOut.Translate( -vVtTrasl[j-1]) ; // lo ritraslo sulla curva + // aggiungo un tratto lineare all'inizio del percorso di svuotatura + pMCrv->AddLine( ptOut, false) ; + // assegno la sua Feed + //AssignFeedForLineInOut( pMCrv, true) ; + // aggiungo un tratto lineare alla fine del percorso di svuotatura + pRCrv->AddLine( ptOut, true) ; + // assegno la sua Feed + //AssignFeedForLineInOut( pRCrv, false) ; + } + } + + // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato + int nOutsideRaw = 0 ; + if ( bOptimizedTrap) { + AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; + bOutStart = ( nOutsideRaw > 0) ; + // imposto la Feed + //AssignFeedSpiralOpt( 1, pMCrv) ; + //AssignFeedForReturnPath( pRCrv) ; + } + + // verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro + bForcedOutStart = ( bMidOut && m_bOpenOutRaw) ; + + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore + if ( m_TParams.m_nType == TT_MILL_NOTIP && ! ( bOutStart || bForcedOutStart)) { + if ( ! LeadInRawIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } + } + + // se sono nel caso ottimizzato per Trapezi e ho attacco e uscita entrambi dentro/fuori dal grezzo, + // ad ogni step pari inverto la direzione della curva solamente se ho un solo chunk e la superificie successiva + // non è cambiata + if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1 && vSfr[j-2]->GetChunkCount() == 1 && ! vbChangedPrec[j-1] + && ( j % 2 == 0)) + pMCrv->Invert() ; - int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale - bool bOutStart ; // flag per entrata da fuori per lo step attuale - bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale + ++nReg ; // incremento del numero di regioni trovate + ++ nOffs_act ; // shift indice - Point3d ptStart ; // punto iniziale del percorso - Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral) - bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step) + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + int nMaxRInd = pRCrv->GetCurveCount() - 1 ; - bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio + // determino l'affondamento attuale + double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ; - // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente - // ( non c'è bisogno di ricalcolare tutti i percorsi) - if ( ! vbChangedPrec[j-1] && j != 1) { - if ( nOffs_act > int( vMCrv_step_prec.size()) - 1) - break ; - pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ; - pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ; - nRegTot = vnRegTot_prec[nOffs_act] ; - bMidOut = vbMidOutPrec[nOffs_act] ; - vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ; - vtMidOut = vvtMidOutPrec[nOffs_act] ; - bOptimizedTrap = vbOptTrap_prec[nOffs_act] ; - } - else { - // se lucidatura con epicicli - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // verifico che i parametri lucidatura siano sensati - if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + // ciclo sulle curve elementari + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pMCrv->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + // aggiungo affondamento + //pCurve->Translate( vVtTrasl[j-1]) ; + // se prima entità + if ( i == 0) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // Entrata ... + if ( j == 1 || vbChangedPrec[j-1] || vSfr[j-2]->GetChunkCount() > 1 || nRegTot > 1) { + // Ricalcolo il punto di attacco sopra al PtStart ( modificato in precedenza dal PtOut) quando : + // 1) sono nel primo Step o ... + // 2) la superificie è diversa da quello dello step precedente o ... + // 3) il numero di chunk allo step precedente è maggiore di 1 o ... + // 4) dal primo offset del chunk cc-esimo ottengo più regioni + + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } - // modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli - m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; - } - // 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( vCrvOEWithFlags, j, pSrfChunkFinal, nInd)) - return false ; - - // ------------------------------------------------------------------------------------ - nRegTot = nReg ; - // calcolo il percorso di svuotatura - if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv, - vCrvOEWithFlags[j-1][nInd], j == 1 ? true : vbChangedPrec[j-1], - bOptimizedTrap)) - return false ; - - // se terminate le regioni, esco - if ( pMCrv->GetCurveCount() == 0) - break ; // passo al chunk originale successivo - - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // riporto il diametro dell'utensile al valore originale - m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; - // aggiorno i percorsi di svuotatura con epicicli - if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + // determino elevazione su inizio attacco + double dStElev = dSink ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { + ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ; + dStElev = -LIO_ELEV_TOL ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart || bForcedOutStart)) { + m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } } - - // memorizzo le curve create e modificate per lo step successivo - vMCrv_step_prec.emplace_back( pMCrv->Clone()) ; - vRCrv_step_prec.emplace_back( pRCrv->Clone()) ; - // memorizzo i Flag per le entrate - vbMidOutPrec.push_back( bMidOut) ; - // memorizzo il numero delle regioni create dal primo Offset - vnRegTot_prec.push_back( nRegTot) ; - // memorizzo il versore di uscita calcolato - vvtMidOutPrec.push_back( vtMidOut) ; - // memorizzo caso ottimizzato - vbOptTrap_prec.push_back( bOptimizedTrap) ; - } - - // controlli per entrate da fuori al grezzo - // NB. Anche se la superficie è rimasta invariata le entrate vanno controllate caso per caso - bOutStart = bMidOut ; - if ( bOutStart && ! bOptimizedTrap) { - // calcolo il punto fuori per il LeadIn - Point3d ptOut = ptStart + vtMidOut * ( 0.5 * m_TParams.m_dDiam + max( dSafeZ, m_dOpenMinSafe)) ; - ptOut.Translate( vVtTrasl[j-1]) ; // lo traslo allo step corrente - double dStElev ; - // controllo l'elevazione - bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ; - if ( bOutStart || m_bOpenOutRaw) { - // aggiungo al ritorno l'uscita - if ( pRCrv->GetCurveCount() == 0) { - Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ; - pRCrv->AddPoint( ptStart) ; - } - ptOut.Translate( -vVtTrasl[j-1]) ; // lo ritraslo sulla curva - // aggiungo un tratto lineare all'inizio del percorso di svuotatura - pMCrv->AddLine( ptOut, false) ; - // assegno la sua Feed - AssignFeedForLineInOut( pMCrv, true) ; - // aggiungo un tratto lineare alla fine del percorso di svuotatura - pRCrv->AddLine( ptOut, true) ; - // assegno la sua Feed - AssignFeedForLineInOut( pRCrv, false) ; - } - } - - // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato - int nOutsideRaw = 0 ; - if ( bOptimizedTrap) { - AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; - bOutStart = ( nOutsideRaw > 0) ; - // imposto la Feed - AssignFeedSpiralOpt( 1, pMCrv) ; - AssignFeedForReturnPath( pRCrv) ; - } - - // verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro - bForcedOutStart = ( bMidOut && m_bOpenOutRaw) ; - - // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore - if ( m_TParams.m_nType == TT_MILL_NOTIP && ! ( bOutStart || bForcedOutStart)) { - if ( ! LeadInRawIsOk()) { - m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false ; - } - } - - // se sono nel caso ottimizzato per Trapezi e ho attacco e uscita entrambi dentro/fuori dal grezzo, - // ad ogni step pari inverto la direzione della curva solamente se ho un solo chunk e la superificie successiva - // non è cambiata - if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1 && vSrfSliced[j-2]->GetChunkCount() == 1 && ! vbChangedPrec[j-1] - && ( j % 2 == 0)) - pMCrv->Invert() ; - - ++nReg ; // incremento del numero di regioni trovate - ++ nOffs_act ; // shift indice - int nMaxInd = pMCrv->GetCurveCount() - 1 ; - int nMaxRInd = pRCrv->GetCurveCount() - 1 ; - - // determino l'affondamento attuale - double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ; - - // ciclo sulle curve elementari - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false ; - // aggiungo affondamento - pCurve->Translate( vVtTrasl[j-1]) ; - // se prima entità - if ( i == 0) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // Entrata ... - if ( j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1 || nRegTot > 1) { - // Ricalcolo il punto di attacco sopra al PtStart ( modificato in precedenza dal PtOut) quando : - // 1) sono nel primo Step o ... - // 2) la superificie è diversa da quello dello step precedente o ... - // 3) il numero di chunk allo step precedente è maggiore di 1 o ... - // 4) dal primo offset del chunk cc-esimo ottengo più regioni - - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) - return false ; - - // determino elevazione su inizio attacco - double dStElev = dSink ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || - GetLeadInType() == POCKET_LI_HELIX || - GetLeadInType() == POCKET_LI_GLIDE) { - ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ; - dStElev = -LIO_ELEV_TOL ; - } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart || bForcedOutStart)) { - m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; - return false ; - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false ; - } - } - // altrimenti solo collegamento - else { - SetFeed( GetStartFeed()) ; - GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } - } - } - // elaborazioni sulla curva corrente - double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; - double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? - GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; - // DrawColoredCrvForFeedTest( pCurve, dFeed) ; - SetFeed( dFeed) ; // <--- - if ( pCurve->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCurve) ; - Point3d ptP3 = pLine->GetEnd() ; - // SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; // <---- - if ( AddLinearMove( ptP3) == GDB_ID_NULL) + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; + } } - else if ( pCurve->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCurve) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) - return false ; - } - // se ultima entità -> passo al chunk cc successivo o allo step sotto - if ( i == nMaxInd) { - // Uscita ... - if ( j < nStep && vSrfSliced[j-1]->GetChunkCount() == 1 && ! vbChangedPrec[j] && nRegTot == 1) { - // Effettuo l'uscita quando : - // 1) non sono nello step intermedio e ... - // 2) il numero di Chunk allo step attuale è 1 e ... - // 3) la superificie non è cambiata dalla precedente e ... - // 4) dal primo offset del chunk cc-esimo non si sono create altre regioni da svuotare + } + // elaborazioni sulla curva corrente + double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; + double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? + GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; + // DrawColoredCrvForFeedTest( pCurve, dFeed) ; + SetFeed( dFeed) ; // <--- + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + // SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; // <---- + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità -> passo al chunk cc successivo o allo step sotto + if ( i == nMaxInd) { + // Uscita ... + if ( j < nStep && vSfr[j-1]->GetChunkCount() == 1 && ! vbChangedPrec[j] && nRegTot == 1) { + // Effettuo l'uscita quando : + // 1) non sono nello step intermedio e ... + // 2) il numero di Chunk allo step attuale è 1 e ... + // 3) la superificie non è cambiata dalla precedente e ... + // 4) dal primo offset del chunk cc-esimo non si sono create altre regioni da svuotare - // se necessario ritorno all'inizio - if ( nMaxRInd >= 0) { - // copio la curva di ritorno - PtrOwner pRet( pRCrv->Clone()) ; - if ( IsNull( pRet)) - return false ; - // aggiungo affondamento - pRet->Translate( vVtTrasl[j-1]) ; - // se attacco a scivolo, accorcio della lunghezza dell'attacco - if ( GetLeadInType() == POCKET_LI_GLIDE) { - double dLen ; pRet->GetLength( dLen) ; - if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) { - if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang)) - pRet->Clear() ; - } - else + // se necessario ritorno all'inizio + if ( nMaxRInd >= 0) { + // copio la curva di ritorno + PtrOwner pRet( pRCrv->Clone()) ; + if ( IsNull( pRet)) + return false ; + // aggiungo affondamento + pRet->Translate( vVtTrasl[j-1]) ; + // se attacco a scivolo, accorcio della lunghezza dell'attacco + if ( GetLeadInType() == POCKET_LI_GLIDE) { + double dLen ; pRet->GetLength( dLen) ; + if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) { + if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang)) pRet->Clear() ; } - // emetto - SetFeed( GetFeed()) ; - if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) - return false ; + else + pRet->Clear() ; } + // emetto + SetFeed( GetFeed()) ; + if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) + return false ; } - // atrimenti ultimo step, uscita e retrazione - else { - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - Point3d ptP1 ; - double dEndElev = dSink ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptP1, dEndElev, true)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false ; - } - // aggiungo retrazione - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; - return false ; - } + } + // atrimenti ultimo step, uscita e retrazione + else { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + double dEndElev = dSink ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptP1, dEndElev, true)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; + return false ; } } } @@ -5296,7 +5904,8 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, //---------------------------------------------------------------------------- bool -Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, +Pocketing::AddSpiralOut( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) { // recupero distanze di sicurezza @@ -5304,53 +5913,30 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; + // ricavo il numero di Step + int nStep = int( vSfr.size()) ; - // determino numero e affondamento degli step - int nStep = 1 ; - nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; - double dStep = dElev / nStep ; - - // ciclo sui chunk della superificie da svuotare - for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) { - - // copio il chunk c-esimo - PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) - return false ; - - // modifico le superifici in base alla geometria del grezzo e alla geometria dell'entità selezionata - ISURFFRPOVECTOR vSrfSliced( nStep) ; - vector vCrvOEWithFlags( nStep) ; - BOOLVECTOR vbChangedPrec( nStep, false) ; - VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; - if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfChunk, - nStep, vtTool, dElev, dDepth, dStep)) - return false ; - - Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente - bool bMidOutPrec ; // flag per entrata precedente da fuori dal grezzo - BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo - ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente - ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente - vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente - INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente - int nOffs_act = 0 ; - - // ciclo su tutti gli step - for ( int j = 1 ; j <= nStep ; ++ j) { - - // se superificie non valida, salto allo step successivo - if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) { - vSrfSliced[j-1].Set( pSrfChunk->Clone()) ; - continue ; - } - - // la superificie che lavoro è quella ottenuta in precedenza allo step j-esimo - PtrOwner pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j - 1])) ; - if( IsNull( pSrfFinal)) + // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo) + for ( int j = 1 ; j <= nStep ; ++ j) { + // se superficie non valida, passo alla prossima + if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid()) + continue ; + // ciclo sui chunk della superificie da svuotare + for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) { + // copio il chunk c-esimo + PtrOwner pSrfChunk( GetSurfFlatRegion( vSfr[j-1]->CloneChunk( c))) ; + if ( IsNull( pSrfChunk)) return false ; - nOffs_act = 0 ; // reset indice dei vettori per step precedenti + Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente + bool bMidOutPrec ; // flag per entrata precedente da fuori dal grezzo + BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo + ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente + ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente + vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente + INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente + int nOffs_act = 0 ; + if ( vbChangedPrec[j-1]) { // se lo step attuale è cambiato rispetto al precedente -> Flush info step precedente vMCrv_step_prec.clear() ; @@ -5360,278 +5946,271 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool vvtMidOutPrec.clear() ; } - for ( int cc = 0 ; cc < ( int)pSrfFinal->GetChunkCount() ; ++ cc) { // per ogni suo chunk cc-esimo... + const int MAX_REGS = 50 ; + int nReg = 0 ; // chunk nuovo corrente da svuotare - const int MAX_REGS = 50 ; - int nReg = 0 ; + // ciclo su tutte le regioni che posso ottenere col primo Offset del chunk cc-esimo + while ( nReg < MAX_REGS) { - PtrOwner pSrfChunkFinal(( pSrfFinal->CloneChunk( cc))) ; + // superificie per ingressi ed uscite + PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ; + if( IsNull( pSrfLeanInOut)) + return false ; + + // calcolo la spirale dall'interno all'esterno + PtrOwner pMCrv( CreateCurveComposite()) ; + PtrOwner pRCrv( CreateCurveComposite()) ; + if ( IsNull( pMCrv) || IsNull( pRCrv)) { + m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; + return false ; + } - while ( nReg < MAX_REGS) { - - // superificie per ingressi ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunkFinal)) ; - if( IsNull( pSrfLeanInOut)) + int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale + bool bOutStart ; // flag per entrata da fuori per lo step attuale + bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale + + Point3d ptStart ; // punto iniziale del percorso + Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral) + bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step) + + bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio + + // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente + // ( non c'è bisogno di ricalcolare tutti i percorsi) + if ( ! vbChangedPrec[j-1] && j != 1) { + if ( nOffs_act > ( int)vMCrv_step_prec.size() - 1) + break ; + pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ; + pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ; + nRegTot = vnRegTot_prec[nOffs_act] ; + bMidOut = vbMidOutPrec[nOffs_act] ; + vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ; + vtMidOut = vvtMidOutPrec[nOffs_act] ; + } + else { + // se lucidatura con epicicli + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { + // verifico che parametri lucidatura siano sensati + if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + // modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli + m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; + } + + bool bOptimizedTrap = false ; + + int nInd = 0 ; + if ( ! GetOptCrvIndex( vCrvOrig, j, pSrfChunk, nInd)) + return false ; + + nRegTot = nReg ; + + if ( ! CalcSpiral( pSrfChunk, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv, + vCrvOrig[j-1][nInd], vbChangedPrec[j-1], bOptimizedTrap)) + return false ; + + // se terminate le regioni, esco + if ( pMCrv->GetCurveCount() == 0) + break ; + + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { + // riporto il diametro dell'utensile al valore originale + m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; + // aggiorno i percorsi di svuotatura con epicicli + if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + } + + // memorizzo le curve create e modificate per lo step successivo + vMCrv_step_prec.emplace_back( pMCrv->Clone()) ; + vRCrv_step_prec.emplace_back( pRCrv->Clone()) ; + // memorizzo i Flag per le entrate + vbMidOutPrec.push_back( bMidOut) ; + // memorizzo il numero delle regioni create dal primo Offset + vnRegTot_prec.push_back( nRegTot) ; + // memorizzo il versore di uscita calcolato + vvtMidOutPrec.push_back( vtMidOut) ; + } + + // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo + bOutStart = false ; + int nOutsideRaw = 0 ; + if ( bOptimizedTrap) { + AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; + bOutStart = ( nOutsideRaw > 0) ; + AssignFeedSpiralOpt( 1, pMCrv) ; + AssignFeedForReturnPath( pRCrv) ; + } + + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore + if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { + if ( ! LeadInRawIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; + return false ; + } + } + + // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato) + if ( ! bOptimizedTrap) { + pMCrv->Invert() ; + pRCrv->Invert() ; + } + + // inversione per caso ottimizzato + if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) + pMCrv->Invert() ; + + ++ nReg ; + ++ nOffs_act ; + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + int nMaxRInd = pRCrv->GetCurveCount() - 1 ; + + // determino l'affondamento attuale + double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ; + + // ciclo sulle curve elementari + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pMCrv->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) return false ; - - // calcolo la spirale dall'interno all'esterno - PtrOwner pMCrv( CreateCurveComposite()) ; - PtrOwner pRCrv( CreateCurveComposite()) ; - if ( IsNull( pMCrv) || IsNull( pRCrv)) { - m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; - return false ; - } - - int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale - bool bOutStart ; // flag per entrata da fuori per lo step attuale - bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale - - Point3d ptStart ; // punto iniziale del percorso - Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral) - bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step) - - bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio - - // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente - // ( non c'è bisogno di ricalcolare tutti i percorsi) - if ( ! vbChangedPrec[j-1] && j != 1) { - if ( nOffs_act > ( int)vMCrv_step_prec.size() - 1) - break ; - pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ; - pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ; - nRegTot = vnRegTot_prec[nOffs_act] ; - bMidOut = vbMidOutPrec[nOffs_act] ; - vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ; - vtMidOut = vvtMidOutPrec[nOffs_act] ; - } - else { - // se lucidatura con epicicli - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // verifico che parametri lucidatura siano sensati - if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + // se prima entità + if ( i == 0) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // se primo step, approccio e affondo + if ( j == 1 || vbChangedPrec[j-1] || vSfr[j-2]->GetChunkCount() > 1 || nRegTot > 1) { + // Ricalcolo il punto di attacco sopra al PtStart ( modificato in precedenza dal PtOut) quando : + // 1) sono nel primo Step o ... + // 2) la superificie è diversa da quello dello step precedente o ... + // 3) il numero di chunk allo step precedente è maggiore di 1 o ... + // 4) dal primo offset del chunk cc-esimo ottengo più regioni + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } - // modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli - m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; - } - - bool bOptimizedTrap = false ; - - int nInd = 0 ; - if ( ! GetOptCrvIndex( vCrvOEWithFlags, j, pSrfChunkFinal, nInd)) - return false ; - - nRegTot = nReg ; - - if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv, - vCrvOEWithFlags[j-1][nInd], vbChangedPrec[j-1], bOptimizedTrap)) - return false ; - - // se terminate le regioni, esco - if ( pMCrv->GetCurveCount() == 0) - break ; - - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // riporto il diametro dell'utensile al valore originale - m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; - // aggiorno i percorsi di svuotatura con epicicli - if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + // determino elevazione su inizio attacco + double dStElev = dSink ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { + ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ; + dStElev = -LIO_ELEV_TOL ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { + m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } } - - // memorizzo le curve create e modificate per lo step successivo - vMCrv_step_prec.emplace_back( pMCrv->Clone()) ; - vRCrv_step_prec.emplace_back( pRCrv->Clone()) ; - // memorizzo i Flag per le entrate - vbMidOutPrec.push_back( bMidOut) ; - // memorizzo il numero delle regioni create dal primo Offset - vnRegTot_prec.push_back( nRegTot) ; - // memorizzo il versore di uscita calcolato - vvtMidOutPrec.push_back( vtMidOut) ; - } - - // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo - bOutStart = false ; - int nOutsideRaw = 0 ; - if ( bOptimizedTrap) { - AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; - bOutStart = ( nOutsideRaw > 0) ; - AssignFeedSpiralOpt( 1, pMCrv) ; - AssignFeedForReturnPath( pRCrv) ; - } - - // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore - if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { - if ( ! LeadInRawIsOk()) { - m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false ; - } - } - - // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato) - if ( ! bOptimizedTrap) { - pMCrv->Invert() ; - pRCrv->Invert() ; - } - - // inversione per caso ottimizzato - if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) - pMCrv->Invert() ; - - ++ nReg ; - ++ nOffs_act ; - int nMaxInd = pMCrv->GetCurveCount() - 1 ; - int nMaxRInd = pRCrv->GetCurveCount() - 1 ; - - // ciclo sulle curve elementari - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false ; - // aggiungo affondamento - pCurve->Translate( vVtTrasl[j-1]) ; - // se prima entità - if ( i == 0) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo - if ( j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1 || nRegTot > 1) { - // determino inizio attacco - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false ; - } - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep ; - bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - bool bUhAboveRaw = ! m_bAboveHead && - GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - //if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab) - dStElev = max( dStElev, j * dStep) ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || - GetLeadInType() == POCKET_LI_HELIX || - GetLeadInType() == POCKET_LI_GLIDE) { - ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ; - dStElev = -LIO_ELEV_TOL ; - } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { - m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; - return false ; - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false ; - } - } - // altrimenti solo collegamento - else { - SetFeed( GetStartFeed()) ; - GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } - } - } - // elaborazioni sulla curva corrente - double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; - double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? - GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; - //DrawColoredCrvForFeedTest( pCurve, dFeed) ; - SetFeed( dFeed) ; - if ( pCurve->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCurve) ; - Point3d ptP3 = pLine->GetEnd() ; - //SetFeed( GetFeed()) ; - //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; - } - else if ( pCurve->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCurve) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - //SetFeed( GetFeed()); - //SetFeed( pCurve->GetTempProp( 0 ) / FEED_DIVISOR) ; - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) - return false ; - } - // se ultima entità - if ( i == nMaxInd) { - // se step intermedio - if ( j < nStep && vSrfSliced[j-1]->GetChunkCount() == 1 && !vbChangedPrec[j] && nRegTot == 1) { - // se necessario ritorno all'inizio - if ( nMaxRInd >= 0) { - // copio la curva di ritorno - PtrOwner pRet( pRCrv->Clone()) ; - if ( IsNull( pRet)) - return false ; - // aggiungo affondamento - pRet->Translate( vVtTrasl[j-1]) ; - // se attacco a scivolo, accorcio della lunghezza dell'attacco - if ( GetLeadInType() == POCKET_LI_GLIDE) { - double dLen ; pRet->GetLength( dLen) ; - if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) - if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang)) - pRet->Clear() ; - else - pRet->Clear() ; - } - // emetto - SetFeed( GetFeed()) ; - if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) - return false ; - } - } - // atrimenti ultimo step, uscita e retrazione - else { - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - Point3d ptQ ; - double dEndElev = dElev ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptQ, dEndElev, false)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false ; - } - // aggiungo retrazione - if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; - return false ; - } } } } - } - } + // elaborazioni sulla curva corrente + double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; + double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? + GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; + //DrawColoredCrvForFeedTest( pCurve, dFeed) ; + SetFeed( dFeed) ; + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + //SetFeed( GetFeed()) ; + //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + //SetFeed( GetFeed()); + //SetFeed( pCurve->GetTempProp( 0 ) / FEED_DIVISOR) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità + if ( i == nMaxInd) { + // se step intermedio + if ( j < nStep && vSfr[j-1]->GetChunkCount() == 1 && !vbChangedPrec[j] && nRegTot == 1) { + // se necessario ritorno all'inizio + if ( nMaxRInd >= 0) { + // copio la curva di ritorno + PtrOwner pRet( pRCrv->Clone()) ; + if ( IsNull( pRet)) + return false ; + // aggiungo affondamento + pRet->Translate( vVtTrasl[j-1]) ; + // se attacco a scivolo, accorcio della lunghezza dell'attacco + if ( GetLeadInType() == POCKET_LI_GLIDE) { + double dLen ; pRet->GetLength( dLen) ; + if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) + if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang)) + pRet->Clear() ; + else + pRet->Clear() ; + } + // emetto + SetFeed( GetFeed()) ; + if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) + return false ; + } + } + // atrimenti ultimo step, uscita e retrazione + else { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptQ ; + double dEndElev = dElev ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptQ, dEndElev, false)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione + if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; + return false ; + } + } + } + } + } + } } + return true ; } @@ -5653,9 +6232,9 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt // recupero il versore normale della superificie, ruotandola nel piano XY PtrOwner pSrfToWork( pSrfPock->Clone()) ; if ( IsNull( pSrfToWork) || pSrfToWork->GetChunkCount() == 0) - return false; + return false ; - // porto il Chunk c-esimo nel sistema di riferimento locale (assieme al punto inziale) + // porto il Chunk c-esimo nel sistema di riferimento locale Vector3d vtExtr = pSrfToWork->GetNormVersor() ; Point3d ptCen ; pSrfToWork->GetCentroid( ptCen) ; Frame3d frPocket ; frPocket.Set( ptCen, vtExtr) ; @@ -5698,12 +6277,13 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt PtrOwner pCrvTrap( CreateCurveComposite()) ; if ( IsNull( pCrvTrap)) return false ; - pCrvOEWithFlags->ToLoc( frPocket) ; Frame3d frTrap ; double dPocketSize ; int nBase, nSecondBase ; + pCrvOEWithFlags->ToLoc( frPocket) ; if ( ! GetTrapezoidFromShape( pCrvOEWithFlags, pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase)) return false ; + pCrvOEWithFlags->ToGlob( frPocket) ; if ( pCrvTrap->IsValid()) { pCrvTrap->SetExtrusion( vtExtr) ; if ( nReg == 0) { @@ -5726,77 +6306,77 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt // ciclo di offset verso l'interno const int MAX_ITER = 1000 ; int nIter = 0 ; - ICRVCOMPOPOVECTOR vOffs ; // vettore delle curve di offset + ICRVCOMPOPOVECTOR vOffs ; // vettore delle curve di offset ICRVCOMPOPOVECTOR vOffsFirstCurve ; // curve di primo offset PtrOwner pSrfAct( CloneSurfFlatRegion( pSrfToWork)) ; // regione attuale - PtrOwner pSrfPrec( CloneSurfFlatRegion( pSrfToWork)) ; // regione precedente - if( IsNull( pSrfAct) || IsNull( pSrfPrec) || pSrfAct->GetChunkCount() == 0 || pSrfPrec->GetChunkCount() == 0) + if ( IsNull( pSrfAct) || pSrfAct->GetChunkCount() == 0) return false ; + double dOffsPrec = 0. ; while ( nIter < MAX_ITER) { - // salvo la regione - pSrfPrec.Set( pSrfAct->Clone()) ; - if ( ! pSrfAct->Offset( - dOffs, ICurve::OFF_FILLET)) { - //int nbadOffs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfPrec->Clone()) ; - //m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ; - return false ; - } - if ( ! pSrfAct->IsValid()) { - // VRONOI ? - pSrfAct.Set( pSrfPrec->Clone()) ; - if ( ! pSrfAct->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) { - //int nbadOffs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfPrec->Clone()) ; - //m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ; - return false ; - } + // ricavo la regione piana da VRONI + PtrOwner pSfrOffsVR( pSrfAct->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ; + if ( IsNull( pSfrOffsVR)) + return false ; + if ( ! pSfrOffsVR->IsValid()) { + pSfrOffsVR.Set( pSrfAct->CreateOffsetSurf( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) ; + if ( IsNull( pSfrOffsVR)) + return false ; } - // estraggo il contorno della FlatRegion (ciclo i Chunks e prendo i rispettivi Loops) + // alla prima iterazione svuoto la regione nReg-esima passata alla funzione CalcSpiral if ( nIter == 0) { - PtrOwner pSrfChunknReg( pSrfAct->CloneChunk( nReg)) ; - nReg = pSrfAct->GetChunkCount() ; // modifico nReg per le uscite - if ( IsNull( pSrfChunknReg)) // se supero i chunk ottenuti + PtrOwner pSrfChunknReg( pSfrOffsVR->CloneChunk( nReg)) ; + nReg = pSfrOffsVR->GetChunkCount() ; // aggiorno il nuovo valore delle regioni + if ( IsNull( pSrfChunknReg)) // se supero i chunk ottenuti return true ; - pSrfAct.Set( pSrfChunknReg) ; } - int nChunks = pSrfAct->GetChunkCount() ; + // ricavo il numero di Chunk ottenuti dall'Offset + int nChunks = pSfrOffsVR->GetChunkCount() ; + // ciclo sui Chunks for ( int i = 0 ; i < nChunks ; ++ i) { // per ogni chunk... - int nLoops = pSrfAct->GetLoopCount( i) ; + int nLoops = pSfrOffsVR->GetLoopCount( i) ; for ( int j = 0 ; j < nLoops ; ++ j) { // per ogni loop... - PtrOwner ptoCCBorder( GetCurveComposite( pSrfAct->GetLoop( i, j))) ; - if ( j > 0) // inverto l'orientamento delle curve interne (offset delle isole trovate) - ptoCCBorder->Invert() ; + PtrOwner pCrvCompoBorder( ConvertCurveToComposite( pSfrOffsVR->GetLoop( i, j))) ; + if ( IsNull( pCrvCompoBorder) || ! pCrvCompoBorder->IsValid()) + return false ; + if ( j > 0) // inverto l'orientamento delle curve interne ( offset delle isole trovate) + pCrvCompoBorder->Invert() ; // controllo quali regioni di Offset possono essere sostituite bool bInsert = true ; - if ( ! CheckIfOffsetIsNecessary( ptoCCBorder, dOffs, ( int)vOffs.size(), nIter, vtExtr, bInsert)) + if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, ( int)vOffs.size(), nIter, vtExtr, bInsert)) return false ; - if ( bInsert) { - vOffs.emplace_back( Release( ptoCCBorder)) ; - } - PtrOwner ptoCCExtBorder( GetCurveComposite( pSrfAct->GetLoop( i, j))) ; + if ( bInsert) + vOffs.emplace_back( Release( pCrvCompoBorder)) ; if ( nIter == 0) { // salvo il bordo per i link (non invertiti) - vOffsFirstCurve.emplace_back( Release( ptoCCExtBorder)) ; + PtrOwner pCrvCompoExtBorder( ConvertCurveToComposite( pSfrOffsVR->GetLoop( i, j))) ; + vOffsFirstCurve.emplace_back( Release( pCrvCompoExtBorder)) ; } } } - bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ; + // controllo se serve un raggio più piccolo di svuotatura + bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs - dOffsPrec < dTRad + EPS_ZERO) ; - if ( nChunks > 0) - dOffs = GetSideStep() ; - else if ( ! bSmallRad) { - pSrfAct.Set( pSrfPrec) ; - dOffs = ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ; - } + // se ho trovato dei chunk, allora aggiorno l'Offset per la passata successiva + if ( nChunks > 0) { + // memorizzo il valore di Offset per l'iterazione successiva + dOffsPrec = dOffs ; + dOffs += GetSideStep() ; + } + // se devo usare un Offset più piccolo... + else if ( ! bSmallRad) + dOffs = dOffsPrec + ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ; + // altrimenti ho finito la regione da svuotare... else break ; - ++ nIter ; + ++ nIter ; // aggiorno l'iterazione } // se non ho trovato curve di Offset allora esco @@ -5820,7 +6400,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt for ( int i = 0 ; i < ( int)vOffs.size() && m_Params.m_bInvert ; ++ i) vOffs[i]->Invert() ; - // smusso le curve di offset ( ad eccezione della prima) ICRVCOMPOPOVECTOR vOffsClosedCurves( vOffs.size()) ; // vettore con tutte le curve di Offset Chiuse @@ -5872,7 +6451,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt ptHelp.Set( ptE.x, ptE.y, ptE.z) ; } } - // avendo la curva più vicina ... + // avendo la curva più vicina ... // 1) scambio la curva i con la curva nClosestInd if ( nClosestInd != i + 1) { @@ -8679,12 +9258,12 @@ Pocketing::AddEpicycles( ICurveComposite* pCompo, ICurveComposite * pCrv, ICurve if ( IsNull( pCrvOffs)) return false ; - // verifico se devo resitituire la curva offsettata + // verifico se devo resitituire la curva offsettata if ( pCrvBound) pCrvBound->AddCurve( pCrvOffs->Clone()) ; pCrv->Clear() ; - double dParPrec = 0 ; + double dParPrec = 0 ; for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) { // calcolo distanza epicili specifica per quel tratto @@ -9281,364 +9860,285 @@ Pocketing::GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOV //---------------------------------------------------------------------------- bool -Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, ICRVCOMPOPOVECTOR& vCrvIsl, - double dTool_Diam, double dOffR, double dSideStep, const Vector3d& vtTrasl, - ISurfTriMesh* pStmRaw, bool bInVsOut) +Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvIsl, const double dDiam, + const double dOffR, const double dStep, const ISurfFlatRegion* pSfrLimit) { + // controllo dei parametri + if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid()) + return false ; - // vettore estrusione - Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ; - // calcolo riferimento nel piano della svuotatura - Frame3d frPocket ; - Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; - frPocket.Set( ptStart, vtExtr) ; - // sposto l'inizio a metà del tratto più lungo - AdjustContourStart( pCompo, vCrvIsl) ; // raggio di riferimento per offset - double dOutEdge = 0.5 * dTool_Diam ; + double dOutEdge = 0.5 * dDiam ; if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_ZIGZAG) - dOutEdge = max( dOutEdge, dTool_Diam - dSideStep) ; + dOutEdge = max( dOutEdge, dDiam - dStep) ; double dRad = dOutEdge + dOffR ; - // estraggo parti con proprietà uniforme in un vettore - ICURVEPOVECTOR vpCrvs ; - int nCurrTempProp ; - int nParStart = 0 ; - for ( int i = 0 ; i < pCompo->GetCurveCount() ; ++ i) { - int nTempProp ; - pCompo->GetCurveTempProp( i, nTempProp) ; - if ( i == 0) { - nCurrTempProp = nTempProp ; - nParStart = i ; - } - else if ( nCurrTempProp != nTempProp) { - PtrOwner pCrv( pCompo->CopyParamRange( nParStart, i)) ; - if ( IsNull( pCrv)) - return false ; - pCrv->SetTempProp( nCurrTempProp) ; - pCrv->SetExtrusion( vtExtr) ; - vpCrvs.emplace_back( Release( pCrv)) ; - nCurrTempProp = nTempProp ; - nParStart = i ; - } - } - PtrOwner pCrv( pCompo->CopyParamRange( nParStart, pCompo->GetCurveCount())) ; - if ( IsNull( pCrv)) - return false ; - pCrv->SetTempProp( nCurrTempProp) ; - pCrv->SetExtrusion( vtExtr) ; - vpCrvs.emplace_back( Release( pCrv)) ; - // offsetto del raggio le curve aperte - for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { - if ( vpCrvs[i]->GetTempProp() == 1) { - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( vpCrvs[i], dRad, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - int nCrv_offs = OffsCrv.GetCurveCount() ; - if ( nCrv_offs == 0) { - // GESTIONE SPECIALE DEGLI APERTI CHE OFFSETTATI NON GENERANO CURVE ----------------------------------- - // se un lato aperto è formato da più curve e l'offset di tale composita sparisce, la superficie può - // estendersi fino all'intersezione delle due curva ad amo che determinano l'immagine del tool nello svuotare - // i lati chiusi adiacenti - if ( i == 0) - continue ; - // determino la curva ad amo - Point3d ptEnd ; vpCrvs[i-1]->GetEndPoint( ptEnd) ; - Vector3d vtTg ; vpCrvs[i-1]->GetEndDir( vtTg) ; - Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ; - Point3d ptArc = ptEnd + ( 1.05 * dTool_Diam + 2 * dOffR ) * vtOrt ; - PtrOwner pCrvArc( CreateCurveArc()) ; - if ( IsNull( pCrvArc)) - return false ; - pCrvArc->SetExtrusion( vtExtr) ; - pCrvArc->Set2PVN( ptEnd, ptArc, vtTg, vtExtr) ; - PtrOwner pJCrv( CreateCurveComposite()) ; - if ( IsNull( pJCrv)) - return false ; - pJCrv->AddCurve( Release( pCrvArc)) ; - // determino la curva ad amo - vpCrvs[i+1]->GetStartPoint( ptStart) ; - vpCrvs[i+1]->GetStartDir( vtTg) ; - vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ; - ptArc = ptStart + ( 1.05 * dTool_Diam + 2 * dOffR ) * vtOrt ; - Point3d ptLine = ptArc + 5 * ( 1.05 * dTool_Diam + 2 * dOffR ) * vtTg ; - PtrOwner pJCrv1( CreateCurveComposite()) ; - if ( IsNull( pJCrv1)) - return false ; - pJCrv1->SetExtrusion( vtExtr) ; - pJCrv1->AddPoint( ptLine) ; - pJCrv1->AddLine( ptArc) ; - pJCrv1->AddArcTg( ptStart) ; - // intersezione - pJCrv->ToLoc( frPocket) ; - pJCrv1->ToLoc( frPocket) ; - IntersCurveCurve intCC( *pJCrv, *pJCrv1) ; - pJCrv->ToGlob( frPocket) ; - pJCrv1->ToGlob( frPocket) ; - // classificazione - IntCrvCrvInfo aInfo ; - if ( intCC.GetIntersCount() > 0) { - if ( intCC.GetIntCrvCrvInfo( 0, aInfo)) { - PtrOwner pCrvFinal( CreateCurveComposite()) ; - PtrOwner PJ_Cut( pJCrv->CopyParamRange( 0, aInfo.IciA[0].dU)) ; - PtrOwner PJ1_Cut( pJCrv1->CopyParamRange( aInfo.IciB[0].dU, 1)) ; - //PJ1_Cut->Invert() ; - pCrvFinal->AddCurve( Release( PJ_Cut)) ; - pCrvFinal->AddCurve( Release( PJ1_Cut)) ; - for ( int u = 0 ; u < pCrvFinal->GetCurveCount() ; ++ u) - pCrvFinal->SetCurveTempProp( u, 0, 0) ; - vpCrvs[i].Set( Release( pCrvFinal)) ; - vpCrvs[i]->SetTempProp( 0) ; - } - } - else - continue ; - } - // ----------------------------------------------------------------------------------------- - // GESTIONE SPECIALE DEGLI APERTI CHE GENERANO ISOLE APERTE -------------------------------- - // dall'offset di un lato aperto posso generare più curva composite... - PtrOwner pCrvlonger( OffsCrv.GetLongerCurve()) ; - while ( ! IsNull( pCrvlonger)) { - // le chiuse mi entrano nel vettore delle isole - if ( pCrvlonger->IsClosed() && nCrv_offs > 1) { - PtrOwner pCrvCompo( CreateCurveComposite()) ; - pCrvCompo->AddCurve( Release( pCrvlonger)) ; - for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) - pCrvCompo->SetCurveTempProp( u, 1, 0) ; - vCrvIsl.emplace_back( pCrvCompo->Clone()) ; - } - else // le aperte rimangono tali - vpCrvs[i].Set( Release( pCrvlonger)) ; - pCrvlonger.Set( OffsCrv.GetLongerCurve()) ; - } - // imposto le curva ottenute come aperte ( nuove isole comprese) - PtrOwner pCrvRange( CreateCurveComposite()) ; - pCrvRange->AddCurve( vpCrvs[i]->Clone()) ; - for ( int j = 0 ; j < pCrvRange->GetCurveCount() ; ++ j) - pCrvRange->SetCurveTempProp( j, 1, 0) ; - vpCrvs[i].Set( pCrvRange) ; - vpCrvs[i]->SetTempProp( 1) ; - } - // ----------------------------------------------------------------------------------------- - } - // clono la pCompo - PtrOwner pCompo_clone( CloneCurveComposite( pCompo)) ; - if ( IsNull( pCompo_clone)) + // ricavo i tratti omogenei + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! GetHomogeneousParts( pCrvCompo, vpCrvs)) return false ; - // reinserisco le curve, chiudendo eventuali gap - pCompo->Clear() ; - pCompo->SetExtrusion( vtExtr) ; - bool bOpenCurr = false ; - double dDiam = 1.05 * dTool_Diam + 2 * dOffR ; + // Offset esterno per CurveJ + double dDiamJ = 1.05 * dDiam + 2 * dOffR ; + // NB. 1.05 serve per eccedere leggermente, in modo che il contro-offset della prima curva di svuotatura presenti + // dei piccoli archi tra i chiusi e gli aperti ( in modo da svuotare bene lungo il chiuso) + // curva finale da restituire + PtrOwner pCrvCompo_final( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo_final)) + return false ; + + // parametro iniziale del tratto corrente, sulla curva originale + double dParS = 0. ; + // scorro tutti i tratti omogenei nel vettore for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { - // stato curve - bool bOpenPrev = bOpenCurr ; - bOpenCurr = ( vpCrvs[i]->GetTempProp() != 0) ; - PtrOwner pCrv_Check( vpCrvs[i]->Clone()) ; - // chiudo eventuale gap - if ( i > 0) { - Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ; - Point3d ptStart ; vpCrvs[i]->GetStartPoint( ptStart) ; - if ( ! AreSamePointEpsilon( ptEnd, ptStart, 10 * EPS_SMALL)) { - // se passo da chiuso ad aperto - if ( ! bOpenPrev && bOpenCurr) { - // ----------------------------------------------------------------------------------- - // creazione della curva di bordo mediante Offset dei chiusi ( per ripulire angoli stretti) - PtrOwner pCrvCompo_i( CreateCurveComposite()) ; - pCrvCompo_i->AddCurve( vpCrvs[i]->Clone()) ; - Point3d ptS ; pCompo->GetEndPoint( ptS) ; - Point3d ptE ; vpCrvs[i+1]->GetStartPoint( ptE) ; - PtrOwner pCrvNew( CreateCurveComposite()) ; - if ( ! bInVsOut && - AdjustPathOutsideRawForOpenEdges( pCompo_clone, vCrvIsl, pCrvCompo_i, ptS, ptE, dRad, dDiam, - pCrvNew, vtTrasl, pStmRaw, bInVsOut)) { - vpCrvs[i].Set( Release( pCrvNew)) ; - vpCrvs[i]->GetStartPoint( ptStart) ; - } - // ----------------------------------------------------------------------------------- - // determino la curva ad amo - Vector3d vtTg ; pCompo->GetEndDir( vtTg) ; - Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ; - Point3d ptArc = ptEnd + dDiam * vtOrt ; - //Point3d ptLine = ptArc - 5 * dDiam * vtTg ; - PtrOwner pCrvArc( CreateCurveArc()) ; - if ( IsNull( pCrvArc)) - return false ; - pCrvArc->SetExtrusion( vtExtr) ; - pCrvArc->Set2PVN( ptEnd, ptArc, vtTg, vtExtr) ; - PtrOwner pJCrv( CreateCurveComposite()) ; - if ( IsNull( pJCrv)) - return false ; - pJCrv->AddCurve( Release( pCrvArc)) ; - // assegno alle sue sottocurve la proprietà di curva aperta - for ( int u = 0 ; u < pJCrv->GetCurveCount() ; ++ u) - pJCrv->SetCurveTempProp( u, 1, 0) ; - - // ------- controllo degli overlap tra la curva ad amo e la nuova curva di lato aperto ottenuta ------ - bool bSucc = false ; - PtrOwner pNewCrv( CreateCurveComposite()) ; - PtrOwner pCrvOffsOri( CreateCurveComposite()) ; - pCrvOffsOri->AddCurve( vpCrvs[i]->Clone()) ; - if ( ! CheckOpenEdgeOverlapParts( pJCrv, vpCrvs[i], true, bSucc, pNewCrv)) - return false ; - if ( bSucc)// se "overlap Trovato", modifico la vpCrvs[i] - vpCrvs[i].Set( Release( pNewCrv)) ; - // --------------------------------------------------------------------------------------------------- - - // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta - pJCrv->ToLoc( frPocket) ; - vpCrvs[i]->ToLoc( frPocket) ; - IntersCurveCurve intCC( *pJCrv, *vpCrvs[i]) ; - pJCrv->ToGlob( frPocket) ; - vpCrvs[i]->ToGlob( frPocket) ; - - // taglio opportunamente le curve - bool bFound = false ; - IntCrvCrvInfo aInfo ; - if ( intCC.GetIntersCount() > 0 && !bInVsOut) { - // cerco la prima intersezione che entra nella curva aperta - for ( int j = 0 ; j < intCC.GetIntersCount() ; ++ j) { - if ( intCC.GetIntCrvCrvInfo( j, aInfo) && ( bSucc || aInfo.IciA[0].nPrevTy == ICCT_OUT)) { - bFound = true ; - break ; - } - } - } - if ( bFound) { - if ( ! pJCrv->TrimEndAtParam( aInfo.IciA[0].dU)) - pJCrv->Clear() ; - vpCrvs[i]->TrimStartAtParam( aInfo.IciB[0].dU) ; - pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ; - } - else { - vpCrvs[i].Set( Release( pCrvOffsOri)) ; - pCompo->AddLine( ptStart) ; - pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, bInVsOut ? 0 : 1, 0) ; // segmento aggiunto - if ( bInVsOut) - pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, -99 , 1) ; // linea da controllare - } - } - // se passo da aperto a chiuso - else if ( bOpenPrev && ! bOpenCurr) { - // determino la curva ad amo - Vector3d vtTg ; vpCrvs[i]->GetStartDir( vtTg) ; - Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ; - Point3d ptArc = ptStart + dDiam * vtOrt ; - Point3d ptLine = ptArc + 5 * dDiam * vtTg ; - PtrOwner pJCrv( CreateCurveComposite()) ; - if ( IsNull( pJCrv)) - return false ; - pJCrv->SetExtrusion( vtExtr) ; - pJCrv->AddPoint( ptLine) ; - pJCrv->AddLine( ptArc) ; - pJCrv->AddArcTg( ptStart) ; - PtrOwner pCrvRemoved( pJCrv->RemoveFirstOrLastCurve( false)) ; - if ( IsNull( pCrvRemoved)) - return false ; - - // assegno alle sue sottocurve la proprietà di curva aperta - for ( int u = 0 ; u < pJCrv->GetCurveCount() ; ++ u) - pJCrv->SetCurveTempProp( u, 1, 0) ; - - // prendo le ultime due curve ( sono sufficienti) della composita attuale per verificare l'intersezione - // con la curva ad amo - PtrOwner pLCrv( CreateCurveComposite()) ; - if ( IsNull( pLCrv)) - return false ; - pLCrv->AddCurve( pCompo->GetLastCurve()->Clone()) ; - if ( pCompo->GetCurveCount() >= 2) - pLCrv->AddCurve( pCompo->GetPrevCurve()->Clone(), false) ; - double dUL = pLCrv->GetCurveCount() ; - - // ------- controllo degli overlap tra la curva ad amo e la nuova curva di lato aperto ottenuta ------ - bool bSucc = false ; - PtrOwner pNewCrv( CreateCurveComposite()) ; - PtrOwner pCrvOffsOri( CreateCurveComposite()) ; - pCrvOffsOri->AddCurve( vpCrvs[i]->Clone()) ; - if ( ! CheckOpenEdgeOverlapParts( pJCrv, pLCrv, false, bSucc, pNewCrv)) - return false ; - if ( bSucc) { // se "overlap Trovato", modifico la vpCrvs[i] - pLCrv.Set( pNewCrv->Clone()) ; - double dUS_tmp, dUE_tmp ; - pCompo->GetDomain( dUS_tmp, dUE_tmp) ; - if ( dUE_tmp >= 2) { // sempre ( ho sempre un pezzo di chiuso e il tratto aperto) - pCompo->TrimEndAtParam( dUE_tmp - dUL) ; - pCompo->AddCurve( pLCrv->Clone()) ; - } - } - dUL = pLCrv->GetCurveCount() ; - // --------------------------------------------------------------------------------------------------- - - // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta - pJCrv->ToLoc( frPocket) ; - pLCrv->ToLoc( frPocket) ; - IntersCurveCurve intCC( *pJCrv, *pLCrv) ; - pJCrv->ToGlob( frPocket) ; - pLCrv->ToGlob( frPocket) ; - - // taglio opportunamente le curve - IntCrvCrvInfo aInfo ; - if ( intCC.GetIntCrvCrvInfo( 0, aInfo) && !bInVsOut) { - double dUs, dUe ; pCompo->GetDomain( dUs, dUe) ; - if ( ! pCompo->TrimEndAtParam( dUe - dUL + aInfo.IciB[0].dU)) - pCompo->Clear() ; - if ( ! pJCrv->TrimStartAtParam( aInfo.IciA[0].dU)) - pJCrv->Clear() ; - pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ; - } - else { - vpCrvs[i].Set( Release( pCrvOffsOri)) ; - pCompo->AddLine( ptStart) ; - pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, bInVsOut ? 0 : 1, 0) ; // segmento come curva aperta - if ( bInVsOut) - pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, -99 , 1) ; // linea da controllare - } - } - else { - vpCrvs[i].Set( Release( pCrv_Check)) ; - pCompo->AddLine( ptStart) ; - pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, 1, 0) ; // segmento come curva aperta - if ( bInVsOut) - pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, -99 , 1) ; // linea da controllare - } - } + // recupero la proprietà della curva composita + int nCurrTmpProp = vpCrvs[i]->GetTempProp() ; + // aggiorno i parametri del lato aperto corrente sulla curva originale + double dParE = dParS + 1. * vpCrvs[i]->GetCurveCount() ; + // se aperta + if ( nCurrTmpProp == 1) { + if ( ! AdjustOpenEdge( pCrvCompo, vCrvIsl, dParS, dParE, dRad, dDiamJ, pSfrLimit, vpCrvs[i])) + return false ; } - // aggiungo la curva - pCompo->AddCurve( ::Release( vpCrvs[i]), 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) ; - } - } + // assegno le proprietà di lato Aperto/Chiuso per la curva corrente + for ( int u = 0 ; u < vpCrvs[i]->GetCurveCount() ; ++ u) + vpCrvs[i]->SetCurveTempProp( u, nCurrTmpProp, 0) ; + // aggiungo la curva ricavata + if ( ! pCrvCompo_final->AddCurve( vpCrvs[i]->Clone())) { + Point3d ptH ; vpCrvs[i]->GetStartPoint( ptH) ; + if ( ! pCrvCompo_final->AddLine( ptH) || + ! pCrvCompo_final->SetCurveTempProp( pCrvCompo_final->GetCurveCount() - 1, 1, 0) || + ! pCrvCompo_final->AddCurve( vpCrvs[i]->Clone())) + return false ; } - + // aggiorno + dParS = dParE ; } // non dovrebbe esserci un gap, ma meglio prevenire problemi - pCompo->Close() ; + pCrvCompo_final->Close() ; + // sostituisco + pCrvCompo->Clear() ; + pCrvCompo->CopyFrom( pCrvCompo_final) ; return true ; } -bool +//---------------------------------------------------------------------------- +bool +Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvIsland, + const double dParS, const double dParE, const double dRad, const double dDiamJ, + const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvBorder) +{ + /* parametri : + pCrvCompo -> curva originaria di bordo + vCrvIsland -> vettore delle isole all'interno di pCrvCompo + pCrvOpenOffs -> tratto aperto corrente già Offsettato verso l'esterno + dParS -> parametro sulla pCrvCompo per l'inizio del tratto aperto + dParE -> parametro sulla pCrvCompo per la fine del tratto aperto + dRad -> raggio di Offset per la regione di incidenza + dDiamJ -> ampiezza delle curve a fagiolo per estendere la regione di incidenza + pCrvRes -> curva da restituire ( inizialmente è il tratto aperto sulla pCrvCompo ; + questa curva sarà l'estensione del lato aperto, adattandosi alla geometria + dei chiusi ( non posso vedere solo i chiusi adiacenti all'aperto, devo considerare TUTTI i chiusi + della pCrvCompo + pStmVol -> Volume di svuotatura + pStm_Part -> Part corrente + */ + + // controllo la validtà dei parametri + if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0 || + pCrvBorder == nullptr || ! pCrvBorder->IsValid() || pCrvBorder->GetCurveCount() == 0) + return false ; + + // definisco la regione di incidenza + PtrOwner pSfrInc( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrInc) || + ! CreateSurfFrIncidence( pCrvBorder, dRad, pSfrLimit, pSfrInc)) + return false ; + + // creo un vettore con tutte le curve che potrebbero cadere in parte nella regione di incidenza + ICRVCOMPOPOVECTOR vCrvToCheck ; + for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i) + vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ; // aggiungo le isole + + // se la curva originale non è tutta Aperta -> devo aggiungere anche essa nelle curve da controllare + bool bIsAllOpen = abs( abs( dParE - dParS) - pCrvCompo->GetCurveCount()) < EPS_SMALL ; + if ( ! bIsAllOpen) { + // recupero il tratto di curva prima e dopo dell'aperto corrente + PtrOwner pCompoOther( ConvertCurveToComposite( pCrvCompo->CopyParamRange( dParE, dParS))) ; + if ( IsNull( pCompoOther) || ! pCompoOther->IsValid()) + return false ; + vCrvToCheck.emplace_back( Release( pCompoOther)) ; + } + + // scorro il vettore creato... + for ( int c = 0 ; c < ( int)vCrvToCheck.size() ; ++ c) { + // 1) recupero la curva corrente + PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ; + if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) + return false ; + // 2) classifico la curva con la superficie + CRVCVECTOR ccClass ; + if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) { + // 3) scorro tutte le classificazioni per cercare i tratti interni + for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) { + if ( ccClass[i].nClass == CRVC_IN) { + // 4) se il tratto è interno, recupero tutti i suoi tratti omogenei + PtrOwner pCrvCurrPartIn( ConvertCurveToComposite( pCrvCurr->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; + if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) + return false ; + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! GetHomogeneousParts( pCrvCurrPartIn, vpCrvs)) + return false ; + // 5) considero solo i tratti chiusi + for ( int cl = 0 ; cl < int( vpCrvs.size()) ; ++ cl) { + if ( vpCrvs[cl]->GetTempProp() == 1) + continue ; + // 6) effettuo l'Offset della curva di metà dDiamJ + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + // 7) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti + PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ; + while ( ! IsNull( pOffLongestCrv)) { + // 8) tengo solo le curve che non si chiudono su loro stesse + if ( ! pOffLongestCrv->IsClosed()) { + // 9) creo la regione di incidenza di tale curva ( "Curva a fagiolo") + PtrOwner pSfrBean( GetSurfFlatRegionFromFatCurve( Release( pOffLongestCrv), dDiamJ * 0.5, false, false)) ; + if ( IsNull( pSfrBean) || ! pSfrBean->IsValid()) + return false ; + // inverto se necessario + if ( AreOppositeVectorApprox( pSfrBean->GetNormVersor(), pSfrInc->GetNormVersor())) + pSfrBean->Invert() ; + // 10) aggiorno la regione di incidenza + if ( ! pSfrInc->Add( *pSfrBean)) + return false ; + } + pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; + } + } + } + } + } + else + return false ; + } + + // recupero la curva di bordo del lato aperto corrente + PtrOwner pCrvNewBorder( ConvertCurveToComposite( pSfrInc->GetLoop( 0, 0))) ; + if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid()) + return false ; + // imposto la curva come tutta aperta + for ( int u = 0 ; u < pCrvNewBorder->GetCurveCount() ; ++ u) + pCrvNewBorder->SetCurveTempProp( u, 1, 0) ; + + // se la curva originale era tutta aperta, allora tengo solo il nuovo loop esterno della regione di incidenza + if ( bIsAllOpen) { + // pulisco la curva originale + pCrvBorder->Clear() ; + return pCrvBorder->AddCurve( Release( pCrvNewBorder)) ; + } + + // altrimenti la spezzo il loop della regione di incidenza nei punti iniziali e finali della curva aperta originale + Point3d ptStart ; pCrvBorder->GetStartPoint( ptStart) ; + Point3d ptEnd ; pCrvBorder->GetEndPoint( ptEnd) ; + double dUTrimS, dUTrimE ;; + pCrvNewBorder->GetParamAtPoint( ptStart, dUTrimS, 300 * EPS_SMALL) ; + pCrvNewBorder->GetParamAtPoint( ptEnd, dUTrimE, 300 * EPS_SMALL) ; + // pulisco la curva originale + pCrvBorder->Clear() ; + if ( ! pCrvBorder->AddCurve( pCrvNewBorder->CopyParamRange( dUTrimS, dUTrimE)) || + ! pCrvBorder->IsValid()) + return false ; + + return true ; + +} + +//--------------------------------------------------------------------------- +bool +Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad, const ISurfFlatRegion* pSfrLimit, + ISurfFlatRegion* pSfrInc) +{ + // controllo dei parametri + if ( pCrv == nullptr || ! pCrv->IsValid()) + return false ; + pSfrInc->Clear() ; + + // creo la Fat Curve dalla curva *pCrv + PtrOwner pSfrInc_tmp( GetSurfFlatRegionFromFatCurve( pCrv->Clone(), dRad + EPS_SMALL, false, false)) ; + if ( IsNull( pSfrInc_tmp) || ! pSfrInc_tmp->IsValid()) + return false ; + pSfrInc->CopyFrom( pSfrInc_tmp) ; + + // La regione di incidenza non deve avere un bordo distante dRad dagli estremi del tratto aperto + // per questo motivo, creo due FlatRegion a rettangolo che andrò a sottrarre alla pSfrInc_tmp + + if ( pCrv->IsClosed()) { + pSfrInc->CopyFrom( pSfrInc_tmp) ; + return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ; + } + + // Rettangolo all'inizio + Vector3d vtTanS ; pCrv->GetStartDir( vtTanS) ; + Point3d ptS ; pCrv->GetStartPoint( ptS) ; + Vector3d vtOut = vtTanS ; vtOut.Rotate( Z_AX, -90) ; + PtrOwner pCrvRectSBorder( CreateCurveComposite()) ; + if ( IsNull( pCrvRectSBorder)) + return false ; + pCrvRectSBorder->AddPoint( ptS + ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ; + pCrvRectSBorder->AddLine( ptS + ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ; + pCrvRectSBorder->Close() ; + PtrOwner pSfrRectStart( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrRectStart) || + ! pSfrRectStart->AddExtLoop( Release( pCrvRectSBorder)) || + ! pSfrRectStart->IsValid()) + return false ; + if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectStart->GetNormVersor())) + pSfrRectStart->Invert() ; + + // Rettangolo alla fine + Vector3d vtTanE ; pCrv->GetEndDir( vtTanE) ; + Point3d ptE ; pCrv->GetEndPoint( ptE) ; + vtOut = vtTanE ; vtOut.Rotate( Z_AX, -90) ; + PtrOwner pCrvRectEBorder( CreateCurveComposite()) ; + if ( IsNull( pCrvRectEBorder)) + return false ; + pCrvRectEBorder->AddPoint( ptE + ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ; + pCrvRectEBorder->AddLine( ptE + ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ; + pCrvRectEBorder->Close() ; + PtrOwner pSfrRectEnd( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrRectEnd) || + ! pSfrRectEnd->AddExtLoop( Release( pCrvRectEBorder)) || + ! pSfrRectEnd->IsValid()) + return false ; + if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectEnd->GetNormVersor())) + pSfrRectEnd->Invert() ; + + // alla superficie di incidenza, sottraggo i due rettangoli ricavati + if ( ! pSfrInc->Subtract( *pSfrRectStart) || + ! pSfrInc->Subtract( *pSfrRectEnd)) + return false ; + + // ATTENZIONE ! + // L'algoritmo di allargamento presso i lati aperti è Euristico; io mi estendo a seconda della geometria del + // lato aperto al di fuori del volume di svuotatura... Devo controllare di non rovinare delle zone al di fuori di + // esso ! + if ( ! pSfrInc->Subtract( *pSfrLimit)) + return false ; + + return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ; +} + +//--------------------------------------------------------------------------- +bool Pocketing::CheckOpenEdgeOverlapParts( const ICurve* pCrvJ, const ICurve* pCrvOffBorder, bool bCloseToOpen, bool& bSucc, ICurveComposite* pCrvFinal) { @@ -9767,257 +10267,257 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons const double dDiam, ICurveComposite* pNewCrv, const Vector3d& vtTrasl, ISurfTriMesh* pStmRaw, bool bInVsOut) { - // controllo la validtà dei parametri - if ( pCompo == nullptr || ! pCompo->IsValid() || pCompo->GetCurveCount() == 0 || - pCrvOpenOffs == nullptr || ! pCrvOpenOffs->IsValid() || pCrvOpenOffs->GetCurveCount() == 0) - return false ; + //// controllo la validtà dei parametri + // if ( pCompo == nullptr || ! pCompo->IsValid() || pCompo->GetCurveCount() == 0 || + // pCrvOpenOffs == nullptr || ! pCrvOpenOffs->IsValid() || pCrvOpenOffs->GetCurveCount() == 0) + // return false ; - // recupero l'estrusione della curva di bordo - Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ; + //// recupero l'estrusione della curva di bordo + // Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ; - // -------------- RECUPERO DELLA CURVA ESTERNA PRIMA E DOPO IL LATO APERTO CORRENTE -------------- - double dUTrimS, dUTrimE ; - PtrOwner pCompo_Prec( CloneCurveComposite( pCompo)) ; - PtrOwner pCompo_Succ( CloneCurveComposite( pCompo)) ; - PtrOwner pCrvOpen( CloneCurveComposite( pCompo)) ; - 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() ; - } + //// -------------- RECUPERO DELLA CURVA ESTERNA PRIMA E DOPO IL LATO APERTO CORRENTE -------------- + // double dUTrimS, dUTrimE ; + // PtrOwner pCompo_Prec( CloneCurveComposite( pCompo)) ; + // PtrOwner pCompo_Succ( CloneCurveComposite( pCompo)) ; + // PtrOwner pCrvOpen( CloneCurveComposite( pCompo)) ; + // 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()) ; + // PtrOwner pCompo_noOpenCrv( CloneCurveComposite( pCompo_Succ)) ; + // pCompo_noOpenCrv->AddCurve( pCompo_Prec->Clone()) ; - // recupero i punti e i vettori tangenti iniziali e finali del lato aperto - Point3d ptSTART ; pCrvOpenOffs->GetStartPoint( ptSTART) ; - Point3d ptEND ; pCrvOpenOffs->GetEndPoint( ptEND) ; - Vector3d vtSTART ; pCrvOpenOffs->GetStartDir( vtSTART) ; - Vector3d vtEND ; pCrvOpenOffs->GetEndDir( vtEND) ; + //// recupero i punti e i vettori tangenti iniziali e finali del lato aperto + // Point3d ptSTART ; pCrvOpenOffs->GetStartPoint( ptSTART) ; + // Point3d ptEND ; pCrvOpenOffs->GetEndPoint( ptEND) ; + // Vector3d vtSTART ; pCrvOpenOffs->GetStartDir( vtSTART) ; + // Vector3d vtEND ; pCrvOpenOffs->GetEndDir( vtEND) ; - // -------------- CREAZIONE DELLA REGIONE DI INFLUENZA -------------- - // 1) Creo una copia della curva - PtrOwner pCrvOpen_clone( CloneCurveComposite( pCrvOpen)) ; - if ( IsNull( pCrvOpen_clone) || ! pCrvOpen_clone->IsValid()) - return false ; - // 2) Controllo la lunghezza della curva - double dLen ; - if ( ! pCrvOpen_clone->GetLength( dLen) || dLen < dDiam + EPS_SMALL) - return false ; - // 3) Accorcio l'inizio e la fine del raggio dell'utensile - double dUS, dUE ; - pCrvOpen_clone->GetParamAtLength( dRad, dUS) ; - pCrvOpen_clone->GetParamAtLength( dLen - dRad, dUE) ; - if ( ! pCrvOpen_clone->TrimStartEndAtParam( dUS, dUE)) - pCrvOpen->Clear() ; - bool bOk = true ; - // 4) Creo regione squadrata da questa curva - PtrOwner pSfrInc( GetSurfFlatRegionFromFatCurve( Release( pCrvOpen_clone), dRad , true, false)) ; - if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) { - Point3d ptE ; - pCrvOpenOffs->GetEndPoint( ptE) ; - PtrOwner pCrv_CompoHelp( CreateCurveComposite()) ; - pCrv_CompoHelp->AddCurve( pCrvOpen->Clone()) ; - pCrv_CompoHelp->AddLine( ptE) ; - PtrOwner pCrvOpenOffs_Clone( CloneCurveComposite( pCrvOpenOffs)) ; - pCrvOpenOffs_Clone->Invert() ; - pCrv_CompoHelp->AddCurve( Release( pCrvOpenOffs_Clone)) ; - pCrvOpen->GetStartPoint( ptE) ; - pCrv_CompoHelp->AddLine( ptE) ; - pSfrInc.Set( CreateSurfFlatRegion()) ; - pSfrInc->AddExtLoop( Release( pCrv_CompoHelp)) ; - bOk = false ; - if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) - return false ; - } + //// -------------- CREAZIONE DELLA REGIONE DI INFLUENZA -------------- + // // 1) Creo una copia della curva + // PtrOwner pCrvOpen_clone( CloneCurveComposite( pCrvOpen)) ; + // if ( IsNull( pCrvOpen_clone) || ! pCrvOpen_clone->IsValid()) + // return false ; + // // 2) Controllo la lunghezza della curva + // double dLen ; + // if ( ! pCrvOpen_clone->GetLength( dLen) || dLen < dDiam + EPS_SMALL) + // return false ; + // // 3) Accorcio l'inizio e la fine del raggio dell'utensile + // double dUS, dUE ; + // pCrvOpen_clone->GetParamAtLength( dRad, dUS) ; + // pCrvOpen_clone->GetParamAtLength( dLen - dRad, dUE) ; + // if ( ! pCrvOpen_clone->TrimStartEndAtParam( dUS, dUE)) + // pCrvOpen->Clear() ; + // bool bOk = true ; + // // 4) Creo regione squadrata da questa curva + // PtrOwner pSfrInc( GetSurfFlatRegionFromFatCurve( Release( pCrvOpen_clone), dRad , true, false)) ; + // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) { + // Point3d ptE ; + // pCrvOpenOffs->GetEndPoint( ptE) ; + // PtrOwner pCrv_CompoHelp( CreateCurveComposite()) ; + // pCrv_CompoHelp->AddCurve( pCrvOpen->Clone()) ; + // pCrv_CompoHelp->AddLine( ptE) ; + // PtrOwner pCrvOpenOffs_Clone( CloneCurveComposite( pCrvOpenOffs)) ; + // pCrvOpenOffs_Clone->Invert() ; + // pCrv_CompoHelp->AddCurve( Release( pCrvOpenOffs_Clone)) ; + // pCrvOpen->GetStartPoint( ptE) ; + // pCrv_CompoHelp->AddLine( ptE) ; + // pSfrInc.Set( CreateSurfFlatRegion()) ; + // pSfrInc->AddExtLoop( Release( pCrv_CompoHelp)) ; + // bOk = false ; + // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) + // return false ; + // } - // -------------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA -------------- - // creo un vettore con la pCompo senza lato aperto e le isole contenute al suo interno - ICRVCOMPOPOVECTOR vCrvToCheck ; - vCrvToCheck.emplace_back( pCompo_noOpenCrv->Clone()) ; // la curva esterna in prima posizione - for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i) - vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ; + //// -------------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA -------------- + //// creo un vettore con la pCompo senza lato aperto e le isole contenute al suo interno + // ICRVCOMPOPOVECTOR vCrvToCheck ; + // vCrvToCheck.emplace_back( pCompo_noOpenCrv->Clone()) ; // la curva esterna in prima posizione + // for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i) + // vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ; - // scorro il vettore creato... - for ( int c = 0 ; c < ( int)vCrvToCheck.size() ; ++ c) { - // 1) recupero la curva corrente - PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ; - if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) - continue ; + //// scorro il vettore creato... + // for ( int c = 0 ; c < ( int)vCrvToCheck.size() ; ++ c) { + // // 1) recupero la curva corrente + // PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ; + // if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) + // continue ; - CRVCVECTOR ccClass ; - if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) { - for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) { - if ( ccClass[i].nClass == CRVC_IN) { - // 2) Trovo il tratto di curva interno - PtrOwner pCrvCurrPartIn_( CloneCurveComposite( pCrvCurr)) ; - if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) - return false ; - if ( ! pCrvCurrPartIn_->TrimStartEndAtParam( ccClass[i].dParS, ccClass[i].dParE)) - pCrvCurrPartIn_->Clear() ; - if ( IsNull( pCrvCurrPartIn_) || ! pCrvCurrPartIn_->IsValid()) - continue ; + // CRVCVECTOR ccClass ; + // if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) { + // for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) { + // if ( ccClass[i].nClass == CRVC_IN) { + // // 2) Trovo il tratto di curva interno + // PtrOwner pCrvCurrPartIn_( CloneCurveComposite( pCrvCurr)) ; + // if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) + // return false ; + // if ( ! pCrvCurrPartIn_->TrimStartEndAtParam( ccClass[i].dParS, ccClass[i].dParE)) + // pCrvCurrPartIn_->Clear() ; + // if ( IsNull( pCrvCurrPartIn_) || ! pCrvCurrPartIn_->IsValid()) + // continue ; - // Cerco solo i tratti di curva che sono chiusi - ICURVEPOVECTOR vCrvOpen, vCrvClose ; - if ( ! GetHomogeneousParts( pCrvCurrPartIn_, vCrvOpen, vCrvClose)) - return false ; + // // Cerco solo i tratti di curva che sono chiusi + // ICURVEPOVECTOR vCrvOpen, vCrvClose ; + // if ( ! GetHomogeneousParts( pCrvCurrPartIn_, vCrvOpen, vCrvClose)) + // return false ; - for ( int t_Open = 0 ; t_Open < ( int)vCrvClose.size() ; ++ t_Open) { - PtrOwner pCrvCurrPartIn( CreateCurveComposite()) ; - pCrvCurrPartIn->AddCurve( vCrvClose[t_Open]->Clone()) ; - if ( IsNull( pCrvCurrPartIn) || ! pCrvCurrPartIn->IsValid()) - continue ; - pCrvCurrPartIn->SetExtrusion( vtExtr) ; - PtrOwner pCrvCurrPartIn_Clone( CloneCurveComposite( pCrvCurrPartIn)) ; - if ( IsNull( pCrvCurrPartIn_Clone) || ! pCrvCurrPartIn_Clone->IsValid()) - continue ; + // for ( int t_Open = 0 ; t_Open < ( int)vCrvClose.size() ; ++ t_Open) { + // PtrOwner pCrvCurrPartIn( CreateCurveComposite()) ; + // pCrvCurrPartIn->AddCurve( vCrvClose[t_Open]->Clone()) ; + // if ( IsNull( pCrvCurrPartIn) || ! pCrvCurrPartIn->IsValid()) + // continue ; + // pCrvCurrPartIn->SetExtrusion( vtExtr) ; + // PtrOwner pCrvCurrPartIn_Clone( CloneCurveComposite( pCrvCurrPartIn)) ; + // if ( IsNull( pCrvCurrPartIn_Clone) || ! pCrvCurrPartIn_Clone->IsValid()) + // continue ; - // 3) ricavo il punto iniziale e il punto finale, assieme ai vettori tangenti - Point3d ptS1 ; pCrvCurrPartIn->GetStartPoint( ptS1) ; - Point3d ptE1 ; pCrvCurrPartIn->GetEndPoint( ptE1) ; - Vector3d vtS1 ; pCrvCurrPartIn->GetStartDir( vtS1) ; - Vector3d vtE1 ; pCrvCurrPartIn->GetEndDir( vtE1) ; + // // 3) ricavo il punto iniziale e il punto finale, assieme ai vettori tangenti + // Point3d ptS1 ; pCrvCurrPartIn->GetStartPoint( ptS1) ; + // Point3d ptE1 ; pCrvCurrPartIn->GetEndPoint( ptE1) ; + // Vector3d vtS1 ; pCrvCurrPartIn->GetStartDir( vtS1) ; + // Vector3d vtE1 ; pCrvCurrPartIn->GetEndDir( vtE1) ; - // 4) effettuo l'Offset della curva del diametro del tool - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCrvCurrPartIn_Clone, - dDiam, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } + // // 4) effettuo l'Offset della curva del diametro del tool + // OffsetCurve OffsCrv ; + // if ( ! OffsCrv.Make( pCrvCurrPartIn_Clone, - dDiam, ICurve::OFF_FILLET)) { + // m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + // return false ; + // } - // 5) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti - PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ; - while ( ! IsNull( pOffLongestCrv)) { - // 6) escludo le curve che si chiudono su se stesse dopo l'Offset - if ( ! pOffLongestCrv->IsClosed()) { - // 7) trasformo la curva in composita - PtrOwner pCompoPartInOffs( CreateCurveComposite()) ; - pCompoPartInOffs->AddCurve( pOffLongestCrv->Clone()) ; - // 8) creo due archi che collegano i punti iniziali e finali della curva originale e di quella con offset - PtrOwner pArcS( CreateCurveArc()) ; - PtrOwner pArcE( CreateCurveArc()) ; - if ( IsNull( pArcS) || IsNull( pArcE)) - return false ; - Point3d ptS2 ; pCompoPartInOffs->GetStartPoint( ptS2) ; - Point3d ptE2 ; pCompoPartInOffs->GetEndPoint( ptE2) ; - Vector3d vtS2 ; pCompoPartInOffs->GetStartDir( vtS2) ; - Vector3d vtE2 ; pCompoPartInOffs->GetEndDir( vtE2) ; - pArcS->Set2PVN( ptS1, ptS2, - vtS1, - vtExtr) ; - pArcE->Set2PVN( ptE2, ptE1, vtE2, - vtExtr) ; - // 9) creo il loop esterno della regione da aggiungere - PtrOwner pCrvExtBorder( CreateCurveComposite()) ; - if ( IsNull( pCrvExtBorder)) - return false ; - pCrvExtBorder->AddCurve( Release( pArcS)) ; // primo tratto lineare - pCrvExtBorder->AddCurve( Release( pCompoPartInOffs)) ; // tratto di offset - pCrvExtBorder->AddCurve( Release( pArcE)) ; // secondo tratto lineare - pCrvCurrPartIn->Invert() ; // inversione del tratto interno - pCrvExtBorder->AddCurve( pCrvCurrPartIn->Clone()) ; // aggiunta del tratto interno + // // 5) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti + // PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ; + // while ( ! IsNull( pOffLongestCrv)) { + // // 6) escludo le curve che si chiudono su se stesse dopo l'Offset + // if ( ! pOffLongestCrv->IsClosed()) { + // // 7) trasformo la curva in composita + // PtrOwner pCompoPartInOffs( CreateCurveComposite()) ; + // pCompoPartInOffs->AddCurve( pOffLongestCrv->Clone()) ; + // // 8) creo due archi che collegano i punti iniziali e finali della curva originale e di quella con offset + // PtrOwner pArcS( CreateCurveArc()) ; + // PtrOwner pArcE( CreateCurveArc()) ; + // if ( IsNull( pArcS) || IsNull( pArcE)) + // return false ; + // Point3d ptS2 ; pCompoPartInOffs->GetStartPoint( ptS2) ; + // Point3d ptE2 ; pCompoPartInOffs->GetEndPoint( ptE2) ; + // Vector3d vtS2 ; pCompoPartInOffs->GetStartDir( vtS2) ; + // Vector3d vtE2 ; pCompoPartInOffs->GetEndDir( vtE2) ; + // pArcS->Set2PVN( ptS1, ptS2, - vtS1, - vtExtr) ; + // pArcE->Set2PVN( ptE2, ptE1, vtE2, - vtExtr) ; + // // 9) creo il loop esterno della regione da aggiungere + // PtrOwner pCrvExtBorder( CreateCurveComposite()) ; + // if ( IsNull( pCrvExtBorder)) + // return false ; + // pCrvExtBorder->AddCurve( Release( pArcS)) ; // primo tratto lineare + // pCrvExtBorder->AddCurve( Release( pCompoPartInOffs)) ; // tratto di offset + // pCrvExtBorder->AddCurve( Release( pArcE)) ; // secondo tratto lineare + // pCrvCurrPartIn->Invert() ; // inversione del tratto interno + // pCrvExtBorder->AddCurve( pCrvCurrPartIn->Clone()) ; // aggiunta del tratto interno - if ( pCrvExtBorder->IsClosed()) { - // 9) Creo la nuova regione da aggiungere a quella di influenza - PtrOwner pSfrExpan( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrExpan)) - return false ; - pSfrExpan->AddExtLoop( Release( pCrvExtBorder)) ; - if ( pSfrExpan->IsValid()) { - if ( AreOppositeVectorApprox( pSfrExpan->GetNormVersor(), vtExtr)) - pSfrExpan->Invert() ; + // if ( pCrvExtBorder->IsClosed()) { + // // 9) Creo la nuova regione da aggiungere a quella di influenza + // PtrOwner pSfrExpan( CreateSurfFlatRegion()) ; + // if ( IsNull( pSfrExpan)) + // return false ; + // pSfrExpan->AddExtLoop( Release( pCrvExtBorder)) ; + // if ( pSfrExpan->IsValid()) { + // if ( AreOppositeVectorApprox( pSfrExpan->GetNormVersor(), vtExtr)) + // pSfrExpan->Invert() ; - // ----------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA ---------- - PtrOwner pSfrInc_c( CloneSurfFlatRegion( pSfrInc)) ; - if ( IsNull( pSfrInc_c)) - return false ; - if ( pSfrInc_c->Subtract( *pSfrExpan)) { - pSfrInc->Clear() ; - for ( int cc = 0 ; cc < pSfrInc_c->GetChunkCount() ; ++ cc) { - CRVCVECTOR ccClass_cc ; - PtrOwner pSfrChunk_cc( pSfrInc_c->CloneChunk( cc)) ; - if ( pSfrChunk_cc->GetCurveClassification( *pCrvOpen, EPS_SMALL, ccClass_cc)) { - for ( int jj = 0 ; jj < ( int)ccClass_cc.size() ; ++ jj) { - if ( ccClass_cc[jj].nClass == CRVC_IN) { - if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) - pSfrInc.Set( pSfrChunk_cc->Clone()) ; - else - pSfrInc->Add( *pSfrChunk_cc) ; - break ; - } - } - } - } - } - pSfrInc->Add( *pSfrExpan) ; - } - } - } - pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; - } - } - } - } - } - else - return false ; - } + // // ----------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA ---------- + // PtrOwner pSfrInc_c( CloneSurfFlatRegion( pSfrInc)) ; + // if ( IsNull( pSfrInc_c)) + // return false ; + // if ( pSfrInc_c->Subtract( *pSfrExpan)) { + // pSfrInc->Clear() ; + // for ( int cc = 0 ; cc < pSfrInc_c->GetChunkCount() ; ++ cc) { + // CRVCVECTOR ccClass_cc ; + // PtrOwner pSfrChunk_cc( pSfrInc_c->CloneChunk( cc)) ; + // if ( pSfrChunk_cc->GetCurveClassification( *pCrvOpen, EPS_SMALL, ccClass_cc)) { + // for ( int jj = 0 ; jj < ( int)ccClass_cc.size() ; ++ jj) { + // if ( ccClass_cc[jj].nClass == CRVC_IN) { + // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) + // pSfrInc.Set( pSfrChunk_cc->Clone()) ; + // else + // pSfrInc->Add( *pSfrChunk_cc) ; + // break ; + // } + // } + // } + // } + // } + // pSfrInc->Add( *pSfrExpan) ; + // } + // } + // } + // pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; + // } + // } + // } + // } + // } + // else + // return false ; + // } - // recupero il Grezzo e sottraggo tutto ciò che sta nella regione - if ( pStmRaw != nullptr) { - bool bIsChanged ; - if ( m_bIntersRaw) { - PtrOwner pSrfInc_Copy( CloneSurfFlatRegion( pSfrInc)) ; - int nChunkBef = pSfrInc->GetChunkCount() ; - if ( ! IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false, false)) - return false ; - if ( IsNull( pSfrInc) || ! pSfrInc->IsValid() || pSfrInc->GetChunkCount() == 0 || - ( nChunkBef < pSfrInc->GetChunkCount())) - pSfrInc.Set( pSrfInc_Copy) ; - } - } - if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) - return false ; + //// recupero il Grezzo e sottraggo tutto ciò che sta nella regione + // if ( pStmRaw != nullptr) { + // bool bIsChanged ; + // if ( m_bIntersRaw) { + // PtrOwner pSrfInc_Copy( CloneSurfFlatRegion( pSfrInc)) ; + // int nChunkBef = pSfrInc->GetChunkCount() ; + // if ( ! IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false, false)) + // return false ; + // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid() || pSfrInc->GetChunkCount() == 0 || + // ( nChunkBef < pSfrInc->GetChunkCount())) + // pSfrInc.Set( pSrfInc_Copy) ; + // } + // } + // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) + // return false ; - // RECUPERO DELLA CURVA DI BORDO ESTERNA DA AGGIUNGERE ALLA SVUOTATURA - PtrOwner pCrvNewBorder( GetCurveComposite( pSfrInc->GetLoop( 0, 0))) ; - if ( IsNull( pCrvNewBorder)) - return false ; + //// RECUPERO DELLA CURVA DI BORDO ESTERNA DA AGGIUNGERE ALLA SVUOTATURA + // PtrOwner pCrvNewBorder( GetCurveComposite( pSfrInc->GetLoop( 0, 0))) ; + // if ( IsNull( pCrvNewBorder)) + // return false ; - 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() ; - } + // 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() ; + // } - pNewCrv->Clear() ; - pNewCrv->AddCurve( Release( pCrvNewBorder)) ; - for ( int u = 0 ; u < pNewCrv->GetCurveCount() ; ++ u) - pNewCrv->SetCurveTempProp( u, 1, 0) ; + // pNewCrv->Clear() ; + // pNewCrv->AddCurve( Release( pCrvNewBorder)) ; + // for ( int u = 0 ; u < pNewCrv->GetCurveCount() ; ++ u) + // pNewCrv->SetCurveTempProp( u, 1, 0) ; return true ; } @@ -10029,8 +10529,8 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& { // se cerco semplicemente il tratto lineare chiuso più lungo ... if ( ! bOrder) { - // cerco il tratto lineare più lungo che non sia aperto - int i = 0 ; + // la priorità è essagnata ai tratti lineari chiusi + int i = 0 ; // <--- indice della curva corrente int nMax = - 1 ; double dLenMax = 0 ; const ICurve* pCrv = pCompo->GetFirstCurve() ; @@ -10043,7 +10543,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& ++ i ; pCrv = pCompo->GetNextCurve() ; } - // se non trovato o troppo corto, cerco il tratto generico più lungo + // se non trovato o troppo corto, cerco il tratto chiuso più lungo in generale if ( nMax < 0 || dLenMax < 2 * m_TParams.m_dDiam) { i = 0 ; pCrv = pCompo->GetFirstCurve() ; @@ -10057,15 +10557,26 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& pCrv = pCompo->GetNextCurve() ; } } + // controllo che il tratto chiuso più lungo trovato sia sufficientemente lungo + if ( dLenMax < 10 * EPS_SMALL) { + // se troppo piccolo allora lo imposto aperto + pCompo->SetCurveTempProp( nMax, 0, 1) ; + // spezzo la curva nel primo tratto aperto sufficientemente lungo + for ( int u = 0 ; u < pCompo->GetCurveCount() ; ++ u) { + double dLen ; pCompo->GetCurve( u)->GetLength( dLen) ; + if ( dLen > 10 * EPS_SMALL) { + nMax = u ; + continue ; + } + } + } - const ICurve* pCrvClone( pCompo->GetCurve( nMax)) ; - double dPar ; - if ( GetParamForPtStartOnEdge( pCrvClone, pCompo, vCrvIsl, dPar)) - pCompo->ChangeStartPoint( nMax + dPar) ; - else - // sposto inizio a metà - if ( nMax >= 0) - pCompo->ChangeStartPoint( nMax + 0.5) ; + // se non trovato, imposto il punto iniziale a mentà del primo tratto + if ( nMax == -1) { + pCompo->ChangeStartPoint( 0.5) ; + return true ; + } + 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 @@ -10982,7 +11493,9 @@ Pocketing::ProjectStmOnPlane( const ISurfTriMesh* pStmAbove, const Plane3d plPoc else // se Up non valida -> copio pSfrProj->CopyFrom( pSfrUp1) ; } - + // se nessuna delle due è valida, non ritorno nulla + if ( ! pSfrUp->IsValid() && ! pSfrUp1->IsValid()) + return true ; return pSfrProj != nullptr && pSfrProj->IsValid() && pSfrProj->GetChunkCount() != 0 ; } @@ -11246,349 +11759,350 @@ bool Pocketing::AdjustFakeOpenEdges( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSfrOrig, const ISurfTriMesh* pStmRaw, const Vector3d vtTrasl, bool bFromProj) { - //if ( ! bFromProj) + // //if ( ! bFromProj) + // return true ; + + //// controllo dei parametri + // if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) + // return false ; + // if ( pStmRaw == nullptr) // se non c'è grezzo... + // return true ; + + //// 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 ; + // Vector3d vtNorm = pSfrOrig->GetNormVersor() ; // normale + // if ( vtNorm.IsSmall()) + // return false ; + // 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 ; + //// ------------------------------------------------------------------------------------------- + + // // ------- 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 + // ICRVCOMPOPOVECTOR 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 + + // 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 ; + // 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)) ; + // } + // } + ////------------------------------------------------------------------------------------------------------------- + + //// ---------------- 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( *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) ; + + // if ( ! bFromProj) { + // //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)) ; + // } + + //// =============================================================================================================== + + //// 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) ; + // if ( ! bFromProj) { + // //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)) ; + // } + + + // bool bLoopL_isChanged = false ; // flag di indetificazione di un Fake Open Edge + // const int MAX_TRY = 10 ; // numero di raffinamenti massimi + // int nCont = -1 ; // contatore dei raffinamenti + //// OGNI VOLTA CHE INDIVIDUO UN LATO APERTO CHE IN REALTA' DEVE ESSERE CHIUSO, QUEST'ULTIMO VIENE IMPOSTATO COME + //// CHIUSO ( FACENDO COSI', PERO', NON GARANTISCO CHE I LATI APERTI CORRETTI IN PRECEDENZA SIANO ANCORA + //// LATI APERTI CORRETTI, DEVO RIPETERE L'ALGORITMO....) + + //// calcolo la regione critica + // PtrOwner pSrf_critica( CloneSurfFlatRegion( pSrf_Proj)) ; + // pSrf_critica->Subtract( *pSrfOrig_clone) ; + + // do { + // ++nCont ; + // bLoopL_isChanged = false ; + // // creo i tratti di curva omogonei ( tratti uniformi chiusi o aperti) + // ICURVEPOVECTOR vCrvOpen ; ICURVEPOVECTOR vCrvClose ; + // if ( ! GetHomogeneousParts( pCrvCompo_Clone_Trasl, vCrvOpen, vCrvClose, true)) + // return false ; + + // // scorro tutti i tratti aperti + // for ( int t = 0 ; t < ( int)vCrvOpen.size() && !bLoopL_isChanged ; ++ t) { + // // 1) ricavo il tratto aperto t-esimo + // PtrOwner pCrvCompo_t_Open( CreateCurveComposite()) ; + // if ( IsNull( pCrvCompo_t_Open)) + // return false ; + // pCrvCompo_t_Open->AddCurve( vCrvOpen[t]->Clone()) ; + + // // 2) Ricavo il paramtro iniziale e finale sulla curva originale + // Point3d ptS ; + // double dU_jump ; + // pCrvCompo_t_Open->GetStartPoint( ptS) ; + // pCrvCompo_Clone_Trasl->GetParamAtPoint( ptS, dU_jump) ; + + // // 3) effettuo l'Offset + // pCrvCompo_t_Open->SetExtrusion( vtExtr) ; + // OffsetCurve OffsCrv ; + // if ( ! OffsCrv.Make( pCrvCompo_t_Open, m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec + m_dOffsetR_Prec : + // 0.5 * m_TParams.m_dDiam + GetOffsR(), ICurve::OFF_FILLET)) + // return false ; + // // -> se Offset non preduce nessuna curva, allora passo al tratto successivo + // int nCrv_offs = OffsCrv.GetCurveCount() ; + // if ( nCrv_offs == 0) + // continue ; + // PtrOwner pCrvlonger( OffsCrv.GetLongerCurve()) ; + // // -> per ogni curva di Offset + // while ( ! IsNull( pCrvlonger) && ! bLoopL_isChanged) { + // if ( ! pCrvlonger->IsClosed() || nCrv_offs == 1) { // salto le curve "chiuse" ( a meno che non sia l'unica) + // // 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 + // PtrOwner pCrv_tOpen_Offs( CloneCurveComposite( pCrvlonger)) ; + // if ( IsNull( pCrv_tOpen_Offs) || ! pCrv_tOpen_Offs->IsValid()) + // return false ; + // if ( ! bFromProj) { + // //int YE = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_tOpen_Offs->Clone()) ; + // //m_pGeomDB->SetMaterial( YE, YELLOW) ; + // } + // CRVCVECTOR ccClass ; + // if ( pSrf_critica->GetCurveClassification( *pCrv_tOpen_Offs, 10 * EPS_SMALL, ccClass)) { + // for ( int j = 0 ; j < ( int)ccClass.size() && ! bLoopL_isChanged ; ++ j) { + // if ( ccClass[j].nClass == CRVC_IN) { + // // 7) se trovo una parte interna alla proeizione, allora devo ricavare la parte di curva + // // originaria ( della pCrvCompo_t_Open) relativa a questo tratto e impostarla come aperta + // // ... ricavo il tratto di curva + // int nRealDUS = ( int)floor( ccClass[j].dParS) ; + // int nRealDUE = ( int)floor( ccClass[j].dParE) ; + // if ( ceil( ccClass[j].dParS) - ccClass[j].dParS < 50 * EPS_SMALL) + // nRealDUS = ( int)ceil( ccClass[j].dParS) ; + // if ( abs( ccClass[j].dParE - ceil( ccClass[j].dParE)) < 50 * EPS_SMALL) + // nRealDUE = ( int)ceil( ccClass[j].dParE) ; + + // // modifico il range per evitare indici errati + // nRealDUS = Clamp( nRealDUS, 0, pCrv_tOpen_Offs->GetCurveCount() - 1) ; + // nRealDUE = Clamp( nRealDUE, 0, pCrv_tOpen_Offs->GetCurveCount() - 1) ; + + // // recupero la TempProp 0 della curva ( mi indica l'offset da chi deriva) + // int nCrvStart ; pCrv_tOpen_Offs->GetCurveTempProp( nRealDUS, nCrvStart, 0) ; + // -- nCrvStart ; + // int nCrvEnd ; pCrv_tOpen_Offs->GetCurveTempProp( nRealDUE, nCrvEnd, 0) ; + // -- nCrvEnd ; + + // double dUStart ; // parametro relativo iniziale + // double dUEnd ; // parametro relativo finale + + // PtrOwner CIAO( pCrv_tOpen_Offs->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; + // if ( ! bFromProj) { + // //int YEs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, CIAO->Clone()) ; + // //m_pGeomDB->SetMaterial( YEs, Color( 0.95, 0.0, 0.63, 1.0)) ; + // } + + // // ------------------------------ PARAMETRO FINALE ----------------------------------- + // // se non sono su un raccordo ... + // if ( nCrvEnd != -1) { + // dUEnd = max( 0., min( nCrvEnd + ( ccClass[j].dParE - ( int)ccClass[j].dParE), + // 1. * pCrv_tOpen_Offs->GetCurveCount())) ; + // if ( abs(( ccClass[j].dParE) - pCrv_tOpen_Offs->GetCurveCount()) < 50 * EPS_SMALL) + // ++ dUEnd ; + // } + // // se sono su un raccordo ... + // else { + // // cerco la prima tra le curve successive che non sia un raccordo + // int nCrvToAsk = ( int)( min( ccClass[j].dParE + 1, 1. * ( pCrv_tOpen_Offs->GetCurveCount() - 1))) ; + // int nCrvEndReal ; + // do { + // pCrv_tOpen_Offs->GetCurveTempProp( nCrvToAsk, nCrvEndReal, 0) ; + // ++ nCrvToAsk ; + // nCrvEndReal = min( nCrvEndReal, pCrv_tOpen_Offs->GetCurveCount()) - 1 ; + // } while ( nCrvEndReal == -1 && nCrvToAsk < pCrv_tOpen_Offs->GetCurveCount()) ; + // if ( nCrvEndReal == -1) // se non trovo -> tratto finale in proporzione + // dUEnd = pCrv_tOpen_Offs->GetCurveCount() - 1 + ( ccClass[j].dParE - ( int)ccClass[j].dParE) ; + // else { // seleziono il pezzo iniziale del primo tratto trovato ... + // const ICurve* pCrv_forLen = pCrv_tOpen_Offs->GetCurve( nCrvEndReal) ; + // double dLen = EPS_SMALL ; + // double dLenMin = 0.05 * ( m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec : 0.5 * m_TParams.m_dDiam) ; + // double dParShift = 1. ; + // if ( pCrv_forLen != nullptr && pCrv_forLen->GetLength( dLen) && dLen > dLenMin) + // dParShift = dLenMin / dLen ; + // dUEnd = max( 0.0 , min( nCrvEndReal + 0 + dParShift, 1. * ( pCrv_tOpen_Offs->GetCurveCount() - 1))) ; + // } + // } + // // ------------------------------ PARAMETRO INZIALE ----------------------------------- + // // se non sono su un raccordo ... + // if ( nCrvStart != -1) + // dUStart = max( 0., min( nCrvStart + ( ccClass[j].dParS - ( int)ccClass[j].dParS), + // 1. * ( pCrv_tOpen_Offs->GetCurveCount()))) ; + // // se sono su un raccordo ... + // else { + // int nCrvToAsk = ( int)( max( 0., ccClass[j].dParS - 1)) ; + // int nCrvStartReal ; + // do { + // pCrv_tOpen_Offs->GetCurveTempProp( nCrvToAsk, nCrvStartReal, 0) ; + // --nCrvToAsk ; + // nCrvStartReal = min( nCrvStartReal, pCrv_tOpen_Offs->GetCurveCount()) - 1 ; + // } while ( nCrvStartReal == -1 && nCrvStartReal > 0) ; + // if ( nCrvStartReal == -1) // se non trovo -> tratto iniziale in proporzione + // nCrvStartReal = ccClass[j].dParS - ( int)ccClass[j].dParS ; + // else { // seleziono il pezzo finale del primo tratto trovato ... + // const ICurve* pCrv_forLen = pCrv_tOpen_Offs->GetCurve( nCrvStartReal) ; + // double dLen = EPS_SMALL ; + // double dLenMin = 0.05 * ( m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec : 0.5 * m_TParams.m_dDiam) ; + // double dParShift = 1. ; + // if ( pCrv_forLen != nullptr && pCrv_forLen->GetLength( dLen) && dLen > dLenMin) + // dParShift = dLenMin / dLen ; + // dUStart = max( 0., min( nCrvStartReal + 1 - dParShift, 1. * pCrv_tOpen_Offs->GetCurveCount())) ; + // } + // } + + // // controllo... + // if ( dUStart > dUEnd) + // swap( dUStart, dUEnd) ; + + // // tratto precente + // PtrOwner pCrv_Bef( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; + // // tratto successivo + // PtrOwner pCrv_Aft( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; + // // tratto corrente da mettere come chiuso + // PtrOwner pCrv_curr_Close( CreateCurveComposite()) ; + // // nuova curva... + // PtrOwner pCrv_New( CreateCurveComposite()) ; + + // if ( IsNull( pCrv_Bef) || ! pCrv_Bef->IsValid() || + // IsNull( pCrv_Aft) || ! pCrv_Aft->IsValid() || + // IsNull( pCrv_curr_Close) || + // IsNull( pCrv_New)) + // return false ; + + // // ricomposizione con tagli per non perdere le proprietà appena impostate + // dUStart += dU_jump ; + // dUEnd += dU_jump ; + // if ( ! pCrv_Bef->TrimEndAtParam( dUStart)) + // pCrv_Bef->Clear() ; + // if ( ! pCrv_Aft->TrimStartAtParam( dUEnd)) + // pCrv_Aft->Clear() ; + // if ( ! IsNull( pCrv_Bef) && pCrv_Bef->IsValid()) + // pCrv_New->AddCurve( Release( pCrv_Bef)) ; + // pCrv_curr_Close->AddCurve( pCrvCompo_Clone_Trasl->CopyParamRange( dUStart, dUEnd)) ; + + // for ( int uu = 0 ; uu < pCrv_curr_Close->GetCurveCount() ; ++ uu) { + // pCrv_curr_Close->SetCurveTempProp( uu, 0, 0) ; // chiusa + // pCrv_curr_Close->SetCurveTempProp( uu, -99, 1) ; // chiusa + // } + + // if ( ! IsNull( pCrv_curr_Close) && pCrv_curr_Close->IsValid()) + // pCrv_New->AddCurve( Release( pCrv_curr_Close)) ; + // else + // // se la nuova curva chiusa è piccola, la ignoro... + // continue ; + + // if ( ! IsNull( pCrv_Aft) && pCrv_Aft->IsValid()) + // pCrv_New->AddCurve( Release( pCrv_Aft)) ; + // // controllo validità della curva, altrimenti non modifico nulla ed esco ( Avrò un chiuso) + // if ( ! IsNull( pCrv_New) && pCrv_New->IsValid() && pCrv_New->IsClosed()) { + // pCrvCompo_Clone_Trasl.Set( Release( pCrv_New)) ; + // bLoopL_isChanged = true ; + // } + // } + // } + // } + // } + // pCrvlonger.Set( OffsCrv.GetLongerCurve()) ; + // } + // } + // } while ( bLoopL_isChanged && nCont < MAX_TRY) ; + + //// sotituisco la curva originale, traslo e miglioro... + // if ( ! IsNull( pCrvCompo_Clone_Trasl) && pCrvCompo_Clone_Trasl->IsValid() && pCrvCompo_Clone_Trasl->IsClosed()) { + // pCrvCompo_Clone_Trasl->Translate( - vtTrasl) ; + // pCrvCompo_Clone_Trasl->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; + // pCrvCompo->Clear() ; + // pCrvCompo->CopyFrom( pCrvCompo_Clone_Trasl) ; + // pCrvCompo->SetExtrusion( vtExtr) ; + // pCrvCompo->SetThickness( dThick) ; + // pCrvCompo->SetTempProp( nTmpProp0, 0) ; + // pCrvCompo->SetTempProp( nTmpProp1, 1) ; + // } + + // return pCrvCompo != nullptr && pCrvCompo->IsValid() && pCrvCompo->GetCurveCount() > 0 ; return true ; - - // controllo dei parametri - if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) - return false ; - if ( pStmRaw == nullptr) // se non c'è grezzo... - return true ; - - // 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 ; - Vector3d vtNorm = pSfrOrig->GetNormVersor() ; // normale - if ( vtNorm.IsSmall()) - return false ; - 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 ; - // ------------------------------------------------------------------------------------------- - - // ------- 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 - ICRVCOMPOPOVECTOR 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 - - 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 ; - 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)) ; - } - } - //------------------------------------------------------------------------------------------------------------- - - // ---------------- 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( *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) ; - - if ( ! bFromProj) { - //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)) ; - } - - // =============================================================================================================== - - // 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) ; - if ( ! bFromProj) { - //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)) ; - } - - - bool bLoopL_isChanged = false ; // flag di indetificazione di un Fake Open Edge - const int MAX_TRY = 10 ; // numero di raffinamenti massimi - int nCont = -1 ; // contatore dei raffinamenti - // OGNI VOLTA CHE INDIVIDUO UN LATO APERTO CHE IN REALTA' DEVE ESSERE CHIUSO, QUEST'ULTIMO VIENE IMPOSTATO COME - // CHIUSO ( FACENDO COSI', PERO', NON GARANTISCO CHE I LATI APERTI CORRETTI IN PRECEDENZA SIANO ANCORA - // LATI APERTI CORRETTI, DEVO RIPETERE L'ALGORITMO....) - - // calcolo la regione critica - PtrOwner pSrf_critica( CloneSurfFlatRegion( pSrf_Proj)) ; - pSrf_critica->Subtract( *pSrfOrig_clone) ; - - do { - ++nCont ; - bLoopL_isChanged = false ; - // creo i tratti di curva omogonei ( tratti uniformi chiusi o aperti) - ICURVEPOVECTOR vCrvOpen ; ICURVEPOVECTOR vCrvClose ; - if ( ! GetHomogeneousParts( pCrvCompo_Clone_Trasl, vCrvOpen, vCrvClose, true)) - return false ; - - // scorro tutti i tratti aperti - for ( int t = 0 ; t < ( int)vCrvOpen.size() && !bLoopL_isChanged ; ++ t) { - // 1) ricavo il tratto aperto t-esimo - PtrOwner pCrvCompo_t_Open( CreateCurveComposite()) ; - if ( IsNull( pCrvCompo_t_Open)) - return false ; - pCrvCompo_t_Open->AddCurve( vCrvOpen[t]->Clone()) ; - - // 2) Ricavo il paramtro iniziale e finale sulla curva originale - Point3d ptS ; - double dU_jump ; - pCrvCompo_t_Open->GetStartPoint( ptS) ; - pCrvCompo_Clone_Trasl->GetParamAtPoint( ptS, dU_jump) ; - - // 3) effettuo l'Offset - pCrvCompo_t_Open->SetExtrusion( vtExtr) ; - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCrvCompo_t_Open, m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec + m_dOffsetR_Prec : - 0.5 * m_TParams.m_dDiam + GetOffsR(), ICurve::OFF_FILLET)) - return false ; - // -> se Offset non preduce nessuna curva, allora passo al tratto successivo - int nCrv_offs = OffsCrv.GetCurveCount() ; - if ( nCrv_offs == 0) - continue ; - PtrOwner pCrvlonger( OffsCrv.GetLongerCurve()) ; - // -> per ogni curva di Offset - while ( ! IsNull( pCrvlonger) && ! bLoopL_isChanged) { - if ( ! pCrvlonger->IsClosed() || nCrv_offs == 1) { // salto le curve "chiuse" ( a meno che non sia l'unica) - // 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 - PtrOwner pCrv_tOpen_Offs( CloneCurveComposite( pCrvlonger)) ; - if ( IsNull( pCrv_tOpen_Offs) || ! pCrv_tOpen_Offs->IsValid()) - return false ; - if ( ! bFromProj) { - //int YE = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_tOpen_Offs->Clone()) ; - //m_pGeomDB->SetMaterial( YE, YELLOW) ; - } - CRVCVECTOR ccClass ; - if ( pSrf_critica->GetCurveClassification( *pCrv_tOpen_Offs, 10 * EPS_SMALL, ccClass)) { - for ( int j = 0 ; j < ( int)ccClass.size() && ! bLoopL_isChanged ; ++ j) { - if ( ccClass[j].nClass == CRVC_IN) { - // 7) se trovo una parte interna alla proeizione, allora devo ricavare la parte di curva - // originaria ( della pCrvCompo_t_Open) relativa a questo tratto e impostarla come aperta - // ... ricavo il tratto di curva - int nRealDUS = ( int)floor( ccClass[j].dParS) ; - int nRealDUE = ( int)floor( ccClass[j].dParE) ; - if ( ceil( ccClass[j].dParS) - ccClass[j].dParS < 50 * EPS_SMALL) - nRealDUS = ( int)ceil( ccClass[j].dParS) ; - if ( abs( ccClass[j].dParE - ceil( ccClass[j].dParE)) < 50 * EPS_SMALL) - nRealDUE = ( int)ceil( ccClass[j].dParE) ; - - // modifico il range per evitare indici errati - nRealDUS = Clamp( nRealDUS, 0, pCrv_tOpen_Offs->GetCurveCount() - 1) ; - nRealDUE = Clamp( nRealDUE, 0, pCrv_tOpen_Offs->GetCurveCount() - 1) ; - - // recupero la TempProp 0 della curva ( mi indica l'offset da chi deriva) - int nCrvStart ; pCrv_tOpen_Offs->GetCurveTempProp( nRealDUS, nCrvStart, 0) ; - -- nCrvStart ; - int nCrvEnd ; pCrv_tOpen_Offs->GetCurveTempProp( nRealDUE, nCrvEnd, 0) ; - -- nCrvEnd ; - - double dUStart ; // parametro relativo iniziale - double dUEnd ; // parametro relativo finale - - PtrOwner CIAO( pCrv_tOpen_Offs->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; - if ( ! bFromProj) { - //int YEs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, CIAO->Clone()) ; - //m_pGeomDB->SetMaterial( YEs, Color( 0.95, 0.0, 0.63, 1.0)) ; - } - - // ------------------------------ PARAMETRO FINALE ----------------------------------- - // se non sono su un raccordo ... - if ( nCrvEnd != -1) { - dUEnd = max( 0., min( nCrvEnd + ( ccClass[j].dParE - ( int)ccClass[j].dParE), - 1. * pCrv_tOpen_Offs->GetCurveCount())) ; - if ( abs(( ccClass[j].dParE) - pCrv_tOpen_Offs->GetCurveCount()) < 50 * EPS_SMALL) - ++ dUEnd ; - } - // se sono su un raccordo ... - else { - // cerco la prima tra le curve successive che non sia un raccordo - int nCrvToAsk = ( int)( min( ccClass[j].dParE + 1, 1. * ( pCrv_tOpen_Offs->GetCurveCount() - 1))) ; - int nCrvEndReal ; - do { - pCrv_tOpen_Offs->GetCurveTempProp( nCrvToAsk, nCrvEndReal, 0) ; - ++ nCrvToAsk ; - nCrvEndReal = min( nCrvEndReal, pCrv_tOpen_Offs->GetCurveCount()) - 1 ; - } while ( nCrvEndReal == -1 && nCrvToAsk < pCrv_tOpen_Offs->GetCurveCount()) ; - if ( nCrvEndReal == -1) // se non trovo -> tratto finale in proporzione - dUEnd = pCrv_tOpen_Offs->GetCurveCount() - 1 + ( ccClass[j].dParE - ( int)ccClass[j].dParE) ; - else { // seleziono il pezzo iniziale del primo tratto trovato ... - const ICurve* pCrv_forLen = pCrv_tOpen_Offs->GetCurve( nCrvEndReal) ; - double dLen = EPS_SMALL ; - double dLenMin = 0.05 * ( m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec : 0.5 * m_TParams.m_dDiam) ; - double dParShift = 1. ; - if ( pCrv_forLen != nullptr && pCrv_forLen->GetLength( dLen) && dLen > dLenMin) - dParShift = dLenMin / dLen ; - dUEnd = max( 0.0 , min( nCrvEndReal + 0 + dParShift, 1. * ( pCrv_tOpen_Offs->GetCurveCount() - 1))) ; - } - } - // ------------------------------ PARAMETRO INZIALE ----------------------------------- - // se non sono su un raccordo ... - if ( nCrvStart != -1) - dUStart = max( 0., min( nCrvStart + ( ccClass[j].dParS - ( int)ccClass[j].dParS), - 1. * ( pCrv_tOpen_Offs->GetCurveCount()))) ; - // se sono su un raccordo ... - else { - int nCrvToAsk = ( int)( max( 0., ccClass[j].dParS - 1)) ; - int nCrvStartReal ; - do { - pCrv_tOpen_Offs->GetCurveTempProp( nCrvToAsk, nCrvStartReal, 0) ; - --nCrvToAsk ; - nCrvStartReal = min( nCrvStartReal, pCrv_tOpen_Offs->GetCurveCount()) - 1 ; - } while ( nCrvStartReal == -1 && nCrvStartReal > 0) ; - if ( nCrvStartReal == -1) // se non trovo -> tratto iniziale in proporzione - nCrvStartReal = ccClass[j].dParS - ( int)ccClass[j].dParS ; - else { // seleziono il pezzo finale del primo tratto trovato ... - const ICurve* pCrv_forLen = pCrv_tOpen_Offs->GetCurve( nCrvStartReal) ; - double dLen = EPS_SMALL ; - double dLenMin = 0.05 * ( m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec : 0.5 * m_TParams.m_dDiam) ; - double dParShift = 1. ; - if ( pCrv_forLen != nullptr && pCrv_forLen->GetLength( dLen) && dLen > dLenMin) - dParShift = dLenMin / dLen ; - dUStart = max( 0., min( nCrvStartReal + 1 - dParShift, 1. * pCrv_tOpen_Offs->GetCurveCount())) ; - } - } - - // controllo... - if ( dUStart > dUEnd) - swap( dUStart, dUEnd) ; - - // tratto precente - PtrOwner pCrv_Bef( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; - // tratto successivo - PtrOwner pCrv_Aft( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; - // tratto corrente da mettere come chiuso - PtrOwner pCrv_curr_Close( CreateCurveComposite()) ; - // nuova curva... - PtrOwner pCrv_New( CreateCurveComposite()) ; - - if ( IsNull( pCrv_Bef) || ! pCrv_Bef->IsValid() || - IsNull( pCrv_Aft) || ! pCrv_Aft->IsValid() || - IsNull( pCrv_curr_Close) || - IsNull( pCrv_New)) - return false ; - - // ricomposizione con tagli per non perdere le proprietà appena impostate - dUStart += dU_jump ; - dUEnd += dU_jump ; - if ( ! pCrv_Bef->TrimEndAtParam( dUStart)) - pCrv_Bef->Clear() ; - if ( ! pCrv_Aft->TrimStartAtParam( dUEnd)) - pCrv_Aft->Clear() ; - if ( ! IsNull( pCrv_Bef) && pCrv_Bef->IsValid()) - pCrv_New->AddCurve( Release( pCrv_Bef)) ; - pCrv_curr_Close->AddCurve( pCrvCompo_Clone_Trasl->CopyParamRange( dUStart, dUEnd)) ; - - for ( int uu = 0 ; uu < pCrv_curr_Close->GetCurveCount() ; ++ uu) { - pCrv_curr_Close->SetCurveTempProp( uu, 0, 0) ; // chiusa - pCrv_curr_Close->SetCurveTempProp( uu, -99, 1) ; // chiusa - } - - if ( ! IsNull( pCrv_curr_Close) && pCrv_curr_Close->IsValid()) - pCrv_New->AddCurve( Release( pCrv_curr_Close)) ; - else - // se la nuova curva chiusa è piccola, la ignoro... - continue ; - - if ( ! IsNull( pCrv_Aft) && pCrv_Aft->IsValid()) - pCrv_New->AddCurve( Release( pCrv_Aft)) ; - // controllo validità della curva, altrimenti non modifico nulla ed esco ( Avrò un chiuso) - if ( ! IsNull( pCrv_New) && pCrv_New->IsValid() && pCrv_New->IsClosed()) { - pCrvCompo_Clone_Trasl.Set( Release( pCrv_New)) ; - bLoopL_isChanged = true ; - } - } - } - } - } - pCrvlonger.Set( OffsCrv.GetLongerCurve()) ; - } - } - } while ( bLoopL_isChanged && nCont < MAX_TRY) ; - - // sotituisco la curva originale, traslo e miglioro... - if ( ! IsNull( pCrvCompo_Clone_Trasl) && pCrvCompo_Clone_Trasl->IsValid() && pCrvCompo_Clone_Trasl->IsClosed()) { - pCrvCompo_Clone_Trasl->Translate( - vtTrasl) ; - pCrvCompo_Clone_Trasl->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; - pCrvCompo->Clear() ; - pCrvCompo->CopyFrom( pCrvCompo_Clone_Trasl) ; - pCrvCompo->SetExtrusion( vtExtr) ; - pCrvCompo->SetThickness( dThick) ; - pCrvCompo->SetTempProp( nTmpProp0, 0) ; - pCrvCompo->SetTempProp( nTmpProp1, 1) ; - } - - return pCrvCompo != nullptr && pCrvCompo->IsValid() && pCrvCompo->GetCurveCount() > 0 ; } //---------------------------------------------------------------------------- @@ -11596,191 +12110,192 @@ bool Pocketing::ModifySurfByOpenEdge( ISurfFlatRegion* pSrf, ICRVCOMPOPOVECTOR& vCrvOEFlags, const Vector3d& vtTrasl, ISurfTriMesh* pStmRaw) { - // controllo dei parametri - if ( pSrf == nullptr || ! pSrf->IsValid() || pSrf->GetChunkCount() == 0) - return false ; - - // creo la superifcie da restituire... - PtrOwner pSrfFinal( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfFinal)) - return false ; + //// controllo dei parametri + // if ( pSrf == nullptr || ! pSrf->IsValid() || pSrf->GetChunkCount() == 0) + // return false ; + // + //// creo la superifcie da restituire... + // PtrOwner pSrfFinal( CreateSurfFlatRegion()) ; + // if ( IsNull( pSrfFinal)) + // return false ; - // salvo un vettore contenente tutte le isole - ICRVCOMPOPOVECTOR vCrvToTIsl ; + //// salvo un vettore contenente tutte le isole + // ICRVCOMPOPOVECTOR vCrvToTIsl ; - // vettore temporaneo di curve originale - ICRVCOMPOPOVECTOR vCrvOrig_tmp ; + //// vettore temporaneo di curve originale + // ICRVCOMPOPOVECTOR vCrvOrig_tmp ; - // per ogni Chunck della superificie ottenuta... - for ( int c = 0 ; c < pSrf->GetChunkCount() ; ++ c) { + //// per ogni Chunck della superificie ottenuta... + // for ( int c = 0 ; c < pSrf->GetChunkCount() ; ++ c) { - // 1) salvo la curva esterna -> per casi ottimizzati - PtrOwner pCrvEL( ConvertCurveToComposite( pSrf->GetLoop( c, 0))) ; - if ( IsNull( pCrvEL)) - return false ; - vCrvOEFlags.emplace_back( Release( pCrvEL)) ; + // // 1) salvo la curva esterna -> per casi ottimizzati + // PtrOwner pCrvEL( ConvertCurveToComposite( pSrf->GetLoop( c, 0))) ; + // if ( IsNull( pCrvEL)) + // return false ; + // vCrvOEFlags.emplace_back( Release( pCrvEL)) ; - // 2) creo un vettore con le isole del Chunk ( e uno con le isole ammissibili) - ICRVCOMPOPOVECTOR vCrvIsl ; - for ( int l = 1 ; l < pSrf->GetLoopCount( c) ; ++ l) { - PtrOwner pCrvIL( ConvertCurveToComposite( pSrf->GetLoop( c, l))) ; - if ( IsNull( pCrvIL)) - return false ; - vCrvIsl.emplace_back( Release( pCrvIL)) ; - } - ICRVCOMPOPOVECTOR vCrvModIsland ; + // // 2) creo un vettore con le isole del Chunk ( e uno con le isole ammissibili) + // ICRVCOMPOPOVECTOR vCrvIsl ; + // for ( int l = 1 ; l < pSrf->GetLoopCount( c) ; ++ l) { + // PtrOwner pCrvIL( ConvertCurveToComposite( pSrf->GetLoop( c, l))) ; + // if ( IsNull( pCrvIL)) + // return false ; + // vCrvIsl.emplace_back( Release( pCrvIL)) ; + // } + // ICRVCOMPOPOVECTOR vCrvModIsland ; - // 3) Allargo la superificie ( curva esterna) mediante i lati aperti - bool bSomeOpen = false ; - int nProp0 = -1 ; - PtrOwner pCrvExt( ConvertCurveToComposite( pSrf->GetLoop( c, 0))) ; - for ( int u = 0 ; u < pCrvExt->GetCurveCount() && !bSomeOpen ; ++ u) { - if ( pCrvExt->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) - bSomeOpen = true ; - } - if ( bSomeOpen) { // se trovo dei lati aperti - // 3.1) sistemo la superificie - if ( ! AdjustContourWithOpenEdges( pCrvExt, vCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, - m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), - m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), - vtTrasl, pStmRaw)) { - m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; - return false ; - } - } + // // 3) Allargo la superificie ( curva esterna) mediante i lati aperti + // bool bSomeOpen = false ; + // int nProp0 = -1 ; + // PtrOwner pCrvExt( ConvertCurveToComposite( pSrf->GetLoop( c, 0))) ; + // for ( int u = 0 ; u < pCrvExt->GetCurveCount() && !bSomeOpen ; ++ u) { + // if ( pCrvExt->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) + // bSomeOpen = true ; + // } + // if ( bSomeOpen) { // se trovo dei lati aperti + // // 3.1) sistemo la superificie + // if ( ! AdjustContourWithOpenEdges( pCrvExt, vCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, + // m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), + // m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), + // vtTrasl, pStmRaw)) { + // m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + // return false ; + // } + // } - // 4) aggiungo le curve alla nuova superificie - // NB Controllo se la curva si Autointerseca... alcuni lati aperti potrebbero mergiarsi - SelfIntersCurve SiC( *pCrvExt) ; - if ( SiC.GetIntersCount() > 0) { - // creo la flatRegion - SurfFlatRegionByContours SfrBC ; - SfrBC.AddCurve( pCrvExt->Clone()) ; - PtrOwner pSfrHelp( SfrBC.GetSurf()) ; - if ( IsNull( pSfrHelp) || ! pSfrHelp->IsValid()) - return false ; - pCrvExt.Set( ConvertCurveToComposite( pSfrHelp->GetLoop( 0, 0))) ; - for ( int l = 1 ; l < pSfrHelp->GetLoopCount( 0) ; ++ l) { - PtrOwner pCrvClosedIsland( ConvertCurveToComposite( pSfrHelp->GetLoop( 0, l))) ; - if ( IsNull( pCrvClosedIsland) || ! pCrvClosedIsland->IsValid()) - return false ; - for ( int u = 0 ; u < pCrvClosedIsland->GetCurveCount() ; ++ u) - pCrvClosedIsland->SetCurveTempProp( u, 0, 0) ; - vCrvIsl.emplace_back( Release( pCrvClosedIsland)) ; - } - } - // 5) Controllo i bordi delle isole ottenute e modifico quelli in cui sono presenti lati aperti - for ( int i = 0 ; i < ( int)vCrvIsl.size() ; ++ i) { - bSomeOpen = false ; - nProp0 = -1 ; - PtrOwner pCrvIsl( ConvertCurveToComposite( vCrvIsl[i]->Clone())) ; - for ( int u = 0 ; u < pCrvIsl->GetCurveCount() ; ++ u) { - if ( pCrvIsl->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) - bSomeOpen = true ; - } - if ( bSomeOpen) { // se trovo dei lati aperti - // 5.1) se l'isola è tutta aperta e trascurabile la talgo - bool bRemove = false ; - if ( ! CheckForRemovingIsland( pCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam, - bRemove)) - return false ; - if ( bRemove) // se si può trascurare passo alla successiva - continue ; - // 5.2) sistemo la superificie - ICRVCOMPOPOVECTOR vCrvNULL ; - if ( ! AdjustContourWithOpenEdges( pCrvIsl, vCrvNULL, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, - m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), - m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), vtTrasl, pStmRaw)) { - m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; - return false ; - } - } - vCrvModIsland.emplace_back( pCrvIsl->Clone()) ; - vCrvToTIsl.emplace_back( pCrvIsl->Clone()) ; - } - // 6) Creo la nuova superificie da svuotare - // NB. I vari chunk, dopo esseresi allargati nei lati aperti, potrebbero unirsi tra loro in alcuni parti... - SurfFlatRegionByContours SfrBC_Def ; - SfrBC_Def.AddCurve( Release( pCrvExt)) ; - for ( int i = 0 ; i < ( int)vCrvModIsland.size() ; ++ i) - SfrBC_Def.AddCurve( Release( vCrvModIsland[i])) ; + // // 4) aggiungo le curve alla nuova superificie + // // NB Controllo se la curva si Autointerseca... alcuni lati aperti potrebbero mergiarsi + // SelfIntersCurve SiC( *pCrvExt) ; + // if ( SiC.GetIntersCount() > 0) { + // // creo la flatRegion + // SurfFlatRegionByContours SfrBC ; + // SfrBC.AddCurve( pCrvExt->Clone()) ; + // PtrOwner pSfrHelp( SfrBC.GetSurf()) ; + // if ( IsNull( pSfrHelp) || ! pSfrHelp->IsValid()) + // return false ; + // pCrvExt.Set( ConvertCurveToComposite( pSfrHelp->GetLoop( 0, 0))) ; + // for ( int l = 1 ; l < pSfrHelp->GetLoopCount( 0) ; ++ l) { + // PtrOwner pCrvClosedIsland( ConvertCurveToComposite( pSfrHelp->GetLoop( 0, l))) ; + // if ( IsNull( pCrvClosedIsland) || ! pCrvClosedIsland->IsValid()) + // return false ; + // for ( int u = 0 ; u < pCrvClosedIsland->GetCurveCount() ; ++ u) + // pCrvClosedIsland->SetCurveTempProp( u, 0, 0) ; + // vCrvIsl.emplace_back( Release( pCrvClosedIsland)) ; + // } + // } + // // 5) Controllo i bordi delle isole ottenute e modifico quelli in cui sono presenti lati aperti + // for ( int i = 0 ; i < ( int)vCrvIsl.size() ; ++ i) { + // bSomeOpen = false ; + // nProp0 = -1 ; + // PtrOwner pCrvIsl( ConvertCurveToComposite( vCrvIsl[i]->Clone())) ; + // for ( int u = 0 ; u < pCrvIsl->GetCurveCount() ; ++ u) { + // if ( pCrvIsl->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) + // bSomeOpen = true ; + // } + // if ( bSomeOpen) { // se trovo dei lati aperti + // // 5.1) se l'isola è tutta aperta e trascurabile la talgo + // bool bRemove = false ; + // if ( ! CheckForRemovingIsland( pCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam, + // bRemove)) + // return false ; + // if ( bRemove) // se si può trascurare passo alla successiva + // continue ; + // // 5.2) sistemo la superificie + // ICRVCOMPOPOVECTOR vCrvNULL ; + // if ( ! AdjustContourWithOpenEdges( pCrvIsl, vCrvNULL, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, + // m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), + // m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), vtTrasl, pStmRaw)) { + // m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + // return false ; + // } + // } + // vCrvModIsland.emplace_back( pCrvIsl->Clone()) ; + // vCrvToTIsl.emplace_back( pCrvIsl->Clone()) ; + // } + // // 6) Creo la nuova superificie da svuotare + // // NB. I vari chunk, dopo esseresi allargati nei lati aperti, potrebbero unirsi tra loro in alcuni parti... + // SurfFlatRegionByContours SfrBC_Def ; + // SfrBC_Def.AddCurve( Release( pCrvExt)) ; + // for ( int i = 0 ; i < ( int)vCrvModIsland.size() ; ++ i) + // SfrBC_Def.AddCurve( Release( vCrvModIsland[i])) ; - PtrOwner pSrfHelp_( SfrBC_Def.GetSurf()) ; + // PtrOwner pSrfHelp_( SfrBC_Def.GetSurf()) ; - if ( pSrfFinal->GetChunkCount() == 0) - pSrfFinal.Set( pSrfHelp_) ; - else - pSrfFinal->Add( *pSrfHelp_) ; - } - // ora che ho la superificie finale, questa potrebbe contenere più isole rispetto a quelle originarie - // ( Se la superficie, dopo intersezione e proeizione, è formata da c-Chunks e questi una volta allargati presso - // i lati aperti dalla funzione AdjustContourWithOpenEdges si sono uniti -> possono esseresi formate ulteriori isole - // aperte...) => devo togliere le isole opportune ) - SurfFlatRegionByContours pSrf_noFakeIslands ; - for ( int c = 0 ; c < pSrfFinal->GetChunkCount() ; ++ c) { - // aggiungo il bordo esterno - pSrf_noFakeIslands.AddCurve( pSrfFinal->GetLoop( c, 0)) ; - for ( int l = 1 ; l < pSrfFinal->GetLoopCount( c) ; ++ l) { - PtrOwner pCrvCompo( ConvertCurveToComposite( pSrfFinal->GetLoop( c, l))) ; - if ( IsNull( pCrvCompo)) - return false ; - bool bIsRealIsland = false ; - // se l'isola attuale ha una curva che fa overlap con una delle isole originarie allora la tengo ... - for ( int is = 0 ; is < ( int)vCrvToTIsl.size() && !bIsRealIsland ; ++ is) { - for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && !bIsRealIsland ; ++ u) { - const ICurve* pCrv_u = pCrvCompo->GetCurve( u) ; - if ( pCrv_u == nullptr) - return false ; - int nStat = -1 ; - if ( CheckSimpleOverlap( pCrv_u, vCrvToTIsl[is], nStat, 50 * EPS_SMALL) && nStat == 1) - bIsRealIsland = true ; - } - } - // ... ( quindi la inserisco) - if ( bIsRealIsland) - pSrf_noFakeIslands.AddCurve( Release( pCrvCompo)) ; - // altrimenti controllo se è necessaria - else { - bool bRemove = false ; - if ( ! CheckForRemovingIsland( pCrvCompo, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam, - bRemove)) - return false ; - if ( ! bRemove) - pSrf_noFakeIslands.AddCurve( Release( pCrvCompo)) ; - } - } - } - // aggiorno la superficie originaria - pSrfFinal.Set( pSrf_noFakeIslands.GetSurf()) ; - if ( IsNull( pSrfFinal)) - return false ; + // if ( pSrfFinal->GetChunkCount() == 0) + // pSrfFinal.Set( pSrfHelp_) ; + // else + // pSrfFinal->Add( *pSrfHelp_) ; + // } + //// ora che ho la superificie finale, questa potrebbe contenere più isole rispetto a quelle originarie + //// ( Se la superficie, dopo intersezione e proeizione, è formata da c-Chunks e questi una volta allargati presso + //// i lati aperti dalla funzione AdjustContourWithOpenEdges si sono uniti -> possono esseresi formate ulteriori isole + //// aperte...) => devo togliere le isole opportune ) + // SurfFlatRegionByContours pSrf_noFakeIslands ; + // for ( int c = 0 ; c < pSrfFinal->GetChunkCount() ; ++ c) { + // // aggiungo il bordo esterno + // pSrf_noFakeIslands.AddCurve( pSrfFinal->GetLoop( c, 0)) ; + // for ( int l = 1 ; l < pSrfFinal->GetLoopCount( c) ; ++ l) { + // PtrOwner pCrvCompo( ConvertCurveToComposite( pSrfFinal->GetLoop( c, l))) ; + // if ( IsNull( pCrvCompo)) + // return false ; + // bool bIsRealIsland = false ; + // // se l'isola attuale ha una curva che fa overlap con una delle isole originarie allora la tengo ... + // for ( int is = 0 ; is < ( int)vCrvToTIsl.size() && !bIsRealIsland ; ++ is) { + // for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && !bIsRealIsland ; ++ u) { + // const ICurve* pCrv_u = pCrvCompo->GetCurve( u) ; + // if ( pCrv_u == nullptr) + // return false ; + // int nStat = -1 ; + // if ( CheckSimpleOverlap( pCrv_u, vCrvToTIsl[is], nStat, 50 * EPS_SMALL) && nStat == 1) + // bIsRealIsland = true ; + // } + // } + // // ... ( quindi la inserisco) + // if ( bIsRealIsland) + // pSrf_noFakeIslands.AddCurve( Release( pCrvCompo)) ; + // // altrimenti controllo se è necessaria + // else { + // bool bRemove = false ; + // if ( ! CheckForRemovingIsland( pCrvCompo, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam, + // bRemove)) + // return false ; + // if ( ! bRemove) + // pSrf_noFakeIslands.AddCurve( Release( pCrvCompo)) ; + // } + // } + // } + //// aggiorno la superficie originaria + // pSrfFinal.Set( pSrf_noFakeIslands.GetSurf()) ; + // if ( IsNull( pSrfFinal)) + // return false ; - // ricavo le curve originali per i casi ottimizzati - for ( int c = 0 ; c < pSrfFinal->GetChunkCount() ; ++ c) { - int nChunk_contained = 0 ; - int nIndex = -1 ; - PtrOwner pSfrChunk( pSrfFinal->CloneChunk( c)) ; - if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid()) - return false ; - for ( int x = 0 ; x < int( vCrvOrig_tmp.size()) ; ++x) { - CRVCVECTOR ccClass ; - if ( pSfrChunk->GetCurveClassification( *vCrvOrig_tmp[x], EPS_SMALL, ccClass)) { - bool bIsOut = false ; - for ( int j = 0 ; j < int( ccClass.size()) && !bIsOut ; ++ j) - if ( ccClass[j].nClass == CRVC_OUT) - bIsOut = true ; - if ( ! bIsOut) { - ++ nChunk_contained ; - nIndex = x ; - } + //// ricavo le curve originali per i casi ottimizzati + // for ( int c = 0 ; c < pSrfFinal->GetChunkCount() ; ++ c) { + // int nChunk_contained = 0 ; + // int nIndex = -1 ; + // PtrOwner pSfrChunk( pSrfFinal->CloneChunk( c)) ; + // if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid()) + // return false ; + // for ( int x = 0 ; x < int( vCrvOrig_tmp.size()) ; ++x) { + // CRVCVECTOR ccClass ; + // if ( pSfrChunk->GetCurveClassification( *vCrvOrig_tmp[x], EPS_SMALL, ccClass)) { + // bool bIsOut = false ; + // for ( int j = 0 ; j < int( ccClass.size()) && !bIsOut ; ++ j) + // if ( ccClass[j].nClass == CRVC_OUT) + // bIsOut = true ; + // if ( ! bIsOut) { + // ++ nChunk_contained ; + // nIndex = x ; + // } - } - } - } + // } + // } + // } - pSrf->Clear() ; - pSrf->CopyFrom( pSrfFinal) ; - return pSrf->IsValid() && pSrf->GetChunkCount() > 0 ; + // pSrf->Clear() ; + // pSrf->CopyFrom( pSrfFinal) ; + // return pSrf->IsValid() && pSrf->GetChunkCount() > 0 ; + return true ; } @@ -12503,263 +13018,263 @@ bool Pocketing::GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSrfOrig, const int nStep, double dStep, const Vector3d& vtTrasl, ISurfFlatRegion* pSfrRawBoxProj) { - // controllo dei parametri - if ( pSfr == nullptr || ! pSfr->IsValid() || pSfr->GetChunkCount() == 0 || - pStmRaw == nullptr || ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0) - return false ; + //// controllo dei parametri + // if ( pSfr == nullptr || ! pSfr->IsValid() || pSfr->GetChunkCount() == 0 || + // pStmRaw == nullptr || ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0) + // return false ; - // copio la superficie in globale - PtrOwner pSfrPock( CloneSurfFlatRegion( pSfr)) ; - if ( IsNull( pSfrPock)) - return false ; + //// copio la superficie in globale + // PtrOwner pSfrPock( CloneSurfFlatRegion( pSfr)) ; + // if ( IsNull( pSfrPock)) + // return false ; - // ------------------------- CREAZIONE DEI PIANI DI TAGLIO NEAR, FAR E DI PROIEZIONE -------------------------------------- - // recupero il piano di proiezione ( piano che contiene la flatRegion) - PtrOwner pCrv( ConvertCurveToComposite( pSfrPock->GetLoop( 0, 0))) ; - if ( IsNull( pCrv)) - return false ; - Plane3d plNear, plFar, plProj ; - Point3d ptCen ; - if ( ! pCrv->GetCentroid( ptCen)) // punto - if ( ! pCrv->GetStartPoint( ptCen)) - return false ; - Vector3d vtNorm = pSfrPock->GetNormVersor() ; // normale - if ( vtNorm.IsSmall()) - return false ; - plNear.Set( ptCen - 2 * EPS_SMALL * vtNorm, -vtNorm ) ; // taglio tutto ciò che sta nel semipiano negativo - Vector3d vtTraslPlane = dStep * vtNorm ; - plFar.Set( ptCen + vtTraslPlane, vtNorm) ; // taglio tutto ciò che sta nel semepiano positivo - plProj.Set( ptCen, -vtNorm) ; - if ( ! plNear.IsValid() || ! plFar.IsValid() || ! plProj.IsValid()) - return false ; + //// ------------------------- CREAZIONE DEI PIANI DI TAGLIO NEAR, FAR E DI PROIEZIONE -------------------------------------- + //// recupero il piano di proiezione ( piano che contiene la flatRegion) + // PtrOwner pCrv( ConvertCurveToComposite( pSfrPock->GetLoop( 0, 0))) ; + // if ( IsNull( pCrv)) + // return false ; + // Plane3d plNear, plFar, plProj ; + // Point3d ptCen ; + // if ( ! pCrv->GetCentroid( ptCen)) // punto + // if ( ! pCrv->GetStartPoint( ptCen)) + // return false ; + // Vector3d vtNorm = pSfrPock->GetNormVersor() ; // normale + // if ( vtNorm.IsSmall()) + // return false ; + // plNear.Set( ptCen - 2 * EPS_SMALL * vtNorm, -vtNorm ) ; // taglio tutto ciò che sta nel semipiano negativo + // Vector3d vtTraslPlane = dStep * vtNorm ; + // plFar.Set( ptCen + vtTraslPlane, vtNorm) ; // taglio tutto ciò che sta nel semepiano positivo + // plProj.Set( ptCen, -vtNorm) ; + // if ( ! plNear.IsValid() || ! plFar.IsValid() || ! plProj.IsValid()) + // return false ; - // ---------------------- RICERCA DELLA REGIONE DI INCIDENZA DI PROIEZIONE -------------------------- - // offsetto la regione della quantità richiesta ( raggio di ricerca per eventuali proeizioni) - PtrOwner pSrf_Pock_Clone( CloneSurfFlatRegion( pSfrPock)) ; - if ( ! pSrf_Pock_Clone->Offset( m_dMaxLenRawProj, ICurve::OFF_CHAMFER)) - return false ; - // per evitare memory leaks all'uscita della funzione per vCrv ( vettore di puntatori a curve const) - ICURVEPOVECTOR vCrvPO ; - CICURVEPVECTOR vCrv ; - for ( int c = 0 ; c < pSrf_Pock_Clone->GetChunkCount() ; ++ c) { - for ( int l = 0 ; l < pSrf_Pock_Clone->GetLoopCount( c) ; ++ l) { - vCrvPO.emplace_back( pSrf_Pock_Clone->GetLoop( c, l)) ; - vCrv.emplace_back( vCrvPO.back()) ; - } - } - const int STEP_HEIGHT = dStep * 1.5 ; - PtrOwner pSrf_ForCuttingRaw( GetSurfTriMeshByRegionExtrusion( vCrv, vtNorm * STEP_HEIGHT)) ; - if ( IsNull( pSrf_ForCuttingRaw) || ! pSrf_ForCuttingRaw->IsValid()) - return false ; + //// ---------------------- RICERCA DELLA REGIONE DI INCIDENZA DI PROIEZIONE -------------------------- + //// offsetto la regione della quantità richiesta ( raggio di ricerca per eventuali proeizioni) + // PtrOwner pSrf_Pock_Clone( CloneSurfFlatRegion( pSfrPock)) ; + // if ( ! pSrf_Pock_Clone->Offset( m_dMaxLenRawProj, ICurve::OFF_CHAMFER)) + // return false ; + //// per evitare memory leaks all'uscita della funzione per vCrv ( vettore di puntatori a curve const) + // ICURVEPOVECTOR vCrvPO ; + // CICURVEPVECTOR vCrv ; + // for ( int c = 0 ; c < pSrf_Pock_Clone->GetChunkCount() ; ++ c) { + // for ( int l = 0 ; l < pSrf_Pock_Clone->GetLoopCount( c) ; ++ l) { + // vCrvPO.emplace_back( pSrf_Pock_Clone->GetLoop( c, l)) ; + // vCrv.emplace_back( vCrvPO.back()) ; + // } + // } + // const int STEP_HEIGHT = dStep * 1.5 ; + // PtrOwner pSrf_ForCuttingRaw( GetSurfTriMeshByRegionExtrusion( vCrv, vtNorm * STEP_HEIGHT)) ; + // if ( IsNull( pSrf_ForCuttingRaw) || ! pSrf_ForCuttingRaw->IsValid()) + // return false ; - // --------------------- CREAZIONE PARTE DI GREZZO AL DI SOPRA DELLA REGIONE SI SVUOTATURA - // ----------------------------------- NELLA REGIONE DI INCIDENZA ----------------------------- - // clono la Trimesh del Grezzo - PtrOwner pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ; - if ( IsNull( pSrfRaw_clone)) - return false ; - // taglio la Trimesh con il piano near e il piano far - pSrfRaw_clone->Cut( plNear, true) ; - if ( pSrfRaw_clone->IsValid()) - pSrfRaw_clone->Cut( plFar, true) ; - // chiudo la superificie dalla parte del piano di far - if ( ! IsNull( pSrfRaw_clone) && pSrfRaw_clone->IsValid()) { - POLYLINEVECTOR vPL ; - pSrfRaw_clone->GetLoops( vPL) ; - for ( int p = 0 ; p < ( int)vPL.size() ; ++ p) { - // controllo se questa curva è contenuta nel piano dove svuoto, nel caso quindi la salto - Plane3d plCheck ; double dArea ; Point3d ptCheck ; - if ( vPL[p].IsClosedAndFlat( plCheck, dArea)) { - if ( vPL[p].GetPointNbr() > 0 ) { - if ( vPL[p].GetFirstPoint( ptCheck)) { - double dDist = DistPointPlane( ptCheck, plNear) ; - if ( abs ( dDist) < 50 * EPS_SMALL) - continue ; - } - } - } - PtrOwner pStm_SideAtFar( CreateSurfTriMesh()) ; - if ( pStm_SideAtFar->CreateByFlatContour( vPL[p])) { - Vector3d vtN ; - if ( pStm_SideAtFar->GetFacetNormal( 0, vtN) && AreOppositeVectorApprox( vtN, -plNear.GetVersN())) - pStm_SideAtFar->Invert() ; - } - pSrfRaw_clone->DoSewing( *pStm_SideAtFar) ; - } - } + //// --------------------- CREAZIONE PARTE DI GREZZO AL DI SOPRA DELLA REGIONE SI SVUOTATURA + //// ----------------------------------- NELLA REGIONE DI INCIDENZA ----------------------------- + //// clono la Trimesh del Grezzo + // PtrOwner pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ; + // if ( IsNull( pSrfRaw_clone)) + // return false ; + //// taglio la Trimesh con il piano near e il piano far + // pSrfRaw_clone->Cut( plNear, true) ; + // if ( pSrfRaw_clone->IsValid()) + // pSrfRaw_clone->Cut( plFar, true) ; + //// chiudo la superificie dalla parte del piano di far + // if ( ! IsNull( pSrfRaw_clone) && pSrfRaw_clone->IsValid()) { + // POLYLINEVECTOR vPL ; + // pSrfRaw_clone->GetLoops( vPL) ; + // for ( int p = 0 ; p < ( int)vPL.size() ; ++ p) { + // // controllo se questa curva è contenuta nel piano dove svuoto, nel caso quindi la salto + // Plane3d plCheck ; double dArea ; Point3d ptCheck ; + // if ( vPL[p].IsClosedAndFlat( plCheck, dArea)) { + // if ( vPL[p].GetPointNbr() > 0 ) { + // if ( vPL[p].GetFirstPoint( ptCheck)) { + // double dDist = DistPointPlane( ptCheck, plNear) ; + // if ( abs ( dDist) < 50 * EPS_SMALL) + // continue ; + // } + // } + // } + // PtrOwner pStm_SideAtFar( CreateSurfTriMesh()) ; + // if ( pStm_SideAtFar->CreateByFlatContour( vPL[p])) { + // Vector3d vtN ; + // if ( pStm_SideAtFar->GetFacetNormal( 0, vtN) && AreOppositeVectorApprox( vtN, -plNear.GetVersN())) + // pStm_SideAtFar->Invert() ; + // } + // pSrfRaw_clone->DoSewing( *pStm_SideAtFar) ; + // } + // } - // controllo validità - if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0) - pSrfRaw_clone.Set( CloneSurfTriMesh( pStmRaw)) ; - // considero la parte di grezzo interna alla regione di incidenza - if ( ! pSrfRaw_clone->CutWithOtherSurf( *pSrf_ForCuttingRaw, true, true)) - return false ; - if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0) { - pSfrRawBoxProj->Clear() ; - return true ; - } + //// controllo validità + // if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0) + // pSrfRaw_clone.Set( CloneSurfTriMesh( pStmRaw)) ; + //// considero la parte di grezzo interna alla regione di incidenza + // if ( ! pSrfRaw_clone->CutWithOtherSurf( *pSrf_ForCuttingRaw, true, true)) + // return false ; + // if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0) { + // pSfrRawBoxProj->Clear() ; + // return true ; + // } - // --------------------- RIMOZIONE DELLE PARTI NON ESSENZIALI --------------------------------- - // 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()) ; - for ( int p = 0 ; p < pSrfRaw_clone->GetPartCount() ; ++ p) { // per ogni part della TriMesh - PtrOwner pStm_raw_part( pSrfRaw_clone->ClonePart( p)) ; - POLYLINEVECTOR vPl ; - pStm_raw_part->GetLoops( vPl) ; // ricavo i Loops - for ( int l = 0 ; l < ( int)vPl.size() ; ++ l) { - PtrOwner pCompo( CreateCurveComposite()) ; - pCompo->FromPolyLine( vPl[l]) ; // converto in curva composita - PtrOwner pSfr_H( CreateSurfFlatRegion()) ; - pSfr_H->AddExtLoop( Release( pCompo)) ; // creo una regione per ogni Loop - if ( ! AreSameVectorApprox( pSfr_H->GetNormVersor(), pSfrPock->GetNormVersor())) - pSfr_H->Invert() ; // se necessario inverto - for ( int c = 0 ; c < pSfrPock->GetChunkCount() ; ++ c) { // per ogni chunk della regione di svuotatura - if ( pSfr_H->GetChunkSimpleClassification( 0, *pSfrPock, c) != CCREGC_OUT) { - if ( pStr_real->GetTriangleCount() != 0) - pStr_real->Add( *Release( pStm_raw_part)) ; - else - pStr_real.Set( Release( pStm_raw_part)) ; - l = ( int)vPl.size() ; - break ; - } - } - } - } + //// --------------------- RIMOZIONE DELLE PARTI NON ESSENZIALI --------------------------------- + //// 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()) ; + // for ( int p = 0 ; p < pSrfRaw_clone->GetPartCount() ; ++ p) { // per ogni part della TriMesh + // PtrOwner pStm_raw_part( pSrfRaw_clone->ClonePart( p)) ; + // POLYLINEVECTOR vPl ; + // pStm_raw_part->GetLoops( vPl) ; // ricavo i Loops + // for ( int l = 0 ; l < ( int)vPl.size() ; ++ l) { + // PtrOwner pCompo( CreateCurveComposite()) ; + // pCompo->FromPolyLine( vPl[l]) ; // converto in curva composita + // PtrOwner pSfr_H( CreateSurfFlatRegion()) ; + // pSfr_H->AddExtLoop( Release( pCompo)) ; // creo una regione per ogni Loop + // if ( ! AreSameVectorApprox( pSfr_H->GetNormVersor(), pSfrPock->GetNormVersor())) + // pSfr_H->Invert() ; // se necessario inverto + // for ( int c = 0 ; c < pSfrPock->GetChunkCount() ; ++ c) { // per ogni chunk della regione di svuotatura + // if ( pSfr_H->GetChunkSimpleClassification( 0, *pSfrPock, c) != CCREGC_OUT) { + // if ( pStr_real->GetTriangleCount() != 0) + // pStr_real->Add( *Release( pStm_raw_part)) ; + // else + // pStr_real.Set( Release( pStm_raw_part)) ; + // l = ( int)vPl.size() ; + // break ; + // } + // } + // } + // } - // ------- 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 ; // <---- 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( ConvertCurveToComposite( pSfr->GetLoop( 0, 0))) ; + // // ------- 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 ; // <---- 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( ConvertCurveToComposite( pSfr->GetLoop( 0, 0))) ; - // 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 ; + //// 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 ; + //// Creo la superficie che dovrò restiturire alla fine della proiezione + // PtrOwner pSrf_Proj_Ext( CreateSurfFlatRegion()) ; + // if ( IsNull( pSrf_Proj_Ext)) + // return false ; - if ( ! ProjectStmOnPlane( pStr_real, plProj, pSrf_Proj_Ext)) - return false ; + // if ( ! ProjectStmOnPlane( pStr_real, plProj, pSrf_Proj_Ext)) + // return false ; - if ( IsNull( pSrf_Proj_Ext) || ! pSrf_Proj_Ext->IsValid()) - return true ; + // if ( IsNull( pSrf_Proj_Ext) || ! pSrf_Proj_Ext->IsValid()) + // return true ; - for ( int c = 0 ; c < pSrf_Proj_Ext->GetChunkCount() ; ++ c) { - for ( int l = 0 ; l < pSrf_Proj_Ext->GetLoopCount( c) ; ++ l) { - PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSrf_Proj_Ext->GetLoop( c, l))) ; - if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) - return false ; - for ( int u = 0 ; u < pCrvCompoLoop->GetCurveCount() ; ++ u) - pCrvCompoLoop->SetCurveTempProp( u, 1, 0) ; - vCrvExtProj.emplace_back( Release( pCrvCompoLoop)) ; - } - } + // for ( int c = 0 ; c < pSrf_Proj_Ext->GetChunkCount() ; ++ c) { + // for ( int l = 0 ; l < pSrf_Proj_Ext->GetLoopCount( c) ; ++ l) { + // PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSrf_Proj_Ext->GetLoop( c, l))) ; + // if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) + // return false ; + // for ( int u = 0 ; u < pCrvCompoLoop->GetCurveCount() ; ++ u) + // pCrvCompoLoop->SetCurveTempProp( u, 1, 0) ; + // vCrvExtProj.emplace_back( Release( pCrvCompoLoop)) ; + // } + // } - // creo la vera e propria regione di proiezione, sommando la proiezione esterna con la superficie originale - // da svuotare - PtrOwner pSrf_Proj( CloneSurfFlatRegion( pSrf_Proj_Ext)) ; - if ( IsNull( pSrf_Proj) || ! pSrf_Proj->IsValid()) - return false ; - pSrf_Proj->Add( *pSfr) ; + //// creo la vera e propria regione di proiezione, sommando la proiezione esterna con la superficie originale + //// da svuotare + // PtrOwner pSrf_Proj( CloneSurfFlatRegion( pSrf_Proj_Ext)) ; + // if ( IsNull( pSrf_Proj) || ! pSrf_Proj->IsValid()) + // return false ; + // pSrf_Proj->Add( *pSfr) ; - // controllo i loop della superificie creata ------------------------ - SurfFlatRegionByContours SrfByC ; - for ( int c = 0 ; c < pSrf_Proj->GetChunkCount() ; ++ c) { - for ( int l = 0 ; l < pSrf_Proj->GetLoopCount( c) ; ++ l) { - PtrOwner pCrvTmp( pSrf_Proj->GetLoop( c, l)) ; - if ( IsNull( pCrvTmp) || ! pCrvTmp->IsValid() || ! pCrvTmp->IsClosed()) - continue ; - double dArea = 0. ; - Plane3d plCheck = plProj ; - if ( pCrvTmp->GetArea( plCheck, dArea) && dArea < 500 * EPS_SMALL) - continue ; - SrfByC.AddCurve( Release( pCrvTmp)) ; - } - } - PtrOwner pSrf_Check( SrfByC.GetSurf()) ; - if ( ! IsNull( pSrf_Check) && pSrf_Check->IsValid()) - pSrf_Proj.Set( Release( pSrf_Check)) ; - // ------------------------------------------------------------------ + //// controllo i loop della superificie creata ------------------------ + // SurfFlatRegionByContours SrfByC ; + // for ( int c = 0 ; c < pSrf_Proj->GetChunkCount() ; ++ c) { + // for ( int l = 0 ; l < pSrf_Proj->GetLoopCount( c) ; ++ l) { + // PtrOwner pCrvTmp( pSrf_Proj->GetLoop( c, l)) ; + // if ( IsNull( pCrvTmp) || ! pCrvTmp->IsValid() || ! pCrvTmp->IsClosed()) + // continue ; + // double dArea = 0. ; + // Plane3d plCheck = plProj ; + // if ( pCrvTmp->GetArea( plCheck, dArea) && dArea < 500 * EPS_SMALL) + // continue ; + // SrfByC.AddCurve( Release( pCrvTmp)) ; + // } + // } + // PtrOwner pSrf_Check( SrfByC.GetSurf()) ; + // if ( ! IsNull( pSrf_Check) && pSrf_Check->IsValid()) + // pSrf_Proj.Set( Release( pSrf_Check)) ; + //// ------------------------------------------------------------------ - // --------- 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 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 aperti 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 ; - // sistemo le rette ottenute per allargare la superificie presso i 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)) ; - if ( IsNull( pSfrProj_Clone) || ! pSfrProj_Clone->IsValid()) - return false ; - // controllo che le normali siano compatibili - if ( AreOppositeVectorApprox( pSfrProj_Clone->GetNormVersor(), pSrfWithOEModified->GetNormVersor())) - pSfrProj_Clone->Invert() ; - // ... 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()) { - // 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()) - return false ; - PtrOwner pCrvCompo_NewExt( CreateCurveComposite()) ; // trasformo in composita - if ( IsNull( pCrvCompo_NewExt)) - return false ; - pCrvCompo_NewExt->AddCurve( Release( pCrv_NewExt)) ; - // Imposto le temp prop - if ( pCrvCompo_NewExt->IsValid()) { - if ( ! SetTmpPropWithRawProjectedFaces( pCrvCompo_NewExt, vCrvExtProj, pSfr->GetNormVersor()) || - ! CheckSmallPartsForOpenEdge( pCrvCompo_NewExt)) - return false ; - // creo la superificie finale - PtrOwner pSrfProj_Final( CreateSurfFlatRegion()) ; - 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) ; - return pSfrRawBoxProj->IsValid() ; - } - } - } - } + //// --------- 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 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 aperti 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 ; + // // sistemo le rette ottenute per allargare la superificie presso i 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)) ; + // if ( IsNull( pSfrProj_Clone) || ! pSfrProj_Clone->IsValid()) + // return false ; + // // controllo che le normali siano compatibili + // if ( AreOppositeVectorApprox( pSfrProj_Clone->GetNormVersor(), pSrfWithOEModified->GetNormVersor())) + // pSfrProj_Clone->Invert() ; + // // ... 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()) { + // // 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()) + // return false ; + // PtrOwner pCrvCompo_NewExt( CreateCurveComposite()) ; // trasformo in composita + // if ( IsNull( pCrvCompo_NewExt)) + // return false ; + // pCrvCompo_NewExt->AddCurve( Release( pCrv_NewExt)) ; + // // Imposto le temp prop + // if ( pCrvCompo_NewExt->IsValid()) { + // if ( ! SetTmpPropWithRawProjectedFaces( pCrvCompo_NewExt, vCrvExtProj, pSfr->GetNormVersor()) || + // ! CheckSmallPartsForOpenEdge( pCrvCompo_NewExt)) + // return false ; + // // creo la superificie finale + // PtrOwner pSrfProj_Final( CreateSurfFlatRegion()) ; + // 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) ; + // return pSfrRawBoxProj->IsValid() ; + // } + // } + // } + // } return true ; @@ -12769,96 +13284,97 @@ Pocketing::GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pSt bool 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 ; + //// controllo validità dei parametri + // if ( pSrfProjected == nullptr || ! pSrfProjected->IsValid() || pSrfProjected->GetChunkCount() == 0 || + // pSrfOrig == nullptr || ! pSrfOrig->IsValid() || pSrfOrig->GetChunkCount() == 0) + // return false ; - // ricavo i tratti tutti i possibili aperti della superificie - ICURVEPOVECTOR vCrvAllClose ; - 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 ; - ICURVEPOVECTOR vCrvOpen, vCrvClose ; - if ( ! GetHomogeneousParts( pCrvCompo, vCrvOpen, vCrvClose, true)) - return false ; - // se nessun lato aperto, esco - if (( int)vCrvClose.size() == 0) - continue ; - else - for ( int u = 0 ; u < ( int)vCrvClose.size() ; ++ u) - vCrvAllClose.emplace_back( Release( vCrvClose[u])) ; - } - } - // se nessun lato aperto, esco - if (( int)vCrvAllClose.size() == 0) - return true ; + //// ricavo i tratti tutti i possibili aperti della superificie + // ICURVEPOVECTOR vCrvAllClose ; + // 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 ; + // ICURVEPOVECTOR vCrvOpen, vCrvClose ; + // if ( ! GetHomogeneousParts( pCrvCompo, vCrvOpen, vCrvClose, true)) + // return false ; + // // se nessun lato aperto, esco + // if (( int)vCrvClose.size() == 0) + // continue ; + // else + // for ( int u = 0 ; u < ( int)vCrvClose.size() ; ++ u) + // vCrvAllClose.emplace_back( Release( vCrvClose[u])) ; + // } + // } + //// se nessun lato aperto, esco + // if (( int)vCrvAllClose.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 ; + //// 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) ; + //// 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 ; + //// 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)vCrvAllClose.size() ; ++ i) { - PtrOwner pCrvClose_i( CloneCurveComposite( vCrvAllClose[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) ; + //// porto tutto in questo frame + // ICRVCOMPOPOVECTOR vCrvClose_c ; + // for ( int i = 0 ; i < ( int)vCrvAllClose.size() ; ++ i) { + // PtrOwner pCrvClose_i( CloneCurveComposite( vCrvAllClose[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) ; + //// 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 ; - // 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)) ; - } + //// 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 ; + // // 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)) ; + // } - // se la superificie finale è valida... - if ( IsNull( pStmProj) || ! pStmProj->IsValid()) - return true ; - // ... ricoverto La Trimesh in FlatRegione - PtrOwner pSfrProj( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrProj)) - return false ; - Plane3d plPlane ; plPlane.Set( ORIG, Z_AX) ; - if ( ! GetSfrByStm( pStmProj, pSfrProj, plPlane, V_NULL, 0.)) - return false ; + //// se la superificie finale è valida... + // if ( IsNull( pStmProj) || ! pStmProj->IsValid()) + // return true ; + //// ... ricoverto La Trimesh in FlatRegione + // PtrOwner pSfrProj( CreateSurfFlatRegion()) ; + // if ( IsNull( pSfrProj)) + // return false ; + // Plane3d plPlane ; plPlane.Set( ORIG, Z_AX) ; + // if ( ! GetSfrByStm( pStmProj, pSfrProj, plPlane, V_NULL, 0.)) + // return false ; - // la risporto in globale e sostituisco - pSfrProj->ToGlob( frPock) ; - pSrfProjected->Clear() ; - pSrfProjected->CopyFrom( pSfrProj) ; + //// la risporto in globale e sostituisco + // pSfrProj->ToGlob( frPock) ; + // pSrfProjected->Clear() ; + // pSrfProjected->CopyFrom( pSfrProj) ; - return pSrfProjected != nullptr && pSrfProjected->IsValid() && pSrfProjected->GetChunkCount() > 0 ; + // return pSrfProjected != nullptr && pSrfProjected->IsValid() && pSrfProjected->GetChunkCount() > 0 ; + return true ; } //---------------------------------------------------------------------------- @@ -13306,7 +13822,7 @@ Pocketing::GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveCompos // fisso il diametro del tool ( più grande per sicurezza ) - double dDiam = m_TParams.m_dDiam * 2.15 + 2 * GetOffsR() + 5 * EPS_SMALL ; + double dDiam = m_TParams.m_dDiam + 2 * GetOffsR() ; double dLen ; if ( ! pCrv->GetLength( dLen)) return false ; @@ -13977,11 +14493,12 @@ Pocketing::CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const doub IntersCurveCurve intCC( *pCrvOffLonger, *pCrvTool) ; intCC.GetCurveClassification( 1, EPS_SMALL, ccClass) ; if (( int)ccClass.size() == 1 && ccClass[0].nClass == CRVC_OUT) { - // CENTROIDE + // centroide bInsert = false ; return true ; } + // recupero la PolyLine per altezza e lunghezza del Box2D ( rettangolo) PolyLine pl ; if ( ! pCrvOffLonger->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, pl)) return true ; @@ -13990,6 +14507,7 @@ Pocketing::CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const doub if ( ! pl.GetMinAreaRectangleXY( ptC, vtX, dLen, dHeight)) return true ; + // frame locale, recupero DimX e DimY Frame3d frLoc ; frLoc.Set( ptC, vtN, vtX) ; if ( ! frLoc.IsValid()) return true ; @@ -13999,6 +14517,7 @@ Pocketing::CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const doub double dDimX = bBox.GetDimX() ; double dDimY = bBox.GetDimY() ; + // se dimensioni accettabili, inserisco if ( dDimX < m_TParams.m_dDiam - 100 * EPS_SMALL || dDimY < m_TParams.m_dDiam - 100 * EPS_SMALL) { bInsert = false ; @@ -14781,10 +15300,10 @@ Pocketing::GetNewSrfByAnotherPocketing( ISurfFlatRegion* pSrf, ISurfFlatRegion* for ( int l = 1 ; l < pSrf_clone->GetLoopCount( c) ; ++ l) vCrvIsl.emplace_back( GetCurveComposite( pSrf_clone->GetLoop( c, l))) ; if ( bSomeOpen) { // se trovo dei lati aperti - if ( ! AdjustContourWithOpenEdges( pCrvExt, vCrvIsl, m_TParams.m_dDiam, GetOffsR(), GetSideStep(), vtTrasl)) { - m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; - return false ; - } + //if ( ! AdjustContourWithOpenEdges( pCrvExt, vCrvIsl, m_TParams.m_dDiam, GetOffsR(), GetSideStep(), vtTrasl)) { + // m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + // return false ; + //} } // Chunk modificato con i lati aperti @@ -14879,8 +15398,12 @@ Pocketing::GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const P // 3) Interpoliamo mediante Linee ed Archi pCrv->ToLoc( frPock) ; pCrv->ApproxWithArcsEx( 500 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; + if ( ! pCrv->IsValid()) + continue ; pCrv->Clear() ; pCrv->FromPolyArc( PA) ; + if ( ! pCrv->IsValid()) + continue ; pCrv->ToGlob( frPock) ; // 4) Estrusione e Thickness della curva pCrv->SetExtrusion( vtExtr) ; @@ -14951,109 +15474,43 @@ Pocketing::GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const P //---------------------------------------------------------------------------- bool -Pocketing::GetHomogeneousParts( ICurveComposite* pCrvCompo, ICURVEPOVECTOR& vCrvOpen, ICURVEPOVECTOR& vCrvClose, - bool bCallAdjust) +Pocketing::GetHomogeneousParts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) { // controllo dei parametri - vCrvClose.clear() ; - vCrvClose.clear() ; + vpCrvs.clear() ; if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) // se curva non valida return true ; - if ( ! pCrvCompo->IsClosed()) - bCallAdjust = false ; - - // controllo se la curva ha solo tratti aperti o tratti chiusi --------------------- - int nFirstTmpProp = -1 ; - int nCheckTmpProp = -1 ; - bool bIsHomogenous = true ; - for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && bIsHomogenous ; ++ u) { - pCrvCompo->GetCurveTempProp( u, nCheckTmpProp, 0) ; - if ( u == 0) - nFirstTmpProp = nCheckTmpProp ; - else - if ( nFirstTmpProp != nCheckTmpProp) - bIsHomogenous = false ; - } - if ( bIsHomogenous) { - if ( nFirstTmpProp == 0) - vCrvClose.emplace_back( pCrvCompo->Clone()) ; - else if ( nFirstTmpProp == 1) - vCrvOpen.emplace_back( pCrvCompo->Clone()) ; - else - return false ; - return true ; - } - // --------------------------------------------------------------------------------- // la curva ha sia tratti aperti che tratti chiusi, quindi sposto l'inizio a metà del tratto più lungo ( se richisto)... - if ( bCallAdjust) { - ICRVCOMPOPOVECTOR vCrvNULL ; - AdjustContourStart( pCrvCompo, vCrvNULL) ; - } - - // estraggo parti con proprietà uniforme in un vettore + ICRVCOMPOPOVECTOR vCrvNULL ; + AdjustContourStart( pCrvCompo, vCrvNULL) ; + + // estraggo parti con proprietà uniforme in un vettore ( vpCrvs) int nCurrTempProp ; int nParStart = 0 ; for ( int i = 0 ; i < pCrvCompo->GetCurveCount() ; ++ i) { int nTempProp ; pCrvCompo->GetCurveTempProp( i, nTempProp) ; - if ( i == 0) + if ( i == 0) { nCurrTempProp = nTempProp ; - else if ( nCurrTempProp != nTempProp || i == pCrvCompo->GetCurveCount() - 1) { - // ricavo la curva uniforme - PtrOwner pCrv( pCrvCompo->CopyParamRange( nParStart, i)) ; + nParStart = i ; + } + else if ( nCurrTempProp != nTempProp) { + PtrOwner pCrv( ConvertCurveToComposite( pCrvCompo->CopyParamRange( nParStart, i))) ; if ( IsNull( pCrv)) return false ; - // setto la Tmp Prop come da originale pCrv->SetTempProp( nCurrTempProp) ; - // converto in composita - PtrOwner pCrvSameTmpProp( CreateCurveComposite()) ; - pCrvSameTmpProp->AddCurve( Release( pCrv)) ; - // ultimo pezzo di curva - if ( i == pCrvCompo->GetCurveCount() - 1) { - // ricavo ultima curva - PtrOwner pCrv_Last( pCrvCompo->GetLastCurve()->Clone()) ; - if ( IsNull( pCrv_Last)) - return false ; - // prendo tmp prop - int nLastTmpProp = pCrv_Last->GetTempProp( 0) ; - // se tmp prop come tratto precedente -> la aggiungo alla curva attuale - if ( nLastTmpProp == nCurrTempProp) - pCrvSameTmpProp->AddCurve( Release( pCrv_Last)) ; - else { - // se tmp prop differente -> inserisco la curva nel vettore corrispondente - if ( nLastTmpProp == 0) - vCrvClose.emplace_back( Release( pCrv_Last)) ; - else - vCrvOpen.emplace_back( Release( pCrv_Last)) ; - } - } - // sistemazione della curva - pCrvSameTmpProp->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - // inserimento nel vettore di aperti e chiusi a seconda del caso - if ( nCurrTempProp == 1) - vCrvOpen.emplace_back( Release( pCrvSameTmpProp)) ; // se aperta - if ( nCurrTempProp == 0) - vCrvClose.emplace_back( Release( pCrvSameTmpProp)) ; // se chiusa - // aggiornamento parametri + vpCrvs.emplace_back( Release( pCrv)) ; nCurrTempProp = nTempProp ; nParStart = i ; } } - - // unisco il primo e l'ultimo tratto chiuso, avendo cambiato l'inizio e la fine - if ( false) { - if ( vCrvClose.size() > 0 && bCallAdjust) { - PtrOwner pCrvCompoFirstLast( CreateCurveComposite()) ; - if ( IsNull( pCrvCompoFirstLast)) - return false ; - pCrvCompoFirstLast->AddCurve( vCrvClose.back()->Clone()) ; - pCrvCompoFirstLast->AddCurve( vCrvClose.front()->Clone()) ; - vCrvClose.front().Set( Release( pCrvCompoFirstLast)) ; - if ( int( vCrvClose.size() != 1)) - vCrvClose.pop_back() ; - } - } + // ultima curva... + PtrOwner pCrv( ConvertCurveToComposite( pCrvCompo->CopyParamRange( nParStart, pCrvCompo->GetCurveCount()))) ; + if ( IsNull( pCrv)) + return false ; + pCrv->SetTempProp( nCurrTempProp) ; + vpCrvs.emplace_back( Release( pCrv)) ; return true ; } diff --git a/Pocketing.h b/Pocketing.h index 165cd9f..129cc8c 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -70,7 +70,7 @@ class Pocketing : public Machining private : bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; - bool GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp) ; + bool GetCurvesAndPartialVolume( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp, Vector3d& vtN) ; bool GetForcedClosed( void) ; bool SetCurveAllTempProp( int nCrvId, bool bForcedClose, ICurve* pCurve, bool* pbSomeOpen = nullptr) ; bool ResetCurveAllTempProp( ICurve* pCurve) ; @@ -84,10 +84,34 @@ class Pocketing : public Machining bool DetectOpenEdgeInsideRaw ( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw) ; - bool CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo) ; - bool GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop) ; + bool CalcDepth( const int nId, const Vector3d& vtExtr, double dThick, double& dDepth) ; + bool ChainCurveArray( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) ; + bool CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo, const Vector3d& vtN) ; + bool GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop, const Vector3d& vtN) ; + bool GetCurrentPart( const Point3d& ptInside, ISurfTriMesh* pStmPart) ; bool SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm) ; - bool GetCurrentPart( const Point3d ptInside, ISurfTriMesh* pStmRawPart) ; + bool AdjustPocketingSideForVolumePart( ISurfTriMesh* pStmVolPart, const Vector3d& vtTool) ; + bool SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlane) ; + bool SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, ISURFFRPOVECTOR& vSrfSliced, + std::vector& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool, + const double dElev, const double dDepth, const double dStep) ; + bool CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, + ISurfFlatRegion* pSfrResult) ; + bool ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, + const Vector3d& vtTraslPrec, ISurfFlatRegion* pSfrOpenProjPrec, ISurfFlatRegion* pSfr) ; + bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm_Part) ; + bool GetCurvesForOptimizedPocketing( ISurfFlatRegion* pSfr, ICRVCOMPOPOVECTOR& vCrvOEWithFlags) ; + bool ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrLimit) ; + bool AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvIsl, const double dDiam, + const double dOffR, const double dStep, const ISurfFlatRegion* pSfrLimit) ; + bool AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvIsland, + const double dParS, const double dParE, const double dRad, const double dDiamJ, + const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvBorder) ; + bool GetProjectionOfStmToNotPocket( const ISurfTriMesh* pStmPart, const ISurfTriMesh* pStmVol, ISurfFlatRegion* pSfrProj) ; + bool CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad, const ISurfFlatRegion* pSfrLimit, + ISurfFlatRegion* pSfrInc) ; + bool GetHomogeneousParts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) ; @@ -111,8 +135,7 @@ class Pocketing : public Machining // =================================================================== // =========================== GREZZO e GEOMETRIE ==================== - bool GetHomogeneousParts( ICurveComposite* pCrvCompo, ICURVEPOVECTOR& vCrvOpen, ICURVEPOVECTOR& vCrvClose, - bool bCallAdjust = false) ; + 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 , @@ -172,9 +195,9 @@ class Pocketing : public Machining bool bFlag) ; bool GetCoeffLinArc( const ICurveArc* pArc, double dDiam, double& dSubArc) ; bool GetParamOnOpenSide( const ICurveComposite* pCompo,const ICRVCOMPOPOVECTOR& vCrvIsl, Point3d& ptMid, Vector3d& vtMidOut) ; - bool AdjustContourWithOpenEdges( ICurveComposite* pCompo, ICRVCOMPOPOVECTOR& vCrvIsl, + /*bool AdjustContourWithOpenEdges( ICurveComposite* pCompo, ICRVCOMPOPOVECTOR& vCrvIsl, double dDiam, double dOffR, double dStepPrec, const Vector3d& vtTrasl, - ISurfTriMesh* pStmRaw = nullptr, bool bInVsOut = false) ; + ISurfTriMesh* pStmRaw = nullptr, bool bInVsOut = false) ;*/ bool AdustTmpPropLinesForProjection( ICurveComposite* pCompo) ; bool AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vCrvIsland, ICurveComposite* pCrvOpenOffs, const Point3d& ptCrvOpenS, @@ -192,8 +215,9 @@ class Pocketing : public Machining // =================================================================== // ============================ ZigZag =============================== - bool AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, - double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; + bool AddZigZag( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; bool CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpCrvs) ; bool CalcZigZagLink( ICurveComposite* pCrv1, ICurveComposite* pCrv2, ICurveComposite* pCrvLink) ; bool OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d & vtTool, double dDepth, double dSafeZ, @@ -214,16 +238,19 @@ class Pocketing : public Machining // =================================================================== // ============================ OneWay =============================== - bool AddOneWay( const ISurfFlatRegion* pSrfPock , const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, - double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; + bool AddOneWay( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; bool OptimizeChunkOneWay( ISurfFlatRegion* pSrfOrig, ISURFFRPOVECTOR& vSrfIdeal) ; // =================================================================== // ============================ SpiralIn/Out ========================= - bool AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, - double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; - bool AddSpiralOut( const ISurfFlatRegion* pSrfpock, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, - double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; + bool AddSpiralIn( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; + bool AddSpiralOut( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, + VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; bool CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptStart, Vector3d& vtMidOut , bool& bMidOut, bool bSplitArcs,ICurveComposite* pMCrv, ICurveComposite* pRCrv, ICurveComposite* pCrvOEWithFlags, bool vbChangedPrec, bool& bOptimizedTrap) ; @@ -380,11 +407,6 @@ class Pocketing : public Machining double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto PtrOwner m_pStmVolPocket ; // volume delle svuotatura - Vector3d m_vtNormal = V_INVALID ; // versore normale ai piani di pocketing - - - - bool m_bIntersRaw = true ; // flag per intersezione con grezzo