diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 1773b2d..b96894b 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/Operation.h b/Operation.h index 4362e57..a674bf2 100644 --- a/Operation.h +++ b/Operation.h @@ -127,6 +127,12 @@ class Operation : public IUserObj bool SetFlag( int nFlag) ; bool GetCurrPos( Point3d& ptCurr) const { if ( ! m_bCurr) return false ; ptCurr = m_ptCurr ; return true ; } + bool SameAsCurrPos( const Point3d& ptP) const + { if ( ! m_bCurr) return false ; return AreSamePointEpsilon( ptP, m_ptCurr, 10 * EPS_SMALL) ; } + bool GetCurrCorr( Vector3d& vtCCurr) const + { if ( ! m_bCurr) return false ; vtCCurr = m_vtCorr ; return true ; } + bool GetCurrAux( Vector3d& vtACurr) const + { if ( ! m_bCurr) return false ; vtACurr = m_vtAux ; return true ; } int AddRapidStart( const Point3d& ptP) ; int AddRapidStart( const Point3d& ptP, const std::string& sName) ; int AddRapidMove( const Point3d& ptP) ; diff --git a/SawFinishing.cpp b/SawFinishing.cpp index 4aa6fbd..7dce825 100644 --- a/SawFinishing.cpp +++ b/SawFinishing.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2016 +// EgalTech 2015-2019 //---------------------------------------------------------------------------- -// File : SawFinishing.cpp Data : 05.04.16 Versione : 1.6o4 +// File : SawFinishing.cpp Data : 23.04.19 Versione : 2.1d3 // Contenuto : Implementazione gestione finitura superficie con lama. // // Note : Questa lavorazione è sempre espressa nel riferimento globale. // // Modifiche : 05.04.16 DS Creazione modulo. -// +// 23.04.19 DS Aggiunte cornici curve. // //---------------------------------------------------------------------------- @@ -37,19 +37,20 @@ using namespace std ; //------------------------------ Errors -------------------------------------- // 2701 = "Error in SawFinishing : UpdateToolData failed" -// 2702 = "Error in SawFinishing : Empty RawBox" -// 2703 = "Error in SawFinishing : Depth not computable" -// 2704 = "Error in SawFinishing : CalculateToolAndCorrVersors" -// 2705 = "Error in SawFinishing : ApproxWithLines" -// 2706 = "Error in SawFinishing : Guide Line not along X or Y" -// 2707 = "Error in SawFinishing : GetElevation" -// 2708 = "Error in SawFinishing : CalculateAlongToolPath failed" -// 2709 = "Error in SawFinishing : CalculateAcrossToolPath failed" -// 2710 = "Error in SawFinishing : axes values not calculable" -// 2711 = "Error in SawFinishing : outstroke xx" -// 2712 = "Error in SawFinishing : link movements not calculable" -// 2713 = "Error in SawFinishing : link outstroke xx" -// 2714 = "Error in SawFinishing : post apply not calculable" +// 2702 = "Error in SawFinishing : AdjustGeometry failed" +// 2703 = "Error in SawFinishing : Empty RawBox" +// 2704 = "Error in SawFinishing : Depth not computable" +// 2705 = "Error in SawFinishing : CalculateToolAndCorrVersors" +// 2706 = "Error in SawFinishing : ApproxWithLines" +// 2707 = "Error in SawFinishing : Guide Line not along X or Y" +// 2708 = "Error in SawFinishing : GetElevation" +// 2709 = "Error in SawFinishing : CalculateAlongToolPath failed" +// 2710 = "Error in SawFinishing : CalculateAcrossToolPath failed" +// 2711 = "Error in SawFinishing : axes values not calculable" +// 2712 = "Error in SawFinishing : outstroke xx" +// 2713 = "Error in SawFinishing : link movements not calculable" +// 2714 = "Error in SawFinishing : link outstroke xx" +// 2715 = "Error in SawFinishing : post apply not calculable" //---------------------------------------------------------------------------- const std::string MCH_SECTION = "Sect" ; @@ -82,6 +83,7 @@ SawFinishing::Clone( void) const if ( pSaw != nullptr) { try { pSaw->m_vId = m_vId ; + pSaw->m_bStraight = m_bStraight ; pSaw->m_pMchMgr = m_pMchMgr ; pSaw->m_nPhase = m_nPhase ; pSaw->m_Params = m_Params ; @@ -105,6 +107,7 @@ SawFinishing::Dump( string& sOut, bool bMM, const char* szNewLine) const sOut += GetClassName() + "[mm]" + szNewLine ; sOut += KEY_PHASE + EQUAL + ToString( m_nPhase) + szNewLine ; sOut += KEY_IDS + EQUAL + ToString( m_vId) + szNewLine ; + sOut += KEY_STRAIGHT + EQUAL + ToString( m_bStraight) + szNewLine ; for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) sOut += m_Params.ToString( i) + szNewLine ; for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) @@ -120,7 +123,7 @@ bool SawFinishing::Save( int nBaseId, STRVECTOR& vString) const { try { - int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() + 3 ; + int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() + 4 ; vString.insert( vString.begin(), nSize, "") ; int k = - 1 ; if ( ! SetVal( KEY_IDS, m_vId, vString[++k])) @@ -135,6 +138,8 @@ SawFinishing::Save( int nBaseId, STRVECTOR& vString) const return false ; if ( ! SetVal( KEY_STAT, m_nStatus, vString[++k])) return false ; + if ( ! SetVal( KEY_STRAIGHT, m_bStraight, vString[++k])) + return false ; } catch( ...) { return false ; @@ -187,6 +192,10 @@ SawFinishing::Load( const STRVECTOR& vString, int nBaseGdbId) if ( ! FromString( sVal, m_nStatus)) return false ; } + else if ( sKey == KEY_STRAIGHT) { + if ( ! FromString( sVal, m_bStraight)) + return false ; + } } return true ; } @@ -201,6 +210,7 @@ SawFinishing::SawFinishing( void) m_TParams.m_sHead = "*" ; m_nStatus = MCH_ST_TO_VERIFY ; m_nCuts = 0 ; + m_bStraight = true ; } //---------------------------------------------------------------------------- @@ -442,7 +452,7 @@ SawFinishing::SetGeometry( const SELVECTOR& vIds) // test sull'entità int nSubs ; if ( ! VerifyGeometry( Id, nSubs)) { - string sOut = "Entity " + ToString( Id) + " skipped by Sawing" ; + string sOut = "Entity " + ToString( Id) + " skipped by SawFinishing" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; continue ; } @@ -508,8 +518,10 @@ SawFinishing::Apply( bool bRecalc, bool bPostApply) } // se necessario, preparo geometria e la inserisco sotto la geometria ausiliaria - if ( bRecalc && ! AdjustGeometry( nAuxId)) + if ( bRecalc && ! AdjustGeometry( nAuxId)) { + m_pMchMgr->SetLastError( 2702, "Error in SawFinishing : AdjustGeometry failed") ; return false ; + } // recupero gruppo per geometria di lavorazione (Cutter Location) int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; @@ -526,15 +538,31 @@ SawFinishing::Apply( bool bRecalc, bool bPostApply) // calcolo le passate if ( m_Params.m_nSubType == SAWFIN_SUB_ALONG) { - if ( ! CalculateAlongToolPath( nAuxId, nClId)) { - m_pMchMgr->SetLastError( 2708, "Error in SawFinishing : CalculateAlongToolPath failed") ; - return false ; + if ( m_bStraight) { + if ( ! CalculateStraightAlongToolPath( nAuxId, nClId)) { + m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAlongToolPath failed") ; + return false ; + } + } + else { + if ( ! CalculateCurvedAlongToolPath( nAuxId, nClId)) { + m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAlongToolPath failed") ; + return false ; + } } } else if ( m_Params.m_nSubType == SAWFIN_SUB_ACROSS) { - if ( ! CalculateAcrossToolPath( nAuxId, nClId)) { - m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAcrossToolPath failed") ; - return false ; + if ( m_bStraight) { + if ( ! CalculateStraightAcrossToolPath( nAuxId, nClId)) { + m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : CalculateAcrossToolPath failed") ; + return false ; + } + } + else { + if ( ! CalculateCurvedAcrossToolPath( nAuxId, nClId)) { + m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : CalculateAcrossToolPath failed") ; + return false ; + } } } @@ -584,9 +612,9 @@ SawFinishing::Update( bool bPostApply) if ( ! CalculateAxesValues( sHint)) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) - m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : axes values not calculable") ; + m_pMchMgr->SetLastError( 2711, "Error in SawFinishing : axes values not calculable") ; else - m_pMchMgr->SetLastError( 2711, "Error in SawFinishing : outstroke ") ; + m_pMchMgr->SetLastError( 2712, "Error in SawFinishing : outstroke ") ; return false ; } @@ -594,15 +622,15 @@ SawFinishing::Update( bool bPostApply) if ( ! AdjustStartEndMovements()) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) - m_pMchMgr->SetLastError( 2712, "Error in SawFinishing : link movements not calculable") ; + m_pMchMgr->SetLastError( 2713, "Error in SawFinishing : link movements not calculable") ; else - m_pMchMgr->SetLastError( 2713, "Error in SawFinishing : link outstroke ") ; + m_pMchMgr->SetLastError( 2714, "Error in SawFinishing : link outstroke ") ; return false ; } // esecuzione eventuali personalizzazioni if ( bPostApply && ! PostApply()) { - m_pMchMgr->SetLastError( 2714, "Error in SawFinishing : post apply not calculable") ; + m_pMchMgr->SetLastError( 2715, "Error in SawFinishing : post apply not calculable") ; return false ; } @@ -878,6 +906,7 @@ bool SawFinishing::AdjustGeometry( int nAuxId) { // sgrossatura di cornici diritte : due o più curve (sezioni e guida rettilinea) + // sgrossatura di cornici curve : due curve (sezione e guida curva) size_t nCrvCount = m_vId.size() ; if ( nCrvCount >= 2) { // le sezioni devono essere chiuse, piane e giacere in uno stesso piano verticale @@ -900,14 +929,39 @@ SawFinishing::AdjustGeometry( int nAuxId) return false ; } } - // l'ultima curva deve essere una linea, iniziare in comune con la prima sezione ed essere perp. al piano + // l'ultima curva è la guida PtrOwner pGuide( GetCurve( m_vId[nCrvCount-1])) ; - if ( IsNull( pGuide) || pGuide->GetType() != CRV_LINE) + if ( IsNull( pGuide)) return false ; + // se linea -> cornici diritte (lama verticale) + if ( pGuide->GetType() == CRV_LINE) + m_bStraight = true ; + // altrimenti curva -> cornici curve (lama orizzontale) + else { + m_bStraight = false ; + // ammessa una sola sezione + if ( nCrvCount > 2) + return false ; + // la guida deve giacere nel piano XY + Plane3d plPlane ; + if ( ! pGuide->IsFlat( plPlane, 10 * EPS_SMALL) || ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), Z_AX)) + return false ; + // verifiche sulla curva (che trasformo in composita) + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pGuide))) + return false ; + // converto in archi e rette + pCompo->ArcsBezierCurvesToArcsPerpExtr( LIN_TOL_MID, ANG_TOL_STD_DEG) ; + // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi + VerifyArcs( pCompo) ; + // reinserisco nella curva originale + pGuide.Set( Release( pCompo)) ; + } + // deve iniziare in comune con la prima sezione ed essere ivi perpendicolare Point3d ptStStart, ptGdStart ; if ( ! vpSects[0]->GetStartPoint( ptStStart) || - ! pGuide->GetStartPoint( ptGdStart) || - ! AreSamePointApprox( ptStStart, ptGdStart)) + ! pGuide->GetStartPoint( ptGdStart) || + ! AreSamePointApprox( ptStStart, ptGdStart)) return false ; Vector3d vtGdDir ; if ( ! pGuide->GetStartDir( vtGdDir) || ! AreSameOrOppositeVectorApprox( vtN, vtGdDir)) @@ -947,7 +1001,7 @@ SawFinishing::AdjustGeometry( int nAuxId) //---------------------------------------------------------------------------- bool -SawFinishing::CalculateAlongToolPath( int nAuxId, int nClId) +SawFinishing::CalculateStraightAlongToolPath( int nAuxId, int nClId) { // Recupero ed elaboro le sezioni per portarle ad essere la curva del centro in basso della lama ICurve* pSect ; @@ -982,7 +1036,7 @@ SawFinishing::CalculateAlongToolPath( int nAuxId, int nClId) b3Test.Add( b3Guide) ; BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { - m_pMchMgr->SetLastError( 2702, "Error in SawFinishing : Empty RawBox") ; + m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ; return false ; } @@ -991,7 +1045,7 @@ SawFinishing::CalculateAlongToolPath( int nAuxId, int nClId) ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; double dDepth ; if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) { - m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Depth not computable") ; + m_pMchMgr->SetLastError( 2704, "Error in SawFinishing : Depth not computable") ; return false ; } @@ -1005,7 +1059,7 @@ SawFinishing::CalculateAlongToolPath( int nAuxId, int nClId) // Determino versori fresa e correzione Vector3d vtTool, vtCorr ; if ( ! CalculateToolAndCorrVersors( vtGdDir, m_Params.m_nHeadSide, vtTool, vtCorr)) { - m_pMchMgr->SetLastError( 2704, "Error in SawFinishing : CalculateToolAndCorrVersors") ; + m_pMchMgr->SetLastError( 2705, "Error in SawFinishing : CalculateToolAndCorrVersors") ; return false ; } @@ -1105,7 +1159,7 @@ SawFinishing::CalculateAlongToolPath( int nAuxId, int nClId) //---------------------------------------------------------------------------- bool -SawFinishing::CalculateAcrossToolPath( int nAuxId, int nClId) +SawFinishing::CalculateStraightAcrossToolPath( int nAuxId, int nClId) { // Recupero ed elaboro le sezioni per portarle ad essere la curva del centro in basso della lama ICurve* pSect ; @@ -1141,7 +1195,7 @@ SawFinishing::CalculateAcrossToolPath( int nAuxId, int nClId) b3Test.Add( b3Guide) ; BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { - m_pMchMgr->SetLastError( 2702, "Error in SawFinishing : Empty RawBox") ; + m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ; return false ; } @@ -1150,7 +1204,7 @@ SawFinishing::CalculateAcrossToolPath( int nAuxId, int nClId) ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; double dDepth ; if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) { - m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Depth not computable") ; + m_pMchMgr->SetLastError( 2704, "Error in SawFinishing : Depth not computable") ; return false ; } @@ -1164,14 +1218,14 @@ SawFinishing::CalculateAcrossToolPath( int nAuxId, int nClId) // Determino versori fresa e correzione Vector3d vtTool, vtCorr ; if ( ! CalculateToolAndCorrVersors( vtGdDir, m_Params.m_nHeadSide, vtTool, vtCorr)) { - m_pMchMgr->SetLastError( 2704, "Error in SawFinishing : CalculateToolAndCorrVersors") ; + m_pMchMgr->SetLastError( 2705, "Error in SawFinishing : CalculateToolAndCorrVersors") ; return false ; } // Approssimo la curva con una spezzata PolyLine PL ; if ( ! pCrv->ApproxWithLines( LIN_TOL_MID, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL)) { - m_pMchMgr->SetLastError( 2705, "Error in SawFinishing : ApproxWithLines") ; + m_pMchMgr->SetLastError( 2706, "Error in SawFinishing : ApproxWithLines") ; return false ; } // Se standard, allungo inizio e fine della sezione dello spessore lama @@ -1252,6 +1306,172 @@ SawFinishing::CalculateAcrossToolPath( int nAuxId, int nClId) return true ; } +//---------------------------------------------------------------------------- +bool +SawFinishing::CalculateCurvedAlongToolPath( int nAuxId, int nClId) +{ + // Ruoto di 90 deg la curva sezione nel suo piano + int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; + int nCrvId = ExeGetFirstInGroup( nSectGrpId) ; + m_pGeomDB->Rotate( nCrvId, ORIG, Z_AX, 90.0) ; + // Recupero ed elaboro la sezione per portarla ad essere la curva del lato verso la cornice della lama + ICurve* pSect ; + if ( ! CalculateSection( nSectGrpId, pSect)) + return false ; + // Contro rotazione della curva + m_pGeomDB->Rotate( nCrvId, ORIG, Z_AX, -90.0) ; + PtrOwner pCrv( pSect) ; + // recupero il riferimento globale della sezione + Frame3d frSect ; + m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; + // recupero il box globale della sezione + BBox3d b3Sect ; + m_pGeomDB->GetGlobalBBox( nSectGrpId, b3Sect) ; + + // Recupero ed elaboro la linea guida + int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; + // recupero la linea guida + ICurve* pGuide = ::GetCurve( m_pGeomDB->GetGeoObj( nGuideId)) ; + if ( pGuide == nullptr) + return false ; + // recupero il suo riferimento + Frame3d frGdL ; + m_pGeomDB->GetGlobFrame( nGuideId, frGdL) ; + // porto la curva in globale (dovrebbe già avere riferimento globale) + pGuide->ToGlob( frGdL) ; + // recupero il box globale della linea guida + BBox3d b3Guide ; + m_pGeomDB->GetGlobalBBox( nGuideId, b3Guide) ; + + // recupero il box del grezzo in globale + BBox3d b3Test ; + b3Test.Add( b3Sect) ; + b3Test.Add( b3Guide) ; + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { + m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ; + return false ; + } + + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", 0) ; + ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; + double dDepth ; + if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) { + m_pMchMgr->SetLastError( 2704, "Error in SawFinishing : Depth not computable") ; + return false ; + } + + // creo gruppo per geometria di lavorazione + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, MCH_PATH + "1_1") ; + m_pGeomDB->SetMaterial( nPxId, GREEN) ; + + // Imposto versore fresa come Z+ + Vector3d vtTool = Z_AX ; + + // Imposto dati comuni + SetPathId( nPxId) ; + SetToolDir( vtTool) ; + + // Classifico i tratti a seconda della pendenza (salita, discesa, verticale, orizzontale) + INTVECTOR vnClass ; + ClassifySection( pCrv, vnClass) ; + + // Ripristino orientamento sezione con controrotazione + pCrv->Rotate( ORIG, Z_AX, -90.0) ; + + // Inizializzo contatore tagli + m_nCuts = 0 ; + + // Passate sui lati verticali + int nUmin = -1, nUmax = -1 ; + for ( size_t i = 0 ; i < vnClass.size() ; ++ i) { + // se lato verticale + if ( vnClass[i] == CCL_VERT) { + if ( nUmin < 0) + nUmin = int( i) ; + nUmax = int( i + 1) ; + } + // se lato non verticale e non piccolo o ultimo + if ( ( vnClass[i] != CCL_VERT && vnClass[i] != CCL_SMALL) || i == vnClass.size() - 1) { + if ( nUmin >= 0) { + // eseguo la passata + if ( ! CalcCurvedAlongVerticalCuts( pCrv, nUmin, nUmax, frSect, + pGuide, dDepth, b3Raw.GetMax().z, vtTool)) + return false ; + nUmin = - 1 ; + } + } + } + // Altre passate + int nStatus = CCL_VERT ; + nUmin = -1 ; + nUmax = -1 ; + bool bSkipMin = false, bSkipMax = false ; + for ( size_t i = 0 ; i < vnClass.size() ; ++ i) { + // se stato nullo (verticale) + if ( nStatus == CCL_VERT) { + if ( vnClass[i] == CCL_VERT || vnClass[i] == CCL_SMALL) + continue ; + else { + nStatus = vnClass[i] ; + nUmin = int( i) ; + nUmax = int( i + 1) ; + bSkipMin = true ; + } + } + // altrimenti + else { + // se classe piatto e trovo salita o discesa, converto a questo + if ( nStatus == CCL_FLAT && ( vnClass[i] == CCL_RISE || vnClass[i] == CCL_FALL)) + nStatus = vnClass[i] ; + // se si conserva la classe, aggiorno fine + if ( vnClass[i] == nStatus || vnClass[i] == CCL_FLAT || vnClass[i] == CCL_SMALL) + nUmax = int( i + 1) ; + // altrimenti calcolo il tratto precedente + else { + // calcolo il tratto + bSkipMax = ( vnClass[i] == CCL_VERT) ; + bool bInvert = ( nStatus == CCL_RISE) ; + if ( ! CalcCurvedAlongStdCuts( pCrv, nUmin, nUmax, + bSkipMin, bSkipMax, bInvert, frSect, + pGuide, dDepth, b3Raw.GetMax().z, vtTool)) + return false ; + // aggiorno stato + if ( vnClass[i] == CCL_VERT) + nStatus = CCL_VERT ; + else { + nStatus = vnClass[i] ; + nUmin = int( i) ; + nUmax = int( i + 1) ; + } + bSkipMin = true ; + } + } + } + // se c'è qualcosa in sospeso + if ( nStatus != CCL_VERT) { + bSkipMax = false ; + bool bInvert = ( nStatus == CCL_RISE) ; + if ( ! CalcCurvedAlongStdCuts( pCrv, nUmin, nUmax, + bSkipMin, bSkipMax, bInvert, frSect, + pGuide, dDepth, b3Raw.GetMax().z, vtTool)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalculateCurvedAcrossToolPath( int nAuxId, int nClId) +{ + return false ; +} + //---------------------------------------------------------------------------- bool SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect) @@ -1401,7 +1621,7 @@ SawFinishing::CalculateGuideLine( int nGuideId, const BBox3d& b3Sect, // per ora ammesse solo linee guida rettilinee dirette lungo X o Y if ( ! AreSameOrOppositeVectorApprox( vtGdDir, X_AX) && ! AreSameOrOppositeVectorApprox( vtGdDir, Y_AX)) { - m_pMchMgr->SetLastError( 2706, "Error in SawFinishing : Guide Line not along X or Y") ; + m_pMchMgr->SetLastError( 2707, "Error in SawFinishing : Guide Line not along X or Y") ; return false ; } // recupero il box globale della linea guida @@ -1414,7 +1634,7 @@ SawFinishing::CalculateGuideLine( int nGuideId, const BBox3d& b3Sect, b3Test.Add( b3Guide) ; BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { - m_pMchMgr->SetLastError( 2702, "Error in SawFinishing : Empty RawBox") ; + m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ; return false ; } @@ -1523,7 +1743,7 @@ SawFinishing::CalcAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const double dElev, dElev2 ; if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { - m_pMchMgr->SetLastError( 2707, "Error in SawFinishinging : GetElevation") ; + m_pMchMgr->SetLastError( 2708, "Error in SawFinishinging : GetElevation") ; return false ; } dElev = max( dElev, dElev2) ; @@ -1610,7 +1830,7 @@ SawFinishing::CalcAlongStdCuts( ICurve* pSect, double dUmin, double dUmax, double dElev, dElev2 ; if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { - m_pMchMgr->SetLastError( 2707, "Error in SawFinishing : GetElevation") ; + m_pMchMgr->SetLastError( 2708, "Error in SawFinishing : GetElevation") ; return false ; } dElev = max( dElev, dElev2) ; @@ -1806,7 +2026,7 @@ SawFinishing::CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, if ( AddLinearMove( ptOriEnd) == GDB_ID_NULL) return false ; SetFeed( GetEndFeed()) ; - if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) + if ( ! AreSamePointApprox( ptNewEnd, ptOriEnd) && AddLinearMove( ptNewEnd) == GDB_ID_NULL) return false ; } // 4 -> retrazione @@ -1933,6 +2153,293 @@ SawFinishing::CalcAcrossZigZagCut( const PolyLine& PL, const Vector3d& vtMove, return true ; } +//---------------------------------------------------------------------------- +bool +SawFinishing::CalcCurvedAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const Frame3d& frSect, + ICurve* pGuide, double dDepth, double dRawMaxZ, const Vector3d& vtTool) +{ + // Ingombro del taglio + BBox3d b3Cut ; + for ( int i = nUmin ; i <= nUmax ; ++ i) { + Point3d ptP ; + if ( pSect->GetPointD1D2( i, ICurve::FROM_MINUS, ptP)) + b3Cut.Add( ptP) ; + } + if ( b3Cut.IsEmpty()) + return false ; + // ordinata + double dY = ( b3Cut.GetMin().y + b3Cut.GetMax().y) / 2 ; + // Calcolo dello step tra le passate + double dL = b3Cut.GetMax().x - b3Cut.GetMin().x ; + if ( dL < 10 * EPS_SMALL) + return true ; + double dStep = max( m_Params.m_dStep, 10 * EPS_SMALL) ; + int nStep = static_cast( ceil( dL / dStep)) ; + dStep = dL / nStep ; + // Ciclo sulle passate + double dLastElev ; + Point3d ptStartPrev ; + for ( int i = 0 ; i <= nStep ; ++ i) { + // ascissa + double dX = b3Cut.GetMax().x - i * dStep ; + // creo la curva di taglio + PtrOwner pCut( pGuide->Clone()) ; + double dOffs = dX ; + Vector3d vtMove = ( dY - m_TParams.m_dThick / 2) * Z_AX ; + pCut->SimpleOffset( dOffs) ; + pCut->Translate( vtMove) ; + Point3d ptStart ; pCut->GetStartPoint( ptStart) ; + // se diverso da precedente, eseguo il taglio + bool bFirst = ( i == 0) ; + if ( bFirst || ! AreSamePointEpsilon( ptStart, ptStartPrev, 10 * EPS_SMALL)) { + if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) { + //if ( ! CalcAlongOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, true)) + // return false ; + } + else { + if ( ! CalcCurvedAlongZigZagCut( pCut, vtTool, true, bFirst, dLastElev)) + return false ; + } + } + ptStartPrev = ptStart ; + } + // se ZigZag e non centrato aggiungo risalita + if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) { + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // aggiungo retrazione + Point3d ptNewEnd ; + Vector3d vtNewCorr ; + if ( ! GetCurrPos( ptNewEnd) || ! GetCurrCorr( vtNewCorr) || ! AddRetract( ptNewEnd, vtNewCorr, dSafeZ, dLastElev, dAppr)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalcCurvedAlongStdCuts( ICurve* pSect, double dUmin, double dUmax, + bool bSkipMin, bool bSkipMax, bool bInvert, const Frame3d& frSect, + ICurve* pGuide, double dDepth, double dRawMaxZ, const Vector3d& vtTool) +{ + // Calcolo dello step tra le passate + double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; + double dLmin, dLmax ; + if ( ! pSect->GetLengthAtParam( dUmin, dLmin) || ! pSect->GetLengthAtParam( dUmax, dLmax)) + return false ; + double dL = dLmax - dLmin ; + if ( dL < 10 * EPS_SMALL) + return true ; + int nStep = static_cast( ceil( dL / dStep)) ; + dStep = dL / nStep ; + // Ciclo sulle passate + double dLastElev ; + Point3d ptStartPrev ; + bool bSkipIni = ( bInvert ? bSkipMax : bSkipMin) ; + bool bSkipFin = ( bInvert ? bSkipMin : bSkipMax) ; + int nIni = ( bSkipIni ? 1 : 0) ; + int nFin = ( bSkipFin ? nStep - 1 : nStep) ; + if ( nFin < nIni) + return true ; + for ( int i = nIni ; i <= nFin ; ++ i) { + // calcolo del parametro + double dLcurr = ( bInvert ? dLmax - i * dStep : dLmin + i * dStep) ; + double dU ; + pSect->GetParamAtLength( dLcurr, dU) ; + // coordinate nel punto + Point3d ptP ; + pSect->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP) ; + // creo la curva di taglio + PtrOwner pCut( pGuide->Clone()) ; + double dOffs = ptP.x ; + Vector3d vtMove = ( ptP.y - m_TParams.m_dThick / 2) * Z_AX ; + pCut->SimpleOffset( dOffs) ; + pCut->Translate( vtMove) ; + Point3d ptStart ; pCut->GetStartPoint( ptStart) ; + // se diverso da precedente, eseguo il taglio + bool bFirst = ( i == nIni) ; + if ( bFirst || ! AreSamePointEpsilon( ptStart, ptStartPrev, 10 * EPS_SMALL)) { + if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) { + //if ( ! CalcAlongOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, false)) + // return false ; + } + else { + if ( ! CalcCurvedAlongZigZagCut( Get( pCut), vtTool, false, bFirst, dLastElev)) + return false ; + } + ptStartPrev = ptStart ; + } + } + // se ZigZag e non centrato aggiungo risalita + if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) { + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // aggiungo retrazione + Point3d ptNewEnd ; + Vector3d vtNewCorr ; + if ( ! GetCurrPos( ptNewEnd) || ! GetCurrCorr( vtNewCorr) || ! AddRetract( ptNewEnd, vtNewCorr, dSafeZ, dLastElev, dAppr)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalcCurvedAlongZigZagCut( const ICurve* pCut, const Vector3d& vtTool, bool bVert, bool bFirst, double& dEndElev) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // verifico se passata da invertire (indice dispari) + bool bInvert = ( ( m_nCuts % 2) != 0) ; + // recupero la passata + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( *pCut)) + return false ; + if ( bInvert) + pCompo->Invert() ; + + // aggiorno inizio, fine e direzione movimento + Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; + Vector3d vtDirStart ; pCompo->GetStartDir( vtDirStart) ; + Vector3d vtOrtStart = vtDirStart ; vtOrtStart.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ; + Vector3d vtDirEnd ; pCompo->GetEndDir( vtDirEnd) ; + Vector3d vtOrtEnd = vtDirEnd ; vtOrtEnd.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + Point3d ptNewStart = ptStart ; + Point3d ptNewEnd = ptEnd ; + + // calcolo elevazioni all'inizio e alla fine + double dTgElevStart = 0 ; + GetElevation( m_nPhase, ptStart, - vtDirStart, dTgElevStart) ; + double dOrtElevStart = 0 ; + GetElevation( m_nPhase, ptStart, vtOrtStart, dOrtElevStart) ; + double dTgElevEnd = 0 ; + GetElevation( m_nPhase, ptEnd, vtDirEnd, dTgElevEnd) ; + double dOrtElevEnd = 0 ; + GetElevation( m_nPhase, ptEnd, vtOrtEnd, dOrtElevEnd) ; + dEndElev = dOrtElevEnd ; + + // se attacco/uscita/collegamento standard allungo inizio e fine dell'approccio + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) { + // modifico inizio + ptNewStart = ptStart - vtDirStart * dAppr ; + // modifico fine + ptNewEnd = ptEnd + vtDirEnd * dAppr ; + } + // se attacco/uscita/collegamento esterno allungo inizio e fine a fuori grezzo + else if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) { + // distanza XY tra centro e bordo taglio + double dDeltaTStart = 0 ; + if ( dOrtElevStart > 0.0 && dOrtElevStart < 0.5 * m_TParams.m_dDiam) + dDeltaTStart = sqrt( dOrtElevStart * m_TParams.m_dDiam - dOrtElevStart * dOrtElevStart) ; + double dDeltaTEnd = 0 ; + if ( dOrtElevEnd > 0.0 && dOrtElevEnd < 0.5 * m_TParams.m_dDiam) + dDeltaTEnd = sqrt( dOrtElevEnd * m_TParams.m_dDiam - dOrtElevEnd * dOrtElevEnd) ; + // modifico inizio + ptNewStart = ptStart - vtDirStart * ( dTgElevStart + dDeltaTStart + dAppr) ; + // modifico fine + ptNewEnd = ptEnd + vtDirEnd * ( dTgElevEnd + dDeltaTEnd + dAppr) ; + } + + // Sempre una sola passata + SetCorrAuxDir( vtOrtStart) ; + // 1 -> approccio + if ( bFirst || m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + if ( ! AddApproach( ptNewStart, vtOrtStart, dSafeZ, dOrtElevStart, dAppr)) + return false ; + } + // 2 -> movimento in affondo al punto iniziale + SetFlag( 0) ; + // con attacco centrato sono sul materiale e devo usare feed di testa + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + // con attacco fuori sono in aria + else { + if ( bFirst) { + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + else { + Point3d ptLast ; + GetCurrPos( ptLast) ; + double dDiff = ( ptNewStart - ptLast) * vtDirStart ; + // se precedente e corrente sono fuori allo stesso modo + if ( abs( dDiff) < 10 * EPS_SMALL) { + // inizio nuova passata + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + // se il precedente è più fuori + else if ( dDiff > 0) { + // allungo nuova passata + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart - dDiff * vtDirStart) == GDB_ID_NULL) + return false ; + } + // se il corrente è più fuori + else { + // allungo passata precedente + if ( AddLinearMove( ptLast + dDiff * vtDirStart) == GDB_ID_NULL) + return false ; + // inizio nuova passata + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + } + } + // se non ci sono già, vado all'inizio dell'arco + if ( ! SameAsCurrPos( ptStart) && AddLinearMove( ptStart) == GDB_ID_NULL) + return false ; + // 3 -> movimento di lato al punto finale + const ICurve* pCrv = pCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ; + Vector3d vtDirEnd ; pCrv->GetEndDir( vtDirEnd) ; + Vector3d vtOrtEnd = vtDirEnd ; vtOrtEnd.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + SetCorrAuxDir( vtOrtEnd) ; + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( pCrv->GetType() == CRV_LINE) { + if ( AddLinearMove( ptEnd) == GDB_ID_NULL) + return false ; + } + else { + Point3d ptCen ; pCrv->GetCenterPoint( ptCen) ; + double dAngCen = GetCurveArc( pCrv)->GetAngCenter() ; + if ( AddArcMove( ptEnd, ptCen, dAngCen, vtTool) == GDB_ID_NULL) + return false ; + } + pCrv = pCompo->GetNextCurve() ; + } + if ( m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) { + SetFeed( GetEndFeed()) ; + if ( ! SameAsCurrPos( ptNewEnd) && AddLinearMove( ptNewEnd) == GDB_ID_NULL) + return false ; + } + // 4 -> retrazione + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + if ( ! AddRetract( ptNewEnd, vtOrtEnd, dSafeZ, dOrtElevEnd, dAppr)) + return false ; + } + // incremento contatore passate + ++ m_nCuts ; + + return true ; +} + //---------------------------------------------------------------------------- bool SawFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, @@ -1951,14 +2458,14 @@ SawFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, } else { SetFlag( 0) ; - if ( AddRapidMove( ptP1) == GDB_ID_NULL) + if ( ! SameAsCurrPos( ptP1) && AddRapidMove( ptP1) == GDB_ID_NULL) return false ; } } else { // 1a -> punto sopra inizio Point3d ptP1b = ptP + vtCorr * ( dElev + dAppr) ; - Point3d ptP1a = ptP1b + Z_AX * ( dSafeZ - dAppr) ; + Point3d ptP1a = ptP1b + vtCorr * ( dSafeZ - dAppr) ; if ( m_nCuts == 0) { SetFlag( 1) ; if ( AddRapidStart( ptP1a) == GDB_ID_NULL) @@ -1966,11 +2473,8 @@ SawFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, } else { SetFlag( 0) ; - Point3d ptCurr ; GetCurrPos( ptCurr) ; - if ( ! AreSamePointEpsilon( ptCurr, ptP1a, 10 * EPS_SMALL)) { - if ( AddRapidMove( ptP1a) == GDB_ID_NULL) - return false ; - } + if ( ! SameAsCurrPos( ptP1a) && AddRapidMove( ptP1a) == GDB_ID_NULL) + return false ; } // 1b -> punto appena sopra inizio SetFlag( 0) ; @@ -1987,27 +2491,22 @@ SawFinishing::AddRetract( const Point3d& ptP, const Vector3d& vtCorr, { // impongo minima distanza di approccio dAppr = max( dAppr, 1.0) ; - Point3d ptCurr ; GetCurrPos( ptCurr) ; // se distanza di sicurezza minore di distanza di fine if ( dSafeZ < dAppr + 10 * EPS_SMALL) { // 4 -> movimento di risalita sopra il punto finale SetFeed( GetEndFeed()) ; Point3d ptP4 = ptP + vtCorr * ( dElev + dAppr) ; - if ( ! AreSamePointEpsilon( ptP4, ptCurr, 10 * EPS_SMALL)) { - if ( AddLinearMove( ptP4) == GDB_ID_NULL) - return false ; - } + if ( ! SameAsCurrPos( ptP4) && AddLinearMove( ptP4) == GDB_ID_NULL) + return false ; } else { // 4a -> movimento di risalita appena sopra il punto finale Point3d ptP4a = ptP + vtCorr * ( dElev + dAppr) ; - if ( ! AreSamePointEpsilon( ptP4a, ptCurr, 10 * EPS_SMALL)) { - SetFeed( GetEndFeed()) ; - if ( AddLinearMove( ptP4a) == GDB_ID_NULL) - return false ; - } + SetFeed( GetEndFeed()) ; + if ( ! SameAsCurrPos( ptP4a) && AddLinearMove( ptP4a) == GDB_ID_NULL) + return false ; // 4b -> movimento di risalita sopra il punto finale - Point3d ptP4b = ptP4a + Z_AX * ( dSafeZ - dAppr) ; + Point3d ptP4b = ptP4a + vtCorr * ( dSafeZ - dAppr) ; if ( AddRapidMove( ptP4b) == GDB_ID_NULL) return false ; } diff --git a/SawFinishing.h b/SawFinishing.h index 0ad2d7e..988b966 100644 --- a/SawFinishing.h +++ b/SawFinishing.h @@ -73,8 +73,10 @@ class SawFinishing : public Machining bool VerifyGeometry( SelData Id, int& nSubs) ; ICurve* GetCurve( SelData Id) ; bool AdjustGeometry( int nAuxId) ; - bool CalculateAlongToolPath( int nAuxId, int nClId) ; - bool CalculateAcrossToolPath( int nAuxId, int nClId) ; + bool CalculateStraightAlongToolPath( int nAuxId, int nClId) ; + bool CalculateStraightAcrossToolPath( int nAuxId, int nClId) ; + bool CalculateCurvedAlongToolPath( int nAuxId, int nClId) ; + bool CalculateCurvedAcrossToolPath( int nAuxId, int nClId) ; bool CalculateSection( int nSectGrpId, ICurve*& pSect) ; bool TrimSection( ICurve* pCrv) ; bool CalculateGuideLine( int nGuideId, const BBox3d& b3Sect, @@ -95,6 +97,12 @@ class SawFinishing : public Machining const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth) ; bool CalcAcrossZigZagCut( const PolyLine& PL, const Vector3d& vtMove, const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst) ; + bool CalcCurvedAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const Frame3d& frSect, + ICurve* pGuide, double dDepth, double dRaxMaxZ, const Vector3d& vtTool) ; + bool CalcCurvedAlongStdCuts( ICurve* pSect, double dUmin, double dUmax, + bool bSkipMin, bool bSkipMax, bool bInvert, const Frame3d& frSect, + ICurve* pGuide, double dDepth, double dRawMaxZ, const Vector3d& vtTool) ; + bool CalcCurvedAlongZigZagCut( const ICurve* pCut, const Vector3d& vtTool, bool bVert, bool bFirst, double& dEndElev) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ; @@ -120,6 +128,7 @@ class SawFinishing : public Machining private : SELVECTOR m_vId ; // identificativi entità geometriche da lavorare + bool m_bStraight ; // flag per cornici diritte/curve SawFinishingData m_Params ; // parametri lavorazione ToolData m_TParams ; // parametri utensile int m_nStatus ; // stato di aggiornamento della lavorazione diff --git a/SawRoughing.cpp b/SawRoughing.cpp index dfab229..be85b5c 100644 --- a/SawRoughing.cpp +++ b/SawRoughing.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2016 +// EgalTech 2015-2019 //---------------------------------------------------------------------------- -// File : SawRoughing.cpp Data : 30.03.16 Versione : 1.6o4 +// File : SawRoughing.cpp Data : 23.04.19 Versione : 2.1d3 // Contenuto : Implementazione gestione sgrossatura superficie con lama. // // Note : Questa lavorazione è sempre espressa nel riferimento globale. // // Modifiche : 30.03.16 DS Creazione modulo. -// +// 23.04.19 DS Aggiunte cornici curve. // //---------------------------------------------------------------------------- @@ -37,19 +37,20 @@ using namespace std ; //------------------------------ Errors -------------------------------------- // 2601 = "Error in SawRoughing : UpdateToolData failed" -// 2602 = "Error in SawRoughing : Guide Line not along X or Y" -// 2603 = "Error in SawRoughing : Empty RawBox" -// 2604 = "Error in SawRoughing : OffsetCurve" -// 2605 = "Error in SawRoughing : OffsetCurveOnX" -// 2606 = "Error in SawRoughing : Depth not computable" -// 2607 = "Error in SawRoughing : CalculateToolAndCorrVersors" -// 2608 = "Error in SawRoughing : GetElevation" -// 2609 = "Error in SawRoughing : TrimSection failed" -// 2610 = "Error in SawRoughing : axes values not calculable" -// 2611 = "Error in SawRoughing : outstroke xxx" -// 2612 = "Error in SawRoughing : link movements not calculable" -// 2613 = "Error in SawRoughing : link outstroke xxx" -// 2614 = "Error in SawRoughing : post apply not calculable" +// 2602 = "Error in SawRoughing : AdjustGeometry failed" +// 2603 = "Error in SawRoughing : Guide Line not along X or Y" +// 2604 = "Error in SawRoughing : Empty RawBox" +// 2605 = "Error in SawRoughing : OffsetCurve" +// 2606 = "Error in SawRoughing : OffsetCurveOnX" +// 2607 = "Error in SawRoughing : Depth not computable" +// 2608 = "Error in SawRoughing : CalculateToolAndCorrVersors" +// 2609 = "Error in SawRoughing : GetElevation" +// 2610 = "Error in SawRoughing : TrimSection failed" +// 2611 = "Error in SawRoughing : axes values not calculable" +// 2612 = "Error in SawRoughing : outstroke xxx" +// 2613 = "Error in SawRoughing : link movements not calculable" +// 2614 = "Error in SawRoughing : link outstroke xxx" +// 2615 = "Error in SawRoughing : post apply not calculable" //---------------------------------------------------------------------------- const std::string MCH_SECTION = "Sect" ; @@ -75,6 +76,7 @@ SawRoughing::Clone( void) const if ( pSaw != nullptr) { try { pSaw->m_vId = m_vId ; + pSaw->m_bStraight = m_bStraight ; pSaw->m_pMchMgr = m_pMchMgr ; pSaw->m_nPhase = m_nPhase ; pSaw->m_Params = m_Params ; @@ -98,6 +100,7 @@ SawRoughing::Dump( string& sOut, bool bMM, const char* szNewLine) const sOut += GetClassName() + "[mm]" + szNewLine ; sOut += KEY_PHASE + EQUAL + ToString( m_nPhase) + szNewLine ; sOut += KEY_IDS + EQUAL + ToString( m_vId) + szNewLine ; + sOut += KEY_STRAIGHT + EQUAL + ToString( m_bStraight) + szNewLine ; for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) sOut += m_Params.ToString( i) + szNewLine ; for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) @@ -113,7 +116,7 @@ bool SawRoughing::Save( int nBaseId, STRVECTOR& vString) const { try { - int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() + 3 ; + int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() + 4 ; vString.insert( vString.begin(), nSize, "") ; int k = - 1 ; if ( ! SetVal( KEY_IDS, m_vId, vString[++k])) @@ -128,6 +131,8 @@ SawRoughing::Save( int nBaseId, STRVECTOR& vString) const return false ; if ( ! SetVal( KEY_STAT, m_nStatus, vString[++k])) return false ; + if ( ! SetVal( KEY_STRAIGHT, m_bStraight, vString[++k])) + return false ; } catch( ...) { return false ; @@ -180,6 +185,10 @@ SawRoughing::Load( const STRVECTOR& vString, int nBaseGdbId) if ( ! FromString( sVal, m_nStatus)) return false ; } + else if ( sKey == KEY_STRAIGHT) { + if ( ! FromString( sVal, m_bStraight)) + return false ; + } } return true ; } @@ -194,6 +203,7 @@ SawRoughing::SawRoughing( void) m_TParams.m_sHead = "*" ; m_nStatus = MCH_ST_TO_VERIFY ; m_nCuts = 0 ; + m_bStraight = true ; } //---------------------------------------------------------------------------- @@ -491,8 +501,10 @@ SawRoughing::Apply( bool bRecalc, bool bPostApply) } // se necessario, preparo geometria e la inserisco sotto la geometria ausiliaria - if ( bRecalc && ! AdjustGeometry( nAuxId)) + if ( bRecalc && ! AdjustGeometry( nAuxId)) { + m_pMchMgr->SetLastError( 2602, "Error in SawRoughing : AdjustGeometry failed") ; return false ; + } // recupero gruppo per geometria di lavorazione (Cutter Location) int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; @@ -508,8 +520,14 @@ SawRoughing::Apply( bool bRecalc, bool bPostApply) m_pGeomDB->EmptyGroup( nClId) ; // calcolo le passate - if ( ! CalculateToolPath( nAuxId, nClId)) - return false ; + if ( m_bStraight) { + if ( ! CalculateToolPath( nAuxId, nClId)) + return false ; + } + else { + if ( ! CalculateCurvedToolPath( nAuxId, nClId)) + return false ; + } m_nCuts = 1 ; // assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso @@ -558,9 +576,9 @@ SawRoughing::Update( bool bPostApply) if ( ! CalculateAxesValues( sHint)) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) - m_pMchMgr->SetLastError( 2610, "Error in SawRoughing : axes values not calculable") ; + m_pMchMgr->SetLastError( 2611, "Error in SawRoughing : axes values not calculable") ; else - m_pMchMgr->SetLastError( 2611, "Error in SawRoughing : outstroke ") ; + m_pMchMgr->SetLastError( 2612, "Error in SawRoughing : outstroke ") ; return false ; } @@ -568,15 +586,15 @@ SawRoughing::Update( bool bPostApply) if ( ! AdjustStartEndMovements()) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) - m_pMchMgr->SetLastError( 2612, "Error in SawRoughing : link movements not calculable") ; + m_pMchMgr->SetLastError( 2613, "Error in SawRoughing : link movements not calculable") ; else - m_pMchMgr->SetLastError( 2613, "Error in SawRoughing : link outstroke ") ; + m_pMchMgr->SetLastError( 2614, "Error in SawRoughing : link outstroke ") ; return false ; } // esecuzione eventuali personalizzazioni if ( bPostApply && ! PostApply()) { - m_pMchMgr->SetLastError( 2614, "Error in SawRoughing : post apply not calculable") ; + m_pMchMgr->SetLastError( 2615, "Error in SawRoughing : post apply not calculable") ; return false ; } @@ -846,6 +864,7 @@ bool SawRoughing::AdjustGeometry( int nAuxId) { // sgrossatura di cornici diritte : due o più curve (sezioni e guida rettilinea) + // sgrossatura di cornici curve : due curve (sezione e guida curva) size_t nCrvCount = m_vId.size() ; if ( nCrvCount >= 2) { // le sezioni devono essere chiuse, piane e giacere in uno stesso piano verticale @@ -868,10 +887,35 @@ SawRoughing::AdjustGeometry( int nAuxId) return false ; } } - // l'ultima curva deve essere una linea, iniziare in comune con la prima sezione ed essere perp. al piano + // l'ultima curva è la guida PtrOwner pGuide( GetCurve( m_vId[nCrvCount-1])) ; - if ( IsNull( pGuide) || pGuide->GetType() != CRV_LINE) + if ( IsNull( pGuide)) return false ; + // se linea -> cornici diritte (lama verticale) + if ( pGuide->GetType() == CRV_LINE) + m_bStraight = true ; + // altrimenti curva -> cornici curve (lama orizzontale) + else { + m_bStraight = false ; + // ammessa una sola sezione + if ( nCrvCount > 2) + return false ; + // la guida deve giacere nel piano XY + Plane3d plPlane ; + if ( ! pGuide->IsFlat( plPlane, 10 * EPS_SMALL) || ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), Z_AX)) + return false ; + // verifiche sulla curva (che trasformo in composita) + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pGuide))) + return false ; + // converto in archi e rette + pCompo->ArcsBezierCurvesToArcsPerpExtr( LIN_TOL_MID, ANG_TOL_STD_DEG) ; + // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi + VerifyArcs( pCompo) ; + // reinserisco nella curva originale + pGuide.Set( Release( pCompo)) ; + } + // deve iniziare in comune con la prima sezione ed essere ivi perpendicolare Point3d ptStStart, ptGdStart ; if ( ! vpSects[0]->GetStartPoint( ptStStart) || ! pGuide->GetStartPoint( ptGdStart) || @@ -917,18 +961,12 @@ SawRoughing::AdjustGeometry( int nAuxId) bool SawRoughing::CalculateToolPath( int nAuxId, int nClId) { - // recupero le sezioni - ICURVEPVECTOR vpSects ; + // Recupero ed elaboro le sezioni + ICurve* pSect ; int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; - int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ; - while ( nSectId != GDB_ID_NULL) { - // recupero il puntatore alla curva - vpSects.emplace_back( ::GetCurve( m_pGeomDB->GetGeoObj( nSectId))) ; - if ( vpSects.back() == nullptr) - return false ; - // passo alla successiva - nSectId = m_pGeomDB->GetNext( nSectId) ; - } + if ( ! CalculateSection( nSectGrpId, pSect)) + return false ; + PtrOwner pCrv( pSect) ; // recupero il riferimento globale delle sezioni Frame3d frSect ; m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; @@ -936,139 +974,38 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) BBox3d b3Sect ; m_pGeomDB->GetGlobalBBox( nSectGrpId, b3Sect) ; - // recupero la linea guida - int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; - ICurve* pGuide = ::GetCurve( m_pGeomDB->GetGeoObj( nGuideId)) ; - if ( pGuide == nullptr) - return false ; - // recupero gli estremi della linea guida + // Recupero ed elaboro la linea guida Point3d ptGdStart, ptGdEnd ; - pGuide->GetStartPoint( ptGdStart) ; - pGuide->GetEndPoint( ptGdEnd) ; - // recupero la direzione della linea guida Vector3d vtGdDir ; - pGuide->GetStartDir( vtGdDir) ; - // per ora ammesse solo linee guida rettilinee dirette lungo X o Y - if ( ! AreSameOrOppositeVectorApprox( vtGdDir, X_AX) && - ! AreSameOrOppositeVectorApprox( vtGdDir, Y_AX)) { - m_pMchMgr->SetLastError( 2602, "Error in SawRoughing : Guide Line not along X or Y") ; + int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; + if ( ! CalculateGuideLine( nGuideId, b3Sect, ptGdStart, ptGdEnd, vtGdDir)) return false ; - } // recupero il box globale della linea guida BBox3d b3Guide ; m_pGeomDB->GetGlobalBBox( nGuideId, b3Guide) ; - // recupero il box del grezzo in globale e nel riferimento locale delle sezioni + // determino l'ingombro della curva risultante in locale + BBox3d b3Crv ; + pCrv->GetLocalBBox( b3Crv) ; + + // recupero il box del grezzo in globale e lo porto in locale alla sezione BBox3d b3Test ; b3Test.Add( b3Sect) ; b3Test.Add( b3Guide) ; BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { - m_pMchMgr->SetLastError( 2603, "Error in SawRoughing : Empty RawBox") ; + m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ; return false ; } BBox3d b3RawLoc = b3Raw ; b3RawLoc.ToLoc( frSect) ; - // aggiusto la linea guida al bordo del box - if ( AreSameVectorApprox( vtGdDir, X_AX)) { - ptGdStart.x = b3Raw.GetMin().x ; - ptGdEnd.x = b3Raw.GetMax().x ; - } - else if ( AreOppositeVectorApprox( vtGdDir, X_AX)) { - ptGdStart.x = b3Raw.GetMax().x ; - ptGdEnd.x = b3Raw.GetMin().x ; - } - else if ( AreSameVectorApprox( vtGdDir, Y_AX)) { - ptGdStart.y = b3Raw.GetMin().y ; - ptGdEnd.y = b3Raw.GetMax().y ; - } - else { - ptGdStart.y = b3Raw.GetMax().y ; - ptGdEnd.y = b3Raw.GetMin().y ; - } - - // elimino eventuali sottosquadra - ICURVEPOVECTOR vpNucCrvs ; - vpNucCrvs.reserve( vpSects.size()) ; - for ( const auto& pSect : vpSects) { - PtrOwner pCrvCompo( CreateCurveComposite()) ; - if ( IsNull( pCrvCompo) || - ! pCrvCompo->AddCurve( *pSect) || - ! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG)) - return false ; - vpNucCrvs.emplace_back( Release( pCrvCompo)) ; - } - - // calcolo ordinamento delle curve secondo la X decrescente - typedef pair INDASC ; // coppia indice, ascissa - typedef vector INDASCVECTOR ; // vettore di coppie indice, ascissa - INDASCVECTOR vIAsc ; - vIAsc.reserve( vpNucCrvs.size()) ; - for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { - Point3d ptStart ; - if ( ! vpNucCrvs[i]->GetStartPoint( ptStart)) - return false ; - vIAsc.emplace_back( i, ptStart.x) ; - } - std::sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) - { return a.second > b.second ; }) ; - - // unisco le diverse curve (ora aperte) in un unico profilo - PtrOwner pCurve( CreateCurveComposite()) ; - if ( IsNull( pCurve)) - return false ; - bool bFirst = true ; - for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { - if ( ! bFirst) { - Point3d ptStart ; - if ( ! vpNucCrvs[vIAsc[i].first]->GetStartPoint( ptStart) || - ! pCurve->AddLine( ptStart)) - return false ; - } - if ( ! pCurve->AddCurve( Release( vpNucCrvs[vIAsc[i].first]))) - return false ; - bFirst = false ; - } - - // offset radiale delle sezioni per il sovramateriale - double dOffsR = GetOffsR() ; - PtrOwner pOvrCrv ; - OffsetCurve OffsCrv ; - OffsCrv.Make( pCurve, dOffsR, ICurve::OFF_FILLET) ; - pOvrCrv.Set( OffsCrv.GetLongerCurve()) ; - if ( IsNull( pOvrCrv)) { - m_pMchMgr->SetLastError( 2604, "Error in SawRoughing : OffsetCurve") ; - return false ; - } - - // ricavo dalla sezione la curva per centro in basso della lama - double dOffsX = 0.5 * m_TParams.m_dThick + GetOffsL() - GetOffsR() ; - PtrOwner pCrv ; - OffsetCurveOnX OffsCrvX ; - OffsCrvX.Make( pOvrCrv, dOffsX) ; - pCrv.Set( OffsCrvX.GetLongerCurve()) ; - if ( IsNull( pCrv)) { - m_pMchMgr->SetLastError( 2605, "Error in SawRoughing : OffsetCurveOnX") ; - return false ; - } - - // determino l'intervallo di curva da conservare - if ( ! TrimSection( pCrv)) { - m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : TrimSection failed") ; - return false ; - } - - // determino l'ingombro della curva risultante in locale - BBox3d b3Crv ; - pCrv->GetLocalBBox( b3Crv) ; - // valuto l'espressione dell'affondamento ExeLuaSetGlobNumVar( "TH", 0) ; ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; double dDepth ; if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) { - m_pMchMgr->SetLastError( 2606, "Error in SawRoughing : Depth not computable") ; + m_pMchMgr->SetLastError( 2607, "Error in SawRoughing : Depth not computable") ; return false ; } @@ -1082,7 +1019,7 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) // Determino versori fresa e correzione Vector3d vtTool, vtCorr ; if ( ! CalculateToolAndCorrVersors( vtGdDir, m_Params.m_nHeadSide, vtTool, vtCorr)) { - m_pMchMgr->SetLastError( 2607, "Error in SawRoughing : CalculateToolAndCorrVersors") ; + m_pMchMgr->SetLastError( 2608, "Error in SawRoughing : CalculateToolAndCorrVersors") ; return false ; } @@ -1176,7 +1113,7 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) double dElev, dElev2 ; if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { - m_pMchMgr->SetLastError( 2608, "Error in SawRoughing : GetElevation") ; + m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ; return false ; } dElev = max( dElev, dElev2) ; @@ -1205,6 +1142,278 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) return true ; } +//---------------------------------------------------------------------------- +bool +SawRoughing::CalculateCurvedToolPath( int nAuxId, int nClId) +{ + // Ruoto di 90 deg la curva sezione nel suo piano + int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; + int nCrvId = ExeGetFirstInGroup( nSectGrpId) ; + m_pGeomDB->Rotate( nCrvId, ORIG, Z_AX, 90.0) ; + // Recupero ed elaboro la sezione + ICurve* pSect ; + if ( ! CalculateSection( nSectGrpId, pSect)) + return false ; + // Contro rotazione della curva + m_pGeomDB->Rotate( nCrvId, ORIG, Z_AX, -90.0) ; + PtrOwner pCrv( pSect) ; + // recupero il riferimento globale della sezione + Frame3d frSect ; + m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; + // recupero il box globale della sezione + BBox3d b3Sect ; + m_pGeomDB->GetGlobalBBox( nSectGrpId, b3Sect) ; + + // Recupero ed elaboro la linea guida + int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; + // recupero la linea guida + ICurve* pGuide = ::GetCurve( m_pGeomDB->GetGeoObj( nGuideId)) ; + if ( pGuide == nullptr) + return false ; + // recupero il box globale della linea guida + BBox3d b3Guide ; + m_pGeomDB->GetGlobalBBox( nGuideId, b3Guide) ; + + // recupero il box del grezzo in globale e lo porto in locale alla sezione + BBox3d b3Test ; + b3Test.Add( b3Sect) ; + b3Test.Add( b3Guide) ; + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { + m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ; + return false ; + } + BBox3d b3RawLoc = b3Raw ; + b3RawLoc.ToLoc( frSect) ; + + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", 0) ; + ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; + double dDepth ; + if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) { + m_pMchMgr->SetLastError( 2607, "Error in SawRoughing : Depth not computable") ; + return false ; + } + + // creo gruppo per geometria di lavorazione + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, MCH_PATH + "1_1") ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + + // Ripristino orientamento sezione con controrotazione + pCrv->Rotate( ORIG, Z_AX, -90.0) ; + + // determino l'ingombro della curva risultante in locale + BBox3d b3Crv ; + pCrv->GetLocalBBox( b3Crv) ; + + // Determino eventuali pareti orizzontali (in senso decrescente di Y) + DBLVECTOR vdVr ; + double dPrevY = INFINITO ; + const ICurveComposite* pCompo = GetCurveComposite( pCrv) ; + if ( pCompo != nullptr) { + const ICurve* pSimpCrv = pCompo->GetLastCurve() ; + while ( pSimpCrv != nullptr) { + Point3d ptStart, ptEnd ; + pSimpCrv->GetStartPoint( ptStart) ; + pSimpCrv->GetEndPoint( ptEnd) ; + if ( abs( ptEnd.y - ptStart.y) < EPS_SMALL) { + double dY = ( ptEnd.y + ptStart.y) / 2 ; + if ( dY < dPrevY - EPS_SMALL) { + vdVr.push_back( dY) ; + dPrevY = dY ; + } + } + pSimpCrv = pCompo->GetPrevCurve() ; + } + } + else { + Point3d ptStart, ptEnd ; + pCrv->GetStartPoint( ptStart) ; + pCrv->GetEndPoint( ptEnd) ; + if ( abs( ptEnd.y - ptStart.y) < EPS_SMALL) + vdVr.push_back( ( ptEnd.y + ptStart.y) / 2) ; + } + + // Determino le posizioni particolari + DBLVECTOR vdPp ; + size_t nVr = vdVr.size() ; + double dSawOffs = 0.5 * m_TParams.m_dThick ; + double dFinOffs = m_Params.m_dSideStep - dSawOffs ; + // calcolo dell'inizio (Ymax) + double dRawMax = b3RawLoc.GetMax().y ; // inizio grezzo + double dStart = min( dRawMax - dFinOffs, b3Crv.GetMax().y) ; // inizio con aletta prima + if ( nVr > 0 && + vdVr[0] > dStart + EPS_SMALL && + vdVr[0] - dSawOffs < dRawMax - EPS_SMALL) + dStart = vdVr[0] ; // correzione per parete verticale + // calcolo della fine (Ymin) + double dRawMin = b3RawLoc.GetMin().y ; // fine grezzo + double dEnd = max( dRawMin + dFinOffs, b3Crv.GetMin().y) ; // fine con aletta dopo + if ( nVr > 0 && + vdVr[nVr-1] < dEnd - EPS_SMALL && + vdVr[nVr-1] + dSawOffs > dRawMax + EPS_SMALL) + dEnd = vdVr[nVr-1] ; // correzione per parete verticale + // assegno le posizioni particolari (ordinate in senso decrescente) + vdPp.push_back( dStart) ; + for ( size_t i = 0 ; i < nVr ; ++ i) { + if ( vdVr[i] < dStart - EPS_SMALL && vdVr[i] > dEnd + EPS_SMALL) + vdPp.push_back( vdVr[i]) ; + } + vdPp.push_back( dEnd) ; + + // Determino versori fresa e correzione + Vector3d vtTool = Z_AX ; + + // Imposto dati comuni + SetPathId( nPxId) ; + SetToolDir( vtTool) ; + + // Ciclo sugli intervalli tra le posizioni particolari per generare le passate + int nCount = 0 ; + for ( size_t j = 0 ; j < vdPp.size() ; ++ j) { + double dYmax = ( j > 0 ? vdPp[j-1] : vdPp[0]) ; + double dYmin = vdPp[j] ; + double dLargh = dYmax - dYmin ; + double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; + int nStep = max( 1, static_cast( ceil( dLargh / dStep))) ; + dStep = dLargh / nStep ; + double dSectXMin = b3Crv.GetMin().x ; + double dSectXMax = b3Crv.GetMax().x ; + for ( int i = 1 ; i <= nStep ; ++ i) { + // flag per primo e ultimo taglio + bool bFirst = ( j == 0 && i == 1) ; + bool bLast = ( j == vdPp.size() -1 && i == nStep) ; + // determino l'ordinata della prima intersezione + double dY = dYmax - i * dStep ; + // determino l'ascissa della prima intersezione + double dX ; + if ( ! GetWidthOnSection( pCrv, dY, dSectXMin, dSectXMax, dX)) + return false ; + // creo la curva di taglio + PtrOwner pCut( pGuide->Clone()) ; + Vector3d vtMove = ( dY - m_TParams.m_dThick / 2) * Z_AX ; + pCut->SimpleOffset( dX) ; + pCut->Translate( vtMove) ; + // ne determino la massima elevazione + double dElev = 0 ; + CalculateSideElevation( pCut, dElev) ; + // la confronto con il massimo affondamento e con la massima lavorazione della lama + double dMaxDepth = min( dDepth, m_TParams.m_dMaxMat) ; + if ( dElev > dMaxDepth) { + double dOffs = dElev - dMaxDepth ; + pCut->SimpleOffset( dOffs) ; + dElev = dMaxDepth ; + } + // esecuzione del taglio + if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) { + //if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast)) + // return false ; + } + else { + if ( ! CalculateCurvedZigZagCut( pCut, vtTool, dElev, bFirst, bLast, nCount)) + return false ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawRoughing::CalculateSection( int nSectGrpId, ICurve*& pSect) +{ + // recupero le sezioni + ICURVEPVECTOR vpSects ; + int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ; + while ( nSectId != GDB_ID_NULL) { + // recupero il puntatore alla curva + vpSects.emplace_back( ::GetCurve( m_pGeomDB->GetGeoObj( nSectId))) ; + if ( vpSects.back() == nullptr) + return false ; + // passo alla successiva + nSectId = m_pGeomDB->GetNext( nSectId) ; + } + + // elimino eventuali sottosquadra + ICURVEPOVECTOR vpNucCrvs ; + vpNucCrvs.reserve( vpSects.size()) ; + for ( const auto& pSect : vpSects) { + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo) || + ! pCrvCompo->AddCurve( *pSect) || + ! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG)) + return false ; + vpNucCrvs.emplace_back( Release( pCrvCompo)) ; + } + + // calcolo ordinamento delle curve secondo la X decrescente + typedef pair INDASC ; // coppia indice, ascissa + typedef vector INDASCVECTOR ; // vettore di coppie indice, ascissa + INDASCVECTOR vIAsc ; + vIAsc.reserve( vpNucCrvs.size()) ; + for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { + Point3d ptStart ; + if ( ! vpNucCrvs[i]->GetStartPoint( ptStart)) + return false ; + vIAsc.emplace_back( i, ptStart.x) ; + } + std::sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) + { return a.second > b.second ; }) ; + + // unisco le diverse curve (ora aperte) in un unico profilo + PtrOwner pCurve( CreateCurveComposite()) ; + if ( IsNull( pCurve)) + return false ; + bool bFirst = true ; + for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { + if ( ! bFirst) { + Point3d ptStart ; + if ( ! vpNucCrvs[vIAsc[i].first]->GetStartPoint( ptStart) || + ! pCurve->AddLine( ptStart)) + return false ; + } + if ( ! pCurve->AddCurve( Release( vpNucCrvs[vIAsc[i].first]))) + return false ; + bFirst = false ; + } + + // offset radiale delle sezioni per il sovramateriale + double dOffsR = GetOffsR() ; + PtrOwner pOvrCrv ; + OffsetCurve OffsCrv ; + OffsCrv.Make( pCurve, dOffsR, ICurve::OFF_FILLET) ; + pOvrCrv.Set( OffsCrv.GetLongerCurve()) ; + if ( IsNull( pOvrCrv)) { + m_pMchMgr->SetLastError( 2605, "Error in SawRoughing : OffsetCurve") ; + return false ; + } + + // ricavo dalla sezione la curva per centro in basso della lama + double dOffsX = 0.5 * m_TParams.m_dThick + GetOffsL() - GetOffsR() ; + PtrOwner pCrv ; + OffsetCurveOnX OffsCrvX ; + OffsCrvX.Make( pOvrCrv, dOffsX) ; + pCrv.Set( OffsCrvX.GetLongerCurve()) ; + if ( IsNull( pCrv)) { + m_pMchMgr->SetLastError( 2606, "Error in SawRoughing : OffsetCurveOnX") ; + return false ; + } + + // determino l'intervallo di curva da conservare + if ( ! TrimSection( pCrv)) { + m_pMchMgr->SetLastError( 2610, "Error in SawRoughing : TrimSection failed") ; + return false ; + } + + pSect = Release( pCrv) ; + + return true ; +} + //---------------------------------------------------------------------------- bool SawRoughing::TrimSection( ICurve* pCrv) @@ -1250,6 +1459,60 @@ SawRoughing::TrimSection( ICurve* pCrv) return ( pCrv->TrimEndAtParam( dUmax) && pCrv->TrimStartAtParam( dUmin)) ; } +//---------------------------------------------------------------------------- +bool +SawRoughing::CalculateGuideLine( int nGuideId, const BBox3d& b3Sect, + Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir) +{ + // recupero la linea guida + ICurve* pGuide = ::GetCurve( m_pGeomDB->GetGeoObj( nGuideId)) ; + if ( pGuide == nullptr) + return false ; + // recupero gli estremi della linea guida + pGuide->GetStartPoint( ptGdStart) ; + pGuide->GetEndPoint( ptGdEnd) ; + // recupero la direzione della linea guida + pGuide->GetStartDir( vtGdDir) ; + // per ora ammesse solo linee guida rettilinee dirette lungo X o Y + if ( ! AreSameOrOppositeVectorApprox( vtGdDir, X_AX) && + ! AreSameOrOppositeVectorApprox( vtGdDir, Y_AX)) { + m_pMchMgr->SetLastError( 2603, "Error in SawRoughing : Guide Line not along X or Y") ; + return false ; + } + // recupero il box globale della linea guida + BBox3d b3Guide ; + m_pGeomDB->GetGlobalBBox( nGuideId, b3Guide) ; + + // recupero il box del grezzo in globale + BBox3d b3Test ; + b3Test.Add( b3Sect) ; + b3Test.Add( b3Guide) ; + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, b3Test, 10 * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) { + m_pMchMgr->SetLastError( 2604, "Error in SawRoughing : Empty RawBox") ; + return false ; + } + + // aggiusto la linea guida al bordo del box + if ( AreSameVectorApprox( vtGdDir, X_AX)) { + ptGdStart.x = b3Raw.GetMin().x ; + ptGdEnd.x = b3Raw.GetMax().x ; + } + else if ( AreOppositeVectorApprox( vtGdDir, X_AX)) { + ptGdStart.x = b3Raw.GetMax().x ; + ptGdEnd.x = b3Raw.GetMin().x ; + } + else if ( AreSameVectorApprox( vtGdDir, Y_AX)) { + ptGdStart.y = b3Raw.GetMin().y ; + ptGdEnd.y = b3Raw.GetMax().y ; + } + else { + ptGdStart.y = b3Raw.GetMax().y ; + ptGdEnd.y = b3Raw.GetMin().y ; + } + return true ; +} + //---------------------------------------------------------------------------- bool SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, @@ -1555,6 +1818,272 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c return true ; } +//---------------------------------------------------------------------------- +bool +SawRoughing::CalculateCurvedZigZagCut( const ICurve* pCut, const Vector3d& vtTool, double dElev, bool bFirst, bool bLast, + int& nCount) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // verifico se passata da invertire (indice dispari) + bool bInvert = ( ( nCount % 2) != 0) ; + // recupero la passata + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( *pCut)) + return false ; + // eseguo eventuale inversione + if ( bInvert) + pCompo->Invert() ; + + // aggiorno inizio, fine e direzione movimento + Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; + Vector3d vtDirStart ; pCompo->GetStartDir( vtDirStart) ; + Vector3d vtOrtStart = vtDirStart ; vtOrtStart.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ; + Vector3d vtDirEnd ; pCompo->GetEndDir( vtDirEnd) ; + Vector3d vtOrtEnd = vtDirEnd ; vtOrtEnd.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + Point3d ptNewStart = ptStart ; + Point3d ptNewEnd = ptEnd ; + + // calcolo elevazioni + double dTgElevStart = 0 ; + GetElevation( m_nPhase, ptStart, - vtDirStart, dTgElevStart) ; + double dOrtElevStart = 0 ; + GetElevation( m_nPhase, ptStart, vtOrtStart, dOrtElevStart) ; + double dTgElevEnd = 0 ; + GetElevation( m_nPhase, ptEnd, vtDirEnd, dTgElevEnd) ; + double dOrtElevEnd = 0 ; + GetElevation( m_nPhase, ptEnd, vtOrtEnd, dOrtElevEnd) ; + + // se attacco/uscita/collegamento esterno allungo inizio e fine + if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { + // distanza XY tra centro e bordo taglio + double dDeltaTStart = 0 ; + if ( dOrtElevStart > 0.0 && dOrtElevStart < 0.5 * m_TParams.m_dDiam) + dDeltaTStart = sqrt( dOrtElevStart * m_TParams.m_dDiam - dOrtElevStart * dOrtElevStart) ; + double dDeltaTEnd = 0 ; + if ( dOrtElevEnd > 0.0 && dOrtElevEnd < 0.5 * m_TParams.m_dDiam) + dDeltaTEnd = sqrt( dOrtElevEnd * m_TParams.m_dDiam - dOrtElevEnd * dOrtElevEnd) ; + // modifico inizio + ptNewStart = ptStart - vtDirStart * ( dTgElevStart + dDeltaTStart + dAppr) ; + // modifico fine + ptNewEnd = ptEnd + vtDirEnd * ( dTgElevEnd + dDeltaTEnd + dAppr) ; + } + + // Se una sola passata + if ( m_Params.m_dStep < EPS_SMALL || dElev <= m_Params.m_dStep) { + SetCorrAuxDir( vtOrtStart) ; + // 1 -> approccio + if ( bFirst || m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { + if ( ! AddApproach( ptNewStart, vtOrtStart, bFirst, dSafeZ, dOrtElevStart, dAppr)) + return false ; + } + // 2 -> movimento in affondo al punto iniziale + SetFlag( 0) ; + // con attacco centrato sono sul materiale e devo usare feed di testa + if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { + SetFeed( GetTipFeed()) ; + Point3d ptCurr ; GetCurrPos( ptCurr) ; + if ( ! AreSamePointEpsilon( ptCurr, ptNewStart, 10 * EPS_SMALL)) { + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + } + // con attacco fuori sono in aria + else { + if ( bFirst) { + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + else { + Point3d ptLast ; + GetCurrPos( ptLast) ; + double dDiff = ( ptNewStart - ptLast) * vtDirStart ; + // se precedente e corrente sono fuori allo stesso modo + if ( abs( dDiff) < 10 * EPS_SMALL) { + // inizio nuova passata + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + // se il precedente è più fuori + else if ( dDiff > 0) { + // allungo nuova passata + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart - dDiff * vtDirStart) == GDB_ID_NULL) + return false ; + } + // se il corrente è più fuori + else { + // allungo passata precedente + if ( AddLinearMove( ptLast + dDiff * vtDirStart) == GDB_ID_NULL) + return false ; + // inizio nuova passata + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + } + } + // se non ci sono già, vado all'inizio dell'arco + if ( ! SameAsCurrPos( ptStart) && AddLinearMove( ptStart) == GDB_ID_NULL) + return false ; + // 3 -> movimento di lato al punto finale + const ICurve* pCrv = pCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ; + Vector3d vtDirEnd ; pCrv->GetEndDir( vtDirEnd) ; + Vector3d vtOrtEnd = vtDirEnd ; vtOrtEnd.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + SetCorrAuxDir( vtOrtEnd) ; + SetFeed( GetFeed()) ; + if ( pCrv->GetType() == CRV_LINE) { + if ( AddLinearMove( ptEnd) == GDB_ID_NULL) + return false ; + } + else { + Point3d ptCen ; pCrv->GetCenterPoint( ptCen) ; + double dAngCen = GetCurveArc( pCrv)->GetAngCenter() ; + if ( AddArcMove( ptEnd, ptCen, dAngCen, vtTool) == GDB_ID_NULL) + return false ; + } + pCrv = pCompo->GetNextCurve() ; + } + if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { + SetFeed( GetEndFeed()) ; + if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) + return false ; + } + // 4 -> retrazione + if ( bLast || m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { + if ( ! AddRetract( ptNewEnd, vtOrtEnd, dSafeZ, dOrtElevEnd, dAppr)) + return false ; + } + // incremento contatore passate + ++ nCount ; + } + + // altrimenti più passate a zig-zag + else { + SetCorrAuxDir( vtOrtStart) ; + // 1 -> approccio + if ( bFirst || m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { + if ( ! AddApproach( ptNewStart, vtOrtStart, bFirst, dSafeZ, dOrtElevStart, dAppr)) + return false ; + } + // 2-3 -> lavorazione + // calcolo numero e valore degli step + double dCutH = dElev ; + int nStep = static_cast( ceil( dCutH / m_Params.m_dStep)) ; + double dStep = dCutH / nStep ; + // offset iniziale della curva + pCompo->SimpleOffset( bInvert ? - nStep * dStep : nStep * dStep) ; + // esecuzione degli step + for ( int i = nStep - 1 ; i >= 0 ; -- i) { + // distanza dal fondo + double dDelta = ( ( i != 0) ? i * dStep : 0) ; + pCompo->SimpleOffset( bInvert ? dStep : -dStep) ; + // movimento in affondo al punto iniziale + // con attacco centrato sono sul materiale e devo usare feed di testa + if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { + SetFlag( 0) ; + if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) + SetFeed( GetTipFeed()) ; + else + SetFeed( GetFeed()) ; + Point3d ptP2 = ptNewStart + vtOrtStart * dDelta ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + } + // con attacco fuori sono in aria + else { + if ( bFirst || i < nStep - 1) { + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart + vtOrtStart * dDelta) == GDB_ID_NULL) + return false ; + } + else { + Point3d ptLast ; + GetCurrPos( ptLast) ; + double dDiff = ( ptNewStart - ptLast) * vtDirStart ; + // se precedente e corrente sono fuori allo stesso modo + if ( abs( dDiff) < 10 * EPS_SMALL) { + // inizio nuova passata + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart + vtOrtStart * dDelta) == GDB_ID_NULL) + return false ; + } + // se il precedente è più fuori + else if ( dDiff > 0) { + // allungo nuova passata + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart + vtOrtStart * dDelta - dDiff * vtDirStart) == GDB_ID_NULL) + return false ; + } + // se il corrente è più fuori + else { + // allungo passata precedente + if ( AddLinearMove( ptLast + dDiff * vtDirStart) == GDB_ID_NULL) + return false ; + // inizio nuova passata + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart + vtOrtStart * dDelta) == GDB_ID_NULL) + return false ; + } + } + } + // se non ci sono già, vado all'inizio dell'arco + if ( ! SameAsCurrPos( ptStart + vtOrtStart * dDelta) && AddLinearMove( ptStart + vtOrtStart * dDelta) == GDB_ID_NULL) + return false ; + // movimento di lato al punto finale + const ICurve* pCrv = pCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ; + Vector3d vtDirEnd ; pCrv->GetEndDir( vtDirEnd) ; + Vector3d vtOrtEnd = vtDirEnd ; vtOrtEnd.Rotate( Z_AX, ( bInvert ? 90 : -90)) ; + SetCorrAuxDir( vtOrtEnd) ; + SetFeed( GetFeed()) ; + if ( pCrv->GetType() == CRV_LINE) { + if ( AddLinearMove( ptEnd) == GDB_ID_NULL) + return false ; + } + else { + Point3d ptCen ; pCrv->GetCenterPoint( ptCen) ; + double dAngCen = GetCurveArc( pCrv)->GetAngCenter() ; + if ( AddArcMove( ptEnd, ptCen, dAngCen, vtTool) == GDB_ID_NULL) + return false ; + } + pCrv = pCompo->GetNextCurve() ; + } + if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { + SetFeed( GetEndFeed()) ; + if ( AddLinearMove( ptNewEnd + vtOrtEnd * dDelta) == GDB_ID_NULL) + return false ; + } + // incremento contatore passate + ++ nCount ; + // scambio inizio e fine + if ( i > 0) { + swap( ptStart, ptEnd) ; + swap( ptNewStart, ptNewEnd) ; + swap( vtOrtStart, vtOrtEnd) ; + swap( dOrtElevStart, dOrtElevEnd) ; + bInvert = ! bInvert ; + pCompo->Invert() ; + } + } + // 4 -> retrazione + if ( bLast || m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { + if ( ! AddRetract( ptNewEnd, vtOrtEnd, dSafeZ, dOrtElevEnd, dAppr)) + return false ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool SawRoughing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirst, @@ -1578,7 +2107,7 @@ SawRoughing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirs else { // 1a -> punto sopra inizio Point3d ptP1b = ptP + vtCorr * ( dElev + dAppr) ; - Point3d ptP1a = ptP1b + Z_AX * ( dSafeZ - m_Params.m_dStartPos) ; + Point3d ptP1a = ptP1b + vtCorr * ( dSafeZ - m_Params.m_dStartPos) ; if ( bFirst) { SetFlag( 1) ; if ( AddRapidStart( ptP1a) == GDB_ID_NULL) @@ -1618,7 +2147,7 @@ SawRoughing::AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSaf return false ; } // 4b -> movimento di risalita sopra il punto finale - Point3d ptP4b = ptP4a + Z_AX * ( dSafeZ - m_Params.m_dStartPos) ; + Point3d ptP4b = ptP4a + vtCorr * ( dSafeZ - m_Params.m_dStartPos) ; if ( AddRapidMove( ptP4b) == GDB_ID_NULL) return false ; } @@ -1668,3 +2197,54 @@ SawRoughing::GetHeightOnSection( const ICurve* pSect, double dX, double dYmin, d dY = dYmin ; return true ; } + +//---------------------------------------------------------------------------- +bool +SawRoughing::GetWidthOnSection( const ICurve* pSect, double dY, double dXmin, double dXmax, double& dX) +{ + // creo raggio per intersezione con direzione X- + PtrOwnerpRay( CreateCurveLine()) ; + if ( IsNull( pRay) || + ! pRay->Set( Point3d( dXmax + EPS_SMALL, dY, 0), Point3d( dXmin - EPS_SMALL, dY, 0))) + return false ; + // eseguo intersezione (considero la prima perchè non ci sono sottosquadra) + IntersCurveCurve intCC( *pRay, *pSect) ; + IntCrvCrvInfo aInfo ; + if ( intCC.GetIntCrvCrvInfo( 0, aInfo)) { + // nel caso di sovrapposizione devo prendere la X massima del tratto + dX = aInfo.IciA[0].ptI.x ; + return true ; + } + // se non c'è intersezione assegno il massimo + dX = dXmax ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawRoughing::CalculateSideElevation( const ICurve* pCut, double& dElev) +{ + // Inizializzo elevazione + dElev = 0 ; + // Lunghezza della curva + double dTotLen ; + pCut->GetLength( dTotLen) ; + // Ciclo sulla curva + double dLen = 0 ; + while ( dLen <= dTotLen) { + double dU ; + if ( pCut->GetParamAtLength( dLen, dU)) { + Point3d ptP ; + Vector3d vtDir ; + pCut->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP, &vtDir) ; + vtDir.Normalize() ; + vtDir.Rotate( Z_AX, -90) ; + double dCurrElev ; + if ( GetElevation(m_nPhase, ptP, vtDir, dCurrElev) && dCurrElev > dElev) + dElev = dCurrElev ; + } + dLen += 20 ; + } + + return true ; +} diff --git a/SawRoughing.h b/SawRoughing.h index cc21cb1..f4e6eba 100644 --- a/SawRoughing.h +++ b/SawRoughing.h @@ -74,18 +74,26 @@ class SawRoughing : public Machining ICurve* GetCurve( SelData Id) ; bool AdjustGeometry( int nAuxId) ; bool CalculateToolPath( int nAuxId, int nClId) ; + bool CalculateCurvedToolPath( int nAuxId, int nClId) ; + bool CalculateSection( int nSectGrpId, ICurve*& pSect) ; bool TrimSection( ICurve* pCrv) ; + bool CalculateGuideLine( int nGuideId, const BBox3d& b3Sect, + Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir) ; bool CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast) ; bool CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, int& nCount) ; + bool CalculateCurvedZigZagCut( const ICurve* pCut, const Vector3d& vtTool, double dElev, bool bFirst, bool bLast, + int& nCount) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirst, double dSafeZ, double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ; bool CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, Vector3d& vtTool, Vector3d& vtCorr) ; bool GetHeightOnSection( const ICurve* pSect, double dX, double dYmin, double dYmax, double& dY) ; + bool GetWidthOnSection( const ICurve* pSect, double dY, double dXmin, double dXmax, double& dX) ; + bool CalculateSideElevation( const ICurve* pCut, double& dElev) ; private : double GetSpeed() const @@ -105,6 +113,7 @@ class SawRoughing : public Machining private : SELVECTOR m_vId ; // identificativi entità geometriche da lavorare + bool m_bStraight ; // flag per cornici diritte/curve SawRoughingData m_Params ; // parametri lavorazione ToolData m_TParams ; // parametri utensile int m_nStatus ; // stato di aggiornamento della lavorazione