diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 1915a1c..3cc170d 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/EgtMachKernel.vcxproj b/EgtMachKernel.vcxproj index a512e30..e945970 100644 --- a/EgtMachKernel.vcxproj +++ b/EgtMachKernel.vcxproj @@ -287,6 +287,8 @@ copy $(TargetPath) \EgtProg\Dll64 + + @@ -429,6 +431,8 @@ copy $(TargetPath) \EgtProg\Dll64 + + diff --git a/EgtMachKernel.vcxproj.filters b/EgtMachKernel.vcxproj.filters index 69e13c7..a0311e1 100644 --- a/EgtMachKernel.vcxproj.filters +++ b/EgtMachKernel.vcxproj.filters @@ -222,6 +222,12 @@ Source Files\Operations + + Source Files\Machinings + + + Source Files\Operations + @@ -644,6 +650,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/MachConst.h b/MachConst.h index b0330cf..4c6038a 100644 --- a/MachConst.h +++ b/MachConst.h @@ -97,6 +97,8 @@ const std::string MILLMAKER_KEY = "MillMaker" ; const std::string MORTISEMAKER_KEY = "MortiseMaker" ; // Chiave per generatore disegno scalpelli const std::string CHISELMAKER_KEY = "ChiselMaker" ; +// Chiave per generatore disegno waterjet +const std::string WATERJETMAKER_KEY = "WaterJetMaker" ; // Chiave per porta utensili punte a forare (marmo) const std::string DRILLHOLDER_KEY = "DrillHolder" ; // Chiave per porta utensili lame (marmo) diff --git a/MachMgrDBTools.cpp b/MachMgrDBTools.cpp index f88e545..bb9bec5 100644 --- a/MachMgrDBTools.cpp +++ b/MachMgrDBTools.cpp @@ -522,6 +522,7 @@ MachMgr::UpdateStandardToolDraw( const ToolData* pTdata, int nGenCtx, int nToolC break ; case TT_MILL_STD : case TT_MILL_NOTIP : + case TT_WATERJET : bOk = bOk && ExeLuaSetGlobStringVar( "TOOL.TOOLHOLDER", sThPath) ; bOk = bOk && ExeLuaSetGlobNumVar( "TOOL.TOTLEN", dTotLen) ; bOk = bOk && ExeLuaSetGlobNumVar( "TOOL.LEN", dLen) ; @@ -615,6 +616,8 @@ MachMgr::GetToolMakerKeyFromType( int nType) const return MORTISEMAKER_KEY ; case TT_CHISEL_STD : return CHISELMAKER_KEY ; + case TT_WATERJET : + return WATERJETMAKER_KEY ; case TT_COMPO : return "" ; } diff --git a/MillingData.cpp b/MillingData.cpp index 9d461a5..b98749d 100644 --- a/MillingData.cpp +++ b/MillingData.cpp @@ -195,7 +195,7 @@ MillingData::CopyFrom( const MachiningData* pMdata) //---------------------------------------------------------------------------- bool -MillingData::SameAs(const MachiningData* pMdata) const +MillingData::SameAs( const MachiningData* pMdata) const { // se coincide con altro -> uguali if ( pMdata == this) diff --git a/OperationConst.h b/OperationConst.h index 3632e3f..511ea98 100644 --- a/OperationConst.h +++ b/OperationConst.h @@ -1,13 +1,14 @@ //---------------------------------------------------------------------------- // EgalTech 2017-2019 //---------------------------------------------------------------------------- -// File : OperationConst.h Data : 28.05.19 Versione : 2.1e5 +// File : OperationConst.h Data : 08.07.19 Versione : 2.1g2 // Contenuto : Costanti per le operazioni. // // // // Modifiche : 17.08.17 DS Creazione modulo. // 25.05.19 DS Aggiunte SurfRoughing e SurfFinishing. +// 25.05.19 DS Aggiunta WaterJetting. // //---------------------------------------------------------------------------- @@ -30,7 +31,8 @@ static const std::string s_OpeClass[] = {"", "EMkGenMachining", "EMkChiseling", "EMkSurfRoughing", - "EMkSurfFinishing"} ; + "EMkSurfFinishing", + "EMkWaterJetting"} ; //---------------------------------------------------------------------------- // Dal tipo numerico restituisce la classe della operazione @@ -50,6 +52,7 @@ GetOperationClass( int nOpeType) case OPER_CHISELING : return s_OpeClass[10] ; case OPER_SURFROUGHING : return s_OpeClass[11] ; case OPER_SURFFINISHING : return s_OpeClass[12] ; + case OPER_WATERJETTING : return s_OpeClass[13] ; } return s_OpeClass[0] ; } @@ -83,6 +86,8 @@ GetOperationType( const std::string& sOpeClass) return OPER_SURFROUGHING ; else if ( sOpeClass == s_OpeClass[12]) return OPER_SURFFINISHING ; + else if ( sOpeClass == s_OpeClass[13]) + return OPER_WATERJETTING ; else return OPER_NULL ; } \ No newline at end of file diff --git a/ToolsMgr.cpp b/ToolsMgr.cpp index 66cd5f1..10e2bb3 100644 --- a/ToolsMgr.cpp +++ b/ToolsMgr.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2017 +// EgalTech 2015-2019 //---------------------------------------------------------------------------- -// File : ToolsMgr.cpp Data : 02.03.17 Versione : 1.8c1 +// File : ToolsMgr.cpp Data : 08.07.19 Versione : 2.1g2 // Contenuto : Implementazione gestore database utensili. // // @@ -10,6 +10,7 @@ // 21.10.15 DS Aggiunti VERSION e TOOLSIZE in HEADER (default VERSION = 1000 e TOOLSIZE = 26). // Ora VERSION = 1001 e TOOLSIZE = 29. // 02.03.17 DS Aggiunto controllo nome. +// 08.07.19 DS Aggiunto water jet. Ora VERSION = 1002. // //---------------------------------------------------------------------------- @@ -35,7 +36,7 @@ const string TF_HEADER = "[HEADER]" ; const string TF_VERSION = "VERSION" ; const string TF_TOOLSIZE = "TOOLSIZE" ; const string TF_TOTAL = "TOTAL" ; -const int TF_CURR_VER = 1001 ; +const int TF_CURR_VER = 1002 ; //---------------------------------------------------------------------------- ToolsMgr::ToolsMgr( void) @@ -700,7 +701,12 @@ ToolsMgr::GetCurrToolMaxDepth( double& dMaxDepth) const dMaxDepth = m_tdCurrTool.m_dMaxMat ; return true ; } - // utensile composito + // se utensile waterjet + else if ( ( m_tdCurrTool.m_nType & TF_WATERJET) != 0) { + dMaxDepth = m_tdCurrTool.m_dMaxMat ; + return true ; + } + // se utensile composito else if ( ( m_tdCurrTool.m_nType & TF_COMPO) != 0) { // non ancora gestito return false ; diff --git a/WaterJetting.cpp b/WaterJetting.cpp new file mode 100644 index 0000000..1f269f4 --- /dev/null +++ b/WaterJetting.cpp @@ -0,0 +1,2239 @@ +//---------------------------------------------------------------------------- +// EgalTech 2019-2019 +//---------------------------------------------------------------------------- +// File : WaterJetting.cpp Data : 08.07.19 Versione : 2.1g2 +// Contenuto : Implementazione gestione taglio water jet. +// +// +// +// Modifiche : 08.07.19 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "MachMgr.h" +#include "DllMain.h" +#include "WaterJetting.h" +#include "GeoConst.h" +#include "OperationConst.h" +#include "/EgtDev/Include/EGkCurveLine.h" +#include "/EgtDev/Include/EGkCurveArc.h" +#include "/EgtDev/Include/EGkCurveComposite.h" +#include "/EgtDev/Include/EGkArcSpecial.h" +#include "/EgtDev/Include/EGkChainCurves.h" +#include "/EgtDev/Include/EGkOffsetCurve.h" +#include "/EgtDev/Include/EGkCurveAux.h" +#include "/EgtDev/Include/EGkSfrCreate.h" +#include "/EgtDev/Include/EGkSurfTriMesh.h" +#include "/EgtDev/Include/EGkExtText.h" +#include "/EgtDev/Include/EGkUserObjFactory.h" +#include "/EgtDev/Include/EGnStringKeyVal.h" +#include "/EgtDev/Include/EgtPointerOwner.h" + +using namespace std ; + +//------------------------------ Errors -------------------------------------- +// 2301 = "Error in Milling : UpdateToolData failed" +// 2302 = "Error in Milling : Offset not computable" +// 2303 = "Error in Milling : Empty RawBox" +// 2304 = "Error in Milling : Depth not computable" +// 2305 = "Error in Milling : machining depth (xx) bigger than MaxMaterial (yy)" +// 2306 = "Error in Milling : Entity GetElevation" +// 2307 = "Error in Milling : missing aggregate from bottom" +// 2308 = "Error in Milling : path too far from part sides" +// 2309 = "Error in Milling : Approach not computable" +// 2310 = "Error in Milling : LeadIn not computable" +// 2311 = "Error in Milling : LeadOut not computable" +// 2312 = "Error in Milling : Retract not computable" +// 2313 = "Error in Milling : Linear Approx not computable" +// 2314 = "Error in Milling : LeadIn must be out of rawpart" +// 2315 = "Error in Milling : Chaining failed" +// 2316 = "Error in Milling : Tool MaxMaterial too small (xx)" +// 2317 = "Error in Milling : axes values not calculable" +// 2318 = "Error in Milling : outstroke xx" +// 2319 = "Error in Milling : link movements not calculable" +// 2320 = "Error in Milling : link outstroke xx" +// 2321 = "Error in Milling : post apply not calculable" +// 2322 = "Error in Milling : Tool loading failed" +// 2323 = "Error in Milling : machining depth (xxx) bigger than MaxDepth (yyy)" +// 2351 = "Warning in Milling : Skipped entity (xx)" +// 2352 = "Warning in Milling : No machinable path" +// 2353 = "Warning in Milling : Tool name changed (xx)" +// 2354 = "Warning in Milling : Tool data changed (xx)" +// 2355 = "Warning in Milling : skipped Path too short" +// 2356 = "Warning in Milling : machining step too small (xx)" +// 2357 = "Warning in Milling : machining step (xxx) bigger than MaxMaterial (yyy)" +// 2358 = "Warning in Milling : machining depth (xxx) bigger than MaxMaterial (yyy)" + +//---------------------------------------------------------------------------- +USEROBJ_REGISTER( GetOperationClass( OPER_WATERJETTING), WaterJetting) ; + +//---------------------------------------------------------------------------- +const string& +WaterJetting::GetClassName( void) const +{ + return USEROBJ_GETNAME( WaterJetting) ; +} + +//---------------------------------------------------------------------------- +WaterJetting* +WaterJetting::Clone( void) const +{ + // alloco oggetto + WaterJetting* pWJ = new(nothrow) WaterJetting ; + // eseguo copia dei dati + if ( pWJ != nullptr) { + try { + pWJ->m_vId = m_vId ; + pWJ->m_pMchMgr = m_pMchMgr ; + pWJ->m_nPhase = m_nPhase ; + pWJ->m_Params = m_Params ; + pWJ->m_TParams = m_TParams ; + pWJ->m_dTHoldLen = m_dTHoldLen ; + pWJ->m_dTHoldDiam = m_dTHoldDiam ; + pWJ->m_nStatus = m_nStatus ; + pWJ->m_nMills = m_nMills ; + pWJ->m_nHeadSolCh = m_nHeadSolCh ; + } + catch( ...) { + delete pWJ ; + return nullptr ; + } + } + // ritorno l'oggetto + return pWJ ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Dump( string& sOut, bool bMM, const char* szNewLine) const +{ + sOut += GetClassName() + "[mm]" + szNewLine ; + sOut += KEY_PHASE + EQUAL + ToString( m_nPhase) + szNewLine ; + sOut += KEY_IDS + EQUAL + ToString( m_vId) + szNewLine ; + for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) + sOut += m_Params.ToString( i) + szNewLine ; + for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) + sOut += m_TParams.ToString( i) + szNewLine ; + sOut += KEY_NUM + EQUAL + ToString( m_nMills) + szNewLine ; + sOut += KEY_STAT + EQUAL + ToString( m_nStatus) + szNewLine ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Save( int nBaseId, STRVECTOR& vString) const +{ + try { + int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() + 3 ; + vString.insert( vString.begin(), nSize, "") ; + int k = - 1 ; + if ( ! SetVal( KEY_IDS, m_vId, vString[++k])) + return false ; + for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) + vString[++k] = m_Params.ToString( i) ; + for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) + vString[++k] = m_TParams.ToString( i) ; + if ( ! SetVal( KEY_PHASE, m_nPhase, vString[++k])) + return false ; + if ( ! SetVal( KEY_NUM, m_nMills, vString[++k])) + return false ; + if ( ! SetVal( KEY_STAT, m_nStatus, vString[++k])) + return false ; + } + catch( ...) { + return false ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Load( const STRVECTOR& vString, int nBaseGdbId) +{ + int nSize = int( vString.size()) ; + // lista identificativi geometrie da lavorare + int k = - 1 ; + if ( k >= nSize - 1 || ! GetVal( vString[++k], KEY_IDS, m_vId)) + return false ; + for ( auto& Sel : m_vId) + Sel.nId += nBaseGdbId ; + // parametri lavorazione + for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) { + int nKey ; + if ( k >= nSize - 1 || ! m_Params.FromString( vString[++k], nKey) || nKey != i) { + if ( m_Params.IsOptional( i)) + -- k ; + else + return false ; + } + } + // parametri utensile + for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) { + int nKey ; + if ( k >= nSize - 1 || ! m_TParams.FromString( vString[++k], nKey) || nKey != i) + return false ; + } + // parametri di stato + while ( k < nSize - 1) { + // separo chiave da valore + string sKey, sVal ; + SplitFirst( vString[++k], "=", sKey, sVal) ; + // leggo + if ( sKey == KEY_PHASE) { + if ( ! FromString( sVal, m_nPhase)) + return false ; + } + else if ( sKey == KEY_NUM) { + if ( ! FromString( sVal, m_nMills)) + return false ; + } + else if ( sKey == KEY_STAT) { + if ( ! FromString( sVal, m_nStatus)) + return false ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +WaterJetting::WaterJetting( void) +{ + m_Params.m_sName = "*" ; + m_Params.m_sToolName = "*" ; + m_TParams.m_sName = "*" ; + m_TParams.m_sHead = "*" ; + m_dTHoldLen = 0 ; + m_dTHoldDiam = 0 ; + m_nStatus = MCH_ST_TO_VERIFY ; + m_nMills = 0 ; + m_nHeadSolCh = MCH_SCC_NONE ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Prepare( const string& sMillName) +{ + // verifico il gestore lavorazioni + if ( m_pMchMgr == nullptr) + return false ; + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero il gestore DB lavorazioni della macchina corrente + MachiningsMgr* pMMgr = m_pMchMgr->GetCurrMachiningsMgr() ; + if ( pMMgr == nullptr) + return false ; + // ricerca della lavorazione di libreria con il nome indicato + const WaterJettingData* pDdata = GetWaterJettingData( pMMgr->GetMachining( sMillName)) ; + if ( pDdata == nullptr) + return false ; + m_Params = *pDdata ; + // ricerca dell'utensile usato dalla lavorazione + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + m_TParams = *pTdata ; + m_Params.m_sToolName = m_TParams.m_sName ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::SetParam( int nType, bool bVal) +{ + switch ( nType) { + case MPA_INVERT : + if ( bVal != m_Params.m_bInvert) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_bInvert = bVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::SetParam( int nType, int nVal) +{ + switch ( nType) { + case MPA_WORKSIDE : + if ( ! m_Params.VerifyWorkSide( nVal)) + return false ; + if ( nVal != m_Params.m_nWorkSide) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_nWorkSide = nVal ; + return true ; + case MPA_LEADINTYPE : + if ( ! m_Params.VerifyLeadInType( nVal)) + return false ; + if ( nVal != m_Params.m_nLeadInType) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_nLeadInType = nVal ; + return true ; + case MPA_LEADOUTTYPE : + if ( ! m_Params.VerifyLeadOutType( nVal)) + return false ; + if ( nVal != m_Params.m_nLeadOutType) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_nLeadOutType = nVal ; + return true ; + case MPA_SCC : + if ( ! m_Params.VerifySolCh( nVal)) + return false ; + if ( nVal != m_Params.m_nSolCh) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_nSolCh = nVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::SetParam( int nType, double dVal) +{ + switch ( nType) { + case MPA_SPEED : + if ( ! m_TParams.VerifySpeed( dVal)) + return false ; + if ( abs( m_TParams.m_dSpeed - dVal) < EPS_MACH_ANG_PAR) + dVal = 0 ; + if ( abs( dVal - m_Params.m_dSpeed) > EPS_MACH_ANG_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dSpeed = dVal ; + return true ; + case MPA_FEED : + if ( abs( m_TParams.m_dFeed - dVal) < EPS_MACH_LEN_PAR) + dVal = 0 ; + if ( abs( dVal - m_Params.m_dFeed) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dFeed = dVal ; + return true ; + case MPA_STARTFEED : + if ( abs( m_TParams.m_dStartFeed - dVal) < EPS_MACH_LEN_PAR) + dVal = 0 ; + if ( abs( dVal - m_Params.m_dStartFeed) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dStartFeed = dVal ; + return true ; + case MPA_ENDFEED : + if ( abs( m_TParams.m_dEndFeed - dVal) < EPS_MACH_LEN_PAR) + dVal = 0 ; + if ( abs( dVal - m_Params.m_dEndFeed) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dEndFeed = dVal ; + return true ; + case MPA_TIPFEED : + if ( abs( m_TParams.m_dTipFeed - dVal) < EPS_MACH_LEN_PAR) + dVal = 0 ; + if ( abs( dVal - m_Params.m_dTipFeed) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dTipFeed = dVal ; + return true ; + case MPA_OFFSR : + if ( abs( m_TParams.m_dOffsR - dVal) < EPS_MACH_LEN_PAR) + dVal = UNKNOWN_PAR ; + if ( abs( dVal - m_Params.m_dOffsR) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dOffsR = dVal ; + return true ; + case MPA_OFFSL : + if ( abs( m_TParams.m_dOffsL - dVal) < EPS_MACH_LEN_PAR) + dVal = UNKNOWN_PAR ; + if ( abs( dVal - m_Params.m_dOffsL) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dOffsL = dVal ; + return true ; + case MPA_DEPTH : { + string sVal = ToString( dVal) ; + if ( sVal != m_Params.m_sDepth) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sDepth = sVal ; + } return true ; + case MPA_STARTPOS : + if ( abs( dVal - m_Params.m_dStartPos) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dStartPos = dVal ; + return true ; + case MPA_OVERL : + if ( abs( dVal - m_Params.m_dOverlap) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dOverlap = dVal ; + return true ; + case MPA_STARTADDLEN : + if ( abs( dVal - m_Params.m_dStartAddLen) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dStartAddLen = dVal ; + return true ; + case MPA_ENDADDLEN : + if ( abs( dVal - m_Params.m_dEndAddLen) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dEndAddLen = dVal ; + return true ; + case MPA_LITANG : + if ( abs( dVal - m_Params.m_dLiTang) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLiTang = dVal ; + return true ; + case MPA_LIPERP : + if ( abs( dVal - m_Params.m_dLiPerp) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLiPerp = dVal ; + return true ; + case MPA_LIELEV : + if ( abs( dVal - m_Params.m_dLiElev) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLiElev = dVal ; + return true ; + case MPA_LICOMPLEN : + if ( abs( dVal - m_Params.m_dLiCompLen) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLiCompLen = dVal ; + return true ; + case MPA_LOTANG : + if ( abs( dVal - m_Params.m_dLoTang) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLoTang = dVal ; + return true ; + case MPA_LOPERP : + if ( abs( dVal - m_Params.m_dLoPerp) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLoPerp = dVal ; + return true ; + case MPA_LOELEV : + if ( abs( dVal - m_Params.m_dLoElev) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLoElev = dVal ; + return true ; + case MPA_LOCOMPLEN : + if ( abs( dVal - m_Params.m_dLoCompLen) > EPS_MACH_LEN_PAR) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dLoCompLen = dVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::SetParam( int nType, const string& sVal) +{ + switch ( nType) { + case MPA_TOOL : { + const ToolData* pTdata ; + if ( ! m_Params.VerifyTool( m_pMchMgr->GetCurrToolsMgr(), sVal, pTdata)) + return false ; + if ( ! SameTool( m_TParams, *pTdata)) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sToolName = sVal ; + m_Params.m_ToolUuid = pTdata->m_Uuid ; + m_TParams = *pTdata ; + } return true ; + case MPA_DEPTH_STR : + if ( sVal != m_Params.m_sDepth) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sDepth = sVal ; + return true ; + case MPA_SYSNOTES : + if ( sVal != m_Params.m_sSysNotes) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sSysNotes = sVal ; + return true ; + case MPA_USERNOTES : + if ( sVal != m_Params.m_sUserNotes) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sUserNotes = sVal ; + return true ; + case MPA_INITANGS : + if ( sVal != m_Params.m_sInitAngs) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sInitAngs = sVal ; + return true ; + case MPA_BLOCKEDAXIS : + if ( sVal != m_Params.m_sBlockedAxis) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_sBlockedAxis = sVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::SetGeometry( const SELVECTOR& vIds) +{ + // verifico validità gestore DB geometrico + if ( m_pGeomDB == nullptr) + return false ; + // reset della geometria corrente + m_vId.clear() ; + // verifico che gli identificativi rappresentino delle entità ammissibili (tutte curve, tutti testi o tutte facce) + int nType = GEO_NONE ; + for ( const auto& Id : vIds) { + // test sull'entità + int nSubs ; + if ( ! VerifyGeometry( Id, nSubs, nType)) { + string sInfo = "Warning in Milling : Skipped entity " + ToString( Id) ; + m_pMchMgr->SetWarning( 2351, sInfo) ; + continue ; + } + // posso aggiungere alla lista + m_vId.emplace_back( Id) ; + } + // aggiorno lo stato + m_nStatus |= MCH_ST_GEO_MODIF ; + // restituisco presenza geometria da lavorare + return ( ! m_vId.empty() || vIds.empty()) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Preview( bool bRecalc) +{ + // reset numero percorsi di lavoro generati + m_nMills = 0 ; + + // verifico validità gestore DB geometrico e Id del gruppo + if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) + return false ; + + // recupero gruppo per geometria ausiliaria + int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ; + bool bChain = false ; + // se non c'è, lo aggiungo + if ( nAuxId == GDB_ID_NULL) { + nAuxId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nAuxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nAuxId, MCH_AUX) ; + m_pGeomDB->SetStatus( nAuxId, GDB_ST_OFF) ; + bChain = true ; + } + // altrimenti, se chiesto ricalcolo, lo svuoto + else if ( bRecalc) { + m_pGeomDB->EmptyGroup( nAuxId) ; + bChain = true ; + } + + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + m_pMchMgr->SetLastError( 2301, "Error in Milling : UpdateToolData failed") ; + return false ; + } + m_nHeadSolCh = m_pMchMgr->GetCurrMachine()->GetHeadSolCh( m_TParams.m_sHead) ; + + // aggiorno anche se non necessario, comunque operazione veloce + + // rendo corrente l'utensile usato nella lavorazione + if ( ! m_pMchMgr->SetCalcTool( m_TParams.m_sName, m_TParams.m_sHead, m_TParams.m_nExit)) { + m_pMchMgr->SetLastError( 2322, "Error in Milling : Tool loading failed") ; + return false ; + } + // recupero i dati del portautensile + int nToolId = m_pMchMgr->GetCalcTool() ; + m_dTHoldLen = 0 ; + m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ; + m_dTHoldDiam = 0 ; + m_pGeomDB->GetInfo( nToolId, TTH_DIAM, m_dTHoldDiam) ; + + // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria + if ( bChain && ! Chain( nAuxId)) { + m_pMchMgr->SetLastError( 2315, "Error in Milling : Chaining failed") ; + return false ; + } + + // recupero gruppo per geometria di Preview + int nPvId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_PV) ; + // se non c'è, lo aggiungo + if ( nPvId == GDB_ID_NULL) { + nPvId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nPvId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPvId, MCH_PV) ; + } + // altrimenti lo svuoto + else + m_pGeomDB->EmptyGroup( nPvId) ; + + // lavoro ogni singola catena + int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; + while ( nPathId != GDB_ID_NULL) { + if ( ! ProcessPath( nPathId, nPvId, GDB_ID_NULL)) + return false ; + nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Apply( bool bRecalc, bool bPostApply) +{ + // reset numero percorsi di lavoro generati + int nCurrMills = m_nMills ; + m_nMills = 0 ; + + // verifico validità gestore DB geometrico e Id del gruppo + if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) + return false ; + + // aggiorno dati geometrici dell'utensile + bool bToolChanged = true ; + if ( ! UpdateToolData( &bToolChanged)) { + m_pMchMgr->SetLastError( 2301, "Error in Milling : UpdateToolData failed") ; + return false ; + } + m_nHeadSolCh = m_pMchMgr->GetCurrMachine()->GetHeadSolCh( m_TParams.m_sHead) ; + + // verifico se necessario continuare nell'aggiornamento + if ( ! bRecalc && ! bToolChanged && + ( m_nStatus == MCH_ST_OK || ( ! bPostApply && m_nStatus == MCH_ST_NO_POSTAPPL))) { + m_nMills = nCurrMills ; + LOG_DBG_INFO( GetEMkLogger(), "Milling apply skipped : status already ok") ; + return true ; + } + m_nStatus = MCH_ST_TO_VERIFY ; + + // recupero gruppo per geometria ausiliaria + int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ; + bool bChain = false ; + // se non c'è, lo aggiungo + if ( nAuxId == GDB_ID_NULL) { + nAuxId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nAuxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nAuxId, MCH_AUX) ; + m_pGeomDB->SetStatus( nAuxId, GDB_ST_OFF) ; + bChain = true ; + } + // altrimenti, se chiesto ricalcolo, lo svuoto + else if ( bRecalc) { + m_pGeomDB->EmptyGroup( nAuxId) ; + bChain = true ; + } + + // rendo corrente l'utensile usato nella lavorazione + if ( ! m_pMchMgr->SetCalcTool( m_TParams.m_sName, m_TParams.m_sHead, m_TParams.m_nExit)) { + m_pMchMgr->SetLastError( 2322, "Error in Milling : Tool loading failed") ; + return false ; + } + // recupero i dati del portautensile + int nToolId = m_pMchMgr->GetCalcTool() ; + m_dTHoldLen = 0 ; + m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ; + m_dTHoldDiam = 0 ; + m_pGeomDB->GetInfo( nToolId, TTH_DIAM, m_dTHoldDiam) ; + + // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria + if ( bChain && ! Chain( nAuxId)) { + m_pMchMgr->SetLastError( 2315, "Error in Milling : Chaining failed") ; + return false ; + } + + // recupero gruppo per geometria di lavorazione (Cutter Location) + int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; + // se non c'è, lo aggiungo + if ( nClId == GDB_ID_NULL) { + nClId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nClId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nClId, MCH_CL) ; + } + // altrimenti lo svuoto + else + m_pGeomDB->EmptyGroup( nClId) ; + + // lavoro ogni singola catena + bool bOk = true ; + int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; + while ( nPathId != GDB_ID_NULL) { + if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) + bOk = false ; + nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + } + if ( ! bOk) + return false ; + + // assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso + CalcAndSetBBox( nClId) ; + + // eseguo aggiornamento assi macchina e collegamento con operazione precedente + if ( ! Update( bPostApply)) + return false ; + + // aggiorno stato della lavorazione + m_nStatus = ( bPostApply ? MCH_ST_OK : MCH_ST_NO_POSTAPPL) ; + // dichiaro successiva da aggiornare + UpdateFollowingOperationsStatus( MCH_ST_OTH_MODIF) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Update( bool bPostApply) +{ + // verifico validità gestore DB geometrico e Id del gruppo + if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) + return false ; + + // se lavorazione vuota, esco + if ( m_nMills == 0) { + m_pMchMgr->SetWarning( 2352, "Warning in Milling : No machinable path") ; + return true ; + } + + // imposto eventuale asse bloccato da lavorazione + if ( ! m_Params.m_sBlockedAxis.empty()) { + string sAxis, sVal ; + Split( m_Params.m_sBlockedAxis, "=", true, sAxis, sVal) ; + double dVal = 0 ; + FromString( sVal, dVal) ; + m_pMchMgr->ClearRotAxisBlock() ; + m_pMchMgr->SetRotAxisBlock( sAxis, dVal) ; + } + + // calcolo gli assi macchina + string sHint = ExtractHint( m_Params.m_sUserNotes) ; + if ( ! m_Params.m_sInitAngs.empty()) + sHint = m_Params.m_sInitAngs ; + if ( ! CalculateAxesValues( sHint)) { + string sInfo = m_pMchMgr->GetOutstrokeInfo() ; + if ( sInfo.empty()) + m_pMchMgr->SetLastError( 2317, "Error in Milling : axes values not calculable") ; + else + m_pMchMgr->SetLastError( 2318, "Error in Milling : outstroke ") ; + return false ; + } + + // gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine della lavorazione + if ( ! AdjustStartEndMovements()) { + string sInfo = m_pMchMgr->GetOutstrokeInfo() ; + if ( sInfo.empty()) + m_pMchMgr->SetLastError( 2319, "Error in Milling : link movements not calculable") ; + else + m_pMchMgr->SetLastError( 2320, "Error in Milling : link outstroke ") ; + return false ; + } + + // esecuzione eventuali personalizzazioni + if ( bPostApply && ! PostApply()) { + m_pMchMgr->SetLastError( 2321, "Error in Milling : post apply not calculable") ; + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetParam( int nType, bool& bVal) const +{ + switch ( nType) { + case MPA_INVERT : + bVal = m_Params.m_bInvert ; + return true ; + } + bVal = false ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetParam( int nType, int& nVal) const +{ + switch ( nType) { + case MPA_TYPE : + nVal = MT_WATERJETTING ; + return true ; + case MPA_WORKSIDE : + nVal = m_Params.m_nWorkSide ; + return true ; + case MPA_LEADINTYPE : + nVal = m_Params.m_nLeadInType ; + return true ; + case MPA_LEADOUTTYPE : + nVal = m_Params.m_nLeadOutType ; + return true ; + case MPA_SCC : + nVal = m_Params.m_nSolCh ; + return true ; + } + nVal = 0 ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetParam( int nType, double& dVal) const +{ + switch ( nType) { + case MPA_SPEED : + dVal = GetSpeed() ; + return true ; + case MPA_FEED : + dVal = GetFeed() ; + return true ; + case MPA_STARTFEED : + dVal = GetStartFeed() ; + return true ; + case MPA_ENDFEED : + dVal = GetEndFeed() ; + return true ; + case MPA_TIPFEED : + dVal = GetTipFeed() ; + return true ; + case MPA_OFFSR : + dVal = GetOffsR() ; + return true ; + case MPA_OFFSL : + dVal = GetOffsL() ; + return true ; + case MPA_STARTPOS : + dVal = m_Params.m_dStartPos ; + return true ; + case MPA_OVERL : + dVal = m_Params.m_dOverlap ; + return true ; + case MPA_STARTADDLEN : + dVal = m_Params.m_dStartAddLen ; + return true ; + case MPA_ENDADDLEN : + dVal = m_Params.m_dEndAddLen ; + return true ; + case MPA_LITANG : + dVal = m_Params.m_dLiTang ; + return true ; + case MPA_LIPERP : + dVal = m_Params.m_dLiPerp ; + return true ; + case MPA_LIELEV : + dVal = m_Params.m_dLiElev ; + return true ; + case MPA_LICOMPLEN : + dVal = m_Params.m_dLiCompLen ; + return true ; + case MPA_LOTANG : + dVal = m_Params.m_dLoTang ; + return true ; + case MPA_LOPERP : + dVal = m_Params.m_dLoPerp ; + return true ; + case MPA_LOELEV : + dVal = m_Params.m_dLoElev ; + return true ; + case MPA_LOCOMPLEN : + dVal = m_Params.m_dLoCompLen ; + return true ; + } + dVal = 0 ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetParam( int nType, string& sVal) const +{ + switch ( nType) { + case MPA_NAME : + sVal = m_Params.m_sName ; + return true ; + case MPA_TOOL : + sVal = m_Params.m_sToolName ; + return true ; + case MPA_DEPTH_STR : + sVal = m_Params.m_sDepth ; + return true ; + case MPA_TUUID : + sVal = ToString( m_Params.m_ToolUuid) ; + return true ; + case MPA_UUID : + sVal = ToString( m_Params.m_Uuid) ; + return true ; + case MPA_SYSNOTES : + sVal = m_Params.m_sSysNotes ; + return true ; + case MPA_USERNOTES : + sVal = m_Params.m_sUserNotes ; + return true ; + case MPA_INITANGS : + sVal = m_Params.m_sInitAngs ; + return true ; + case MPA_BLOCKEDAXIS : + sVal = m_Params.m_sBlockedAxis ; + return true ; + } + sVal = "" ; + return false ; +} + +//---------------------------------------------------------------------------- +const ToolData& +WaterJetting::GetToolData( void) const +{ + return m_TParams ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::UpdateToolData( bool* pbChanged) +{ + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero l'utensile nel DB utensili + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + // verifico se sono diversi (ad esclusione del nome) + m_TParams.m_sName = pTdata->m_sName ; + bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // aggiorno comunque i parametri + m_TParams = *pTdata ; + // eventuali segnalazioni + if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { + string sInfo = "Warning in Milling : tool name changed (" + + m_Params.m_sToolName + "->" + m_TParams.m_sName + ")" ; + m_pMchMgr->SetWarning( 2353, sInfo) ; + m_Params.m_sToolName = m_TParams.m_sName ; + } + if ( bChanged) { + string sInfo = "Warning in Milling : tool data changed (" + + m_Params.m_sToolName + ")" ; + m_pMchMgr->SetWarning( 2354, sInfo) ; + } + // se definito parametro di ritorno, lo assegno + if ( pbChanged != nullptr) + *pbChanged = bChanged ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetGeometry( SELVECTOR& vIds) const +{ + // restituisco l'elenco delle entità + vIds = m_vId ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::VerifyGeometry( SelData Id, int& nSubs, int& nType) +{ + // ammessi : curve, testi, facce di trimesh o regioni + const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; + if ( pGObj == nullptr) + return false ; + // se ammesse curve ed è tale + if ( ( nType == GEO_NONE || nType == GEO_CURVE) && ( pGObj->GetType() & GEO_CURVE) != 0) { + nType = GEO_CURVE ; + const ICurve* pCurve = nullptr ; + // se direttamente la curva + if ( Id.nSub == SEL_SUB_ALL) { + pCurve = ::GetCurve( pGObj) ; + if ( pCurve == nullptr) + return false ; + if ( pCurve->GetType() == CRV_COMPO) + nSubs = ::GetCurveComposite( pCurve)->GetCurveCount() ; + else + nSubs = 0 ; + } + // altrimenti sottocurva di composita + else { + const ICurveComposite* pCompo = GetCurveComposite( pGObj) ; + pCurve = ( pCompo != nullptr ? pCompo->GetCurve( Id.nSub) : nullptr) ; + if ( pCurve == nullptr) + return false ; + nSubs = 0 ; + } + return true ; + } + // se altrimenti ammessi testi ed è tale + else if ( ( nType == GEO_NONE || nType == EXT_TEXT) && pGObj->GetType() == EXT_TEXT) { + nType = EXT_TEXT ; + const IExtText* pText = ::GetExtText( pGObj) ; + if ( pText == nullptr) + return false ; + // tutto bene + nSubs = 0 ; + return true ; + } + // se altrimenti ammesse superfici trimesh ed è tale + else if ( ( nType == GEO_NONE || nType == SRF_TRIMESH) && pGObj->GetType() == SRF_TRIMESH) { + nType = SRF_TRIMESH ; + const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ; + if ( pSurf == nullptr) + return false ; + // se direttamente la superficie + if ( Id.nSub == SEL_SUB_ALL) { + // deve avere una sola faccia + if ( pSurf->GetFacetCount() != 1) + return false ; + nSubs = 1 ; + } + // altrimenti faccia di superficie trimesh + else { + // se faccia non esistente + if ( Id.nSub > pSurf->GetFacetCount()) + return false ; + nSubs = 0 ; + } + return true ; + } + // se altrimenti ammesse regioni ed è tale + else if ( ( nType == GEO_NONE || nType == SRF_FLATRGN) && pGObj->GetType() == SRF_FLATRGN) { + nType = SRF_FLATRGN ; + const ISurfFlatRegion* pReg = ::GetSurfFlatRegion( pGObj) ; + if ( pReg == nullptr) + return false ; + // se direttamente la regione + if ( Id.nSub == SEL_SUB_ALL) { + nSubs = pReg->GetChunkCount() ; + } + // altrimenti chunk di regione + else { + // se chunk non esistente + if ( Id.nSub >= pReg->GetChunkCount()) + return false ; + // tutto bene + nSubs = 0 ; + } + return true ; + } + // altrimenti errore + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetCurves( SelData Id, ICURVEPLIST& lstPC) +{ + // ammessi : curve, testi, facce di trimesh o regioni + const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; + if ( pGObj == nullptr) + return false ; + // ne recupero il riferimento globale + Frame3d frGlob ; + if ( ! m_pGeomDB->GetGlobFrame( Id.nId, frGlob)) + return false ; + // se curva + if ( ( pGObj->GetType() & GEO_CURVE) != 0) { + PtrOwner pCurve ; + // se direttamente curva + if ( Id.nSub == SEL_SUB_ALL) { + // recupero la curva + const ICurve* pOriCurve = ::GetCurve( pGObj) ; + if ( pOriCurve == nullptr) + return false ; + // la duplico + pCurve.Set( pOriCurve->Clone()) ; + // se estrusione mancante, imposto default + Vector3d vtExtr ; + if ( ! pCurve->GetExtrusion( vtExtr) || vtExtr.IsSmall()) + pCurve->SetExtrusion( Z_AX) ; + } + // altrimenti sottocurva di composita + else { + // recupero la composita + const ICurveComposite* pCompo = GetCurveComposite( pGObj) ; + if ( pCompo == nullptr) + return false ; + // recupero la curva semplice + const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ; + if ( pOriCurve == nullptr) + return false ; + // la duplico + pCurve.Set( pOriCurve->Clone()) ; + // recupero estrusione e spessore + Vector3d vtExtr ; + if ( ! pCompo->GetExtrusion( vtExtr) || vtExtr.IsSmall()) + vtExtr = Z_AX ; + pCurve->SetExtrusion( vtExtr) ; + double dThick ; + if ( pCompo->GetThickness( dThick)) + pCurve->SetThickness( dThick) ; + } + if ( IsNull( pCurve)) + return false ; + // la porto in globale + pCurve->ToGlob( frGlob) ; + // la restituisco + lstPC.emplace_back( Release( pCurve)) ; + return true ; + } + // se altrimenti testo + else if ( pGObj->GetType() == EXT_TEXT) { + // recupero il testo + const IExtText* pText = ::GetExtText( pGObj) ; + if ( pText == nullptr) + return false ; + // recupero l'outline del testo + if ( ! pText->GetOutline( lstPC)) + return false ; + // porto le curve in globale + for ( auto pCrv : lstPC) + pCrv->ToGlob( frGlob) ; + // ritorno + return true ; + } + // altrimenti errore + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::Chain( int nGrpDestId) +{ + // vettore puntatori alle curve + ICURVEPOVECTOR vpCrvs ; + vpCrvs.reserve( m_vId.size()) ; + // vettore selettori delle curve originali + SELVECTOR vInds ; + vInds.reserve( m_vId.size()) ; + // recupero tutte le curve e le porto in globale + for ( const auto& Id : m_vId) { + // prendo le curve + ICURVEPLIST lstPC ; + if ( ! GetCurves( Id, lstPC)) { + string sInfo = "Warning in Milling : Skipped entity " + ToString( Id) ; + m_pMchMgr->SetWarning( 2351, sInfo) ; + } + for ( auto pCrv : lstPC) { + vpCrvs.emplace_back( pCrv) ; + vInds.emplace_back( Id) ; + } + } + // preparo i dati per il concatenamento + bool bFirst = true ; + Point3d ptNear = ORIG ; + double dToler = 10 * EPS_SMALL ; + ChainCurves chainC ; + chainC.Init( true, dToler, int( vpCrvs.size())) ; + for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) { + // recupero la curva e il suo riferimento + ICurve* pCrv = vpCrvs[i] ; + if ( pCrv == nullptr) + continue ; + // recupero i dati della curva necessari al concatenamento e li assegno + Point3d ptStart, ptEnd ; + Vector3d vtStart, vtEnd ; + if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetStartDir( vtStart) || + ! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd)) + return false ; + if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd)) + return false ; + // se prima curva, assegno inizio della ricerca + if ( bFirst) { + ptNear = ptStart + 10 * EPS_SMALL * vtStart ; + bFirst = false ; + } + } + // recupero i percorsi concatenati + int nCount = 0 ; + INTVECTOR vnId2 ; + while ( chainC.GetChainFromNear( ptNear, false, vnId2)) { + // creo una curva composita + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return false ; + // estrusione e spessore + Vector3d vtExtr = Z_AX ; + double dThick = 0 ; + // vettore Id originali + SELVECTOR vId2 ; + vId2.reserve( vnId2.size()) ; + // recupero le curve semplici e le inserisco nella curva composita + for ( size_t i = 0 ; i < vnId2.size() ; ++ i) { + int nId = abs( vnId2[i]) - 1 ; + bool bInvert = ( vnId2[i] < 0) ; + vId2.emplace_back( vInds[nId]) ; + // recupero la curva + ICurve* pCrv = vpCrvs[nId] ; + // se necessario, la inverto + if ( bInvert) + pCrv->Invert() ; + // recupero eventuali estrusione e spessore + Vector3d vtTemp ; + if ( pCrv->GetExtrusion( vtTemp)) { + vtExtr = vtTemp ; + double dTemp ; + if ( pCrv->GetThickness( dTemp) && abs( dTemp) > abs( dThick)) + dThick = dTemp ; + } + // la aggiungo alla curva composta + if ( ! pCrvCompo->AddCurve( ::Release( vpCrvs[nId]), true, dToler)) + return false ; + } + // se non sono state inserite curve, vado oltre + if ( pCrvCompo->GetCurveCount() == 0) + continue ; + // imposto estrusione e spessore + pCrvCompo->SetExtrusion( vtExtr) ; + pCrvCompo->SetThickness( dThick) ; + // aggiorno il nuovo punto vicino + pCrvCompo->GetEndPoint( ptNear) ; + // se utile, approssimo con archi + if ( ! ApproxWithArcsIfUseful( pCrvCompo)) + return false ; + // creo nuovo gruppo + int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDestId, Frame3d()) ; + if ( nPathId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( ++ nCount)) ; + m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( vId2)) ; + // inserisco la curva composita nel gruppo destinazione + int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, ::Release( pCrvCompo)) ; + if ( nNewId == GDB_ID_NULL) + return false ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) const +{ + // se utensile lama + if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0) { + // traslazione opposta a quanto fatto in AdjustPathDrawForSaw + double dOffset = 0.5 * m_TParams.m_dTDiam - 10 * EPS_SMALL ; + ptP.Translate( dOffset * pCamData->GetCorrDir()) ; + } + // negli altri casi, non devo fare alcunché + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AdjustArcCenterForAxesCalc( const CamData* pCamData, Point3d& ptCen) const +{ + // se utensile lama + if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0) { + // recupero il precedente movimento + int nPrevId = m_pGeomDB->GetPrev( pCamData->GetOwner()) ; + CamData* pPrevCamData = GetCamData( m_pGeomDB->GetUserObj( nPrevId)) ; + if ( pPrevCamData == nullptr) + return false ; + // se versori correzione uguali, correggo il centro + if ( AreSameVectorApprox( pCamData->GetCorrDir(), pPrevCamData->GetCorrDir())) { + // traslazione opposta a quanto fatto in AdjustPathDrawForSaw + double dOffset = 0.5 * m_TParams.m_dTDiam - 10 * EPS_SMALL ; + ptCen.Translate( dOffset * pCamData->GetCorrDir()) ; + } + } + // negli altri casi, non devo fare alcunché + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) +{ + // recupero gruppo per geometria temporanea + const string GRP_TEMP = "Temp" ; + int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; + // se non c'è, lo aggiungo + if ( nTempId == GDB_ID_NULL) { + nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nTempId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nTempId, GRP_TEMP) ; + } + // altrimenti lo svuoto + else + m_pGeomDB->EmptyGroup( nTempId) ; + // in ogni caso lo dichiaro temporaneo e non visibile + m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; + m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; + + // copio la curva composita da elaborare + int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; + if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO) + return false ; + int nCopyId = m_pGeomDB->CopyGlob( nCrvId, GDB_ID_NULL, nTempId) ; + if ( nCopyId == GDB_ID_NULL) + return false ; + ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId)) ; + + // converto in archi e rette + pCompo->ArcsBezierCurvesToArcsPerpExtr( LIN_TOL_MID, ANG_TOL_STD_DEG) ; + + // eventuale inversione percorso + if ( m_Params.m_bInvert) + pCompo->Invert() ; + + // recupero direzione utensile da estrusione e spessore + Vector3d vtTool ; + pCompo->GetExtrusion( vtTool) ; + if ( vtTool.IsSmall()) + vtTool = Z_AX ; + double dThick ; + pCompo->GetThickness( dThick) ; + + // se percorso chiuso con inizio/fine su angolo interno, porto la partenza a metà del primo lato + if ( pCompo->IsClosed()) { + Vector3d vtStart, vtEnd ; + pCompo->GetStartDir( vtStart) ; + pCompo->GetEndDir( vtEnd) ; + if ( ! AreSameVectorApprox( vtStart, vtEnd)) { + bool bAngCCW = ( ( vtEnd ^ vtStart) * vtTool > 0.0) ; + if ( m_Params.m_nWorkSide == WJET_WS_CENTER || + ( m_Params.m_nWorkSide == WJET_WS_RIGHT && ! bAngCCW) || + ( m_Params.m_nWorkSide == WJET_WS_LEFT && bAngCCW)) + pCompo->ChangeStartPoint( 0.5) ; + } + } + + // eventuali allungamenti/accorciamenti per percorso aperto o chiuso senza sovrapposizione + if ( ! pCompo->IsClosed() || m_Params.m_dOverlap < EPS_SMALL) { + // verifico che il percorso sia abbastanza lungo + double dLen ; pCompo->GetLength( dLen) ; + if ( dLen + m_Params.m_dStartAddLen + m_Params.m_dEndAddLen < 10 * EPS_SMALL) { + m_pMchMgr->SetWarning( 2355, "Warning in Milling : skipped Path too short") ; + return true ; + } + // se una sola entità circonferenza completa, la divido in due per poterla allungare + if ( pCompo->GetCurveCount() == 1 && pCompo->IsClosed()) + pCompo->AddJoint( 0.5) ; + // eventuali allungamenti + if ( m_Params.m_dStartAddLen > EPS_SMALL) { + if ( ! pCompo->ExtendStartByLen( m_Params.m_dStartAddLen)) + return false ; + dLen += m_Params.m_dStartAddLen ; + } + if ( m_Params.m_dEndAddLen > EPS_SMALL) { + if ( ! pCompo->ExtendEndByLen( m_Params.m_dEndAddLen)) + return false ; + dLen += m_Params.m_dEndAddLen ; + } + // eventuale accorciamenti (da fare dopo tutti gli allungamenti) + if ( m_Params.m_dStartAddLen < - EPS_SMALL) { + if ( ! pCompo->TrimStartAtLen( - m_Params.m_dStartAddLen)) + return false ; + dLen += m_Params.m_dStartAddLen ; + } + if ( m_Params.m_dEndAddLen < - EPS_SMALL) { + if ( ! pCompo->TrimEndAtLen( dLen + m_Params.m_dEndAddLen)) + return false ; + dLen += m_Params.m_dEndAddLen ; + } + } + + // se utensile non centrato, eseguo correzione raggio utensile ed eventuale offset + double dOffs = 0.5 * m_TParams.m_dDiam + GetOffsR() ; + if ( m_Params.m_nWorkSide != WJET_WS_CENTER && abs( dOffs) > EPS_SMALL) { + // valore offset + double dSignOffs = ( m_Params.m_nWorkSide == WJET_WS_RIGHT) ? dOffs : - dOffs ; + // esecuzione offset + if ( ! CalcOffset( pCompo, dSignOffs)) { + m_pMchMgr->SetLastError( 2302, "Error in Milling : Offset not computable") ; + return false ; + } + } + + // eventuale sovrapposizione per percorso chiuso + double dAddedOverlap = 0 ; + if ( pCompo->IsClosed()) { + if ( m_Params.m_dOverlap > EPS_SMALL) { + double dParS, dParE ; + if ( pCompo->GetParamAtLength( 0.0, dParS) && + pCompo->GetParamAtLength( m_Params.m_dOverlap, dParE)) { + PtrOwner pCrv( pCompo->CopyParamRange( dParS, dParE)) ; + if ( ! IsNull( pCrv)) { + pCompo->AddCurve( Release( pCrv)) ; + dAddedOverlap = m_Params.m_dOverlap ; + } + } + } + } + + // unisco le parti allineate (tranne inizio-fine se chiusa) + if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false)) + return false ; + + // recupero i punti di inizio e fine (per poi salvarli nelle info di CL path) + Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; + Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ; + + // recupero il box del grezzo in globale + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { + m_pMchMgr->SetLastError( 2303, "Error in Milling : Empty RawBox") ; + return false ; + } + + // recupero distanza da fondo dei grezzi interessati dal percorso + double dRbDist = 0 ; + if ( AreSameVectorApprox( vtTool, Z_AX)) { + if ( ! GetDistanceFromRawBottom( m_nPhase, nCopyId, m_TParams.m_dTDiam, dRbDist)) + return false ; + } + + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", abs( dThick)) ; + ExeLuaSetGlobNumVar( "RB", dRbDist) ; + double dDepth ; + string sMyDepth = m_Params.m_sDepth ; + if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) { + m_pMchMgr->SetLastError( 2304, "Error in Milling : Depth not computable") ; + return false ; + } + // se spessore positivo, lo sottraggo dal risultato + if ( dThick > 0) + dDepth -= dThick ; + // sottraggo eventuale offset longitudinale + dDepth -= GetOffsL() ; + + // recupero nome del path + string sPathName ; + m_pGeomDB->GetName( nPathId, sPathName) ; + + // eventuale approssimazione con segmenti di retta + int nSplitArcs = m_pMchMgr->GetCurrMachiningsMgr()->GetSplitArcs() ; + bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS || + ( nSplitArcs == SPLAR_NO_XY_PLANE && ! vtTool.IsZplus()) || + ( nSplitArcs == SPLAR_GEN_PLANE && vtTool.IsGeneric())) ; + if ( bSplitArcs && ! ApproxWithLines( pCompo)) { + m_pMchMgr->SetLastError( 2313, "Error in Milling : Linear Approx not computable") ; + return false ; + } + + // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi + VerifyArcs( pCompo) ; + + // calcolo l'elevazione massima + double dElev ; + if ( CalcPathElevation( pCompo, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dElev)) { + if ( dElev < EPS_SMALL && AreSameVectorApprox( vtTool, Z_AX)) { + BBox3d b3Crv ; + pCompo->GetLocalBBox( b3Crv) ; + dElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min( 0., dThick) + dDepth) ; + } + } + else + return false ; + // eventuale imposizione massima elevazione da note utente + double dMaxElev ; + if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) + dElev = dMaxElev ; + // eventuale elevazione di fianco (solo per lama) + double dSideElev = 0 ; + FromString( ExtractInfo( m_Params.m_sUserNotes, "SideElev="), dSideElev) ; + + // verifico che il massimo materiale dell'utensile sia sensato + const double MIN_MAXMAT = 1.0 ; + if ( m_TParams.m_dMaxMat < dElev && m_TParams.m_dMaxMat < MIN_MAXMAT) { + string sInfo = "Error in Milling : Tool MaxMaterial too small (" + + ToString( m_TParams.m_dMaxMat, 2) + ")" ; + m_pMchMgr->SetLastError( 2316, sInfo) ; + return false ; + } + + // verifico di non superare il massimo materiale con l'elevazione + if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL) { + string sInfo = "Error in Milling : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + m_pMchMgr->SetLastError( 2305, sInfo) ; + return false ; + } + + // se richiesta anteprima + if ( nPvId != GDB_ID_NULL) { + // creo gruppo per geometria di anteprima del percorso + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sPathName) ; + m_pGeomDB->SetMaterial( nPxId, GREEN) ; + // creo l'anteprima del percorso + if ( ! GenerateMillingPv( nPxId, pCompo)) + return false ; + } + + // se richiesta lavorazione + if ( nClId != GDB_ID_NULL) { + // creo gruppo per geometria di lavorazione del percorso + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sPathName) ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + + // assegno il vettore estrazione al gruppo del percorso + m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; + // assegno i punti di inizio e fine al gruppo del percorso + m_pGeomDB->SetInfo( nPxId, KEY_START, ptStart) ; + m_pGeomDB->SetInfo( nPxId, KEY_END, ptEnd) ; + // assegno l'elevazione massima + m_pGeomDB->SetInfo( nPxId, KEY_ELEV, dElev) ; + + // Imposto dati comuni + SetPathId( nPxId) ; + SetToolDir( vtTool) ; + + // Inserisco la lavorazione + if ( ! AddStandardMilling( pCompo, vtTool, dDepth, dElev, bSplitArcs)) + return false ; + } + + // incremento numero di fresate + ++ m_nMills ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, + double& dElev) const +{ + dElev = 0 ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( i) ; + // calcolo elevazione + double dCurrElev ; + Point3d ptStart, ptMid, ptEnd ; + pCrvC->GetStartPoint( ptStart) ; + pCrvC->GetMidPoint( ptMid) ; + pCrvC->GetEndPoint( ptEnd) ; + Vector3d vtStartPerp, vtMidPerp, vtEndPerp, vtTg ; + pCrvC->GetStartDir( vtTg) ; + vtStartPerp = vtTg ^ vtTool ; + vtStartPerp.Normalize() ; + vtStartPerp *= dRad ; + pCrvC->GetMidDir( vtTg) ; + vtMidPerp = vtTg ^ vtTool ; + vtMidPerp.Normalize() ; + vtMidPerp *= dRad ; + pCrvC->GetEndDir( vtTg) ; + vtEndPerp = vtTg ^ vtTool ; + vtEndPerp.Normalize() ; + vtEndPerp *= dRad ; + Vector3d vtDepth = vtTool * dDepth ; + // linea centro utensile + if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { + if ( dCurrElev > dElev) + dElev = dCurrElev ; + } + else { + m_pMchMgr->SetLastError( 2306, "Error in Milling : Entity GetElevation") ; + return false ; + } + // da una parte + if ( GetElevation( m_nPhase, ptStart + vtStartPerp - vtDepth, ptMid + vtMidPerp - vtDepth, + ptEnd + vtEndPerp - vtDepth, vtTool, dCurrElev)) { + if ( dCurrElev > dElev) + dElev = dCurrElev ; + } + else { + m_pMchMgr->SetLastError( 2306, "Error in Milling : Entity GetElevation") ; + return false ; + } + // dall'altra parte + if ( GetElevation( m_nPhase, ptStart - vtStartPerp - vtDepth, ptMid - vtMidPerp - vtDepth, + ptEnd - vtEndPerp - vtDepth, vtTool, dCurrElev)) { + if ( dCurrElev > dElev) + dElev = dCurrElev ; + } + else { + m_pMchMgr->SetLastError( 2306, "Error in Milling : Entity GetElevation") ; + return false ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) +{ + // creo copia della curva composita + PtrOwner< ICurve> pCrv( pCompo->Clone()) ; + if ( IsNull( pCrv)) + return false ; + // calcolo la regione + PtrOwner pSfr ; + pSfr.Set( GetSurfFlatRegionFromFatCurve( Release( pCrv), 0.5 * m_TParams.m_dDiam, false, false)) ; + if ( IsNull( pSfr)) + return false ; + // ne recupero il contorno + PtrOwner< ICurve> pCrv2 ; + pCrv2.Set( pSfr->GetLoop( 0, 0)) ; + if ( IsNull( pCrv2)) + return false ; + // inserisco la curva nel DB + int nC2Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrv2)) ; + if ( nC2Id == GDB_ID_NULL) + return false ; + // assegno nome e colore + m_pGeomDB->SetName( nC2Id, MCH_PV_CUT) ; + m_pGeomDB->SetMaterial( nC2Id, LIME) ; + // eventuali altri contorni ( interni di contornatura chiusa) + const int MAX_INT_LOOP = 1000 ; + for ( int i = 1 ; i <= MAX_INT_LOOP ; ++i) { + PtrOwner< ICurve> pCrv3 ; + pCrv3.Set( pSfr->GetLoop( 0, i)) ; + if ( IsNull( pCrv3)) + break ; + // inserisco la curva nel DB + int nC3Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrv3)) ; + if ( nC3Id == GDB_ID_NULL) + return false ; + // assegno nome e colore + m_pGeomDB->SetName( nC3Id, MCH_PV_CUT) ; + m_pGeomDB->SetMaterial( nC3Id, LIME) ; + } + // inserisco la regione nel DB + int nRId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pSfr)) ; + if ( nRId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nRId, MCH_PV_RCUT) ; + m_pGeomDB->SetMaterial( nRId, INVISIBLE) ; + // la copio anche come regione ridotta + int nRrId = m_pGeomDB->Copy( nRId, GDB_ID_NULL, nPathId) ; + if ( nRrId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nRrId, MCH_PV_RRCUT) ; + m_pGeomDB->SetMaterial( nRrId, INVISIBLE) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, + double dDepth, double dElev, bool bSplitArcs) +{ + // recupero distanze di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + + // ciclo sulle curve elementari + bool bClosed = pCompo->IsClosed() ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + // aggiungo affondamento + pCurve->Translate( - vtTool * dDepth) ; + // se prima entità, approccio e affondo + if ( i == 0) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // determino elevazione su inizio percorso di lavoro + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dElev ; + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, false, pCompo, ptP1)) + return false ; + // determino se l'inizio dell'attacco è fuori dal grezzo + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, dElev) ; + // determino se l'inizio dell'attacco è sopra il grezzo + bool bAboveStart = GetPointAboveRaw( ptP1) ; + // imposto versore correzione e ausiliario sul punto di partenza + CalcAndSetCorrAuxDir( pCompo, i) ; + // aggiungo approccio per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) + if ( vtTool.z < - EPS_SMALL) + dStElev -= ScalarXY( (ptP1 - ptStart), vtTool) ; + else + dStElev -= ( ptP1 - ptStart) * vtTool ; + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } + } + // altrimenti, approccio per lame + else { + // verifico di entrare in aria + if ( ! bOutStart) { + m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; + return false ; + } + // affondo al punto iniziale + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, false, pCompo, bSplitArcs)) { + m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; + return false ; + } + } + // imposto versore correzione e ausiliario sul punto di arrivo + CalcAndSetCorrAuxDir( pCompo, i+1) ; + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; pArc->GetEndPoint( ptP3) ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità, uscita e retrazione + if ( i == nMaxInd) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // elevazione sul punto finale + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + dEndElev = dElev ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1)) { + m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) + if ( vtTool.z < - EPS_SMALL) + dEndElev -= ScalarXY( (ptP1 - ptEnd), vtTool) ; + else + dEndElev -= ( ptP1 - ptEnd) * vtTool ; + // determino se la fine dell'uscita è sopra il grezzo + bool bAboveEnd = GetPointAboveRaw( ptP1) ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveEnd)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } + } + // per lame non è necessario + } + } + return true ; +} + + +//---------------------------------------------------------------------------- +class LeadIOStatus +{ + public : + LeadIOStatus( WaterJetting* pWJ) + { m_pWJ = pWJ ; + m_dLiPerp = m_pWJ->m_Params.m_dLiPerp ; + m_dLoPerp = m_pWJ->m_Params.m_dLoPerp ; + } + ~LeadIOStatus( void) + { Restore() ; + } + void Restore( void) + { m_pWJ->m_Params.m_dLiPerp = m_dLiPerp ; + m_pWJ->m_Params.m_dLoPerp = m_dLoPerp ; + } + + private : + WaterJetting* m_pWJ ; + double m_dLiPerp ; + double m_dLoPerp ; +} ; + +//---------------------------------------------------------------------------- +bool +WaterJetting::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, + double dElev, double dAppr, bool bOutStart, bool bAboveStart) +{ + SetFlag( 1) ; + // se non sono già sopra il pezzo e sopra attacco c'è spazio per sicurezza o approccio + double dSafeDist = dSafeZ ; + if ( ! bAboveStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { + // se distanza di sicurezza minore di distanza di inizio + if ( dSafeDist < dAppr + 10 * EPS_SMALL) { + // 1 -> punto sopra inizio + Point3d ptP1 = ptP + vtTool * ( dElev + dAppr) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } + else { + // 1a -> punto sopra inizio + Point3d ptP1b = ptP + vtTool * ( dElev + dAppr) ; + Point3d ptP1a = ptP1b + vtTool * ( dSafeDist - dAppr) ; + if ( AddRapidStart( ptP1a) == GDB_ID_NULL) + return false ; + // 1b -> punto appena sopra inizio + if ( ( dElev + dAppr) > EPS_SMALL) { + SetFlag( 0) ; + if ( AddRapidMove( ptP1b) == GDB_ID_NULL) + return false ; + } + } + // affondo al punto iniziale + SetFlag( 0) ; + SetFeed( bOutStart ? GetStartFeed() : GetTipFeed()) ; + if ( AddLinearMove( ptP) == GDB_ID_NULL) + return false ; + } + // sono sopra il pezzo ma non abbastanza + else if ( bAboveStart && ( dElev + dAppr) > 10 * EPS_SMALL) { + // 1b -> punto appena sopra inizio (in Z globale) + Point3d ptP1b = ptP + Z_AX * ( dElev + dAppr) ; + if ( AddRapidStart( ptP1b) == GDB_ID_NULL) + return false ; + // affondo al punto iniziale + SetFlag( 0) ; + SetFeed( bOutStart ? GetStartFeed() : GetTipFeed()) ; + if ( AddLinearMove( ptP) == GDB_ID_NULL) + return false ; + } + // altrimenti + else { + // affondo diretto al punto iniziale + if ( AddRapidStart( ptP) == GDB_ID_NULL) + return false ; + SetFlag( 0) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AddDirectApproach( const Point3d& ptP) +{ + SetFlag( 1) ; + // affondo diretto al punto iniziale + if ( AddRapidMove( ptP) == GDB_ID_NULL) + return false ; + SetFlag( 0) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, + double dElev, double dAppr, bool bAboveEnd) +{ + // se non sono già sopra il pezzo e sopra uscita c'è spazio per sicurezza o approccio + double dSafeDist = dSafeZ ; + if ( ! bAboveEnd && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { + if ( dSafeDist < dAppr + 10 * EPS_SMALL) { + // 4 -> movimento di risalita sopra il punto finale + SetFeed( GetEndFeed()) ; + Point3d ptP4 = ptP + vtTool * ( dElev + dAppr) ; + if ( AddLinearMove( ptP4) == GDB_ID_NULL) + return false ; + } + else { + // 4a -> movimento di risalita appena sopra il punto finale + Point3d ptP4a = ptP + vtTool * ( dElev + dAppr) ; + if ( dElev + dAppr > EPS_SMALL) { + SetFeed( GetEndFeed()) ; + if ( AddLinearMove( ptP4a) == GDB_ID_NULL) + return false ; + } + // 4b -> movimento di risalita sopra il punto finale + Point3d ptP4b = ptP4a + vtTool * ( dSafeDist - dAppr) ; + if ( AddRapidMove( ptP4b) == GDB_ID_NULL) + return false ; + } + } + // sono sopra il pezzo ma non abbastanza + else if ( bAboveEnd && ( dElev + dAppr) > 10 * EPS_SMALL) { + if ( dSafeDist < dAppr + 10 * EPS_SMALL) { + // 4 -> movimento di risalita sopra il punto finale + SetFeed( GetEndFeed()) ; + Point3d ptP4 = ptP + Z_AX * ( dElev + dAppr) ; + if ( AddLinearMove( ptP4) == GDB_ID_NULL) + return false ; + } + else { + // 4a -> movimento di risalita appena sopra il punto finale + Point3d ptP4a = ptP + Z_AX * ( dElev + dAppr) ; + if ( dElev + dAppr > EPS_SMALL) { + SetFeed( GetEndFeed()) ; + if ( AddLinearMove( ptP4a) == GDB_ID_NULL) + return false ; + } + // 4b -> movimento di risalita sopra il punto finale + Point3d ptP4b = ptP4a + Z_AX * ( dSafeDist - dAppr) ; + if ( AddRapidMove( ptP4b) == GDB_ID_NULL) + return false ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +int +WaterJetting::GetLeadInType( void) const +{ + if ( abs( m_Params.m_dLiTang) < min( 0.1 * m_TParams.m_dDiam, 0.1) && + abs( m_Params.m_dLiPerp) < min( 0.1 * m_TParams.m_dDiam, 0.1)) + return WJET_LI_NONE ; + return m_Params.m_nLeadInType ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, + double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const +{ + // Assegno tipo e parametri + int nType = GetLeadInType() ; + double dTang = m_Params.m_dLiTang ; + double dPerp = m_Params.m_dLiPerp ; + double dElev = min( m_Params.m_dLiElev, dStElev + LIO_ELEV_TOL) ; + // se step invertito + if ( bInvert) { + switch ( m_Params.m_nLeadOutType) { + case WJET_LO_LINEAR : nType = WJET_LI_LINEAR ; break ; + case WJET_LO_TANGENT : nType = WJET_LI_TANGENT ; break ; + case WJET_LO_AS_LI : /* resta inalterato */ ; break ; + default : nType = WJET_LI_NONE ; break ; + } + if ( m_Params.m_nLeadOutType != WJET_LO_AS_LI) { + dTang = m_Params.m_dLoTang ; + dPerp = m_Params.m_dLoPerp ; + dElev = min( m_Params.m_dLoElev, dStElev + LIO_ELEV_TOL) ; + } + } + // senso di rotazione da dir tg a dir esterna + bool bCcwRot = (( ! bInvert && m_Params.m_nWorkSide == WJET_WS_LEFT) || + ( bInvert && m_Params.m_nWorkSide != WJET_WS_LEFT)) ; + // Calcolo punto iniziale + switch ( nType) { + case WJET_LI_NONE : + ptP1 = ptStart ; + return true ; + case WJET_LI_LINEAR : + case WJET_LI_TANGENT : { + Vector3d vtPerp = vtStart ; + vtPerp.Rotate( vtN, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 = ptStart - vtStart * dTang + vtPerp * dPerp + vtN * dElev ; + return true ; + } + default : + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, + const Vector3d& vtN, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) +{ + // Assegno il tipo + int nType = GetLeadInType() ; + double dTang = m_Params.m_dLiTang ; + // se step invertito + if ( bInvert) { + switch ( GetLeadOutType()) { + case WJET_LO_LINEAR : nType = WJET_LI_LINEAR ; break ; + case WJET_LO_TANGENT : nType = WJET_LI_TANGENT ; break ; + case WJET_LO_AS_LI : /* resta inalterato */ ; break ; + default : nType = WJET_LI_NONE ; break ; + } + if ( m_Params.m_nLeadOutType != WJET_LO_AS_LI) + dTang = m_Params.m_dLoTang ; + } + // Eseguo a seconda del tipo + switch ( nType) { + case WJET_LI_NONE : + return true ; + case WJET_LI_LINEAR : + return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ; + case WJET_LI_TANGENT : + { + PtrOwner pCrv( GetArc2PVN( ptStart, ptP1, - vtStart, vtN)) ; + if ( IsNull( pCrv)) + return false ; + pCrv->Invert() ; + // eventuale spezzatura + if ( bSplitArcs) { + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pCrv)) || ! ApproxWithLines( pCompo)) + return false ; + return ( AddCurveMove( pCompo, MCH_CL_LEADIN) != GDB_ID_NULL) ; + } + else { + return ( AddCurveMove( pCrv, MCH_CL_LEADIN) != GDB_ID_NULL) ; + } + } + default : + return false ; + } +} + +//---------------------------------------------------------------------------- +int +WaterJetting::GetLeadOutType( void) const +{ + if ( abs( m_Params.m_dLoTang) < min( 0.1 * m_TParams.m_dDiam, 0.1) && + abs( m_Params.m_dLoPerp) < min( 0.1 * m_TParams.m_dDiam, 0.1) && + m_Params.m_nLeadOutType != WJET_LO_AS_LI) + return WJET_LO_NONE ; + return m_Params.m_nLeadOutType ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, double dEndElev, + bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1) +{ + // assegno i parametri + int nType = GetLeadOutType() ; + double dTang = m_Params.m_dLoTang ; + double dPerp = m_Params.m_dLoPerp ; + double dElev = min( m_Params.m_dLoElev, dEndElev + LIO_ELEV_TOL) ; + // se uscita come ingresso o step invertito + if ( nType == WJET_LO_AS_LI || bInvert) { + int nLiType = GetLeadInType() ; + switch ( nLiType) { + case WJET_LI_LINEAR : nType = WJET_LO_LINEAR ; break ; + case WJET_LI_TANGENT : nType = WJET_LO_TANGENT ; break ; + default : nType = WJET_LO_NONE ; break ; + } + dTang = m_Params.m_dLiTang ; + dPerp = m_Params.m_dLiPerp ; + dElev = min( m_Params.m_dLiElev, dEndElev + LIO_ELEV_TOL) ; + } + // senso di rotazione da dir tg a dir esterna + bool bCcwRot = (( ! bInvert && m_Params.m_nWorkSide == WJET_WS_LEFT) || + ( bInvert && m_Params.m_nWorkSide != WJET_WS_LEFT)) ; + // eseguo a seconda del tipo + switch ( nType) { + case WJET_LO_NONE : + ptP1 = ptEnd ; + return true ; + case WJET_LO_LINEAR : + { + Vector3d vtPerp = vtEnd ; + vtPerp.Rotate( vtN, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtN * dElev ; + return ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + } + case WJET_LO_TANGENT : + { + // calcolo punto finale dell'uscita + Vector3d vtPerp = vtEnd ; + vtPerp.Rotate( vtN, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtN * dElev ; + // inserisco uscita + PtrOwner pCrv( GetArc2PVN( ptEnd, ptP1, vtEnd, vtN)) ; + if ( IsNull( pCrv)) + return false ; + // eventuale spezzatura + if ( bSplitArcs) { + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pCrv)) || ! ApproxWithLines( pCompo)) + return false ; + return ( AddCurveMove( pCompo, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + } + else { + return ( AddCurveMove( pCrv, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + } + } + default : + return false ; + } +} + +//---------------------------------------------------------------------------- +double +WaterJetting::GetRadiusForStartEndElevation( void) const +{ + const double DELTA_ELEV_RAD = 20.0 ; + double dDeltaRad = DELTA_ELEV_RAD + max( max( m_Params.m_dStartAddLen, m_Params.m_dEndAddLen), 0.0) ; + return ( 0.5 * m_TParams.m_dTDiam + dDeltaRad) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, double dElev) const +{ + // per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // determino se l'inizio dell'attacco è fuori dal grezzo (considero movimento fresa lungo il suo asse) + double dTemp ; + if ( ! GetElevation( m_nPhase, ptP, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dTemp)) + return false ; + return ( dTemp < 10 * EPS_SMALL || dTemp > dElev + 10 * EPS_SMALL) ; + } + // per lame + else { + // determino se l'inizio dell'attacco è fuori dal grezzo (considero movimento lama in Z) + double dTemp ; + if ( ! GetElevation( m_nPhase, ptP, vtTool, 0.5 * m_TParams.m_dDiam, Z_AX, dTemp) || dTemp > 10 * EPS_SMALL) + return false ; + if ( ! GetElevation( m_nPhase, ptP + vtTool * m_TParams.m_dThick, vtTool, 0.5 * m_TParams.m_dDiam, Z_AX, dTemp) || dTemp > 10 * EPS_SMALL) + return false ; + return true ; + } +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::GetPointAboveRaw( const Point3d& ptP) const +{ + // determino la posizione del punto rispetto al grezzo + // ciclo sui grezzi + int nRawId = m_pMchMgr->GetFirstRawPart() ; + while ( nRawId != GDB_ID_NULL) { + // se il grezzo compare nella fase + if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) { + int nStmId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; + BBox3d b3Raw ; + m_pGeomDB->GetGlobalBBox( nStmId, b3Raw) ; + if ( ! b3Raw.IsEmpty() && ptP.z < b3Raw.GetMax().z + 10 * EPS_SMALL) + return false ; + } + nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU) +{ + // verifico curva + if ( pCompo == nullptr) + return false ; + // se utensile centrato, direzione di correzione nulla + if ( m_Params.m_nWorkSide == WJET_WS_CENTER) + return true ; + // calcolo del versore correzione + Vector3d vtCorr = CalcCorrDir( pCompo, dU) ; + // imposto versore correzione + SetCorrDir( vtCorr) ; + // se impostato uso direttamente da lavorazione, imposto anche come versore aux + if ( m_Params.m_nSolCh == MCH_SCC_ADIR_NEAR || m_Params.m_nSolCh == MCH_SCC_ADIR_FAR) + SetAuxDir( vtCorr) ; + // se standard o nullo o suo opposto + if ( m_Params.m_nSolCh == MCH_SCC_STD || m_Params.m_nSolCh == MCH_SCC_NONE || m_Params.m_nSolCh == MCH_SCC_OPPOSITE) { + // verifico se richiesto dalla testa + if ( m_nHeadSolCh == MCH_SCC_ADIR_NEAR || m_nHeadSolCh == MCH_SCC_ADIR_FAR) + SetAuxDir( vtCorr) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +Vector3d +WaterJetting::CalcCorrDir( const ICurveComposite* pCompo, double dU) +{ + // verifico curva + if ( pCompo == nullptr) + return V_NULL ; + // se utensile centrato, direzione di correzione nulla + if ( m_Params.m_nWorkSide == WJET_WS_CENTER) + return V_NULL ; + // angolo di rotazione da tg a versore corr/aux + bool bCcwRot = (m_Params.m_nWorkSide == WJET_WS_LEFT) ; + double dCaRot = ( bCcwRot ? ANG_RIGHT : -ANG_RIGHT) ; + // dominio parametrico della curva + double dUs, dUe ; + pCompo->GetDomain( dUs, dUe) ; + // se inizio + if ( dU < dUs + EPS_ZERO) { + // recupero la tangente dopo + Point3d ptP ; + Vector3d vtN ; + pCompo->GetPointTang( dU, ICurve::FROM_PLUS, ptP, vtN) ; + vtN.Rotate( m_vtTool, dCaRot) ; + return vtN ; + } + // se fine + else if ( dU > dUe - EPS_ZERO) { + // recupero la tangente prima + Point3d ptP ; + Vector3d vtN ; + pCompo->GetPointTang( dU, ICurve::FROM_MINUS, ptP, vtN) ; + vtN.Rotate( m_vtTool, dCaRot) ; + return vtN ; + } + // altrimenti + else { + // recupero la tangente prima e dopo il punto + Point3d ptP1, ptP2 ; + Vector3d vtT1, vtT2 ; + pCompo->GetPointTang( dU, ICurve::FROM_MINUS, ptP1, vtT1) ; + pCompo->GetPointTang( dU, ICurve::FROM_PLUS, ptP2, vtT2) ; + // se coincidono + if ( AreSameVectorApprox( vtT1, vtT2)) { + Vector3d vtN = vtT1 ; + vtN.Rotate( m_vtTool, dCaRot) ; + return vtN ; + } + // se sono opposte + else if ( AreOppositeVectorApprox( vtT1, vtT2)) { + Vector3d vtN = ( bCcwRot ? vtT2 : vtT1) ; + return vtN ; + } + // altrimenti + else { + Vector3d vtN = ( vtT1 + vtT2) / 2 ; + vtN.Rotate( m_vtTool, dCaRot) ; + return vtN ; + } + } +} + +//---------------------------------------------------------------------------- +bool +WaterJetting::CalcOffset( ICurveComposite* pCompo, double dSignOffs) +{ + // eseguo offset semplice + int nFlag = ICurve::OFF_EXTEND | ICurve::OFF_FORCE_OPEN ; + if ( pCompo->SimpleOffset( dSignOffs, nFlag)) + return true ; + // se curva piatta, provo con offset avanzato + bool bOk = false ; + Plane3d plPlane ; + Vector3d vtExtr ; + pCompo->GetExtrusion( vtExtr) ; + if ( pCompo->IsFlat( plPlane, 100 * EPS_SMALL) && + AreSameOrOppositeVectorApprox( vtExtr, plPlane.GetVersN())) { + OffsetCurve OffsCrv ; + if ( OffsCrv.Make( pCompo, dSignOffs, nFlag)) { + ICurve* pOffs = OffsCrv.GetLongerCurve() ; + if ( pOffs != nullptr) { + pCompo->Clear() ; + pCompo->AddCurve( pOffs) ; + bOk = true ; + } + } + } + return bOk ; +} diff --git a/WaterJetting.h b/WaterJetting.h new file mode 100644 index 0000000..253cf75 --- /dev/null +++ b/WaterJetting.h @@ -0,0 +1,125 @@ +//---------------------------------------------------------------------------- +// EgalTech 2019-2019 +//---------------------------------------------------------------------------- +// File : WaterJetting.h Data : 08.07.19 Versione : 2.1gf2 +// Contenuto : Dichiarazione della classe WaterJetting. +// +// +// +// Modifiche : 08.07.19 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "Machining.h" +#include "WaterJettingData.h" +#include "ToolData.h" +#include "/EgtDev/Include/EGkCurve.h" + +class ICurveComposite ; + +//---------------------------------------------------------------------------- +class WaterJetting : public Machining +{ + public : // IUserObj + WaterJetting* Clone( void) const override ; + const std::string& GetClassName( void) const override ; + bool Dump( std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ; + bool ToSave( void) const override + { return true ; } + bool Save( int nBaseId, STRVECTOR& vString) const override ; + bool Load( const STRVECTOR& vString, int nBaseGdbId) override ; + + public : // Operation + int GetType( void) const override + { return OPER_WATERJETTING ; } + bool IsEmpty( void) const override + { return ( m_nMills == 0) ; } + bool UpdateStatus( int nModif) override + { m_nStatus |= nModif ; return true ; } + + protected : // Operation + int GetSolCh( void) const override + { return m_Params.m_nSolCh ; } + bool AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) const override ; + bool AdjustArcCenterForAxesCalc( const CamData* pCamData, Point3d& ptCen) const override ; + + public : // Machining + bool Prepare( const std::string& sMillName) override ; + bool SetParam( int nType, bool bVal) override ; + bool SetParam( int nType, int nVal) override ; + bool SetParam( int nType, double dVal) override ; + bool SetParam( int nType, const std::string& sVal) override ; + bool SetGeometry( const SELVECTOR& vIds) override ; + bool Preview( bool bRecalc) override ; + bool Apply( bool bRecalc, bool bPostApply) override ; + bool Update( bool bPostApply) override ; + bool GetParam( int nType, bool& bVal) const override ; + bool GetParam( int nType, int& nVal) const override ; + bool GetParam( int nType, double& dVal) const override ; + bool GetParam( int nType, std::string& sVal) const override ; + bool UpdateToolData( bool* pbChanged = nullptr) override ; + const ToolData& GetToolData( void) const override ; + bool GetGeometry( SELVECTOR& vIds) const override ; + + public : + WaterJetting( void) ; + + private : + bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; + bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ; + bool Chain( int nGrpDestId) ; + bool ProcessPath( int nPathId, int nPvId, int nClId) ; + bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const ; + bool GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) ; + bool AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, + double dDepth, double dElev, bool bSplitArcs) ; + bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, + double dElev, double dAppr, bool bOutStart, bool bAboveStart) ; + bool AddDirectApproach( const Point3d& ptP) ; + bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, + double dElev, double dAppr, bool bAboveEnd) ; + bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, + double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const ; + bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, + const Vector3d& vtN, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) ; + bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, double dEndElev, + bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1) ; + double GetRadiusForStartEndElevation( void) const ; + bool GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, double dElev) const ; + bool GetPointAboveRaw( const Point3d& ptP) const ; + bool CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU) ; + Vector3d CalcCorrDir( const ICurveComposite* pCompo, double dU) ; + bool CalcOffset( ICurveComposite* pCompo, double dSignOffs) ; + + private : + double GetSpeed() const + { return ( IsNullAngValue( m_Params.m_dSpeed) ? m_TParams.m_dSpeed : m_Params.m_dSpeed) ; } + double GetFeed() const + { return ( IsNullLenValue( m_Params.m_dFeed) ? m_TParams.m_dFeed : m_Params.m_dFeed) ; } + double GetStartFeed() const + { return ( IsNullLenValue( m_Params.m_dStartFeed) ? m_TParams.m_dStartFeed : m_Params.m_dStartFeed) ; } + double GetEndFeed() const + { return ( IsNullLenValue( m_Params.m_dEndFeed) ? m_TParams.m_dEndFeed : m_Params.m_dEndFeed) ; } + double GetTipFeed() const + { return ( IsNullLenValue( m_Params.m_dTipFeed) ? m_TParams.m_dTipFeed : m_Params.m_dTipFeed) ; } + double GetOffsL() const + { return ( IsUnknownValue( m_Params.m_dOffsL) ? m_TParams.m_dOffsL : m_Params.m_dOffsL) ; } + double GetOffsR() const + { return ( IsUnknownValue( m_Params.m_dOffsR) ? m_TParams.m_dOffsR : m_Params.m_dOffsR) ; } + int GetLeadInType( void) const ; + int GetLeadOutType( void) const ; + friend class LeadIOStatus ; + + private : + SELVECTOR m_vId ; // identificativi entità geometriche da lavorare + WaterJettingData m_Params ; // parametri lavorazione + ToolData m_TParams ; // parametri utensile + double m_dTHoldLen ; // lunghezza del porta-utensile + double m_dTHoldDiam ; // diametro del porta-utensile + int m_nStatus ; // stato di aggiornamento della lavorazione + int m_nMills ; // numero di percorsi di lavoro generati + int m_nHeadSolCh ; // criterio scelta soluzione impostato nella testa +} ; \ No newline at end of file diff --git a/WaterJettingData.cpp b/WaterJettingData.cpp new file mode 100644 index 0000000..c7145ba --- /dev/null +++ b/WaterJettingData.cpp @@ -0,0 +1,779 @@ +//---------------------------------------------------------------------------- +// EgalTech 2019-2019 +//---------------------------------------------------------------------------- +// File : WaterJettingData.cpp Data : 08.07.19 Versione : 2.1g2 +// Contenuto : Implementazione struttura dati lavorazione di taglio water jet. +// +// +// +// Modifiche : 08.07.19 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "WaterJettingData.h" +#include "MachiningDataFactory.h" +#include "MachiningConst.h" +#include "/EgtDev/Include/EmkToolConst.h" +#include "/EgtDev/Include/EmkSimuGenConst.h" +#include "/EgtDev/Include/EGnStringUtils.h" +#include +#include + +using namespace std ; + +//---------------------------------------------------------------------------- +enum nWaterJetting { + KEY_AB = 0, + KEY_AI, + KEY_DH, + KEY_EAL, + KEY_F, + KEY_FE, + KEY_FS, + KEY_FT, + KEY_INV, + KEY_LICL, + KEY_LIEL, + KEY_LIPR, + KEY_LITG, + KEY_LITY, + KEY_LOCL, + KEY_LOEL, + KEY_LOPR, + KEY_LOTG, + KEY_LOTY, + KEY_NAME, + KEY_NNS, + KEY_NNU, + KEY_OL, + KEY_OR, + KEY_OVL, + KEY_PS, + KEY_S, + KEY_SA, + KEY_SAL, + KEY_SCC, + KEY_TNAME, + KEY_TUUID, + KEY_UUID, + KEY_WS, + KEY_ZZZ} ; // rappresenta il numero di elementi + +static const std::array sWaterJettingKey = { + "AB", + "AI", + "DH", + "EAL", + "F", + "FE", + "FS", + "FT", + "INV", + "LICL", + "LIEL", + "LIPR", + "LITG", + "LITY", + "LOCL", + "LOEL", + "LOPR", + "LOTG", + "LOTY", + "NAME", + "NNS", + "NNU", + "OL", + "OR", + "OVL", + "PS", + "S", + "SA", + "SAL", + "SCC", + "TN", + "TU", + "UUID", + "WS"} ; + +//---------------------------------------------------------------------------- +MCHDATA_REGISTER( MT_WATERJETTING, "WATERJETTING", WaterJettingData) ; + +//---------------------------------------------------------------------------- +WaterJettingData* +WaterJettingData::Clone( void) const +{ + // alloco oggetto + WaterJettingData* pMdata = new(nothrow) WaterJettingData ; + // copio i dati + if ( pMdata != nullptr) { + if ( ! pMdata->CopyFrom( this)) { + delete pMdata ; + return nullptr ; + } + } + return pMdata ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::CopyFrom( const MachiningData* pMdata) +{ + // è inutile copiare se sorgente coincide con destinazione + if ( pMdata == this) + return true ; + // la sorgente deve essere dello stesso tipo + const WaterJettingData* pSdata = GetWaterJettingData( pMdata) ; + if ( pSdata == nullptr) + return false ; + // eseguo copia + m_Uuid = pSdata->m_Uuid ; + m_sName = pSdata->m_sName ; + m_ToolUuid = pSdata->m_ToolUuid ; + m_sToolName = pSdata->m_sToolName ; + m_sBlockedAxis = pSdata->m_sBlockedAxis ; + m_sInitAngs = pSdata->m_sInitAngs ; + m_nSolCh = pSdata->m_nSolCh ; + m_dSpeed = pSdata->m_dSpeed ; + m_dFeed = pSdata->m_dFeed ; + m_dEndFeed = pSdata->m_dEndFeed ; + m_dStartFeed = pSdata->m_dStartFeed ; + m_dTipFeed = pSdata->m_dTipFeed ; + m_dOffsL = pSdata->m_dOffsL ; + m_dOffsR = pSdata->m_dOffsR ; + m_bInvert = pSdata->m_bInvert ; + m_nWorkSide = pSdata->m_nWorkSide ; + m_sDepth = pSdata->m_sDepth ; + m_dStartPos = pSdata->m_dStartPos ; + m_dOverlap = pSdata->m_dOverlap ; + m_dSideAngle = pSdata->m_dSideAngle ; + m_dStartAddLen = pSdata->m_dStartAddLen ; + m_dEndAddLen = pSdata->m_dEndAddLen ; + m_nLeadInType = pSdata->m_nLeadInType ; + m_dLiTang = pSdata->m_dLiTang ; + m_dLiPerp = pSdata->m_dLiPerp ; + m_dLiElev = pSdata->m_dLiElev ; + m_dLiCompLen = pSdata->m_dLiCompLen ; + m_nLeadOutType = pSdata->m_nLeadOutType ; + m_dLoTang = pSdata->m_dLoTang ; + m_dLoPerp = pSdata->m_dLoPerp ; + m_dLoElev = pSdata->m_dLoElev ; + m_dLoCompLen = pSdata->m_dLoCompLen ; + m_sSysNotes = pSdata->m_sSysNotes ; + m_sUserNotes = pSdata->m_sUserNotes ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::SameAs( const MachiningData* pMdata) const +{ + // se coincide con altro -> uguali + if ( pMdata == this) + return true ; + // se sono di tipo diverso -> diversi + const WaterJettingData* pSdata = GetWaterJettingData( pMdata) ; + if ( pSdata == nullptr) + return false ; + // confronto termine a termine + return ( m_Uuid == pSdata->m_Uuid && + m_sName == pSdata->m_sName && + m_ToolUuid == pSdata->m_ToolUuid && + m_sToolName == pSdata->m_sToolName && + m_sBlockedAxis == pSdata->m_sBlockedAxis && + m_sInitAngs == pSdata->m_sInitAngs && + m_nSolCh == pSdata->m_nSolCh && + abs( m_dSpeed - pSdata->m_dSpeed) < EPS_MACH_ANG_PAR && + abs( m_dFeed - pSdata->m_dFeed) < EPS_MACH_LEN_PAR && + abs( m_dEndFeed - pSdata->m_dEndFeed) < EPS_MACH_LEN_PAR && + abs( m_dStartFeed - pSdata->m_dStartFeed) < EPS_MACH_LEN_PAR && + abs( m_dTipFeed - pSdata->m_dTipFeed) < EPS_MACH_LEN_PAR && + abs( m_dOffsL - pSdata->m_dOffsL) < EPS_MACH_LEN_PAR && + abs( m_dOffsR - pSdata->m_dOffsR) < EPS_MACH_LEN_PAR && + m_bInvert == pSdata->m_bInvert && + m_nWorkSide == pSdata->m_nWorkSide && + m_sDepth == pSdata->m_sDepth && + abs( m_dStartPos - pSdata->m_dStartPos) < EPS_MACH_LEN_PAR && + abs( m_dOverlap - pSdata->m_dOverlap) < EPS_MACH_LEN_PAR && + abs( m_dSideAngle - pSdata->m_dSideAngle) < EPS_MACH_ANG_PAR && + abs( m_dStartAddLen - pSdata->m_dStartAddLen) < EPS_MACH_LEN_PAR && + abs( m_dEndAddLen - pSdata->m_dEndAddLen) < EPS_MACH_LEN_PAR && + m_nLeadInType == pSdata->m_nLeadInType && + abs( m_dLiTang - pSdata->m_dLiTang) < EPS_MACH_LEN_PAR && + abs( m_dLiPerp - pSdata->m_dLiPerp) < EPS_MACH_LEN_PAR && + abs( m_dLiElev - pSdata->m_dLiElev) < EPS_MACH_LEN_PAR && + abs( m_dLiCompLen - pSdata->m_dLiCompLen) < EPS_MACH_LEN_PAR && + m_nLeadOutType == pSdata->m_nLeadOutType && + abs( m_dLoTang - pSdata->m_dLoTang) < EPS_MACH_LEN_PAR && + abs( m_dLoPerp - pSdata->m_dLoPerp) < EPS_MACH_LEN_PAR && + abs( m_dLoElev - pSdata->m_dLoElev) < EPS_MACH_LEN_PAR && + abs( m_dLoCompLen - pSdata->m_dLoCompLen) < EPS_MACH_LEN_PAR && + m_sSysNotes == pSdata->m_sSysNotes && + m_sUserNotes == pSdata->m_sUserNotes) ; +} + +//---------------------------------------------------------------------------- +int +WaterJettingData::GetSize( void) const +{ + // in debug verifico validità ultimo campo + assert( sWaterJettingKey[KEY_WS] == "WS") ; + return KEY_ZZZ ; +} +//---------------------------------------------------------------------------- +string +WaterJettingData::GetTitle( void) const +{ + return MCHDATA_GETNAME( WaterJettingData) ; +} + +//---------------------------------------------------------------------------- +int +FindWaterJettingKey( const string& sKey) +{ + auto TheRange = equal_range( sWaterJettingKey.cbegin(), sWaterJettingKey.cend(), sKey) ; + if ( TheRange.first == TheRange.second) + return - 1 ; + return int( TheRange.first - sWaterJettingKey.cbegin()) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::FromString( const string& sString, int& nKey) +{ + // separo chiave da valore + string sKey, sVal ; + SplitFirst( sString, "=", sKey, sVal) ; + // riconosco la chiave + nKey = FindWaterJettingKey( ToUpper( sKey)) ; + bool bOk = ( nKey >= 0) ; + switch ( nKey) { + case KEY_AB : + m_sBlockedAxis = sVal ; + break ; + case KEY_AI : + m_sInitAngs = sVal ; + break ; + case KEY_DH : + m_sDepth = sVal ; + if ( m_sDepth.empty()) + m_sDepth = "0" ; + break ; + case KEY_EAL : + bOk = ::FromString( sVal, m_dEndAddLen) ; + break ; + case KEY_F : + bOk = ::FromString( sVal, m_dFeed) ; + break ; + case KEY_FE : + bOk = ::FromString( sVal, m_dEndFeed) ; + break ; + case KEY_FS : + bOk = ::FromString( sVal, m_dStartFeed) ; + break ; + case KEY_FT : + bOk = ::FromString( sVal, m_dTipFeed) ; + break ; + case KEY_INV : + bOk = ::FromString( sVal, m_bInvert) ; + break ; + case KEY_LICL : + bOk = ::FromString( sVal, m_dLiCompLen) ; + break ; + case KEY_LIEL : + bOk = ::FromString( sVal, m_dLiElev) ; + break ; + case KEY_LIPR : + bOk = ::FromString( sVal, m_dLiPerp) ; + break ; + case KEY_LITG : + bOk = ::FromString( sVal, m_dLiTang) ; + break ; + case KEY_LITY : + bOk = ::FromString( sVal, m_nLeadInType) ; + break ; + case KEY_LOCL : + bOk = ::FromString( sVal, m_dLoCompLen) ; + break ; + case KEY_LOEL : + bOk = ::FromString( sVal, m_dLoElev) ; + break ; + case KEY_LOPR : + bOk = ::FromString( sVal, m_dLoPerp) ; + break ; + case KEY_LOTG : + bOk = ::FromString( sVal, m_dLoTang) ; + break ; + case KEY_LOTY : + bOk = ::FromString( sVal, m_nLeadOutType) ; + break ; + case KEY_NAME : + m_sName = sVal ; + bOk = ! m_sName.empty() ; + break ; + case KEY_NNS : + m_sSysNotes = sVal ; + break ; + case KEY_NNU : + m_sUserNotes = sVal ; + break ; + case KEY_OL : + bOk = ::FromString( sVal, m_dOffsL) ; + break ; + case KEY_OR : + bOk = ::FromString( sVal, m_dOffsR) ; + break ; + case KEY_OVL : + bOk = ::FromString( sVal, m_dOverlap) ; + break ; + case KEY_PS : + bOk = ::FromString( sVal, m_dStartPos) ; + break ; + case KEY_S : + bOk = ::FromString( sVal, m_dSpeed) ; + break ; + case KEY_SA : + bOk = ::FromString( sVal, m_dSideAngle) ; + break ; + case KEY_SAL : + bOk = ::FromString( sVal, m_dStartAddLen) ; + break ; + case KEY_SCC : + bOk = ::FromString( sVal, m_nSolCh) ; + break ; + case KEY_TNAME : + m_sToolName = sVal ; + break ; + case KEY_TUUID : + bOk = ::FromString( sVal, m_ToolUuid) ; + break ; + case KEY_UUID : + bOk = ::FromString( sVal, m_Uuid) ; + break ; + case KEY_WS : + bOk = ::FromString( sVal, m_nWorkSide) ; + break ; + default : + bOk = false ; + break ; + } + return bOk ; +} + +//---------------------------------------------------------------------------- +string +WaterJettingData::ToString( int nInd) const +{ + switch ( nInd) { + case KEY_AB : return ( sWaterJettingKey[KEY_AB] + "=" + m_sBlockedAxis) ; + case KEY_AI : return ( sWaterJettingKey[KEY_AI] + "=" + m_sInitAngs) ; + case KEY_DH : return ( sWaterJettingKey[KEY_DH] + "=" + m_sDepth) ; + case KEY_EAL : return ( sWaterJettingKey[KEY_EAL] + "=" + ::ToString( m_dEndAddLen)) ; + case KEY_F : return ( sWaterJettingKey[KEY_F] + "=" + ::ToString( m_dFeed)) ; + case KEY_FE : return ( sWaterJettingKey[KEY_FE] + "=" + ::ToString( m_dEndFeed)) ; + case KEY_FS : return ( sWaterJettingKey[KEY_FS] + "=" + ::ToString( m_dStartFeed)) ; + case KEY_FT : return ( sWaterJettingKey[KEY_FT] + "=" + ::ToString( m_dTipFeed)) ; + case KEY_INV : return ( sWaterJettingKey[KEY_INV] + "=" + ::ToString( m_bInvert)) ; + case KEY_LICL : return ( sWaterJettingKey[KEY_LICL] + "=" + ::ToString( m_dLiCompLen)) ; + case KEY_LIEL : return ( sWaterJettingKey[KEY_LIEL] + "=" + ::ToString( m_dLiElev)) ; + case KEY_LIPR : return ( sWaterJettingKey[KEY_LIPR] + "=" + ::ToString( m_dLiPerp)) ; + case KEY_LITG : return ( sWaterJettingKey[KEY_LITG] + "=" + ::ToString( m_dLiTang)) ; + case KEY_LITY : return ( sWaterJettingKey[KEY_LITY] + "=" + ::ToString( m_nLeadInType)) ; + case KEY_LOCL : return ( sWaterJettingKey[KEY_LOCL] + "=" + ::ToString( m_dLoCompLen)) ; + case KEY_LOEL : return ( sWaterJettingKey[KEY_LOEL] + "=" + ::ToString( m_dLoElev)) ; + case KEY_LOPR : return ( sWaterJettingKey[KEY_LOPR] + "=" + ::ToString( m_dLoPerp)) ; + case KEY_LOTG : return ( sWaterJettingKey[KEY_LOTG] + "=" + ::ToString( m_dLoTang)) ; + case KEY_LOTY : return ( sWaterJettingKey[KEY_LOTY] + "=" + ::ToString( m_nLeadOutType)) ; + case KEY_NAME : return ( sWaterJettingKey[KEY_NAME] + "=" + m_sName) ; + case KEY_NNS : return ( sWaterJettingKey[KEY_NNS] + "=" + m_sSysNotes) ; + case KEY_NNU : return ( sWaterJettingKey[KEY_NNU] + "=" + m_sUserNotes) ; + case KEY_OL : return ( sWaterJettingKey[KEY_OL] + "=" + ::ToString( m_dOffsL)) ; + case KEY_OR : return ( sWaterJettingKey[KEY_OR] + "=" + ::ToString( m_dOffsR)) ; + case KEY_OVL : return ( sWaterJettingKey[KEY_OVL] + "=" + ::ToString( m_dOverlap)) ; + case KEY_PS : return ( sWaterJettingKey[KEY_PS] + "=" + ::ToString( m_dStartPos)) ; + case KEY_S : return ( sWaterJettingKey[KEY_S] + "=" + ::ToString( m_dSpeed)) ; + case KEY_SA : return ( sWaterJettingKey[KEY_SA] + "=" + ::ToString( m_dSideAngle)) ; + case KEY_SAL : return ( sWaterJettingKey[KEY_SAL] + "=" + ::ToString( m_dStartAddLen)) ; + case KEY_SCC : return ( sWaterJettingKey[KEY_SCC] + "=" + ::ToString( m_nSolCh)) ; + case KEY_TNAME : return ( sWaterJettingKey[KEY_TNAME] + "=" + m_sToolName) ; + case KEY_TUUID : return ( sWaterJettingKey[KEY_TUUID] + "=" + ::ToString( m_ToolUuid)) ; + case KEY_UUID : return ( sWaterJettingKey[KEY_UUID] + "=" + ::ToString( m_Uuid)) ; + case KEY_WS : return ( sWaterJettingKey[KEY_WS] + "=" + ::ToString( m_nWorkSide)) ; + default : return "" ; + } +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::IsOptional( int nKey) const +{ + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::VerifySolCh( int nVal) const +{ + return IsValidOperationScc( nVal) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::VerifyWorkSide( int nVal) const +{ + return ( nVal == MILL_WS_CENTER || nVal == MILL_WS_LEFT || nVal == MILL_WS_RIGHT) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::VerifyLeadInType( int nVal) const +{ + return ( nVal == MILL_LI_NONE || nVal == MILL_LI_LINEAR || + nVal == MILL_LI_TANGENT || nVal == MILL_LI_GLIDE || + nVal == MILL_LI_ZIGZAG || nVal == MILL_LI_HELIX) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::VerifyLeadOutType( int nVal) const +{ + return ( nVal == MILL_LO_NONE || nVal == MILL_LO_LINEAR || + nVal == MILL_LO_TANGENT || nVal == MILL_LO_GLIDE || + nVal == MILL_LO_AS_LI) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::VerifySideAngle( double dVal) const +{ + return ( ( dVal > - EPS_SMALL && dVal < 90 + EPS_SMALL) || abs( dVal - 99) < EPS_SMALL) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::VerifyTool( const ToolsMgr* pToolsMgr, const std::string& sVal, const ToolData*& pTdata) const +{ + if ( pToolsMgr == nullptr) + return false ; + pTdata = pToolsMgr->GetTool( sVal) ; + if ( pTdata == nullptr) + return false ; + if ( ( pTdata->m_nType & TF_WATERJET) == 0) + return false ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::GetTool( const ToolsMgr* pToolsMgr, const ToolData*& pTdata) const +{ + if ( pToolsMgr == nullptr) + return false ; + pTdata = pToolsMgr->GetTool( m_ToolUuid) ; + return ( pTdata != nullptr) ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::SetParam( int nType, bool bVal) +{ + switch ( nType) { + case MPA_INVERT : + m_bInvert = bVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::SetParam( int nType, int nVal) +{ + switch ( nType) { + case MPA_WORKSIDE : + if ( ! VerifyWorkSide( nVal)) + return false ; + m_nWorkSide = nVal ; + return true ; + case MPA_LEADINTYPE : + if ( ! VerifyLeadInType( nVal)) + return false ; + m_nLeadInType = nVal ; + return true ; + case MPA_LEADOUTTYPE : + if ( ! VerifyLeadOutType( nVal)) + return false ; + m_nLeadOutType = nVal ; + return true ; + case MPA_SCC : + if ( ! VerifySolCh( nVal)) + return false ; + m_nSolCh = nVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::SetParam( int nType, double dVal) +{ + switch ( nType) { + case MPA_SPEED : + m_dSpeed = dVal ; + return true ; + case MPA_FEED : + m_dFeed = dVal ; + return true ; + case MPA_STARTFEED : + m_dStartFeed = dVal ; + return true ; + case MPA_ENDFEED : + m_dEndFeed = dVal ; + return true ; + case MPA_TIPFEED : + m_dTipFeed = dVal ; + return true ; + case MPA_OFFSL : + m_dOffsL = dVal ; + return true ; + case MPA_OFFSR : + m_dOffsR = dVal ; + return true ; + case MPA_DEPTH : + m_sDepth = ::ToString( dVal) ; + return true ; + case MPA_OVERL : + m_dOverlap = dVal ; + return true ; + case MPA_STARTPOS : + m_dStartPos = dVal ; + return true ; + case MPA_SIDEANGLE : + if ( ! VerifySideAngle( dVal)) + return false ; + m_dSideAngle = dVal ; + return true ; + case MPA_STARTADDLEN : + m_dStartAddLen = dVal ; + return true ; + case MPA_ENDADDLEN : + m_dEndAddLen = dVal ; + return true ; + case MPA_LITANG : + m_dLiTang = dVal ; + return true ; + case MPA_LIPERP : + m_dLiPerp = dVal ; + return true ; + case MPA_LIELEV : + m_dLiElev = dVal ; + return true ; + case MPA_LICOMPLEN : + m_dLiCompLen = dVal ; + return true ; + case MPA_LOTANG : + m_dLoTang = dVal ; + return true ; + case MPA_LOPERP : + m_dLoPerp = dVal ; + return true ; + case MPA_LOELEV : + m_dLoElev = dVal ; + return true ; + case MPA_LOCOMPLEN : + m_dLoCompLen = dVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::SetParam( int nType, const string& sVal) +{ + switch ( nType) { + case MPA_NAME : + m_sName = sVal ; + return true ; + case MPA_TOOL : + m_sToolName = sVal ; + return true ; + case MPA_DEPTH_STR : + m_sDepth = sVal ; + return true ; + case MPA_TUUID : + return ::FromString( sVal, m_ToolUuid) ; + case MPA_UUID : + return ::FromString( sVal, m_Uuid) ; + case MPA_SYSNOTES : + m_sSysNotes = sVal ; + return true ; + case MPA_USERNOTES : + m_sUserNotes = sVal ; + return true ; + case MPA_INITANGS : + m_sInitAngs = sVal ; + return true ; + case MPA_BLOCKEDAXIS : + m_sBlockedAxis = sVal ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::ResetTool( void) +{ + m_sToolName.clear() ; + m_ToolUuid.Clear() ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::GetParam( int nType, bool& bVal) const +{ + switch ( nType) { + case MPA_INVERT : + bVal = m_bInvert ; + return true ; + } + bVal = false ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::GetParam( int nType, int& nVal) const +{ + switch ( nType) { + case MPA_TYPE : + nVal = MT_MILLING ; + return true ; + case MPA_WORKSIDE : + nVal = m_nWorkSide ; + return true ; + case MPA_LEADINTYPE : + nVal = m_nLeadInType ; + return true ; + case MPA_LEADOUTTYPE : + nVal = m_nLeadOutType ; + return true ; + case MPA_SCC : + nVal = m_nSolCh ; + return true ; + } + nVal = 0 ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::GetParam( int nType, double& dVal) const +{ + switch ( nType) { + case MPA_SPEED : + dVal = m_dSpeed ; + return true ; + case MPA_FEED : + dVal = m_dFeed ; + return true ; + case MPA_STARTFEED : + dVal = m_dStartFeed ; + return true ; + case MPA_ENDFEED : + dVal = m_dEndFeed ; + return true ; + case MPA_TIPFEED : + dVal = m_dTipFeed ; + return true ; + case MPA_OFFSL : + dVal = m_dOffsL ; + return true ; + case MPA_OFFSR : + dVal = m_dOffsR ; + return true ; + case MPA_OVERL : + dVal = m_dOverlap ; + return true ; + case MPA_STARTPOS : + dVal = m_dStartPos ; + return true ; + case MPA_SIDEANGLE : + dVal = m_dSideAngle ; + return true ; + case MPA_STARTADDLEN : + dVal = m_dStartAddLen ; + return true ; + case MPA_ENDADDLEN : + dVal = m_dEndAddLen ; + return true ; + case MPA_LITANG : + dVal = m_dLiTang ; + return true ; + case MPA_LIPERP : + dVal = m_dLiPerp ; + return true ; + case MPA_LIELEV : + dVal = m_dLiElev ; + return true ; + case MPA_LICOMPLEN : + dVal = m_dLiCompLen ; + return true ; + case MPA_LOTANG : + dVal = m_dLoTang ; + return true ; + case MPA_LOPERP : + dVal = m_dLoPerp ; + return true ; + case MPA_LOELEV : + dVal = m_dLoElev ; + return true ; + case MPA_LOCOMPLEN : + dVal = m_dLoCompLen ; + return true ; + } + dVal = 0 ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +WaterJettingData::GetParam( int nType, string& sVal) const +{ + switch ( nType) { + case MPA_NAME : + sVal = m_sName ; + return true ; + case MPA_TOOL : + sVal = m_sToolName ; + return true ; + case MPA_DEPTH_STR : + sVal = m_sDepth ; + return true ; + case MPA_TUUID : + sVal = ::ToString( m_ToolUuid) ; + return true ; + case MPA_UUID : + sVal = ::ToString( m_Uuid) ; + return true ; + case MPA_SYSNOTES : + sVal = m_sSysNotes ; + return true ; + case MPA_USERNOTES : + sVal = m_sUserNotes ; + return true ; + case MPA_INITANGS : + sVal = m_sInitAngs ; + return true ; + case MPA_BLOCKEDAXIS : + sVal = m_sBlockedAxis ; + return true ; + } + sVal = "" ; + return false ; +} diff --git a/WaterJettingData.h b/WaterJettingData.h new file mode 100644 index 0000000..953ae4a --- /dev/null +++ b/WaterJettingData.h @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------- +// EgalTech 2019-2019 +//---------------------------------------------------------------------------- +// File : WaterJettingData.h Data : 08.07.19 Versione :2.1g2 +// Contenuto : Dichiarazione della struct WaterJettingData e costanti associate. +// +// +// +// Modifiche : 08.07.19 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "MachiningData.h" + +//---------------------------------------------------------------------------- +struct WaterJettingData : public MachiningData +{ + EgtUUID m_ToolUuid ; // identificativo universale dell'utensile + std::string m_sToolName ; // nome dell'utensile + std::string m_sInitAngs ; // angoli iniziali suggeriti (Nome1=val1,Nome2=val2) + std::string m_sBlockedAxis ; // eventuale asse rotante bloccato (Nome=val) + int m_nSolCh ; // criterio scelta soluzione (quando possibili molteplici) + double m_dSpeed ; // velocità di rotazione (+ se CCW, - se CW) ( se 0 da utensile) + double m_dFeed ; // velocità di lavorazione normale ( se 0 da utensile) + double m_dStartFeed ; // velocità di lavorazione iniziale ( se 0 da utensile) + double m_dEndFeed ; // velocità di lavorazione finale ( se 0 da utensile) + double m_dTipFeed ; // velocità di lavorazione di testa ( se 0 da utensile) + double m_dOffsR ; // offset radiale ( se UNKNOWN_PAR da utensile) + double m_dOffsL ; // offset longitudinale ( se UNKNOWN_PAR da utensile) + bool m_bInvert ; // flag di inversione direzione lavorazione + int m_nWorkSide ; // lato di lavoro (destra, sinistra, centro) + std::string m_sDepth ; // affondamento (espressione numerica) + double m_dStartPos ; // quota di inizio lavorazione (sempre >= 0) + double m_dOverlap ; // lunghezza di sovrapposizione se percorso chiuso + double m_dSideAngle ; // angolo di sbandamento (0-60deg) + double m_dStartAddLen ; // lunghezza da aggiungere/togliere all'inizio + double m_dEndAddLen ; // lunghezza da aggiungere/togliere alla fine + int m_nLeadInType ; // tipo di attacco (nessuno, lineare, tangente, inseguimento) + double m_dLiTang ; // distanza tangente da inizio attacco + double m_dLiPerp ; // distanza perpendicolare da inizio attacco + double m_dLiElev ; // elevazione da inizio attacco + double m_dLiCompLen ; // lunghezza del tratto di inserimento correttore raggio utensile + int m_nLeadOutType ; // tipo di uscita (come attacco, nessuno, lineare, tangente, inseguimento) + double m_dLoTang ; // distanza tangente verso fine uscita + double m_dLoPerp ; // distanza perpendicolare verso fine uscita + double m_dLoElev ; // elevazione verso fine uscita + double m_dLoCompLen ; // lunghezza del tratto di disinserimento correttore raggio utensile + std::string m_sSysNotes ; // note interne + std::string m_sUserNotes ; // note dell'utente + + WaterJettingData( void) + : m_ToolUuid(), m_nSolCh( 0), m_dSpeed( 0), m_dFeed( 0), m_dStartFeed( 0), m_dEndFeed( 0), m_dTipFeed( 0), + m_dOffsR( UNKNOWN_PAR), m_dOffsL( UNKNOWN_PAR), + m_bInvert( false), m_nWorkSide( 0), + m_dStartPos( 0), m_dOverlap( 0), m_dSideAngle( 0), + m_dStartAddLen( 0), m_dEndAddLen( 0), + m_nLeadInType( 0), m_dLiTang( 0), m_dLiPerp( 0), m_dLiElev( 0), m_dLiCompLen( 0), + m_nLeadOutType( 0), m_dLoTang( 0), m_dLoPerp( 0), m_dLoElev( 0), m_dLoCompLen( 0) {} + WaterJettingData* Clone( void) const override ; + bool CopyFrom( const MachiningData* pMdata) override ; + bool SameAs(const MachiningData* pMdata) const override ; + int GetType( void) const override + { return MT_WATERJETTING ; } + int GetSize( void) const override ; + std::string GetTitle( void) const override ; + bool FromString( const std::string& sString, int& nKey) override ; + std::string ToString( int nInd) const override ; + bool IsOptional( int nKey) const override ; + bool SetParam( int nType, bool bVal) override ; + bool SetParam( int nType, int nVal) override ; + bool SetParam( int nType, double dVal) override ; + bool SetParam( int nType, const std::string& sVal) override ; + bool ResetTool( void) override ; + bool GetParam( int nType, bool& bVal) const override; + bool GetParam( int nType, int& nVal) const override ; + bool GetParam( int nType, double& dVal) const override ; + bool GetParam( int nType, std::string& sVal) const override ; + bool GetTool( const ToolsMgr* pToolsMgr, const ToolData*& pTdata) const override ; + bool VerifyTool( const ToolsMgr* pToolsMgr, const std::string& sVal, const ToolData*& pTdata) const override ; + bool VerifySolCh( int nVal) const ; + bool VerifyWorkSide( int nVal) const ; + bool VerifyLeadInType( int nVal) const ; + bool VerifyLeadOutType( int nVal) const ; + bool VerifySideAngle( double dVal) const ; +} ; + +//---------------------------------------------------------------------------- +inline const WaterJettingData* GetWaterJettingData( const MachiningData* pMdata) + { return (dynamic_cast( pMdata)) ; } +inline WaterJettingData* GetWaterJettingData( MachiningData* pMdata) + { return (dynamic_cast( pMdata)) ; }