diff --git a/CamData.cpp b/CamData.cpp index 426046b..a52a9b3 100644 --- a/CamData.cpp +++ b/CamData.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2016 //---------------------------------------------------------------------------- -// File : CamData.cpp Data : 10.06.15 Versione : 1.6f2 +// File : CamData.cpp Data : 24.02.16 Versione : 1.6n8 // Contenuto : Implementazione informazioni Cam di ogni movimento. // // // // Modifiche : 10.06.15 DS Creazione modulo. -// +// 24.02.16 DS Versione 2 (aggiunti m_nMove e m_ptCen). // //---------------------------------------------------------------------------- @@ -22,7 +22,7 @@ using namespace std ; //---------------------------------------------------------------------------- -static int CAM_TOTPARAM = 10 ; +static int CAM_PARAM_V1 = 10 ; static std::string CAM_CORR = "Corr" ; static std::string CAM_TDIR = "TDir" ; static std::string CAM_CDIR = "CDir" ; @@ -33,6 +33,14 @@ static std::string CAM_FLAG = "Flg" ; static std::string CAM_AXSTS = "AxS" ; static std::string CAM_AXMSK = "AxM" ; static std::string CAM_AXVAL = "AxV" ; +static int CAM_PARAM_V2 = 16 ; +static std::string CAM_MOVE = "Move" ; +static std::string CAM_PCEN = "PCen" ; +static std::string CAM_ACEN = "ACen" ; +static std::string CAM_AXMC = "AxMC" ; +static std::string CAM_AXMR = "AxMR" ; +static std::string CAM_AXAC = "AxAC" ; +static int CAM_TOTPARAM =CAM_PARAM_V2 ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkCamData", CamData) ; @@ -55,16 +63,20 @@ CamData::Clone( void) const try { pCam->m_nOwnerId = GDB_ID_NULL ; pCam->m_pGeomDB = nullptr ; + pCam->m_nMove = m_nMove ; pCam->m_nCorre = m_nCorre ; pCam->m_vtTool = m_vtTool ; pCam->m_vtCorr = m_vtCorr ; pCam->m_vtAux = m_vtAux ; - pCam->m_ptBase = m_ptBase ; + pCam->m_ptEnd = m_ptEnd ; + pCam->m_ptCen = m_ptCen ; + pCam->m_dAngCen = m_dAngCen ; pCam->m_dFeed = m_dFeed ; pCam->m_nFlag = m_nFlag ; pCam->m_nAxesStatus = m_nAxesStatus ; pCam->m_nAxesMask = m_nAxesMask ; pCam->m_vMachAxes = m_vMachAxes ; + pCam->m_ptMachCen = m_ptMachCen ; } catch( ...) { delete pCam ; @@ -80,16 +92,22 @@ bool CamData::Dump( string& sOut, bool bMM, const char* szNewLine) const { sOut += GetClassName() + "[mm]" + szNewLine ; + sOut += CAM_MOVE + "=" + ToString( m_nMove) + szNewLine ; sOut += CAM_CORR + "=" + ToString( m_nCorre) + szNewLine ; sOut += CAM_TDIR + "=" + ToString( m_vtTool) + szNewLine ; sOut += CAM_CDIR + "=" + ToString( m_vtCorr) + szNewLine ; sOut += CAM_ADIR + "=" + ToString( m_vtAux) + szNewLine ; - sOut += CAM_PBAS + "=" + ToString( m_ptBase) + szNewLine ; + sOut += CAM_PBAS + "=" + ToString( m_ptEnd) + szNewLine ; + sOut += CAM_PCEN + "=" + ToString( m_ptCen) + szNewLine ; + sOut += CAM_ACEN + "=" + ToString( m_dAngCen) + szNewLine ; sOut += CAM_FEED + "=" + ToString( m_dFeed) + szNewLine ; sOut += CAM_FLAG + "=" + ToString( m_nFlag) + szNewLine ; sOut += CAM_AXSTS + "=" + ToString( m_nAxesStatus) + szNewLine ; sOut += CAM_AXMSK + "=" + ToString( m_nAxesMask) + szNewLine ; sOut += CAM_AXVAL + "=" + ToString( m_vMachAxes) + szNewLine ; + sOut += CAM_AXMC + "=" + ToString( m_ptMachCen) + szNewLine ; + sOut += CAM_AXMR + "=" + ToString( m_dMachRad) + szNewLine ; + sOut += CAM_AXAC + "=" + ToString( m_dMachAngCen) + szNewLine ; return true ; } @@ -128,12 +146,19 @@ CamData::Save( STRVECTOR& vString) const vString[++k] = CAM_TDIR + "=" + ToString( m_vtTool) ; vString[++k] = CAM_CDIR + "=" + ToString( m_vtCorr) ; vString[++k] = CAM_ADIR + "=" + ToString( m_vtAux) ; - vString[++k] = CAM_PBAS + "=" + ToString( m_ptBase) ; + vString[++k] = CAM_PBAS + "=" + ToString( m_ptEnd) ; vString[++k] = CAM_FEED + "=" + ToString( m_dFeed) ; vString[++k] = CAM_FLAG + "=" + ToString( m_nFlag) ; vString[++k] = CAM_AXSTS + "=" + ToString( m_nAxesStatus) ; vString[++k] = CAM_AXMSK + "=" + ToString( m_nAxesMask) ; vString[++k] = CAM_AXVAL + "=" + ToString( m_vMachAxes) ; + // parametri aggiunti V2 + vString[++k] = CAM_MOVE + "=" + ToString( m_nMove) ; + vString[++k] = CAM_PCEN + "=" + ToString( m_ptCen) ; + vString[++k] = CAM_ACEN + "=" + ToString( m_dAngCen) ; + vString[++k] = CAM_AXMC + "=" + ToString( m_ptMachCen) ; + vString[++k] = CAM_AXMR + "=" + ToString( m_dMachRad) ; + vString[++k] = CAM_AXAC + "=" + ToString( m_dMachAngCen) ; } catch( ...) { return false ; @@ -145,20 +170,38 @@ CamData::Save( STRVECTOR& vString) const bool CamData::Load( const STRVECTOR& vString) { - if ( int( vString.size()) < CAM_TOTPARAM) + if ( int( vString.size()) < CAM_PARAM_V1) return false ; int k = - 1 ; if ( ! GetVal( vString[++k], CAM_CORR, m_nCorre) || ! GetVal( vString[++k], CAM_TDIR, m_vtTool) || ! GetVal( vString[++k], CAM_CDIR, m_vtCorr) || ! GetVal( vString[++k], CAM_ADIR, m_vtAux) || - ! GetVal( vString[++k], CAM_PBAS, m_ptBase) || + ! GetVal( vString[++k], CAM_PBAS, m_ptEnd) || ! GetVal( vString[++k], CAM_FEED, m_dFeed) || ! GetVal( vString[++k], CAM_FLAG, m_nFlag) || ! GetVal( vString[++k], CAM_AXSTS, m_nAxesStatus) || ! GetVal( vString[++k], CAM_AXMSK, m_nAxesMask) || ! GetVal( vString[++k], CAM_AXVAL, m_vMachAxes)) return false ; + // parametri aggiunti V2 + if ( int( vString.size()) >= CAM_PARAM_V2) { + if ( ! GetVal( vString[++k], CAM_MOVE, m_nMove) || + ! GetVal( vString[++k], CAM_PCEN, m_ptCen) || + ! GetVal( vString[++k], CAM_ACEN, m_dAngCen) || + ! GetVal( vString[++k], CAM_AXMC, m_ptMachCen) || + ! GetVal( vString[++k], CAM_AXMR, m_dMachRad) || + ! GetVal( vString[++k], CAM_AXAC, m_dMachAngCen)) + return false ; + } + else { + m_nMove = ( m_dFeed < EPS_SMALL ? 0 : 1) ; + m_ptCen = ORIG ; + m_dAngCen = 0 ; + m_ptMachCen = ORIG ; + m_dMachRad = 0 ; + } + return true ; } @@ -177,8 +220,8 @@ CamData::GetDrawPolyLines( POLYLINELIST& lstPL) const const double TLEN = 40 ; const double ALEN = 4 ; // inserisco disegno nella polilinea - PL.AddUPoint( 0, m_ptBase) ; - Point3d ptTip = m_ptBase + m_vtTool * TLEN ; + PL.AddUPoint( 0, m_ptEnd) ; + Point3d ptTip = m_ptEnd + m_vtTool * TLEN ; PL.AddUPoint( 1, ptTip) ; // aggiungo simil-freccia Frame3d frF ; @@ -208,8 +251,8 @@ CamData::GetDrawPolyLines( POLYLINELIST& lstPL) const const double CLEN = 20 ; const double ALEN = 2 ; // inserisco disegno nella polilinea - PL.AddUPoint( 0, m_ptBase) ; - Point3d ptTip = m_ptBase + m_vtCorr * CLEN ; + PL.AddUPoint( 0, m_ptEnd) ; + Point3d ptTip = m_ptEnd + m_vtCorr * CLEN ; PL.AddUPoint( 1, ptTip) ; // aggiungo simil-freccia Frame3d frF ; @@ -237,8 +280,8 @@ CamData::GetDrawPolyLines( POLYLINELIST& lstPL) const const double CLEN = 20 ; const double ALEN = 2 ; // inserisco disegno nella polilinea - PL.AddUPoint( 0, m_ptBase) ; - Point3d ptTip = m_ptBase + m_vtAux * CLEN ; + PL.AddUPoint( 0, m_ptEnd) ; + Point3d ptTip = m_ptEnd + m_vtAux * CLEN ; PL.AddUPoint( 1, ptTip) ; // aggiungo simil-freccia Frame3d frF ; @@ -261,7 +304,8 @@ CamData::GetDrawPolyLines( POLYLINELIST& lstPL) const bool CamData::Translate( const Vector3d& vtMove) { - m_ptBase.Translate( vtMove) ; + m_ptEnd.Translate( vtMove) ; + m_ptCen.Translate( vtMove) ; return true ; } @@ -269,7 +313,9 @@ CamData::Translate( const Vector3d& vtMove) bool CamData::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { - if ( ! m_ptBase.Rotate( ptAx, vtAx, dCosAng, dSinAng)) + if ( ! m_ptEnd.Rotate( ptAx, vtAx, dCosAng, dSinAng)) + return false ; + if ( ! m_ptCen.Rotate( ptAx, vtAx, dCosAng, dSinAng)) return false ; if ( ! m_vtTool.Rotate( vtAx, dCosAng, dSinAng)) return false ; @@ -284,7 +330,9 @@ CamData::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub bool CamData::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { - if ( ! m_ptBase.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) + if ( ! m_ptEnd.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) + return false ; + if ( ! m_ptCen.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) return false ; if ( ! m_vtTool.IsSmall()) { if ( ! m_vtTool.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) || ! m_vtTool.Normalize()) @@ -307,8 +355,11 @@ CamData::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCo bool CamData::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) { - if ( ! m_ptBase.Mirror( ptOn, vtNorm)) + if ( ! m_ptEnd.Mirror( ptOn, vtNorm)) return false ; + if ( ! m_ptCen.Mirror( ptOn, vtNorm)) + return false ; + m_dAngCen = - m_dAngCen ; if ( ! m_vtTool.Mirror( vtNorm)) return false ; if ( ! m_vtCorr.Mirror( vtNorm)) @@ -322,7 +373,9 @@ CamData::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) bool CamData::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { - if ( ! m_ptBase.Shear( ptOn, vtNorm, vtDir, dCoeff)) + if ( ! m_ptEnd.Shear( ptOn, vtNorm, vtDir, dCoeff)) + return false ; + if ( ! m_ptCen.Shear( ptOn, vtNorm, vtDir, dCoeff)) return false ; if ( ! m_vtTool.IsSmall()) { if ( ! m_vtTool.Shear( vtNorm, vtDir, dCoeff) || ! m_vtTool.Normalize()) @@ -345,7 +398,9 @@ CamData::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD bool CamData::ToGlob( const Frame3d& frRef) { - if ( ! m_ptBase.ToGlob( frRef)) + if ( ! m_ptEnd.ToGlob( frRef)) + return false ; + if ( ! m_ptCen.ToGlob( frRef)) return false ; if ( ! m_vtTool.ToGlob( frRef)) return false ; @@ -360,7 +415,9 @@ CamData::ToGlob( const Frame3d& frRef) bool CamData::ToLoc( const Frame3d& frRef) { - if ( ! m_ptBase.ToLoc( frRef)) + if ( ! m_ptEnd.ToLoc( frRef)) + return false ; + if ( ! m_ptCen.ToLoc( frRef)) return false ; if ( ! m_vtTool.ToLoc( frRef)) return false ; @@ -375,7 +432,9 @@ CamData::ToLoc( const Frame3d& frRef) bool CamData::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) { - if ( ! m_ptBase.LocToLoc( frOri, frDest)) + if ( ! m_ptEnd.LocToLoc( frOri, frDest)) + return false ; + if ( ! m_ptCen.LocToLoc( frOri, frDest)) return false ; if ( ! m_vtTool.LocToLoc( frOri, frDest)) return false ; @@ -392,12 +451,24 @@ CamData::CamData( void) { m_nOwnerId = GDB_ID_NULL ; m_pGeomDB = nullptr ; + m_nMove = 0 ; m_nCorre = 0 ; + m_dAngCen = 0 ; m_dFeed = 0 ; m_nFlag = 0 ; m_nAxesStatus = AS_NONE ; m_nAxesMask = 0x00 ; m_vMachAxes.reserve( 8) ; + m_dMachRad = 0 ; +} + +//---------------------------------------------------------------------------- +bool +CamData::SetMoveType( int nMove) +{ + m_nMove = nMove ; + ResetObjGraphics() ; + return true ; } //---------------------------------------------------------------------------- @@ -429,13 +500,30 @@ CamData::SetAuxDir( const Vector3d& vtDir) //---------------------------------------------------------------------------- bool -CamData::SetBasePoint( const Point3d& ptBase) +CamData::SetEndPoint( const Point3d& ptEnd) { - m_ptBase = ptBase ; + m_ptEnd = ptEnd ; ResetObjGraphics() ; return true ; } +//---------------------------------------------------------------------------- +bool +CamData::SetCenter( const Point3d& ptCen) +{ + m_ptCen = ptCen ; + ResetObjGraphics() ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CamData::SetAngCen( double dAngCen) +{ + m_dAngCen = dAngCen ; + ResetObjGraphics() ; + return true ; +} //---------------------------------------------------------------------------- bool CamData::SetFeed( double dFeed) @@ -472,6 +560,36 @@ CamData::ChangeAxesMask( int nMask) return true ; } +//---------------------------------------------------------------------------- +bool +CamData::SetAxesCen( const Point3d ptAxCen) +{ + if ( ! IsArc()) + return false ; + m_ptMachCen = ptAxCen ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CamData::SetAxesRad( double dRad) +{ + if ( ! IsArc()) + return false ; + m_dMachRad = dRad ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CamData::SetAxesAngCen( double dAngCen) +{ + if ( ! IsArc()) + return false ; + m_dMachAngCen = dAngCen ; + return true ; +} + //---------------------------------------------------------------------------- void CamData::ResetObjGraphics( void) diff --git a/CamData.h b/CamData.h index cacb4c7..4c8e0ef 100644 --- a/CamData.h +++ b/CamData.h @@ -45,24 +45,38 @@ class CamData : public IUserObj public : CamData( void) ; + bool SetMoveType( int nMove) ; bool SetToolDir( const Vector3d& vtDir) ; bool SetCorrDir( const Vector3d& vtDir) ; bool SetAuxDir( const Vector3d& vtDir) ; - bool SetBasePoint( const Point3d& ptBase) ; + bool SetEndPoint( const Point3d& ptEnd) ; + bool SetCenter( const Point3d& ptCen) ; + bool SetAngCen( double dAngCen) ; bool SetFeed( double dFeed) ; bool SetFlag( int nFlag) ; bool SetAxes( int nStatus, const DBLVECTOR& vAxVal) ; bool ChangeAxesMask( int nMask) ; bool ResetAxes( void) { m_nAxesStatus = AS_NONE ; return true ; } + bool SetAxesCen( const Point3d ptAxCen) ; + bool SetAxesRad( double dRad) ; + bool SetAxesAngCen( double dAngCen) ; + const int GetMoveType( void) const + { return m_nMove ; } + const bool IsArc( void) const + { return ( m_nMove == 2 || m_nMove == 3) ; } const Vector3d& GetToolDir( void) const { return m_vtTool ; } const Vector3d& GetCorrDir( void) const { return m_vtCorr ; } const Vector3d& GetAuxDir( void) const { return m_vtAux ; } - const Point3d& GetBasePoint( void) const - { return m_ptBase ; } + const Point3d& GetEndPoint( void) const + { return m_ptEnd ; } + const Point3d& GetCenter( void) const + { return m_ptCen ; } + double GetAngCen( void) const + { return m_dAngCen ; } double GetFeed( void) const { return m_dFeed ; } int GetFlag( void) const @@ -71,8 +85,14 @@ class CamData : public IUserObj { return m_nAxesStatus ; } int GetAxesMask( void) const { return m_nAxesMask ; } - const DBLVECTOR& GetAxisVal( void) const + const DBLVECTOR& GetAxesVal( void) const { return m_vMachAxes ; } + const Point3d& GetAxesCen( void) const + { return m_ptMachCen ; } + const double GetAxesRad( void) const + { return m_dMachRad ; } + const double GetAxesAngCen( void) const + { return m_dMachAngCen ; } public : enum { AS_NONE = 0, @@ -92,16 +112,22 @@ class CamData : public IUserObj private : int m_nOwnerId ; IGeomDB* m_pGeomDB ; + int m_nMove ; // tipo movimento (0=rapido, 1=lineare, 2=arco CW, 3=arco CCW) int m_nCorre ; // tipo correzione (0, 41, 42, 141, 142, 40) Vector3d m_vtTool ; // versore fresa Vector3d m_vtCorr ; // versore correzione Vector3d m_vtAux ; // versore ausiliario - Point3d m_ptBase ; // punto base per il disegno dei vettori + Point3d m_ptEnd ; // punto finale + Point3d m_ptCen ; // centro per archi + double m_dAngCen ; // angolo al centro per archi double m_dFeed ; // velocità di avanzamento in lavorazione int m_nFlag ; // flag per usi vari int m_nAxesStatus ; // stato dei valori degli assi int m_nAxesMask ; // mask di emissione degli assi (bit a bit) DBLVECTOR m_vMachAxes ; // valori degli assi macchina + Point3d m_ptMachCen ; // centro arco espresso in assi macchina + double m_dMachRad ; // raggio arco espresso in macchina + double m_dMachAngCen ; // angolo al centro per archi espresso in macchina } ; diff --git a/Drilling.cpp b/Drilling.cpp index 7966471..50c36bc 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -1309,7 +1309,7 @@ Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId) //---------------------------------------------------------------------------- bool -Drilling::AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) +Drilling::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) { // non devo fare alcunché return true ; diff --git a/Drilling.h b/Drilling.h index b37d457..da25155 100644 --- a/Drilling.h +++ b/Drilling.h @@ -47,7 +47,7 @@ class Drilling : public Machining bool GetParam( int nType, std::string& sVal) const override ; const ToolData& GetToolData( void) const override ; bool GetGeometry( SELVECTOR& vIds) const override ; - bool AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) override ; + bool AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) override ; bool IsEmpty( void) const override { return ( m_nDrillings == 0) ; } diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 073f58c..a6857b7 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/Generator.cpp b/Generator.cpp index 277ed67..39c412e 100644 --- a/Generator.cpp +++ b/Generator.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2016 //---------------------------------------------------------------------------- -// File : Generator.cpp Data : 28.10.15 Versione : 1.6j4 +// File : Generator.cpp Data : 26.02.16 Versione : 1.6n8 // Contenuto : Implementazione della classe generator. // // // // Modifiche : 28.10.15 DS Creazione modulo. -// +// 26.02.16 DS Aggiunta gestione archi. // //---------------------------------------------------------------------------- @@ -37,9 +37,9 @@ static const string GVAR_NUMTOK = ".Nt" ; // (string) token per numer static const string GVAR_LINENBR = ".LINENBR" ; // (int) numero progressivo di linea static const string GVAR_LINEINC = ".LINEINC" ; // (int) incremento per numero di linea static const string GVAR_F = ".F" ; // (num) valore della feed -static const string GVAR_FTOK = ".Ft" ; // (string) token per feed +static const string GVAR_FT = ".Ft" ; // (string) token per feed static const string GVAR_S = ".S" ; // (num) valore della speed -static const string GVAR_STOK = ".St" ; // (string) token per speed +static const string GVAR_ST = ".St" ; // (string) token per speed static const string GVAR_FILE = ".FILE" ; // (string) path file di output static const string GVAR_INFO = ".INFO" ; // (string) informazioni iniziali static const string GVAR_DISPID = ".DISPID" ; // (int) identificativo disposizione @@ -61,11 +61,17 @@ static const string GVAR_MCHID = ".MCHID" ; // (int) identificativo static const string GVAR_MCHIND = ".MCHIND" ; // (int) indice lavorazione static const string GVAR_PATHID = ".PATHID" ; // (int) identificativo percorso di lavorazione static const string GVAR_PATHIND = ".PATHIND" ; // (int) indice percorso di lavorazione +static const string GVAR_MOVE = ".MOVE" ; // (int) tipo di movimento (0,1,2,3) static const string GVAR_L1 = ".L1" ; // (num) valore del primo asse lineare static const string GVAR_L2 = ".L2" ; // (num) valore del secondo asse lineare static const string GVAR_L3 = ".L3" ; // (num) valore del terzo asse lineare static const string GVAR_R1 = ".R1" ; // (num) valore del primo asse rotante static const string GVAR_R2 = ".R2" ; // (num) valore del secondo asse rotante +static const string GVAR_C1 = ".C1" ; // (num) valore del primo asse lineare per centro arco +static const string GVAR_C2 = ".C2" ; // (num) valore del secondo asse lineare per centro arco +static const string GVAR_C3 = ".C3" ; // (num) valore del terzo asse lineare per centro arco +static const string GVAR_RR = ".RR" ; // (num) valore raggio per arco +static const string GVAR_AC = ".AC" ; // (num) valore angolo al centro per arco static const string GVAR_L1P = ".L1p" ; // (num) valore precedente del primo asse lineare static const string GVAR_L2P = ".L2p" ; // (num) valore precedente del secondo asse lineare static const string GVAR_L3P = ".L3p" ; // (num) valore precedente del terzo asse lineare @@ -76,6 +82,10 @@ static const string GVAR_L2T = ".L2t" ; // (num) token del secon static const string GVAR_L3T = ".L3t" ; // (num) token del terzo asse lineare static const string GVAR_R1T = ".R1t" ; // (num) token del primo asse rotante static const string GVAR_R2T = ".R2t" ; // (num) token del secondo asse rotante +static const string GVAR_C1T = ".C1t" ; // (num) token del primo asse lineare per centro arco +static const string GVAR_C2T = ".C2t" ; // (num) token del secondo asse lineare per centro arco +static const string GVAR_C3T = ".C3t" ; // (num) token del terzo asse lineare per centro arco +static const string GVAR_RRT = ".RRt" ; // (num) token del raggio per arco static const string GVAR_MASK = ".MASK" ; // (int) mask associato ai movimenti in rapido static const string GVAR_FLAG = ".FLAG" ; // (int) flag associato ad ogni movimento static const string TEMP_VAR = "LOC" ; // tavola variabili locali (temporanee) @@ -367,17 +377,24 @@ Generator::ProcessClEnt( int nEntId, int nEntInd, int nClPathId, int nClPathInd, CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nEntId)) ; if ( pCamData == nullptr || pCamData->GetAxesStatus() != CamData::AS_OK) return false ; - const DBLVECTOR& AxesEnd = pCamData->GetAxisVal() ; - // Verifico se movimento in rapido - bool bRapid = ( pCamData->GetFeed() < EPS_SMALL) ; + const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ; // Emetto movimento - if ( bRapid) { - if ( ! OnRapid( AxesEnd, pCamData->GetAxesMask(), pCamData->GetFlag())) + int nMove = pCamData->GetMoveType() ; + switch ( nMove) { + case 0 : // rapido + if ( ! OnRapid( nMove, AxesEnd, pCamData->GetAxesMask(), pCamData->GetFlag())) return false ; - } - else { - if ( ! OnLinear( AxesEnd, pCamData->GetFeed(), pCamData->GetFlag())) + break ; + case 1 : // linea + if ( ! OnLinear( nMove, AxesEnd, pCamData->GetFeed(), pCamData->GetFlag())) return false ; + break ; + case 2 : // arco CW + case 3 : // arco CCW + if ( ! OnArc( nMove, AxesEnd, pCamData->GetAxesCen(), pCamData->GetAxesRad(), pCamData->GetAxesAngCen(), + pCamData->GetFeed(), pCamData->GetFlag())) + return false ; + break ; } return true ; @@ -427,8 +444,12 @@ Generator::OnStart( void) bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NUMTOK, "N") ; bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_LINENBR, 0) ; bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_LINEINC, 1) ; - bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FTOK, "F") ; - bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_STOK, "S") ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_C1T, "I") ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_C2T, "J") ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_C3T, "K") ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_RRT, "R") ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FT, "F") ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ST, "S") ; // chiamo la funzione bOk = bOk && m_pMachine->LuaCallFunction( ON_START) ; // cancello variabili locali @@ -663,10 +684,14 @@ Generator::OnPathEnd( void) //---------------------------------------------------------------------------- bool -Generator::OnRapid( const DBLVECTOR& AxesEnd, int nAxesMask, int nFlag) +Generator::OnRapid( int nMove, const DBLVECTOR& AxesEnd, int nAxesMask, int nFlag) { + // cancello variabili estranee + ResetArcData() ; // definisco tavola variabili locali (temporanee) bool bOk = m_pMachine->LuaCreateGlobTable( TEMP_VAR) ; + // assegno il tipo di movimento + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, nMove) ; // assegno il valore degli assi int nNumAxes = int( AxesEnd.size()) ; for ( int i = 1 ; i <= MAX_AXES ; ++ i) { @@ -688,10 +713,14 @@ Generator::OnRapid( const DBLVECTOR& AxesEnd, int nAxesMask, int nFlag) //---------------------------------------------------------------------------- bool -Generator::OnLinear( const DBLVECTOR& AxesEnd, double dFeed, int nFlag) +Generator::OnLinear( int nMove, const DBLVECTOR& AxesEnd, double dFeed, int nFlag) { + // cancello variabili estranee + ResetArcData() ; // definisco tavola variabili locali (temporanee) bool bOk = m_pMachine->LuaCreateGlobTable( TEMP_VAR) ; + // assegno il tipo di movimento + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, nMove) ; // assegno il valore degli assi int nNumAxes = int( AxesEnd.size()) ; for ( int i = 1 ; i <= MAX_AXES ; ++ i) { @@ -711,6 +740,55 @@ Generator::OnLinear( const DBLVECTOR& AxesEnd, double dFeed, int nFlag) return bOk ; } +//---------------------------------------------------------------------------- +bool +Generator::OnArc( int nMove, const DBLVECTOR& AxesEnd, const Point3d& ptCen, double dRad, double dAngCen, + double dFeed, int nFlag) +{ + // definisco tavola variabili locali (temporanee) + bool bOk = m_pMachine->LuaCreateGlobTable( TEMP_VAR) ; + // assegno il tipo di movimento + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, nMove) ; + // assegno il valore degli assi + int nNumAxes = int( AxesEnd.size()) ; + for ( int i = 1 ; i <= MAX_AXES ; ++ i) { + if ( i <= nNumAxes) + bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisValue(i), AxesEnd[i-1]) ; + else + bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisValue(i)) ; + } + // assegno le coordinate del centro + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_C1, ptCen.x) ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_C2, ptCen.y) ; + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_C3, ptCen.z) ; + // assegno il valore del raggio + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_RR, dRad) ; + // assegno il valore dell'angolo al centro + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AC, dAngCen) ; + // assegno il valore della feed + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_F, dFeed) ; + // assegno il valore del flag + bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG, nFlag) ; + // chiamo la funzione di movimento in rapido + bOk = bOk && m_pMachine->LuaCallFunction( ON_ARC) ; + // cancello variabili locali + bOk = bOk && m_pMachine->LuaResetGlobVar( TEMP_VAR) ; + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +Generator::ResetArcData( void) +{ + // reset dati arco + bool bOk = m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_C1) ; + bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_C2) ; + bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_C3) ; + bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_RR) ; + bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_AC) ; + return bOk ; +} + //---------------------------------------------------------------------------- string Generator::GetGlobVarAxisValue( int nAx) diff --git a/Generator.h b/Generator.h index 1243802..53c793b 100644 --- a/Generator.h +++ b/Generator.h @@ -51,8 +51,11 @@ class Generator bool OnMachiningEnd( void) ; bool OnPathStart( int nClPathId, int nClPathInd) ; bool OnPathEnd( void) ; - bool OnRapid( const DBLVECTOR& AxesEnd, int nAxesMask, int nFlag) ; - bool OnLinear( const DBLVECTOR& AxesEnd, double dFeed, int nFlag) ; + bool OnRapid( int nMove, const DBLVECTOR& AxesEnd, int nAxesMask, int nFlag) ; + bool OnLinear( int nMove, const DBLVECTOR& AxesEnd, double dFeed, int nFlag) ; + bool OnArc( int nMove, const DBLVECTOR& AxesEnd, const Point3d& ptCen, double dRad, double dAngCen, + double dFeed, int nFlag) ; + bool ResetArcData( void) ; std::string GetGlobVarAxisValue( int nAx) ; std::string GetGlobVarAxisPrev( int nAx) ; std::string GetGlobVarAxisToken( int nAx) ; diff --git a/MachMgrDBMachinings.cpp b/MachMgrDBMachinings.cpp index 407f7c9..ef07701 100644 --- a/MachMgrDBMachinings.cpp +++ b/MachMgrDBMachinings.cpp @@ -278,6 +278,8 @@ MachMgr::MdbSetGeneralParam( int nType, double dVal) return pMsMgr->SetExtraROnDrillRegion( dVal) ; case MGP_HOLEDIAMTOLER : return pMsMgr->SetHoleDiamToler( dVal) ; + case MGP_EXTSAWARCMINRAD : + return pMsMgr->SetExtSawArcMinRad( dVal) ; } return false ; } @@ -304,6 +306,9 @@ MachMgr::MdbGetGeneralParam( int nType, double& dVal) const case MGP_HOLEDIAMTOLER : dVal = pMsMgr->GetHoleDiamToler() ; return true ; + case MGP_EXTSAWARCMINRAD : + dVal = pMsMgr->GetExtSawArcMinRad() ; + return true ; } return false ; } diff --git a/Machining.cpp b/Machining.cpp index 7fe8377..de95087 100644 --- a/Machining.cpp +++ b/Machining.cpp @@ -18,8 +18,10 @@ #include "Machining.h" #include "MachiningConst.h" #include "CamData.h" +#include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveLine.h" +#include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EgkDistPointCurve.h" #include "/EgtDev/Include/EgkIntersCurves.h" #include "/EgtDev/Include/EGkIntersLineSurfTm.h" @@ -75,7 +77,8 @@ Machining::Machining( void) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool -Machining::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dElev) +Machining::GetElevation( int nPhase, const Point3d& ptP, + const Vector3d& vtDir, double& dElev) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -131,7 +134,8 @@ Machining::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtDir, //---------------------------------------------------------------------------- bool -Machining::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtDir, double& dElev) +Machining::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, + const Vector3d& vtDir, double& dElev) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -206,6 +210,23 @@ Machining::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, c return bFound ; } +//---------------------------------------------------------------------------- +bool +Machining::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3, + const Vector3d& vtDir, double& dElev) +{ + if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) + return false ; + // approssimo l'arco con due linee + double dElev1, dElev2 ; + if ( ! GetElevation( nPhase, ptP1, ptP2, vtDir, dElev1)) + return false ; + if ( ! GetElevation( nPhase, ptP2, ptP3, vtDir, dElev2)) + return false ; + dElev = max( dElev1, dElev2) ; + return true ; +} + //---------------------------------------------------------------------------- bool Machining::GetDistanceFromRawSide( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist) @@ -377,10 +398,11 @@ Machining::AddRapidStart( const Point3d& ptP) if ( IsNull( pCam)) return GDB_ID_NULL ; // assegno valori + pCam->SetMoveType( 0) ; pCam->SetToolDir( m_vtTool) ; pCam->SetCorrDir( m_vtCorr) ; pCam->SetAuxDir( m_vtAux) ; - pCam->SetBasePoint( ptP) ; + pCam->SetEndPoint( ptP) ; pCam->SetFeed( 0) ; pCam->SetFlag( m_nFlag) ; // associo questo oggetto a quello geometrico @@ -416,10 +438,11 @@ Machining::AddRapidMove( const Point3d& ptP) if ( IsNull( pCam)) return GDB_ID_NULL ; // assegno valori + pCam->SetMoveType( 0) ; pCam->SetToolDir( m_vtTool) ; pCam->SetCorrDir( m_vtCorr) ; pCam->SetAuxDir( m_vtAux) ; - pCam->SetBasePoint( ptP) ; + pCam->SetEndPoint( ptP) ; pCam->SetFeed( 0) ; pCam->SetFlag( m_nFlag) ; // associo questo oggetto a quello geometrico @@ -461,10 +484,63 @@ Machining::AddLinearMove( const Point3d& ptP) if ( IsNull( pCam)) return GDB_ID_NULL ; // assegno valori + pCam->SetMoveType( 1) ; pCam->SetToolDir( m_vtTool) ; pCam->SetCorrDir( m_vtCorr) ; pCam->SetAuxDir( m_vtAux) ; - pCam->SetBasePoint( ptP) ; + pCam->SetEndPoint( ptP) ; + pCam->SetFeed( m_dFeed) ; + pCam->SetFlag( m_nFlag) ; + // associo questo oggetto a quello geometrico + m_pGeomDB->SetUserObj( nId, Release( pCam)) ; + // salvo la posizione corrente + m_ptCurr = ptP ; + return nId ; +} + +//---------------------------------------------------------------------------- +int +Machining::AddArcMove( const Point3d& ptP, const Point3d& ptCen, double dAngCen, double dDeltaZ) +{ + if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) + return GDB_ID_NULL ; + // verifico di essere in uno stato valido per un movimento arco + if ( ! m_bCurr || m_vtTool.IsSmall()) { + LOG_INFO( GetEMkLogger(), "Error on ArcMove : Curr or ToolDir") + return GDB_ID_NULL ; + } + // se feed nulla, assegno il minimo e lo segnalo + if ( m_dFeed < FEED_MIN) { + m_dFeed = FEED_MIN ; + LOG_INFO( GetEMkLogger(), "Error on ArcMove : Min Feed") + } + // creo oggetto arco per DB geometrico + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc)) + return GDB_ID_NULL ; + // assegno i dati dell'arco + if ( ! pArc->SetCPA( ptCen, m_ptCurr, dAngCen, dDeltaZ)) + return GDB_ID_NULL ; + Point3d ptFin ; + if ( ! pArc->GetEndPoint( ptFin) || ! AreSamePointApprox( ptFin, ptP)) + return GDB_ID_NULL ; + int nMove = ( dAngCen > 0 ? 3 : 2) ; + // inserisco l'oggetto nel DB geometrico + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPathId, Release( pArc)) ; + if ( nId == GDB_ID_NULL) + return GDB_ID_NULL ; + // creo oggetto dati Cam + PtrOwner pCam( new( nothrow) CamData) ; + if ( IsNull( pCam)) + return GDB_ID_NULL ; + // assegno valori + pCam->SetMoveType( nMove) ; + pCam->SetToolDir( m_vtTool) ; + pCam->SetCorrDir( m_vtCorr) ; + pCam->SetAuxDir( m_vtAux) ; + pCam->SetEndPoint( ptP) ; + pCam->SetCenter( ptCen) ; + pCam->SetAngCen( dAngCen) ; pCam->SetFeed( m_dFeed) ; pCam->SetFlag( m_nFlag) ; // associo questo oggetto a quello geometrico @@ -518,7 +594,7 @@ Machining::GetClPathInitialAxesValues( int nClPathId, DBLVECTOR& vAxVal) if ( pCamData == nullptr) return false ; // assegno i valori degli assi - vAxVal = pCamData->GetAxisVal() ; + vAxVal = pCamData->GetAxesVal() ; return ( vAxVal.size() > 0) ; } @@ -551,7 +627,7 @@ Machining::GetClPathFinalAxesValues( int nClPathId, DBLVECTOR& vAxVal) if ( pCamData == nullptr) return false ; // assegno i valori degli assi - vAxVal = pCamData->GetAxisVal() ; + vAxVal = pCamData->GetAxesVal() ; return ( vAxVal.size() > 0) ; } @@ -622,8 +698,20 @@ Machining::CalculateAxesValues( void) bool bOk = true ; int nClPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; while ( nClPathId != GDB_ID_NULL) { - if ( ! CalculateClPathAxesValues( nClPathId, nLinAxes, nRotAxes, dRot1W, dAngAprec, dAngBprec)) - bOk = false ; + double dAngAprecOri = dAngAprec ; + double dAngBprecOri = dAngBprec ; + int nOutStrC = 0 ; + if ( ! CalculateClPathAxesValues( nClPathId, nLinAxes, nRotAxes, dRot1W, dAngAprec, dAngBprec, nOutStrC)) { + // se extracorsa dell'asse C, provo a precaricarlo al contrario + if ( nOutStrC != 0) { + dAngAprec = dAngAprecOri + ( nOutStrC > 0 ? - ANG_FULL : ANG_FULL) ; + dAngBprec = dAngBprecOri ; + if ( ! CalculateClPathAxesValues( nClPathId, nLinAxes, nRotAxes, dRot1W, dAngAprec, dAngBprec, nOutStrC)) + bOk = false ; + } + else + bOk = false ; + } nClPathId = m_pGeomDB->GetNextGroup( nClPathId) ; } @@ -633,7 +721,7 @@ Machining::CalculateAxesValues( void) //---------------------------------------------------------------------------- bool Machining::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, double dRot1W, - double& dAngAprec, double& dAngBprec) + double& dAngAprec, double& dAngBprec, int& nOutStrC) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -641,15 +729,25 @@ Machining::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, // predispongo variabile per valori assi DBLVECTOR vAxVal ; vAxVal.reserve( 8) ; + // variabili per coordinate lineari precedenti + double dXprec, dYprec, dZprec ; // ciclo su tutte le entità del percorso CL + nOutStrC = 0 ; bool bOk = true ; + bool bFirst = true ; for ( int nEntId = m_pGeomDB->GetFirstInGroup( nClPathId) ; nEntId != GDB_ID_NULL ; - nEntId = m_pGeomDB->GetNext( nEntId)) { + nEntId = m_pGeomDB->GetNext( nEntId), bFirst = false) { // recupero i dati Cam dell'entità CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nEntId)) ; if ( pCamData == nullptr) continue ; + // verifico che il primo movimento non sia un arco + if ( bFirst && pCamData->IsArc()) { + pCamData->ResetAxes() ; + LOG_INFO( GetEMkLogger(), "Error : first move in ClPath is an arc") + return false ; + } // calcolo degli assi rotanti della macchina int nRStat ; double dAngA1, dAngB1, dAngA2, dAngB2 ; @@ -660,16 +758,35 @@ Machining::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, continue ; } if ( nRStat == 1) { - // porto gli angoli ai valori più vicini ai precedenti con offset di uno o più giri - m_pMchMgr->GetNearestAngleInStroke( 1, dAngAprec, dAngA1) ; - m_pMchMgr->GetNearestAngleInStroke( 2, dAngBprec, dAngB1) ; + // se primo movimento + if ( bFirst) { + // porto gli angoli ai valori più vicini ai precedenti con offset di uno o più giri + m_pMchMgr->GetNearestAngleInStroke( 1, dAngAprec, dAngA1) ; + m_pMchMgr->GetNearestAngleInStroke( 2, dAngBprec, dAngB1) ; + } + // per movimenti successivi + else { + // scelgo gli angoli più vicini, per continuità non applico offset per stare nelle corse + dAngA1 = AngleNearAngle( dAngA1, dAngAprec) ; + dAngB1 = AngleNearAngle( dAngB1, dAngBprec) ; + } } if ( nRStat == 2) { - // porto gli angoli ai valori più vicini ai precedenti con offset di uno o più giri - m_pMchMgr->GetNearestAngleInStroke( 1, dAngAprec, dAngA1) ; - m_pMchMgr->GetNearestAngleInStroke( 2, dAngBprec, dAngB1) ; - m_pMchMgr->GetNearestAngleInStroke( 1, dAngAprec, dAngA2) ; - m_pMchMgr->GetNearestAngleInStroke( 2, dAngBprec, dAngB2) ; + // se primo movimento + if ( bFirst) { + // porto gli angoli ai valori più vicini ai precedenti con offset di uno o più giri + m_pMchMgr->GetNearestAngleInStroke( 1, dAngAprec, dAngA1) ; + m_pMchMgr->GetNearestAngleInStroke( 2, dAngBprec, dAngB1) ; + m_pMchMgr->GetNearestAngleInStroke( 1, dAngAprec, dAngA2) ; + m_pMchMgr->GetNearestAngleInStroke( 2, dAngBprec, dAngB2) ; + } + else { + // scelgo gli angoli più vicini, per continuità non applico offset per stare nelle corse + dAngA1 = AngleNearAngle( dAngA1, dAngAprec) ; + dAngB1 = AngleNearAngle( dAngB1, dAngBprec) ; + dAngA2 = AngleNearAngle( dAngA2, dAngAprec) ; + dAngB2 = AngleNearAngle( dAngB2, dAngBprec) ; + } // scelgo la soluzione più vicina ai precedenti double dDeltaA1 = dRot1W * fabs( dAngA1 - dAngAprec) ; double dDeltaB1 = fabs( dAngB1 - dAngBprec) ; @@ -681,8 +798,8 @@ Machining::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, } } // ricavo posizione con eventuali modifiche dipendenti dalla lavorazione - Point3d ptP = pCamData->GetBasePoint() ; - AdjustPositionForAxesCalc( pCamData, ptP) ; + Point3d ptP = pCamData->GetEndPoint() ; + AdjustEndPointForAxesCalc( pCamData, ptP) ; // calcolo gli assi lineari della macchina int nLStat ; double dX, dY, dZ ; @@ -705,12 +822,94 @@ Machining::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, if ( ! bOsOk || nStat != 0) { bOk = false ; pCamData->SetAxes( CamData::AS_OUTSTROKE, vAxVal) ; + if ( nOutStrC == 0) { + if ( (nStat & 64) != 0) + nOutStrC = - 1 ; + else if ( (nStat & 128) != 0) + nOutStrC = 1 ; + } string sInfo = "Outstroke : " + m_pMchMgr->GetOutstrokeInfo() ; LOG_INFO( GetEMkLogger(), sInfo.c_str()) continue ; } // salvo i valori degli assi pCamData->SetAxes( CamData::AS_OK, vAxVal) ; + // se arco (per ora solo nel piano XY) devo calcolarne il centro in assi macchina + if ( pCamData->IsArc()) { + // ricavo punto medio + Point3d ptCen = pCamData->GetCenter() ; + double dAngCen = pCamData->GetAngCen() ; + Point3d ptMid = ptP ; + ptMid.Rotate( ptCen, Z_AX, - dAngCen / 2) ; + // determino i valori degli assi al punto medio + double dAngAmid = ( dAngAprec + dAngA1) / 2 ; + double dAngBmid = ( dAngBprec + dAngB1) / 2 ; + int nLmidStat ; + double dXmid, dYmid, dZmid ; + bool bLmidOk = m_pMchMgr->GetCalcPositions( ptMid, dAngAmid, dAngBmid, nLmidStat, dXmid, dYmid, dZmid) ; + if ( ! bLmidOk || nLmidStat != 0) { + bOk = false ; + pCamData->SetAxes( CamData::AS_ERR, vAxVal) ; + continue ; + } + // punti espressi in assi macchina + Point3d ptP1M( dXprec, dYprec, dZprec) ; + Point3d ptP2M( dXmid, dYmid, dZmid) ; + Point3d ptP3M( dX, dY, dZ) ; + // se coincidono + if ( AreSamePointApprox( ptP1M, ptP2M) && AreSamePointApprox( ptP1M, ptP3M)) { + // lo considero un arco di raggio nullo + pCamData->SetAxesCen( ptP2M) ; + pCamData->SetAxesRad( 0) ; + pCamData->SetAxesAngCen( 0) ; + // il movimento diventa lineare + pCamData->SetMoveType( 1) ; + // non è necessario verificare i limiti di corsa degli assi + } + // altrimenti calcolo l'arco cui appartengono + else { + // calcolo arco per i tre punti espressi in assi macchina + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc) || ! pArc->Set3P( ptP1M, ptP2M, ptP3M, false)) { + bOk = false ; + continue ; + } + // verifico il piano + if ( pArc->GetNormVersor().z < 0) + pArc->InvertN() ; + // assegno il centro e il raggio di questo arco ai dati cam + pCamData->SetAxesCen( pArc->GetCenter()) ; + pCamData->SetAxesRad( pArc->GetRadius()) ; + pCamData->SetAxesAngCen( pArc->GetAngCenter()) ; + // aggiorno il tipo di arco + pCamData->SetMoveType( pArc->GetAngCenter() > 0 ? 3 : 2) ; + // verifico i limiti di corsa dei punti lungo l'arco + const int NUM_VERIF_STEP = 16 ; + Point3d ptCen = pCamData->GetAxesCen() ; + double dAngCenStep = pCamData->GetAxesAngCen() / NUM_VERIF_STEP ; + Vector3d vtCurr = Point3d( dXprec, dYprec, dZprec) - ptCen ; + for ( int i = 1 ; i < NUM_VERIF_STEP ; ++ i) { + vtCurr.Rotate( Z_AX, dAngCenStep) ; + Point3d ptCurr = ptCen + vtCurr ; + double dCoeff = i / NUM_VERIF_STEP ; + double dAngA = dAngAprec * ( 1 - dCoeff) + dAngA1 * dCoeff ; + double dAngB = dAngBprec * ( 1 - dCoeff) + dAngB1 * dCoeff ; + int nStat ; + bool bOsOk = m_pMchMgr->VerifyOutstroke( ptCurr.x, ptCurr.y, ptCurr.z, dAngA, dAngB, nStat) ; + if ( ! bOsOk || nStat != 0) { + bOk = false ; + pCamData->SetAxes( CamData::AS_OUTSTROKE, vAxVal) ; + string sInfo = "Outstroke : " + m_pMchMgr->GetOutstrokeInfo() ; + LOG_INFO( GetEMkLogger(), sInfo.c_str()) + continue ; + } + } + } + } + // memorizzo i valori degli assi lineari come nuovi precedenti + dXprec = dX ; + dYprec = dY ; + dZprec = dZ ; // memorizzo i valori degli angoli come nuovi precedenti dAngAprec = dAngA1 ; dAngBprec = dAngB1 ; @@ -816,7 +1015,7 @@ Machining::AdjustOneStartMovement( int nClPathId, const DBLVECTOR& vAxPrev) return false ; // recupero i valori degli assi DBLVECTOR vAxCurr ; - vAxCurr = pCamData->GetAxisVal() ; + vAxCurr = pCamData->GetAxesVal() ; // se Z pressochè uguali non devo fare alcunché if ( fabs( vAxCurr[2] - vAxPrev[2]) < 10 * EPS_SMALL) return true ; @@ -892,7 +1091,7 @@ Machining::AddRise( DBLVECTOR& vAxVal, double dDelta) if ( IsNull( pGP)) return false ; // assegno le coordinate del punto - pGP->Set( pCamData->GetBasePoint()) ; + pGP->Set( pCamData->GetEndPoint()) ; // inserisco l'oggetto nel DB geometrico int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLastPxClId, Release( pGP)) ; if ( nId == GDB_ID_NULL) @@ -903,7 +1102,7 @@ Machining::AddRise( DBLVECTOR& vAxVal, double dDelta) if ( IsNull( pCam)) return false ; // recupero i valori degli assi - vAxVal = pCam->GetAxisVal() ; + vAxVal = pCam->GetAxesVal() ; // flag di movimento in rapido int nFlag = 0 ; // se delta positivo lo uso come incremento di Z @@ -989,7 +1188,7 @@ Machining::AddHome( void) if ( IsNull( pGP)) return false ; // assegno le coordinate del punto - pGP->Set( pCamData->GetBasePoint()) ; + pGP->Set( pCamData->GetEndPoint()) ; // inserisco l'oggetto nel DB geometrico int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLastPxClId, Release( pGP)) ; if ( nId == GDB_ID_NULL) diff --git a/Machining.h b/Machining.h index 6ffd40b..c42005c 100644 --- a/Machining.h +++ b/Machining.h @@ -51,15 +51,19 @@ class Machining : public IUserObj virtual bool GetParam( int nType, std::string& sVal) const = 0 ; virtual const ToolData& GetToolData( void) const = 0 ; virtual bool GetGeometry( SELVECTOR& vIds) const = 0 ; - virtual bool AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) = 0 ; + virtual bool AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) = 0 ; virtual bool IsEmpty( void) const = 0 ; protected : Machining( void) ; protected : - bool GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dElev) ; - bool GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtDir, double& dElev) ; + bool GetElevation( int nPhase, const Point3d& ptP, + const Vector3d& vtDir, double& dElev) ; + bool GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, + const Vector3d& vtDir, double& dElev) ; + bool GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3, + const Vector3d& vtDir, double& dElev) ; bool GetDistanceFromRawSide( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist) ; bool GetDistanceFromRawBottom( int nPhase, int nPathId, double dToler, double& dRbDist) ; bool GetInitialAxesValues( DBLVECTOR& vAxVal) ; @@ -68,7 +72,7 @@ class Machining : public IUserObj bool GetClPathFinalAxesValues( int nClPathId, DBLVECTOR& vAxVal) ; bool CalculateAxesValues( void) ; bool CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, double dRot1W, - double& dAngAprec, double& dAngBprec) ; + double& dAngAprec, double& dAngBprec, int& nOutStrC) ; bool AdjustStartEndMovements( void) ; bool AdjustOneStartMovement( int nClPathId, const DBLVECTOR& vAxPrev) ; bool ToolChangeNeeded( const ToolData& T1, const ToolData& T2) ; @@ -88,6 +92,7 @@ class Machining : public IUserObj int AddRapidStart( const Point3d& ptP) ; int AddRapidMove( const Point3d& ptP) ; int AddLinearMove( const Point3d& ptP) ; + int AddArcMove( const Point3d& ptP, const Point3d& ptCen, double dAngCen, double dDeltaZ = 0) ; bool ResetMoveData( void) ; protected : diff --git a/MachiningsMgr.cpp b/MachiningsMgr.cpp index dcdbc61..f2b8f3b 100644 --- a/MachiningsMgr.cpp +++ b/MachiningsMgr.cpp @@ -48,6 +48,8 @@ const string MF_EXTRARDR = "EXTRARDR" ; const double MF_CURR_EXTRARDR = 0 ; const string MF_HOLEDTOL = "HOLEDTOL" ; const double MF_CURR_HOLEDTOL = 10 * EPS_SMALL ; +const string MF_EXTSAWARCMINRAD = "EXTSAWARCMINRAD" ; +const double MF_CURR_EXTSAWARCMINRAD = 200 ; //---------------------------------------------------------------------------- @@ -62,6 +64,7 @@ MachiningsMgr::MachiningsMgr( void) m_b5AxComp = MF_CURR_5AXCOMP ; m_dExtraLOnCutRegion = MF_CURR_EXTRALCR ; m_dExtraROnDrillRegion = MF_CURR_EXTRARDR ; + m_dExtSawArcMinRad = MF_CURR_EXTSAWARCMINRAD ; } //---------------------------------------------------------------------------- @@ -243,6 +246,8 @@ MachiningsMgr::LoadGeneral( Scanner& TheScanner, bool& bEnd) bOk = FromString( sVal, m_dExtraROnDrillRegion) ; else if ( ToUpper( sKey) == MF_HOLEDTOL) bOk = FromString( sVal, m_dHoleDiamToler) ; + else if ( ToUpper( sKey) == MF_EXTSAWARCMINRAD) + bOk = FromString( sVal, m_dExtSawArcMinRad) ; else bOk = false ; } @@ -413,6 +418,8 @@ MachiningsMgr::SaveGeneral( Writer& TheWriter) const bOk = bOk && TheWriter.OutText( sOut) ; sOut = MF_HOLEDTOL + "=" + ToString( m_dHoleDiamToler) ; bOk = bOk && TheWriter.OutText( sOut) ; + sOut = MF_EXTSAWARCMINRAD + "=" + ToString( m_dExtSawArcMinRad) ; + return bOk ; } @@ -840,3 +847,18 @@ MachiningsMgr::SetHoleDiamToler( double dToler) } return true ; } + +//---------------------------------------------------------------------------- +bool +MachiningsMgr::SetExtSawArcMinRad( double dRad) +{ + // deve essere un valore positivo o nullo + if ( dRad < - EPS_SMALL) + return false ; + // se cambiato, salvo e setto modifica + if ( fabs( dRad - m_dExtSawArcMinRad) > EPS_SMALL) { + m_dExtSawArcMinRad = dRad ; + m_bModified = true ; + } + return true ; +} diff --git a/MachiningsMgr.h b/MachiningsMgr.h index 277c7e6..b42d53c 100644 --- a/MachiningsMgr.h +++ b/MachiningsMgr.h @@ -65,6 +65,9 @@ class MachiningsMgr bool SetHoleDiamToler( double dToler) ; double GetHoleDiamToler( void) { return m_dHoleDiamToler ; } + bool SetExtSawArcMinRad( double dRad) ; + double GetExtSawArcMinRad( void) + { return m_dExtSawArcMinRad ; } private : bool Clear( void) ; @@ -102,4 +105,5 @@ class MachiningsMgr double m_dExtraLOnCutRegion ; double m_dExtraROnDrillRegion ; double m_dHoleDiamToler ; + double m_dExtSawArcMinRad ; } ; \ No newline at end of file diff --git a/Milling.cpp b/Milling.cpp index efc0949..3e5d878 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -526,7 +526,7 @@ Milling::Chain( int nGrpDestId) //---------------------------------------------------------------------------- bool -Milling::AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) +Milling::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) { // non devo fare alcunché return true ; diff --git a/Milling.h b/Milling.h index f65dc13..fb1b2c6 100644 --- a/Milling.h +++ b/Milling.h @@ -46,7 +46,7 @@ class Milling : public Machining bool GetParam( int nType, std::string& sVal) const override ; const ToolData& GetToolData( void) const ; bool GetGeometry( SELVECTOR& vIds) const override ; - bool AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) override ; + bool AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) override ; bool IsEmpty( void) const override { return ( m_nMills == 0) ; } diff --git a/Sawing.cpp b/Sawing.cpp index 0e04bae..a2f3ff9 100644 --- a/Sawing.cpp +++ b/Sawing.cpp @@ -21,6 +21,7 @@ #include "/EgtDev/Include/EXeCmdLogOff.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkCurveLine.h" +#include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EgkChainCurves.h" #include "/EgtDev/Include/EGkUserObjFactory.h" @@ -640,7 +641,7 @@ Sawing::GetGeometry( SELVECTOR& vIds) const //---------------------------------------------------------------------------- bool -Sawing::AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) +Sawing::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) { // compenso il raggio dell'utensile ptP += pCamData->GetCorrDir() * ( m_TParams.m_dDiam / 2) ; @@ -729,7 +730,7 @@ bool Sawing::VerifySideAngle( void) { // verifiche per angolo di sbandamento - if ( fabs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { // non ammesso lato di lavoro in centro if ( m_Params.m_nWorkSide == SAW_WS_CENTER) { LOG_INFO( GetEMkLogger(), "Center work not allowed with side angle") ; @@ -983,7 +984,7 @@ Sawing::ProcessPath( int nPathId, int nPvId, int nClId) // determino l'eccesso di taglio double dExtraCut = max( 0., dDepth - dRbDist) ; // correzione per angolo di fianco - if ( fabs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { // generale double dCoeff = 1 / cos( m_Params.m_dSideAngle * DEGTORAD) ; dDepth *= dCoeff ; @@ -1003,9 +1004,22 @@ Sawing::ProcessPath( int nPathId, int nPvId, int nClId) string sPathName ; m_pGeomDB->GetName( nPathId, sPathName) ; + // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi + const double MAX_ANG_CEN = 181 ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // se arco con angolo al centro oltre il limite, lo divido a metà + const ICurveArc* pArc = GetCurveArc( pCompo->GetCurve( i)) ; + if ( pArc != nullptr && abs( pArc->GetAngCenter()) > MAX_ANG_CEN) { + pCompo->AddJoint( i + 0.5) ; + ++ i ; + ++ nMaxInd ; + } + } + // ciclo sulle curve elementari bool bClosed = pCompo->IsClosed() ; - int nMaxInd = pCompo->GetCurveCount() - 1 ; + nMaxInd = pCompo->GetCurveCount() - 1 ; for ( int i = 0 ; i <= nMaxInd ; ++ i) { // curva precedente int j = (( i == 0 && bClosed) ? nMaxInd : i - 1) ; @@ -1030,14 +1044,53 @@ Sawing::ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* p double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, const string& sName, int nPvId, int nClId) { - // se non è una linea, la salto - if ( pCrvC->GetType() != CRV_LINE) - return true ; + switch ( pCrvC->GetType()) { + case CRV_LINE : + { + const ICurveLine* pLine = GetCurveLine( pCrvC) ; + if ( pLine == nullptr) + return false ; + return ProcessLine( pCrvP, pLine, pCrvN, dDepth, dExtraCut, bIsFirst, bIsLast, sName, nPvId, nClId) ; + } + case CRV_ARC : + { + const ICurveArc* pArc = GetCurveArc( pCrvC) ; + if ( pArc == nullptr) + return false ; + // verifico che non ci sia angolo di fianco + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : SideAngle not allowed on Arc") ; + return false ; + } + // se arco lavorato dall'esterno + if ( ( pArc->GetAngCenter() > 0 && m_Params.m_nWorkSide == SAW_WS_RIGHT) || + ( pArc->GetAngCenter() < 0 && m_Params.m_nWorkSide == SAW_WS_LEFT)) + return ProcessExtArc( pCrvP, pArc, pCrvN, dDepth, dExtraCut, bIsFirst, bIsLast, sName, nPvId, nClId) ; + // altrimenti arco lavorato dall'interno + else + return ProcessIntArc( pCrvP, pArc, pCrvN, dDepth, dExtraCut, bIsFirst, bIsLast, sName, nPvId, nClId) ; + } + default : + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +Sawing::ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve* pCrvN, + double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, + const string& sName, int nPvId, int nClId) +{ // copio la curva - PtrOwner pLine( GetCurveLine( pCrvC->Clone())) ; + PtrOwner pLine( GetCurveLine( pLineC->Clone())) ; + if ( IsNull( pLine)) + return false ; + // direzione linea corrente + Vector3d vtDirC ; + pLine->GetStartDir( vtDirC) ; // calcolo i versori fresa e correzione Vector3d vtTool, vtCorr ; - if ( ! CalculateToolAndCorrVersors( Get( pLine), vtTool, vtCorr)) { + if ( ! CalculateToolAndCorrVersors( vtDirC, m_Params.m_nHeadSide, m_Params.m_nWorkSide, m_Params.m_dSideAngle, vtTool, vtCorr)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity CalculateToolAndCorrVersors") ; return false ; } @@ -1048,7 +1101,7 @@ Sawing::ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* p } // aggiungo affondamento pLine->Translate( - vtCorr * dDepth) ; - // calcolo elevazione (sui due bordi della striscia + // calcolo elevazione (sui due bordi della striscia) double dElev, dElev2 ; Vector3d vtThick = vtTool * m_TParams.m_dThick ; if ( ! GetElevation( m_nPhase, pLine->GetStart(), pLine->GetEnd(), vtCorr, dElev) || @@ -1057,9 +1110,6 @@ Sawing::ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* p return false ; } dElev = max( dElev, dElev2) ; - // direzione linea corrente - Vector3d vtDirC ; - pLine->GetStartDir( vtDirC) ; // calcolo tipo angolo con precedente bool bExtAngPC = true ; if ( pCrvP != nullptr) { @@ -1084,7 +1134,7 @@ Sawing::ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* p } // aggiusto per tipo estremi bool bToSkip = false ; - if ( ! AdjustForEdges( Get( pLine), dElev, vtThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { + if ( ! AdjustLineForEdges( Get( pLine), dElev, vtThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForEdges") ; return false ; } @@ -1095,13 +1145,13 @@ Sawing::ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* p // Se richiesto Preview if ( nPvId != GDB_ID_NULL) { - if ( ! GenerateEntityPv( Get( pLine), vtTool, vtCorr, dElev, dExtraCut, sName, nPvId)) + if ( ! GenerateLinePv( Get( pLine), vtTool, vtCorr, dElev, dExtraCut, sName, nPvId)) return false ; } // Se richiesta geometria di lavorazione if ( nClId != GDB_ID_NULL) { - if ( ! GenerateEntityCl( Get( pLine), vtTool, vtCorr, dElev, dExtraCut, sName, nClId)) + if ( ! GenerateLineCl( Get( pLine), vtTool, vtCorr, dElev, dExtraCut, sName, nClId)) return false ; } @@ -1113,8 +1163,8 @@ Sawing::ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* p //---------------------------------------------------------------------------- bool -Sawing::GenerateEntityPv( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, - double dElev, double dExtraCut, const string& sName, int nPvId) +Sawing::GenerateLinePv( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, + double dElev, double dExtraCut, const string& sName, int nPvId) { // creo gruppo per anteprima di lavorazione della linea int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; @@ -1187,8 +1237,8 @@ Sawing::GenerateEntityPv( const ICurveLine* pLine, const Vector3d& vtTool, const //---------------------------------------------------------------------------- bool -Sawing::GenerateEntityCl( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, - double dElev, double dExtraCut, const string& sName, int nClId) +Sawing::GenerateLineCl( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, + double dElev, double dExtraCut, const string& sName, int nClId) { // creo gruppo per geometria di lavorazione della linea int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; @@ -1204,7 +1254,7 @@ Sawing::GenerateEntityCl( const ICurveLine* pLine, const Vector3d& vtTool, const double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - if ( fabs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) dAppr /= cos( m_Params.m_dSideAngle * DEGTORAD) ; // Se una sola passata @@ -1314,6 +1364,912 @@ Sawing::GenerateEntityCl( const ICurveLine* pLine, const Vector3d& vtTool, const return true ; } +//---------------------------------------------------------------------------- +bool +Sawing::ProcessExtArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve* pCrvN, + double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, + const string& sName, int nPvId, int nClId) +{ + // copio la curva + PtrOwner pArc( GetCurveArc( pArcC->Clone())) ; + if ( IsNull( pArc)) + return false ; + // verifico che il raggio sia superiore al minimo + if ( pArc->GetRadius() < m_pMchMgr->GetCurrMachiningsMgr()->GetExtSawArcMinRad()) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Radius too small in ExtSawArc") ; + return false ; + } + // Recupero le direzioni iniziale, intermedia e finale dell'arco + Vector3d vtStaDirC ; + pArc->GetStartDir( vtStaDirC) ; + Vector3d vtMidDirC ; + pArc->GetMidDir( vtMidDirC) ; + Vector3d vtEndDirC ; + pArc->GetEndDir( vtEndDirC) ; + // calcolo i versori fresa e correzione + Vector3d vtStaTool, vtStaCorr, vtMidTool, vtMidCorr, vtEndTool, vtEndCorr ; + if ( ! CalculateToolAndCorrVersors( vtStaDirC, m_Params.m_nHeadSide, m_Params.m_nWorkSide, m_Params.m_dSideAngle, vtStaTool, vtStaCorr) || + ! CalculateToolAndCorrVersors( vtMidDirC, m_Params.m_nHeadSide, m_Params.m_nWorkSide, m_Params.m_dSideAngle, vtMidTool, vtMidCorr) || + ! CalculateToolAndCorrVersors( vtEndDirC, m_Params.m_nHeadSide, m_Params.m_nWorkSide, m_Params.m_dSideAngle, vtEndTool, vtEndCorr) || + ! AreSameVectorApprox( vtStaCorr, vtMidCorr) || + ! AreSameVectorApprox( vtStaCorr, vtEndCorr)) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity CalculateToolAndCorrVersors") ; + return false ; + } + // correzioni per lato lama, lato mandrino + if ( ! AdjustForSide( Get( pArc))) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForSide") ; + return false ; + } + // aggiungo affondamento + pArc->Translate( - vtStaCorr * dDepth) ; + // calcolo elevazione (sui due bordi della striscia) + double dElev, dElev2 ; + Point3d ptStart, ptMid, ptEnd ; + pArc->GetStartPoint( ptStart) ; + pArc->GetMidPoint( ptMid) ; + pArc->GetEndPoint( ptEnd) ; + Vector3d vtStaThick = vtStaTool * m_TParams.m_dThick ; + Vector3d vtMidThick = vtMidTool * m_TParams.m_dThick ; + Vector3d vtEndThick = vtEndTool * m_TParams.m_dThick ; + if ( ! GetElevation( m_nPhase, ptStart, ptMid, ptEnd, vtStaCorr, dElev) || + ! GetElevation( m_nPhase, ptStart + vtStaThick, ptMid + vtMidThick, ptEnd + vtEndThick, vtStaCorr, dElev2) ) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity GetElevation") ; + return false ; + } + dElev = max( dElev, dElev2) ; + // calcolo tipo angolo con precedente + bool bExtAngPC = true ; + if ( pCrvP != nullptr) { + Vector3d vtDirP ; + pCrvP->GetEndDir( vtDirP) ; + double dAngPC ; + vtDirP.GetAngleXY( vtStaDirC, dAngPC) ; + if ( ( m_Params.m_nWorkSide == SAW_WS_LEFT && dAngPC > EPS_ANG_SMALL) || + ( m_Params.m_nWorkSide == SAW_WS_RIGHT && dAngPC < - EPS_ANG_SMALL)) + bExtAngPC = false ; + } + // calcolo tipo angolo con successivo + bool bExtAngCN = true ; + if ( pCrvN != nullptr) { + Vector3d vtDirN ; + pCrvN->GetStartDir( vtDirN) ; + double dAngCN ; + vtEndDirC.GetAngleXY( vtDirN, dAngCN) ; + if ( ( m_Params.m_nWorkSide == SAW_WS_LEFT && dAngCN > EPS_ANG_SMALL) || + ( m_Params.m_nWorkSide == SAW_WS_RIGHT && dAngCN < - EPS_ANG_SMALL)) + bExtAngCN = false ; + } + // aggiusto per tipo estremi + bool bToSkip = false ; + if ( ! AdjustArcForEdges( Get( pArc), dElev, vtStaThick, vtEndThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForEdges") ; + return false ; + } + if ( bToSkip) { + LOG_INFO( GetEMkLogger(), "Warning in Sawing : skipped Entity too small") ; + return true ; + } + + // Se richiesto Preview + if ( nPvId != GDB_ID_NULL) { + if ( ! GenerateExtArcPv( Get( pArc), vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nPvId)) + return false ; + } + + // Se richiesta geometria di lavorazione + if ( nClId != GDB_ID_NULL) { + if ( ! GenerateExtArcCl( Get( pArc), vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nClId)) + return false ; + } + + // incremento numero di tagli + ++ m_nCuts ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Sawing::GenerateExtArcPv( const ICurveArc* pArc, const Vector3d& vtStaTool, const Vector3d& vtMidTool, + const Vector3d& vtEndTool, const Vector3d& vtCorr, + double dElev, double dExtraCut, const string& sName, int nPvId) +{ + // creo gruppo per anteprima di lavorazione dell'arco + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sName) ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + + // disabilito eventuale registrazione comandi EXE (riabilitazione automatica) + CmdLogOff cmdLogOff ; + + // lunghezza taglio parziale + double dDeltaT = (( dElev < 0.5 * m_TParams.m_dDiam) ? sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) : 0) ; + + // calcolo dei raggi + double dIntRad ; + double dExtRad ; + if ( AreHeadWorkOnSameSide()) { + dIntRad = pArc->GetRadius() ; + double dRadTot = pArc->GetRadius() + m_TParams.m_dThick ; + dExtRad = sqrt( dRadTot * dRadTot + dDeltaT * dDeltaT) ; + } + else { + dIntRad = pArc->GetRadius() - m_TParams.m_dThick ; + dExtRad = sqrt( pArc->GetRadius() * pArc->GetRadius() + dDeltaT * dDeltaT) ; + } + + // contorno per parte di taglio completo + { + PtrOwner pIntArc( GetCurveArc( pArc->Clone())) ; + if ( IsNull( pIntArc) || ! pIntArc->ChangeRadius( dIntRad)) + return false ; + PtrOwner pExtArc( GetCurveArc( pArc->Clone())) ; + if ( IsNull( pExtArc) || ! pExtArc->ChangeRadius( dExtRad)) + return false ; + pExtArc->Invert() ; + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) + return false ; + Point3d ptEnd ; + pIntArc->GetEndPoint( ptEnd) ; + Point3d ptStart ; + pExtArc->GetStartPoint( ptStart) ; + pLine->Set( ptEnd, ptStart) ; + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || + ! pCompo->AddCurve( Release( pIntArc)) || + ! pCompo->AddCurve( Release( pLine)) || + ! pCompo->AddCurve( Release( pExtArc)) || + ! pCompo->Close()) + return false ; + pCompo->Translate( dElev * vtCorr + Vector3d( 0, 0, 0.1)) ; + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPxId, Release( pCompo)) ; + m_pGeomDB->SetName( nId, MCH_PV_CUT) ; + m_pGeomDB->SetMaterial( nId, LIME) ; + } + + // contorno per parte iniziale di taglio + { + // direzione iniziale del taglio + Vector3d vtStaDir ; + pArc->GetStartDir( vtStaDir) ; + // punto iniziale e direzione radiale iniziale + Point3d ptStart ; + pArc->GetStartPoint( ptStart) ; + if ( ! AreHeadWorkOnSameSide()) + ptStart += vtStaTool * m_TParams.m_dThick ; + Vector3d vtStaVer = pArc->GetStartVersor() ; + // punto prima di inizio + Point3d ptPre = ptStart - vtStaDir * dDeltaT ; + // punto fuori prima di inizio + Point3d ptOutPre = ptPre + vtStaVer * m_TParams.m_dThick ; + // punto fuori inizio + Point3d ptOut = ptStart + vtStaVer * ( dExtRad - dIntRad) ; + // linea base + PtrOwner pLine1( CreateCurveLine()) ; + if ( IsNull( pLine1) || ! pLine1->Set( ptStart, ptPre)) + return false ; + // linea di spessore lama + PtrOwner pLine2( CreateCurveLine()) ; + if ( IsNull( pLine2) || ! pLine2->Set( ptPre, ptOutPre)) + return false ; + // arco + PtrOwner pExtArc( GetCurveArc( pArc->Clone())) ; + if ( IsNull( pExtArc) || ! pExtArc->SetC2P( pArc->GetCenter(), ptOutPre, ptOut)) + return false ; + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || + ! pCompo->AddCurve( Release( pLine1)) || + ! pCompo->AddCurve( Release( pLine2)) || + ! pCompo->AddCurve( Release( pExtArc)) || + ! pCompo->Close()) + return false ; + pCompo->Translate( dElev * vtCorr + Vector3d( 0, 0, 0.1)) ; + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPxId, Release( pCompo)) ; + m_pGeomDB->SetName( nId, MCH_PV_PRE_CUT) ; + m_pGeomDB->SetMaterial( nId, BLUE) ; + } + + // contorno per parte finale di taglio + { + // direzione finale del taglio + Vector3d vtEndDir ; + pArc->GetEndDir( vtEndDir) ; + // punto finale e direzione radiale finale + Point3d ptEnd ; + pArc->GetEndPoint( ptEnd) ; + Vector3d vtEndVer = ptEnd - pArc->GetCenter() ; + vtEndVer.Normalize() ; + if ( ! AreHeadWorkOnSameSide()) + ptEnd += vtEndTool * m_TParams.m_dThick ; + // punto dopo fine + Point3d ptPost = ptEnd + vtEndDir * dDeltaT ; + // punto fuori dopo fine + Point3d ptOutPost = ptPost + vtEndVer * m_TParams.m_dThick ; + // punto fuori fine + Point3d ptOut = ptEnd + vtEndVer * ( dExtRad - dIntRad) ; + // linea base + PtrOwner pLine1( CreateCurveLine()) ; + if ( IsNull( pLine1) || ! pLine1->Set( ptEnd, ptPost)) + return false ; + // linea di spessore lama + PtrOwner pLine2( CreateCurveLine()) ; + if ( IsNull( pLine2) || ! pLine2->Set( ptPost, ptOutPost)) + return false ; + // arco + PtrOwner pExtArc( GetCurveArc( pArc->Clone())) ; + if ( IsNull( pExtArc) || ! pExtArc->SetC2P( pArc->GetCenter(), ptOutPost, ptOut)) + return false ; + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || + ! pCompo->AddCurve( Release( pLine1)) || + ! pCompo->AddCurve( Release( pLine2)) || + ! pCompo->AddCurve( Release( pExtArc)) || + ! pCompo->Close()) + return false ; + pCompo->Translate( dElev * vtCorr + Vector3d( 0, 0, 0.1)) ; + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPxId, Release( pCompo)) ; + m_pGeomDB->SetName( nId, MCH_PV_POST_CUT) ; + m_pGeomDB->SetMaterial( nId, BLUE) ; + } + + +#if 0 + // rettangolo per parte di taglio completo + Point3d ptIni = pLine->GetStart() + dElev * vtCorr ; + Point3d ptEnd = pLine->GetEnd() + dElev * vtCorr ; + Vector3d vtToolH( vtTool.x, vtTool.y, 0) ; + vtToolH *= m_TParams.m_dThick / vtToolH.SqLen() ; + Point3d ptCross = ptEnd + vtToolH ; + Vector3d vtDZ( 0, 0, 0.1) ; + int nId = ExeCreateRectangle3P( nPxId, ptIni + vtDZ, ptCross + vtDZ, ptEnd + vtDZ, RTY_LOC) ; + m_pGeomDB->SetName( nId, MCH_PV_CUT) ; + m_pGeomDB->SetMaterial( nId, LIME) ; + + // distanza XY tra centro e bordo taglio + double dDeltaT = (( dElev < 0.5 * m_TParams.m_dDiam) ? sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) : 0) ; + // direzione del taglio + Vector3d vtDir ; + pLine->GetStartDir( vtDir) ; + + // rettangolo per parte parziale iniziale + int nId2 = ExeCreateRectangle3P( nPxId, ptIni - vtDir * dDeltaT, ptIni + vtToolH, ptIni, RTY_LOC) ; + // assegno nome e colore + m_pGeomDB->SetName( nId2, MCH_PV_PRE_CUT) ; + m_pGeomDB->SetMaterial( nId2, BLUE) ; + + // rettangolo per parte parziale finale + int nId3 = ExeCreateRectangle3P( nPxId, ptEnd, ptCross + vtDir * dDeltaT, ptEnd + vtDir * dDeltaT, RTY_LOC) ; + // assegno nome e colore + m_pGeomDB->SetName( nId3, MCH_PV_POST_CUT) ; + m_pGeomDB->SetMaterial( nId3, BLUE) ; + + // regione di taglio completo per nesting + double dExtraL = m_pMchMgr->GetCurrMachiningsMgr()->GetExtraLOnCutRegion() ; + int nRId = ExeCreateSurfFrRectangle3P( nPxId, ptIni - vtDir * ( dDeltaT + dExtraL), + ptCross + vtDir * ( dDeltaT + dExtraL), ptEnd, RTY_LOC) ; + m_pGeomDB->SetName( nRId, MCH_PV_RCUT) ; + m_pGeomDB->SetMaterial( nRId, INVISIBLE) ; + // regione di taglio ridotto per nesting (sono escluse le parti iniziale e finale) + const double EXTRALEN_R = 10 * EPS_SMALL ; + int nRrId = ExeCreateSurfFrRectangle3P( nPxId, ptIni - vtDir * EXTRALEN_R, + ptCross + vtDir * EXTRALEN_R, ptEnd, RTY_LOC) ; + m_pGeomDB->SetName( nRrId, MCH_PV_RRCUT) ; + m_pGeomDB->SetMaterial( nRrId, INVISIBLE) ; + // regione di ingresso al taglio (parte iniziale) + int nRsId = ExeCreateSurfFrRectangle3P( nPxId, ptIni - vtDir * ( dDeltaT + dExtraL), + ptIni + vtToolH, ptIni, RTY_LOC) ; + m_pGeomDB->SetName( nRsId, MCH_PV_RLICUT) ; + m_pGeomDB->SetMaterial( nRsId, INVISIBLE) ; + // regione di uscita dal taglio (parte finale) + int nReId = ExeCreateSurfFrRectangle3P( nPxId, ptEnd, ptCross + vtDir * ( dDeltaT + dExtraL), + ptEnd + vtDir * ( dDeltaT + dExtraL) , RTY_LOC) ; + m_pGeomDB->SetName( nReId, MCH_PV_RLOCUT) ; + m_pGeomDB->SetMaterial( nReId, INVISIBLE) ; + + // salvo in info del gruppo la larghezza XY del taglio e la distanza XY tra centro e bordo taglio + m_pGeomDB->SetInfo( nPxId, MCH_PV_KEY_WT, vtToolH.LenXY()) ; + m_pGeomDB->SetInfo( nPxId, MCH_PV_KEY_DT, dDeltaT) ; + +#endif + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Sawing::GenerateExtArcCl( const ICurveArc* pArc, const Vector3d& vtStaTool, const Vector3d& vtMidTool, + const Vector3d& vtEndTool, const Vector3d& vtCorr, + double dElev, double dExtraCut, const string& sName, int nClId) +{ + // creo gruppo per geometria di lavorazione dell'arco + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sName) ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + // Imposto dati comuni + SetPathId( nPxId) ; + SetCorrDir( vtCorr) ; + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) + dAppr /= cos( m_Params.m_dSideAngle * DEGTORAD) ; + + // angolo al centro massimo + const double MAX_ANG_CEN = 150.0 ; + + // Se una sola passata + if ( m_Params.m_dStepExtArc < EPS_SMALL) { + // 1 -> approccio + SetToolDir( vtStaTool) ; + Point3d ptP1 ; + pArc->GetStartPoint( ptP1) ; + if ( ! AddApproach( ptP1, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + // 2 -> movimento in affondo al punto iniziale + SetFlag( 0) ; + SetFeed( m_TParams.m_dTipFeed) ; + Point3d ptP2 ; + pArc->GetStartPoint( ptP2) ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + // 3 -> movimento di lato al punto finale + SetFeed( m_TParams.m_dFeed) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + // se angolo al centro minore del limite, un solo arco + if ( abs( dAngCen) < MAX_ANG_CEN) { + SetToolDir( vtEndTool) ; + if ( AddArcMove( ptP3, ptCen, dAngCen) == GDB_ID_NULL) + return false ; + } + // altrimenti due archi + else { + Point3d ptMid ; + pArc->GetMidPoint( ptMid) ; + // prima metà arco + SetToolDir( vtMidTool) ; + if ( AddArcMove( ptMid, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + // seconda metà arco + SetToolDir( vtEndTool) ; + if ( AddArcMove( ptP3, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + } + // 4 -> retrazione + Point3d ptP4 ; + pArc->GetEndPoint( ptP4) ; + if ( ! AddRetract( ptP4, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + + // Se step a Zig-Zag o ToAndFrom + else if ( m_Params.m_nStepType == SAW_ST_ZIGZAG || m_Params.m_nStepType == SAW_ST_TOANDFROM) { + // 1 -> approccio + SetToolDir( vtStaTool) ; + Point3d ptP1 ; + pArc->GetStartPoint( ptP1) ; + if ( ! AddApproach( ptP1, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + // 2-3 -> lavorazione (sempre numero pari di passate) + // calcolo numero e valore degli step + double dCutH = dElev - dExtraCut ; + int nStep = 2 ; + if ( m_Params.m_nStepType == SAW_ST_ZIGZAG) { + nStep = static_cast( ceil( dCutH / m_Params.m_dStepExtArc)) ; + if ( ( nStep % 2) == 1) + nStep += 1 ; + } + double dStep = dCutH / nStep ; + // esecuzione degli step + for ( int i = nStep - 1 ; i >= 0 ; -- i) { + // distanza dal fondo + double dDelta = ( ( i != 0) ? dExtraCut + i * dStep : 0) ; + // estremi del movimento (dispari vanno, pari tornano) + Point3d ptP2 ; + pArc->GetStartPoint( ptP2) ; + ptP2 += vtCorr * dDelta ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + ptP3 += vtCorr * dDelta ; + if ( ( i % 2) == 0) + swap( ptP2, ptP3) ; + // movimento in affondo + SetToolDir( ( ( i % 2) == 0) ? vtEndTool : vtStaTool) ; + SetFlag( 0) ; + SetFeed( m_TParams.m_dTipFeed) ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + // movimento di lato + SetFeed( m_TParams.m_dFeed) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + // se angolo al centro minore del limite, un solo arco + if ( abs( dAngCen) < MAX_ANG_CEN) { + double dCurrAngCen = dAngCen * ((( i % 2) == 0) ? -1 : 1) ; + SetToolDir( ( ( i % 2) == 0) ? vtStaTool : vtEndTool) ; + if ( AddArcMove( ptP3, ptCen, dCurrAngCen) == GDB_ID_NULL) + return false ; + } + // altrimenti due archi + else { + Point3d ptMid ; + pArc->GetMidPoint( ptMid) ; + ptMid += vtCorr * dDelta ; + double dCurrAngCen = dAngCen / 2 * ((( i % 2) == 0) ? -1 : 1) ; + // prima metà arco + SetToolDir( vtMidTool) ; + if ( AddArcMove( ptMid, ptCen, dCurrAngCen) == GDB_ID_NULL) + return false ; + // seconda metà arco + SetToolDir( ( ( i % 2) == 0) ? vtStaTool : vtEndTool) ; + if ( AddArcMove( ptP3, ptCen, dCurrAngCen) == GDB_ID_NULL) + return false ; + } + } + // 4 -> retrazione + SetToolDir( vtStaTool) ; + Point3d ptP4 ; + pArc->GetStartPoint( ptP4) ; + if ( ! AddRetract( ptP4, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + + // Altrimenti step a una via + else { + // 1 -> approccio + SetToolDir( vtStaTool) ; + Point3d ptP1 ; + pArc->GetStartPoint( ptP1) ; + if ( ! AddApproach( ptP1, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + // 2-3 -> lavorazione + // calcolo numero e valore degli step + double dCutH = dElev - dExtraCut ; + int nStep = static_cast( ceil( dCutH / m_Params.m_dStepExtArc)) ; + double dStep = dCutH / nStep ; + // esecuzione degli step + for ( int i = nStep - 1 ; i >= 0 ; -- i) { + // distanza dal fondo + double dDelta = ( ( i != 0) ? dExtraCut + i * dStep : 0) ; + // movimento in affondo al punto iniziale + SetToolDir( vtStaTool) ; + SetFlag( 0) ; + SetFeed( m_TParams.m_dTipFeed) ; + Point3d ptP2 ; + pArc->GetStartPoint( ptP2) ; + ptP2 += vtCorr * dDelta ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + // movimento di lato al punto finale + SetFeed( m_TParams.m_dFeed) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + ptP3 += vtCorr * dDelta ; + // se angolo al centro minore del limite, un solo arco + if ( abs( dAngCen) < MAX_ANG_CEN) { + SetToolDir( vtEndTool) ; + if ( AddArcMove( ptP3, ptCen, dAngCen) == GDB_ID_NULL) + return false ; + } + // altrimenti due archi + else { + Point3d ptMid ; + pArc->GetMidPoint( ptMid) ; + ptMid += vtCorr * dDelta ; + // prima metà arco + SetToolDir( vtMidTool) ; + if ( AddArcMove( ptMid, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + // seconda metà arco + SetToolDir( vtEndTool) ; + if ( AddArcMove( ptP3, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + } + // se non è ultimo passo + if ( i != 0) { + // movimento di risalita sopra il punto finale + SetFeed( m_TParams.m_dEndFeed) ; + Point3d ptP4 ; + pArc->GetEndPoint( ptP4) ; + ptP4 += vtCorr * ( dElev + dAppr) ; + if ( AddLinearMove( ptP4) == GDB_ID_NULL) + return false ; + // movimento di ritorno sopra il punto iniziale + SetToolDir( vtStaTool) ; + SetFeed( m_TParams.m_dEndFeed) ; + Point3d ptP5 ; + pArc->GetStartPoint( ptP5) ; + ptP5 += vtCorr * ( dElev + dAppr) ; + if ( AddLinearMove( ptP5) == GDB_ID_NULL) + return false ; + } + } + // 4 -> retrazione + Point3d ptP4 ; + pArc->GetEndPoint( ptP4) ; + if ( ! AddRetract( ptP4, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Sawing::ProcessIntArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve* pCrvN, + double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, + const string& sName, int nPvId, int nClId) +{ + // copio la curva + PtrOwner pArc( GetCurveArc( pArcC->Clone())) ; + if ( IsNull( pArc)) + return false ; + // determino l'inclinazione per ottenere il raggio e ne verifico il limite + const double MAX_SIDE_ANG = 60 + EPS_ANG_SMALL ; + double dSawRad = m_TParams.m_dDiam / 2 ; + double dRad = pArc->GetRadius() ; + double dSinA = dSawRad / dRad ; + if ( dSinA > sin( MAX_SIDE_ANG * DEGTORAD)) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Radius too small in IntSawArc") ; + return false ; + } + double dSideAng = - asin( dSinA) * RADTODEG ; + // Verifiche su lato di lavoro e lato testa (si lavora con angolo di sbandamento negativo) + int nHeadSide = m_Params.m_nHeadSide ; + if ( m_Params.m_nWorkSide == SAW_WS_CENTER) { + LOG_INFO( GetEMkLogger(), "Center work not allowed with internal arc") ; + return false ; + } + else if ( m_Params.m_nWorkSide == SAW_WS_LEFT) { + if ( m_Params.m_nHeadSide == SAW_HS_LEFT) + nHeadSide = SAW_HS_RIGHT ; + } + else { + if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) + nHeadSide = SAW_HS_LEFT ; + } + // Recupero le direzioni iniziale, intermedia e finale dell'arco + Vector3d vtStaDirC ; + pArc->GetStartDir( vtStaDirC) ; + Vector3d vtMidDirC ; + pArc->GetMidDir( vtMidDirC) ; + Vector3d vtEndDirC ; + pArc->GetEndDir( vtEndDirC) ; + // calcolo i versori fresa e correzione + Vector3d vtStaTool, vtStaCorr, vtMidTool, vtMidCorr, vtEndTool, vtEndCorr ; + if ( ! CalculateToolAndCorrVersors( vtStaDirC, nHeadSide, m_Params.m_nWorkSide, dSideAng, vtStaTool, vtStaCorr) || + ! CalculateToolAndCorrVersors( vtMidDirC, nHeadSide, m_Params.m_nWorkSide, dSideAng, vtMidTool, vtMidCorr) || + ! CalculateToolAndCorrVersors( vtEndDirC, nHeadSide, m_Params.m_nWorkSide, dSideAng, vtEndTool, vtEndCorr)) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity CalculateToolAndCorrVersors") ; + return false ; + } + // correzioni per lato lama, lato mandrino + if ( ! AdjustIntArcForSide( Get( pArc), dSideAng)) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForSide") ; + return false ; + } + // aggiungo affondamento + pArc->Translate( - Z_AX * ( dDepth + dSinA * m_TParams.m_dThick)) ; + // calcolo elevazione (sui due bordi della striscia) + double dElev, dElev2 ; + Point3d ptStart, ptMid, ptEnd ; + pArc->GetStartPoint( ptStart) ; + pArc->GetMidPoint( ptMid) ; + pArc->GetEndPoint( ptEnd) ; + Vector3d vtStaThick = vtStaTool * m_TParams.m_dThick ; + Vector3d vtMidThick = vtMidTool * m_TParams.m_dThick ; + Vector3d vtEndThick = vtEndTool * m_TParams.m_dThick ; + if ( ! GetElevation( m_nPhase, ptStart, ptMid, ptEnd, Z_AX, dElev) || + ! GetElevation( m_nPhase, ptStart + vtStaThick, ptMid + vtMidThick, ptEnd + vtEndThick, Z_AX, dElev2) ) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity GetElevation") ; + return false ; + } + dElev = max( dElev, dElev2) ; + // calcolo tipo angolo con precedente + bool bExtAngPC = true ; + if ( pCrvP != nullptr) { + Vector3d vtDirP ; + pCrvP->GetEndDir( vtDirP) ; + double dAngPC ; + vtDirP.GetAngleXY( vtStaDirC, dAngPC) ; + if ( ( m_Params.m_nWorkSide == SAW_WS_LEFT && dAngPC > EPS_ANG_SMALL) || + ( m_Params.m_nWorkSide == SAW_WS_RIGHT && dAngPC < - EPS_ANG_SMALL)) + bExtAngPC = false ; + } + // calcolo tipo angolo con successivo + bool bExtAngCN = true ; + if ( pCrvN != nullptr) { + Vector3d vtDirN ; + pCrvN->GetStartDir( vtDirN) ; + double dAngCN ; + vtEndDirC.GetAngleXY( vtDirN, dAngCN) ; + if ( ( m_Params.m_nWorkSide == SAW_WS_LEFT && dAngCN > EPS_ANG_SMALL) || + ( m_Params.m_nWorkSide == SAW_WS_RIGHT && dAngCN < - EPS_ANG_SMALL)) + bExtAngCN = false ; + } + // aggiusto per tipo estremi + bool bToSkip = false ; + if ( ! AdjustArcForEdges( Get( pArc), dElev, vtStaThick, vtEndThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForEdges") ; + return false ; + } + if ( bToSkip) { + LOG_INFO( GetEMkLogger(), "Warning in Sawing : skipped Entity too small") ; + return true ; + } + + // Se richiesto Preview + if ( nPvId != GDB_ID_NULL) { + if ( ! GenerateExtArcPv( Get( pArc), vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nPvId)) + return false ; + } + + // Se richiesta geometria di lavorazione + if ( nClId != GDB_ID_NULL) { + if ( ! GenerateIntArcCl( Get( pArc), vtStaTool, vtMidTool, vtEndTool, + vtStaCorr, vtMidCorr, vtEndCorr, dElev, dExtraCut, sName, nClId)) + return false ; + } + + // incremento numero di tagli + ++ m_nCuts ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Sawing::GenerateIntArcCl( const ICurveArc* pArc, + const Vector3d& vtStaTool, const Vector3d& vtMidTool, const Vector3d& vtEndTool, + const Vector3d& vtStaCorr, const Vector3d& vtMidCorr, const Vector3d& vtEndCorr, + double dElev, double dExtraCut, const string& sName, int nClId) +{ + // creo gruppo per geometria di lavorazione dell'arco + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sName) ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + // Imposto dati comuni + SetPathId( nPxId) ; + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) + dAppr /= cos( m_Params.m_dSideAngle * DEGTORAD) ; + + // angolo al centro massimo + const double MAX_ANG_CEN = 150.0 ; + + // Se una sola passata + if ( m_Params.m_dStepIntArc < EPS_SMALL) { + // 1 -> approccio + SetToolDir( vtStaTool) ; + SetCorrDir( vtStaCorr) ; + Point3d ptP1 ; + pArc->GetStartPoint( ptP1) ; + if ( ! AddApproach( ptP1, Z_AX, dSafeZ, dElev, dAppr)) + return false ; + // 2 -> movimento in affondo al punto iniziale + SetFlag( 0) ; + SetFeed( m_TParams.m_dTipFeed) ; + Point3d ptP2 ; + pArc->GetStartPoint( ptP2) ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + // 3 -> movimento di lato al punto finale + SetFeed( m_TParams.m_dFeed) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + // se angolo al centro minore del limite, un solo arco + if ( abs( pArc->GetAngCenter()) < MAX_ANG_CEN) { + SetToolDir( vtEndTool) ; + SetCorrDir( vtEndCorr) ; + if ( AddArcMove( ptP3, ptCen, dAngCen) == GDB_ID_NULL) + return false ; + } + // altrimenti due archi + else { + Point3d ptMid ; + pArc->GetMidPoint( ptMid) ; + // prima metà arco + SetToolDir( vtMidTool) ; + SetCorrDir( vtMidCorr) ; + if ( AddArcMove( ptMid, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + // seconda metà arco + SetToolDir( vtEndTool) ; + SetCorrDir( vtEndCorr) ; + if ( AddArcMove( ptP3, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + } + // 4 -> retrazione + Point3d ptP4 ; + pArc->GetEndPoint( ptP4) ; + if ( ! AddRetract( ptP4, Z_AX, dSafeZ, dElev, dAppr)) + return false ; + } + + // Se step a Zig-Zag o ToAndFrom + else if ( m_Params.m_nStepType == SAW_ST_ZIGZAG || m_Params.m_nStepType == SAW_ST_TOANDFROM) { + // 1 -> approccio + SetToolDir( vtStaTool) ; + SetCorrDir( vtStaCorr) ; + Point3d ptP1 ; + pArc->GetStartPoint( ptP1) ; + if ( ! AddApproach( ptP1, Z_AX, dSafeZ, dElev, dAppr)) + return false ; + // 2-3 -> lavorazione (sempre numero pari di passate) + // calcolo numero e valore degli step + double dCutH = dElev - dExtraCut ; + int nStep = 2 ; + if ( m_Params.m_nStepType == SAW_ST_ZIGZAG) { + nStep = static_cast( ceil( dCutH / m_Params.m_dStepIntArc)) ; + if ( ( nStep % 2) == 1) + nStep += 1 ; + } + double dStep = dCutH / nStep ; + // esecuzione degli step + for ( int i = nStep - 1 ; i >= 0 ; -- i) { + // distanza dal fondo + double dDelta = ( ( i != 0) ? dExtraCut + i * dStep : 0) ; + // estremi del movimento (dispari vanno, pari tornano) + Point3d ptP2 ; + pArc->GetStartPoint( ptP2) ; + ptP2 += Z_AX * dDelta ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + ptP3 += Z_AX * dDelta ; + if ( ( i % 2) == 0) + swap( ptP2, ptP3) ; + // movimento in affondo + SetToolDir( ( ( i % 2) == 0) ? vtEndTool : vtStaTool) ; + SetCorrDir( ( ( i % 2) == 0) ? vtEndCorr : vtStaCorr) ; + SetFlag( 0) ; + SetFeed( m_TParams.m_dTipFeed) ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + // movimento di lato + SetFeed( m_TParams.m_dFeed) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + // se angolo al centro minore del limite, un solo arco + if ( abs( dAngCen) < MAX_ANG_CEN) { + double dCurrAngCen = dAngCen * ((( i % 2) == 0) ? -1 : 1) ; + SetToolDir( ( ( i % 2) == 0) ? vtStaTool : vtEndTool) ; + SetCorrDir( ( ( i % 2) == 0) ? vtStaCorr : vtEndCorr) ; + if ( AddArcMove( ptP3, ptCen, dCurrAngCen) == GDB_ID_NULL) + return false ; + } + // altrimenti due archi + else { + Point3d ptMid ; + pArc->GetMidPoint( ptMid) ; + ptMid += Z_AX * dDelta ; + double dCurrAngCen = dAngCen / 2 * ((( i % 2) == 0) ? -1 : 1) ; + // prima metà arco + SetToolDir( vtMidTool) ; + SetCorrDir( vtMidCorr) ; + if ( AddArcMove( ptMid, ptCen, dCurrAngCen) == GDB_ID_NULL) + return false ; + // seconda metà arco + SetToolDir( ( ( i % 2) == 0) ? vtStaTool : vtEndTool) ; + SetCorrDir( ( ( i % 2) == 0) ? vtStaCorr : vtEndCorr) ; + if ( AddArcMove( ptP3, ptCen, dCurrAngCen) == GDB_ID_NULL) + return false ; + } + } + // 4 -> retrazione + SetToolDir( vtStaTool) ; + SetCorrDir( vtStaCorr) ; + Point3d ptP4 ; + pArc->GetStartPoint( ptP4) ; + if ( ! AddRetract( ptP4, Z_AX, dSafeZ, dElev, dAppr)) + return false ; + } + + // Altrimenti step a una via + else { + // 1 -> approccio + SetToolDir( vtStaTool) ; + SetCorrDir( vtStaCorr) ; + Point3d ptP1 ; + pArc->GetStartPoint( ptP1) ; + if ( ! AddApproach( ptP1, Z_AX, dSafeZ, dElev, dAppr)) + return false ; + // 2-3 -> lavorazione + // calcolo numero e valore degli step + double dCutH = dElev - dExtraCut ; + int nStep = static_cast( ceil( dCutH / m_Params.m_dStepIntArc)) ; + double dStep = dCutH / nStep ; + // esecuzione degli step + for ( int i = nStep - 1 ; i >= 0 ; -- i) { + // distanza dal fondo + double dDelta = ( ( i != 0) ? dExtraCut + i * dStep : 0) ; + // movimento in affondo al punto iniziale + SetToolDir( vtStaTool) ; + SetCorrDir( vtStaCorr) ; + SetFlag( 0) ; + SetFeed( m_TParams.m_dTipFeed) ; + Point3d ptP2 ; + pArc->GetStartPoint( ptP2) ; + ptP2 += Z_AX * dDelta ; + if ( AddLinearMove( ptP2) == GDB_ID_NULL) + return false ; + // movimento di lato al punto finale + SetFeed( m_TParams.m_dFeed) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + ptP3 += Z_AX * dDelta ; + // se angolo al centro minore del limite, un solo arco + if ( abs( dAngCen) < MAX_ANG_CEN) { + SetToolDir( vtEndTool) ; + SetCorrDir( vtEndCorr) ; + if ( AddArcMove( ptP3, ptCen, dAngCen) == GDB_ID_NULL) + return false ; + } + // altrimenti due archi + else { + Point3d ptMid ; + pArc->GetMidPoint( ptMid) ; + ptMid += Z_AX * dDelta ; + // prima metà arco + SetToolDir( vtMidTool) ; + SetCorrDir( vtMidCorr) ; + if ( AddArcMove( ptMid, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + // seconda metà arco + SetToolDir( vtEndTool) ; + SetCorrDir( vtEndCorr) ; + if ( AddArcMove( ptP3, ptCen, dAngCen / 2) == GDB_ID_NULL) + return false ; + } + // se non è ultimo passo + if ( i != 0) { + // movimento di risalita sopra il punto finale + SetFeed( m_TParams.m_dEndFeed) ; + Point3d ptP4 ; + pArc->GetEndPoint( ptP4) ; + ptP4 += Z_AX * ( dElev + dAppr) ; + if ( AddLinearMove( ptP4) == GDB_ID_NULL) + return false ; + // movimento di ritorno sopra il punto iniziale + SetToolDir( vtStaTool) ; + SetCorrDir( vtStaCorr) ; + SetFeed( m_TParams.m_dEndFeed) ; + Point3d ptP5 ; + pArc->GetStartPoint( ptP5) ; + ptP5 += Z_AX * ( dElev + dAppr) ; + if ( AddLinearMove( ptP5) == GDB_ID_NULL) + return false ; + } + } + // 4 -> retrazione + Point3d ptP4 ; + pArc->GetEndPoint( ptP4) ; + if ( ! AddRetract( ptP4, Z_AX, dSafeZ, dElev, dAppr)) + return false ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool Sawing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) @@ -1369,19 +2325,16 @@ Sawing::AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, d //---------------------------------------------------------------------------- bool -Sawing::CalculateToolAndCorrVersors( const ICurve* pCurve, Vector3d& vtTool, Vector3d& vtCorr) +Sawing::CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, int nWorkSide, double dSideAng, + Vector3d& vtTool, Vector3d& vtCorr) { - // Recupero la direzione della linea e la proietto nel piano XY - Vector3d vtTang ; - pCurve->GetStartDir( vtTang) ; - vtTang.z = 0 ; - if ( ! vtTang.Normalize()) - return false ; - // Versore fresa : annullo la componente in Z e normalizzo vtTool = vtTang ; + vtTool.z = 0 ; + if ( ! vtTool.Normalize()) + return false ; // ruoto attorno a Zglob+ a seconda del lato mandrino - if ( m_Params.m_nHeadSide == SAW_HS_LEFT) + if ( nHeadSide == SAW_HS_LEFT) vtTool.Rotate( Z_AX, 90) ; else vtTool.Rotate( Z_AX, -90) ; @@ -1390,14 +2343,14 @@ Sawing::CalculateToolAndCorrVersors( const ICurve* pCurve, Vector3d& vtTool, Vec vtCorr = Z_AX ; // Se lama sbandata - if ( fabs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { - if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) { - vtTool.Rotate( vtTang, - m_Params.m_dSideAngle) ; - vtCorr.Rotate( vtTang, - m_Params.m_dSideAngle) ; + if ( fabs( dSideAng) > EPS_ANG_SMALL) { + if ( nWorkSide == SAW_WS_RIGHT) { + vtTool.Rotate( vtTang, - dSideAng) ; + vtCorr.Rotate( vtTang, - dSideAng) ; } else { - vtTool.Rotate( vtTang, m_Params.m_dSideAngle) ; - vtCorr.Rotate( vtTang, m_Params.m_dSideAngle) ; + vtTool.Rotate( vtTang, dSideAng) ; + vtCorr.Rotate( vtTang, dSideAng) ; } } @@ -1423,7 +2376,7 @@ Sawing::AdjustForSide( ICurve* pCurve) else // testa a destra e lama in centro dOffs = - 0.5 * m_TParams.m_dThick ; // correzione per angolo di fianco - if ( fabs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) dOffs /= cos( m_Params.m_dSideAngle * DEGTORAD) ; // eseguo offset curva ( nel piano XY globale) return pCurve->SimpleOffset( dOffs) ; @@ -1431,8 +2384,25 @@ Sawing::AdjustForSide( ICurve* pCurve) //---------------------------------------------------------------------------- bool -Sawing::AdjustForEdges( ICurveLine* pLine, double dElev, const Vector3d& vtThick, - bool bIsFirst, bool bIsLast, bool bExtAngPC, bool bExtAngCN, bool& bToSkip) +Sawing::AdjustIntArcForSide( ICurve* pCurve, double dSideAng) +{ + // calcolo offset curva + double dOffs = 0 ; + if ( m_Params.m_nWorkSide == SAW_WS_LEFT) + dOffs = - m_TParams.m_dThick ; + else + dOffs = m_TParams.m_dThick ; + // correzione per angolo di fianco + if ( fabs( dSideAng) > EPS_ANG_SMALL) + dOffs *= cos( dSideAng * DEGTORAD) ; + // eseguo offset curva ( nel piano XY globale) + return pCurve->SimpleOffset( dOffs) ; +} + +//---------------------------------------------------------------------------- +bool +Sawing::AdjustLineForEdges( ICurveLine* pLine, double dElev, const Vector3d& vtThick, + bool bIsFirst, bool bIsLast, bool bExtAngPC, bool bExtAngCN, bool& bToSkip) { // distanza XY tra centro e bordo taglio double dDeltaT = (( dElev < 0.5 * m_TParams.m_dDiam) ? sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) : 0) ; @@ -1555,3 +2525,62 @@ Sawing::AdjustForEdges( ICurveLine* pLine, double dElev, const Vector3d& vtThick return true ; } + +//---------------------------------------------------------------------------- +bool +Sawing::AdjustArcForEdges( ICurveArc* pArc, double dElev, const Vector3d& vtStaThick, const Vector3d& vtEndThick, + bool bIsFirst, bool bIsLast, bool bExtAngPC, bool bExtAngCN, bool& bToSkip) +{ + // --- gli archi non vanno estesi al bordo del grezzo --- + // distanza XY tra centro e bordo taglio + double dDeltaT = (( dElev < 0.5 * m_TParams.m_dDiam) ? sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) : 0) ; + // verifiche e aggiustamenti sull'inizio + double dDeltaI = 0 ; + if ( ! bExtAngPC) + dDeltaI = - dDeltaT ; + else if ( bIsFirst) { + if ( m_Params.m_nLeadInType == SAW_LI_STRICT) + // all'interno + dDeltaI = - dDeltaT ; + else if ( m_Params.m_nLeadInType == SAW_LI_OUT || + m_Params.m_nLeadInType == SAW_LI_EXT_OUT) + // all'esterno + dDeltaI = dDeltaT ; + } + // verifiche e aggiustamenti sulla fine + double dDeltaF = 0 ; + if ( ! bExtAngCN) + dDeltaF = - dDeltaT ; + else if ( bIsLast) { + if ( m_Params.m_nLeadOutType == SAW_LO_STRICT) + dDeltaF = - dDeltaT ; + } + // controllo se lunghezza entità accettabile + const double MIN_LEN = 10 ; + double dLenXY ; + pArc->GetLength( dLenXY) ; + if ( dDeltaI + dLenXY + dDeltaF < MIN_LEN) { + bToSkip = true ; + return true ; + } + bToSkip = false ; + // modifico gli estremi + if ( dDeltaF > EPS_SMALL) + pArc->ExtendEndByLen( dDeltaF) ; + else if ( dDeltaF < - EPS_SMALL) + pArc->TrimEndAtLen( dLenXY + dDeltaF) ; + if ( dDeltaI > EPS_SMALL) + pArc->ExtendStartByLen( dDeltaI) ; + else if ( dDeltaI < - EPS_SMALL) + pArc->TrimStartAtLen( fabs( dDeltaI)) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Sawing::AreHeadWorkOnSameSide( void) const +{ + return ( ( m_Params.m_nWorkSide == SAW_WS_LEFT && m_Params.m_nHeadSide == SAW_HS_LEFT) || + ( m_Params.m_nWorkSide == SAW_WS_RIGHT && m_Params.m_nHeadSide == SAW_HS_RIGHT)) ; +} \ No newline at end of file diff --git a/Sawing.h b/Sawing.h index e3414d1..3f1915a 100644 --- a/Sawing.h +++ b/Sawing.h @@ -19,6 +19,7 @@ class ICurve ; class ICurveLine ; +class ICurveArc ; //---------------------------------------------------------------------------- class Sawing : public Machining @@ -47,7 +48,7 @@ class Sawing : public Machining bool GetParam( int nType, std::string& sVal) const override ; const ToolData& GetToolData( void) const override ; bool GetGeometry( SELVECTOR& vIds) const override ; - bool AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) override ; + bool AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) override ; bool IsEmpty( void) const override { return ( m_nCuts == 0) ; } @@ -63,16 +64,41 @@ class Sawing : public Machining bool ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* pCrvN, double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, const std::string& sName, int nPvId, int nClId) ; - bool GenerateEntityPv( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, + bool ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve* pCrvN, + double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, + const std::string& sName, int nPvId, int nClId) ; + bool GenerateLinePv( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, + double dElev, double dExtraCut, const string& sName, int nPvId) ; + bool GenerateLineCl( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, + double dElev, double dExtraCut, const string& sName, int nClId) ; + bool ProcessExtArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve* pCrvN, + double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, + const string& sName, int nPvId, int nClId) ; + bool GenerateExtArcPv( const ICurveArc* pArc, const Vector3d& vtStaTool, const Vector3d& vtMidTool, + const Vector3d& vtEndTool, const Vector3d& vtCorr, double dElev, double dExtraCut, const string& sName, int nPvId) ; - bool GenerateEntityCl( const ICurveLine* pLine, const Vector3d& vtTool, const Vector3d& vtCorr, + bool GenerateExtArcCl( const ICurveArc* pArc, const Vector3d& vtStaTool, const Vector3d& vtMidTool, + const Vector3d& vtEndTool, const Vector3d& vtCorr, double dElev, double dExtraCut, const string& sName, int nClId) ; - bool CalculateToolAndCorrVersors( const ICurve* pCurve, Vector3d& vtTool, Vector3d& vtCorr) ; + bool ProcessIntArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve* pCrvN, + double dDepth, double dExtraCut, bool bIsFirst, bool bIsLast, + const string& sName, int nPvId, int nClId) ; + bool GenerateIntArcCl( const ICurveArc* pArc, + const Vector3d& vtStaTool, const Vector3d& vtMidTool, const Vector3d& vtEndTool, + const Vector3d& vtStaCorr, const Vector3d& vtMidCorr, const Vector3d& vtEndCorr, + double dElev, double dExtraCut, const string& sName, int nClId) ; + bool CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, int nWorkSide, double dSideAng, + Vector3d& vtTool, Vector3d& vtCorr) ; bool AdjustForSide( ICurve* pCurve) ; - bool AdjustForEdges( ICurveLine* pLine, double dElev, const Vector3d& vtThick, - bool bIsFirst, bool bIsLast, bool bExtAngPC, bool bExtAngCN, bool& ToSkip) ; + bool AdjustIntArcForSide( ICurve* pCurve, double dSideAng) ; + bool AdjustLineForEdges( ICurveLine* pLine, double dElev, const Vector3d& vtThick, + bool bIsFirst, bool bIsLast, bool bExtAngPC, bool bExtAngCN, bool& ToSkip) ; + bool AdjustArcForEdges( ICurveArc* pArc, double dElev, const Vector3d& vtStaThick, const Vector3d& vtEndThick, + bool bIsFirst, bool bIsLast, bool bExtAngPC, bool bExtAngCN, bool& ToSkip) ; 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) ; + bool AreHeadWorkOnSameSide( void) const ; + private : SELVECTOR m_vId ; // identificativi entità geometriche da lavorare diff --git a/SawingData.cpp b/SawingData.cpp index 6939e22..fa5014a 100644 --- a/SawingData.cpp +++ b/SawingData.cpp @@ -371,7 +371,7 @@ SawingData::VerifyLeadOutType( int nVal) const bool SawingData::VerifyCurveUse( int nVal) const { - return ( nVal == SAW_CRV_SKIP || nVal == SAW_CRV_APPROX || nVal == SAW_CRV_CONVEX) ; + return ( nVal == SAW_CRV_SKIP || nVal == SAW_CRV_APPROX || nVal == SAW_CRV_CONVEX || nVal == SAW_CRV_KEEP) ; } //---------------------------------------------------------------------------- diff --git a/Simulator.cpp b/Simulator.cpp index 049d1da..e11db7e 100644 --- a/Simulator.cpp +++ b/Simulator.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2016 //---------------------------------------------------------------------------- -// File : Simulator.cpp Data : 19.10.15 Versione : 1.6j2 +// File : Simulator.cpp Data : 26.02.16 Versione : 1.6n8 // Contenuto : Implementazione della classe Simulator. // // // // Modifiche : 19.10.15 DS Creazione modulo. -// +// 26.02.16 DS Aggiunta gestione archi. // //---------------------------------------------------------------------------- @@ -173,7 +173,7 @@ Simulator::Move( int& nStatus) case CamData::AS_OK : break ; case CamData::AS_OUTSTROKE : { - DBLVECTOR OutAxes = pCamData->GetAxisVal() ; + DBLVECTOR OutAxes = pCamData->GetAxesVal() ; for ( size_t i = OutAxes.size() ; i < 5 ; ++ i) OutAxes.emplace_back( 0) ; int nStat ; @@ -187,9 +187,9 @@ Simulator::Move( int& nStatus) nStatus = MCH_SIM_ERR ; return false ; } - const DBLVECTOR& AxesEnd = pCamData->GetAxisVal() ; - // Verifico se movimento in rapido - bool bRapid = ( pCamData->GetFeed() < EPS_SMALL) ; + const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ; + // Tipo di movimento + int nMoveType = pCamData->GetMoveType() ; // Calcolo distanza di movimento double dSqDist = 0 ; for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { @@ -198,13 +198,30 @@ Simulator::Move( int& nStatus) dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ; } double dDist = sqrt( dSqDist) ; - m_dCoeff += ( bRapid ? 4 : 1) * m_dStep / dDist ; + m_dCoeff += ( nMoveType == 0 ? 4 : 1) * m_dStep / dDist ; if ( m_dCoeff > 1) m_dCoeff = 1 ; - // Eseguo movimento - for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { - double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; - m_pMchMgr->SetAxisPos( m_AxesName[i], dVal) ; + // Eseguo movimento rapido o lineare + if ( nMoveType != 2 && nMoveType != 3) { + for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { + double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; + m_pMchMgr->SetAxisPos( m_AxesName[i], dVal) ; + } + } + // Eseguo movimento su arco (per ora sempre nel piano XY) + else { + // primi due assi lineari + Point3d ptCen = pCamData->GetAxesCen() ; + double dAngCen = pCamData->GetAxesAngCen() ; + Vector3d vtCurr = Point3d( m_AxesVal[0], m_AxesVal[1], ptCen.z) - ptCen ; + vtCurr.Rotate( Z_AX, m_dCoeff * dAngCen) ; + m_pMchMgr->SetAxisPos( m_AxesName[0], ptCen.x + vtCurr.x) ; + m_pMchMgr->SetAxisPos( m_AxesName[1], ptCen.y + vtCurr.y) ; + // altri assi + for ( size_t i = 2 ; i < m_AxesName.size() ; ++ i) { + double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; + m_pMchMgr->SetAxisPos( m_AxesName[i], dVal) ; + } } // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo