diff --git a/PocketingNT.cpp b/PocketingNT.cpp index 13141e8..13ff64e 100644 --- a/PocketingNT.cpp +++ b/PocketingNT.cpp @@ -46,8 +46,6 @@ #include "/EgtDev/Include/EGkDistPointSurfFr.h" #include - - using namespace std ; //------------------------------ Errors -------------------------------------- @@ -82,6 +80,7 @@ using namespace std ; // 2430 = "Error in PocketingNT : adjust open edges failed" // 2431 = "Error in PocketingNT : LeadIn with Mill NoTip in material" // 2432 = "Error in PocketingNT : Mirror for Double calculation failed" +// 2433 = "Error in PocketingNT : Calc Region Elevation failed" // 2451 = "Warning in PocketingNT : Skipped entity (xx)" // 2452 = "Warning in PocketingNT : No machinable pocket" // 2453 = "Warning in PocketingNT : Tool name changed (xx)" @@ -90,12 +89,22 @@ using namespace std ; // 2456 = "Warning in PocketingNT : machining step too small (xx)" // 2457 = "Warning in PocketingNT : machining step (xxx) bigger than MaxMaterial (yyy)" // 2458 = "Warning in PocketingNT : machining depth (xxx) bigger than MaxMaterial (yyy)" +// 2459 = "Warning in PocketingNT : Steps too far away from Raw" //---------------------------------------------------------------------------- static string KEY_OPEN = "OPEN" ; static string KEY_THICK = "THICK" ; static int LINK_CURVE_PROP = -3 ; +//---------------------------------------------------------------------------- +// _debug +#define DEBUG_OPEN_EDGE_EXTENSION 0 +#define DEBUG_FLATREGIONS 0 +#if DEBUG_OPEN_EDGE_EXTENSION || DEBUG_FLATREGIONS + #include "EgtDev/Include/EGkGeoPoint3d.h" + #include "EgtDev/Include/EGkFrame3d.h" +#endif + //---------------------------------------------------------------------------- #if POCKETING_NT == 1 USEROBJ_REGISTER( GetOperationClass( OPER_POCKETING), PocketingNT) ; @@ -1118,6 +1127,7 @@ PocketingNT::GetCurves( SelData Id, ICURVEPLIST& lstPC) // se curva if ( ( pGObj->GetType() & GEO_CURVE) != 0) { PtrOwner pCurve ; + Vector3d vtExtr ; // se direttamente curva if ( Id.nSub == SEL_SUB_ALL) { // recupero la curva @@ -1129,9 +1139,13 @@ PocketingNT::GetCurves( SelData Id, ICURVEPLIST& lstPC) // recupero eventuali informazioni per lati aperti SetCurveAllTempProp( Id.nId, false, pCurve) ; // se estrusione mancante, imposto default - Vector3d vtExtr ; if ( ! pCurve->GetExtrusion( vtExtr) || vtExtr.IsSmall()) pCurve->SetExtrusion( Z_AX) ; + // sistemo senso antiorario visto dalla direzione di estrusione + Plane3d plPlane ; double dArea ; + pOriCurve->GetArea( plPlane, dArea) ; + if ( plPlane.GetVersN() * vtExtr * dArea < 0) + pCurve->Invert() ; } // altrimenti sottocurva di composita else { @@ -1148,13 +1162,17 @@ PocketingNT::GetCurves( SelData Id, ICURVEPLIST& lstPC) // reset proprietà temporanee ResetCurveAllTempProp( pCurve) ; // recupero estrusione e spessore - Vector3d vtExtr ; if ( ! pCompo->GetExtrusion( vtExtr) || vtExtr.IsSmall()) vtExtr = Z_AX ; pCurve->SetExtrusion( vtExtr) ; double dThick ; if ( pCompo->GetThickness( dThick)) pCurve->SetThickness( dThick) ; + // sistemo senso antiorario visto dalla direzione di estrusione + Plane3d plPlane ; double dArea ; + pCompo->GetArea( plPlane, dArea) ; + if ( plPlane.GetVersN() * vtExtr * dArea < 0) + pCurve->Invert() ; } if ( IsNull( pCurve)) return false ; @@ -1212,7 +1230,7 @@ PocketingNT::GetCurves( SelData Id, ICURVEPLIST& lstPC) int nFlag = int( dPar) ; // se non c'è nulla di adiacente, lato aperto if ( nFlag == SVT_NULL) - pCrvCompo->SetCurveTempProp( nInd, 1) ; + pCrvCompo->SetCurveTempProp( nInd, TEMP_PROP_OPEN_EDGE) ; // altrimenti verifico se la faccia adiacente forma diedro convesso o concavo else { bool bAdjac ; @@ -1240,6 +1258,8 @@ PocketingNT::GetCurves( SelData Id, ICURVEPLIST& lstPC) // sistemazioni varie AdjustCurveFromSurf( pCrvCompo, TOOL_ORTHO, FACE_CONT, V_NULL, 0) ; // la restituisco + if ( m_bAllClose) + ResetCurveAllTempProp( pCrvCompo) ; lstPC.emplace_back( Release( pCrvCompo)) ; } return true ; @@ -1299,6 +1319,8 @@ PocketingNT::SetCurveAllTempProp( int nCrvId, bool bForcedClose, ICurve* pCurve, *pbSomeOpen = false ; // reset proprietà temporanee ResetCurveAllTempProp( pCurve) ; + if ( m_bAllClose) + return true ; // se forzato chiuso o non presenti info per lati aperti, esco if ( bForcedClose || ! m_pGeomDB->ExistsInfo( nCrvId, KEY_OPEN)) return true ; @@ -1379,6 +1401,9 @@ PocketingNT::Chain( int nGrpDestId) vpCrvs.reserve( m_vId.size()) ; // vettore selettori delle curve originali SELVECTOR vInds ; + // flag per imposizione lati chiusi + m_bAllClose = false ; + GetValInNotes( m_Params.m_sUserNotes, "bAllClose", m_bAllClose) ; // recupero tutte le curve e le porto in globale for ( const auto& Id : m_vId) { // prendo le curve @@ -1418,7 +1443,7 @@ PocketingNT::Chain( int nGrpDestId) } } // recupero i percorsi concatenati e definisco la regione piana di svuotatura - SurfFlatRegionByContours SfrByC ; + ICRVCOMPOPOVECTOR vCrvCompo ; INTVECTOR vnId2 ; while ( chainC.GetChainFromNear( ptNear, false, vnId2)) { // creo una curva composita @@ -1487,7 +1512,23 @@ PocketingNT::Chain( int nGrpDestId) if ( ! ApproxWithArcsIfUseful( pCrvCompo, true)) return false ; // inserisco la curva nella regione piana - SfrByC.AddCurve( Release( pCrvCompo)) ; + vCrvCompo.emplace_back( Release( pCrvCompo)) ; + // salvo vettore estrusione + vCrvCompo.back()->SetExtrusion( vtExtr) ; + // salvo la thickness come seconda temp prop ( la Sfr rimuove la thick delle curve) + vCrvCompo.back()->SetTempParam( dThick, 1) ; + } + + // per ogni curva estendo i suoi lati aperti fino al bordo del grezzo) + SurfFlatRegionByContours SfrByC ; + for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) { + Vector3d vtExtr ; vCrvCompo[i]->GetExtrusion( vtExtr) ; + double dThick = vCrvCompo[i]->GetTempParam( 1) ; + if ( ! ExtendOpenEdgesToRaw( vCrvCompo[i], vtExtr)) + return false ; + vCrvCompo[i]->SetExtrusion( vtExtr) ; + vCrvCompo[i]->SetTempParam( dThick, 1) ; + SfrByC.AddCurve( Release( vCrvCompo[i])) ; } // scorro le regioni piane ricavate dalle curve @@ -1506,15 +1547,25 @@ PocketingNT::Chain( int nGrpDestId) PtrOwner pSfrChunk( pSfrCurr->CloneChunk( nC)) ; if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid()) return false ; - int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, ::CloneSurfFlatRegion( pSfrChunk)) ; - if ( nNewId == GDB_ID_NULL) - return false ; // salvo eventuali lati aperti per il Chunk corrente + int nNewId = GDB_ID_NULL ; for ( int nL = 0 ; nL < pSfrChunk->GetLoopCount( 0) ; ++ nL) { // recupero il Loop PtrOwner pCrvLoop( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, nL))) ; if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) return false ; + // se loop esterno + if ( nL == 0) { + // recupero la ThickNess e l'Estrusione + double dThick = pCrvLoop->GetTempParam( 1) ; + Vector3d vtExtr ; pCrvLoop->GetExtrusion( vtExtr) ; + // aggiungo la superfifice al gruppo con le relative informazioni + nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, ::CloneSurfFlatRegion( pSfrChunk)) ; + if ( nNewId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetInfo( nNewId, KEY_THICK, dThick) ; + m_pGeomDB->SetInfo( nNewId, KEY_EXTR, vtExtr) ; + } // memorizzo le proprietà di lato aperto nelle Info del gruppo INTVECTOR vIndOpen ; for ( int nU = 0 ; nU < pCrvLoop->GetCurveCount() ; ++ nU) { @@ -1524,14 +1575,6 @@ PocketingNT::Chain( int nGrpDestId) } if ( ! vIndOpen.empty()) m_pGeomDB->SetInfo( nNewId, KEY_OPEN + ToString( nL), vIndOpen) ; - // memorizzo la Thickness e l'Estrusione nelle Info del gruppo - if ( nL == 0) { - double dThick = pCrvLoop->GetTempParam( 1) ; - m_pGeomDB->SetInfo( nNewId, KEY_THICK, dThick) ; - Vector3d vtExtr ; - pCrvLoop->GetExtrusion( vtExtr) ; - m_pGeomDB->SetInfo( nNewId, KEY_EXTR, vtExtr) ; - } } } // aggiorno la regione piana con la successiva calcolata @@ -1608,49 +1651,16 @@ PocketingNT::GetExtrusionStm( const ISurfFlatRegion* pSfr, const Vector3d& vtTra // scorro i Loop della superficie piana bool bExistClose = false ; - for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) { - for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) { + for ( int nC = 0 ; nC < pMySfr->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pMySfr->GetLoopCount( nC) ; ++ nL) { // recupero il Loop come curva composita - PtrOwner pCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( nC, nL))) ; + PtrOwner pCompoLoop( ConvertCurveToComposite( pMySfr->GetLoop( nC, nL))) ; if ( IsNull( pCompoLoop) || ! pCompoLoop->IsValid()) return nullptr ; // recupero i tratti con proprietà uniformi ICRVCOMPOPOVECTOR vpCrvs ; - int nCurrTempProp ; - int nParStart = 0 ; - for ( int nU = 0 ; nU < pCompoLoop->GetCurveCount() ; ++ nU) { - // ricavo la TmpProp - int nTempProp = TEMP_PROP_INVALID ; - pCompoLoop->GetCurveTempProp( nU, nTempProp) ; - if ( nU == 0) { - nCurrTempProp = nTempProp ; - nParStart = nU ; - } - // se TmpProp differiscono, ricavo il tratto di curva omogeneo - else if ( nCurrTempProp != nTempProp) { - PtrOwner pCrv( ConvertCurveToComposite( pCompoLoop->CopyParamRange( nParStart, nU))) ; - if ( IsNull( pCrv)) - return nullptr ; - pCrv->SetTempProp( nCurrTempProp) ; // globale, al tratto di curva nel vettore - vpCrvs.emplace_back( Release( pCrv)) ; - nCurrTempProp = nTempProp ; - nParStart = nU ; - } - } - // ultima curva... - PtrOwner pCrvLast( ConvertCurveToComposite( pCompoLoop->CopyParamRange( nParStart, pCompoLoop->GetCurveCount()))) ; - if ( ! IsNull( pCrvLast)) { - pCrvLast->SetTempProp( nCurrTempProp) ; - vpCrvs.emplace_back( Release( pCrvLast)) ; - } - if ( vpCrvs.size() > 1) { // unisco il primo e l'ultimo se estremi compatibili - Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ; - Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ; - if ( AreSamePointApprox( ptS, ptE) && vpCrvs[0]->GetTempProp() == vpCrvs.back()->GetTempProp()) { - vpCrvs[0]->AddCurve( Release( vpCrvs.back()), false) ; - vpCrvs.erase( vpCrvs.end() - 1) ; - } - } + if ( ! GetHomogeneousParts( pCompoLoop, vpCrvs)) + return nullptr ; // scorro i tratti omogenei chiusi for ( int nP = 0 ; nP < int( vpCrvs.size()) ; ++ nP) { if ( vpCrvs[nP]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) { @@ -1771,6 +1781,213 @@ PocketingNT::GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, doubl return ( ( ! IsNull( pSfrFromCrvs) && pSfrFromCrvs->IsValid()) ? Release( pSfrFromCrvs) : nullptr) ; } +//---------------------------------------------------------------------------- +bool +PocketingNT::GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) const +{ + // controllo dei parametri + if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid()) + return false ; + vpCrvs.clear() ; + + // scorro tutte le curve semplici nella composita + int nCurrTempProp ; + int nParStart = 0 ; + for ( int i = 0 ; i < pCrvCompo->GetCurveCount() ; ++ i) { + // ricavo la TmpProp + int nTempProp ; + pCrvCompo->GetCurveTempProp( i, nTempProp) ; + if ( i == 0) { + nCurrTempProp = nTempProp ; + nParStart = i ; + } + // se TmpProp differiscono, ricavo il tratto di curva omogeneo + else if ( nCurrTempProp != nTempProp) { + PtrOwner pCrv( ConvertCurveToComposite( pCrvCompo->CopyParamRange( nParStart, i))) ; + if ( IsNull( pCrv)) + return false ; + pCrv->SetTempProp( nCurrTempProp) ; // globale, al tratto di curva nel vettore + vpCrvs.emplace_back( Release( pCrv)) ; + nCurrTempProp = nTempProp ; + nParStart = i ; + } + } + // ultima curva... + PtrOwner pCrvLast( ConvertCurveToComposite( pCrvCompo->CopyParamRange( nParStart, pCrvCompo->GetCurveCount()))) ; + if ( ! IsNull( pCrvLast)) { + pCrvLast->SetTempProp( nCurrTempProp) ; + vpCrvs.emplace_back( Release( pCrvLast)) ; + } + if ( vpCrvs.size() > 1) { // unisco il primo e l'ultimo se estremi compatibili + Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ; + Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ; + if ( AreSamePointApprox( ptS, ptE) && vpCrvs[0]->GetTempProp() == vpCrvs.back()->GetTempProp()) { + vpCrvs[0]->AddCurve( Release( vpCrvs.back()), false) ; + vpCrvs.erase( vpCrvs.end() - 1) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PocketingNT::ExtendOpenEdgesToRaw( ICurveComposite* pCompo, const Vector3d& vtExtr) +{ + // controllo validità della curva + if ( pCompo == nullptr || ! vtExtr.IsValid()) + return false ; + if ( ! pCompo->IsValid()) + return true ; + + #if DEBUG_OPEN_EDGE_EXTENSION + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay, "Open_edge_extension") ; + _debug_draw_loop( pCompo, nLay, false) ; + #endif + + // recupero i tratti con proprietà uniformi della superficie + ICRVCOMPOPOVECTOR vpCrv ; + if ( ! GetHomogeneousParts( pCompo, vpCrv)) + return false ; + // se non esistono lati aperti, non devo fare nulla + if ( int( vpCrv.size()) == 1 && vpCrv[0]->GetTempProp() == TEMP_PROP_CLOSE_EDGE) + return true ; + + // recupero la superficie del grezzo + PtrOwner pStmRaw( GetRaw()) ; + if ( IsNull( pStmRaw) || ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0) { + m_pMchMgr->SetLastError( 3025, "Error in PocketingNT : RawPart not computable") ; + return false ; + } + + // definisco un piano di taglio per il grezzo, mediante la curva + Plane3d plCut ; + Point3d ptC ; pCompo->GetCentroid( ptC) ; + if ( ! plCut.Set( ptC, - vtExtr)) + return false ; + + // taglio il grezzo con il piano + if ( ! pStmRaw->Cut( plCut, true)) + return false ; + if ( ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0) + return true ; + + #if DEBUG_OPEN_EDGE_EXTENSION + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pStmRaw->Clone()) ; + m_pGeomDB->SetMaterial( a, Color( 0.2, 0.2, 0.8, .65)) ; + #endif + + // recupero il Box del grezzo definito dal frame implito dal piano + Frame3d frCut ; + if ( ! frCut.Set( ptC, vtExtr)) + return false ; + frCut.Invert() ; + BBox3d BBoxRawCut ; + if ( ! pStmRaw->GetBBox( frCut, BBoxRawCut)) + return false ; + + #if DEBUG_OPEN_EDGE_EXTENSION + frCut.Invert() ; + _degub_draw_box( BBoxRawCut, frCut, nLay) ; + frCut.Invert() ; + #endif + + // definisco offset di estensione per tratti aperti + double dOffs = 0 ; + m_dOpenExtension = 0 ; + GetValInNotes( m_Params.m_sUserNotes, "OpenExtension", m_dOpenExtension) ; + if ( m_dOpenExtension < EPS_SMALL) + dOffs = max( BBoxRawCut.GetDimX(), BBoxRawCut.GetDimY()) + m_TParams.m_dDiam ; + else + dOffs = abs( m_dOpenExtension) ; + + // sostiuisco ogni tratto aperto con il suo Offset + for ( int i = 0 ; i < int( vpCrv.size()) ; ++ i) { + if ( vpCrv[i]->GetTempProp() == TEMP_PROP_OPEN_EDGE) { + vpCrv[i]->SetExtrusion( vtExtr) ; + OffsetCurve OffsCurve ; + OffsCurve.Make( vpCrv[i], dOffs, ICurve::OFF_EXTEND) ; + PtrOwner pCompoOpenOffs( ConvertCurveToComposite( OffsCurve.GetLongerCurve())) ; ; + if ( ! IsNull( pCompoOpenOffs) && pCompoOpenOffs->IsValid()) { + for ( int j = 0 ; j < pCompoOpenOffs->GetCurveCount() ; ++ j) + pCompoOpenOffs->SetCurveTempProp( j, TEMP_PROP_OPEN_EDGE, 0) ; + pCompoOpenOffs->SetTempProp( TEMP_PROP_OPEN_EDGE, 0) ; + vpCrv[i].Set( Release( pCompoOpenOffs)) ; + } + // se la curva era tutta aperta, ho finito + if ( int( vpCrv.size()) == 1 && vpCrv[0]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) { + pCompo->Clear() ; + pCompo->CopyFrom( vpCrv[0]) ; + #if DEBUG_OPEN_EDGE_EXTENSION + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pCompo->Clone()) ; + m_pGeomDB->SetMaterial( a, ORANGE) ; + #endif + return ( pCompo != nullptr && pCompo->IsValid()) ; + } + } + } + + // scorro i tratti omogenei + PtrOwner pCompoExtended( CreateCurveComposite()) ; + if ( IsNull( pCompoExtended)) + return false ; + Point3d ptLineS, ptLineE ; + for ( int i = 0 ; i < int( vpCrv.size()) ; ++ i) { + if ( vpCrv[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) { + // recupero l'indice del tratto chiuso precedente e successivo + int nIndCLprec = ( i == 0 ? int( vpCrv.size()) -1 : i - 1) ; + int nIndCLsucc = ( i == int( vpCrv.size()) -1 ? 0 : i + 1) ; + // tratto lineare chiuso precedente + vpCrv[nIndCLprec]->GetEndPoint( ptLineS) ; + vpCrv[i]->GetStartPoint( ptLineE) ; + PtrOwner pLinePrec( CreateCurveLine()) ; + if ( ! IsNull( pLinePrec) && pLinePrec->Set( ptLineS, ptLineE)) { + #if DEBUG_OPEN_EDGE_EXTENSION + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pLinePrec->Clone()) ; + m_pGeomDB->SetMaterial( a, AQUA) ; + #endif + if ( ! pCompoExtended->AddCurve( Release( pLinePrec))) + return false ; + pCompoExtended->SetCurveTempProp( pCompoExtended->GetCurveCount() - 1, 0, TEMP_PROP_CLOSE_EDGE) ; + } + // tratto aperto esteso + #if DEBUG_OPEN_EDGE_EXTENSION + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, vpCrv[i]->Clone()) ; + m_pGeomDB->SetMaterial( a, ORANGE) ; + #endif + if ( ! pCompoExtended->AddCurve( vpCrv[i]->Clone())) + return false ; + // tratto lineare chiuso successivo + vpCrv[i]->GetEndPoint( ptLineS) ; + vpCrv[nIndCLsucc]->GetStartPoint( ptLineE) ; + PtrOwner pLineSucc( CreateCurveLine()) ; + if ( ! IsNull( pLineSucc) && pLineSucc->Set( ptLineS, ptLineE)) { + #if DEBUG_OPEN_EDGE_EXTENSION + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pLineSucc->Clone()) ; + m_pGeomDB->SetMaterial( a, AQUA) ; + #endif + if ( ! pCompoExtended->AddCurve( Release( pLineSucc))) + return false ; + pCompoExtended->SetCurveTempProp( pCompoExtended->GetCurveCount() - 1, 0, TEMP_PROP_CLOSE_EDGE) ; + } + } + else if ( vpCrv[i]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) { + #if DEBUG_OPEN_EDGE_EXTENSION + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, vpCrv[i]->Clone()) ; + m_pGeomDB->SetMaterial( a, AQUA) ; + #endif + if ( ! pCompoExtended->AddCurve( vpCrv[i]->Clone())) + return false ; + } + } + + pCompo->Clear() ; + pCompo->CopyFrom( pCompoExtended) ; + return ( pCompo != nullptr && pCompo->IsValid()) ; +} + //---------------------------------------------------------------------------- bool PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion) @@ -1846,7 +2063,7 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe if ( pSfrLimit == nullptr || ! pSfrLimit->IsValid()) return false ; // piccolo Offset di correzione - PtrOwner pSfrOffs( pSfrPock->CreateOffsetSurf( 5 * EPS_SMALL, ICurve::OFF_FILLET)) ; + PtrOwner pSfrOffs( pSfrPock->CreateOffsetSurf( 10 * EPS_SMALL, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid()) return false ; // sottrazione @@ -1862,41 +2079,8 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe return false ; // recupero i tratti con proprietà omogenee ICRVCOMPOPOVECTOR vpCrvs ; - int nCurrTempProp = TEMP_PROP_INVALID ; - int nParStart = 0 ; - for ( int i = 0 ; i < pCrvLoop->GetCurveCount() ; ++ i) { - // ricavo la TmpProp - int nTempProp = TEMP_PROP_INVALID ; - pCrvLoop->GetCurveTempProp( i, nTempProp) ; - if ( i == 0) { - nCurrTempProp = nTempProp ; - nParStart = i ; - } - // se TmpProp differiscono, ricavo il tratto di curva omogeneo - else if ( nCurrTempProp != nTempProp) { - PtrOwner pCrv( ConvertCurveToComposite( pCrvLoop->CopyParamRange( nParStart, i))) ; - if ( IsNull( pCrv)) - return false ; - pCrv->SetTempProp( nCurrTempProp) ; // globale, al tratto di curva nel vettore - vpCrvs.emplace_back( Release( pCrv)) ; - nCurrTempProp = nTempProp ; - nParStart = i ; - } - } - // ultima curva... - PtrOwner pCrvLast( ConvertCurveToComposite( pCrvLoop->CopyParamRange( nParStart, pCrvLoop->GetCurveCount()))) ; - if ( ! IsNull( pCrvLast)) { - pCrvLast->SetTempProp( nCurrTempProp) ; - vpCrvs.emplace_back( Release( pCrvLast)) ; - } - if ( vpCrvs.size() > 1) { // unisco il primo e l'ultimo se estremi compatibili - Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ; - Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ; - if ( AreSamePointApprox( ptS, ptE) && vpCrvs[0]->GetTempProp() == vpCrvs.back()->GetTempProp()) { - vpCrvs[0]->AddCurve( Release( vpCrvs.back()), false) ; - vpCrvs.erase( vpCrvs.end() - 1) ; - } - } + if ( ! GetHomogeneousParts( pCrvLoop, vpCrvs)) + return false ; // scorro i tratti omogenei aperti for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) { @@ -1986,7 +2170,6 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe } return true ; - } //---------------------------------------------------------------------------- @@ -2041,7 +2224,6 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) if ( m_Params.m_bToolInvert) { pSfr->Invert() ; vtExtr.Invert() ; - dThick = - dThick ; } // recupero il box del grezzo in globale @@ -2080,22 +2262,27 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) // assegno il versore fresa Vector3d vtTool = vtExtr ; - // recupero il Loop esterno della regione da svuotatare - PtrOwner pCrvLoopExt( ConvertCurveToComposite( pSfr->GetLoop( 0, 0))) ; - if ( IsNull( pCrvLoopExt) || ! pCrvLoopExt->IsValid()) - return false ; - - // calcolo l'elevazione massima - double dElev ; - if ( CalcRegionElevation( pCrvLoopExt, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, m_TParams.m_dLen, dElev)) { - if ( dElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { - BBox3d b3Crv ; - pCrvLoopExt->GetLocalBBox( b3Crv) ; - dElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min( 0., dThick) + dDepth) ; + // calcolo l'elevazione massima (tra tutti i Loop di tutti i Chunk della regione) + double dElev = 0. ; + for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfr->GetLoopCount( nL) ; ++ nL) { + // recupero la curva + PtrOwner pCrvLoop( ConvertCurveToComposite( pSfr->GetLoop( nC, nL))) ; + if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) + return false ; + // se isola inverto + if ( nL > 0) + pCrvLoop->Invert() ; + // determino l'elevazione + double dCurrElev ; + if ( ! CalcRegionElevation( pCrvLoop, vtTool, 0., 0.5 * m_TParams.m_dDiam, m_TParams.m_dLen, dCurrElev)) { + m_pMchMgr->SetLastError( 2433, "Error in PocketingNT : Calc Region Elevation failed") ; + return false ; + } + // aggiorno l'elevazione + dElev = max( dElev, dCurrElev) ; } } - else - return false ; // eventuale imposizione massima elevazione da note utente double dMaxElev ; if ( GetValInNotes( m_Params.m_sUserNotes, "MaxElev", dMaxElev) && dElev > dMaxElev) @@ -2120,14 +2307,19 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) return false ; } - // verifico di non superare il massimo materiale - // se lo step supera la capacità dell'utensile + // verifico di non superare il massimo materiale (se lo step supera la capacità dell'utensile) if ( m_Params.m_dStep > m_TParams.m_dMaxMat + EPS_SMALL) { dOkStep = m_TParams.m_dMaxMat + EPS_SMALL ; string sInfo = "Warning in PocketingNT : machining step (" + ToString( m_Params.m_dStep, 1) + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; m_pMchMgr->SetWarning( 2457, sInfo) ; } + + // porto la superficie nel punto più basso della lavorazione + pSfr->Translate( - vtTool * dDepth) ; + // aggiorno la sua nuova elevazione + dElev += dDepth ; + // se lavorazione singola if ( dOkStep < EPS_SMALL || dOkStep > dElev) { // se l'elevazione supera la capacità dell'utensile @@ -2135,7 +2327,9 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) string sInfo = "Warning in PocketingNT : machining depth (" + ToString( dElev, 1) + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; m_pMchMgr->SetWarning( 2458, sInfo) ; - dDepth -= dElev - m_TParams.m_dMaxMat ; + // traslo la superficie nel nuovo punto più basso + pSfr->Translate( vtTool * ( dElev - m_TParams.m_dMaxMat)) ; + // aggiorno l'elevazione alla massima profondità raggiunta dall'utensile dElev = m_TParams.m_dMaxMat ; } } @@ -2149,7 +2343,9 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) string sInfo = "Warning in PocketingNT : machining depth (" + ToString( dElev, 1) + ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; m_pMchMgr->SetWarning( 2458, sInfo) ; - dDepth -= dElev - dMaxDepth ; + // traslo la superficie nel nuovo punto più basso + pSfr->Translate( vtTool * ( dElev - dMaxDepth)) ; + // aggiorno l'elevazione alla massima profondità raggiunta dall'utensile dElev = dMaxDepth ; } } @@ -2162,16 +2358,28 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ; // verifiche per svuotature dal basso - m_bAggrBottom = false ; - if ( ! VerifyPathFromBottom( pCrvLoopExt, vtTool)) - return false ; + m_bAggrBottom = false ; + for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfr->GetLoopCount( nL) ; ++ nL) { + // recupero la curva + PtrOwner pCrvLoop( ConvertCurveToComposite( pSfr->GetLoop( nC, nL))) ; + if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) + return false ; + // se isola inverto + if ( nL > 0) + pCrvLoop->Invert() ; + // verifica + if ( ! VerifyPathFromBottom( pCrvLoop, vtTool)) + return false ; + } + } // recupero eventuale flag di lato aperto forzato fuori dal grezzo int nOpenOutRaw ; m_bOpenOutRaw = ( GetValInNotes( m_Params.m_sUserNotes, "OpenOutRaw", nOpenOutRaw) && nOpenOutRaw != 0) ; // recupero eventuale minima lunghezza di attacco su lato aperto - m_dOpenMinSafe = 0 ; + m_dOpenMinSafe = 5. ; GetValInNotes( m_Params.m_sUserNotes, "OpenMinSafe", m_dOpenMinSafe) ; // se richiesta anteprima @@ -2219,7 +2427,6 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3025, "Error in PocketingNT : RawPart not computable") ; return false ; } - pStmRaw->Translate( - vtTool * 510 * EPS_SMALL) ; // per tasche passanti // determino numero e affondamento degli step int nStep = 1 ; @@ -2227,7 +2434,6 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) double dStep = dElev / nStep ; // su tutti gli step ricavati, calcolo le PolyLine delle Silhouette - int nPocket = 0 ; // numero effettivo di Pocketing calcolate int nProgressBarStep = 0 ; // step per progressBar // vettore per gli step @@ -2242,16 +2448,19 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) IntersParPlanesSurfTm IPPStm( frPocket, *pStmRaw) ; // definisco una trimesh derivante dalla regione piana mediante estrusione dei lati chiusi - Vector3d vtSfrTrasl = - vtTool * ( dDepth - dElev + nStep * dStep) ; - Vector3d vtStmExtr = - vtTool * ( dDepth - dElev + dStep - 500 * EPS_SMALL) ; + Vector3d vtSfrTrasl = V_NULL ; + Vector3d vtStmExtr = vtTool * ( 2 * m_TParams.m_dMaxMat) ; PtrOwner pStmExtrusion( GetExtrusionStm( pSfr, vtSfrTrasl, vtStmExtr)) ; if ( IsNull( pStmExtrusion)) return false ; - if ( _m_Debug) { - int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmExtrusion->Clone()) ; + #if DEBUG_FLATREGIONS + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay, "Extr_Stm_Close_edge") ; + int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pStmExtrusion->Clone()) ; m_pGeomDB->SetMaterial( _a, Color( 1., 0., 1., .75)) ; - } + #endif for ( int j = 1 ; j <= nStep ; ++ j) { // per i contatori non controllo se effettivamente svuoto una superficie o meno @@ -2260,17 +2469,36 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) // porto la superficie allo step corrente PtrOwner pSfrPock( CloneSurfFlatRegion( pSfr)) ; if ( IsNull( pSfrPock) || ! pSfrPock->IsValid() || - ! pSfrPock->Translate( - vtTool * ( dDepth - dElev + j * dStep))) + ! pSfrPock->Translate( vtTool * ( dElev - j * dStep))) return false ; // adatto la regione piana alla geometria del grezzo - PtrOwner pSfrRaw( GetSfrByStmIntersection( IPPStm, - ( dDepth - dElev + j * dStep), 0)) ; + PtrOwner pSfrRaw( GetSfrByStmIntersection( IPPStm, dElev - j * dStep, 0)) ; if ( IsNull( pSfrRaw)) { m_pMchMgr->SetLastError( 3027, "Error in PocketingNT : Slicing Raw failed") ; return false ; } if ( pSfrRaw->IsValid() && pSfrRaw->GetChunkCount() > 0) pSfrPock->Intersect( *pSfrRaw) ; + else { + // potrebbe essere una tasca passante, in questo caso provo a traslare il grezzo + double MAX_DEPTH_EXTRA = 5. + 50 * EPS_SMALL ; + pStmRaw->Translate( - vtTool * MAX_DEPTH_EXTRA) ; + IntersParPlanesSurfTm IPPStm1( frPocket, *pStmRaw) ; + pSfrRaw.Set( GetSfrByStmIntersection( IPPStm1, dElev - j * dStep, 0)) ; + if ( IsNull( pSfrRaw)) { + m_pMchMgr->SetLastError( 3027, "Error in PocketingNT : Slicing Raw failed") ; + return false ; + } + if ( pSfrRaw->IsValid() && pSfrRaw->GetChunkCount() > 0) { + pSfrPock->Intersect( *pSfrRaw) ; + pStmExtrusion->Translate( - vtTool * MAX_DEPTH_EXTRA) ; + } + else { + m_pMchMgr->SetWarning( 2459, "Warning in PocketingNT : Steps too far away from Raw") ; + continue ; + } + } // se regione risultante non vuota if ( pSfrPock->IsValid() && pSfrPock->GetChunkCount() > 0) { @@ -2279,8 +2507,9 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3026, "Error in PocketingNT : Detecting open edges failed") ; return false ; } - if ( _m_Debug) + #if DEBUG_FLATREGIONS _debug_draw_sfr( pSfrPock, false) ; + #endif // determino la regione limite PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; if ( IsNull( pSfrLimit) || @@ -2288,11 +2517,13 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3027, "Error in PocketingNT : Calc limit region failed") ; return false ; } - - if ( _m_Debug) { + #if DEBUG_FLATREGIONS + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay, "Sfr_Limit") ; int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrLimit->Clone()) ; m_pGeomDB->SetMaterial( _a, Color( .5, .5, .5, .5)) ; - } + #endif // inserisco le informazioni dello step nel vettore vStepInfo.resize( vStepInfo.size() + 1) ; vStepInfo.back().dDepth = - j * dStep ; @@ -2302,8 +2533,6 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) if ( pSfrLimit->IsValid()) vStepInfo.back().pSfrLimit.Set( pSfrLimit) ; } - - ++ nPocket ; // aggiorno la progressBar ExeProcessEvents( 5 + nProgressBarStep * 45 / nStep, 0) ; @@ -2543,12 +2772,12 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) for ( int i = 0 ; i < int( vStepInfo.size()) ; ++ i) { // calcolo i percorsi di Pocketing ICRVCOMPOPOVECTOR vCrvPaths ; - if ( ! CalcPocketing( vStepInfo[i].pSfrPock, m_TParams.m_dDiam / 2, 0., m_Params.m_dSideStep, - m_Params.m_dSideAngle, m_Params.m_nSubType, true, m_Params.m_bInvert, + if ( ! CalcPocketing( vStepInfo[i].pSfrPock, m_TParams.m_dDiam / 2, GetOffsR(), m_Params.m_dSideStep, + m_Params.m_dSideAngle, m_dOpenMinSafe, m_Params.m_nSubType, true, m_Params.m_bInvert, false, true, true, ptEndLastPath, vStepInfo[i].pSfrLimit, false, vCrvPaths)) { m_pMchMgr->SetLastError( 3028, "Error in PocketingNT : Error in CalcPocketing") ; return false ; - } + } // se non ho ottenuto percorsi, allora passo allo step successivo ( nInd non viene aggiornato!) if ( vCrvPaths.empty()) continue ; @@ -2564,6 +2793,10 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) vStepInfo[i].vPaths[j].bOutStart = ( vCrvPaths[j]->GetCurveCount() > 0 && vCrvPaths[j]->GetFirstCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ; + // controllo se il percorso ha un'uscita presso un lato aperto + vStepInfo[i].vPaths[j].bOutEnd = ( vCrvPaths[j]->GetCurveCount() > 0 && + vCrvPaths[j]->GetLastCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ; + // controllo se il percorso è formato da una singola curva seguente il lato chiuso vStepInfo[i].vPaths[j].bSingleCrv = ( vCrvPaths[j]->GetCurveCount() > 0 && vCrvPaths[j]->GetTempProp( 0) == TEMP_PROP_SINGLE_CURVE) ; @@ -2577,27 +2810,41 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) ( m_Params.m_nSubType == POCKET_SUB_ONEWAY || m_Params.m_nSubType == POCKET_SUB_ZIGZAG) && vCrvPaths[j]->GetTempProp( 0) == TEMP_PROP_BORDER_CURVE) ; - // se LeadIn o LeadOut a guida recupero la curva di ritorno se necessaria - if ( ( GetLeadInType() == POCKET_LI_GLIDE || GetLeadOutType() == POCKET_LO_GLIDE) && - ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN && - ! vStepInfo[i].vPaths[j].bSingleCrv && ! vStepInfo[i].vPaths[j].bOutStart)) - { - if ( vStepInfo[i].vPaths[j].bOptTrap) - vStepInfo[i].vPaths[j].pCrvRet.Set( ConvertCurveToComposite( vCrvPaths[i]->GetFirstCurve()->Clone())) ; - else { - Point3d ptStart ; vCrvPaths[j]->GetFirstCurve()->GetStartPoint( ptStart) ; - vStepInfo[i].vPaths[j].pCrvRet.Set( CreateCurveComposite()) ; - for ( int k = 0 ; k < vCrvPaths[j]->GetCurveCount() ; ++ k) { - const ICurve* pCrv = vCrvPaths[j]->GetCurve( k) ; - Point3d ptEnd ; - if ( pCrv == nullptr || - ! vStepInfo[i].vPaths[j].pCrvRet->AddCurve( *pCrv) || - ! pCrv->GetEndPoint( ptEnd)) - return false ; - if ( AreSamePointApprox( ptStart, ptEnd)) - break ; - } + // se entrata a guida + if ( GetLeadInType() == POCKET_LI_GLIDE && ! vStepInfo[i].vPaths[j].bOutStart) { + Vector3d vtTan ; + Point3d ptStart ; + if ( ! vCrvPaths[j]->GetStartDir( vtTan) || + ! vCrvPaths[j]->GetStartPoint( ptStart)) + return false ; + PtrOwner pLine( CreateCurveLine()) ; + bool bOkLeadIn = pLine->Set( ptStart, ptStart - vtTan * m_Params.m_dLiTang) ; + // controllo di essere sufficientemente distante dalla regione limite + if ( vStepInfo[i].pSfrLimit != nullptr && vStepInfo[i].pSfrLimit->IsValid()) { + CRVCVECTOR ccClass ; + bOkLeadIn = vStepInfo[j].pSfrLimit->GetCurveClassification( *pLine, m_TParams.m_dDiam / 2. + GetOffsR(), ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT ; } + if ( bOkLeadIn) + vStepInfo[i].vPaths[j].pCrvGuideIn.Set( ConvertCurveToComposite( Release( pLine))) ; + } + // se uscita a guida + if ( GetLeadOutType() == POCKET_LO_GLIDE && ! vStepInfo[i].vPaths[j].bOutEnd) { + Vector3d vtTan ; + Point3d ptEnd ; + if ( ! vCrvPaths[j]->GetEndDir( vtTan) || + ! vCrvPaths[j]->GetEndPoint( ptEnd)) + return false ; + PtrOwner pLine( CreateCurveLine()) ; + bool bOkLeadOut = pLine->Set( ptEnd, ptEnd + vtTan * m_Params.m_dLiTang) ; + // controllo di essere sufficientemente distante dalla regione limite + if ( vStepInfo[i].pSfrLimit != nullptr && vStepInfo[i].pSfrLimit->IsValid()) { + CRVCVECTOR ccClass ; + bOkLeadOut = vStepInfo[i].pSfrLimit->GetCurveClassification( *pLine, m_TParams.m_dDiam / 2. + GetOffsR(), ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT ; + } + if ( bOkLeadOut) + vStepInfo[i].vPaths[j].pCrvGuideOut.Set( ConvertCurveToComposite( Release( pLine))) ; } // assegno il percorso @@ -2634,18 +2881,15 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou // scorro il vettore dei piani di pocketing for ( int i = 0 ; i < int( vStepInfo.size()) ; ++ i) { - // riferimento alle informazioni relative allo step i-esimo StepInfoPO& currStep = vStepInfo[i] ; // scorro i percorsi calcolati per il piano di pocketing i-esimo for ( int j = 0 ; j < int( currStep.vPaths.size()) ; ++ j) { - // riferimento alle informazioni relative al percorso j-esimo del piano di pocketing i-esimo PathInfoPO& currPath = currStep.vPaths[j] ; // ciclo sulle curve elementari del percorso attuale int nMaxInd = currPath.pCrvPath->GetCurveCount() - 1 ; for ( int k = 0 ; k <= nMaxInd ; ++ k) { - // curva corrente const ICurve* pCrvC = currPath.pCrvPath->GetCurve( k) ; // copio la curva @@ -2655,7 +2899,6 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou // coefficiente feed ( riduzione di feed per sezione di taglio superiore al previsto ) double dTempParam ; currPath.pCrvPath->GetCurveTempParam( k, dTempParam) ; double dCoeffFeed = min( 1., ( dTempParam > EPS_SMALL ? dTempParam /= 1000 : 1)) ; - // se prima entità if ( k == 0) { // dati inizio entità @@ -2666,7 +2909,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou dCoeffFeed = ( dTempParam > EPS_SMALL ? dTempParam : 1) ; // calcolo ptP1 per LeadIn iniziale Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtTool, currPath.pCrvRet, ptP1)) { + if ( ! CalcLeadInStart( ptStart, vtTool, currPath.pCrvGuideIn, ptP1)) { m_pMchMgr->SetLastError( 3013, "Error in PocketingNT : LeadIn not computable") ; return false ; } @@ -2701,16 +2944,14 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou bool bNoneForced = ( currPath.bOutStart || currPath.bSingleCrv || ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG && ! currPath.bIsZigZagOneWayBorder) || ( m_Params.m_nSubType == POCKET_SUB_ONEWAY && ! currPath.bIsZigZagOneWayBorder)) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, currStep.pSfrPock, - ( ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT)) ? Get( currPath.pCrvRet) : nullptr, + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, currStep.pSfrPock, Get( currPath.pCrvGuideIn), ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) ? m_Params.m_bInvert : ! m_Params.m_bInvert, bSplitArcs, bNoneForced, false)) { m_pMchMgr->SetLastError( 3013, "Error in PocketingNT : LeadIn not computable") ; return false ; } } - - // elaborazioni sulla curva corrente (sempre un segmento di retta) + // elaborazioni sulla curva corrente if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; Point3d ptP3 = pLine->GetEnd() ; @@ -2730,7 +2971,6 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) return false ; } - // se ultima entità if ( k == nMaxInd) { // dati fine entità @@ -2741,9 +2981,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou // aggiungo LeadOut Point3d ptP1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, - ( ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT)) ? Get( currPath.pCrvRet) : nullptr, - bSplitArcs, false, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, currPath.pCrvGuideOut, bSplitArcs, false, ptP1)) { m_pMchMgr->SetLastError( 3014, "Error in PocketingNT : LeadOut not computable") ; return false ; } @@ -2766,23 +3004,29 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou bNextIsBelow = ( ( ptDest - ptEnd) * vtTool < - 50 * EPS_SMALL) ; } // determino se un collegamento lineare tra i punti proiettati nel piano attuale è ammissibile - bool bSafe = false ; + bool bSafeLimit = false ; + bool bSafePock = false ; if ( m_Params.m_nSubType != POCKET_SUB_ZIGZAG && m_Params.m_nSubType != POCKET_SUB_ONEWAY) { if ( ! CheckSafetyLinearLink( ptEnd, ( bSamePlane ? currStep.pSfrLimit : ( bNextIsBelow ? currStep.pSfrLimit : vStepInfo[i+1].pSfrLimit)), - vtTool, ptDest, bSafe)) + vtTool, ptDest, bSafeLimit)) + return false ; + if ( ! CheckSafetyLinearLink( ptEnd, + ( bSamePlane ? currStep.pSfrPock : + ( bNextIsBelow ? currStep.pSfrPock : vStepInfo[i+1].pSfrPock)), + vtTool, ptDest, bSafePock)) return false ; } // determino l'elevazione sul punto corrente e sul punto di destinazione - dCurrElev = dSafeZ ; - double dNextElev = dSafeZ ; - if ( bSafe) { + dCurrElev = 0. ; + double dNextElev = 0. ; + if ( bSafeLimit) { if ( bSamePlane) { if ( ( ( m_Params.m_nSubType == SURFROU_SUB_SPIRALIN || m_Params.m_nSubType == SURFROU_SUB_SPIRALOUT) && ! vStepInfo[i].vPaths[j+1].bOutStart) || ( m_Params.m_nSubType != SURFROU_SUB_SPIRALIN && m_Params.m_nSubType != SURFROU_SUB_SPIRALOUT)) { - dCurrElev -= currStep.dRelativeDepth ; + dCurrElev -= bSafePock ? 0. : currStep.dRelativeDepth ; dNextElev = dCurrElev ; } } @@ -2836,21 +3080,6 @@ PocketingNT::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) return min( GetFeed(), GetTipFeed() / abs( dCosMove)) ; } -//---------------------------------------------------------------------------- -static double -GetCurveRadius( const ICurve* pCrv) -{ - if ( pCrv == nullptr) - return 0.0 ; - BBox3d b3Loc ; - if ( ! pCrv->GetLocalBBox( b3Loc, BBF_EXACT)) - return 0.0 ; - double dRad ; - if ( ! b3Loc.GetRadius( dRad)) - return 0.0 ; - return dRad ; -} - //------------------------------------------------------------------ bool PocketingNT::CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB) @@ -3346,12 +3575,8 @@ PocketingNT::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtTool, return true ; case SURFROU_LI_GLIDE : { - double dLen, dU ; - if ( ! pRCrv->GetLength( dLen) || ! pRCrv->GetParamAtLength( dLen - m_Params.m_dLiTang, dU) || - ! pRCrv->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP1)) { - if ( ! pRCrv->GetStartPoint( ptP1)) - return false ; - } + if ( ! pRCrv->GetEndPoint( ptP1)) + return false ; ptP1 += vtTool * ( vtTool * ( ptStart - ptP1)) ; return true ; } @@ -3424,27 +3649,18 @@ PocketingNT::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vecto if ( nType == POCKET_LI_GLIDE) { if ( pRCrv != nullptr) { // recupero la parte richiesta della curva di ritorno - PtrOwner pCrv ; - double dLen, dU ; - if ( pRCrv->GetLength( dLen) && pRCrv->GetParamAtLength( dLen - m_Params.m_dLiTang, dU)) { - double dParS, dParE ; - pRCrv->GetDomain( dParS, dParE) ; - if ( ! pCrv.Set( ConvertCurveToComposite( pRCrv->CopyParamRange( dU, dParE)))) - return false ; - } - else { - if ( ! pCrv.Set( pRCrv->Clone())) - return false ; - } + PtrOwner pCrv( CloneCurveComposite( pRCrv)) ; + if ( IsNull( pCrv) || ! pCrv->IsValid()) + return false ; pCrv->SetExtrusion( vtN) ; // la porto alla giusta quota Point3d ptFin ; pCrv->GetEndPoint( ptFin) ; - Vector3d vtMove = ptStart - ptFin ; - pCrv->Translate( vtMove) ; // assegno la corretta pendenza - double dNini = ( ptP1 - ORIG) * vtN ; - double dNfin = ( ptStart - ORIG) * vtN ; + double dNini = ( ptStart - ORIG) * vtN ; + double dNfin = ( ptP1 - ORIG) * vtN ; AdjustCurveSlope( pCrv, dNini, dNfin) ; + pCrv->Invert() ; + m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; // emetto (con eventuale spezzatura) return ( AddCurveMove( pCrv, bSplitArcs, MCH_CL_LEADIN) != GDB_ID_NULL) ; } @@ -3940,30 +4156,73 @@ PocketingNT::_debug_draw_sfr( const ISurfFlatRegion* pSfr, bool bUniform) if ( pSfr == nullptr || ! pSfr->IsValid()) return ; - int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfr->Clone()) ; + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay, "Sfr_Pocketing") ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfr->Clone()) ; m_pGeomDB->SetMaterial( nInd, Color( 0., 255., 0., .5)) ; for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) { for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) { PtrOwner pCrvCompo( ConvertCurveToComposite( pSfr->GetLoop( nC, nL))) ; - _debug_draw_loop( pCrvCompo->Clone(), bUniform) ; + _debug_draw_loop( pCrvCompo->Clone(), nLay, bUniform) ; } } return ; } +//---------------------------------------------------------------------------- void -PocketingNT::_debug_draw_loop( const ICurveComposite* pCrvCompo, bool bUniform) +PocketingNT::_debug_draw_loop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) { if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid()) return ; - for ( int nU = 0 ; nU < pCrvCompo->GetCurveCount() ; ++ nU) { int nProp0 ; pCrvCompo->GetCurveTempProp( nU, nProp0, 0) ; int nProp1 ; pCrvCompo->GetCurveTempProp( nU, nProp1, 1) ; - int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( nU)->Clone()) ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pCrvCompo->GetCurve( nU)->Clone()) ; m_pGeomDB->SetMaterial( nInd, bUniform ? WHITE : ( nProp0 == 0 ? BLUE : RED)) ; } return ; } + +//---------------------------------------------------------------------------- +void +PocketingNT::_degub_draw_box( const BBox3d& BBox, const Frame3d& FrBox, int nLayer) +{ + Point3d ptMin = BBox.GetMin() ; ptMin.ToGlob( FrBox) ; + Point3d ptMax = BBox.GetMax() ; ptMax.ToGlob( FrBox) ; + PtrOwner pBase( CreateCurveComposite()) ; + pBase->AddPoint( ptMin) ; + Vector3d vtPtNext = ( ptMin - ORIG) + BBox.GetDimX() * FrBox.VersX() ; + pBase->AddLine( Point3d( vtPtNext.x, vtPtNext.y, vtPtNext.z)) ; + vtPtNext = ( ptMax - ORIG) - BBox.GetDimZ() * FrBox.VersZ() ; + pBase->AddLine( Point3d( vtPtNext.x, vtPtNext.y, vtPtNext.z)) ; + vtPtNext = ( ptMin - ORIG) + BBox.GetDimY() * FrBox.VersY() ; + pBase->AddLine( Point3d( vtPtNext.x, vtPtNext.y, vtPtNext.z)) ; + pBase->Close() ; + int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pBase->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + pBase->Translate( BBox.GetDimZ() * FrBox.VersZ()) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pBase->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + pBase->Clear() ; + pBase->AddPoint( ptMin) ; + vtPtNext = ( ptMin - ORIG) + BBox.GetDimZ() * FrBox.VersZ() ; + pBase->AddLine( Point3d( vtPtNext.x, vtPtNext.y, vtPtNext.z)) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pBase->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + pBase->Translate( BBox.GetDimX() * FrBox.VersX()) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pBase->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + pBase->Translate( BBox.GetDimY() * FrBox.VersY()) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pBase->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + pBase->Translate( - BBox.GetDimX() * FrBox.VersX()) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, pBase->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + PtrOwner fr( CreateGeoFrame3d()) ; + fr->Set( FrBox) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayer, fr->Clone()) ; +} diff --git a/PocketingNT.h b/PocketingNT.h index 0b06644..a9464d3 100644 --- a/PocketingNT.h +++ b/PocketingNT.h @@ -25,11 +25,13 @@ // struttura informazioni sui singoli percorsi struct PathInfoPO { bool bOutStart ; // flag per entrata da fuori + bool bOutEnd ; // flag per uscita da fuori bool bSingleCrv ; // se percorso formato da una curva singola ( in generale per SubSteps) bool bOptTrap ; // flag per casi ottimizzati a trapezio ( per Spiral) bool bIsZigZagOneWayBorder ; // curve di bordo dei lati chiusi ( per ZigZag e OneWay) PtrOwner pCrvPath ; // percorso del centro utensile - PtrOwner pCrvRet ; // curva di ritorno per LeadIn/Out a guida + PtrOwner pCrvGuideIn ; // curva per LeadIn a guida + PtrOwner pCrvGuideOut ; // curva per LeadOut a guida } ; // tipo percorso typedef std::vector PATHINFOPOVECTOR ; @@ -100,6 +102,8 @@ class PocketingNT : public Machining ISurfTriMesh* GetRaw( void) ; ISurfTriMesh* GetExtrusionStm( const ISurfFlatRegion* pSfr, const Vector3d& vtTrasl, const Vector3d& vtExtr) ; ISurfFlatRegion* GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, double dDist, double dSmallOffs = 0) ; + bool GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) const ; + bool ExtendOpenEdgesToRaw( ICurveComposite* pCompo, const Vector3d& vtExtr) ; bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion) ; bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; @@ -140,7 +144,8 @@ class PocketingNT : public Machining bool CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist, Vector3d& vtNorm) ; // debug void _debug_draw_sfr( const ISurfFlatRegion* pSfr, bool bUniform) ; - void _debug_draw_loop( const ICurveComposite* pCrvCompo, bool bUniform) ; + void _debug_draw_loop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) ; + void _degub_draw_box( const BBox3d& BBox, const Frame3d& FrBox, int nlayer) ; private : double GetSpeed( void) const @@ -193,6 +198,6 @@ class PocketingNT : public Machining AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto - - bool _m_Debug = false ; // _debug + double m_dOpenExtension ; // estensione dei tratti aperti dentro al grezzo + bool m_bAllClose ; // flag per forzare i lati come tutti chiusi } ; \ No newline at end of file diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 1ee1e09..d07ee6a 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -1795,7 +1795,7 @@ SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons double dPockRad = m_Params.m_dSideStep ; double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., POCKET_ZIGZAG, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; @@ -1996,7 +1996,7 @@ SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons double dPockRad = m_Params.m_dSideStep ; double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., POCKET_ONEWAY, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; @@ -2198,7 +2198,7 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; int nType = ( bInVsOut ? POCKET_SPIRALIN : POCKET_SPIRALOUT) ; ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., nType, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; @@ -4495,7 +4495,7 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr } // lavorazione Spiral ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcPocketing( pSfrSpiral, m_Params.m_dSideStep, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, + if ( ! CalcPocketing( pSfrSpiral, m_Params.m_dSideStep, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., POCKET_SPIRALIN, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index 43f81c1..783285d 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -2335,7 +2335,7 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, STEPINFOSRVECTOR& vStepInf // calcolo i percorsi di Pocketing ICRVCOMPOPOVECTOR vCrvPaths ; if ( ! CalcPocketing( vStepInfo[nInd].pSfrPock, m_TParams.m_dDiam / 2, 0., m_Params.m_dSideStep, - m_Params.m_dSideAngle, vStepInfo[nInd].nSubType, true, vStepInfo[nInd].bInverted, + m_Params.m_dSideAngle, 5., vStepInfo[nInd].nSubType, true, vStepInfo[nInd].bInverted, false, true, true, ptEndLastPath, vStepInfo[nInd].pSfrLimit, false, vCrvPaths)) { if ( vStepInfo[nInd].bIsExtraStep) { string sWarn = "Warning in SurfRoughing : CalcPocketing failed with substep (" + ToString( vStepInfo[nInd].dDepth, 1) + ")" ;