diff --git a/PocketingNT.cpp b/PocketingNT.cpp index 7409f0a..2015e3c 100644 --- a/PocketingNT.cpp +++ b/PocketingNT.cpp @@ -49,12 +49,13 @@ using namespace std ; -//------------------------------ Constants ------------------------------------ +//------------------------------ Costanti ------------------------------------ static string KEY_OPEN = "OPEN" ; static string KEY_THICK = "THICK" ; static int LINK_CURVE_PROP = -3 ; static double EXTRA_ELEV = 5. ; static double SAFETY_LINK_COS = cos( - ( 175 * DEGTORAD)) ; +static double TOOL_RAD_PTSTART = 20. ; // Parametri avanzati da UserNotes const string UN_MAXELEV = "MaxElev" ; const string UN_OPEN = "Open" ; @@ -62,7 +63,7 @@ const string UN_OPENOUTRAW = "OpenOutRaw" ; const string UN_OPENMINSAFE = "OpenMinSafe" ; const string UN_MAXOPTSIZE = "MaxOptSize" ; -//------------------------------ Errors -------------------------------------- +//------------------------------ Errori/Warnings -------------------------------------- // 2401 = "Error in PocketingNT : UpdateToolData failed" // 2402 = "Error in PocketingNT : Open Contour" // 2403 = "Error in PocketingNT : Contour Not Flat" @@ -108,14 +109,16 @@ const string UN_MAXOPTSIZE = "MaxOptSize" ; // 2459 = "Warning in PocketingNT : Steps too far away from Raw" //---------------------------------------------------------------------------- -// _debug -#define DEBUG_OPEN_EDGE_EXTENSION 0 -#define DEBUG_OPEN_EDGE_IN_RAW 0 -#define DEBUG_FLATREGIONS 0 -#define DEBUG_SFR_RAW 0 -#define DEBUG_GLIDE 0 -#define DEBUG_SAFETY_LINK 0 -#if DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_FLATREGIONS || DEBUG_SFR_RAW || DEBUG_GLIDE || DEBUG_SAFETY_LINK +// Debug +#define DEBUG_OPEN_EDGE_EXTENSION 0 // Debug estensione dei lati aperti +#define DEBUG_OPEN_EDGE_IN_RAW 0 // Debug gestione lati aperti interni al grezzo +#define DEBUG_SFR_STEPS 0 // Debug Sfr ( Pock e Limit) nei vari step ( risultato finale per CalcPocketing) +#define DEBUG_SFR_RAW 0 // Debug intersezioni tra SurfFlatRegion e SurfTriMesh +#define DEBUG_STM_EXTRUSION 0 // Debug superficie TriMesh di estrusione dei lati chiusi +#define DEBUG_GLIDE 0 // Debug percorsi a Scivolo ( LeadIn/LeadOut) +#define DEBUG_MAXDEPTH 0 // Debug per controllo di MaxDepth +#define DEBUG_SAFETY_LINK 0 // Debug raccordi tra percorsi di lavorazioni differenti +#if DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_SFR_STEPS || DEBUG_SFR_RAW || DEBUG_GLIDE || DEBUG_SAFETY_LINK #include "EgtDev/Include/EGkGeoPoint3d.h" #include "EgtDev/Include/EGkFrame3d.h" #endif @@ -1920,7 +1923,7 @@ PocketingNT::ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) 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_sfr( pSfr, false, nLay) ; + DebugDrawSfr( pSfr, false, nLay) ; #endif // clono la superficie trimesh ( devo effettuare un taglio) PtrOwner pStmCL( CloneSurfTriMesh( pStm)) ; @@ -1950,7 +1953,7 @@ PocketingNT::ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) return false ; #if DEBUG_OPEN_EDGE_EXTENSION frCut.Invert() ; - _debug_draw_box( BBoxRawCut, frCut, nLay) ; + DebugDrawBox( BBoxRawCut, frCut, nLay) ; frCut.Invert() ; #endif @@ -2071,7 +2074,7 @@ PocketingNT::ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) } #if DEBUG_OPEN_EDGE_EXTENSION - _debug_draw_sfr( pSfr, false, nLay) ; + DebugDrawSfr( pSfr, false, nLay) ; #endif return ( pSfr->IsValid()) ; } @@ -2264,8 +2267,8 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe bool PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) { - /* Bisogna distingere tra lati aperti sul bordo del pezzo e lati aperti all'interno del pezzo ; - * I lati aperti all'interno del pezzo vanno estesi di circa il raggio utensile e poi considerati + /* Bisogna distingere tra lati aperti sul bordo del grezzo e lati aperti all'interno del grezzo ; + * I lati aperti all'interno del grezzo vanno estesi di circa il raggio utensile e poi considerati * come chiusi */ // controllo dei parametri @@ -2363,7 +2366,7 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) // recupero i nuovi tratti omogenei GetHomogeneousParts( pCrvNewBorder, vpCrvs) ; #if DEBUG_OPEN_EDGE_IN_RAW - _debug_draw_OpenEdgesInRaw( vpCrvs, nLayBase) ; + DebugDrawOpenEdgesInRaw( vpCrvs, nLayBase) ; #endif // caso limite : tutta la curva è aperta ed interna alla regione if ( int( vpCrvs.size()) == 1 && vpCrvs[0]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE_IN_RAW) { @@ -2416,71 +2419,99 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) PtrOwner pLineAfter( CreateCurveLine()) ; if ( IsNull( pLinePrev) || IsNull( pLineAfter)) return false ; - Point3d ptInters ; - // ----------------------- Segmento iniziale ----------------------------- - Point3d myPt ; - Vector3d myVect ; - vpCrvs[nIndPrev]->GetEndPoint( myPt) ; - vpCrvs[nIndPrev]->GetEndDir( myVect) ; - if ( ! pLinePrev->Set( myPt, myPt + LEN_EXTENSION * myVect)) + Point3d ptLineStart ; + Vector3d vtLineStart ; + vpCrvs[nIndPrev]->GetEndPoint( ptLineStart) ; + vpCrvs[nIndPrev]->GetEndDir( vtLineStart) ; + if ( ! pLinePrev->Set( ptLineStart, ptLineStart + LEN_EXTENSION * vtLineStart)) return false ; #if DEBUG_OPEN_EDGE_IN_RAW _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pLinePrev->Clone()) ; m_pGeomDB->SetMaterial( _a, BLACK) ; #endif - IntersCurveCurve ICC_Prev( *pLinePrev, *pCrvOffsOpenInPart) ; - if ( ICC_Prev.GetIntersCount() > 0 && ICC_Prev.GetIntersPointNearTo( 0, myPt, ptInters)) { - double dU ; - pLinePrev->GetParamAtPoint( ptInters, dU) ; - pLinePrev->TrimEndAtParam( dU) ; - pLinePrev->SetTempProp( vpCrvs[nIndPrev]->GetTempProp( 0), 0) ; - pCrvOffsOpenInPart->GetParamAtPoint( ptInters, dU) ; - pCrvOffsOpenInPart->TrimStartAtParam( dU) ; - } - else { - bOk = false ; - continue ; - } - // ----------------------- Segmento finale ------------------------------- - vpCrvs[nIndAfter]->GetStartPoint( myPt) ; - vpCrvs[nIndAfter]->GetStartDir( myVect) ; - if ( ! pLineAfter->Set( myPt - LEN_EXTENSION * myVect, myPt)) + Point3d ptLineEnd ; + Vector3d vtLineEnd ; + vpCrvs[nIndAfter]->GetStartPoint( ptLineEnd) ; + vpCrvs[nIndAfter]->GetStartDir( vtLineEnd) ; + if ( ! pLineAfter->Set( ptLineEnd - LEN_EXTENSION * vtLineEnd, ptLineEnd)) return false ; #if DEBUG_OPEN_EDGE_IN_RAW _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayConstr, pLineAfter->Clone()) ; m_pGeomDB->SetMaterial( _a, BLACK) ; #endif - IntersCurveCurve ICC_After( *pLineAfter, *pCrvOffsOpenInPart) ; - if ( ICC_After.GetIntersCount() > 0 && ICC_After.GetIntersPointNearTo( 0, myPt, ptInters)) { - double dU ; - pLineAfter->GetParamAtPoint( ptInters, dU) ; - pLineAfter->TrimStartAtParam( dU) ; - pLineAfter->SetTempProp( vpCrvs[nIndAfter]->GetTempProp( 0), 0) ; - pCrvOffsOpenInPart->GetParamAtPoint( ptInters, dU) ; - pCrvOffsOpenInPart->TrimEndAtParam( dU) ; + // intersezione con primo segmento ( raccordo verso lato Open In Raw Offs) + Point3d ptIntS ; + double dUS_Trim_Line ; + double dUS_Trim_Offs ; + IntersCurveCurve ICC_Prev( *pLinePrev, *pCrvOffsOpenInPart) ; + if ( ICC_Prev.GetIntersCount() > 0 && ICC_Prev.GetIntersPointNearTo( 0, ptLineStart, ptIntS)) { + pLinePrev->GetParamAtPoint( ptIntS, dUS_Trim_Line) ; + pCrvOffsOpenInPart->GetParamAtPoint( ptIntS, dUS_Trim_Offs) ; } else { bOk = false ; continue ; } - // aggiorno tutte le curve + // intersezione con secondo segmento ( raccordo da Lato Open In Raw Offs) + Point3d ptIntE ; + double dUE_Trim_Line ; + double dUE_Trim_Offs ; + IntersCurveCurve ICC_After( *pLineAfter, *pCrvOffsOpenInPart) ; + if ( ICC_After.GetIntersCount() > 0 && ICC_After.GetIntersPointNearTo( 0, ptLineEnd, ptIntE)) { + pLineAfter->GetParamAtPoint( ptIntE, dUE_Trim_Line) ; + pCrvOffsOpenInPart->GetParamAtPoint( ptIntE, dUE_Trim_Offs) ; + } + else { + bOk = false ; + continue ; + } + // se le rette si intersecano tra loro prima di raccordarsi sull'Offset + if ( dUS_Trim_Offs > dUE_Trim_Offs) { + // recupero punto di intersezione tra le rette + IntersCurveCurve ILL( *pLinePrev, *pLineAfter) ; + Point3d ptIntersLL ; + if ( ILL.GetIntersCount() != 1 || + ! ILL.GetIntersPointNearTo( 0, ptLineStart, ptIntersLL) || + ! pLinePrev->GetParamAtPoint( ptIntersLL, dUS_Trim_Line) || + ! pLineAfter->GetParamAtPoint( ptIntersLL, dUE_Trim_Line)) { + bOk = false ; + continue ; + } + // pulisco la curva di Offset + pCrvOffsOpenInPart->Clear() ; + } + // se le rette non si intersecano tra loro + else { + double dU_Offs_Trim_Start = 0. ; + pCrvOffsOpenInPart->GetParamAtPoint( ptIntS, dU_Offs_Trim_Start) ; + pCrvOffsOpenInPart->TrimStartAtParam( dU_Offs_Trim_Start) ; + double dU_Offs_Trim_End = 0. ; + pCrvOffsOpenInPart->GetParamAtPoint( ptIntE, dU_Offs_Trim_End) ; + pCrvOffsOpenInPart->TrimEndAtParam( dU_Offs_Trim_End) ; + } + // aggiorno tutte le curve e le loro proprietà + pLinePrev->TrimEndAtParam( dUS_Trim_Line) ; + pLinePrev->SetTempProp( vpCrvs[nIndPrev]->GetTempProp( 0), 0) ; vpCrvs[nIndPrev]->AddCurve( Release( pLinePrev), true) ; + pLineAfter->TrimStartAtParam( dUE_Trim_Line) ; + pLineAfter->SetTempProp( vpCrvs[nIndAfter]->GetTempProp( 0), 0) ; vpCrvs[nIndAfter]->AddCurve( Release( pLineAfter), false) ; vpCrvs[i].Set( Release( pCrvOffsOpenInPart)) ; // considero questo tratto come chiuso for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j) vpCrvs[i]->SetCurveTempProp( j, TEMP_PROP_CLOSE_EDGE, 0) ; } - } // ricostrusico il nuovo bordo pCrvNewBorder->Clear() ; #if DEBUG_OPEN_EDGE_IN_RAW - _debug_draw_OpenEdgesInRaw( vpCrvs, nLayResult) ; + DebugDrawOpenEdgesInRaw( vpCrvs, nLayResult) ; #endif for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { - if ( ! pCrvNewBorder->AddCurve( Release( vpCrvs[i]))) - return false ; + if ( ! IsNull( vpCrvs[i]) && vpCrvs[i]->IsValid() && vpCrvs[i]->GetCurveCount() > 0) { + if ( ! pCrvNewBorder->AddCurve( Release( vpCrvs[i]))) + return false ; + } } // lo riporto nel frame globale pCrvNewBorder->ToGlob( frXY) ; @@ -2512,11 +2543,94 @@ PocketingNT::ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) } #if DEBUG_OPEN_EDGE_IN_RAW - _debug_draw_sfr( pSfr, false, nLayResult) ; + DebugDrawSfr( pSfr, false, nLayResult) ; #endif return ( pSfr->IsValid()) ; } +//---------------------------------------------------------------------------- +bool +PocketingNT::CheckMaxDepth( const ISurfFlatRegion* pSfr, double dDepth, const Vector3d& vtTool, + const ISurfTriMesh* pStmRaw, const ISurfTriMesh* pStmExtrusion, + const IntersParPlanesSurfTm& IPPStm, bool& bSkipMaxDepth) +{ + // controllo dei parametri + if ( pSfr == nullptr || ! pSfr->IsValid() || + pStmRaw == nullptr || ! pStmRaw->IsValid() || + pStmExtrusion == nullptr) + return false ; + bSkipMaxDepth = false ; + + #if DEBUG_MAXDEPTH + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + m_pGeomDB->SetName( nGrp, "MaxDepth") ; + int nLaySfr = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLaySfr, "Sfr") ; + DebugDrawSfr( pSfr, false, nLaySfr) ; + int nLayRaw = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLayRaw, "Raw") ; + int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayRaw, pStmRaw->Clone()) ; + m_pGeomDB->SetMaterial( _a, Color( 0., 0., 1., .35)) ; + #endif + + // se la superficie di estrusione dei chiusi è vuota + if ( ! pStmExtrusion->IsValid() || pStmExtrusion->GetTriangleCount() == 0) { + bSkipMaxDepth = true ; + return true ; + } + + #if DEBUG_MAXDEPTH + int nLayStmExtr = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nGrp, "StmExtrusion") ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayStmExtr, pStmExtrusion->Clone()) ; + m_pGeomDB->SetMaterial( _a, AQUA) ; + #endif + + // adatto la regione piana attuale al grezzo + // NB. La pStmExtrusion potrebbe esistere ma non toccare nessun lato adattato al grezzo + PtrOwner pSfrRaw( GetSfrByStmIntersection( IPPStm, - dDepth, 0)) ; + if ( IsNull( pSfrRaw)) { + m_pMchMgr->SetLastError( 3027, "Error in PocketingNT : Slicing Raw failed") ; + return false ; + } + if ( ! pSfrRaw->IsValid() || pSfrRaw->GetChunkCount() == 0) + return true ; // ??? ( non deve capitare) + PtrOwner pSfrAdj( CloneSurfFlatRegion( pSfr)) ; + if ( IsNull( pSfrAdj) || ! pSfrAdj->IsValid() || + ! pSfrAdj->Translate( - dDepth * vtTool)) + return false ; + pSfrAdj->Intersect( *pSfrRaw) ; + if ( ! pSfrAdj->IsValid()) + return true ; // ??? ( non deve capitare) + + // determino i lati aperti della regione ricavata + if ( ! ChooseCloseOrOpenEdge( pSfrAdj, pStmExtrusion)) { + m_pMchMgr->SetLastError( 3026, "Error in PocketingNT : Detecting open edges failed") ; + return false ; + } + + #if DEBUG_MAXDEPTH + nLaySfr = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLaySfr, "Sfr_Raw_Inters") ; + DebugDrawSfr( pSfr, true, nLaySfr) ; + #endif + + // controllo se la regione ha tutti i lati aperti + int nTmpProp = TEMP_PROP_INVALID ; + for ( int nC = 0 ; nC < pSfrAdj->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfrAdj->GetLoopCount( nL) ; ++ nL) { + for ( int nU = 0 ; nU < pSfrAdj->GetLoopCurveCount( nC, nL) ; ++ nU) { + if ( pSfrAdj->GetCurveTempProp( nC, nL, nU, nTmpProp, 0) && + nTmpProp == TEMP_PROP_CLOSE_EDGE) { + return true ; + } + } + } + } + bSkipMaxDepth = true ; + return true ; +} + //---------------------------------------------------------------------------- bool PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) @@ -2661,9 +2775,54 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetWarning( 2457, sInfo) ; } + // recupero il grezzo + PtrOwner pStmRaw( GetRaw()) ; + if ( IsNull( pStmRaw)) { + m_pMchMgr->SetLastError( 3025, "Error in PocketingNT : RawPart not computable") ; + return false ; + } + // inizializzo la classe di intersezione tra grezzo e piani paralleli ( quelli di lavoro) + Frame3d frSfr ; + Point3d ptCen ; pSfr->GetCentroid( ptCen) ; + Frame3d frPocket ; + if ( ! frPocket.Set( ptCen, vtTool) || ! frPocket.IsValid()) + return false ; + IntersParPlanesSurfTm IPPStm( frPocket, *pStmRaw) ; + #if DEBUG_SFR_RAW + int nGrpSR = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + int nLaySR = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpSR, GLOB_FRM) ; + m_pGeomDB->SetName( nLaySR, "Sfr_Raw_Position") ; + PtrOwner pFr( CreateGeoFrame3d()) ; + pFr->Set( frPocket) ; + int _nFr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pFr->Clone()) ; + int _nSfr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pSfr->Clone()) ; + m_pGeomDB->SetMaterial( _nSfr, Color( 0., 1., 0., .75)) ; + int _nRaw = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pStmRaw->Clone()) ; + m_pGeomDB->SetMaterial( _nRaw, Color( .35, .46, .78, .1)) ; + #endif + + // definisco una trimesh derivante dalla regione piana mediante estrusione dei lati chiusi + // NB. La traslazione in questo caso è euristica + // NB. Questa superficie servirà per definire i lati chiusi una volta che la regione piana + // è stata intersecata con la superficie del grezzo + pSfr->Translate( - vtTool * ( dDepth + m_TParams.m_dMaxMat)) ; + Vector3d vtStmExtr = vtTool * ( dDepth + m_TParams.m_dMaxMat + dElev + m_TParams.m_dMaxMat) ; + PtrOwner pStmExtrusion( GetExtrusionStm( pSfr, vtStmExtr)) ; + pSfr->Translate( vtTool * ( dDepth + m_TParams.m_dMaxMat)) ; + if ( IsNull( pStmExtrusion)) + return false ; + #if DEBUG_STM_EXTRUSION + 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)) ; + m_pGeomDB->SetStatus( _a, GDB_ST_OFF) ; + #endif + // se lavorazione singola if ( dOkStep < EPS_SMALL || dOkStep > dElev) { - // se l'elevazione supera la capacità dell'utensile + // se l'elevazione supera la capacità dell'utensile if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL) { string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; @@ -2678,12 +2837,18 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) double dSafe = GetMaxDepthSafe() ; double dMaxDepth = m_TParams.m_dLen - ( m_TParams.m_dDiam > m_dTHoldDiam ? m_dTHoldBase : m_dTHoldLen) - dSafe ; if ( dElev > dMaxDepth + EPS_SMALL) { - // segnalo, riduco e continuo - string sInfo = "Warning in PocketingNT : machining depth (" + ToString( dElev, 1) + - ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; - m_pMchMgr->SetWarning( 2458, sInfo) ; - dDepth -= dElev - dMaxDepth ; - dElev = dMaxDepth ; + // controllo se posso evitare il controllo + bool bSkipMaxDepth = false ; + if ( ! CheckMaxDepth( pSfr, dDepth, vtTool, pStmRaw, pStmExtrusion, IPPStm, bSkipMaxDepth)) + return false ; + if ( ! bSkipMaxDepth) { + // segnalo, riduco e continuo + string sInfo = "Warning in PocketingNT : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; + m_pMchMgr->SetWarning( 2458, sInfo) ; + dDepth -= dElev - dMaxDepth ; + dElev = dMaxDepth ; + } } } @@ -2758,61 +2923,17 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) // assegno l'elevazione massima m_pGeomDB->SetInfo( nPxId, KEY_ELEV, dElev) ; - // recupero il grezzo - PtrOwner pStmRaw( GetRaw()) ; - if ( IsNull( pStmRaw)) { - m_pMchMgr->SetLastError( 3025, "Error in PocketingNT : RawPart not computable") ; - return false ; - } - // determino numero e affondamento degli step int nStep = 1 ; nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; double dStep = dElev / nStep ; - // su tutti gli step ricavati, calcolo le PolyLine delle Silhouette - int nProgressBarStep = 0 ; // step per progressBar + // step per progressBar + int nProgressBarStep = 0 ; // vettore per gli step STEPINFOPOVECTOR vStepInfo ; - // inizializzo la classe di intersezione tra grezzo e piani paralleli ( quelli di lavoro) - Frame3d frSfr ; - Point3d ptCen ; pSfr->GetCentroid( ptCen) ; - Frame3d frPocket ; - if ( ! frPocket.Set( ptCen, vtTool) || ! frPocket.IsValid()) - return false ; - IntersParPlanesSurfTm IPPStm( frPocket, *pStmRaw) ; - #if DEBUG_SFR_RAW - int nGrpSR = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; - int nLaySR = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpSR, GLOB_FRM) ; - m_pGeomDB->SetName( nLaySR, "Sfr_Raw_Position") ; - PtrOwner pFr( CreateGeoFrame3d()) ; - pFr->Set( frPocket) ; - int _nFr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pFr->Clone()) ; - int _nSfr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pSfr->Clone()) ; - m_pGeomDB->SetMaterial( _nSfr, Color( 0., 1., 0., .75)) ; - int _nRaw = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pStmRaw->Clone()) ; - m_pGeomDB->SetMaterial( _nRaw, Color( .35, .46, .78, .1)) ; - #endif - - // definisco una trimesh derivante dalla regione piana mediante estrusione dei lati chiusi - Vector3d vtStmExtr = vtTool * ( 2 * m_TParams.m_dMaxMat) ; - pSfr->Translate( - vtTool * ( dDepth - dElev + nStep * dStep)) ; - PtrOwner pStmExtrusion( GetExtrusionStm( pSfr, vtStmExtr)) ; - pSfr->Translate( vtTool * ( dDepth - dElev + nStep * dStep)) ; - if ( IsNull( pStmExtrusion)) - return false ; - - #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)) ; - m_pGeomDB->SetStatus( _a, GDB_ST_OFF) ; - #endif - for ( int j = 1 ; j <= nStep ; ++ j) { // per i contatori non controllo se effettivamente svuoto una superficie o meno ++ nProgressBarStep ; // aggiorno step per progressBar @@ -2850,7 +2971,6 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) continue ; } } - #if DEBUG_SFR_RAW int _nPlane = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySR, pSfrRaw->Clone()) ; m_pGeomDB->SetMaterial( _nPlane, Color( .35, .46, .78, 1.)) ; @@ -2863,11 +2983,11 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3026, "Error in PocketingNT : Detecting open edges failed") ; return false ; } - #if DEBUG_FLATREGIONS + #if DEBUG_SFR_STEPS 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") ; - _debug_draw_sfr( pSfrPock, false, nLay) ; + DebugDrawSfr( pSfrPock, false, nLay) ; #endif // determino la regione limite PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; @@ -2876,7 +2996,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3027, "Error in PocketingNT : Calc limit region failed") ; return false ; } - #if DEBUG_FLATREGIONS + #if DEBUG_SFR_STEPS int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfrLimit->Clone()) ; m_pGeomDB->SetMaterial( _a, Color( .5, .5, .5, .5)) ; #endif @@ -3286,22 +3406,19 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) // punto finale di riferimento per il percorso attuale ( serve per trovare il punto iniziale // del percorso successivo) - Point3d ptEndLastPath = P_INVALID ; + Point3d ptStartRef = P_INVALID ; // controllo parametri per casi ottimizzati double dMaxOptSize = m_Params.m_dSideStep ; GetValInNotes( m_Params.m_sUserNotes, UN_MAXOPTSIZE, dMaxOptSize) ; - // se non richiesto controllo con il grezzo, elimino la superficie limite - - // scorro gli indici delle superfici 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, 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, dMaxOptSize, vCrvPaths)) { + false, true, true, ptStartRef, vStepInfo[i].pSfrLimit, false, dMaxOptSize, vCrvPaths)) { m_pMchMgr->SetLastError( 3028, "Error in PocketingNT : Error in CalcPocketing") ; return false ; } @@ -3311,8 +3428,15 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) // sistemo gli archi per massimo angolo al centro for ( int j = 0 ; j < int( vCrvPaths.size()) ; ++ j) VerifyArcs( vCrvPaths[j]) ; - // recupero il punto finale del percorso per lo step successivo - vCrvPaths.back()->GetEndPoint( ptEndLastPath) ; + // definisco il nuovo punto di riferimento per il percorso successivo + // se l'utensile ha un raggio sotto la tolleranza, allora è il punto finale del percorso attuale + if ( m_TParams.m_dDiam / 2. < TOOL_RAD_PTSTART) + vCrvPaths.back()->GetEndPoint( ptStartRef) ; + // se l'utensile ha un raggio sopra la tolleranza, rimane fisso al punto iniziale del primo percorso + else { + if ( ! ptStartRef.IsValid()) + vCrvPaths.front()->GetStartPoint( ptStartRef) ; + } // inserisco i percorsi nel vettore dei Paths vStepInfo[i].vPaths.resize( int( vCrvPaths.size())) ; for ( int j = 0 ; j < int( vCrvPaths.size()) ; ++ j) { @@ -4887,7 +5011,7 @@ PocketingNT::CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const V // debug functions //---------------------------------------------------------------------------- void -PocketingNT::_debug_draw_sfr( const ISurfFlatRegion* pSfr, bool bUniform, int nLayer) +PocketingNT::DebugDrawSfr( const ISurfFlatRegion* pSfr, bool bUniform, int nLayer) { if ( pSfr == nullptr || ! pSfr->IsValid()) return ; @@ -4897,7 +5021,7 @@ PocketingNT::_debug_draw_sfr( const ISurfFlatRegion* pSfr, bool bUniform, int nL 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(), nLayer, bUniform) ; + DebugDrawLoop( pCrvCompo->Clone(), nLayer, bUniform) ; } } @@ -4906,7 +5030,7 @@ PocketingNT::_debug_draw_sfr( const ISurfFlatRegion* pSfr, bool bUniform, int nL //---------------------------------------------------------------------------- void -PocketingNT::_debug_draw_loop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) +PocketingNT::DebugDrawLoop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) { if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid()) return ; @@ -4922,7 +5046,7 @@ PocketingNT::_debug_draw_loop( const ICurveComposite* pCrvCompo, int nLayer, boo //---------------------------------------------------------------------------- void -PocketingNT::_debug_draw_box( const BBox3d& BBox, const Frame3d& FrBox, int nLayer) +PocketingNT::DebugDrawBox( const BBox3d& BBox, const Frame3d& FrBox, int nLayer) { Point3d ptMin = BBox.GetMin() ; ptMin.ToGlob( FrBox) ; Point3d ptMax = BBox.GetMax() ; ptMax.ToGlob( FrBox) ; @@ -4962,7 +5086,7 @@ PocketingNT::_debug_draw_box( const BBox3d& BBox, const Frame3d& FrBox, int nLay //---------------------------------------------------------------------------- void -PocketingNT::_debug_draw_OpenEdgesInRaw( const ICRVCOMPOPOVECTOR& vpCrvs, int nlayer) +PocketingNT::DebugDrawOpenEdgesInRaw( const ICRVCOMPOPOVECTOR& vpCrvs, int nlayer) { for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { Color myColor = BLACK ; diff --git a/PocketingNT.h b/PocketingNT.h index fd56ab5..8df55a9 100644 --- a/PocketingNT.h +++ b/PocketingNT.h @@ -113,6 +113,9 @@ class PocketingNT : public Machining bool GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) const ; bool ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) ; bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion) ; + bool CheckMaxDepth( const ISurfFlatRegion* pSfr, double dDepth, const Vector3d& vtTool, + const ISurfTriMesh* pStmRaw, const ISurfTriMesh* pStmExtrusion, + const IntersParPlanesSurfTm& IPPStm, bool& bSkipMaxDepth) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double dLen, double& dElev) ; bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ; @@ -160,10 +163,10 @@ class PocketingNT : public Machining bool VerifyLeadInOutGlide( const ISurfFlatRegion* pSfr, const ICurveComposite* pCrvGlide) ; bool CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist, Vector3d& vtNorm) ; // debug - void _debug_draw_sfr( const ISurfFlatRegion* pSfr, bool bUniform, int nlayer = GDB_ID_NULL) ; - void _debug_draw_loop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) ; - void _debug_draw_box( const BBox3d& BBox, const Frame3d& FrBox, int nlayer) ; - void _debug_draw_OpenEdgesInRaw( const ICRVCOMPOPOVECTOR& vpCrvsm, int nlayer) ; + void DebugDrawSfr( const ISurfFlatRegion* pSfr, bool bUniform, int nlayer = GDB_ID_NULL) ; + void DebugDrawLoop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) ; + void DebugDrawBox( const BBox3d& BBox, const Frame3d& FrBox, int nlayer) ; + void DebugDrawOpenEdgesInRaw( const ICRVCOMPOPOVECTOR& vpCrvsm, int nlayer) ; private : double GetSpeed( void) const