diff --git a/Pocketing.cpp b/Pocketing.cpp index 948e976..c99a279 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -1446,7 +1446,7 @@ Pocketing::Chain( int nGrpDestId) // concateno le curve se necessario ICRVCOMPOPOVECTOR vCrvCompo ; - if ( ! ChainCurveArray( vInds, vpCrvs, vCrvCompo)) + if ( ! ChainCurveArray( vpCrvs, vCrvCompo)) return false ; // verifico che siano curve chiuse ( devono delimitare l'area da svuotare) @@ -1498,7 +1498,7 @@ Pocketing::Chain( int nGrpDestId) //---------------------------------------------------------------------------- bool -Pocketing::ChainCurveArray( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) +Pocketing::ChainCurveArray( ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) { // preparo i dati per il concatenamento bool bFirst = true ; @@ -1536,14 +1536,10 @@ Pocketing::ChainCurveArray( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVC // estrusione e spessore Vector3d vtExtr = Z_AX ; double dThick = 0 ; - // vettore Id originali - SELVECTOR vId2 ; - vId2.reserve( vnId2.size()) ; // recupero le curve semplici e le inserisco nella curva composita for ( size_t i = 0 ; i < vnId2.size() ; ++ i) { int nId = abs( vnId2[i]) - 1 ; bool bInvert = ( vnId2[i] < 0) ; - vId2.emplace_back( vInds[nId]) ; // recupero la curva ICurve* pCrv = vpCrvs[nId] ; // se necessario, la inverto @@ -2052,6 +2048,7 @@ Pocketing::AdjustPocketingSideForVolumePart( ISurfTriMesh* pStmVolPart, const Ve 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) ; @@ -5970,7 +5967,7 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; // se prima etità in assoluto - if ( e == 1 && j == 1) { + if ( e == 0 && j == 1) { // LeadIn if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, vRCrv[e], ptP1)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; @@ -6153,6 +6150,11 @@ bool Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double& dSafeZ, const ISurfFlatRegion* pSfr, ICurveComposite* pCrvStepLink) { + // ptS -> punto finale del percorso attuale di pocketing + // ptE -> punto iniziale del successivo percorso di pocketing + // pSfr -> superficie da svuotare + // pCrvStepLink -> curva di collegamento tra Chunks o Steps diversi + // controllo dei parametri if ( ! ptS.IsValid() || ! ptE.IsValid() || pSfr == nullptr || ! pSfr->IsValid() || @@ -6161,7 +6163,7 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double& pCrvStepLink->Clear() ; // prendo la regione ed Offsetto internamente per ricavare la regione sicura dove posso muovermi - PtrOwner pSfrSafe( pSfr->CreateOffsetSurf( - m_TParams.m_dDiam - GetOffsR() + 5 * EPS_SMALL, + PtrOwner pSfrSafe( pSfr->CreateOffsetSurf( - 0.5 * m_TParams.m_dDiam - GetOffsR() + 5 * EPS_SMALL, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrSafe) || ! pSfrSafe->IsValid()) return false ; @@ -6196,11 +6198,13 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double& return false ; if ( int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_IN) // creo il tratto lineare leggermente rialzato - return ( pCrvStepLink->AddPoint( ORIG) && - pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) && - pCrvStepLink->AddLine( ptEProj + dSafeZ * Z_AX) && - pCrvStepLink->IsValid() && - pCrvStepLink->ToGlob( frCurr)) ; + return pCrvStepLink->AddPoint( ORIG) && + pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) && + pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) && + pCrvStepLink->AddLine( ptEProj + dSafeZ * Z_AX) && + pCrvStepLink->SetCurveTempProp( 1, FEED_DIVISOR * GetEndFeed(), 0) && + pCrvStepLink->IsValid() && + pCrvStepLink->ToGlob( frCurr) ; // se invece esistono intersezioni devo prendere in considerazione i tratti esterni alla regione // su di essi calcolo l'elevazione considerata sopra la segmento @@ -6222,16 +6226,150 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double& } // se l'elevazione massima è nulla, allora sono sempre fuori dal grezzo ( quindi passo per i lati aperti) if ( dMAxElev < EPS_SMALL) - return ( pCrvStepLink->AddPoint( ORIG) && - pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) && - pCrvStepLink->AddLine( ptEProj + dSafeZ * Z_AX) && - pCrvStepLink->IsValid() && - pCrvStepLink->ToGlob( frCurr)) ; + return pCrvStepLink->AddPoint( ORIG) && + pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) && + pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) && + pCrvStepLink->AddLine( ptEProj + dSafeZ * Z_AX) && + pCrvStepLink->SetCurveTempProp( 1, FEED_DIVISOR * GetEndFeed(), 0) && + pCrvStepLink->IsValid() && + pCrvStepLink->ToGlob( frCurr) ; + + // in questo caso creo un percorso con i Bisettori seguendo VRONI + ICURVEPOVECTOR vCrvBisectors ; + PtrOwner pVRONI( pSfr->GetVoronoiObject()) ; + if ( IsNull( pVRONI) || + ! pVRONI->CalcMedialAxis( vCrvBisectors, Voronoi::WMAT_LEFT) || + vCrvBisectors.empty()) + return false ; + + // porto i bisettori nel riferimento corrente e cerco le due curve più vicine a ORIG ( pts) e ptEProj + double dMinDistORIG = INFINITO, dMinDistEnd = INFINITO ; + int nIndS, nIndE ; + Point3d ptCheck ; // punto sulla curva finale più vicina a ptEProj + for ( int i = 0 ; i < ( int)vCrvBisectors.size() ; ++ i) { + vCrvBisectors[i]->ToLoc( frCurr) ; + double dCurrDistORIG, dCurrDistEND ; + if ( ! DistPointCurve( ORIG, *vCrvBisectors[i]).GetDist( dCurrDistORIG) || + ! DistPointCurve( ptEProj, *vCrvBisectors[i]).GetDist( dCurrDistEND)) + return false ; + if ( dCurrDistORIG < dMinDistORIG) { + dMinDistORIG = dCurrDistORIG ; + nIndS = i ; + } + if ( dCurrDistEND < dMinDistEnd) { + dMinDistEnd = dCurrDistEND ; + nIndE = i ; + if ( ! vCrvBisectors[i]->GetMidPoint( ptCheck)) + return false ; + } + } + // porto la curva più vicina a ORIG ( ptS) in prima posizione + swap( vCrvBisectors[0], vCrvBisectors[nIndS]) ; + + // concateno le curve per cercare dei percorsi ammissibili + ICRVCOMPOPOVECTOR vCompoBisChain ; + if ( ! ChainCurveArray( vCrvBisectors, vCompoBisChain)) + return false ; + + // per ogni percorso trovato + int nIndBestPath = -1 ; + double dLenBestPath = INFINITO ; + for ( int i = 0 ; i < int( vCompoBisChain.size()) ; ++ i) { + // non considero il percorso se esso non contiene ptCheck + if ( ! vCompoBisChain[i]->IsPointOn( ptCheck, 10 * EPS_SMALL)) + continue ; + // Spezzo nei punti più vicini a + // ORIG ( ptS) e ptEProj raccordo linearmente l'inizio e la fine a tali punti ( se necessario) + // NB. Non è esclusa la possibilità che ORIG ( ptS) e ptEProj siano già sul bisettore + double dUS = 0, dUE = vCompoBisChain[i]->GetCurveCount() ; + if ( ! vCompoBisChain[i]->GetParamAtPoint( ORIG, dUS) || + ( dUS > 10 * EPS_SMALL && ! vCompoBisChain[i]->TrimStartAtParam( dUS)) || + ! vCompoBisChain[i]->GetParamAtPoint( ptEProj, dUE) || + ( dUE < vCompoBisChain[i]->GetCurveCount() - 10 * EPS_SMALL && + ! vCompoBisChain[i]->TrimEndAtParam( dUE))) + return false ; + + // collego il percorso valido trovato all'ORIG ( ptS) e al ptEProj + vCompoBisChain[i]->AddLine( ORIG, false) ; + vCompoBisChain[i]->AddLine( ptEProj, true) ; + + // creo la FatCurve da qeusto percorso + PtrOwner pSfrTool( GetSurfFlatRegionFromFatCurve( vCompoBisChain[i]->Clone(), + 0.5 * m_TParams.m_dDiam, false, false)) ; + if ( IsNull( pSfrTool) || ! pSfrTool->IsValid()) + return false ; + if ( AreOppositeVectorApprox( pSfrTool->GetNormVersor(), Z_AX)) + pSfrTool->Invert() ; + + // controllo se è interamente contenuta nella regione Safe, altrimenti non considero il percorso + bool bIsInside = false ; + for ( int c = 0 ; c < pSfrSafe->GetChunkCount() && ! bIsInside ; ++ c) + bIsInside = pSfrTool->GetChunkSimpleClassification( 0, *pSfrTool, c) == REGC_IN1 ; + if ( ! bIsInside) + continue ; + + /* + double dUS = 0, dUE = vCompoBisChain[i]->GetCurveCount() ; + if ( ! vCompoBisChain[i]->GetParamAtPoint( ORIG, dUS)) + return false ; + if ( dUS > 10 * EPS_SMALL && ! vCompoBisChain[i]->TrimStartAtParam( dUS)) + return false ; + if ( ! vCompoBisChain[i]->GetParamAtPoint( ptEProj, dUE)) + return false ; + if ( dUE < vCompoBisChain[i]->GetCurveCount() - 10 * EPS_SMALL && + ! vCompoBisChain[i]->TrimEndAtParam( dUE)) + return false ; + */ + // calcolo la sua lunghezza + double dCurrLen ; + if ( ! vCompoBisChain[i]->GetLength( dCurrLen)) + return false ; + // aggiorno i parametri se di lunghezza inferiore + if ( dCurrLen < dLenBestPath) { + dLenBestPath = dCurrLen ; + nIndBestPath = i ; + } + } + // se non ho trovato un percorso valido, privilegio lo scarico ed esco + if ( nIndBestPath < 0) + return pCrvStepLink->AddPoint( ORIG) && + pCrvStepLink->AddLine( ORIG + ( dSafeZ + dMAxElev) * Z_AX) && + pCrvStepLink->AddLine( ptEProj + ( dSafeZ + dMAxElev) * Z_AX) && + pCrvStepLink->IsValid() && + pCrvStepLink->ToGlob( frCurr) ; + // smusso il miglior percorso trovato + ModifyCurveToSmoothed( vCompoBisChain[nIndBestPath], m_TParams.m_dDiam / 16, m_TParams.m_dDiam / 16, + false) ; + + // assegno la Feed al percorso + for ( int i = 0 ; i < vCompoBisChain[nIndBestPath]->GetCurveCount() ; ++ i) + vCompoBisChain[nIndBestPath]->SetCurveTempProp( i, FEED_DIVISOR * GetEndFeed(), 0) ; + + // valuto se invece è più conveniente scaricare ( quindi alzandomi di dMaxElev) + // la lunghezza del tratto in salita e in discesa è dMaxElev + // la lunghezza del tratto orizzontale è data dalla distanza tra ORIG e ptEProj + if ( dLenBestPath > 2 * dMAxElev + Dist( ORIG, ptEProj)) + // privilegio il percorso + return pCrvStepLink->AddPoint( ORIG) && + pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) && + pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) && + vCompoBisChain[nIndBestPath]->Translate( dSafeZ * Z_AX) && + pCrvStepLink->AddCurve( Release( vCompoBisChain[nIndBestPath])) && + pCrvStepLink->IsValid() && + pCrvStepLink->ToGlob( frCurr) ; + + // privilegio lo scarico + return pCrvStepLink->AddPoint( ORIG) && + pCrvStepLink->AddLine( ORIG + ( dSafeZ + dMAxElev) * Z_AX) && + pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) && + pCrvStepLink->AddLine( ptEProj + ( dSafeZ + dMAxElev) * Z_AX) && + pCrvStepLink->SetCurveTempProp( 1, FEED_DIVISOR * GetEndFeed(), 0) && + pCrvStepLink->IsValid() && + pCrvStepLink->ToGlob( frCurr) ; - return true ; } //---------------------------------------------------------------------------- @@ -6858,36 +6996,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt return false ; } - // calcolo il percorso di ritorno - if (( int)vOffs.size() >= 2) { - pRCrv->Clear() ; - // punto inziale e finale | vettore iniziale e finale - Point3d ptStart ; vOffs.back()->GetEndPoint( ptStart) ; - Point3d ptEnd ; vOffs.front()->GetStartPoint( ptEnd) ; - Vector3d vtStart ; vOffs.back()->GetEndDir( vtStart) ; - Vector3d vtEnd ; vOffs.front()->GetStartDir( vtEnd) ; - - // calcolo il ritorno (garantendo che non esca dalla svuotatura) - PtrOwner pCrvLink( CreateCurveComposite()) ; - if ( CalcBoundedSmootedLink( ptStart, vtStart, ptEnd, vtEnd, 0.5, vOffsFirstCurve, pCrvLink)) { - pRCrv->AddCurve( Release( pCrvLink)) ; - pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ; - // se necessario, approssimo archi con rette - if ( bSplitArcs && ! ApproxWithLines( pRCrv)) { - m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Linear Approx not computable") ; - return false ; - } - VerifyArcs( pRCrv) ; - } - else { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - - // Feed per percorso di ritorno - AssignFeedForReturnPath( pRCrv) ; - } - // creo il percorso di lavoro a partire dalla raccolta degli offset e dei collegamenti for ( int i = 0 ; i < int( vOffs.size()) ; ++i) { // se collegamento da aggiungere @@ -6923,7 +7031,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt // riporto tutto nel sistema di riferimento originale pMCrv->ToGlob( frPocket) ; - pRCrv->ToGlob( frPocket) ; ptStart.ToGlob( frPocket) ; vtMidOut.ToGlob( frPocket) ; pCrvOEWithFlags->ToGlob( frPocket) ; diff --git a/Pocketing.h b/Pocketing.h index d3f4858..2e1bff2 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -81,7 +81,7 @@ class Pocketing : public Machining bool GeneratePocketingPv( int nPathId, const ISurfTriMesh* pStm_PartVolume) ; bool CheckSimpleOverlap( const ICurve* pCrv, const ICurveComposite* pCrvOri, int& nStat, double dToll) ; bool CalcDepth( const int nId, const Vector3d& vtExtr, double dThick, double& dDepth) ; - bool ChainCurveArray( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) ; + bool ChainCurveArray( ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) ; bool CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo, const Vector3d& vtN) ; bool CalcOffsExtensionsForCurves( const ICurveComposite* pCrvCompo, const Vector3d& vtN, double& dExt) ; bool GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop, const double& dExt, const Vector3d& vtN) ;