diff --git a/Operation.cpp b/Operation.cpp index 3008f45..4f3dac5 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -1345,6 +1345,9 @@ Operation::ApproxWithArcsIfUseful( ICurveComposite* pCompo, bool bCareTempProp) pCompo->GetExtrusion( vtExtr) ; double dThick = 0 ; pCompo->GetThickness( dThick) ; + // recupero le tmp prop della composita + int nProp0 = pCompo->GetTempProp( 0) ; + int nProp1 = pCompo->GetTempProp( 1) ; // verifico se ci sono tante linee corte int nSmallLineCnt = 0 ; const ICurve* pCrv = pCompo->GetFirstCurve() ; @@ -1440,6 +1443,11 @@ Operation::ApproxWithArcsIfUseful( ICurveComposite* pCompo, bool bCareTempProp) pCompo->SetExtrusion( vtExtr) ; pCompo->SetThickness( dThick) ; + // riassegno temp prop alla composita + pCompo->SetTempProp( nProp0, 0) ; + pCompo->SetTempProp( nProp1, 1) ; + + return true ; } diff --git a/Pocketing.cpp b/Pocketing.cpp index 6a1dbc8..8b3fc01 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -1161,7 +1161,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) pCrv->ToGlob( frGlob) ; // salvo come TmpProp0 -> l'id della superificie ( per ogni loop ) // salvo come TmpProp1 -> -1, non ho lati adiacenti - for( auto pCrv : lstPC) { + for ( auto pCrv : lstPC) { pCrv->SetTempProp( Id.nId, 0) ; pCrv->SetTempProp( -1, 1) ; } @@ -1226,10 +1226,10 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) // --------------------------------- Proiezioni lati adiacenti -------------------------------------- // 1) Creo una regione piana dalla curva esterna PtrOwner pSrfpCompo( CreateSurfFlatRegion()) ; - if( IsNull( pSrfpCompo)) + if ( IsNull( pSrfpCompo)) return false ; pSrfpCompo->AddExtLoop( pCrvCompo->Clone()) ; - if( IsNull( pSrfpCompo) || pSrfpCompo->GetChunkCount() == 0) + if ( IsNull( pSrfpCompo) || pSrfpCompo->GetChunkCount() == 0) return false ; //m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->Clone()) ; @@ -1237,23 +1237,23 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) INTVECTOR vBannedId{ -1, nFacet} ; // 2) scorro tutte le curve del bordo esterno - for( int j = 0 ; j < pCrvCompo->GetCurveCount() ; ++ j) { + for ( int j = 0 ; j < pCrvCompo->GetCurveCount() ; ++ j) { int nProp = 0 ; // 3) controllo che nella seconda temp prop ho una faccia adiancente non già considerata da un altro bordo // e creo un vettore con gli Id delle facce del bordo laterale adiacente alla curva j della pCrvCompo - if( pCrvCompo->GetCurveTempProp( j, nProp, 1) && nProp != -1 //-> se la curva j ha una faccia adiacente... + if ( pCrvCompo->GetCurveTempProp( j, nProp, 1) && nProp != -1 //-> se la curva j ha una faccia adiacente... && find( vBannedId.begin(), vBannedId.end(), nProp) == vBannedId.end() //-> ...non già considerata da altre curve... && GetSurfByAdj( pSurf, vBannedId, nProp)) { //-> ...e riesco a ricavare tutte le facce del bordo // 4) creo una regione piana con tutte le facce proiettate contenute PtrOwner pSfrProj( CreateSurfFlatRegion()) ; - if( ! IsNull( pSfrProj) && ProjectEdgesOnSelFace( pSrfpCompo, pSurf, vBannedId, nFacet, pSfrProj)) { + if ( ! IsNull( pSfrProj) && ProjectEdgesOnSelFace( pSrfpCompo, pSurf, vBannedId, nFacet, pSfrProj)) { // sto modificando le singole superifici, quindi superificie del bordo esterno e superificie delle isole !!! - if( i == 0) { - if( ! pSrfpCompo->Subtract( *pSfrProj)) + if ( i == 0) { + if ( ! pSrfpCompo->Subtract( *pSfrProj)) return false ; } else { - if( ! pSrfpCompo->Add( *pSfrProj)) + if ( ! pSrfpCompo->Add( *pSfrProj)) return false ; } bIspCompoMod = true ; @@ -1269,33 +1269,18 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) // se questa nuova superificie è modificata rispetto a quella selezionata, devo aggiornare le curve, con quelle // della nuova FlatRegion - if( bIspCompoMod) { + if ( bIspCompoMod) { // scorro ora il bordo della mia superificie if( pSrfpCompo->GetChunkCount() == 0) return false ; PtrOwner pCrvBorder( GetCurveComposite( pSrfpCompo->GetLoop( 0, 0))) ; - if( IsNull( pCrvBorder) || pCrvBorder->GetCurveCount() == 0) + if ( IsNull( pCrvBorder) || pCrvBorder->GetCurveCount() == 0) return false ; - for( int c = 0 ; c < pCrvBorder->GetCurveCount() ; ++ c) { - // alle curve a cui riesco a fare un overlap copio le stesse TmpProp - // a quelle che non fanno overlap le segno chiuse - /* - int nIndC = -1 ; - if( GetCurveByOverlap( pCrvBorder->GetCurve( c), pCrvCompo, nIndC) && nIndC != -1) { - int nProp0 = -1 ; pCrvCompo->GetCurveTempProp( nIndC, nProp0, 0) ; - int nProp1 = -1 ; pCrvCompo->GetCurveTempProp( nIndC, nProp1, 1) ; - pCrvBorder->SetCurveTempProp( c, nProp0, 0) ; - pCrvBorder->SetCurveTempProp( c, nProp1, 1) ; - } - else { - pCrvBorder->SetCurveTempProp( c, 0, 0) ; - pCrvBorder->SetCurveTempProp( c, -1, 1) ; - } - */ + for ( int c = 0 ; c < pCrvBorder->GetCurveCount() ; ++ c) { int nStat = 0 ; - if( ! SetTmpPropByOverlap( pCrvBorder, c, pCrvCompo, nStat)) + if ( ! SetTmpPropByOverlap( pCrvBorder, c, pCrvCompo, nStat)) return false ; - if( nStat == 0 || nStat == 2) { // se non c'è overlap o geometria complessa + if ( nStat == 0 || nStat == 2) { // se non c'è overlap o geometria complessa pCrvBorder->SetCurveTempProp( c, 0, 0) ; // lato chiuso pCrvBorder->SetCurveTempProp( c, -1, 1) ; // lato esterno non definito } @@ -2473,6 +2458,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ; SetFeed( dFeed) ; + DrawColoredCrvForFeedTest( pCurve, dFeed) ; if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; Point3d ptP3 = pLine->GetEnd() ; @@ -2705,13 +2691,15 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c //} } // elaborazioni sulla curva corrente - double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; - double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? + 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( GetFeed()) ; if ( AddLinearMove( ptP3) == GDB_ID_NULL) return false ; } @@ -2722,7 +2710,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c Vector3d vtN = pArc->GetNormVersor() ; Point3d ptP3 ; pArc->GetEndPoint( ptP3) ; - SetFeed( GetFeed()); + //SetFeed( GetFeed()); if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) return false ; } @@ -2872,13 +2860,11 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC int nStatus = 0 ; // 0 -> inizio oppure ho inserito una parte di isola | 2 -> sto inserendo un segmento Point3d ptS_ref ; - PtrOwner plastLine( CreateCurveLine()) ; - - // creo dinamicamente la superificie svuotata ( per Feed ) - PtrOwner PSrfRemoved( CreateSurfFlatRegion()) ; - if ( IsNull( PSrfRemoved)) - return false ; - bool bFirstLine = true ; // flag per prima linea in assoluto + PtrOwner pLastSeg( CreateCurveComposite()) ; // ultimo segmento nel percorso + PtrOwner pCrvLink( CreateCurveComposite()) ; // ultimo link aggiunto + // vettore dei link aggiunti ( per Feed ) + ICRVCOMPOPOVECTOR vAddedLinks ; + bool bFirstLine = true ; // flag per prima linea di ogni percorso // creo i percorsi di svuotatura vpCrvs.reserve( nCount) ; @@ -2913,105 +2899,81 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC // aggiungo la sezione alla curva Section& Sec = vvSec[nI][nJ] ; Sec.bActive = false ; - vpCrvs.back()->AddLine( vvSec[nI][nJ].ptE) ; + // creo i vettori con le linee Under e Above nella struttura della Section + ICURVEPOVECTOR vLineAbove ; + if ( nI < nYStep) { + for ( int a = 0 ; a < ( int)vvSec[nI + 1].size() ; ++ a) { + if ( vvSec[nI + 1][a].bActive) + continue ; + PtrOwner pLA( CreateCurveLine()) ; + pLA->Set( vvSec[nI + 1][a].ptS, vvSec[nI + 1][a].ptE) ; + vLineAbove.emplace_back( Release( pLA)) ; + } + } + ICURVEPOVECTOR vLineUnder ; + if ( nI > 0) { + for ( int u = 0 ; u < ( int)vvSec[nI - 1].size() ; ++ u) { + if ( vvSec[ nI - 1][u].bActive) + continue ; + PtrOwner pLU( CreateCurveLine()) ; + pLU->Set( vvSec[nI - 1][u].ptS, vvSec[nI - 1][u].ptE) ; + vLineUnder.emplace_back( Release( pLU)) ; + } + } + // creo la linea come curva composita, aggiungerò dei Joint per ogni tratto con Feed differente + PtrOwner pLineCompo( CreateCurveComposite()) ; + if ( IsNull( pLineCompo)) + return false ; + + Point3d ptE_l ; + if ( bFirstLine) + ptE_l = vvSec[nI][nJ].ptS ; + else + vpCrvs.back()->GetEndPoint( ptE_l) ; + + pLineCompo->AddPoint( ptE_l) ; + pLineCompo->AddLine( vvSec[nI][nJ].ptE) ; + if ( ! AssignFeedZigZagOneWay( pLineCompo, false, vLineAbove, vLineUnder, vAddedLinks)) // Assegno la Feed + return false ; + bFirstLine = false ; + vpCrvs.back()->AddCurve( pLineCompo->Clone()) ; // aggiungo la curva al percorso if ( nStatus == 0) { // primo segmento per il raccordo smussato - plastLine.Set( CloneCurveLine( vpCrvs.back()->GetLastCurve())) ; - plastLine->GetStartPoint( ptS_ref) ; + pLastSeg.Set( pLineCompo) ; + pLastSeg->GetStartPoint( ptS_ref) ; } if ( nStatus == 2) { // ho precedentemente aggiunto il bordo di un'isola, quindi mi salvo il secondo segmento - PtrOwner pSeg2( CloneCurveLine( vpCrvs.back()->GetLastCurve())) ; - PtrOwner pCrvLink( CreateCurveComposite()) ; - PtrOwner pSeg1( CloneCurveLine( plastLine)) ; - if ( CalcBoundedZigZagLink( pSeg1, pSeg2, vFirstOff, pCrvLink)) { // se riesco a creare una semicirconferenza ... - double dUE ; // parametro finale della curva totale fino ad ora - vpCrvs.back()->GetParamAtPoint( ptS_ref, dUE) ; // punto finale della curva totale fino ad ora - PtrOwner pCrvToSave( CreateCurveComposite()) ; // tratto di curva precedente a pSeg1, pCrvLink, pSeg2 - if ( dUE != 0) // se il tratto di curva precedente esiste ... - pCrvToSave.Set( GetCurveComposite( vpCrvs.back()->CopyParamRange( 0, dUE))) ; // ... lo salvo - PtrOwner pCrvS1_Link_S2( CreateCurveComposite()) ; - if ( IsNull( pCrvS1_Link_S2)) - return false ; - pCrvS1_Link_S2->AddCurve( Release( pSeg1)) ; // aggiungo al tratto precedente il pSeg1 (trimmed alla fine) - pCrvS1_Link_S2->AddCurve( Release( pCrvLink)) ; // aggiungo la semicirconferenza - pCrvS1_Link_S2->AddCurve( Release( pSeg2)) ; // aggiungo il pSeg2 (trimmed all'inizio) + PtrOwner pSeg1( CloneCurveComposite( pLastSeg)) ; + PtrOwner pSeg2( CloneCurveComposite( pLineCompo)) ; - // ora che ho creato la curva formata da Segmento - Raccordo - Segmento, assegno la Feed a questi tratti - if ( ! AssignFeedForZigZagParts( pCrvS1_Link_S2, bFirstLine, PSrfRemoved, plastLine->GetTempProp( 0)) || - ! GetDynamicClearedRegion( PSrfRemoved, pCrvS1_Link_S2)) - return false ; - bFirstLine = false ; + if ( ! CalcZigZagLink( pSeg1, pSeg2, pCrvLink)) + return false ; - pCrvToSave->AddCurve( Release( pCrvS1_Link_S2)) ; - vpCrvs.back()->Clear() ; - vpCrvs.back()->AddCurve( Release( pCrvToSave)) ; // sistemo il percorso - } - else { // ... se non ho creato una semicirconferenza cerco di smussare pSeg1 - pCrvLink - pSeg2 (pCrvlink è il tratto di isola) - double dUS, dUE, dUS_I, dUE_I ; - vpCrvs.back()->GetDomain( dUS, dUE) ; // dominio del percorso - vpCrvs.back()->GetParamAtPoint( ptS_ref, dUS) ; // dUS -> parametro della curva totale nel punto iniziale di pSeg1 - PtrOwner pCrvToSmooth( CreateCurveComposite()) ; // curva smussata pSeg1 - pCrvLink - pSeg2 - pCrvToSmooth->AddCurve( vpCrvs.back()->CopyParamRange( dUS, dUE)) ; - - double dLen1, dLenI_s, dLenI_e, dLen2 ; + // aggiorno il vettore delle curve ZigZag + Point3d ptE_Seg1 ; + pSeg1->GetEndPoint( ptE_Seg1) ; + double dUS_Link = EPS_SMALL ; + vpCrvs.back()->GetParamAtPoint( ptE_Seg1, dUS_Link) ; + vpCrvs.back()->TrimEndAtParam( dUS_Link) ; - PtrOwner pCrv1( CreateCurveLine()) ; // segmento pSeg1 - Point3d pt1, pt2 ; - pCrvToSmooth->GetFirstCurve()->GetStartPoint( pt1) ; - pCrvToSmooth->GetFirstCurve()->GetEndPoint( pt2) ; - pCrv1->Set( pt1, pt2) ; - PtrOwner pCrv2( CreateCurveLine()); // segmento pSeg2 - pCrvToSmooth->GetLastCurve()->GetStartPoint( pt1) ; - pCrvToSmooth->GetLastCurve()->GetEndPoint( pt2) ; - pCrv2->Set( pt1, pt2) ; + //AssignFeedZigZagLink( pCrvLink) ; // assegno la Feed al Link + if ( ! AssignFeedZigZagOneWay( pCrvLink, true, vLineAbove, vLineUnder, vAddedLinks)) + return false ; - Point3d ptSH, ptEH ; // punto iniziale sul pSeg1 - pCrv1->GetEndPoint( ptSH) ; vpCrvs.back()->GetParamAtPoint( ptSH, dUS_I) ; // parametro sulla curva globale di inizio di pCrvLink - pCrv2->GetStartPoint( ptEH) ; vpCrvs.back()->GetParamAtPoint( ptEH, dUE_I) ; // paramtro sulla curva globale di fine di pCrvLink - PtrOwner pCrvIsl( CreateCurveComposite()) ; // segmento pCrvLink - pCrvIsl->AddCurve( vpCrvs.back()->CopyParamRange( dUS_I, dUE_I)) ; - + vpCrvs.back()->AddCurve( pCrvLink->Clone()) ; // aggiungo il Link + vpCrvs.back()->AddCurve( pSeg2->Clone()) ; // aggiungo pSeg2 - pCrv1->GetLength( dLen1) ; // lunghezza di pSeg1 - pCrv2->GetLength( dLen2) ; // lunghezza di pSeg2 - pCrvIsl->GetFirstCurve()->GetLength( dLenI_s) ; // lunghezza prima curva di PCrvLink - pCrvIsl->GetLastCurve()->GetLength( dLenI_e) ; // lunghezza ultima curva di pCrvLink + // aggiorno il vettore dei Link ( nel caso sia un link tra due segmenti sullo stesso livello ) + Point3d ptS1 ; + pSeg1->GetStartPoint( ptS1) ; + Point3d ptS2 ; + pSeg2->GetStartPoint( ptS2) ; + if ( abs( ptS1.y - ptS2.y) < 50 * EPS_SMALL) + vAddedLinks.emplace_back( pCrvLink->Clone()) ; - // raccordo tra pSeg1 e pCrvLink - double dTollLeft = 1 - ( dLen1 - ( m_TParams.m_dTDiam / 16)) / dLen1 ; // % parametro sinistro per smusso - double dTollRight = ( m_TParams.m_dTDiam / 16) / dLenI_s ; // % parametro destro di smusso - PtrOwner pCrv_1I( CreateCurveComposite()) ; // curva unione di pSeg1 e pCrvLink smussata - pCrv_1I->AddCurve( pCrv1->Clone()) ; pCrv_1I->AddCurve( pCrvIsl->Clone()) ; - ModifyCurveToSmoothed( pCrv_1I, dTollLeft, dTollRight) ; - - double dUS_1IH, dUE_1IH, dToTLen ; - pCrv_1I->GetDomain( dUS_1IH, dUE_1IH) ; // dominio della curva smussata tra pSeg1 e PCrvLink - pCrv_1I->GetLength( dToTLen) ; // nuova lunghezza della curva smussata tra pSeg1 e pCrvLink - dTollLeft = 1 - ( dLenI_e - ( m_TParams.m_dTDiam / 16)) / dLenI_e ; // % paramtro sinistro per smusso - dTollRight = ( m_TParams.m_dTDiam / 16) / dLen2 ; // % parametro destro per smusso - PtrOwner pCrv_I2( CreateCurveComposite()) ; // curva unione del primo smusso con pSeg2 (il tutto smussato) - pCrv_I2->AddCurve( pCrv_1I->Clone()) ; pCrv_I2->AddCurve( pCrv2->Clone()) ; - ModifyCurveToSmoothed( pCrv_I2, dTollLeft, dTollRight) ; - - PtrOwner pCrvToSave( CreateCurveComposite()) ; - if ( dUS != 0) - pCrvToSave->AddCurve(( vpCrvs.back()->CopyParamRange( 0, dUS))) ; - - // ora che ho creato la curva formata da Segmento - Raccordo - Segmento, assegno la Feed a questi tratti - if ( ! AssignFeedForZigZagParts( pCrv_I2, bFirstLine, PSrfRemoved, plastLine->GetTempProp( 0)) || - ! GetDynamicClearedRegion( PSrfRemoved, pCrv_I2)) - return false ; - bFirstLine = false ; - - pCrvToSave->AddCurve( Release( pCrv_I2)) ; - vpCrvs.back()->Clear() ; - vpCrvs.back()->AddCurve( Release( pCrvToSave)) ; - - } - // pSeg2 ora diventa pSeg1 e il procedimento si itera per tutto il percorso - plastLine.Set( CloneCurveLine( vpCrvs.back()->GetLastCurve())) ; - plastLine->GetStartPoint( ptS_ref) ; + // pSeg2 ora diventa pSeg1 e il procedimento si itera per tutto il percorso + pLastSeg.Set( Release( pSeg2)) ; } // cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno double dUstart = Sec.dOe ; @@ -3084,6 +3046,8 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC pCopy->GetLocalBBox( b3Copy) ; if ( ! b3Copy.IsEmpty() && ( b3Copy.GetMax().y - b3Copy.GetMin().y) < dYStep + 10 * EPS_SMALL) { // tengo la curva (non ritorno indietro più dello step) Point3d ptS, ptE ; + pCrvLink->Clear() ; + pCrvLink->AddCurve( pCopy->Clone()) ; vpCrvs.back()->AddCurve( Release( pCopy)) ; nStatus = 2 ; // aggiunta parte di isola // aggiungo il Link @@ -3106,23 +3070,15 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC //---------------------------------------------------------- bool -Pocketing::GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICURVEPOVECTOR& vLinks, ISurfFlatRegion* pSrfToCut) { - - // controllo dei parametri +Pocketing::GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICURVEPOVECTOR& vLinks, + const ICurveComposite* pCrv_orig, ISurfFlatRegion* pSrfToCut) +{ + + // controllo dei parametri if ( vFirstOffs.size() == 0 || ( int)vCrvs.size() < ( int)vFirstOffs.size()) return false ; pSrfToCut->Clear() ; - // copio il vettore delle curve di Offset e dei link - ICRVCOMPOPOVECTOR vCrvOffs ; vCrvOffs.reserve(( int)vCrvs.size()) ; - ICURVEPOVECTOR vCrvLinks ; //vCrvLinks.reserve(( int)vLinks.size()) ; - for ( int i = 0 ; i < ( int)vCrvs.size() ; ++ i) - vCrvOffs.emplace_back( vCrvs[i]->Clone()) ; - for ( int i = 0 ; i < ( int)vLinks.size() ; ++ i) { - if ( ! IsNull( vLinks[i])) - vCrvLinks.emplace_back( vLinks[i]->Clone()) ; - } - // 1) creo la regione esterna PtrOwner pSrfExtern( CreateSurfFlatRegion()) ; if ( IsNull( pSrfExtern)) @@ -3138,27 +3094,74 @@ Pocketing::GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& } } - // 2) Creo la regione svuotata dal Tool + // ---- le seguenti regioni sono distinte per calcolar emeglio la Feed ---- + // 2) Creo la regione svuotata dal Tool negli Offset, nei Links e sia dagli Offsets che dai Links + PtrOwner pSrfTool_Offs( CreateSurfFlatRegion()) ; + PtrOwner pSrfTool_Links( CreateSurfFlatRegion()) ; PtrOwner pSrfTool( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfTool)) + if ( IsNull( pSrfTool_Offs) || IsNull( pSrfTool_Links) || IsNull( pSrfTool)) return false ; - for ( int i = 0 ; i < int( vCrvOffs.size()) ; ++ i) { - PtrOwner pSrfToolRegOffi( GetSurfFlatRegionFromFatCurve( Release( vCrvOffs[i]) , m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false)) ; - int bianco = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pSrfToolRegOffi->Clone()) ; - m_pGeomDB->SetMaterial( bianco, WHITE) ; - if ( i == 0) - pSrfTool.Set( pSrfToolRegOffi) ; - else - pSrfTool->Add( *pSrfToolRegOffi) ; + // creo un vettore che conterrà solamente i Link percorsi fino ad Ora + ICRVCOMPOPOVECTOR vLinks_done ; + + for ( int i = m_Params.m_nSubType == POCKET_SUB_SPIRALIN ? 0 : ( int)vCrvs.size() - 1 ; + m_Params.m_nSubType == POCKET_SUB_SPIRALIN ? i < int( vCrvs.size()) : i >= 0 ; + m_Params.m_nSubType == POCKET_SUB_SPIRALIN ? ++ i : -- i) { + + // ================= LINK ================================ + if ( i <= ( int)vLinks.size() && ! IsNull( vLinks[i]) && vLinks[i]->IsValid()) { + + // Feed + PtrOwner pCompoLink_i( CreateCurveComposite()) ; + if ( IsNull( pCompoLink_i)) + return false ; + pCompoLink_i->AddCurve( vLinks[i]->Clone()) ; + if ( ! AssignFeedSpiral( pCompoLink_i, pSrfTool_Offs, true, vLinks_done, pCrv_orig, m_TParams.m_dDiam / 3)) + return false ; + + // per Link ... + PtrOwner pCrvLink_i( vLinks[i]->Clone()) ; + if ( IsNull( pCrvLink_i)) + return false ; + PtrOwner pSrfToolRegLinki( GetSurfFlatRegionFromFatCurve( Release( pCrvLink_i), m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false)) ; + if ( ! IsNull( pSrfToolRegLinki)) { + if ( ! pSrfTool_Links->IsValid() || pSrfTool_Links->GetChunkCount() == 0) + pSrfTool_Links.Set( pSrfToolRegLinki) ; + else + pSrfTool_Links->Add( *pSrfToolRegLinki) ; + } + + // risetto il Link come curva composita ... + vLinks[i].Set( pCompoLink_i->Clone()) ; + + // inserisco il Link nel vettore dei Link percorsi + vLinks_done.emplace_back( Release( pCompoLink_i)) ; + } + + // ================== OFFSET ============================= + // Feed + if ( ! AssignFeedSpiral( vCrvs[i], pSrfTool_Offs, false, vLinks_done, pCrv_orig, m_TParams.m_dDiam / 3)) + return false ; + + // aggiorno la superificie svuotata + PtrOwner pCrvOffs_i( CloneCurveComposite( vCrvs[i])) ; + if ( IsNull( pCrvOffs_i)) + return false ; + PtrOwner pSrfToolRegOffi( GetSurfFlatRegionFromFatCurve( Release( pCrvOffs_i) , m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false)) ; + if ( ! IsNull( pSrfToolRegOffi)) { + if ( ! pSrfTool_Offs->IsValid() || pSrfTool_Offs->GetChunkCount() == 0) + pSrfTool_Offs.Set( Release( pSrfToolRegOffi)) ; + else + pSrfTool_Offs->Add( *pSrfToolRegOffi) ; + } } - for ( int i = 0 ; i < int( vCrvLinks.size()) ; ++ i) { - PtrOwner pSrfToolRegLinki( GetSurfFlatRegionFromFatCurve( Release( vCrvLinks[i]), m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false)) ; - pSrfTool->Add( *pSrfToolRegLinki) ; - } + // 3) Calcolo la superificie svuotata + pSrfTool.Set( pSrfTool_Offs) ; + pSrfTool->Add( *pSrfTool_Links) ; - // 3) Creo la regione contenente tutte le parti non svuotate + // 4) Creo la regione contenente tutte le parti non svuotate pSrfToCut->CopyFrom( pSrfExtern) ; if ( ! pSrfToCut->Subtract( *pSrfTool)) return false ; @@ -3168,22 +3171,19 @@ Pocketing::GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& //---------------------------------------------------------- bool -Pocketing::CalcBoundedZigZagLink( ICurveLine* pCrv1, ICurveLine* pCrv2, ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink, int nIndexCut) { +Pocketing::CalcZigZagLink( ICurveComposite* pCrv1, ICurveComposite* pCrv2, ICurveComposite* pCrvLink) { // controllo dei parametri if ( pCrv1 == nullptr || pCrv2 == nullptr) return false ; - // nIndexCut : 0 -> taglio solo la prima curva | 1 -> taglio solo la seconda curva | 3 -> taglio entrambe le curve - if ( ! ( nIndexCut == 1 || nIndexCut == 2 || nIndexCut == 3 || nIndexCut == 4)) - return false ; - pCrvLink->Clear() ; + pCrvLink->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; // prendo i parametri per il raccordo Vector3d vtS, vtE, vtH ; pCrv1->GetEndDir( vtS) ; pCrv2->GetStartDir( vtE) ; Point3d ptS, ptE, ptE1, ptS2 ; - pCrv1->GetEndPoint( ptS) ; + pCrv1->GetEndPoint( ptS) ; pCrv2->GetStartPoint( ptE) ; vtH = ptE - ptS ; double dLen1, dLen2 ; @@ -3195,66 +3195,115 @@ Pocketing::CalcBoundedZigZagLink( ICurveLine* pCrv1, ICurveLine* pCrv2, ICRVCOMP double dAngle, dAngleH ; double dDist = Dist( ptS, ptE) ; - PtrOwner pCrvH1( CreateCurveLine()) ; - PtrOwner pCrvH2( CreateCurveLine()) ; + // curve per controllo validità del collegamento + PtrOwner pCrvH1( CreateCurveComposite()) ; + PtrOwner pCrvH2( CreateCurveComposite()) ; PtrOwner pCrvTempLink( CreateCurveComposite()) ; PtrOwner pCrvTest( CreateCurveComposite()) ; - if ( IsNull( pCrvH1) || IsNull( pCrvH2) || IsNull( pCrvTempLink) || IsNull( pCrvTest)) return false ; - if ( vtS.GetAngle( vtE, dAngle) && abs( dAngle) < 180 + 5 * EPS_SMALL && abs( dAngle) > 180 - 5 * EPS_SMALL && - vtH.GetAngle( vtE, dAngleH) && abs( dAngleH) < 90 + 5 * EPS_SMALL && abs( dAngleH) > 90 - 5 * EPS_SMALL && - dLen1 > dDist && dLen2 > dDist) { - // creo una semi circonferenza ( nel caso ho tutti angoli di 90 gradi ) - double dRad = dDist / 2 ; - PtrOwner pSemiCir( CreateCurveArc()) ; + if ( vtS.GetAngle( vtE, dAngle) && + abs( dAngle) < ANG_STRAIGHT + 5 * EPS_SMALL && abs( dAngle) > ANG_STRAIGHT - 5 * EPS_SMALL && + vtH.GetAngle( vtE, dAngleH) && + abs( dAngleH) < ANG_RIGHT + 5 * EPS_SMALL && abs( dAngleH) > ANG_RIGHT - 5 * EPS_SMALL && + dLen1 > dDist && dLen2 > dDist && + pCrvLink->GetCurveCount() == 1 && pCrvLink->GetFirstCurve()->GetType() == CRV_LINE) { + + // CREO UNA SEMICIRCONFERENZA + double dRad = dDist / 2 ; // raggio Point3d ptNS, ptNE ; + pCrv1->GetParamAtLength( dLen1 - dRad, dUE1) ; + pCrv2->GetParamAtLength( dRad, dUS2) ; + pCrv1->GetPointD1D2( dUE1, ICurve::FROM_MINUS, ptNS) ; // parametro di intersezione su curva 1 + pCrv2->GetPointD1D2( dUS2, ICurve::FROM_PLUS, ptNE) ; // parametro di intersezione su curva 2 - switch ( nIndexCut) - { - case 1: // taglio solo la prima - pCrv1->GetParamAtLength( dLen1 - dRad, dUE1) ; - break ; - case 2: // taglio solo la seconda - pCrv2->GetParamAtLength( dRad, dUS2) ; - break ; - case 3: // taglio entrambe - pCrv1->GetParamAtLength( dLen1 - dRad, dUE1) ; - pCrv2->GetParamAtLength( dRad, dUS2) ; - break ; - default: - break ; - } - - pCrv1->GetPointD1D2( dUE1, ICurve::FROM_MINUS, ptNS) ; - pCrv2->GetPointD1D2( dUS2, ICurve::FROM_PLUS, ptNE) ; + PtrOwner pSemiCir( CreateCurveArc()) ; if ( pSemiCir->Set2PVN( ptNS, ptNE, vtS, Z_AX)) { - pCrvH1.Set( GetCurveLine( pCrv1->CopyParamRange( dUS1, dUE1))) ; - pCrvH2.Set( GetCurveLine( pCrv2->CopyParamRange( dUS2, dUE2))) ; + pCrvH1.Set( GetCurveComposite( pCrv1->CopyParamRange( dUS1, dUE1))) ; + pCrvH2.Set( GetCurveComposite( pCrv2->CopyParamRange( dUS2, dUE2))) ; pCrvTempLink->AddCurve( pSemiCir->Clone()) ; } - } - else if( dLen1 - m_TParams.m_dDiam / 4 > 50 * EPS_SMALL && dLen2 - m_TParams.m_dDiam / 4 > 50 * EPS_SMALL) { - // lascio solo per voler ottimizzare se si vuole - return false ; + + // controllo finale sui raccordi ammissibili ... + if ( pCrvTest->AddCurve( pCrvH1->Clone()) && pCrvTest->AddCurve( pCrvTempLink->Clone()) && + pCrvTest->AddCurve( pCrvH2->Clone())) { + + pCrv1->TrimEndAtParam( dUE1) ; + pCrvLink->Clear() ; + pCrvLink->AddCurve( Release( pCrvTempLink)) ; + pCrv2->TrimStartAtParam( dUS2) ; + return true ; + } } else { - return false ; - } + // DEVO SMUSSARE LA CURVA FORMATA DA pCrv1 - pCrvLink ( da creare) - pCrv2 - // controllo finale sui raccordi ammissibili ... - if ( pCrvTest->AddCurve( pCrvH1->Clone()) && pCrvTest->AddCurve( pCrvTempLink->Clone()) && - pCrvTest->AddCurve( pCrvH2->Clone())) { - Point3d pt1, pt2 ; - pCrvH1->GetStartPoint( pt1) ; - pCrvH1->GetEndPoint( pt2) ; - pCrv1->Set( pt1, pt2) ; + pCrvH1->AddCurve( pCrv1->Clone()) ; + pCrvH2->AddCurve( pCrv2->Clone()) ; + pCrvTempLink->AddCurve( pCrvLink->Clone()) ; + + // prendo le lunghezze necessarie + double dLenSeg1 = EPS_SMALL ; double dLenSeg2 = EPS_SMALL ; + double dLenI_s = EPS_SMALL ; // lunghezza prima curva del Link + double dLenI_e = EPS_SMALL ; // lunghezza ultima curva del Link + pCrvH1->GetLength( dLenSeg1) ; + pCrvH2->GetLength( dLenSeg2) ; + pCrvTempLink->GetFirstCurve()->GetLength( dLenI_s) ; + pCrvTempLink->GetLastCurve()->GetLength( dLenI_e) ; + + // raccordo pSeg1 con pCrvLink + double dTollLeft = 1 - ( dLen1 - ( m_TParams.m_dTDiam / 16)) / dLen1 ; // % parametro sinistro per smusso + double dTollRight = ( m_TParams.m_dTDiam / 16) / dLenI_s ; // % parametro destro di smusso + PtrOwner pCrv_Seg1_Isl( CreateCurveComposite()) ; // curva unione di pSeg1 e pCrvLink smussata + pCrv_Seg1_Isl->AddCurve( pCrvH1->Clone()) ; + pCrv_Seg1_Isl->AddCurve( pCrvTempLink->Clone()) ; + ModifyCurveToSmoothed( pCrv_Seg1_Isl, dTollLeft, dTollRight) ; + + // raccordo questa curva con pSeg2 + double dUS_1IH, dUE_1IH, dToTLen ; + pCrv_Seg1_Isl->GetDomain( dUS_1IH, dUE_1IH) ; // dominio della curva smussata tra pSeg1 e PCrvLink + pCrv_Seg1_Isl->GetLength( dToTLen) ; // nuova lunghezza della curva smussata tra pSeg1 e pCrvLink + dTollLeft = 1 - ( dLenI_e - ( m_TParams.m_dTDiam / 16)) / dLenI_e ; // % paramtro sinistro per smusso + dTollRight = ( m_TParams.m_dTDiam / 16) / dLen2 ; // % parametro destro per smusso + PtrOwner pCrv_smoothed( CreateCurveComposite()) ; // curva unione del primo smusso con pSeg2 + pCrv_smoothed->AddCurve( pCrv_Seg1_Isl->Clone()) ; + pCrv_smoothed->AddCurve( pCrvH2->Clone()) ; + ModifyCurveToSmoothed( pCrv_smoothed, dTollLeft, dTollRight) ; + + // recupero i parametri del nuovo collegamento che si è creato dallo smusso + pCrvH1->Clear() ; + pCrvTempLink->Clear() ; + pCrvH2->Clear() ; + int nStat = -1 ; + for ( int u = 0 ; u < pCrv_smoothed->GetCurveCount() ; ++ u) { + // recupero la curva u-esima + const ICurve* pCrv = pCrv_smoothed->GetCurve( u) ; + if ( pCrv->GetType() == CRV_LINE) { + if ( CheckSimpleOverlap( pCrv, pCrv1, nStat, EPS_SMALL) && nStat == 1) + pCrvH1->AddCurve( pCrv->Clone()) ; + else if ( CheckSimpleOverlap( pCrv, pCrv2, nStat, EPS_SMALL) && nStat == 1) + pCrvH2->AddCurve( pCrv->Clone()) ; + } + } + + Point3d ptCrv1_e, ptCrv2_s ; + double dULink_s = EPS_SMALL ; + double dULink_e = EPS_SMALL ; + + pCrvH1->GetEndPoint( ptCrv1_e) ; + pCrv1->GetParamAtPoint( ptCrv1_e, dULink_s) ; + pCrv1->TrimEndAtParam( dULink_s) ; + + pCrvH2->GetStartPoint( ptCrv2_s) ; + pCrv2->GetParamAtPoint( ptCrv2_s, dULink_e) ; + pCrv2->TrimStartAtParam( dULink_e) ; + + pCrv_smoothed->GetParamAtPoint( ptCrv1_e, dULink_s) ; + pCrv_smoothed->GetParamAtPoint( ptCrv2_s, dULink_e) ; pCrvLink->Clear() ; - pCrvLink->AddCurve( pCrvTempLink->Clone()) ; - pCrvH2->GetStartPoint( pt1) ; - pCrvH2->GetEndPoint( pt2) ; - pCrv2->Set( pt1, pt2) ; + pCrvLink->AddCurve( GetCurveComposite( pCrv_smoothed->CopyParamRange( dULink_s, dULink_e))) ; + return true ; } @@ -3920,15 +3969,15 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c // le curve ottenute andranno percorse dall'utensile for ( int u = 0 ; u < ( int)vAllCrv.size() ; ++ u) { - // per ogni curva di bordo... + // per ogni curva di bordo... bool bOutTmp = false ; - + PtrOwner pSrfCurrChunk( vSrfSliced[j-1]->CloneChunk( vInd[u])) ; if ( IsNull( pSrfCurrChunk)) return false ; if ( ! SetBetterPtStartForSubChunks( vAllCrv[u], pSrfCurrChunk, - vPtStart[u], vVtMidOut[u], bOutTmp, dOffs)) + vPtStart[u], vVtMidOut[u], bOutTmp, dOffs)) return false ; vbMidOut[u] = bOutTmp ; // vector::reference da Bit a Bool @@ -3989,11 +4038,11 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c //double dFeedRid = min( GetSideStep() / m_TParams.m_dDiam, 1.0) ; // creo la superificie svuotata ( per Feed ) - PtrOwner pSrfRemoved( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfRemoved)) - return false ; - for ( int u = 0 ; u < vAllCrv.size() ; ++ u) - GetDynamicClearedRegion( pSrfRemoved, vAllCrv[u]) ; + //PtrOwner pSrfRemoved( CreateSurfFlatRegion()) ; + //if ( IsNull( pSrfRemoved)) + // return false ; + //for ( int u = 0 ; u < vAllCrv.size() ; ++ u) + // GetDynamicClearedRegion( pSrfRemoved, vAllCrv[u]) ; // ---------------------------- Disegno le curve di contorno ---------------------- @@ -4079,9 +4128,11 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c // } } // 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 ; + DrawColoredCrvForFeedTest( pCurve, dFeed) ; SetFeed( dFeed) ; if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; @@ -4151,6 +4202,11 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c double dYStep = ( nYStep > 0 ? ( dDimY + 2 * dExtra) / nYStep : 0) ; --nYStep ; + // vettore dei segmenti al di sotto della linea corrente ( per la Feed) + ICURVEPOVECTOR vLineUnder ; + ICURVEPOVECTOR vLineAbove ; // in questo caso sempre vuoto + ICRVCOMPOPOVECTOR vCrvLink ; // in questo caso sempre vuoto + // calcolo le linee di svuotatura const double EXP_LEN = 1.0 ; //for ( int j = 1 ; j <= nStep ; ++j) { @@ -4164,6 +4220,14 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c return false ; } + // linea come composita per Feed ( la dovrò spezzare) + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return false ; + + // vettore di tutti i segmenti lineari che si formano nello step nYStep + ICURVEPOVECTOR vAddedLines ; + // riempio il vettore di segmenti CRVCVECTOR ccClassSeg ; pSrfFirstOffs->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ; @@ -4182,16 +4246,22 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c Point3d ptS, ptE ; pCrvSeg->GetStartPoint( ptS) ; - pCrvSeg->GetEndPoint( ptE) ; + //pCrvSeg->GetEndPoint( ptE) ; // imposto la Feed - PtrOwner pCrvCompo( CreateCurveComposite()) ; - if ( IsNull( pCrvCompo)) - return false ; + //vAddedLines.emplace_back( pCrvSeg->Clone()) ; + pCrvCompo->Clear() ; pCrvCompo->AddCurve( pCrvSeg->Clone()) ; - if ( ! AssignFeedOneWay( pCrvSeg, pSrfRemoved) || - ! GetDynamicClearedRegion( pSrfRemoved, pCrvCompo)) + vAddedLines.emplace_back( pCrvCompo->Clone()) ; + if ( ! AssignFeedZigZagOneWay( pCrvCompo, false, vLineAbove, vLineUnder, vCrvLink)) return false ; + //PtrOwner pCrvCompo( CreateCurveComposite()) ; + //if ( IsNull( pCrvCompo)) + // return false ; + //pCrvCompo->AddCurve( pCrvSeg->Clone()) ; + //if ( ! AssignFeedOneWay( pCrvSeg, pSrfRemoved) || + // ! GetDynamicClearedRegion( pSrfRemoved, pCrvCompo)) + // return false ; // INIZIO ptS.ToGlob( frPocket) ; @@ -4225,17 +4295,37 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c return false ; } - ptE.ToGlob( frPocket) ; - ptE.Translate( -vtTool * (dDepth - dElev + j * dStep)) ; + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { - // movimento al punto finale - double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ; - double dFeed = pCrvSeg->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ? - GetFeed() : pCrvSeg->GetTempProp( 0) / FEED_DIVISOR ; - SetFeed( dFeed) ; - //SetFeed( GetFeed()) ; - if ( AddLinearMove( ptE) == GDB_ID_NULL) - return false ; + //ptE.ToGlob( frPocket) ; + //ptE.Translate( -vtTool * (dDepth - dElev + j * dStep)) ; + const ICurve* pCurve( pCrvCompo->GetCurve( u)) ; + pCurve->GetEndPoint( ptE) ; + ptE.ToGlob( frPocket) ; + ptE.Translate( -vtTool * ( dDepth - dElev + j * dStep)) ; + + // movimento al punto finale + // 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 ; + SetFeed( dFeed) ; + //PtrOwner pCrv_TestFeed( pCurve->Clone()) ; + //pCrv_TestFeed->ToGlob( frPocket) ; + //if ( abs( dFeed - GetMinFeed()) < EPS_SMALL) { + // int rosso = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCrv_TestFeed->Clone()) ; + // m_pGeomDB->SetMaterial( rosso, RED) ; + //} + //if ( abs( dFeed - GetMaxFeed()) < EPS_SMALL) { + // int verde = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCrv_TestFeed->Clone()) ; + // m_pGeomDB->SetMaterial( verde, GREEN) ; + //} + SetFeed( dFeed) ; + //SetFeed( GetFeed()) ; + if ( AddLinearMove( ptE) == GDB_ID_NULL) + return false ; + + } // FINE Point3d ptQ ; @@ -4266,6 +4356,9 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } } } + vLineUnder.clear() ; + for ( int u = 0 ; u < ( int)vAddedLines.size() ; ++ u) + vLineUnder.emplace_back( vAddedLines[u]->Clone()) ; } } // fine ciclo sugli step } // fine ciclo sulle superifici ideali @@ -4404,7 +4497,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, /*PNTVECTOR vPtStart,*/ else { for ( int k = 0 ; k < ( int)vCrvOEWithFlags[j-1].size() ; ++ k) { CRVCVECTOR ccClass ; - if( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[j-1][k], EPS_SMALL, ccClass)) { + if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[j-1][k], EPS_SMALL, ccClass)) { bool bIsThis = true ; for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++ kk) { if ( ccClass[kk].nClass == CRVC_OUT) @@ -4426,6 +4519,10 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, /*PNTVECTOR vPtStart,*/ bool bMidOut ; // ammissibilità entrata da fuori int nRegTot = nReg ; + + //int k = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfChunkFinal->Clone()) ; + //m_pGeomDB->SetMaterial( k, WHITE) ; + // calcolo il percorso di svuotatura if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv, vCrvOEWithFlags[j-1][nInd], bOptimizedTrap)) return false ; @@ -4479,7 +4576,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, /*PNTVECTOR vPtStart,*/ bOutStart = ( nOutsideRaw > 0) ; // imposto la Feed AssignFeedSpiralOpt( 1, pMCrv) ; - AssignFeedSpiral( pRCrv, 2, false, false, nullptr, nullptr, nullptr) ; + AssignFeedForReturnPath( pRCrv) ; } // verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro @@ -4577,6 +4674,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, /*PNTVECTOR vPtStart,*/ 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) ; @@ -4816,7 +4914,7 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; bOutStart = ( nOutsideRaw > 0) ; AssignFeedSpiralOpt( 1, pMCrv) ; - AssignFeedSpiral( pRCrv, 2, false, false, nullptr, nullptr, nullptr) ; + AssignFeedForReturnPath( pRCrv) ; } // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore @@ -4909,6 +5007,7 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool 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) ; @@ -5270,64 +5369,21 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt } } + // copio il vettore degli Offset per settare poi la Feed ICRVCOMPOPOVECTOR vOffsFeed ; vOffsFeed.reserve(( int)vOffs.size()) ; for ( int i = 0 ; i < ( int)vOffs.size() ; ++ i) vOffsFeed.emplace_back( vOffs[i]->Clone()) ; // 3) controllo eventuali parti non svuotate... + pCrvOEWithFlags->ToLoc( frPocket) ; PtrOwner pSrfToCut( CreateSurfFlatRegion()) ; - if ( GetUnclearedRegion( vOffsFirstCurve, vOffs, vLinks, pSrfToCut)) { + if ( GetUnclearedRegion( vOffsFirstCurve, vOffs, vLinks, pCrvOEWithFlags, pSrfToCut)) { // 4) Modifico i percorsi if ( ! RemoveExtraParts( pSrfToCut, vOffs, vOffsClosedCurves, vOffsFirstCurve, vLinks)) return false ; } - // 4) Assegno la Feed ad ogni curva - // per prima cosa creo dinamicamente la regione svuotata che si crea curva per curva - PtrOwner pSrfRemoved( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfRemoved)) - return false ; - pCrvOEWithFlags->ToLoc( frPocket) ; - bool bFirstLink = true ; - for ( int i = m_Params.m_nSubType == POCKET_SUB_SPIRALIN ? 0 : ( int)vOffs.size() - 1 ; - m_Params.m_nSubType == POCKET_SUB_SPIRALIN ? i < ( int)vOffs.size() : i >= 0 ; - m_Params.m_nSubType == POCKET_SUB_SPIRALIN ? ++ i : -- i) { - - // per ogni Link - if ( ! IsNull( vLinks[i])) { - PtrOwner pLinkCompo( CreateCurveComposite()) ; - if ( IsNull( pLinkCompo)) - return false ; - pLinkCompo->AddCurve( vLinks[i]->Clone()) ; - if ( ! AssignFeedSpiral( pLinkCompo, 1, false, false, pSrfRemoved, pCrvOEWithFlags, nullptr) || - ! GetDynamicClearedRegion( pSrfRemoved, pLinkCompo)) - return false ; - vLinks[i].Set( pLinkCompo) ; - bFirstLink = false ; - } - - // parametri per le curve - bool bIsFirst = false ; - bool bIsLast = false ; - if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN) { - if ( i == 0) - bIsFirst = true ; - if ( i == ( int)vOffs.size() - 1) - bIsLast = true ; - } - else { - if ( i == ( int)vOffs.size() - 1) - bIsFirst = true ; - if ( i == 0) - bIsLast = true ; - } - // per ogni curva di Offset, creo la regione svuotata e assegno la Feed alle sottocurve... - if ( ! GetDynamicClearedRegion( pSrfRemoved, vOffsFeed[i]) || - ! AssignFeedSpiral( vOffs[i], 0, bIsFirst, bIsLast, pSrfRemoved, pCrvOEWithFlags, vOffsFeed[i])) - return false ; - } - // calcolo il percorso di ritorno if (( int)vOffs.size() >= 2) { pRCrv->Clear() ; @@ -5355,7 +5411,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt } // Feed per percorso di ritorno - AssignFeedSpiral( pRCrv, 2, false, false, nullptr, nullptr, nullptr) ; + AssignFeedForReturnPath( pRCrv) ; } // creo il percorso di lavoro a partire dalla raccolta degli offset e dei collegamenti @@ -6012,13 +6068,13 @@ Pocketing::CutOffsetToClosestPoint( ICRVCOMPOPOVECTOR& vCurves, const Point3d& p if ( nIndex < 0) return false ; - // ricavo le due curve ( l'Offset viene spezzato in due sottocurve mediante il punto trovato ) + // ricavo le due curve ( l'Offset viene spezzato in due sottocurve mediante il punto trovato) double dUTan, dUS, dUE ; - if ( ! vCurves[nIndex]->GetParamAtPoint( ptCL, dUTan) || ! vCurves[nIndex]->GetDomain( dUS, dUE)) - return false ; - - pCrv1->AddCurve(( vCurves[nIndex]->CopyParamRange( dUS, dUTan))) ; - pCrv2->AddCurve(( vCurves[nIndex]->CopyParamRange( dUTan, dUE))) ; + vCurves[nIndex]->GetParamAtPoint( ptCL, dUTan) ; + pCrv1->AddCurve( vCurves[nIndex]->Clone()) ; + pCrv1->TrimEndAtParam( dUTan) ; + pCrv2->AddCurve( vCurves[nIndex]->Clone()) ; + pCrv2->TrimStartAtParam( dUTan) ; return true ; } @@ -6065,17 +6121,19 @@ Pocketing::CutLinkToClosestPoint( ICURVEPOVECTOR& vCurves, ICRVCOMPOPOVECTOR& vO // ricavo le due curve ( il link viene spezzato in due sottocurve mediante il punto trovato ) double dUS, dUE, dUTan ; - if ( ! vCurves[nIndex]->GetDomain( dUS, dUE) || ! vCurves[nIndex]->GetParamAtPoint( ptCL, dUTan)) - return false ; - pCrv1->AddCurve(( vCurves[nIndex]->CopyParamRange( dUS, dUTan))) ; - pCrv2->AddCurve(( vCurves[nIndex]->CopyParamRange( dUTan, dUE))) ; + vCurves[nIndex]->GetParamAtPoint( ptCL, dUTan) ; + pCrv1->AddCurve( vCurves[nIndex]->Clone()) ; + pCrv1->TrimEndAtParam( dUTan) ; + pCrv2->AddCurve( vCurves[nIndex]->Clone()) ; + pCrv2->TrimStartAtParam( dUTan) ; return true ; } //---------------------------------------------------------------------------- bool -Pocketing::GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, Point3d& ptC, bool bCir, ICRVCOMPOPOVECTOR& VFirstOff, ICurveComposite* pCrvNewCurve) { +Pocketing::GetNewCurvetWithCentroid( const ICurveComposite* pCrvH1, const ICurveComposite* pCrvH2, Point3d& ptC, + bool bCir, ICRVCOMPOPOVECTOR& VFirstOff, ICurveComposite* pCrvNewCurve) { PtrOwner pPath1( CreateCurveComposite()) ; PtrOwner pPath2( CreateCurveComposite()) ; @@ -6099,12 +6157,20 @@ Pocketing::GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* p // creo la circonferenza if ( ! CalcBoundedSmootedLink( ptS, vtTanS, ptE, vtTanE, 0, VFirstOff, pPath1)) return false ; + Vector3d vtS_cir ; pPath1->GetStartDir( vtS_cir) ; + Vector3d vtS_CrvH1 ; pCrvH1->GetEndDir( vtS_CrvH1) ; + if ( ! AreSameVectorApprox( vtS_cir, vtS_CrvH1)) + pPath1->Invert() ; + + // Assegno la Feed + if ( ! AssignFeedCrvOnUnclearedRegions( pPath1)) + return false ; // controllo che la circonferenza sia ammissibile ( solo che non esca dalle prime curve di Offset ) Point3d ptCrvS ; pPath1->GetStartPoint( ptCrvS) ; - if ( ! CutCurveByOffsets( pPath1, VFirstOff)) { // taglio la curva sugli Offsets + if ( ! CutCurveByOffsets( pPath1, VFirstOff)) // taglio la curva sugli Offsets return false ; - } + double dUCrvS ; ModifyCurveToSmoothed( pPath1, 0.075, 0.075) ; if ( pPath1->IsClosed()) { @@ -6141,6 +6207,11 @@ Pocketing::GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* p || ! CalcBoundedSmootedLink( ptE, vtTanS, ptS, vtTanS, 0.5, VFirstOff, pPath2)) return false ; + // Assegno la Feed a queste nuove curve + if ( ! AssignFeedCrvOnUnclearedRegions( pPath1) || + ! AssignFeedCrvOnUnclearedRegions( pPath2)) + return false ; + // creo la nuova curva con il doppio Biarco if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio @@ -6157,7 +6228,7 @@ Pocketing::GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* p //---------------------------------------------------------------------------- bool -Pocketing::GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, ICurveComposite* pCrvPath, ICRVCOMPOPOVECTOR& VFirstOff, ICRVCOMPOPOVECTOR& VoffsCl, ICurveComposite* pCrvNewCurve) { +Pocketing::GetNewCurvetWithPath( const ICurveComposite* pCrvH1, const ICurveComposite* pCrvH2, ICurveComposite* pCrvPath, ICRVCOMPOPOVECTOR& VFirstOff, ICRVCOMPOPOVECTOR& VoffsCl, ICurveComposite* pCrvNewCurve) { PtrOwner pPath1( CreateCurveComposite()) ; PtrOwner pPath2( CreateCurveComposite()) ; @@ -6204,6 +6275,10 @@ Pocketing::GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH if ( ! ManageSmoothAndAutoInters( pCrvToAdd, pCrvPath, pPath1, pPath2, VoffsCl)) return false ; + // alla curva ottenuta setto la Feed + if ( ! AssignFeedCrvOnUnclearedRegions( pCrvToAdd)) + return false ; + // curva finale if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio @@ -6221,12 +6296,18 @@ Pocketing::GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH if ( ! CalcBoundedSmootedLink( ptHS, vtHS, ptHE, vtHE, 0.5, VFirstOff, pCrvBiArcHelper)) if ( ! CalcBoundedLink( ptHS, ptHE, VFirstOff, pCrvBiArcHelper)) return false ; + + // assegno la Feed ... + if ( ! AssignFeedCrvOnUnclearedRegions( pCrvBiArcHelper)) + return false ; + if ( ! pCrvNewCurve->AddCurve( Release( pCrvBiArcHelper)) || ! pCrvNewCurve->AddCurve( pCrvToAdd->Clone())) return false ; } if ( pCrvH2 != nullptr && pCrvH2->GetFirstCurve() != nullptr) { if ( ! pCrvNewCurve->AddCurve( pCrvH2->Clone())) { // aggiungo fine + // nel caso non funzioni questo raccordo, recupero un biarco valido e uso questo ... int nTry = 1 ; int nMaxTry = 10 ; bool bFound = false ; while ( nTry < nMaxTry && ! bFound) { Vector3d vtHS, vtHE ; @@ -6239,6 +6320,11 @@ Pocketing::GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH if ( ! CalcBoundedSmootedLink( ptHS, vtHS, ptHE, vtHE, 0.5, VFirstOff, pCrvBiArcHelper)) if ( ! CalcBoundedLink( ptHS, ptHE, VFirstOff, pCrvBiArcHelper) ) return false ; + + // assegno la Feed ... + if ( ! AssignFeedCrvOnUnclearedRegions( pCrvBiArcHelper)) + return false ; + if ( ! pCrvNewCurve->AddCurve( pCrvBiArcHelper->Clone()) || ! pCrvNewCurve->AddCurve( pCrvH2->Clone())) { ++nTry ; @@ -7092,8 +7178,15 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d return false ; } + // creo la superificie per la Feed + PtrOwner pSrfRemoved( CreateSurfFlatRegion()) ; + if ( IsNull( pSrfRemoved)) + return false ; + ICRVCOMPOPOVECTOR vLinksDone ; + Vector3d vtDir = pArc->GetStartVersor() ; pMCrv->AddCurve( Release( pArc)) ; + // se richiesta percorrenza invertita if ( m_Params.m_bInvert) pMCrv->Invert() ; @@ -7129,7 +7222,7 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d return false ; } - // setto la feed per la curva a spirale + // Assegno la Feed al percorso AssignFeedSpiralOpt( 0, pMCrv) ; // eventuale sistemazione archi @@ -7150,7 +7243,7 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d pRCrv->Invert() ; // setto la feed per il percorso di ritorno - AssignFeedSpiral( pRCrv, 2, false, false, nullptr, nullptr, nullptr) ; + AssignFeedForReturnPath( pRCrv) ; VerifyArcs( pRCrv) ; } @@ -8389,6 +8482,10 @@ bool Pocketing::GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOtherCrv, Point3d& ptMid, Vector3d& vtMidOrt) { + + //int Y = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompo->Clone()) ; + //m_pGeomDB->SetMaterial( Y, YELLOW) ; + // recupero il vettore estrusione Vector3d vtExtr = Z_AX ; pCompo->GetExtrusion( vtExtr) ; @@ -8488,7 +8585,8 @@ Pocketing::GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOV //---------------------------------------------------------------------------- bool -Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vCrvIsl) +Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vCrvIsl, + double dTool_Diam, double dOffR) { // vettore estrusione @@ -8500,7 +8598,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP // sposto l'inizio a metà del tratto più lungo AdjustContourStart( pCompo, vCrvIsl) ; // raggio di riferimento per offset - double dRad = 0.5 * m_TParams.m_dDiam + GetOffsR() ; + double dRad = 0.5 * dTool_Diam + dOffR ; // estraggo parti con proprietà uniforme in un vettore ICURVEPOVECTOR vpCrvs ; int nCurrTempProp ; @@ -8541,6 +8639,10 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP // ---------- PtrOwner pCrvRange( CreateCurveComposite()) ; pCrvRange->AddCurve( vpCrvs[i]->Clone()) ; + + //int W = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvRange->Clone()) ; + //m_pGeomDB->SetMaterial( W, WHITE) ; + for ( int j = 0 ; j < pCrvRange->GetCurveCount() ; ++ j) pCrvRange->SetCurveTempProp( j, 1, 0) ; vpCrvs[i].Set( pCrvRange) ; @@ -8548,12 +8650,11 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP // ---------- } } - // reinserisco le curve, chiudendo eventuali gap pCompo->Clear() ; pCompo->SetExtrusion( vtExtr) ; bool bOpenCurr = false ; - double dDiam = 1.05 * m_TParams.m_dDiam + 2 * GetOffsR() ; + double dDiam = 1.05 * dTool_Diam + 2 * dOffR ; for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { // stato curve bool bOpenPrev = bOpenCurr ; @@ -8577,6 +8678,13 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP pJCrv->AddPoint( ptLine) ; pJCrv->AddLine( ptArc, false) ; pJCrv->AddArcTg( ptEnd, false) ; + + //int y = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pJCrv->Clone()) ; + //m_pGeomDB->SetMaterial( y, YELLOW) ; + + // assegno alle sue sottocurve la proprietà di curva aperta + for ( int u = 0 ; u < pJCrv->GetCurveCount() ; ++ u) + pJCrv->SetCurveTempProp( u, 1, 0) ; // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta pJCrv->ToLoc( frPocket) ; vpCrvs[i]->ToLoc( frPocket) ; @@ -8600,8 +8708,10 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP vpCrvs[i]->TrimStartAtParam( aInfo.IciB[0].dU) ; pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ; } - else + else { pCompo->AddLine( ptStart) ; + pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, 1, 0) ; // segmento come curva aperta + } } // se passo da aperto a chiuso else if ( bOpenPrev && ! bOpenCurr) { @@ -8617,6 +8727,13 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP pJCrv->AddPoint( ptLine) ; pJCrv->AddLine( ptArc) ; pJCrv->AddArcTg( ptStart) ; + + //int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pJCrv->Clone()) ; + //m_pGeomDB->SetMaterial( a, ORANGE) ; + + // assegno alle sue sottocurve la proprietà di curva aperta + for ( int u = 0 ; u < pJCrv->GetCurveCount() ; ++ u) + pJCrv->SetCurveTempProp( u, 1, 0) ; // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta PtrOwner pLCrv( CreateCurveComposite()) ; if ( IsNull( pLCrv)) @@ -8638,15 +8755,23 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOP pJCrv->TrimStartAtParam( aInfo.IciA[0].dU) ; pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ; } - else + else { pCompo->AddLine( ptStart) ; + pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, 1, 0) ; // segmento come curva aperta + } } - else + else { pCompo->AddLine( ptStart) ; + pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, 1, 0) ; // segmento come curva aperta + } } } // aggiungo la curva pCompo->AddCurve( ::Release( vpCrvs[i]), true, 10 * EPS_SMALL) ; + + //int p = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompo->Clone()) ; + //m_pGeomDB->SetMaterial( p, PURPLE) ; + } // non dovrebbe esserci un gap, ma meglio prevenire problemi pCompo->Close() ; @@ -8692,7 +8817,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& const ICurve* pCrvClone( pCompo->GetCurve( nMax)) ; double dPar ; if ( GetParamForPtStartOnEdge( pCrvClone, pCompo, vCrvIsl, dPar)) - pCompo->ChangeStartPoint( dPar) ; + pCompo->ChangeStartPoint( nMax + dPar) ; else { // sposto inizio a metà if ( nMax >= 0) @@ -8700,7 +8825,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& } } - // se invece csto cercando di entrare da un lato chiuso per una svuotatura, allora riordino i lati + // 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 // un'entrata sufficientemente distante da isole e da altre curve della curva stessa su cui cerco l'entrata ... else { @@ -8887,7 +9012,7 @@ Pocketing::CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const Vec //---------------------------------------------------------------------------- bool -Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ICRVCOMPOPOVECTOR& vCrvOEFlags, +Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ICRVCOMPOPOVECTOR& vCrvOEFlags, bool& bChanged, double dAreaToll) { @@ -8901,7 +9026,7 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ICRVCOMPOPO return false ; double dThick ; pCrv->GetThickness( dThick) ; Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ; - // recupero la temp prop 0 + // recupero la temp prop 0 ( id per gruppo del grezzo corrente) int nProp0 = pCrv->GetTempProp( 0) ; // ricavo il grezzo attuale della lavorazione @@ -8913,21 +9038,29 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ICRVCOMPOPO if ( pStmRaw->IsValid() || pStmRaw->GetTriangleCount() > 0) { // interseco la superificie con il grezzo - if ( ! IntersSurfWithRaw( pSrf, pStmRaw, vtTrasl, bChanged)) - return false ; + if ( m_IntersRaw) { + if ( ! IntersSurfWithRaw( pSrf, pStmRaw, vtTrasl, bChanged)) + return false ; + } // proietto il grezzo - if ( ! ProjectRaw( pSrf, vtTrasl, pStmRaw)) - return false ; + if ( m_ProjectRaw) { + if ( ! ProjectRaw( pSrf, vtTrasl, pStmRaw)) + return false ; + } // aggiusto i bordi nel caso di Tool non cilindrico // --- } - // creo la superifcie da restituire ( aggiornamento ) + // creo la superifcie da restituire ( aggiornamento) PtrOwner pSrfFinal( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfFinal)) + PtrOwner pSrf_noOpenEdge( CloneSurfFlatRegion( pSrf)) ; + if ( IsNull( pSrfFinal) || IsNull( pSrf_noOpenEdge)) return false ; + //int v = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf->Clone()) ; + //m_pGeomDB->SetMaterial( v, PURPLE) ; + // per ogni Chunck della superificie ottenuta... for ( int c = 0 ; c < pSrf->GetChunkCount() ; ++ c) { @@ -8956,7 +9089,8 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ICRVCOMPOPO } if ( bSomeOpen) { // se trovo dei lati aperti // 3.1) sistemo la superificie - if ( ! AdjustContourWithOpenEdges( pCrvExt, vCrvIsl)) { + if ( ! AdjustContourWithOpenEdges( pCrvExt, vCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, + m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR())) { m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; return false ; } @@ -8968,11 +9102,17 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, ICRVCOMPOPO pSrfFinal->AddIntLoop( Release( vCrvIsl[i])) ; } - // se parametrri Off+ sOTTR + // se superificie già lavorata in precedenza ... + if ( m_dDiam_Prec > 0) { + if ( ! GetNewSrfByAnotherPocketing( pSrfFinal, pSrf_noOpenEdge)) + return false ; + } - // restituisco la nuova superificie + + // aggiorno la superificie pSrf->Clear() ; pSrf->CopyFrom( pSrfFinal) ; + return pSrf->IsValid() && pSrf->GetChunkCount() != 0 ; } @@ -9257,7 +9397,11 @@ Pocketing::CheckBoundingPointForIslands( ICurveComposite* pCrvCurr, int nInd, co //---------------------------------------------------------------------------- bool -Pocketing::GetStmRawPart( int nId, ISurfTriMesh* pSrfTMRaw, Frame3d frPocket) { +Pocketing::GetStmRawPart( int nId, ISurfTriMesh* pSrfTMRaw, Frame3d frPocket) +{ + // controllo se ho i flag abilitati + if ( !m_IntersRaw && !m_ProjectRaw) + return true ; // controllo MachManager e database geometrico if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) @@ -9721,15 +9865,26 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl, const ISu } } if ( ! bCEFound) { // se la curva ha tutti lati aperti, allora la imposto uguale alla proiezione del grezzo + pCrvExtSfr->Clear() ; pCrvExtProj->ToGlob( frLoc) ; - pCrvExtSfr->AddCurve( pSrfOnPlPlus->GetLoop( 0, 0)) ; + pCrvExtSfr->AddCurve( Release( pCrvExtProj)) ; if ( ! pCrvExtSfr->IsValid() || pCrvExtSfr->GetCurveCount() == 0 || ! pCrvExtSfr->IsClosed()) return false ; for ( int i = 0 ; i < pCrvExtSfr->GetCurveCount() ; ++ i) pCrvExtSfr->SetCurveTempProp( i, 1) ; pCrvExtSfr->SetExtrusion( vtExtr) ; pCrvExtSfr->SetThickness( dthick) ; + PtrOwner pSrf_h( CreateSurfFlatRegion()) ; + for ( int cc = 0 ; cc < pSrf->GetChunkCount() ; ++ cc) { + if ( cc != c) + pSrf_h->Add( *pSrf->CloneChunk( cc)) ; + else + pSrf_h->AddExtLoop( Release( pCrvExtSfr)) ; + } + pSrf->Clear() ; + pSrf->CopyFrom( pSrf_h) ; + pSrf->Translate( -vtTrasl) ; return true ; } @@ -10071,22 +10226,24 @@ Pocketing::GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveCompos double dNum = 1.0 * i ; double dParT = dNum / nDen ; Point3d ptTest ; + Vector3d vtPerpIn ; - if ( pCrv->GetPointD1D2( dParT, ICurve::FROM_PLUS, ptTest)) { + if ( pCrv->GetPointD1D2( dParT, ICurve::FROM_PLUS, ptTest, &vtPerpIn)) { if ( pCrv->GetTempProp() == 0) { // se la curva è chiusa sposto il centro verso l'interno. // Devo essere sicuro di essere su una curva di Offset interno, altrimenti potrebbe essere valido // il punto trovato, però facendo poi il primo offeset tale punto potrebbe diventare un punto // di convergenza tra più chunks... - Vector3d vtPerpIn ; + //Vector3d vtPerpIn ; PtrOwner pCompoClone( CloneCurveComposite( pCompo)) ; if ( IsNull( pCompoClone)) return false ; double dU ; pCompoClone->GetParamAtPoint( ptTest, dU) ; pCompoClone->ChangeStartPoint( dU) ; - pCompoClone->GetStartDir( vtPerpIn) ; + vtPerpIn.Normalize() ; + //pCompoClone->GetStartDir( vtPerpIn) ; vtPerpIn.Rotate( Z_AX, 0, 1) ; // cos( pi/2) = 0, sin( pi/2) = 1 vtPerpIn *= (( 0.5 * m_TParams.m_dDiam + GetOffsR() + 5 * EPS_SMALL)) ; ptTest = ptTest + vtPerpIn ; @@ -10104,8 +10261,14 @@ Pocketing::GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveCompos IntersCurveCurve intCC( *pCompo, *pCrvToolShape) ; + //int v = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompo->Clone()) ; + //m_pGeomDB->SetMaterial( v, GREEN) ; + //int p = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvToolShape->Clone()) ; + //m_pGeomDB->SetMaterial( p, PURPLE) ; + + if ( intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) { - if (( int)ccClass.size() == 3 && ccClass[1].nClass == CRVC_IN) { + //if (( int)ccClass.size() == 3 && ccClass[1].nClass == CRVC_IN) { // se ho solo due intersezioni, controllo di non intersecare isole bool bOk = true ; for ( int j = 0 ; j < ( int)vCrvNoInters.size() && bOk ; ++ j) { @@ -10122,7 +10285,7 @@ Pocketing::GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveCompos dPar = dParT ; return true ; } - } + //} } else return false ; @@ -10329,16 +10492,33 @@ Pocketing::SetTmpPropByOverlap( ICurveComposite* pCrv_, int nInd, const ICurveCo pCrvOri->GetParamAtPoint( ptS, dUS, dToll) ; pCrvOri->GetParamAtPoint( ptE, dUE, dToll) ; + + //double dLen_useless ; pCrv->GetLength( dLen_useless) ; + //if ( dLen_useless > 74.8 && dLen_useless < 75) { + // int w = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvOri->Clone()) ; + // m_pGeomDB->SetMaterial( w, WHITE) ; + // int o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; + // m_pGeomDB->SetMaterial( o, ORANGE) ; + //} + + // controllare questa funzione, con 50 funziona la C, ma non la passata con il tool a 75 ! int nRealDUS = ( int)floor( dUS) ; int nRealDUE = ( int)ceil( dUE) ; - if ( ceil( dUS) - dUS < 50 * EPS_SMALL) + if ( ceil( dUS) - dUS < EPS_SMALL) nRealDUS = ( int)ceil( dUS) ; - if ( dUE - floor( dUE) < 50 * EPS_SMALL) - nRealDUE = ( int)floor( dUE) ; + if ( dUE - floor( dUE) < EPS_SMALL) + nRealDUE = ( int)floor( dUE) ; - // controllo subito se tocco più curve sulla originale - if ( nRealDUE - nRealDUS - 1 < EPS_SMALL) { // == 0 ? - // se ne tocco solo una, allora imposto le proprietà e finisco + // controllo subito se tocco più curve sulla originale con stesse temp prop + bool bHasAllSameProp = true ; + int nProp_prec ; pCrvOri->GetCurveTempProp( nRealDUS, nProp_prec, 0) ; + for ( int u = nRealDUS + 1 ; u < nRealDUE && bHasAllSameProp ; ++ u) { + int nProp_act ; + pCrvOri->GetCurveTempProp( u, nProp_act, 0) ; + if ( nProp_prec != nProp_act) + bHasAllSameProp = false ; + } + if ( bHasAllSameProp) { int nCrv = nRealDUS ; int nProp0 = 0 ; pCrvOri->GetCurveTempProp( nCrv, nProp0, 0) ; int nProp1 = 0 ; pCrvOri->GetCurveTempProp( nCrv, nProp1, 1) ; @@ -10347,12 +10527,10 @@ Pocketing::SetTmpPropByOverlap( ICurveComposite* pCrv_, int nInd, const ICurveCo return true ; } - // ricopio il tratto di curva compreso in questo range - PtrOwner pCrvOriRange( CreateCurveComposite()) ; - if ( IsNull( pCrvOriRange)) - return false ; - - pCrvOriRange->AddCurve( pCrvOri->CopyParamRange( floor( dUS), ceil( dUE))) ; + // copio le sottocurve toccate + PtrOwner pCrvOriRange( CloneCurveComposite( pCrvOri)) ; + pCrvOriRange->TrimStartEndAtParam( floor( dUS), ceil( dUE)) ; + if ( ! pCrvOriRange->IsValid()) { nStat = 2 ; return true ; @@ -10380,12 +10558,12 @@ Pocketing::SetTmpPropByOverlap( ICurveComposite* pCrv_, int nInd, const ICurveCo else pCrv->GetParamAtPoint( ptCrvOriE, dUProjE, dToll) ; - PtrOwner pCrvRange( GetCurve( pCrv->CopyParamRange( dUProjS, dUProjE))) ; + PtrOwner pCrvRange( GetCurveComposite( pCrv->CopyParamRange( dUProjS, dUProjE))) ; if ( ! IsNull( pCrvRange) && pCrvRange->IsValid()) { int nProp0 = 0 ; pCrvOriRange->GetCurveTempProp( u, nProp0, 0) ; int nProp1 = -1 ; pCrvOriRange->GetCurveTempProp( u, nProp1, 1) ; - pCrvRange->SetTempProp( nProp0, 0) ; - pCrvRange->SetTempProp( nProp1, 1) ; + pCrvRange->SetCurveTempProp( 0, nProp0, 0) ; + pCrvRange->SetCurveTempProp( 0, nProp1, 1) ; pCrvFinal->AddCurve( Release( pCrvRange)) ; } else { @@ -10539,6 +10717,14 @@ Pocketing::CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const doub bool Pocketing::AssignFeedSpiralOpt( const int nOptType, ICurveComposite* pCrv ) { + // controllo della curva corrente + if ( pCrv == nullptr || !pCrv->IsValid() || pCrv->GetCurveCount() == 0) + return false ; + + // controllo se il Flag per assegnare la Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + switch ( m_Params.m_nSubType ) { case POCKET_SUB_SPIRALIN : @@ -10578,268 +10764,269 @@ Pocketing::AssignFeedSpiralOpt( const int nOptType, ICurveComposite* pCrv ) { } //---------------------------------------------------------------------------- -bool -Pocketing::AssignFeedForSpiralLinks( ICurveComposite* pCrvLink, const ISurfFlatRegion* pSrfRemoved) +bool +Pocketing::AssignFeedZigZagOneWay( ICurveComposite* pCompo, const bool bIsLink, const ICURVEPOVECTOR& vLAbove, + const ICURVEPOVECTOR& vLUnder, const ICRVCOMPOPOVECTOR& vAddedLinks) { - - // controllo validità del link - if ( pCrvLink == nullptr || ! pCrvLink->IsValid() || pCrvLink->GetCurveCount() == 0) + // controllo che la pCompoLine sia effettivamente una linea valida + if ( pCompo == nullptr || ! pCompo->IsValid()) return false ; + + // controllo se il Flag per assegnare la Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCompo) ; - // inizializzo di default tutte le sottocurve del link a speed minima - for ( int u = 0 ; u < pCrvLink->GetCurveCount() ; ++ u) - pCrvLink->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; - // se non ho nessuna regione già svuotata -> Theta = 180 ° - if ( pSrfRemoved == nullptr || ! pSrfRemoved->IsValid() || pSrfRemoved->GetChunkCount() == 0) - return true ; // quindi la feed è minima + // inzialmente setto la feed Minima alla curva + for ( int u = 0 ; u < pCompo->GetCurveCount() ; ++ u) + pCompo->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; - // controllo se la regione che è svuotata da questo link è interna alla regione già svuotata - bool bIsOut = false ; - if ( CheckCrvToolSurfInters( nullptr, pSrfRemoved, pCrvLink, bIsOut) && !bIsOut) { - // in caso affermativo questo link può essere percorso con FeedMassima - for ( int u = 0 ; u < pCrvLink->GetCurveCount() ; ++ u) - pCrvLink->SetCurveTempProp( 0, FEED_DIVISOR * GetMaxFeed(), 0) ; - return true ; + // se è un link tra livelli diversi, allora esco ( con Feed Minima ) + if ( bIsLink) { + Point3d ptS_link ; pCompo->GetStartPoint( ptS_link) ; + Point3d ptE_link ; pCompo->GetEndPoint( ptE_link) ; + if ( abs( ptE_link.y - ptS_link.y) > 500 * EPS_SMALL) + return true ; } - return true ; // per ora ! <- - - // se il link è parte interno o parte esterno alla regione non svuotata... - // 1) Controllo la lunghezza del link, se piccolo -> Feed Minima ( ho impatto con materiale non svuotato) - double dLinkLen = EPS_SMALL ; pCrvLink->GetLength( dLinkLen) ; - if ( dLinkLen < 200 ) + // se la curva è piccola, allora esco ( con Feed Minima) + double dLen = EPS_SMALL ; + if ( ! pCompo->GetLength( dLen) || dLen < 0.6 * m_TParams.m_dDiam) return true ; - // 2) Se il link è sufficientemente lungo, allora controllo se riesco a dividerlo in più pezzi ( assegnando - // una Feed propria per ogni intervallo scelto) - ICRVCOMPOPOVECTOR vCrvStep ; - CRVCVECTOR ccClass ; - bool bIsFirst = true ; - double dPar_cS = 0 ; - PtrOwner pCrvLink_sbs( CreateCurveComposite()) ; - if ( pSrfRemoved->GetCurveClassification( *pCrvLink, EPS_SMALL, ccClass)) { - for ( int i = 1 ; i < ( int)ccClass.size() ; ++ i) { - // essendo il link attaccato all'Offset, la prima parte sarà sempre dentro - PtrOwner pCrvLink_piece( GetCurveComposite( - pCrvLink->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; - if ( IsNull( pCrvLink_piece) || ! pCrvLink_piece->IsValid()) - return true ; - if ( ccClass[i].nClass == CRVC_IN) { // se non interna - pCrvLink_sbs.Set( GetCurveComposite( pCrvLink->CopyParamRange( dPar_cS, ccClass[i].dParE))) ; - if ( IsNull( pCrvLink_sbs) || ! pCrvLink_sbs->IsValid()) - return true ; - // ricavo la lunghezza al parametro in cui il link entra nella regione - double dLenOut = EPS_SMALL ; - pCrvLink->GetLengthAtParam( ccClass[i].dParS, dLenOut) ; - double dLenIn = EPS_SMALL ; - pCrvLink->GetLength( dLenIn) ; dLenIn -= dLenOut ; - if ( dLenOut > 3.0 * m_TParams.m_dDiam && dLenIn > 3.0 * m_TParams.m_dDiam) { // se lunghezze non piccole, - double dPar_len = EPS_SMALL ; - // per sicurezza ... - pCrvLink->GetParamAtLength( dLenOut - m_TParams.m_dDiam / 2, dPar_len) ; - PtrOwner pCrvA( GetCurveComposite( - pCrvLink->CopyParamRange( dPar_cS, dPar_len))) ; - PtrOwner pCrvIn( GetCurveComposite( - pCrvLink->CopyParamRange( dPar_len, ccClass[i].dParE))) ; - if ( IsNull( pCrvA) || IsNull( pCrvIn) || ! pCrvA->IsValid() || ! pCrvIn->IsValid()) - return true ; - // aggiorno parametro per intervallo successivo - dPar_cS = ccClass[i].dParE ; - for ( int u = 0 ; u < pCrvA->GetCurveCount() ; ++ u) // feed minima per le parti "esterne" - pCrvA->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; - for ( int u = 0 ; u < pCrvIn->GetCurveCount() ; ++ u) // feed massima per le parti "interne" - pCrvIn->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed(), 0) ; - vCrvStep.emplace_back( Release( pCrvA)) ; - vCrvStep.emplace_back( Release( pCrvIn)) ; - } + Point3d ptS, ptE ; + pCompo->GetStartPoint( ptS) ; + pCompo->GetEndPoint( ptE) ; + + // creo l'intervallo desiderato valutanto le coordinate x + Intervals IntMinFeed ; IntMinFeed.Set( ptS.x, ptE.x) ; + + // creo un vettore contenente i tratti sopra e i tratti sotto attivi + ICURVEPOVECTOR vAllInt ; vAllInt.reserve(( int)vLUnder.size() + ( int)vLAbove.size()) ; + for ( int i = 0 ; i < ( int)vLUnder.size() ; ++ i) + vAllInt.emplace_back( vLUnder[i]->Clone()) ; + for ( int i = 0 ; i < ( int)vLAbove.size() ; ++ i) + vAllInt.emplace_back( vLAbove[i]->Clone()) ; + + int nDim = ( int)vAllInt.size() ; + + // aggiungo le parti dei link interessate + double dCurrY = ptS.y ; + BBox3d bBoxLink ; + for ( int l = 0 ; l < ( int)vAddedLinks.size() ; ++ l) { + vAddedLinks[l]->GetLocalBBox( bBoxLink) ; + if (( dCurrY - bBoxLink.GetMin().y) < GetSideStep() + 50 * EPS_SMALL || + ( dCurrY - bBoxLink.GetMax().y) < GetSideStep() + 50 * EPS_SMALL) { + + // determino la direzione del Link + Vector3d vtLinkDir( - 25, 0, 0) ; + + Point3d ptS_l ; + vAddedLinks[l]->GetStartPoint( ptS_l) ; + Point3d ptE_l ; + vAddedLinks[l]->GetEndPoint( ptE_l) ; + if ( ptE_l.x - ptS_l.x < EPS_SMALL) + vtLinkDir.x -= ptS_l.x - ptE_l.x ; + + PtrOwner pSfrRectUp( GetSurfFlatRegionRectangle( bBoxLink.GetDimX() + 50, GetSideStep())) ; + pSfrRectUp->Translate(( ptS_l - ORIG) + vtLinkDir) ; + + // link sopra o sotto alla curva currente ? + bool bIsDown = true ; + if ( dCurrY - ptS_l.y < EPS_SMALL) + bIsDown = false ; + + CRVCVECTOR ccClass ; + pSfrRectUp->GetCurveClassification( *vAddedLinks[l], EPS_SMALL, ccClass) ; + for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) { + if ( ccClass[i].nClass == CRVC_IN && bIsDown || + ccClass[i].nClass == CRVC_OUT && ! bIsDown) + vAllInt.emplace_back( GetCurveComposite( vAddedLinks[l]->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; } } - PtrOwner pCrvEnd( GetCurveComposite( - pCrvLink->CopyParamRange( dPar_cS, pCrvLink->GetCurveCount()))) ; - if ( IsNull( pCrvEnd) || ! pCrvEnd->IsValid()) - return true ; - vCrvStep.emplace_back( Release( pCrvEnd)) ; - } - else // nel caso non si riesca a classificare, tengo la feed minima... - return true ; - - if ( int( vCrvStep.size()) == 0) - return true ; - - // controllo che il tutto sia coerente ( quindi che i punti iniziali e finale siano coerenti a quelli del link ) - Point3d ptS, ptSN, ptE, ptEN ; - pCrvLink->GetStartPoint( ptS) ; - pCrvLink->GetEndPoint( ptE) ; - vCrvStep[0]->GetStartPoint( ptSN) ; - vCrvStep.back()->GetEndPoint( ptEN) ; - if ( ! AreSamePointApprox( ptS, ptSN) || ! AreSamePointApprox( ptE, ptEN)) - return true ; - - PtrOwner pCrvLinkFinal( CreateCurveComposite()) ; - if ( IsNull( pCrvLinkFinal)) - return true ; - - // se riesco ad aggiungere tutte le curve trovate, sostituisco il link con quello nuovo - for ( int i = 0 ; i < ( int)vCrvStep.size() ; ++ i) { - if ( pCrvLinkFinal->AddCurve( Release( vCrvStep[i]))) - return true ; } - pCrvLink->Clear() ; - pCrvLink->AddCurve( Release( pCrvLinkFinal)) ; + // scorro tutti i tratti Attivi + for ( int i = 0 ; i < ( int)vAllInt.size() ; ++ i) { + + // controllo che il tratto lineare sotto sia sufficientemente lungo + double dLen_iU = EPS_SMALL ; + if ( ! vAllInt[i]->GetLength( dLen_iU) || ( dLen_iU < 1.1 * m_TParams.m_dDiam && i < nDim)) + continue ; + + Point3d ptS_iU, ptE_iU ; + vAllInt[i]->GetStartPoint( ptS_iU) ; + vAllInt[i]->GetEndPoint( ptE_iU) ; + + // la vtDir per Above e Under è sempre invertita rispetto alla linea corrente + // sottraggo questo intervallo a quello originale + IntMinFeed.Subtract( ptS_iU.x, ptE_iU.x) ; + } + + // l'intervallo orginale ora conterrà i sottointervalli con feed Minima, tolgo quelli troppo piccoli + Intervals IntMinFeed_noSmall ; + + double dParS = EPS_SMALL ; double dParE = EPS_SMALL ; + bool bFound = IntMinFeed.GetFirst( dParS, dParE) ; + while ( bFound) { + if ( dParE - dParS > m_TParams.m_dDiam * 0.5 - 5 * EPS_SMALL) + IntMinFeed_noSmall.Add( dParS, dParE) ; + bFound = IntMinFeed.GetNext( dParS, dParE) ; + } + + // ora che ho solo tratti abbastanza lunghi, creo l'intervallo complementare + // questo intervallo contiene tutte le feed Massime + Intervals IntMaxFeed ; IntMaxFeed.Set( ptS.x, ptE.x) ; + IntMaxFeed.Subtract( IntMinFeed_noSmall) ; + + // tolgo le parti piccole + Intervals IntMaxFeed_noSmall ; + + bFound = IntMaxFeed.GetFirst( dParS, dParE) ; + while ( bFound) { + if ( dParE - dParS > m_TParams.m_dDiam * 0.5 - 5 * EPS_SMALL) + IntMaxFeed_noSmall.Add( dParS, dParE) ; + bFound = IntMaxFeed.GetNext( dParS, dParE) ; + } + + // recupero la direzione principale della curva corrente + Vector3d vtDir = X_AX ; + if ( ptE.x - ptS.x < EPS_SMALL) + vtDir = - X_AX ; + + // trasformo questi intervalli nei parametri corrispondenti sulla linea originale + bool bFMax = false ; + bFound = IntMaxFeed_noSmall.GetFirst( dParS, dParE) ; + if ( bFound && IntMaxFeed_noSmall.IsInside( ptS.x + vtDir.x * 20 * EPS_SMALL)) + bFMax = true ; + if ( ! bFound && bIsLink) // se non ho intervalli a Feed Massima, allora esco ( con Feed Minima) + return true ; + + + while ( bFound) { + if ( ! bIsLink) { // se segmento di ZigZag + double du_js = EPS_SMALL ; pCompo->GetParamAtPoint( Point3d( dParS, ptS.y, ptS.z), du_js) ; + pCompo->AddJoint( du_js) ; + double du_je = EPS_SMALL ; pCompo->GetParamAtPoint( Point3d( dParE, ptE.y, ptE.z), du_je) ; + pCompo->AddJoint( du_je) ; + } + bFound = IntMaxFeed_noSmall.GetNext( dParS, dParE) ; + } + + // aggiorno le proprietà temporanee con la feed + if ( ! bIsLink) { + for ( int u = 0 ; u < pCompo->GetCurveCount() ; ++ u) + { + if ( IsEven( u) == bFMax) + pCompo->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed() , 0) ; + else + pCompo->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed() , 0) ; + } + } return true ; - - /* - // creo la regione svuotata dal Tool lungo il collegamento - PtrOwner pCrvLink_clone( pCrvLink->Clone()) ; - if ( IsNull( pCrvLink_clone)) - return false ; - PtrOwner pSrfForBorder( GetSurfFlatRegionFromFatCurve( Release( pCrvLink_clone), m_TParams.m_dDiam, false, false)) ; - if ( IsNull( pSrfForBorder) || ! pSrfForBorder->IsValid() || pSrfForBorder->GetChunkCount() == 0) - return true ; - - // ricavo il bordo di questa regione - PtrOwner pCrvBorder( GetCurveComposite( pSrfForBorder->GetLoop( 0, 0))) ; - if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid() || pCrvBorder->GetCurveCount() == 0) - return true ; - - CRVCVECTOR ccClass ; - if ( pSrfRemoved->GetCurveClassification( *pCrvLink, EPS_SMALL, ccClass)) { - if (( int)ccClass.size() == 1 && ccClass[0].nClass == CRVC_IN) // se curva interna alla regione già svuotata - dCurrFeed = dMaxFeed ; // ( theta = 0 °) - else - dCurrFeed = dMinFeed ; // ( theta = 180 °) - } - else - dCurrFeed = dMinFeed ; - - return true ; - */ } //---------------------------------------------------------------------------- bool -Pocketing::AssignFeedForZigZagParts( ICurveComposite* pCrvPart, const bool bIsAbsFirst, const ISurfFlatRegion* pSrfRemoved, - const int nFeedFirstLine) // int perchè è moltiplicata per FEED_DIVISOR +Pocketing::AssignFeedOnCorners( ICurveComposite* pCrv, const ICurveComposite* pCrv_orig, const double dLenToll) { - // ricavo il primo tratto lineare - const ICurve* pSeg1 = pCrvPart->GetFirstCurve() ; - const ICurve* pSeg2 = pCrvPart->GetLastCurve() ; - PtrOwner pCrvLink( GetCurveComposite( pCrvPart->CopyParamRange( 1, pCrvPart->GetCurveCount() - 1))) ; - if ( pSeg1 == nullptr || pSeg2 == nullptr || - IsNull( pCrvLink) || ! pCrvLink->IsValid() || pCrvLink->GetCurveCount() == 0) - return true ; - // imposto la feed per il primo tratto lineare ( calcolata da questa funzione nello step precedente ) - if ( ! bIsAbsFirst) - pCrvPart->SetCurveTempProp( 0, nFeedFirstLine, 0) ; - - // setto la feed minima per ogni sottocurva del percorso ( evitando la prima che ho già settato ) - for ( int u = bIsAbsFirst ? 0 : 1 ; u < pCrvPart->GetCurveCount() ; ++ u) - pCrvPart->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; - - // clono la superificie passata - PtrOwner pSrfRemoved_copy( CreateSurfFlatRegion()) ; - if ( pSrfRemoved != nullptr && pSrfRemoved->IsValid() && pSrfRemoved->GetChunkCount() != 0) - pSrfRemoved_copy.Set( pSrfRemoved->Clone()) ; - - // ricavo la superificie di lavoro coerente per il tratto richiesto : - // se la superificie rimossa esiste |-> controllo se il primo segmento non è contenuto in quella esistente - // |-> controllo se il secondo segmento non è contenuto nella nuova superificie - // rimossa - // se la superificie rimossa non esiste |-> controllo che il secondo segmento non è contenuto nella nuova superificie - // rimossa - - bool bIsOutside ; - if ( ! pSrfRemoved_copy->IsValid() || pSrfRemoved_copy->GetChunkCount() == 0) { // se la superificie rimossa non esiste - PtrOwner pCrv1( CreateCurveComposite()) ; - pCrv1->AddCurve( pSeg1->Clone()) ; - pCrv1->AddCurve( pCrvLink->Clone()) ; - if ( CheckCrvToolSurfInters( pCrv1, nullptr, pSeg2, bIsOutside) && !bIsOutside) - pCrvPart->SetCurveTempProp( pCrvPart->GetCurveCount() - 1, FEED_DIVISOR * GetMaxFeed(), 0) ; - } - else { // se la superificie rimossa esiste - // se prima linea in assoluto, non controllo la feed, è gia messa a minimo - if ( bIsAbsFirst && CheckCrvToolSurfInters( nullptr, pSrfRemoved_copy, pSeg1, bIsOutside) && !bIsOutside) - pCrvPart->SetCurveTempProp( 0, FEED_DIVISOR * GetMaxFeed(), 0) ; // il primo segmento può andare veloce - PtrOwner pCrv_S1_Link( CreateCurveComposite()) ; - pCrv_S1_Link->AddCurve( pSeg1->Clone()) ; - pCrv_S1_Link->AddCurve( pCrvLink->Clone()) ; - GetDynamicClearedRegion( pSrfRemoved_copy, pCrv_S1_Link) ; - if ( CheckCrvToolSurfInters( nullptr, pSrfRemoved_copy, pSeg2, bIsOutside) && !bIsOutside) - pCrvPart->SetCurveTempProp( pCrvPart->GetCurveCount() - 1, FEED_DIVISOR * GetMaxFeed(), 0) ; - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Pocketing::CheckCrvToolSurfInters( const ICurve* pCrv1, const ISurfFlatRegion* pSrfRemoved, const ICurve* pCrv2, - bool& bIsOut, double dToll) -{ - bIsOut = true ; - - // controllo validità superificie passata - bool bValidSrf = true ; - if ( pSrfRemoved == nullptr || ! pSrfRemoved->IsValid() || pSrfRemoved->GetChunkCount() == 0) - bValidSrf = false ; - - // se la superificie passata non è valida e la curva pCrv1 è nulla -> errore - if (( pCrv1 == nullptr || ! pCrv1->IsValid()) && !bValidSrf) + // controllo sulla curva iniziale + if ( pCrv == nullptr || ! pCrv->IsValid() || pCrv->GetCurveCount() == 0 || ! pCrv->IsClosed()) return false ; - // controllo la lunghezza del secondo tratto di curva ( deve essere almeno più grande del diametro del tool ) - double dLen ; pCrv2->GetLength( dLen) ; - if ( dLen < m_TParams.m_dDiam + 50 * dToll) { - bIsOut = false ; - return true ; // segmento piccolo già contenuto - } + // controllo se Flag per Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; - // la superificie che uso per controllare la posizione della curva 2 - PtrOwner pSrfBack( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfBack)) - return false ; + // nuova curva finale + PtrOwner pCrv_new( CreateCurveComposite()) ; + if ( IsNull( pCrv_new)) + return false ; - // se non ho una superificie ... - if ( ! bValidSrf) { - // la pSrfBack è quella generata dalla curva 1 - PtrOwner pCrv1Compo( CreateCurveComposite()) ; - if ( IsNull( pCrv1Compo) || ! pCrv1Compo->AddCurve( pCrv1->Clone()) || - ! GetDynamicClearedRegion( pSrfBack, pCrv1Compo) || - ! pSrfBack->IsValid() || pSrfBack->GetChunkCount() == 0) - return false ; - } - else - // la pSrfBack è la superficie ( valida ) passata alla funzione - pSrfBack.Set( CloneSurfFlatRegion( pSrfRemoved)) ; + Intervals IntU ; IntU.Set( 0.0, 1.0 * pCrv->GetCurveCount()) ; - // creo la superificie svuotata dal secondo tratto ( ridotto all'inizio del raggio ) e ne estraggo il bordo - PtrOwner pCrv2_copy( CreateCurveComposite()) ; - if ( IsNull( pCrv2_copy)) - return false ; - pCrv2_copy->AddCurve( pCrv2->Clone()) ; - pCrv2_copy->TrimStartAtLen( m_TParams.m_dDiam + 15 * dToll) ; - PtrOwner pSrf_seg2( CreateSurfFlatRegion()) ; - if ( IsNull( pSrf_seg2) || - ! GetDynamicClearedRegion( pSrf_seg2, pCrv2_copy) || - ! pSrf_seg2->IsValid() || pSrf_seg2->GetChunkCount() == 0) - return false ; - PtrOwner pCrvBorder( GetCurveComposite( pSrf_seg2->GetLoop( 0, 0))) ; - if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid() || pCrvBorder->GetCurveCount() == 0) - return false ; + // scorro tutte le curve cercando i punti non C' + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u ) { + // curva u-esima + const ICurve* pCrv_u = pCrv->GetCurve( u) ; + // curva (u+1)-esima + int u_f = u + 1 ; + if ( u_f == pCrv->GetCurveCount()) + u_f = 0 ; + const ICurve* pCrv_uu = pCrv->GetCurve( u_f) ; + // calcolo l'angolo tra le due curve + double dAng = EPS_ANG_ZERO ; + Vector3d dTan_u = V_NULL ; pCrv_u->GetEndDir( dTan_u) ; + Vector3d dTan_uu = V_NULL ; pCrv_uu->GetStartDir( dTan_uu) ; - // controllo se il bordo non è interno alla superficie precedente - CRVCVECTOR ccClass ; - if ( pSrfBack->GetCurveClassification( *pCrvBorder, dToll, ccClass)) { - if ( ! (( int)ccClass.size() == 1 && ccClass[0].nClass == CRVC_OUT)) - bIsOut = false ; - } - else - return false ; + double dU_S = 0.0 ; + double dU_E = 1.0 ; - return true ; + if ( ! dTan_u.GetAngle( dTan_uu, dAng) || abs( dAng) > EPS_ANG_SMALL) { // se spigolo... + // ricavo la lunghezza delle due curve e controllo che non siano dei lati aperti + int nStat_u = 0 ; + if ( CheckSimpleOverlap( pCrv_u, pCrv_orig, nStat_u, 50 * EPS_SMALL) && nStat_u != 1) { + double dLen_u = EPS_SMALL ; pCrv_u->GetLength( dLen_u) ; + if ( dLen_u > dLenToll + 500 * EPS_SMALL) + pCrv_u->GetParamAtLength( dLen_u - dLenToll, dU_S) ; + } + int nStat_uu = 0 ; + if ( CheckSimpleOverlap( pCrv_uu, pCrv_orig, nStat_uu, 50 * EPS_SMALL) && nStat_uu != 1) { + double dLen_uu = EPS_SMALL ; pCrv_uu->GetLength( dLen_uu) ; + if ( dLen_uu > dLenToll + 500 * EPS_SMALL) + pCrv_uu->GetParamAtLength( dLenToll, dU_E) ; + } + + if ( u_f != 0) { + IntU.Subtract( u + ( nStat_u == 0 ? dU_S : 1), u_f + ( nStat_uu == 0 ? dU_E : 0)) ; + } + else { + if ( nStat_u == 0) + IntU.Subtract( u + dU_S, pCrv->GetCurveCount()) ; + if ( nStat_uu == 0) + IntU.Subtract( 0.0, dU_E) ; + } + } + } + + ICRVCOMPOPOVECTOR vCrvMinFeed ; + double dParS = EPS_SMALL ; double dParE = EPS_SMALL ; + + Intervals IntMinFeed ; IntMinFeed.Set( 0.0, 1.0 * pCrv->GetCurveCount()) ; + IntMinFeed.Subtract( IntU) ; + + bool bFound = IntMinFeed.GetFirst( dParS, dParE) ; + while ( bFound) { + Point3d ptS, ptE ; + vCrvMinFeed.emplace_back( GetCurveComposite( pCrv->CopyParamRange( dParS, dParE))) ; + for ( int u = 0 ; u < vCrvMinFeed.back()->GetCurveCount() ; ++ u) + vCrvMinFeed.back()->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; + bFound = IntMinFeed.GetNext( dParS, dParE) ; + } + + PtrOwner pCrv_clone( pCrv->Clone()) ; + + for ( int i = 0 ; i < ( int)vCrvMinFeed.size() ; ++ i) { + PtrOwner pCrv_back( pCrv_clone->Clone()) ; + PtrOwner pCrv_forward( pCrv_clone->Clone()) ; + Point3d ptS, ptE ; + vCrvMinFeed[i]->GetStartPoint( ptS) ; + vCrvMinFeed[i]->GetEndPoint( ptE) ; + double duS ; double duE ; + pCrv_clone->GetParamAtPoint( ptS, duS) ; + pCrv_clone->GetParamAtPoint( ptE, duE) ; + pCrv_back->TrimEndAtParam( duS) ; + pCrv_forward->TrimStartAtParam( duE) ; + pCrv_clone->Clear() ; + pCrv_clone->AddCurve( Release( pCrv_back)) ; + pCrv_clone->AddCurve( vCrvMinFeed[i]->Clone()) ; + pCrv_clone->AddCurve( Release( pCrv_forward)) ; + } + + pCrv->Clear() ; + pCrv->AddCurve( Release( pCrv_clone)) ; + return false ; } //---------------------------------------------------------------------------- @@ -10886,6 +11073,9 @@ Pocketing::GetFeedForParam( double& dPar, double& dFeed) bool Pocketing::AssignFeedForOpenEdge( ICurveComposite* pCrv, const ICurveComposite* pCrvOF_orig) { + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + // controllo se qualche curva passa sopra ad un lato aperto... if ( pCrvOF_orig != nullptr ) { for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { @@ -10914,79 +11104,16 @@ Pocketing::AssignFeedForLineInOut( ICurveComposite* pCrv, const bool bIsIn) if ( pCrv == nullptr || pCrv->GetCurveCount() < 2) return false ; + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + if ( bIsIn) // Segmento in ingresso pCrv->SetCurveTempProp( 0, FEED_DIVISOR * GetMinFeed(), 0) ; - else // Segmento in uscita + else // Segmento in uscita pCrv->SetCurveTempProp( pCrv->GetCurveCount() - 1, FEED_DIVISOR * GetMaxFeed(), 0) ; return true ; } -//---------------------------------------------------------------------------- -bool -Pocketing::AssignFeedSpiralForCrvOnUnclearedRegion( ICurveComposite* pCrv, const ICurveComposite* pCrv_simple_offs) -{ - // nel caso di SpiralIN/OUT controllo le curve per le regioni non svuotate, queste curve vengono rallentate - if ( m_Params.m_nSubType != POCKET_SUB_SPIRALIN && m_Params.m_nSubType != POCKET_SUB_SPIRALOUT) - return false ; - - // se ho una curva per il controllo... - if ( pCrv_simple_offs != nullptr) { - // N.B. spesso le curve sulle regione non svuotate sono circonferenze ( quindi curve piccole) - // o curve di Medial Axis... setto la feed bassa - for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { - const ICurve* pCrv_u = pCrv->GetCurve( u) ; - if ( pCrv_u == nullptr) - return false ; - int nStat = -1 ; - if ( CheckSimpleOverlap( pCrv_u, pCrv_simple_offs, nStat, 1500 * EPS_SMALL) && nStat == 0) - pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; - } - } - return true ; -} - - -//---------------------------------------------------------------------------- -bool -Pocketing::AssignFeedSpiral( ICurveComposite* pCrv, const int nCrvType, const bool bIsFirst, const bool bIsLast, - const ISurfFlatRegion* pSrfRemoved, const ICurveComposite* pCrvOF_orig, - const ICurveComposite* pCrv_simple_Offset) -{ - // ======================================================================== - // nCrvType : 0 -> Curva di Offset | 1 -> Link | 2 -> percorso di ritorno - // ======================================================================== - - if ( pCrv == nullptr) - return false ; - double dCurrFeed = GetMinFeed() ; - - if ( nCrvType == 0) { // curva di Offset - if ( bIsFirst) - dCurrFeed = GetMinFeed() ; - else - dCurrFeed = GetMaxFeed() ; - } - else if ( nCrvType == 1) // Link - AssignFeedForSpiralLinks( pCrv, pSrfRemoved) ; - else if ( nCrvType == 2) { // se percorso di ritorno - for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) - pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed(), 0) ; - return true ; - } - - // assegno a tutte le sottocurve la Feed trovata - for ( int u = 0 ; u < ( int)pCrv->GetCurveCount() && nCrvType != 1; ++ u) - pCrv->SetCurveTempProp( u, FEED_DIVISOR * dCurrFeed, 0) ; - - // rallento le curve che passano sulle regioni non svuotate - AssignFeedSpiralForCrvOnUnclearedRegion( pCrv, pCrv_simple_Offset) ; - - // controllo se ho sovrapposizioni con lati aperti - AssignFeedForOpenEdge( pCrv, pCrvOF_orig) ; - - return true ; -} - //---------------------------------------------------------------------------- bool Pocketing::AssignFeedForEdgeCleaning( ICurveComposite *pCrv, const ICRVCOMPOPOVECTOR& vCrvOF_orig, int nInd) { @@ -10995,9 +11122,13 @@ Pocketing::AssignFeedForEdgeCleaning( ICurveComposite *pCrv, const ICRVCOMPOPOVE if ( pCrv == nullptr || ! pCrv->IsValid() || pCrv->GetCurveCount() == 0) return false ; // controllo che la svuotatura sia ZigZag o OneWay - if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) + if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) return false ; + // controllo se il Flag per assegnare la Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + double dCurrFeed = GetMinFeed() ; if ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG) // se pulitura ZigZag -> posso andare alla FeedMassima @@ -11009,38 +11140,380 @@ Pocketing::AssignFeedForEdgeCleaning( ICurveComposite *pCrv, const ICRVCOMPOPOVE pCrv->SetCurveTempProp( u, FEED_DIVISOR * dCurrFeed, 0) ; // controllo se le curve di Bordo passano su una curva originale -> controllo dei lati aperti - if ( m_Params.m_nSubType == POCKET_LI_ZIGZAG && nInd >= 0) + if ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG && nInd >= 0) AssignFeedForOpenEdge( pCrv, vCrvOF_orig[nInd]) ; else { for ( int i = 0 ; i < ( int)vCrvOF_orig.size() ; ++ i) // se sono nel caso OneWay ho una regione con più chunk... AssignFeedForOpenEdge( pCrv, vCrvOF_orig[i]) ; } + // se sono in una svuotatura a ZigZag, controllo la Feed sugli Angoli + if ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG) + AssignFeedOnCorners( pCrv, vCrvOF_orig[nInd], m_TParams.m_dTDiam) ; + return true ; } //---------------------------------------------------------------------------- bool -Pocketing::AssignFeedOneWay( ICurveLine* pLine, const ISurfFlatRegion* pSrfRemoved) +Pocketing::AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs, const bool bIsLink, + const ICRVCOMPOPOVECTOR& vLinks_done, const ICurveComposite* pCrv_orig, double dToll) { - // controllo dei parametri - if ( pLine == nullptr || ! pLine->IsValid()) + + // controllo la validità della curva + if ( pCrv == nullptr || ! pCrv->IsValid() || pCrv->GetCurveCount() == 0) return false ; - // imposto come feed della linea quella minima - pLine->SetTempProp( FEED_DIVISOR * GetMinFeed(), 0) ; + // controllo se il Flag per assegnare la Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + + // imposto di Default la Feed minima per ogni sottocurva + for ( int u = 0 ; u < ( int)pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; - // se ho una superificie già svuotata, allora controllo se la linea svuota parti nuove o no... - if ( ! ( pSrfRemoved == nullptr || ! pSrfRemoved->IsValid() || pSrfRemoved->GetChunkCount() == 0)) { - bool bIsOut = false ; - if ( CheckCrvToolSurfInters( nullptr, pSrfRemoved, pLine, bIsOut) && !bIsOut) - pLine->SetTempProp( FEED_DIVISOR * GetMaxFeed(), 0) ; + // se non ho una superificie svuotata, allora esco ( con Feed Minima) + if ( pSrfRemoved_offs == nullptr || ! pSrfRemoved_offs->IsValid() || pSrfRemoved_offs->GetChunkCount() == 0) { + // controllo eventuali sovrapposizioni con lati aperti + AssignFeedForOpenEdge( pCrv, pCrv_orig) ; + return true ; + } + + // clono la superificie ( valida) + PtrOwner pSrf_Removed_offs_clone( CloneSurfFlatRegion( pSrfRemoved_offs)) ; + if ( IsNull( pSrf_Removed_offs_clone) || ! pSrf_Removed_offs_clone->IsValid() || + pSrf_Removed_offs_clone->GetChunkCount() == 0) + return true ; // esco ( sempre con Feed Minima) + + // restringo la superificie in maniera appropriata + if ( bIsLink) { // se curva di Link + if ( ! pSrf_Removed_offs_clone->Offset( - m_TParams.m_dDiam / 2 + 1500 * EPS_SMALL, ICurve::OFF_CHAMFER) || + ! pSrf_Removed_offs_clone->IsValid() || pSrf_Removed_offs_clone->GetChunkCount() == 0) + return true ; // esco ( sempre con Feed Minima) + } + else if ( m_TParams.m_dDiam / 2 < GetSideStep()) { // se curva di Offset e raggio utensile < Side step + if ( ! pSrf_Removed_offs_clone->Offset( GetSideStep() - m_TParams.m_dDiam / 2, ICurve::OFF_CHAMFER) || + ! pSrf_Removed_offs_clone->IsValid() || pSrf_Removed_offs_clone->GetChunkCount() == 0) + return true ; // esco ( sempre con Feed Minima) + } + + // classifico le parti interne alla superificie creata solo dagli Offset + CRVCVECTOR ccClass ; + if ( ! pSrf_Removed_offs_clone->GetCurveClassification( *pCrv, EPS_SMALL, ccClass)) + return true ; // esco ( sempre con Feed Minima) + + // creo la nuova curva con le Feed regolate + PtrOwner pCrv_new( CreateCurveComposite()) ; + if ( IsNull( pCrv_new)) + return false ; + + for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) { + double dCurrFeed = GetMinFeed() ; + PtrOwner PCrv_sez( GetCurveComposite( pCrv->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; + if ( ccClass[i].nClass == CRVC_IN) + dCurrFeed = GetMaxFeed() ; + + for ( int u = 0 ; u < PCrv_sez->GetCurveCount() ; ++ u) + PCrv_sez->SetCurveTempProp( u, FEED_DIVISOR * dCurrFeed, 0) ; + pCrv_new->AddCurve( Release( PCrv_sez)) ; + } + + pCrv->Clear() ; + pCrv->AddCurve( Release( pCrv_new)) ; + + // controllo eventuali suvrapposizioni tra la curva attuale e i Link in precedenza percorsi + for ( int l = 0 ; l < ( int)vLinks_done.size() ; ++ l) { + IntersCurveCurve intCC( *pCrv, *vLinks_done[l]) ; + for ( int i = 0 ; i < intCC.GetIntersCount() ; ++ i) { + IntCrvCrvInfo aInfo ; + if ( ! intCC.GetIntCrvCrvInfo( i, aInfo) || ! aInfo.bOverlap || + AreSamePointApprox( aInfo.IciA[0].ptI, aInfo.IciA[1].ptI)) + continue ; + + PtrOwner pCrv_before( CloneCurveComposite( pCrv)) ; + pCrv_before->TrimEndAtParam( aInfo.IciA[0].dU) ; + PtrOwner pCrv_after( CloneCurveComposite( pCrv)) ; + pCrv_after->TrimStartAtParam( aInfo.IciA[1].dU) ; + PtrOwner pCrv_overlap( GetCurveComposite( pCrv->CopyParamRange( aInfo.IciA[0].dU, aInfo.IciA[1].dU))) ; + for ( int u = 0 ; u < pCrv_overlap->GetCurveCount() ; ++ u) + pCrv_overlap->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed(), 0) ; + + pCrv->Clear() ; + pCrv->AddCurve( Release( pCrv_before)) ; + pCrv->AddCurve( Release( pCrv_overlap)) ; + pCrv->AddCurve( Release( pCrv_after)) ; + + } + } + + if ( ! bIsLink) { // NEL CASO DI OFFSET + // creo un intervallo con tutte le Feed Minime + Intervals IntMinFeed ; + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { + int nProp ; pCrv->GetCurveTempProp( u, nProp, 0) ; + if ( abs ( nProp - int( FEED_DIVISOR * GetMinFeed()) < 5 * EPS_SMALL)) + IntMinFeed.Add( u, u + 1) ; + } + double dParS = EPS_SMALL ; double dParE = EPS_SMALL ; + + // a questo intervallo tolgo tutti i sottotratti di lunghezza inferiore alla tolleranza richiesta + Intervals IntMinFeed_noSmall ; + bool bFound = IntMinFeed.GetFirst( dParS, dParE) ; + while ( bFound) { + PtrOwner pCrv_Crv( pCrv->CopyParamRange( dParS, dParE)) ; + double dLen = EPS_SMALL ; pCrv_Crv->GetLength( dLen) ; + if ( dLen > dToll + 5 * EPS_SMALL) + IntMinFeed_noSmall.Add( dParS, dParE) ; + bFound = IntMinFeed.GetNext( dParS, dParE) ; + } + + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { + if ( IntMinFeed_noSmall.IsInside( u + 0.5)) + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; + else + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed(), 0) ; + } + } + else { // NEL CASO DI LINK + // le curve con lunghezza < dToll vanno modificate + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { + double dLen = EPS_SMALL ; + pCrv->GetCurve( u)->GetLength( dLen) ; + if ( dLen < dToll + 5 * EPS_SMALL) { + PtrOwner pCrvCompo( CloneCurveComposite( pCrv)) ; + pCrvCompo->TrimStartAtParam( u) ; + pCrvCompo->TrimEndAtLen( dLen + m_TParams.m_dDiam) ; + if ( pCrvCompo->IsValid()) { + bool bFound = false ; + for ( int uu = 1 ; uu < pCrvCompo->GetCurveCount() ; ++ uu) { + double dLenH = EPS_SMALL ; pCrvCompo->GetCurve( uu)->GetLength( dLenH) ; + if ( dLenH < dToll + 5 * EPS_SMALL) + continue ; + // cerco tra le curve successive vicine se ne trovo una con Feed Minima + int nProp ; pCrvCompo->GetCurveTempProp( uu, nProp, 0) ; + if ( abs ( nProp - int( FEED_DIVISOR * GetMinFeed()) < 5 * EPS_SMALL)) { + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; + bFound = true ; + break ; + } + } + if ( ! bFound && u != 0) { + // arrivato qui, so che successivamente non ho curve con Feed Minima vicine + int nProp ; pCrv->GetCurveTempProp( u - 1, nProp, 0) ; + if ( abs ( nProp - int( FEED_DIVISOR * GetMaxFeed()) < 5 * EPS_SMALL)) + // se anche la precedente ha Feed Massima -> la curva u-esima è piccola ed Isolata + pCrv->SetCurveTempProp( u, nProp, 0) ; + } + } + else + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; + } + } + } + + // controllo eventuali sovrapposizioni con lati aperti + AssignFeedForOpenEdge( pCrv, pCrv_orig) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::AssignFeedForReturnPath( ICurveComposite* pCrv) +{ + // controllo curva corrente + if ( pCrv == nullptr || !pCrv->IsValid() || pCrv->GetCurveCount() == 0) + return false ; + + // controllo se il Flag per assegnare la Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + + if ( pCrv == nullptr || ! pCrv->IsValid() || pCrv->GetCurveCount() == 0) + return false ; + + for ( int u = 0 ; u < ( int)pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed(), 0) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::AssignFeedCrvOnUnclearedRegions( ICurveComposite* pCrv) +{ + + // controllo validità della curva + if ( pCrv == nullptr || !pCrv->IsValid() || pCrv->GetCurveCount() == 0) + return false ; + + // controllo se il Flag per assegnare la Feed è attivo + if ( !m_bAssignFeed) + return AssignDefaultFeed( pCrv) ; + + if ( pCrv == nullptr || ! pCrv->IsValid() || pCrv->GetCurveCount() == 0) + return false ; + + for ( int u = 0 ; u < ( int)pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMinFeed(), 0) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::AssignDefaultFeed( ICurveComposite* pCrv) { + if ( pCrv == nullptr || !pCrv->IsValid() || pCrv->GetCurveCount() == 0) + return false ; + + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempProp( u, FEED_DIVISOR * GetMaxFeed(), 0) ; + + return true ; +} + +bool +Pocketing::DrawColoredCrvForFeedTest( ICurve* pCurve, double dFeed) +{ + return true ; + if ( abs( dFeed - GetMinFeed()) < EPS_SMALL) { + int rosso = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCurve->Clone()) ; + m_pGeomDB->SetMaterial( rosso, RED) ; + m_pGeomDB->SetStatus( rosso, ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || + m_Params.m_nSubType == POCKET_SUB_SPIRALIN) ? GDB_ST_OFF : GDB_ST_ON) ; + } else if ( abs( dFeed - GetMaxFeed()) < EPS_SMALL) { + int verde = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCurve->Clone()) ; + m_pGeomDB->SetMaterial( verde, GREEN) ; + m_pGeomDB->SetStatus( verde, ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || + m_Params.m_nSubType == POCKET_SUB_SPIRALIN) ? GDB_ST_OFF : GDB_ST_ON) ; + } + else { + int giallo = m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCurve->Clone()) ; + m_pGeomDB->SetMaterial( giallo, YELLOW) ; + m_pGeomDB->SetStatus( giallo, ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || + m_Params.m_nSubType == POCKET_SUB_SPIRALIN) ? GDB_ST_OFF : GDB_ST_ON) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::GetNewSrfByAnotherPocketing( ISurfFlatRegion* pSrf, ISurfFlatRegion* pSrf_noOpenEdge) +{ + // controllo dei parametri + if ( pSrf == nullptr || ! pSrf->IsValid() || pSrf->GetChunkCount() == 0 || m_dDiam_Prec < 0) + return false ; + + // se e i parametri ed il tool permettono la nuova lavoazione... + if ( m_TParams.m_dDiam / 2 + GetOffsR() < m_dDiam_Prec / 2 + m_dOffsetR_Prec) { + // clono la superificie ricavata in precedenza ( senza estensione con lati aperti) + PtrOwner pSrf_Sub( CloneSurfFlatRegion( pSrf)) ; + if ( IsNull( pSrf_Sub) || ! pSrf_Sub->IsValid()) + return false ; + // effettuo un Offset verso l'interno ( curve esterne che percorre il centro del Tool) + if ( pSrf_Sub->Offset( - m_dDiam_Prec / 2 - m_dOffsetR_Prec - 5 * EPS_SMALL, ICurve::OFF_FILLET)) { + + // effettuo un Offset del raggio del tool precedente per ricavare la regione svuotata in precedenza + if ( pSrf_Sub->Offset( m_dDiam_Prec / 2 + 20 * EPS_SMALL, ICurve::OFF_FILLET)) { + //int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_Sub->Clone()) ; + //m_pGeomDB->SetMaterial( r, RED) ; + } + + PtrOwner pSrf_clone( CloneSurfFlatRegion( pSrf_noOpenEdge)) ; + if ( pSrf_clone->Subtract( *pSrf_Sub)) { + //int v = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_clone->Clone()) ; + //m_pGeomDB->SetMaterial( v, GREEN) ; + + // ricavo la curva esterna originale + PtrOwner pCrvExt_orig( GetCurveComposite( pSrf->GetLoop( 0, 0))) ; + + //int y = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvExt_orig->Clone()) ; + //m_pGeomDB->SetMaterial( y, YELLOW) ; + + // superificie finale da restituire ... + PtrOwner pSrf_Final( CreateSurfFlatRegion()) ; + if ( IsNull( pSrf_Final)) + return false ; + + // per ogni chunk della superificie ricavata.... + for ( int c = 0 ; c < pSrf_clone->GetChunkCount() ; ++ c) { + + // singolo chunk della superificie modificato per i lati aperti... + PtrOwner pChunk_WithOpenEdges( CreateSurfFlatRegion()) ; + if ( IsNull( pChunk_WithOpenEdges)) + return false ; + + int nStat = 0 ; + PtrOwner pCrvExt( GetCurveComposite( pSrf_clone->GetLoop( c, 0))) ; + // setto tutte le sottocurve aperte + for ( int u = 0 ; u < pCrvExt->GetCurveCount() ; ++ u) { + pCrvExt->SetCurveTempProp( u, 1, 0) ; + const ICurve* pCrv_u = pCrvExt->GetCurve( u) ; + for ( int cu = 0 ; cu < pSrf->GetChunkCount() ; ++ cu) { + for ( int l = 1 ; l < pSrf->GetLoopCount( cu) ; ++ l) { + PtrOwner pCrvCompo_isl( GetCurveComposite( pSrf->GetLoop( cu, l))) ; + // se overlap con un' isola -> curva chiusa + if ( CheckSimpleOverlap( pCrv_u, pCrvCompo_isl, nStat) && nStat == 1) + pCrvExt->SetCurveTempProp( u, 0, 0) ; + } + } + for ( int cu = 0 ; cu < pSrf_noOpenEdge->GetChunkCount() ; ++ cu) { + for ( int l = 0 ; l < pSrf_noOpenEdge->GetLoopCount( cu) ; ++ l) { + // se overlap con curva della superficie originale -> copio la rispettiva temp prop + PtrOwner pCrvCompo( GetCurveComposite( pSrf_noOpenEdge->GetLoop( cu, l))) ; + SetTmpPropByOverlap( pCrvExt, u, pCrvCompo, nStat) ; + } + } + } + + //int R = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvExt->Clone()) ; + //m_pGeomDB->SetMaterial( R, RED) ; + + bool bSomeOpen = false ; + int nProp0 = -1 ; + for ( int u = 0 ; u < pCrvExt->GetCurveCount() && !bSomeOpen ; ++ u) { + if ( pCrvExt->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) + bSomeOpen = true ; + } + ICRVCOMPOPOVECTOR vCrvIsl ; + 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())) { + m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + return false ; + } + } + + // Chunk modificato con i lati aperti + pChunk_WithOpenEdges->AddExtLoop( Release( pCrvExt)) ; // aggiungo la curva esterna + for ( int i = 1 ; i < int( vCrvIsl.size()) ; ++ i) + pChunk_WithOpenEdges->AddIntLoop( Release( vCrvIsl[i])) ; // aggiungo le eventuali isole + + + //int W = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pChunk_WithOpenEdges->Clone()) ; + //m_pGeomDB->SetMaterial( W, WHITE) ; + + // aggiungo questo Chunk alla superificie finale ( potrebbero essere sovrapposti per alcune parti...) + if ( pSrf_Final->GetChunkCount() == 0) + pSrf_Final.Set( pChunk_WithOpenEdges) ; + else + pSrf_Final->Add( *pChunk_WithOpenEdges) ; + + + } + + pSrf->Clear() ; + pSrf->CopyFrom( pSrf_Final) ; + } + } } return true ; } + //---------------------------------------------------------------------------- bool Pocketing::GetDynamicClearedRegion( ISurfFlatRegion* pSrfPrec, const ICurveComposite* pCrv) diff --git a/Pocketing.h b/Pocketing.h index 4668567..ed736e5 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -113,18 +113,19 @@ 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, const ICRVCOMPOPOVECTOR& vCrvIsl) ; + bool AdjustContourWithOpenEdges( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vCrvIsl, + double dDiam, double dOffR) ; bool AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vCrvIsl, bool bOrder = false) ; bool GetParamForPtStartOnEdge( const ICurve* pCrv, const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vCrvIsl, double& dPar) ; + bool GetNewSrfByAnotherPocketing( ISurfFlatRegion* pSrf, ISurfFlatRegion* pSrf_noOpenEdge) ; // =================================================================== // ============================ ZigZag =============================== bool AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; bool CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpCrvs) ; - bool CalcBoundedZigZagLink( ICurveLine* pCrv1, ICurveLine* pCrv2, ICRVCOMPOPOVECTOR& vOffIslands, - ICurveComposite* pCrvLink, int nIndexCut = 3) ; + bool CalcZigZagLink( ICurveComposite* pCrv1, ICurveComposite* pCrv2, ICurveComposite* pCrvLink) ; bool OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d & vtTool, double dDepth, double dSafeZ, Frame3d& frPocket, ICurveComposite* pCrvOrig, bool& bOptimizedZigZag, ICRVCOMPOPOVECTOR& vpCrvs) ; @@ -159,7 +160,7 @@ class Pocketing : public Machining bool CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, const int nIter, const int nOffsCount, const Vector3d& vtN, bool& bInsert) ; bool GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICURVEPOVECTOR& vLinks, - ISurfFlatRegion* pSrfToCut) ; + const ICurveComposite* pCrv_orig, ISurfFlatRegion* pSrfToCut) ; bool GetDynamicClearedRegion( ISurfFlatRegion* pSrfPrec, const ICurveComposite* pCrv) ; bool RemoveFirstLoopFromSfr( ISurfFlatRegion* pSrfOrig ) ; bool RemoveExtraParts( ISurfFlatRegion* pSrfToCut, ICRVCOMPOPOVECTOR& vOffs, ICRVCOMPOPOVECTOR& vOffsClosedCurves, @@ -170,9 +171,9 @@ class Pocketing : public Machining ICurveComposite* pCrv2, int& nIndex) ; bool CutLinkToClosestPoint( ICURVEPOVECTOR& vCurves, ICRVCOMPOPOVECTOR& vOffs, const Point3d& ptFocus, ICurveComposite* pCrv1, ICurveComposite* pCrv2, bool& bFound, int& nIndex) ; - bool GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, Point3d& ptC, bool bCir, + bool GetNewCurvetWithCentroid( const ICurveComposite* pCrvH1, const ICurveComposite* pCrvH2, Point3d& ptC, bool bCir, ICRVCOMPOPOVECTOR& VFirstOff, ICurveComposite* pCrvNewCurve) ; - bool GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, ICurveComposite* pCrvPath, + bool GetNewCurvetWithPath( const ICurveComposite* pCrvH1, const ICurveComposite* pCrvH2, ICurveComposite* pCrvPath, ICRVCOMPOPOVECTOR& VFirstOff, ICRVCOMPOPOVECTOR& VoffsCl, ICurveComposite* pCrvNewCurve) ; bool ManageSmoothAndAutoInters( ICurveComposite* pCrv, ICurveComposite* pCrvPath, ICurveComposite* pPath1, ICurveComposite* pPath2, ICRVCOMPOPOVECTOR& vOffsCL) ; @@ -206,27 +207,24 @@ class Pocketing : public Machining double GetMinFeed( void ) const { return GetFeed() * GetSideStep() / m_TParams.m_dDiam ; } double GetMaxFeed( void ) const { return GetFeed() ; } bool GetFeedForParam( double& dPar, double& dFeed) ; - bool CheckCrvToolSurfInters( const ICurve* pCrv1, const ISurfFlatRegion* pSrfRemoved, const ICurve* pCrv2, - bool& bIsOut, double dToll = EPS_SMALL) ; + bool AssignDefaultFeed( ICurveComposite* pCrv) ; + bool DrawColoredCrvForFeedTest( ICurve* pCurve, double dFeed) ; bool AssignFeedForOpenEdge( ICurveComposite* pCrv, const ICurveComposite* pCrvOF_ori) ; bool AssignFeedForLineInOut( ICurveComposite* pCrv, const bool bIsIn) ; + bool AssignFeedOnCorners( ICurveComposite* pCrv, const ICurveComposite* pCrv_orig, const double dLenToll) ; bool AssignFeedForEdgeCleaning( ICurveComposite *pCrv, const ICRVCOMPOPOVECTOR& vCrvOF_orig, int nInd = -1) ; - // --- SpiralIn/SpiralOut --- - bool AssignFeedSpiral( ICurveComposite* pCrv, const int nCrvType, const bool bIsFirst, const bool bIsLast, - const ISurfFlatRegion* pSrfRemoved, const ICurveComposite* pCrvOF_orig, - const ICurveComposite* pCrv_simple_Offset) ; - bool AssignFeedForSpiralLinks( ICurveComposite* pCrvLink, const ISurfFlatRegion* pSrfRemoved) ; - bool AssignFeedSpiralForCrvOnUnclearedRegion( ICurveComposite* pCrv, const ICurveComposite* pCrv_simple_offs) ; + // --- ZigZag/OneWay --- + bool AssignFeedZigZagOneWay( ICurveComposite* pCompoLine, const bool bIsLink, const ICURVEPOVECTOR& vLAbove, + const ICURVEPOVECTOR& vLUnder, const ICRVCOMPOPOVECTOR& vAddedLinks) ; + + // --- SpiralIn/SpiralOut --- + bool AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs, const bool bIsLink, + const ICRVCOMPOPOVECTOR& vLinks_done, const ICurveComposite* pCrv_orig, double dToll) ; bool AssignFeedSpiralOpt( const int nOptType, ICurveComposite* pCrv) ; - - // --- ZigZag --- - bool AssignFeedForZigZagParts( ICurveComposite* pCrvPart, const bool bIsAbsFirst, const ISurfFlatRegion* pSrfRemoved, - const int nFeedFirstLine) ; - - // --- OneWay --- - bool AssignFeedOneWay( ICurveLine* pLine, const ISurfFlatRegion* pSrfRemoved) ; - + bool AssignFeedCrvOnUnclearedRegions( ICurveComposite* pCrv) ; + bool AssignFeedForReturnPath( ICurveComposite* pCrv) ; + // ========================================================================= // ============================ IN/OUT ===================================== @@ -291,25 +289,29 @@ class Pocketing : public Machining return m_Params.m_nLeadOutType ; } private : - SELVECTOR m_vId ; // identificativi entit� geometriche da lavorare - PocketingData m_Params ; // parametri lavorazione - ToolData m_TParams ; // parametri utensile - double m_dTHoldBase ; // posizione base del porta-utensile - double m_dTHoldLen ; // lunghezza del porta-utensile - double m_dTHoldDiam ; // diametro del porta-utensile - double m_dMaxHelixRad ; // raggio massimo attacco ad elica nel caso di cerchi - int m_nStatus ; // stato di aggiornamento della lavorazione - int m_nPockets ; // numero di percorsi di svuotatura generati - bool m_bTiltingTab ; // flag utilizzo tavola basculante - Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante - bool m_bAboveHead ; // flag utilizzo testa da sopra - bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto - Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto - AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto - bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo - bool m_bOptOffset = true ; // flag per ottimizzazione numero di Offset necessari - bool m_bOptOffsetCM = false ; // flag per ottimizzazione numero di Offset necessari con centroidi e medial Axis - double m_dDiam_Prec ; // diametro utensile per precedente svuotatura - double m_dOffsetR_Prec ; // Offset radiale della svuotatura precedente + SELVECTOR m_vId ; // identificativi entit� geometriche da lavorare + PocketingData m_Params ; // parametri lavorazione + ToolData m_TParams ; // parametri utensile + double m_dTHoldBase ; // posizione base del porta-utensile + double m_dTHoldLen ; // lunghezza del porta-utensile + double m_dTHoldDiam ; // diametro del porta-utensile + double m_dMaxHelixRad ; // raggio massimo attacco ad elica nel caso di cerchi + int m_nStatus ; // stato di aggiornamento della lavorazione + int m_nPockets ; // numero di percorsi di svuotatura generati + bool m_bTiltingTab ; // flag utilizzo tavola basculante + Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante + bool m_bAboveHead ; // flag utilizzo testa da sopra + bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto + Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto + AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto + bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo + + bool m_IntersRaw = true ; // flag per intersezione con grezzo + bool m_ProjectRaw = true ; // flag di proiezione del grezzo + bool m_bOptOffset = true ; // flag per ottimizzazione numero di Offset necessari + bool m_bOptOffsetCM = false ; // flag per ottimizzazione numero di Offset necessari con centroidi e medial Axis + bool m_bAssignFeed = true ; // flag per controllo della Feed + double m_dDiam_Prec = 75.0 ; // diametro utensile per precedente svuotatura + double m_dOffsetR_Prec = 0.0 ; // Offset radiale della svuotatura precedente } ; \ No newline at end of file