diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc
index 59ba50d..a583864 100644
Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ
diff --git a/EgtMachKernel.vcxproj b/EgtMachKernel.vcxproj
index 884ac02..921d8b3 100644
--- a/EgtMachKernel.vcxproj
+++ b/EgtMachKernel.vcxproj
@@ -283,7 +283,8 @@ copy $(TargetPath) \EgtProg\Dll64
-
+
+
Create
Create
@@ -459,6 +460,8 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
diff --git a/EgtMachKernel.vcxproj.filters b/EgtMachKernel.vcxproj.filters
index 87a3c0a..8c0d39e 100644
--- a/EgtMachKernel.vcxproj.filters
+++ b/EgtMachKernel.vcxproj.filters
@@ -150,7 +150,7 @@
Source Files\MachMgr
-
+
Source Files\Output
@@ -246,6 +246,9 @@
Source Files\Operations
+
+ Source Files\Output
+
@@ -341,7 +344,7 @@
Header Files\Include
-
+
Header Files
@@ -752,6 +755,12 @@
Header Files\Include
+
+ Header Files
+
+
+ Header Files
+
diff --git a/MachMgr.h b/MachMgr.h
index 7822799..5e8dfe5 100644
--- a/MachMgr.h
+++ b/MachMgr.h
@@ -475,6 +475,8 @@ class MachMgr : public IMachMgr
const INTVECTOR& vVmill, bool bFirst) ;
bool SimEnableToolsForVmill( bool bEnable) ;
int SimMoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt) ;
+ bool SimSaveCmd( int nType, int nPar, const std::string& sPar) ;
+
// Machine
bool GetHeadAbove( const std::string& sHead) const ;
double GetAngDeltaMinForHome( void) const ;
@@ -550,5 +552,5 @@ class MachMgr : public IMachMgr
int m_nCurrDispId ; // identificativo della disposizione corrente
int m_nCurrMachiningId ; // identificativo della lavorazione corrente
AXBLOCKVECTOR m_vAxisBlock ; // elenco assi da bloccare
- Simulator* m_pSimul ; // puntatore al simulatore attivo
+ ISimulator* m_pSimul ; // puntatore al simulatore attivo
} ;
diff --git a/MachMgrClEntities.cpp b/MachMgrClEntities.cpp
index 85d991e..58896ee 100644
--- a/MachMgrClEntities.cpp
+++ b/MachMgrClEntities.cpp
@@ -16,6 +16,7 @@
#include "DllMain.h"
#include "MachMgr.h"
#include "MachConst.h"
+#include "CamData.h"
using namespace std ;
diff --git a/MachMgrGeneration.cpp b/MachMgrGeneration.cpp
index e6ce8cd..2357967 100644
--- a/MachMgrGeneration.cpp
+++ b/MachMgrGeneration.cpp
@@ -26,8 +26,8 @@ using namespace std ;
bool
MachMgr::Generate( const string& sCncFile, const string& sInfo)
{
- // se necessaria stima speciale
- if ( GetCurrMachine() != nullptr && GetCurrMachine()->GetSpecialEstimate()) {
+ // se macchina multiprocesso è necessaria stima speciale
+ if ( GetCurrMachine() != nullptr && GetCurrMachine()->GetMultiProcess()) {
// inizializzazione stimatore
Estimator estPP ;
if ( ! estPP.Init( this)) {
diff --git a/MachMgrSimulation.cpp b/MachMgrSimulation.cpp
index 74bd84a..b434abd 100644
--- a/MachMgrSimulation.cpp
+++ b/MachMgrSimulation.cpp
@@ -16,7 +16,8 @@
#include "DllMain.h"
#include "MachMgr.h"
#include "MachConst.h"
-#include "Simulator.h"
+#include "SimulatorSP.h"
+#include "SimulatorMP.h"
using namespace std ;
@@ -27,7 +28,12 @@ MachMgr::SimInit( void)
// alloco o rialloco il simulatore
if ( m_pSimul != nullptr)
delete m_pSimul ;
- m_pSimul = new( nothrow) Simulator ;
+ if ( GetCurrMachine() == nullptr)
+ return false ;
+ if ( GetCurrMachine()->GetMultiProcess( 2))
+ m_pSimul = CreateSimulatorMP() ;
+ else
+ m_pSimul = CreateSimulatorSP() ;
if ( m_pSimul == nullptr)
return false ;
// lo inizializzo
@@ -214,3 +220,14 @@ MachMgr::SimMoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt)
// lancio movimento assi
return m_pSimul->MoveAxes( nMoveType, vAxNaEpSt) ;
}
+
+//----------------------------------------------------------------------------
+bool
+MachMgr::SimSaveCmd( int nType, int nPar, const string& sPar)
+{
+ // verifico simulatore
+ if ( m_pSimul == nullptr)
+ return false ;
+ // salvo il comando
+ return m_pSimul->SaveCmd( nType, nPar, sPar) ;
+}
diff --git a/Machine.cpp b/Machine.cpp
index 5e23e82..f1d5e45 100644
--- a/Machine.cpp
+++ b/Machine.cpp
@@ -41,7 +41,7 @@ Machine::Machine( void)
m_dExitMaxAdjust = EPS_SMALL ;
m_dExitMaxRotAdj = 10 * EPS_ANG_SMALL ;
m_dAngDeltaMinForHome = INFINITO ;
- m_bSpecialEstimate = false ;
+ m_nMultiProcess = 0 ;
m_nCalcTabId = GDB_ID_NULL ;
m_nCalcHeadId = GDB_ID_NULL ;
m_nCalcExitId = GDB_ID_NULL ;
diff --git a/Machine.h b/Machine.h
index 361888b..6113d47 100644
--- a/Machine.h
+++ b/Machine.h
@@ -71,8 +71,8 @@ class Machine
int GetHeadSelectType(const std::string& sHead) const ;
double GetAngDeltaMinForHome( void) const
{ return m_dAngDeltaMinForHome ; }
- bool GetSpecialEstimate( void) const
- { return m_bSpecialEstimate ; }
+ bool GetMultiProcess( int nOpt = 1) const
+ { return ( m_nMultiProcess >= nOpt) ; }
bool LoadTool( const std::string& sHead, int nExit, const std::string& sTool) ;
bool GetLoadedTool( const std::string& sHead, int nExit, std::string& sTool) const ;
bool UnloadTool( const std::string& sHead, int nExit) ;
@@ -293,7 +293,7 @@ class Machine
double m_dExitMaxAdjust ; // massimo aggiustamento uscita da geometria a descrizione cinematica
double m_dExitMaxRotAdj ; // massima rotazione di aggiustamento uscita da geometria a descrizione cinematica
double m_dAngDeltaMinForHome ; // minima differenza angolare da valore precedente per scegliere di stare vicino a home
- bool m_bSpecialEstimate ; // flag di esecuzione stima speciale prima della generazione
+ int m_nMultiProcess ; // flag di macchina multi-processo con stima speciale prima di generazione e simulazione ad hoc
INTVECTOR m_vLinkedRawParts ; // elenco dei grezzi agganciati a gruppi della macchina
INTVECTOR m_vLinkedFixtures ; // elenco dei bloccaggi agganciati a gruppi della macchina
INTVECTOR m_vLinkedParts ; // elenco dei pezzi agganciati a gruppi della macchina
@@ -380,6 +380,7 @@ class Machine
static int LuaEmtAddToolForVmill( lua_State* L) ;
static int LuaEmtEnableToolsForVmill( lua_State* L) ;
static int LuaEmtMoveAxes( lua_State* L) ;
+ static int LuaEmtSaveCmd( lua_State* L) ;
} ;
//----------------------------------------------------------------------------
diff --git a/MachineLua.cpp b/MachineLua.cpp
index 0974e03..b3151a5 100644
--- a/MachineLua.cpp
+++ b/MachineLua.cpp
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2024
//----------------------------------------------------------------------------
-// File : MachineLua.cpp Data : 05.08.24 Versione : 2.6h1
+// File : MachineLua.cpp Data : 01.09.24 Versione : 2.6i1
// Contenuto : Implementazione gestione macchina : funzioni Lua.
//
//
@@ -9,6 +9,7 @@
// Modifiche : 06.05.15 DS Creazione modulo.
// 26.04.20 DS Aggiunta gestione TcPos.
// 05.08.24 DS Aggiunta gestione SpecialEstimate.
+// 01.09.24 DS SpecialEstimate è diventato MultiProcess.
//
//----------------------------------------------------------------------------
@@ -35,7 +36,7 @@ static const string FLD_AXISMAXROTADJ = "AxisMaxRotAdj" ;
static const string FLD_EXITMAXADJUST = "ExitMaxAdjust" ;
static const string FLD_EXITMAXROTADJ = "ExitMaxRotAdj" ;
static const string FLD_ANGDELTAMINFORHOME = "AngDeltaMinForHome" ;
-static const string FLD_SPECIALESTIMATE = "SpecialEstimate" ;
+static const string FLD_MULTIPROCESS = "MultiProcess" ;
static const string FLD_NAME = "Name" ;
static const string FLD_PARENT = "Parent" ;
static const string FLD_GEO = "Geo" ;
@@ -145,6 +146,8 @@ Machine::LuaInit( const string& sMachineName)
m_LuaMgr.RegisterFunction( "EmtEnableToolsForVmill", Machine::LuaEmtEnableToolsForVmill) ;
// registro la funzione di movimento assi in simulazione
m_LuaMgr.RegisterFunction( "EmtMoveAxes", Machine::LuaEmtMoveAxes) ;
+ // registro la funzione di salvataggio comandi in simulazione MP
+ m_LuaMgr.RegisterFunction( "EmtSaveCmd", Machine::LuaEmtSaveCmd) ;
return true ;
}
@@ -344,9 +347,9 @@ Machine::LuaEmtGeneral( lua_State* L)
// lettura eventuale campo 'AngDeltaForHome' dalla tabella (default INFINITO)
double dAngDeltaMinForHome = INFINITO ;
LuaGetTabFieldParam( L, 1, FLD_ANGDELTAMINFORHOME, dAngDeltaMinForHome) ;
- // lettura eventuale campo 'SpecialEstimate' dalla tabella (default false)
- bool bSpecialEstimate = false ;
- LuaGetTabFieldParam( L, 1, FLD_SPECIALESTIMATE, bSpecialEstimate) ;
+ // lettura eventuale campo 'MultiProcess' dalla tabella (0=no, 1=si, 2=si con simulazione MP)
+ int nMultiProcess = 0 ;
+ LuaGetTabFieldParam( L, 1, FLD_MULTIPROCESS, nMultiProcess) ;
LuaClearStack( L) ;
// info
@@ -396,8 +399,8 @@ Machine::LuaEmtGeneral( lua_State* L)
// imposto minima differenza angolare da posizione precedente per stare vivino a posizione home
m_pMchLua->m_dAngDeltaMinForHome = dAngDeltaMinForHome ;
- // imposto flag per stima speciale
- m_pMchLua->m_bSpecialEstimate = bSpecialEstimate ;
+ // imposto flag per macchina multiprocesso
+ m_pMchLua->m_nMultiProcess = nMultiProcess ;
return 0 ;
}
@@ -1511,7 +1514,7 @@ int
Machine::LuaEmtEnableToolsForVmill( lua_State* L)
{
// 1 parametro : bEnable
- bool bEnable ;
+ bool bEnable = false ;
LuaGetParam( L, 1, bEnable) ;
LuaClearStack( L) ;
// verifico ci sia una macchina attiva
@@ -1553,7 +1556,31 @@ Machine::LuaEmtMoveAxes( lua_State* L)
// assegno risultato
if ( nRes == SIM_AXMV_RES_STOP)
return luaL_error( L, "STOP") ;
- else
+ else {
LuaSetParam( L, ( nRes == SIM_AXMV_RES_OK)) ;
+ LuaSetParam( L, m_pMchLua->GetMultiProcess()) ;
+ }
+ return 2 ;
+}
+
+//----------------------------------------------------------------------------
+int
+Machine::LuaEmtSaveCmd( lua_State* L)
+{
+ // parametri : nType,
+ int nType = 0 ;
+ LuaGetParam( L, 1, nType) ;
+ int nPar = 0 ;
+ LuaGetParam( L, 2, nPar) ;
+ string sPar ;
+ LuaGetParam( L, 3, sPar) ;
+ LuaClearStack( L) ;
+ // verifico ci sia una macchina attiva
+ if ( m_pMchLua == nullptr)
+ return luaL_error( L, " Unknown Machine") ;
+ // salvo il comando
+ bool bOk = ( m_pMchLua->m_pMchMgr != nullptr && m_pMchLua->m_pMchMgr->SimSaveCmd( nType, nPar, sPar)) ;
+ // assegno risultato
+ LuaSetParam( L, bOk) ;
return 1 ;
}
diff --git a/MachineLuaCL.cpp b/MachineLuaCL.cpp
index f81ee6c..fca5e18 100644
--- a/MachineLuaCL.cpp
+++ b/MachineLuaCL.cpp
@@ -15,6 +15,7 @@
#include "stdafx.h"
#include "MachMgr.h"
#include "DllMain.h"
+#include "CamData.h"
#include "/EgtDev/Include/EXeExecutor.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
diff --git a/Operation.h b/Operation.h
index abe69a4..da97f8a 100644
--- a/Operation.h
+++ b/Operation.h
@@ -17,6 +17,7 @@
#include "MachMgr.h"
#include "MachConst.h"
#include "MachineStruConst.h"
+#include "CamData.h"
#include "/EgtDev/Include/EGkPoint3d.h"
#include "/EgtDev/Include/EGkUserObj.h"
#include "/EgtDev/Include/EGkSelection.h"
diff --git a/OutputConst.h b/OutputConst.h
index 97ba635..1ee6854 100644
--- a/OutputConst.h
+++ b/OutputConst.h
@@ -184,6 +184,7 @@ static const std::string GVAR_SIMUISTAT = ".SIMUISTAT" ; // (num) stato sim
static const std::string GVAR_SAFEDIST = ".SAFEDIST" ; // (num) distanza di sicurezza per verifica di collisione
static const std::string GVAR_SIMVMID = ".SIMVMID" ; // (int) identificativo grezzo Vmill in collisione
static const std::string GVAR_SIMCOBIND = ".SIMCOBIND" ; // (int) indice oggetto in collisione
+static const std::string GVAR_MPSIM = ".MPSIM" ; // (bool) flag simulazione multiprocesso
// Funzioni generazione
static const std::string ON_START = "OnStart" ;
static const std::string ON_END = "OnEnd" ;
diff --git a/Pocketing.cpp b/Pocketing.cpp
index ee2f079..0c22ab8 100644
--- a/Pocketing.cpp
+++ b/Pocketing.cpp
@@ -5744,7 +5744,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo)
pCrv = pCompo->GetNextCurve() ;
}
// se non trovato o troppo corto, cerco il tratto generico più lungo
- if ( nMax < 0 || dLenMax < 2 * m_TParams.m_dDiam) {
+ if ( nMax < 0 || dLenMax < 1.25 * m_TParams.m_dDiam) {
i = 0 ;
pCrv = pCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
diff --git a/Simulator.h b/Simulator.h
index aeb8fac..d2704e3 100644
--- a/Simulator.h
+++ b/Simulator.h
@@ -1,25 +1,24 @@
//----------------------------------------------------------------------------
-// EgalTech 2015-2023
+// EgalTech 2015-2024
//----------------------------------------------------------------------------
-// File : Simulator.h Data : 16.01.23 Versione : 2.5a2
-// Contenuto : Dichiarazione della classe Simulator.
+// File : Simulator.h Data : 01.09.24 Versione : 2.6i1
+// Contenuto : Dichiarazione della classe interfaccia ISimulator.
//
//
//
-// Modifiche : 19.10.15 DS Creazione modulo.
+// Modifiche : 01.09.24 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
-#include "CamData.h"
+#include "/EgtDev/Include/EGkVector3d.h"
#include "/EgtDev/Include/EMkSimuGenConst.h"
+#include "/EgtDev/Include/EgtNumCollection.h"
+#include
class MachMgr ;
-class IGeomDB ;
-class Machine ;
-class PerformanceCounter ;
//------------------------ Struttura per movimento esterno assi --------------
struct SimAxMv
@@ -38,160 +37,27 @@ enum SimAxMvRes { SIM_AXMV_RES_STOP = -1,
SIM_AXMV_RES_OK = 1} ;
//----------------------------------------------------------------------------
-class Simulator
+class __declspec( novtable) ISimulator
{
public :
- Simulator( void) ;
- ~Simulator( void) ;
- bool Init( MachMgr* pMchMgr) ;
- bool Start( bool bFirst) ;
- bool Move( int& nStatus) ;
- bool GoHome( void) ;
- bool SetStep( double dStep) ;
- bool SetUiStatus( int nUiStatus) ;
- bool GetAxisInfoPos( int nI, std::string& sName, std::string& sToken, bool& bLinear, double& dVal) const ;
- bool GetToolInfo( std::string& sName, double& dSpeed) const ;
- bool GetOperationInfo( std::string& sName, int& nType) const ;
- bool GetMoveInfo( int& nGmove, double& dFeed) const ;
- bool AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType, const Vector3d& vtMove, double dPar1, double dPar2, double dPar3) ;
- bool ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType) ;
- bool OnCollision( int nCdInd, int nObjInd, int& nErr) ;
- bool SetToolForVmill( const std::string& sTool, const std::string& sHead, int nExit, int nFlag, double dPar1, double dPar2,
- const INTVECTOR& vVmill, bool bFirst) ;
- bool EnableToolsForVmill( bool bEnable) ;
- int MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt) ;
-
- private :
- bool UpdateTool( bool bFirst, int& nErr) ;
- bool UpdateAxes( void) ;
- bool UpdateAxesPos( void) ;
- bool ResetInterpolation( void) ;
- bool ResetAxes( void) ;
- bool ResetAuxAxes( void) ;
-
- private :
- bool VerifySetup( void) ;
- bool FindAndManageOperationStart( bool bStart, bool bFirst, int& nStatus) ;
- bool ManageOperationEnd( int& nStatus) ;
- bool FindAndManagePathStart( int& nStatus) ;
- bool ManagePathEnd( int& nStatus) ;
- bool ManagePathStartAux( int& nStatus) ;
- bool ManagePathEndAux( int& nStatus) ;
- bool ManageMove( int& nStatus) ;
- bool ManageSingleMove( int& nStatus, double& dMove) ;
- int CalcStatusOnError( int nErr) ;
- bool GetHeadCurrPosDirAux( const std::string& sHead, int nExit, Point3d& ptH, Vector3d& vtH, Vector3d& vtA) ;
- bool ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVmAdOffs,
- const Point3d& ptHi, const Vector3d& vtHi, const Vector3d& vtAi, const Frame3d& frVzmI,
- const Point3d& ptHf, const Vector3d& vtHf, const Vector3d& vtAf, const Frame3d& frVzmF) ;
- bool NeedCollisionCheck( void) const
- { return ( ! m_CollObj.empty() && ! m_CdId.empty()) ; }
- bool Stopped( void)
- { return ( m_nUiStatus == MCH_UISIM_STOP) ; }
- bool SetCollisionMark( int nCdInd, int nObjInd) ;
- bool ResetCollisionMark( void) ;
- bool OnInit( void) ;
- bool OnExit( void) ;
- bool OnProgramStart( bool bFirst) ;
- bool OnProgramEnd( void) ;
- bool OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
- const std::string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand) ;
- bool OnDispositionStart( int nOpId, int nOpInd, int nPhase,
- const std::string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand) ;
- bool OnDispositionEnd( void) ;
- bool OnToolSelect( const std::string& sTool, const std::string& sHead, int nExit, const std::string& sTcPos, bool bFirst, int& nErr) ;
- bool OnToolDeselect( const std::string& sNextTool, const std::string& sNextHead, int nNextExit, const std::string& sNextTcPos, int& nErr) ;
- bool OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax,
- const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax) ;
- bool OnMachiningEnd( void) ;
- bool OnPathStartAux( int nInd, const std::string& sAS, int& nErr) ;
- bool OnPathEndAux( int nInd, const std::string& sAE, int& nErr) ;
- bool OnPathStart( int nClPathId, int nClPathInd, int nAS, const Point3d& ptStart, const Point3d& ptEnd,
- const Vector3d& vtExtr, const Point3d& ptMin, const Point3d& ptMax,
- const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax, double dElev) ;
- bool OnPathEnd( int nAE) ;
- bool OnMoveStart( const CamData* pCamData, const CamData* pNextCamData, int& nErr) ;
- bool OnMoveEnd( int& nErr) ;
- bool OnResetMachine( void) ;
-
- private :
- struct CollObj {
- int nInd ;
- bool bToolOn ;
- int nFrameId ;
- int nType ;
- Vector3d vtMove ;
- double dPar1 ;
- double dPar2 ;
- double dPar3 ;
- CollObj( void) : nInd( 0), bToolOn( false), nFrameId( -1), nType( 0), vtMove(), dPar1( 0), dPar2( 0), dPar3( 0) {}
- CollObj( int nI, bool bTOn, int nF, int nT, const Vector3d& vtM, double dP1, double dP2, double dP3)
- : nInd( nI), bToolOn( bTOn), nFrameId( nF), nType( nT), vtMove( vtM), dPar1( dP1), dPar2( dP2), dPar3( dP3) {}
- } ;
- typedef std::vector COBVECTOR ;
- struct VmTool
- {
- std::string sName ;
- std::string sHead ;
- int nExit ;
- double dTdOffs ;
- double dAdOffs ;
- VmTool( void) : nExit( 0), dTdOffs( 0), dAdOffs( 0) {}
- VmTool( std::string sN, std::string sH, int nE, double dT, double dA)
- : sName( sN), sHead( sH), nExit( nE), dTdOffs( dT), dAdOffs( dA) {}
- } ;
- typedef std::vector VMTVECTOR ;
- enum { SIS_CREATED = 0,
- SIS_INITIALIZED = 1,
- SIS_READYTOSTART = 2,
- SIS_READYTORUN = 3} ;
-
- private :
- MachMgr* m_pMchMgr ; // puntatore al gestore di tutte le lavorazioni
- IGeomDB* m_pGeomDB ; // puntatore al DB geometrico
- Machine* m_pMachine ; // puntatore alla macchina
- PerformanceCounter* m_pPerfCnt ; // timer per calcolo FPS
- int m_nStatus ; // stato interno del simulatore (creato, inizializzato, pronto al movimento)
- double m_dStep ; // lunghezza di riferimento per la velocità di simulazione
- int m_nUiStatus ; // stato simulazione a livello utente
- int m_nOpId ; // identificativo della operazione (lavoraz.) corrente
- int m_nOpInd ; // contatore della operazione (lavoraz.) corrente
- int m_nCLPathId ; // identificativo del percorso di lavoro corrente
- int m_nCLPathInd ; // contatore del percorso di lavoro corrente nell'operazione
- int m_nEntId ; // identificativo dell'entità corrente
- int m_nEntInd ; // contatore dell'entità corrente nel percorso di lavoro
- double m_dCoeff ; // coefficiente di esecuzione del movimento corrente (0...1)
- int m_nAuxSTot ; // numero totale movimenti ausiliari di inizio percorso
- int m_nAuxSInd ; // indice del movimento ausiliario di inizio percorso corrente
- int m_nAuxETot ; // numero totale movimenti ausiliari di fine percorso
- int m_nAuxEInd ; // indice del movimento ausiliario di fine percorso corrente
- std::string m_sTool ; // nome dell'utensile corrente
- std::string m_sHead ; // nome della testa corrente
- int m_nExit ; // indice dell'uscita corrente
- double m_dTDiam ; // diametro dell'utensile corrente
- bool m_bCutOnTip ; // flag capacità di lavorare di testa dell'utensile corrente
- bool m_bEnableVm ; // flag abilitazione Virtual Milling
- INTVECTOR m_VmId ; // vettore identificativi Zmap per Virtual Milling
- INTVECTOR m_CdId ; // vettore identificativi Zmap per Collision Detection
- VMTVECTOR m_VmTool ; // vettore utensili attivi per virtual milling
- COBVECTOR m_CollObj ; // vettore oggetti da testare per collisione con grezzo
- double m_dSafeDist ; // distanza di sicurezza per verifica collisioni
- INTVECTOR m_nCollMarkId ; // elenco oggetti marcati per visualizzare meglio la collisione rilevata
- int m_nAxesMask ; // maschera a bit di abilitazione movimento assi (solo se rapido)
- bool m_bEnabAxes ; // flag abilitazione movimento assi attivi
- bool m_bShowAxes ; // flag visualizzazione assi attivi
- STRVECTOR m_AxesName ; // nomi degli assi macchina attivi
- STRVECTOR m_AxesToken ; // token degli assi macchina attivi
- BOOLVECTOR m_AxesInvert ; // flag di asse con verso invertito degli assi macchina attivi
- DBLVECTOR m_AxesOffset ; // valore di offset delgli assi macchina ttivi
- BOOLVECTOR m_AxesLinear ; // flag di lineare degli assi macchina attivi
- DBLVECTOR m_AxesVal ; // valori degli assi macchina all'inizio del movimento corrente
- STRVECTOR m_AuxAxesName ; // nomi degli assi macchina ausiliari abilitati
- STRVECTOR m_AuxAxesToken ; // token degli assi macchina ausiliari abilitati
- BOOLVECTOR m_AuxAxesInvert ; // flag di asse con verso invertito degli assi macchina ausiliari abilitati
- DBLVECTOR m_AuxAxesOffset ; // valore di offset degli assi macchina ausiliari abilitati
- BOOLVECTOR m_AuxAxesLinear ; // flag di lineare degli assi macchina ausiliari abilitati
- DBLVECTOR m_AuxAxesVal ; // valori degli assi macchina ausiliari all'inizio del movimento corrente
- DBLVECTOR m_AuxAxesEnd ; // valori degli assi macchina ausiliari alla fine del movimento corrente
- INTVECTOR m_AuxAxesLink ; // indice + 1 asse principale di aggancio (negativo valore opposto, 0 nessuno)
+ virtual ~ISimulator( void) {}
+ virtual bool Init( MachMgr* pMchMgr) = 0 ;
+ virtual bool Start( bool bFirst) = 0 ;
+ virtual bool Move( int& nStatus) = 0 ;
+ virtual bool GoHome( void) = 0 ;
+ virtual bool SetStep( double dStep) = 0 ;
+ virtual bool SetUiStatus( int nUiStatus) = 0 ;
+ virtual bool GetAxisInfoPos( int nI, std::string& sName, std::string& sToken, bool& bLinear, double& dVal) const = 0 ;
+ virtual bool GetToolInfo( std::string& sName, double& dSpeed) const = 0 ;
+ virtual bool GetOperationInfo( std::string& sName, int& nType) const = 0 ;
+ virtual bool GetMoveInfo( int& nGmove, double& dFeed) const = 0 ;
+ virtual bool AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType,
+ const Vector3d& vtMove, double dPar1, double dPar2, double dPar3) = 0 ;
+ virtual bool ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType) = 0 ;
+ virtual bool OnCollision( int nCdInd, int nObjInd, int& nErr) = 0 ;
+ virtual bool SetToolForVmill( const std::string& sTool, const std::string& sHead, int nExit, int nFlag,
+ double dPar1, double dPar2, const INTVECTOR& vVmill, bool bFirst) = 0 ;
+ virtual bool EnableToolsForVmill( bool bEnable) = 0 ;
+ virtual int MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt) = 0 ;
+ virtual bool SaveCmd( int nType, int nPar, const std::string& sPar) = 0 ;
} ;
diff --git a/SimulatorMP.cpp b/SimulatorMP.cpp
new file mode 100644
index 0000000..6df9161
--- /dev/null
+++ b/SimulatorMP.cpp
@@ -0,0 +1,2572 @@
+//----------------------------------------------------------------------------
+// EgalTech 2024-2024
+//----------------------------------------------------------------------------
+// File : SimulatorMP.cpp Data : 01.09.24 Versione : 2.6i1
+// Contenuto : Implementazione della classe SimulatorMP.
+// Simulatore multi-processo.
+//
+//
+// Modifiche : 01.09.24 DS Creazione modulo.
+//
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "SimulatorMP.h"
+#include "MachMgr.h"
+#include "Disposition.h"
+#include "Machining.h"
+#include "MachiningConst.h"
+#include "OutputConst.h"
+#include "DllMain.h"
+#include "/EgtDev/Include/EGkCDeBoxClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeCylClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeSpheClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeConeFrustumClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h"
+#include "/EgtDev/Include/EGkVolZmap.h"
+#include "/EgtDev/Include/EGkGeoVector3d.h"
+#include "/EgtDev/Include/EGkStringUtils3d.h"
+#include "/EgtDev/Include/EGkSurfLocal.h"
+#include "/EgtDev/Include/EXeCmdLogOff.h"
+#include "/EgtDev/Include/EXeConst.h"
+#include "/EgtDev/Include/EMkToolConst.h"
+#include "/EgtDev/Include/EMkOperationConst.h"
+#include "/EgtDev/Include/EgtPerfCounter.h"
+#include "/EgtDev/Include/EgtNumUtils.h"
+
+using namespace std ;
+
+//------------------------------ Errors --------------------------------------
+// 1001 = "Error with setup : xxx"
+
+//----------------------------------------------------------------------------
+static const double MIN_STEP = 1.0 ;
+static const double MAX_STEP = 500.0 ;
+static const double MID_STEP = 50.0 ;
+static const double COLL_STEP = 10. ;
+static const double SQ_COEFF_ROT_MOVE = 100. ;
+static const double COEFF_LIM = 0.999 ;
+static const double SAFEDIST_STD = 5.0 ;
+static const int ERR_NONE = 0 ;
+static const int ERR_OUTSTROKE = 1 ;
+static const int ERR_COLLISION = 11 ;
+static const int ERR_TOOL_SEL = 21 ;
+
+//----------------------------------------------------------------------------
+ISimulator*
+CreateSimulatorMP( void)
+{
+ return static_cast ( new( nothrow) SimulatorMP) ;
+}
+
+//----------------------------------------------------------------------------
+SimulatorMP::SimulatorMP( void)
+{
+ m_pMchMgr = nullptr ;
+ m_pGeomDB = nullptr ;
+ m_pMachine = nullptr ;
+ m_pPerfCnt = nullptr ;
+ m_nStatus = SIS_CREATED ;
+ m_dStep = MID_STEP ;
+ m_nUiStatus = MCH_UISIM_NULL ;
+ m_nOpId = GDB_ID_NULL ;
+ m_nOpInd = 0 ;
+ m_nCLPathId = GDB_ID_NULL ;
+ m_nCLPathInd = 0 ;
+ m_nEntId = GDB_ID_NULL ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ m_bChangedTool = false ;
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ m_nExit = 0 ;
+ m_dTDiam = 0 ;
+ m_bCutOnTip = false ;
+ m_bEnableVm = false ;
+ m_dSafeDist = SAFEDIST_STD ;
+ m_nAxesMask = 0 ;
+ m_bEnabAxes = true ;
+ m_bShowAxes = true ;
+ m_AxesName.reserve( 8) ;
+ m_AxesToken.reserve( 8) ;
+ m_AxesLinear.reserve( 8) ;
+ m_AxesVal.reserve( 8) ;
+ m_nCmdInd = 0 ;
+ m_dCmdCoeff = 0 ;
+}
+
+//----------------------------------------------------------------------------
+SimulatorMP::~SimulatorMP( void)
+{
+ // porto la macchina in posizione home
+ GoHome() ;
+ // gestione evento uscita dal simulatore
+ OnExit() ;
+ // rimuovo tavola variabili globali
+ m_pMachine->LuaResetGlobVar( GLOB_VAR) ;
+ // rimuovo performance counter
+ if ( m_pPerfCnt != nullptr) {
+ delete m_pPerfCnt ;
+ m_pPerfCnt = nullptr ;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::Init( MachMgr* pMchMgr)
+{
+ // verifico ambiente
+ if ( pMchMgr == nullptr || pMchMgr->GetContextId() == 0 ||
+ pMchMgr->GetGeomDB() == nullptr || pMchMgr->GetCurrMachine() == nullptr)
+ return false ;
+ m_pMchMgr = pMchMgr ;
+ m_pGeomDB = m_pMchMgr->GetGeomDB() ;
+ m_pMachine = m_pMchMgr->GetCurrMachine() ;
+ m_pPerfCnt = new PerformanceCounter ;
+ m_nStatus = SIS_INITIALIZED ;
+ if ( ExeGetDebugLevel() >= 1)
+ LOG_INFO( GetEMkLogger(), " * SimulatorMP *")
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::Start( bool bFirst)
+{
+ // Verifico ci sia una macchinata corrente
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr || m_pMachine == nullptr ||
+ m_pMchMgr->GetCurrMachGroup() == GDB_ID_NULL)
+ return false ;
+ m_pMchMgr->ResetLastError() ;
+ m_pMchMgr->ResetWarnings() ;
+
+ bool bOk = true ;
+
+ // Se appena entrati in simulazione
+ if ( m_nStatus == SIS_INITIALIZED) {
+ // Forzo aggiornamento attrezzaggio della macchinata
+ if ( ! m_pMchMgr->UpdateCurrSetup())
+ bOk = false ;
+ // Verifico attrezzaggio
+ if ( ! VerifySetup())
+ bOk = false ;
+ }
+
+ // Reset utensile, interpolazione e assi correnti
+ m_sTool.clear() ;
+ m_sHead.clear() ;
+ m_nExit = 0 ;
+ m_dTDiam = 0 ;
+ m_bCutOnTip = false ;
+ m_bChangedTool = false ;
+ ResetInterpolation() ;
+ ResetAxes() ;
+ ResetAuxAxes() ;
+
+ // porto la macchina in home
+ if ( ! GoHome())
+ bOk = false ;
+
+ // Verifico la disposizione iniziale della macchinata
+ m_nOpId = m_pMchMgr->GetFirstActiveOperation() ;
+ m_nOpInd = 1 ;
+ if ( m_pMchMgr->GetOperationType( m_nOpId) != OPER_DISP)
+ bOk = false ;
+
+ // Definisco tabella variabili globali
+ if ( ! m_pMachine->LuaCreateGlobTable( GLOB_VAR))
+ bOk = false ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_INCHES, ! ExeUiUnitsAreMM()) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_VER, GetEMkVer()) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MACHNAME, m_pMachine->GetMachineName()) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MPSIM, true) ;
+
+ // Se appena entrati in simulazione
+ if ( m_nStatus == SIS_INITIALIZED) {
+ if ( ! OnInit())
+ bOk = false ;
+ m_nStatus = SIS_READYTOSTART ;
+ }
+
+ // Richiamo funzione per evento avvio simulazione
+ if ( ! OnProgramStart( bFirst))
+ bOk = false ;
+
+ // Arrivo alla preparazione per la prima lavorazione
+ int nStatus ;
+ if ( ! FindAndManageOperationStart( true, bFirst, m_bChangedTool, nStatus) && nStatus != MCH_SIM_STOP)
+ bOk = false ;
+ // se sono ancora su disposizione
+ if ( m_pMchMgr->GetOperationType( m_nOpId) == OPER_DISP) {
+ // ricerca e gestione inizio percorso di lavoro
+ if ( ! FindAndManagePathStart( nStatus))
+ return false ;
+ // eventuali comandi ausiliari di inizio percorso
+ while ( m_nAuxSInd < m_nAuxSTot) {
+ if ( ! ManagePathStartAux( nStatus))
+ return false ;
+ }
+ // aggiornamento assi per eventuali teste caricate
+ UpdateAxes() ;
+ }
+
+ if ( ! ExecAllCmdData( nStatus))
+ return false ;
+
+ // Reset timer
+ if ( m_pPerfCnt != nullptr)
+ m_pPerfCnt->Start() ;
+
+ // Imposto lo stato interno
+ m_nStatus = ( bOk ? SIS_READYTORUN : SIS_READYTOSTART) ;
+
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::VerifySetup( void)
+{
+ // se attrezzaggio non definito, nulla da verificare
+ if ( ! m_pMchMgr->GetCurrSetupMgr().Exists())
+ return true ;
+
+ // lancio la verifica
+ STRVECTOR vsErr ;
+ if ( m_pMchMgr->VerifyCurrSetup( vsErr))
+ return true ;
+
+ // gestisco errore
+ string sErr = "Error with setup :" ;
+ for ( const auto& sTmp : vsErr)
+ sErr += " " + sTmp ;
+ m_pMchMgr->SetLastError( 1001, sErr) ;
+ return false ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ResetInterpolation( void)
+{
+ m_nOpId = GDB_ID_NULL ;
+ m_nOpInd = 0 ;
+ m_nCLPathId = GDB_ID_NULL ;
+ m_nCLPathInd = 0 ;
+ m_nEntId = GDB_ID_NULL ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ m_VmId.clear() ;
+ m_CdId.clear() ;
+ m_VmTool.clear() ;
+ m_CollObj.clear() ;
+ m_dSafeDist = SAFEDIST_STD ;
+ m_nAxesMask = 0 ;
+ m_bEnabAxes = true ;
+ m_bShowAxes = true ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::Move( int& nStatus)
+{
+ // Verifiche
+ if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr || m_nStatus != SIS_READYTORUN) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+
+ // Recupero tempo impiegato (calcolo + visualizzazione precedenti)
+ if ( m_pPerfCnt != nullptr && ExeGetDebugLevel() >= 5) {
+ double dElapsed = m_pPerfCnt->Stop() ;
+ string sOut = "Elapsed=" + ToString( dElapsed, 1) ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ m_pPerfCnt->Start() ;
+ }
+
+ // reset visualizzazione collisioni
+ ResetCollisionMark() ;
+
+ // Se arrivato alla fine dell'interpolazione
+ if ( m_dCoeff > COEFF_LIM) {
+ // recupero una nuova entità
+ m_nEntId = m_pGeomDB->GetNext( m_nEntId) ;
+ m_dCoeff = 0 ;
+ }
+
+ // Se appena arrivato alla fine di un percorso di lavoro (verifico anche completamento dei comandi aux di start per path vuote)
+ if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd == 0 && m_nCLPathInd > 0 && m_nAuxSInd >= m_nAuxSTot) {
+ // gestione fine percorso di lavoro
+ if ( ! ManagePathEnd( nStatus))
+ return false ;
+ }
+
+ // Se alla fine del percorso dopo esecuzione azioni ausiliarie (verifico anche completamento dei comandi aux di start per path vuote)
+ if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd >= m_nAuxETot && m_nAuxSInd >= m_nAuxSTot) {
+ // ricerca e gestione inizio percorso di lavoro
+ if ( ! FindAndManagePathStart( nStatus))
+ return false ;
+ }
+
+ // Se arrivato alla fine di una operazione o appena scaricato utensile
+ if ( m_nCLPathId == GDB_ID_NULL || m_bChangedTool) {
+ // gestione fine operazione
+ if ( m_nCLPathId == GDB_ID_NULL && ! ManageOperationEnd( nStatus))
+ return false ;
+ // ricerca e gestione nuova operazione
+ if ( ! FindAndManageOperationStart( false, false, m_bChangedTool, nStatus))
+ return false ;
+ if ( m_bChangedTool)
+ return true ;
+ // se non ce ne sono altre, sono alla fine
+ if ( m_nOpId == GDB_ID_NULL) {
+ OnProgramEnd() ;
+ nStatus = MCH_SIM_END ;
+ return false ;
+ }
+ // ricerca e gestione inizio percorso di lavoro
+ if ( ! FindAndManagePathStart( nStatus))
+ return false ;
+ }
+
+ // Se comandi in lista ancora da eseguire, procedo con uno step
+ if ( m_nCmdInd < int( m_CmdData.size())) {
+ return ExecCmdData( nStatus) ;
+ }
+ else {
+ m_CmdData.clear() ;
+ m_nCmdInd = 0 ;
+ }
+
+ // Se sto eseguendo i movimenti ausiliari di inizio percorso
+ if ( m_nAuxSInd < m_nAuxSTot)
+ return ManagePathStartAux( nStatus) ;
+
+ // Se sto eseguendo i movimenti ausiliari di fine percorso
+ if ( m_nAuxEInd < m_nAuxETot)
+ return ManagePathEndAux( nStatus) ;
+
+ // Gestione movimento assi
+ return ManageMove( nStatus) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::GetAxisInfoPos( int nI, string& sName, string& sToken, bool& bLinear, double& dVal) const
+{
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // numero assi di calcolo e ausiliari
+ int nAxisCount = ( m_bShowAxes ? int( m_AxesName.size()) : 0) ;
+ int nAuxAxisCount = int( m_AuxAxesName.size()) ;
+ // recupero i dati dell'asse
+ if ( nI < 0 || nI >= nAxisCount + nAuxAxisCount)
+ return false ;
+ // se asse principale
+ if ( nI < nAxisCount) {
+ sName = m_AxesName[nI] ;
+ sToken = m_AxesToken[nI] ;
+ bLinear = m_AxesLinear[nI] ;
+ }
+ // altrimenti asse ausiliario
+ else {
+ sName = m_AuxAxesName[ nI - nAxisCount] ;
+ sToken = m_AuxAxesToken[ nI - nAxisCount] ;
+ bLinear = m_AuxAxesLinear[ nI - nAxisCount] ;
+ }
+ // recupero la posizione
+ if ( ! m_pMchMgr->GetAxisPos( sName, dVal))
+ return false ;
+ // verifico se da invertire o offsettare
+ if ( nI < nAxisCount) {
+ if ( m_AxesInvert[nI])
+ dVal = - dVal ;
+ dVal += m_AxesOffset[nI] ;
+ }
+ else {
+ if ( m_AuxAxesInvert[nI - nAxisCount])
+ dVal = - dVal ;
+ dVal += m_AxesOffset[nI - nAxisCount] ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::GetToolInfo( string& sName, double& dSpeed) const
+{
+ // Inizializzo i parametri di ritorno
+ sName.clear() ;
+ dSpeed = 0 ;
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // Assegno il nome dell'utensile
+ sName = m_sTool ;
+ if ( sName.empty())
+ return true ;
+ // Recupero speed
+ const Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ return ( pMch != nullptr && pMch->GetParam( MPA_SPEED, dSpeed)) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::GetOperationInfo( string& sName, int& nType) const
+{
+ // Inizializzo i parametri di ritorno
+ sName.clear() ;
+ nType = OPER_NULL ;
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // Recupero il tipo
+ Operation* pOpe = GetOperation( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pOpe == nullptr)
+ return false ;
+ nType = pOpe->GetType() ;
+ // Recupero il nome
+ return m_pGeomDB->GetName( m_nOpId, sName) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::GetMoveInfo( int& nGmove, double& dFeed) const
+{
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // Recupero il movimento corrente
+ const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
+ if ( pCamData == nullptr)
+ return false ;
+ // Assegno feed
+ dFeed = pCamData->GetFeed() ;
+ // Assegno tipo di movimento
+ nGmove = pCamData->GetMoveType() ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::SetStep( double dStep)
+{
+ m_dStep = Clamp( dStep, MIN_STEP, MAX_STEP) ;
+ // imposto step per movimenti gestiti nelle macro di simulazione ( con ripristino macchina Lua originale)
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::SetUiStatus( int nUiStatus)
+{
+ m_nUiStatus = nUiStatus ;
+ // imposto stato utente del simulatore per movimenti gestiti nelle macro di simulazione ( con ripristino macchina Lua originale)
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMUISTAT, m_nUiStatus) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::GoHome( void)
+{
+ // controllo validità stato
+ if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr)
+ return false ;
+ // reset visualizzazione collisioni
+ ResetCollisionMark() ;
+ // reset stato macchina
+ OnResetMachine() ;
+ // porto la macchina in home
+ m_pMchMgr->ResetAllAxesPos() ;
+ // assegno valori home degli assi macchina attivi
+ return m_pMchMgr->GetAllCurrAxesHomePos( m_AxesVal) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::UpdateMachiningTool( bool bFirst, bool& bDeselected, int& nErr)
+{
+ // Reset stato
+ nErr = ERR_NONE ;
+
+ // Recupero la lavorazione corrente
+ Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pMch == nullptr)
+ return false ;
+
+ // Recupero nome e dati nuovo utensile
+ string sTuuid, sTool ;
+ if ( ! pMch->GetParam( MPA_TUUID, sTuuid) ||
+ ! m_pMchMgr->TdbGetToolFromUUID( sTuuid, sTool))
+ return false ;
+ string sTcPos ; string sHead ; int nExit ;
+ if ( ! m_pMchMgr->GetCurrSetupMgr().GetToolData( sTool, sTcPos, sHead, nExit)) {
+ if ( m_pMchMgr->TdbSetCurrTool( sTool)) {
+ m_pMchMgr->TdbGetCurrToolParam( TPA_TCPOS, sTcPos) ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_HEAD, sHead) ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_EXIT, nExit) ;
+ }
+ // ripristino l'utensile corrente
+ m_pMchMgr->TdbSetCurrTool( m_sTool) ;
+ }
+ // verifico se cambierà
+ bool bDiffTool = ( sTool != m_sTool) ;
+ // se cambierà ed esiste il corrente, lo scarico
+ if ( bDiffTool && ! m_sTool.empty() && ! bDeselected) {
+ // eventuale lancio script per scarico utensile
+ int nCurrErr ;
+ if ( OnToolDeselect( sTool, sHead, nExit, sTcPos, nCurrErr)) {
+ bDeselected = true ;
+ return true ;
+ }
+ else {
+ nErr = ( nErr != ERR_NONE ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ }
+ bDeselected = false ;
+ // se prima volta, pulisco la testa
+ if ( bFirst)
+ m_pMchMgr->ResetHeadSet( sHead) ;
+ // recupero la lavorazione corrente e imposto la nuova
+ int nCurrMchId = m_pMchMgr->GetCurrMachining() ;
+ m_pMchMgr->SetCurrMachining( m_nOpId) ;
+ // carico l'utensile (e lo rendo corrente)
+ if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
+ return false ;
+ m_sTool = sTool ;
+ m_sHead = sHead ;
+ m_nExit = nExit ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ;
+ double dTipFeed = 0 ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ;
+ m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ;
+ // ripristino la lavorazione corrente
+ m_pMchMgr->SetCurrMachining( nCurrMchId) ;
+ // aggiorno gli assi macchina
+ if ( ! UpdateAxes())
+ return false ;
+ // se cambiato oppure prima volta, lancio lo script di selezione
+ if ( bDiffTool || bFirst) {
+ int nCurrErr ;
+ if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst, nCurrErr)) {
+ nErr = ( nErr != ERR_NONE ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ }
+ return ( nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::UpdateDispositionTool( bool bFirst, int& nErr)
+{
+ // Reset stato di errore da script
+ nErr = ERR_NONE ;
+ // Recupero la disposizione
+ Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pDisp == nullptr)
+ return false ;
+
+ // Recupero i dati
+ string sTool ; string sHead ; int nExit ; string sTcPos ;
+ pDisp->GetToolData( sTool, sHead, nExit, sTcPos) ;
+ // se esiste utensile corrente e cambierà, lo scarico
+ if ( ! m_sTool.empty() && sTool != m_sTool) {
+ // eventuale lancio script per scarico utensile
+ int nCurrErr ;
+ if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos, nCurrErr)) {
+ nErr = ( nErr != ERR_NONE ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ }
+ // carico l'utensile
+ if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
+ return false ;
+ m_sTool = sTool ;
+ m_sHead = sHead ;
+ m_nExit = nExit ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ;
+ double dTipFeed = 0 ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ;
+ m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ;
+ // aggiorno gli assi macchina
+ if ( ! UpdateAxes())
+ return false ;
+ // eventuale lancio script
+ int nCurrErr ;
+ if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst, nCurrErr)) {
+ nErr = ( nErr != ERR_NONE ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ return ( nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::UpdateAxes( void)
+{
+ ResetAxes() ;
+ // Macchina corrente
+ Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
+ if ( pMachine == nullptr)
+ return false ;
+ // Carico i nomi e i token degli assi macchina attivi
+ if ( ! pMachine->GetAllCurrAxesNames( m_AxesName) ||
+ ! pMachine->GetAllCurrAxesTokens( m_AxesToken))
+ return false ;
+ // Aggiorno flag di invertito, offset, tipo e posizione corrente degli assi macchina attivi
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ bool bInvert ;
+ m_pMachine->GetAxisInvert( m_AxesName[i], bInvert) ;
+ m_AxesInvert.push_back( bInvert) ;
+ double dOffset ;
+ m_pMachine->GetAxisOffset( m_AxesName[i], dOffset) ;
+ m_AxesOffset.push_back( dOffset) ;
+ bool bLinear ;
+ m_pMachine->GetAxisType( m_AxesName[i], bLinear) ;
+ m_AxesLinear.push_back( bLinear) ;
+ double dVal ;
+ m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
+ m_AxesVal.emplace_back( dVal) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::UpdateAxesPos( void)
+{
+ // Macchina corrente
+ Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
+ if ( pMachine == nullptr)
+ return false ;
+ // Aggiorno la posizione corrente degli assi macchina attivi
+ m_AxesVal.clear() ;
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ double dVal ;
+ m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
+ m_AxesVal.emplace_back( dVal) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ResetAxes( void)
+{
+ // pulisco dati assi
+ m_AxesName.clear() ;
+ m_AxesToken.clear() ;
+ m_AxesInvert.clear() ;
+ m_AxesLinear.clear() ;
+ m_AxesVal.clear() ;
+ m_nAxesMask = 0 ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ResetAuxAxes( void)
+{
+ // pulisco dati assi ausiliari
+ m_AuxAxesName.clear() ;
+ m_AuxAxesToken.clear() ;
+ m_AuxAxesInvert.clear() ;
+ m_AuxAxesOffset.clear() ;
+ m_AuxAxesLinear.clear() ;
+ m_AuxAxesVal.clear() ;
+ m_AuxAxesEnd.clear() ;
+ m_AuxAxesLink.clear() ;
+ // abilito assi principali
+ m_bEnabAxes = true ;
+ m_bShowAxes = true ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::FindAndManageOperationStart( bool bStart, bool bFirst, bool& bChangedTool, int& nStatus)
+{
+ // verifico parametri
+ if ( ! bStart)
+ bFirst = false ;
+ // recupero la nuova operazione
+ if ( ! bChangedTool) {
+ if ( bStart) {
+ m_nOpId = m_pMchMgr->GetFirstActiveOperation() ;
+ m_nOpInd = 0 ;
+ }
+ else
+ m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ;
+ }
+ // ciclo sulle successive operazioni
+ while ( m_nOpId != GDB_ID_NULL) {
+ // se lavorazione valida
+ Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pMch != nullptr && ! pMch->IsEmpty()) {
+ bool bOk = true ;
+ // aggiorno utensile e assi conseguenti
+ int nErr ;
+ if ( ! UpdateMachiningTool( bFirst, bChangedTool, nErr)) {
+ string sOut = "Err=" + ToString( nErr) ;
+ LOG_INFO( GetEMkLogger(), sOut.c_str())
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ if ( bChangedTool)
+ return true ;
+ ++ m_nOpInd ;
+ // imposto la lavorazione come corrente
+ m_pMchMgr->SetCurrMachining( m_nOpId) ;
+ // recupero punti di minimo e massimo ingombro
+ int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ;
+ Point3d ptMin, ptMax ;
+ m_pGeomDB->GetInfo( nClId, KEY_MMIN, ptMin) ;
+ m_pGeomDB->GetInfo( nClId, KEY_MMAX, ptMax) ;
+ DBLVECTOR vAxMin, vAxMax ;
+ m_pGeomDB->GetInfo( nClId, KEY_MAXMIN, vAxMin) ;
+ m_pGeomDB->GetInfo( nClId, KEY_MAXMAX, vAxMax) ;
+ // richiamo gestione evento inizio lavorazione
+ if ( ! OnMachiningStart( m_nOpId, m_nOpInd, ptMin, ptMax, vAxMin, vAxMax)) {
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return false ;
+ }
+ return true ;
+ }
+ // se disposizione con cambio di fase
+ Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pDisp != nullptr) {
+ // in alcuni casi la disposizione non è inizializzata
+ pDisp->Init( m_pMchMgr) ;
+ // recupero dati tavola
+ string sTable ;
+ pDisp->GetTable( sTable) ;
+ Point3d ptOri1 ;
+ pDisp->GetTableRef1( ptOri1) ;
+ // recupero la fase della disposizione
+ int nPhase = pDisp->GetPhase() ;
+ // recupero se con movimenti autonomi
+ bool bEmpty = pDisp->IsEmpty() ;
+ // recupero flag disposizione con movimenti manuali
+ bool bSomeByHand = pDisp->GetSomeByHand() ;
+ // se con movimenti autonomi
+ if ( ! bEmpty) {
+ // richiamo gestione evento appena prima di inizio disposizione
+ if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return false ;
+ }
+ // cambio fase
+ m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
+ // se previsto, aggiorno utensile e assi conseguenti
+ if ( pDisp->IsWithTool()) {
+ int nErr ;
+ if ( ! UpdateDispositionTool( bFirst, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ }
+ ++ m_nOpInd ;
+ // richiamo gestione evento inizio disposizione
+ if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return false ;
+ }
+ // se ci sono movimenti manuali, aggiorno visualizzazione e breve pausa (200 ms)
+ if ( bSomeByHand)
+ Sleep( 200) ;
+ break ;
+ }
+ // altrimenti disposizione passiva
+ else {
+ // richiamo gestione evento appena prima di inizio disposizione
+ if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, true, bSomeByHand)) {
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return false ;
+ }
+ // cambio fase
+ m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
+ ++ m_nOpInd ;
+ // richiamo gestione evento inizio e fine disposizione
+ if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, true, bSomeByHand) ||
+ ! OnDispositionEnd()) {
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return false ;
+ }
+ // se non è inizio, aggiorno visualizzazione e breve pausa (200 ms)
+ if ( nPhase != 1) {
+ ExeDraw() ;
+ Sleep( 200) ;
+ }
+ }
+ }
+ // passo alla operazione successiva
+ m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ManageOperationEnd( int& nStatus)
+{
+ bool bOk = false ;
+ // non c'è operazione in corso (solo prima disposizione senza lavorazioni)
+ if ( m_nOpId == GDB_ID_NULL)
+ bOk = true ;
+ // se altrimenti è una lavorazione
+ else if ( GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) {
+ // richiamo gestione evento fine lavorazione
+ bOk = OnMachiningEnd() ;
+ }
+ // se altrimenti è una disposizione
+ else if ( GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) {
+ // richiamo gestione evento fine disposizione
+ bOk = OnDispositionEnd() ;
+ }
+ // gestione stato
+ if ( ! bOk)
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::FindAndManagePathStart( int& nStatus)
+{
+ // se devo cercare il primo nella nuova operazione
+ if ( m_nCLPathId == GDB_ID_NULL) {
+ // aggiorno gli altri dati
+ int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ;
+ m_nCLPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
+ m_nCLPathInd = 0 ;
+ m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ }
+ // altrimenti cerco il successivo nella stessa operazione
+ else {
+ // recupero un nuovo CLpath
+ while ( m_nEntId == GDB_ID_NULL) {
+ m_nCLPathId = m_pGeomDB->GetNextGroup( m_nCLPathId) ;
+ // se non ce ne sono altri, devo passare a una nuova lavorazione
+ if ( m_nCLPathId == GDB_ID_NULL)
+ break ;
+ m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ }
+ }
+ // se trovato nuovo CLpath con entità, gestisco inizio percorso di lavoro
+ if ( m_nEntId != GDB_ID_NULL) {
+ ++ m_nCLPathInd ;
+ // recupero punti di inizio e fine percorso
+ Point3d ptStart ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ;
+ Point3d ptEnd ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_END, ptEnd) ;
+ // recupero versore estrusione associato al percorso (normale al piano di interpolazione)
+ Vector3d vtExtr ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ;
+ // recupero punti di minimo e massimo ingombro
+ Point3d ptMin, ptMax ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ;
+ // Recupero valori degli assi di minimo e massimo ingombro
+ DBLVECTOR vAxMin, vAxMax ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PAXMIN, vAxMin) ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PAXMAX, vAxMax) ;
+ // recupero massima elevazione
+ double dElev = 0 ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_ELEV, dElev) ;
+ // recupero il numero di eventi ausiliari di inizio
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS_TOT, m_nAuxSTot))
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ // reset numero eventi ausiliari di fine
+ m_nAuxEInd = 0 ;
+ m_nAuxETot = 0 ;
+ // richiamo gestione evento inizio percorso di lavoro
+ if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, m_nAuxSTot, ptStart, ptEnd, vtExtr, ptMin, ptMax, vAxMin, vAxMax, dElev)) {
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return false ;
+ }
+ }
+ // se altrimenti trovato nuovo CL path vuoto
+ else if ( m_nCLPathId != GDB_ID_NULL) {
+ // recupero il numero di eventi ausiliari di inizio
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS_TOT, m_nAuxSTot))
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ // recupero il numero di eventi ausiliari di fine
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE_TOT, m_nAuxETot))
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ManagePathEnd( int& nStatus)
+{
+ // recupero il numero di eventi ausiliari di fine
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE_TOT, m_nAuxETot))
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ // richiamo gestione evento fine percorso di lavoro
+ bool bOk = OnPathEnd( m_nAuxETot) ;
+ // gestione stato
+ if ( ! bOk)
+ nStatus = CalcStatusOnError( ERR_NONE) ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ManagePathStartAux( int& nStatus)
+{
+ // aggiorno indice corrente
+ ++ m_nAuxSInd ;
+ // recupero i dati per l'evento corrente
+ string sAS ;
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS + ToString( m_nAuxSInd), sAS)) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // richiamo gestione evento ausiliario prima di inizio percorso di lavoro
+ int nErr ;
+ if ( ! OnPathStartAux( m_nAuxSInd, sAS, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ nStatus = MCH_SIM_END_STEP ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ManagePathEndAux( int& nStatus)
+{
+ // aggiorno indice corrente
+ ++ m_nAuxEInd ;
+ // recupero i dati per l'evento corrente
+ string sAE ;
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE + ToString( m_nAuxEInd), sAE)) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // richiamo gestione evento ausiliario dopo fine percorso di lavoro
+ int nErr ;
+ if ( ! OnPathEndAux( m_nAuxEInd, sAE, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ nStatus = MCH_SIM_END_STEP ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ManageMove( int& nStatus)
+{
+ // Imposto lunghezza di movimento effettuata
+ double dCurrMove = 0 ;
+ while ( m_nEntId != GDB_ID_NULL) {
+ // eseguo movimento singolo
+ double dMove ;
+ if ( ! ManageSingleMove( nStatus, dMove))
+ return false ;
+ dCurrMove += dMove ;
+ // se modalità play e fine entità e non raggiunta la lunghezza di movimento voluto
+ if ( m_nUiStatus == MCH_UISIM_PLAY && nStatus == MCH_SIM_END_STEP && dCurrMove < 0.75 * m_dStep) {
+ // recupero una nuova entità
+ m_nEntId = m_pGeomDB->GetNext( m_nEntId) ;
+ m_dCoeff = 0 ;
+ }
+ else
+ break ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ManageSingleMove( int& nStatus, double& dMove)
+{
+ // Recupero posizione finale
+ const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
+ if ( pCamData == nullptr) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ switch ( pCamData->GetAxesStatus()) {
+ case CamData::AS_OK :
+ break ;
+ case CamData::AS_OUTSTROKE : {
+ DBLVECTOR OutAxes = pCamData->GetAxesVal() ;
+ for ( size_t i = OutAxes.size() ; i < 5 ; ++ i)
+ OutAxes.emplace_back( 0) ;
+ DBLVECTOR vAng( OutAxes.begin() + 3, OutAxes.end()) ;
+ int nStat ;
+ m_pMachine->VerifyOutstroke( OutAxes[0], OutAxes[1], OutAxes[2], vAng, true, nStat) ;
+ nStatus = MCH_SIM_OUTSTROKE ;
+ return false ; }
+ case CamData::AS_DIR_ERR :
+ nStatus = MCH_SIM_DIR_ERR ;
+ return false ;
+ default :
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ DBLVECTOR AxesEnd = pCamData->GetAxesVal() ;
+ // Tipo di movimento
+ int nMoveType = pCamData->GetMoveType() ;
+ // Se inizio di nuova entità, mascheratura movimento
+ if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO)
+ m_nAxesMask = pCamData->GetAxesMask() ;
+ // Se movimento in rapido muovo solo gli assi abilitati dal mask
+ if ( nMoveType == 0) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ if ( ( m_nAxesMask & 1 << i) == 0)
+ AxesEnd[i] = m_AxesVal[i] ;
+ }
+ }
+
+ // Se inizio di nuova entità
+ if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO) {
+ ++ m_nEntInd ;
+ const CamData* pNextCamData = GetCamData( m_pGeomDB->GetUserObj( m_pGeomDB->GetNext( m_nEntId))) ;
+ int nErr ;
+ if ( ! OnMoveStart( pCamData, pNextCamData, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ // Se movimento in rapido aggiorno quote degli assi disabilitati dal mask
+ if ( nMoveType == 0) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ if ( ( m_nAxesMask & 1 << i) == 0)
+ AxesEnd[i] = m_AxesVal[i] ;
+ }
+ }
+ }
+
+ // Posizione e direzione attuali degli utensili e riferimenti dei pezzi (per Vmill)
+ bool bOkI = true ;
+ PNTVECTOR vPtNoseI( m_VmTool.size()) ;
+ VCT3DVECTOR vVtDirI( m_VmTool.size()) ;
+ VCT3DVECTOR vVtAuxI( m_VmTool.size()) ;
+ for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i)
+ bOkI = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, vPtNoseI[i], vVtDirI[i], vVtAuxI[i]) && bOkI ;
+ vector vFrVzmI( m_VmId.size()) ;
+ for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
+ bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
+
+ // Dati per eventuale verifica di collisione
+ int nCdInd, nObjInd ;
+ bool bCollCheck = true ;
+
+ // Eseguo movimento assi principali ed eventuali ausiliari
+ if ( m_bEnabAxes) {
+ // Calcolo distanza di movimento
+ double dSqDist = 0 ;
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ // coefficiente moltiplicativo per differenziare assi lineari e rotanti
+ double dSqCoeff = ( m_AxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
+ dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ;
+ }
+ // Calcolo distanza di movimento eventuali assi ausiliari
+ double dSqDistAux = 0 ;
+ for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
+ if ( m_AuxAxesLink[i] != 0)
+ continue ;
+ // coefficiente moltiplicativo per differenziare assi lineari e rotanti
+ double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
+ dSqDistAux += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
+ }
+ // Considero il massimo delle due distanze
+ double dPrevCoeff = m_dCoeff ;
+ double dDist = sqrt( max( dSqDist, dSqDistAux)) ;
+ if ( dDist > EPS_SMALL) {
+ double dStep = min( ( nMoveType == 0 ? 2 : 1) * m_dStep, MAX_STEP) ;
+ int nStep = max( int( dDist / dStep), 1) ;
+ m_dCoeff += 1. / nStep ;
+ if ( m_dCoeff > 1)
+ m_dCoeff = 1 ;
+ }
+ else
+ m_dCoeff = 1 ;
+ dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
+
+ // Log per debug
+ if ( ExeGetDebugLevel() >= 10) {
+ string sOut = "MoveType=" + ToString( nMoveType) + " Coeff=" + ToString( m_dCoeff) ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+
+ // Eseguo movimento rapido o lineare (non arco)
+ if ( nMoveType != 2 && nMoveType != 3) {
+ // se attivo CollisionCheck approssimo movimento con più step
+ int nStep = 1 ;
+ if ( NeedCollisionCheck())
+ nStep = max( int( dMove / COLL_STEP), 1) ;
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
+ DBLVECTOR vDeltaVal( m_AxesName.size()) ;
+ // assegno posizioni finali
+ for ( int j = 0 ; j < int( m_AxesName.size()) ; ++ j) {
+ double dPrevVal ;
+ m_pMachine->GetAxisPos( m_AxesName[j], dPrevVal) ;
+ double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
+ m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
+ vDeltaVal[j] = dVal - dPrevVal ;
+ }
+ // muovo eventuali assi ausiliari
+ for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
+ double dVal = 0 ;
+ if ( m_AuxAxesLink[j] == 0) {
+ dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
+ }
+ else {
+ m_pMachine->GetAxisPos( m_AuxAxesName[j], dVal) ;
+ if ( m_AuxAxesLink[j] > 0)
+ dVal += vDeltaVal[m_AuxAxesLink[j] - 1] ;
+ else
+ dVal -= vDeltaVal[-m_AuxAxesLink[j] - 1] ;
+ }
+ m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
+ }
+ // se abilitato e non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill
+ if ( m_bEnableVm && ( nMoveType != 0 || ! NeedCollisionCheck())) {
+ for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ }
+ // eseguo eventuale collision check
+ bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ }
+ }
+ // Eseguo movimento su arco
+ else {
+ // dati dell'arco
+ Point3d ptCen = pCamData->GetAxesCen() ;
+ double dAngCen = pCamData->GetAxesAngCen() ;
+ double dRad = pCamData->GetAxesRad() ;
+ Vector3d vtN = pCamData->GetAxesNormDir() ;
+ double dDeltaN = ( Point3d( AxesEnd[0], AxesEnd[1], AxesEnd[2]) - ptCen) * vtN ;
+ double dDiffAng = ( m_dCoeff - dPrevCoeff) * dAngCen ;
+ Vector3d vtRot = Point3d( m_AxesVal[0], m_AxesVal[1], m_AxesVal[2]) - ptCen ;
+ vtRot.Rotate( vtN, dPrevCoeff * dAngCen) ;
+ // se attivi Vmill o CollisionCheck approssimo movimento con più step
+ int nStep = 1 ;
+ if ( ! m_VmId.empty() || NeedCollisionCheck()) {
+ const double MIN_LEN_STEP = 2. ;
+ const double MAX_LEN_STEP = 10. ;
+ double dLenStep = Clamp( 0.1 * m_dTDiam, MIN_LEN_STEP, MAX_LEN_STEP) ;
+ nStep = max( int( abs( dDiffAng * DEGTORAD * dRad) / dLenStep), 1) ;
+ const double ANG_STEP = 5. ;
+ if ( abs( dDiffAng) / nStep > ANG_STEP)
+ nStep = int( abs( dDiffAng) / ANG_STEP) ;
+ }
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
+ DBLVECTOR vDeltaVal( m_AxesName.size()) ;
+ // assi lineari
+ vtRot.Rotate( vtN, dDiffAng / nStep) ;
+ double dPrevVal, dVal ;
+ m_pMachine->GetAxisPos( m_AxesName[0], dPrevVal) ;
+ dVal = ptCen.x + vtRot.x + dCurrCoeff * dDeltaN * vtN.x ;
+ m_pMachine->SetAxisPos( m_AxesName[0], dVal) ;
+ vDeltaVal[0] = dVal - dPrevVal ;
+ m_pMachine->GetAxisPos( m_AxesName[1], dPrevVal) ;
+ dVal = ptCen.y + vtRot.y + dCurrCoeff * dDeltaN * vtN.y ;
+ m_pMachine->SetAxisPos( m_AxesName[1], dVal) ;
+ vDeltaVal[1] = dVal - dPrevVal ;
+ m_pMachine->GetAxisPos( m_AxesName[2], dPrevVal) ;
+ dVal = ptCen.z + vtRot.z + dCurrCoeff * dDeltaN * vtN.z ;
+ m_pMachine->SetAxisPos( m_AxesName[2], dVal) ;
+ vDeltaVal[2] = dVal - dPrevVal ;
+ // assi rotanti
+ for ( int j = 3 ; j < int( m_AxesName.size()) ; ++ j) {
+ double dPrevVal ; m_pMachine->GetAxisPos( m_AxesName[j], dPrevVal) ;
+ double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
+ m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
+ vDeltaVal[j] = dVal - dPrevVal ;
+ }
+ // eventuali assi ausiliari
+ for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
+ double dVal = 0 ;
+ if ( m_AuxAxesLink[j] == 0) {
+ dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
+ }
+ else {
+ m_pMachine->GetAxisPos( m_AuxAxesName[j], dVal) ;
+ if ( m_AuxAxesLink[j] > 0)
+ dVal += vDeltaVal[m_AuxAxesLink[j] - 1] ;
+ else
+ dVal -= vDeltaVal[-m_AuxAxesLink[j] - 1] ;
+ }
+ m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
+ }
+ // se abilitato, eseguo eventuale Vmill
+ for ( int j = 0 ; m_bEnableVm && j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ // eseguo eventuale collision check
+ bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ }
+ }
+ }
+
+ // altrimenti eseguo movimento soli eventuali assi ausiliari
+ else {
+ // Calcolo distanza di movimento
+ double dSqDist = 0 ;
+ for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
+ // coefficiente moltiplicativo per differenziare assi lineari e rotanti
+ double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
+ dSqDist += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
+ }
+ double dPrevCoeff = m_dCoeff ;
+ double dDist = sqrt( dSqDist) ;
+ if ( dDist > EPS_SMALL) {
+ double dStep = min( ( nMoveType == 0 ? 2 : 1) * m_dStep, MAX_STEP) ;
+ int nStep = max( int( dDist / dStep), 1) ;
+ m_dCoeff += 1. / nStep ;
+ if ( m_dCoeff > 1)
+ m_dCoeff = 1 ;
+ }
+ else
+ m_dCoeff = 1 ;
+ dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
+ // se attivo CollisionCheck approssimo movimento con più step
+ int nStep = 1 ;
+ if ( NeedCollisionCheck())
+ nStep = max( int( dMove / COLL_STEP), 1) ;
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
+ // muovo eventuali assi ausiliari
+ for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
+ if ( m_AuxAxesLink[j] == 0) {
+ double dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
+ m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
+ }
+ }
+ // se abilitato e non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill
+ if ( m_bEnableVm && ( nMoveType != 0 || ! NeedCollisionCheck())) {
+ for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ }
+ // eseguo eventuale collision check
+ bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ }
+ }
+
+ // Se riscontrata collisione
+ if ( ! bCollCheck) {
+ // Richiamo funzione di convalida collisione
+ int nErr ;
+ if ( ! OnCollision( nCdInd, nObjInd, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo
+ if ( m_dCoeff > COEFF_LIM) {
+ if ( m_bEnabAxes) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
+ m_AxesVal[i] = AxesEnd[i] ;
+ }
+ // richiamo gestione evento fine entità, senza gestirne eventuali errori
+ int nErr ;
+ OnMoveEnd( nErr) ;
+ }
+ return false ;
+ }
+ }
+
+ // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo
+ if ( m_dCoeff > COEFF_LIM) {
+ if ( m_bEnabAxes) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
+ m_AxesVal[i] = AxesEnd[i] ;
+ }
+ nStatus = MCH_SIM_END_STEP ;
+ // richiamo gestione evento fine entità
+ int nErr ;
+ if ( ! OnMoveEnd( nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ }
+ // Altrimenti sto muovendomi all'interno dell'entità
+ else
+ nStatus = MCH_SIM_OK ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+int
+SimulatorMP::CalcStatusOnError( int nErr)
+{
+ if ( Stopped())
+ return MCH_SIM_STOP ;
+ else if ( nErr == ERR_OUTSTROKE)
+ return MCH_SIM_OUTSTROKE ;
+ else if ( nErr == ERR_COLLISION)
+ return MCH_SIM_COLLISION ;
+ else
+ return MCH_SIM_ERR ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::GetHeadCurrPosDirAux( const std::string& sHead, int nExit, Point3d& ptH, Vector3d& vtH, Vector3d& vtA)
+{
+ int nHeadId = m_pMachine->GetHeadId( sHead) ;
+ int nExitId = m_pMachine->GetExitId( sHead, nExit) ;
+ if ( nHeadId == GDB_ID_NULL || nExitId == GDB_ID_NULL)
+ return false ;
+ Frame3d frExit ; m_pGeomDB->GetGroupGlobFrame( nExitId, frExit) ;
+ ptH = frExit.Orig() ;
+ vtH = frExit.VersZ() ;
+ vtA = V_NULL ;
+ int nDirAuxId = m_pGeomDB->GetFirstNameInGroup( nHeadId, MCH_AUX_VECT) ;
+ if ( nDirAuxId != GDB_ID_NULL) {
+ const IGeoVector3d* pGV = GetGeoVector3d( m_pGeomDB->GetGeoObj( nDirAuxId)) ;
+ if ( pGV != nullptr) {
+ Frame3d frHead ; m_pGeomDB->GetGroupGlobFrame( nHeadId, frHead) ;
+ vtA = pGV->GetVector() ;
+ vtA.ToGlob( frHead) ;
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVmAdOffs,
+ const Point3d& ptHi, const Vector3d& vtHi, const Vector3d& vtAi, const Frame3d& frVzmI,
+ const Point3d& ptHf, const Vector3d& vtHf, const Vector3d& vtAf, const Frame3d& frVzmF)
+{
+ // Recupero Zmap
+ IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( nVmId)) ;
+ if ( pVZM == nullptr) {
+ string sOut = " --> GetVolZmap (" + ToString( nVmId) +") Error <--" ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ return false ;
+ }
+ // Porto gli estremi nel riferimento opportuno dello Zmap
+ Point3d ptHiL = ptHi ; ptHiL.ToLoc( frVzmI) ;
+ Vector3d vtHiL = vtHi ; vtHiL.ToLoc( frVzmI) ;
+ Vector3d vtAiL = vtAi ; vtAiL.ToLoc( frVzmI) ;
+ Point3d ptHfL = ptHf ; ptHfL.ToLoc( frVzmF) ;
+ Vector3d vtHfL = vtHf ; vtHfL.ToLoc( frVzmF) ;
+ Vector3d vtAfL = vtAf ; vtAfL.ToLoc( frVzmF) ;
+ // Eventuali offset
+ ptHiL += dVmTdOffs * vtHiL + dVmAdOffs * vtAiL ;
+ ptHfL += dVmTdOffs * vtHfL + dVmAdOffs * vtAfL ;
+ // Log per debug
+ if ( ExeGetDebugLevel() >= 10) {
+ string sOut = "Zmap=" + ToString( nVmId) + " Tool=" + ToString( nCurrTool) +
+ " Pi=(" + ToString( ptHiL) + ") Vi=(" + ToString( vtHiL) + ") Ai=(" + ToString( vtAiL) +
+ ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ // Se utensile che non lavora di testa
+ if ( ! m_bCutOnTip) {
+ // se movimento di testa (angolo movimento verso la testa oltre 5.8deg), non eseguo asportazione
+ Vector3d vtDirM = Media( vtHiL, vtHfL) ;
+ vtDirM.Normalize() ;
+ double dAxMove = ( ptHfL - ptHiL) * vtDirM ;
+ if ( dAxMove < -EPS_SMALL) {
+ double dMove = ( ptHfL - ptHiL).Len() ;
+ if ( dAxMove < -0.1 * abs( dMove))
+ return true ;
+ }
+ }
+ // Eseguo
+ bool bOk = pVZM->MillingStep( nCurrTool, ptHiL, vtHiL, vtAiL, ptHfL, vtHfL, vtAfL) ;
+ if ( ! bOk) {
+ if ( ExeGetDebugLevel() < 10) {
+ string sOut = "Zmap=" + ToString( nVmId) + " Tool=" + ToString( nCurrTool) +
+ " Pi=(" + ToString( ptHiL) + ") Vi=(" + ToString( vtHiL) + ") Ai=(" + ToString( vtAiL) +
+ ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ LOG_DBG_INFO( GetEMkLogger(), " --> MillingStep Error <--")
+ }
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType)
+{
+ // se non ci sono oggetti da controllare o non ci sono grezzi o equivalenti, tutto bene
+ if ( ! NeedCollisionCheck())
+ return true ;
+ // ciclo sui grezzi o equivalenti
+ for ( int i = 0 ; i < int( m_CdId.size()) ; ++ i) {
+ // se modo hidden è da saltare
+ int nMode ;
+ if ( m_pGeomDB->GetCalcMode( m_CdId[i], nMode) && nMode == GDB_MD_HIDDEN)
+ continue ;
+ // verifico se è il grezzo in lavorazione
+ bool bIsRaw = ( find( m_VmId.begin(), m_VmId.end(), m_CdId[i]) != m_VmId.end()) ;
+ // recupero solido o trimesh, se altro lo salto
+ const IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
+ const ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
+ if ( pVZM == nullptr && pSTM == nullptr)
+ continue ;
+ // recupero il riferimento
+ Frame3d frCd ; m_pGeomDB->GetGlobFrame( m_CdId[i], frCd) ;
+ // ciclo sugli oggetti con cui verificare
+ for ( int j = 0 ; j < int( m_CollObj.size()) ; ++ j) {
+ // se modo hidden è da saltare
+ int nMode ;
+ if ( m_pGeomDB->GetCalcMode( m_CollObj[j].nFrameId, nMode) && nMode == GDB_MD_HIDDEN)
+ continue ;
+ // verifico se è l'utensile attivo
+ string sHead ; m_pGeomDB->GetName( m_pGeomDB->GetParentId( m_CollObj[j].nFrameId), sHead) ;
+ string sExit ; m_pGeomDB->GetName( m_CollObj[j].nFrameId, sExit) ;
+ bool bIsTool = m_CollObj[j].bToolOn ||
+ ( sHead == m_sHead && ( sExit == "_T" + ToString( m_nExit) || sExit == "_TT" + ToString( m_nExit))) ;
+ // se utensile attivo su grezzo in lavoro e non è rapido, salto
+ if ( bIsTool && bIsRaw && nMoveType != 0)
+ continue ;
+ // esecuzione controlli di collisione
+ bool bOk = true ;
+ // oggetti che richiedono frame associato (Box, Cylinder, Sphere, Cone)
+ if ( m_CollObj[j].nType != MCH_SIM_COB_POLY) {
+ // se riferimento non trovato, si salta
+ const IGeoFrame3d* pGeoFrame = GetGeoFrame3d( m_pGeomDB->GetGeoObj( m_CollObj[j].nFrameId)) ;
+ if ( pGeoFrame == nullptr)
+ continue ;
+ Frame3d frObj = pGeoFrame->GetFrame() ;
+ if ( ! m_CollObj[j].vtMove.IsSmall())
+ frObj.Translate( m_CollObj[j].vtMove.x * frObj.VersX() +
+ m_CollObj[j].vtMove.y * frObj.VersY() +
+ m_CollObj[j].vtMove.z * frObj.VersZ()) ;
+ Frame3d frParent ; m_pGeomDB->GetGlobFrame( m_CollObj[j].nFrameId, frParent) ;
+ frObj.LocToLoc( frParent, frCd) ;
+ // controlli di collisione
+ if ( m_CollObj[j].nType == MCH_SIM_COB_BOX) {
+ Vector3d vtDiag( m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3) ;
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeBox( frObj, vtDiag, m_dSafeDist) ;
+ else
+ bOk = ! CDeBoxClosedSurfTm( frObj, vtDiag, *pSTM, m_dSafeDist) ;
+ }
+ else if ( m_CollObj[j].nType == MCH_SIM_COB_CYL) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeCylinder( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_dSafeDist) ;
+ else
+ bOk = ! CDeCylClosedSurfTm( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, *pSTM, m_dSafeDist) ;
+ }
+ else if ( m_CollObj[j].nType == MCH_SIM_COB_SPHE) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeSphere( frObj.Orig(), m_CollObj[j].dPar1, m_dSafeDist) ;
+ else
+ bOk = ! CDeSpheClosedSurfTm( frObj.Orig(), m_CollObj[j].dPar1, *pSTM, m_dSafeDist) ;
+ }
+ else if ( m_CollObj[j].nType == MCH_SIM_COB_CONE) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeConeFrustum( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3, m_dSafeDist) ;
+ else
+ bOk = ! CDeConeFrustumClosedSurfTm( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3, *pSTM, m_dSafeDist) ;
+ }
+ }
+ // altrimenti poliedro
+ else {
+ SurfLocal SurfLoc( m_pGeomDB, m_CollObj[j].nFrameId, frCd) ;
+ const ISurfTriMesh* pStmLoc = GetSurfTriMesh( SurfLoc) ;
+ if ( pStmLoc != nullptr) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeSurfTm( *pStmLoc, m_dSafeDist) ;
+ else
+ bOk = ! CDeClosedSurfTmClosedSurfTm( *pStmLoc, *pSTM, m_dSafeDist) ;
+ }
+ else
+ bOk = false ;
+ }
+ // se trovata collisione
+ if ( ! bOk) {
+ nCdInd = i ;
+ nObjInd = j ;
+ return false ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+static int
+FindCollisionMarkId( const IGeomDB* pGeomDB, int nCollId)
+{
+ int nCollParId = pGeomDB->GetParentId( nCollId) ;
+ string sCollParName = "COLLISION" ;
+ pGeomDB->GetName( nCollParId, sCollParName) ;
+ if ( sCollParName != "COLLISION")
+ return nCollParId ;
+ else {
+ int nCollGprId = pGeomDB->GetParentId( nCollParId) ;
+ int nCollSolId = pGeomDB->GetFirstNameInGroup( nCollGprId, "SOLID") ;
+ if ( nCollSolId != GDB_ID_NULL)
+ return nCollSolId ;
+ else
+ return nCollGprId ;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::SetCollisionMark( int nCdInd, int nObjInd)
+{
+ if ( m_pGeomDB == nullptr)
+ return false ;
+ m_nCollMarkId.clear() ;
+ int nCdMarkId = FindCollisionMarkId( m_pGeomDB, m_CdId[nCdInd]) ;
+ m_pGeomDB->SetMark( nCdMarkId, GDB_MK_ON) ;
+ m_nCollMarkId.push_back( nCdMarkId) ;
+ int nCoMarkId = FindCollisionMarkId( m_pGeomDB, m_CollObj[nObjInd].nFrameId) ;
+ m_pGeomDB->SetMark( nCoMarkId, GDB_MK_ON_2) ;
+ m_nCollMarkId.push_back( nCoMarkId) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ResetCollisionMark( void)
+{
+ if ( m_pGeomDB == nullptr)
+ return false ;
+ for ( auto nId : m_nCollMarkId)
+ m_pGeomDB->ResetMark( nId) ;
+ m_nCollMarkId.clear() ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnInit( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_INIT))
+ return true ;
+ // chiamo la funzione di ingresso nella simulazione
+ return m_pMachine->LuaCallFunction( ON_SIMUL_INIT) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnExit( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_EXIT))
+ return true ;
+ // chiamo la funzione di uscita dalla simulazione
+ return m_pMachine->LuaCallFunction( ON_SIMUL_EXIT) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnProgramStart( bool bFirst)
+{
+ // assegno flag inizio simulazione
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIM1ST, bFirst) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_START))
+ return true ;
+ // chiamo la funzione di inizio simulazione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_START) ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnProgramEnd( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_END))
+ return true ;
+ // chiamo la funzione di fine simulazione
+ return m_pMachine->LuaCallFunction( ON_SIMUL_END) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
+ const string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand)
+{
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
+ // assegno nuovo indice di fase
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
+ // assegno nome e valore riferimento della tavola corrente
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
+ // assegno flag disposizione passiva
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
+ // assegno flag disposizione con operazioni manuali
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SBH, bSomeByHand) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_STARTING))
+ return true ;
+ // chiamo la funzione di inizio disposizione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_STARTING) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnDispositionStart( int nOpId, int nOpInd, int nPhase,
+ const string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand)
+{
+ // assegno identificativo e indice disposizione
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
+ // assegno nuovo indice di fase
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
+ // assegno nome e valore riferimento della tavola corrente
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
+ // assegno flag disposizione passiva
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
+ // assegno flag disposizione con operazioni manuali
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SBH, bSomeByHand) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_START))
+ return true ;
+ // chiamo la funzione di inizio disposizione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_START) ;
+ // recupero i dati di ritorno
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_VMILL, m_VmId) ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnDispositionEnd( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_END))
+ return true ;
+ // chiamo la funzione di fine disposizione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_END) ;
+ // recupero i dati di ritorno
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_VMILL, m_VmId) ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnToolSelect( const string& sTool, const string& sHead, int nExit, const string& sTcPos,
+ bool bFirst, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // reset oggetti per verifica collisione con grezzo
+ m_CollObj.clear() ;
+ // assegno il nome dell'utensile, la testa e l'uscita
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TOOL, sTool) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_HEAD, sHead) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXIT, nExit) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TCPOS, sTcPos))
+ return false ;
+ // assegno il token e il nome degli assi
+ bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
+ int nNumAxes = int( m_AxesName.size()) ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
+ if ( i <= nNumAxes) {
+ if ( ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisToken( i, bIsRobot), m_AxesToken[i-1]) ||
+ ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisName( i, bIsRobot), m_AxesName[i-1]))
+ return false ;
+ }
+ else {
+ if ( ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisToken( i, bIsRobot)) ||
+ ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisName( i, bIsRobot)))
+ return false ;
+ }
+ }
+ // assegno il flag di chiamata di utensile iniziale
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FIRST, bFirst))
+ return false ;
+ // reset errore
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
+ return false ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_SELECT))
+ return true ;
+ // chiamo la funzione di selezione utensile
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_SELECT) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // recupero dati per verifica collisione
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SAFEDIST, m_dSafeDist) ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // recupero i dati di ritorno per assi ausiliari
+ ResetAuxAxes() ;
+ int nNumAuxAxes = 0 ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
+ return ( bOk && nErr == ERR_NONE) ;
+ m_AuxAxesName.reserve( nNumAuxAxes) ;
+ m_AuxAxesToken.reserve( nNumAuxAxes) ;
+ m_AuxAxesInvert.reserve( nNumAuxAxes) ;
+ m_AuxAxesOffset.reserve( nNumAuxAxes) ;
+ m_AuxAxesLinear.reserve( nNumAuxAxes) ;
+ m_AuxAxesVal.reserve( nNumAuxAxes) ;
+ m_AuxAxesEnd.reserve( nNumAuxAxes) ;
+ for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
+ string sName ; string sToken ; bool bInvert ; double dOffset ; bool bLinear ; double dVal ;
+ string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
+ if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
+ m_pMachine->GetAxisToken( sName, sToken) &&
+ m_pMachine->GetAxisInvert( sName, bInvert) &&
+ m_pMachine->GetAxisOffset( sName, dOffset) &&
+ m_pMachine->GetAxisType( sName, bLinear) &&
+ m_pMachine->GetAxisPos( sName, dVal)) {
+ // se non è già negli assi principali, lo aggiungo
+ if ( find( m_AxesName.begin(), m_AxesName.end(), sName) == m_AxesName.end()) {
+ m_AuxAxesName.emplace_back( sName) ;
+ m_AuxAxesToken.emplace_back( sToken) ;
+ m_AuxAxesInvert.push_back( bInvert) ;
+ m_AuxAxesOffset.push_back( dOffset) ;
+ m_AuxAxesLinear.push_back( bLinear) ;
+ m_AuxAxesVal.emplace_back( dVal) ;
+ m_AuxAxesEnd.emplace_back( dVal) ;
+ m_AuxAxesLink.emplace_back( 0) ;
+ }
+ }
+ else {
+ bOk = false ;
+ nErr = ERR_TOOL_SEL ;
+ }
+ }
+
+ return ( bOk && nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnToolDeselect( const string& sNextTool, const string& sNextHead, int nNextExit, const string& sNextTcPos, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // assegno il prossimo utensile
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTOOL, sNextTool) ;
+ // assegno la prossima testa
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTHEAD, sNextHead) ;
+ // assegno la prossima uscita
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTEXIT, nNextExit) ;
+ // assegno l'eventuale prossima posizione nel TC
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTCPOS, sNextTcPos) ;
+ // reset errore
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_DESELECT))
+ return bOk ;
+ // chiamo la funzione di deselezione utensile
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_DESELECT) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax)
+{
+ // assegno identificativo e indice lavorazione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHID, nOpId) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHIND, nOpInd))
+ return false ;
+ // assegno punti estremi dell'ingombro della lavorazione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MMIN, ptMin) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MMAX, ptMax))
+ return false ;
+ // assegno punti estremi dell'ingombro degli assi della lavorazione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MAXMIN, vAxMin) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MAXMAX, vAxMax))
+ return false ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_START))
+ return true ;
+ // chiamo la funzione di inizio disposizione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_START) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnMachiningEnd( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_END))
+ return true ;
+ // chiamo la funzione di fine lavorazione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_END) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnPathStart( int nClPathId, int nClPathInd, int nAS, const Point3d& ptStart, const Point3d& ptEnd,
+ const Vector3d& vtExtr, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax, double dElev)
+{
+ // assegno identificativo e indice percorso di lavorazione
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHID, nClPathId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHIND, nClPathInd) ;
+ // assegno numero di dati ausiliari iniziali
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXTOT, nAS) ;
+ // assegno punti iniziale e finale e versore estrusione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_START, ptStart) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_END, ptEnd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXTR, vtExtr) ;
+ // assegno punti estremi dell'ingombro del percorso di lavorazione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMIN, ptMin) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMAX, ptMax) ;
+ // assegno punti estremi dell'ingombro degli assi della lavorazione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PAXMIN, vAxMin) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PAXMAX, vAxMax) ;
+ // assegno la massima elevazione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ELEV, dElev) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START))
+ return bOk ;
+ // chiamo la funzione di inizio percorso di lavorazione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnPathEnd( int nAE)
+{
+ // assegno numero di dati ausiliari finali
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXTOT, nAE) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END))
+ return bOk ;
+ // chiamo la funzione di fine percorso di lavorazione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnPathStartAux( int nInd, const string& sAS, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START_AUX))
+ return true ;
+ // assegno indice, valore dato ausiliario e resetto errore
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXIND, nInd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUX, sAS) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // chiamo la funzione di evento ausiliario all'inizio del percorso
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START_AUX) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnPathEndAux( int nInd, const string& sAE, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END_AUX))
+ return true ;
+ // assegno indice, valore dato ausiliario e resetto errore
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXIND, nInd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUX, sAE) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // chiamo la funzione di evento ausiliario alla fine del percorso
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END_AUX) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnMoveStart( const CamData* pCamData, const CamData* pNextCamData, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // recupero e assegno i dati
+ // dati generali e reset errore
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEID, m_nEntId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEIND, m_nEntInd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, pCamData->GetMoveType()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MASK, pCamData->GetAxesMask()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG, pCamData->GetFlag()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG2, pCamData->GetFlag2()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_INDEX, pCamData->GetIndex()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // valore degli assi all'inizio e alla fine del movimento
+ bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
+ int nNumAxes = int( m_AxesName.size()) ;
+ const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
+ if ( i <= nNumAxes) {
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisPrev( i, GLOB_VAR, bIsRobot), m_AxesVal[i-1]) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisValue( i, GLOB_VAR, bIsRobot), AxesEnd[i-1]) ;
+ }
+ else {
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisPrev( i, GLOB_VAR, bIsRobot)) ;
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisValue( i, GLOB_VAR, bIsRobot)) ;
+ }
+ }
+ // versori utensile, correzione e ausiliario alla fine del movimento
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TDIR, pCamData->GetToolDir()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_CDIR, pCamData->GetCorrDir()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ADIR, pCamData->GetBackAuxDir()) ;
+ // anticipazione di alcuni dati dell'eventuale movimento successivo dello stesso percorso
+ if ( pNextCamData != nullptr && pNextCamData->GetAxesStatus() == CamData::AS_OK) {
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVESUCC, pNextCamData->GetMoveType()) ;
+ const DBLVECTOR& AxesNext = pNextCamData->GetAxesVal() ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
+ if ( i <= nNumAxes)
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot), AxesNext[i-1]) ;
+ else
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot)) ;
+ }
+ }
+ else {
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_MOVESUCC) ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i)
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot)) ;
+ }
+ // reset abilitazione assi attivi
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_ENABAXES) ;
+ // reset numero assi ausiliari
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_AUXAXES) ;
+
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_START)) {
+ ResetAuxAxes() ;
+ return bOk ;
+ }
+ // chiamo la funzione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_START) ;
+ // con errore, esco
+ if ( ! bOk) {
+ ResetAuxAxes() ;
+ return false ;
+ }
+
+ // verifico codice di errore
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ if ( nErr != ERR_NONE)
+ return false ;
+
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+
+ // reset assi ausiliari
+ ResetAuxAxes() ;
+
+ // recupero i dati di ritorno
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_MASK, m_nAxesMask) ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ENABAXES, m_bEnabAxes))
+ m_bEnabAxes = true ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SHOWAXES, m_bShowAxes))
+ m_bShowAxes = m_bEnabAxes ;
+ int nNumAuxAxes = 0 ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
+ return true ;
+ m_AuxAxesName.reserve( nNumAuxAxes) ;
+ m_AuxAxesToken.reserve( nNumAuxAxes) ;
+ m_AuxAxesInvert.reserve( nNumAuxAxes) ;
+ m_AuxAxesOffset.reserve( nNumAuxAxes) ;
+ m_AuxAxesLinear.reserve( nNumAuxAxes) ;
+ m_AuxAxesVal.reserve( nNumAuxAxes) ;
+ m_AuxAxesEnd.reserve( nNumAuxAxes) ;
+ for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
+ string sName ; string sToken ; bool bInvert ; double dOffset ; bool bLinear ; double dVal ; double dEnd ; string sLink ;
+ string sAuxAxVal = GLOB_VAR + GVAR_AN ; ReplaceString( sAuxAxVal, "N", ToString( i)) ;
+ string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
+ string sAuxAxMaster = GLOB_VAR + GVAR_ANM ; ReplaceString( sAuxAxMaster, "N", ToString( i)) ;
+ if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
+ m_pMachine->GetAxisToken( sName, sToken) &&
+ m_pMachine->GetAxisInvert( sName, bInvert) &&
+ m_pMachine->GetAxisOffset( sName, dOffset) &&
+ m_pMachine->GetAxisType( sName, bLinear) &&
+ m_pMachine->GetAxisPos( sName, dVal)) {
+ // se assi principali abilitati e da agganciare ad asse principale
+ if ( m_bEnabAxes && m_pMachine->LuaGetGlobVar( sAuxAxMaster, sLink)) {
+ bool bNeg = ( sLink.find( '-') != string::npos) ;
+ string sMainAxis = sLink ; ReplaceString( sMainAxis, "-", "") ;
+ int nInd = 0 ;
+ for ( int i = 0 ; nInd == 0 && i < int( m_AxesName.size()) ; ++ i) {
+ if ( m_AxesName[i] == sMainAxis)
+ nInd = i + 1 ;
+ }
+ // se trovato asse principale di riferimento
+ if ( nInd > 0) {
+ m_AuxAxesName.emplace_back( sName) ;
+ m_AuxAxesToken.emplace_back( sToken) ;
+ m_AuxAxesInvert.push_back( bInvert) ;
+ m_AuxAxesOffset.push_back( dOffset) ;
+ m_AuxAxesLinear.push_back( bLinear) ;
+ m_AuxAxesVal.emplace_back( 0) ;
+ m_AuxAxesEnd.emplace_back( 0) ;
+ m_AuxAxesLink.emplace_back( ( bNeg ? -nInd : nInd)) ;
+ }
+ }
+ // se altrimenti specificato valore finale del movimento
+ else if ( m_pMachine->LuaGetGlobVar( sAuxAxVal, dEnd)) {
+ // se assi principali disabilitati o non è tra questi, lo aggiungo
+ if ( ! m_bEnabAxes || find( m_AxesName.begin(), m_AxesName.end(), sName) == m_AxesName.end()) {
+ m_AuxAxesName.emplace_back( sName) ;
+ m_AuxAxesToken.emplace_back( sToken) ;
+ m_AuxAxesInvert.push_back( bInvert) ;
+ m_AuxAxesOffset.push_back( dOffset) ;
+ m_AuxAxesLinear.push_back( bLinear) ;
+ m_AuxAxesVal.emplace_back( dVal) ;
+ m_AuxAxesEnd.emplace_back( dEnd) ;
+ m_AuxAxesLink.emplace_back( 0) ;
+ if ( ! m_pMachine->VerifyOutstroke( sName, dEnd)) {
+ nErr = ERR_OUTSTROKE ;
+ bOk = false ;
+ }
+ }
+ }
+ // altrimenti errore
+ else
+ bOk = false ;
+ }
+ else
+ bOk = false ;
+ }
+
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnMoveEnd( int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_END))
+ return true ;
+ // reset errore
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
+ return false ;
+ // chiamo la funzione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_END) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnCollision( int nCdInd, int nObjInd, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = ERR_NONE ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_COLLISION))
+ return true ;
+ // reset stato di errore
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
+ return false ;
+ // assegno identificativi grezzo e oggetto in collisione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMVMID, m_CdId[nCdInd]))
+ return false ;
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMCOBIND, m_CollObj[nObjInd].nInd))
+ return false ;
+ // chiamo la funzione
+ if ( ! m_pMachine->LuaCallFunction( ON_SIMUL_COLLISION))
+ return false ;
+ // verifico codice di errore
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // l'errore standard di collisione è stato portato da 1 a 11 per non collidere con altri tipi di errori
+ if ( nErr == 1) {
+ nErr = ERR_COLLISION ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ }
+ // evidenzio le geometrie in collisione
+ if ( nErr == ERR_COLLISION) {
+ SetCollisionMark( nCdInd, nObjInd) ;
+ ExeDraw() ;
+ }
+
+ return ( nErr == ERR_NONE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::OnResetMachine( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_RESET_MACHINE))
+ return true ;
+ // eseguo reset macchina
+ return m_pMachine->LuaCallFunction( ON_RESET_MACHINE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType, const Vector3d& vtMove, double dPar1, double dPar2, double dPar3)
+{
+ // verifiche sui parametri
+ if ( nInd <= 0 || nFrameId <= GDB_ID_NULL)
+ return false ;
+ switch ( nType) {
+ case MCH_SIM_COB_BOX :
+ if ( abs( dPar1) < EPS_SMALL || abs( dPar2) < EPS_SMALL || abs( dPar3) < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_CYL :
+ if ( dPar1 < EPS_SMALL || abs( dPar2) < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_SPHE :
+ if ( dPar1 < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_CONE :
+ if ( ( dPar1 < EPS_SMALL && dPar2 < EPS_SMALL) || dPar3 < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_POLY :
+ if ( ! ExeSurfIsClosed( nFrameId))
+ return false ;
+ break ;
+ default :
+ return false ;
+ }
+ // aggiungo al vettore
+ m_CollObj.emplace_back( nInd, bToolOn, nFrameId, nType, vtMove, dPar1, dPar2, dPar3) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::SetToolForVmill( const string& sTool, const string& sHead, int nExit, int nFlag, double dPar1, double dPar2,
+ const INTVECTOR& vVmill, bool bFirst)
+{
+ // disabilito eventuale registrazione comandi EXE (riabilitazione automatica)
+ CmdLogOff cmdLogOff ;
+ // se vVmill vuoto, esco
+ if ( vVmill.empty())
+ return true ;
+ // se utensile, testa o uscita non definiti, reset ed esco
+ if ( IsEmptyOrSpaces( sTool) || IsEmptyOrSpaces( sHead) || nExit < 1) {
+ ExeVolZmapResetTools( vVmill) ;
+ if ( bFirst)
+ m_bEnableVm = false ;
+ return false ;
+ }
+ // imposto utensile come corrente
+ string sOldTool ; m_pMchMgr->TdbGetCurrToolParam( TPA_NAME, sOldTool) ;
+ if ( sTool != sOldTool && ! m_pMchMgr->TdbSetCurrTool( sTool)) {
+ ExeVolZmapResetTools( vVmill) ;
+ if ( bFirst)
+ m_bEnableVm = false ;
+ return false ;
+ }
+ // recupero dati utensile
+ int nInd = 1 ;
+ int nType ; m_pMchMgr->TdbGetCurrToolParam( TPA_TYPE, nType) ;
+ double dLen ; m_pMchMgr->TdbGetCurrToolParam( TPA_LEN, dLen) ;
+ double dDiam ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, dDiam) ;
+ double dThick ; m_pMchMgr->TdbGetCurrToolParam( TPA_THICK, dThick) ;
+ double dCornR ; m_pMchMgr->TdbGetCurrToolParam( TPA_CORNRAD, dCornR) ;
+ double dSideAng ; m_pMchMgr->TdbGetCurrToolParam( TPA_SIDEANG, dSideAng) ;
+ double dMaxMat ; m_pMchMgr->TdbGetCurrToolParam( TPA_MAXMAT, dMaxMat) ;
+ string sNotes ; m_pMchMgr->TdbGetCurrToolParam( TPA_USERNOTES, sNotes) ;
+ bool bAdditive = ( nFlag == 1) ;
+ // ricerca dell'outline e del diametro gambo
+ int nExitId = m_pMachine->GetExitId( sHead, nExit) ;
+ int nToolId = m_pGeomDB->GetFirstNameInGroup( nExitId, sTool) ;
+ int nOutlineId = m_pGeomDB->GetFirstNameInGroup( nToolId, "Outline") ;
+ double dMaxStemDiam = dDiam ; m_pGeomDB->GetInfo( nToolId, "D_STEM", dMaxStemDiam) ;
+ // imposto profilo utensile per Vmill
+ if ( bAdditive)
+ ExeVolZmapSetAdditiveTool( vVmill, sTool, dPar1, dPar2, 0, nInd, bFirst) ;
+ else if ( nOutlineId != GDB_ID_NULL)
+ ExeVolZmapSetGenTool( vVmill, sTool, nOutlineId, nInd, bFirst) ;
+ else if ( nType == TT_MORTISE_STD)
+ ExeVolZmapSetMortiserTool( vVmill, sTool, dLen, dDiam, dThick, dCornR, nInd, bFirst) ;
+ else if ( nType == TT_CHISEL_STD)
+ ExeVolZmapSetChiselTool( vVmill, sTool, dLen, dDiam, dDiam, nInd, bFirst) ;
+ else if ( nType == TT_SAW_STD || nType == TT_SAW_FLAT)
+ ExeVolZmapSetSawTool( vVmill, sTool, dLen, dDiam, dThick, 0, dCornR, nInd, bFirst) ;
+ else if ( nType == TT_WATERJET)
+ ExeVolZmapSetStdTool( vVmill, sTool, dLen + 50, dDiam, dCornR, dMaxMat, nInd, bFirst) ;
+ else if ( abs( dSideAng) < EPS_ANG_SMALL || abs( dThick) < EPS_SMALL) {
+ ExeVolZmapSetStdTool( vVmill, sTool, dLen, dDiam, dCornR, dMaxMat, nInd, bFirst) ;
+ }
+ else {
+ bool bExtra = ( dThick > 0) ;
+ double dTipLen = abs( dThick) ;
+ double dTotLen = ( bExtra ? dLen + dTipLen : dLen) ;
+ double dDelta ;
+ if ( dSideAng > 0) {
+ if ( dCornR < EPS_SMALL)
+ dDelta = 2 * dTipLen * tan( dSideAng * DEGTORAD) ;
+ else
+ dDelta = 2 * ( dCornR * cos( dSideAng * DEGTORAD) + ( dTipLen - dCornR + dCornR * sin( dSideAng * DEGTORAD)) * tan( dSideAng * DEGTORAD)) ;
+ }
+ else
+ dDelta = 2 * tan( dSideAng * DEGTORAD) * dTipLen ;
+ double dStemDiam = ( bExtra ? dDiam : dDiam + dDelta) ;
+ double dTipDiam = ( bExtra ? dDiam - dDelta : dDiam) ;
+ ExeVolZmapSetAdvTool( vVmill, sTool, dTotLen, dStemDiam, dTipLen, dTipDiam, dCornR, dMaxMat, nInd, bFirst) ;
+ }
+ // eventuali offset per Vmill (per adattare lo ZeroT macchina con quello di Zmap)
+ double dVmTdOffs = 0 ;
+ double dVmAdOffs = 0 ;
+ if ( nType == TT_MORTISE_STD) {
+ dVmTdOffs = 0 ;
+ dVmAdOffs = 0.5 * dThick ;
+ }
+ else if ( nType == TT_SAW_STD || nType == TT_SAW_FLAT) {
+ dVmTdOffs = ( ( dLen <= dThick) ? -dLen + dThick : 0) ;
+ dVmAdOffs = 0 ;
+ }
+ // inserisco in lista utensili per virtual milling
+ if ( bFirst) {
+ m_VmTool.resize( 1) ;
+ m_VmTool[0] = VmTool( sTool, sHead, nExit, dVmTdOffs, dVmAdOffs) ;
+ }
+ else
+ m_VmTool.emplace_back( sTool, sHead, nExit, dVmTdOffs, dVmAdOffs) ;
+ // ripristino eventuale diverso utensile corrente
+ if ( sTool != sOldTool)
+ m_pMchMgr->TdbSetCurrTool( sOldTool) ;
+
+ if ( bFirst)
+ m_bEnableVm = true ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::EnableToolsForVmill( bool bEnable)
+{
+ m_bEnableVm = bEnable ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+int
+SimulatorMP::MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt)
+{
+ // Verifico ci siano assi da muovere
+ if ( vAxNaEpSt.empty())
+ return SIM_AXMV_RES_ERR ;
+ // Salvo i dati di movimento
+ m_CmdData.emplace_back( nMoveType, vAxNaEpSt) ;
+ // Log dati
+ if ( ExeGetDebugLevel() >= 4) {
+ string sOut = "Save=SimulMoveAxes," + ToString( nMoveType) ;
+ for ( int i = 0 ; i < int( vAxNaEpSt.size()) ; ++ i)
+ sOut += "," + vAxNaEpSt[i].sName +
+ "," + ToString( vAxNaEpSt[i].dEndPos, 3) +
+ "," + ToString( vAxNaEpSt[i].dStep, 3) ;
+ LOG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+
+ return SIM_AXMV_RES_OK ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::SaveCmd( int nType, int nPar, const string& sPar)
+{
+ // Salvo il comando
+ m_CmdData.emplace_back( nType, nPar, sPar) ;
+ // Log dati
+ if ( ExeGetDebugLevel() >= 4) {
+ string sOut = "Save=SimulSaveCmd," + ToString( nType) + "," + ToString( nPar) + "," + sPar ;
+ LOG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ return false ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ExecCmdData( int& nStatus)
+{
+ // Comando corrente
+ auto& CmdCurr = m_CmdData[m_nCmdInd] ;
+
+ // Stampe di debug
+ if ( ExeGetDebugLevel() >= 4) {
+ if ( CmdCurr.nType == 1) {
+ string sOut = "Cmd=SimulMoveAxes," + ToString( CmdCurr.nMoveType) ;
+ for ( int i = 0 ; i < int( CmdCurr.vAxNaEpSt.size()) ; ++ i)
+ sOut += "," + CmdCurr.vAxNaEpSt[i].sName +
+ "," + ToString( CmdCurr.vAxNaEpSt[i].dEndPos, 3) +
+ "," + ToString( CmdCurr.vAxNaEpSt[i].dStep, 3) ;
+ LOG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ else {
+ string sOut = "Cmd=SimulSaveCmd," + ToString( CmdCurr.nType) + "," + ToString( CmdCurr.nPar) + "," + CmdCurr.sPar ;
+ LOG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ }
+
+ // Eseguo movimento assi
+ if ( CmdCurr.nType == 1) {
+ // Numero assi da muovere
+ int nAxCount = int( CmdCurr.vAxNaEpSt.size()) ;
+ // Posizioni iniziali
+ DBLVECTOR vPrev( nAxCount) ;
+ for ( int i = 0 ; i < nAxCount ; ++ i) {
+ if ( ! m_pMchMgr->GetAxisPos( CmdCurr.vAxNaEpSt[i].sName, vPrev[i]))
+ return SIM_AXMV_RES_ERR ;
+ }
+ // Posizione e direzione attuali degli utensili e riferimenti dei pezzi (per Vmill)
+ bool bExecVmill = (( CmdCurr.nMoveType != 0 || ! NeedCollisionCheck()) && ! m_VmTool.empty() && ! m_VmId.empty()) ;
+ PNTVECTOR vPtNoseI ;
+ VCT3DVECTOR vVtDirI ;
+ VCT3DVECTOR vVtAuxI ;
+ vector vFrVzmI ;
+ if ( bExecVmill) {
+ vPtNoseI.resize( m_VmTool.size()) ;
+ vVtDirI.resize( m_VmTool.size()) ;
+ vVtAuxI.resize( m_VmTool.size()) ;
+ vFrVzmI.resize( m_VmId.size()) ;
+ bool bOkI = true ;
+ for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i)
+ bOkI = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, vPtNoseI[i], vVtDirI[i], vVtAuxI[i]) && bOkI ;
+ for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
+ bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
+ }
+ // Determino gli step di movimento
+ static const int STEP_FEED = -1 ;
+ static const int STEP_RAPID = -2 ;
+ static const int STEP_RAPROT = -3 ;
+ static const int STEP_COLLROT = -4 ;
+ int nStep = 1 ;
+ for ( int i = 0 ; i < nAxCount ; ++ i) {
+ double dMove = abs( CmdCurr.vAxNaEpSt[i].dEndPos - vPrev[i]) ;
+ double dStep = CmdCurr.vAxNaEpSt[i].dStep ;
+ if ( dStep < 0) {
+ if ( abs( dStep - STEP_FEED) < EPS_SMALL)
+ dStep = m_dStep ;
+ else if ( abs( dStep - STEP_RAPID) < EPS_SMALL)
+ dStep = 4 * m_dStep ;
+ else if ( abs( dStep - STEP_RAPROT) < EPS_SMALL)
+ dStep = 0.4 * m_dStep ;
+ else // STEP_COLLROT
+ dStep = min( 0.4 * m_dStep, 10.) ;
+ }
+ dStep = max( dStep, 1.) ;
+ int nAxStep = int( dMove / dStep) + 1 ;
+ nStep = max( nStep, nAxStep) ;
+ }
+ double dCoeff = 1. / nStep ;
+ m_dCmdCoeff += dCoeff * ( 1. - m_dCmdCoeff) ;
+
+ // Eseguo il movimento
+ bool bMoveOk = true ;
+ for ( int j = 0 ; j < nAxCount ; ++ j) {
+ bMoveOk = m_pMchMgr->SetAxisPos( CmdCurr.vAxNaEpSt[j].sName, ( 1 - dCoeff) * vPrev[j] + dCoeff * CmdCurr.vAxNaEpSt[j].dEndPos) && bMoveOk ;
+ }
+ // Se abilitato e richiesto, eseguo eventuale Vmill
+ if ( m_bEnableVm && bExecVmill) {
+ for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ }
+ // Verifico collisioni
+ int nCdInd, nObjInd ;
+ bool bCollCheck = ExecCollisionCheck( nCdInd, nObjInd, CmdCurr.nMoveType) ;
+ if ( ! bCollCheck) {
+ // Richiamo funzione di convalida collisione
+ int nErr ;
+ if ( ! OnCollision( nCdInd, nObjInd, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ UpdateAxesPos() ;
+ return false ;
+ }
+ }
+ // In caso di errore esco
+ if ( ! bMoveOk) {
+ nStatus = MCH_SIM_OUTSTROKE ;
+ UpdateAxesPos() ;
+ return false ;
+ }
+ UpdateAxesPos() ;
+ // Aggiorno dati interpolazione
+ if ( m_dCmdCoeff > COEFF_LIM) {
+ m_nCmdInd += 1 ;
+ m_dCmdCoeff = 0 ;
+ }
+ }
+ // eseguo impostazione stato
+ else if ( CmdCurr.nType == 2) {
+ // imposto
+ if ( ! m_pGeomDB->SetStatus( CmdCurr.nPar, ( CmdCurr.sPar == "ON" ? GDB_ST_ON : GDB_ST_OFF))) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // Aggiorno indice comandi eseguiti
+ m_nCmdInd += 1 ;
+ m_dCmdCoeff = 0 ;
+ }
+ // eseguo impostazione modo
+ else if ( CmdCurr.nType == 3) {
+ // imposto
+ if ( ! m_pGeomDB->SetMode( CmdCurr.nPar, ( CmdCurr.sPar == "STD" ? GDB_MD_STD : GDB_MD_HIDDEN))) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // Aggiorno indice comandi eseguiti
+ m_nCmdInd += 1 ;
+ m_dCmdCoeff = 0 ;
+ }
+ // eseguo chiamata funzione
+ else if ( CmdCurr.nType == 5) {
+ // chiamo la funzione
+ if ( ! m_pMachine->LuaCallFunction( CmdCurr.sPar)) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // Aggiorno indice comandi eseguiti
+ m_nCmdInd += 1 ;
+ m_dCmdCoeff = 0 ;
+ }
+ // altrimenti errore
+ else {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorMP::ExecAllCmdData( int& nStatus)
+{
+ // Eseguo tutti i comandi pendenti
+ while ( m_nCmdInd < int( m_CmdData.size())) {
+ if ( ! ExecCmdData( nStatus))
+ return false ;
+ ExeDraw() ;
+ }
+ m_CmdData.clear() ;
+ m_nCmdInd = 0 ;
+ m_dCmdCoeff = 0 ;
+
+ return true ;
+}
diff --git a/SimulatorMP.h b/SimulatorMP.h
new file mode 100644
index 0000000..b768ddd
--- /dev/null
+++ b/SimulatorMP.h
@@ -0,0 +1,209 @@
+//----------------------------------------------------------------------------
+// EgalTech 2024-2024
+//----------------------------------------------------------------------------
+// File : SimulatorMP.h Data : 01.09.24 Versione : 2.6i1
+// Contenuto : Dichiarazione della classe SimulatorMP.
+// Simulatore multi-processo.
+//
+//
+// Modifiche : 01.09.24 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "Simulator.h"
+#include "CamData.h"
+
+class IGeomDB ;
+class Machine ;
+class PerformanceCounter ;
+
+//----------------------------------------------------------------------------
+ISimulator* CreateSimulatorMP( void) ;
+
+//----------------------------------------------------------------------------
+class SimulatorMP : public ISimulator
+{
+ public : // ISimulator
+ ~SimulatorMP( void) override ;
+ bool Init( MachMgr* pMchMgr) override ;
+ bool Start( bool bFirst) override ;
+ bool Move( int& nStatus) override ;
+ bool GoHome( void) override ;
+ bool SetStep( double dStep) override ;
+ bool SetUiStatus( int nUiStatus) override ;
+ bool GetAxisInfoPos( int nI, std::string& sName, std::string& sToken, bool& bLinear, double& dVal) const override ;
+ bool GetToolInfo( std::string& sName, double& dSpeed) const override ;
+ bool GetOperationInfo( std::string& sName, int& nType) const override ;
+ bool GetMoveInfo( int& nGmove, double& dFeed) const override ;
+ bool AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType,
+ const Vector3d& vtMove, double dPar1, double dPar2, double dPar3) override ;
+ bool ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType) override ;
+ bool OnCollision( int nCdInd, int nObjInd, int& nErr) override ;
+ bool SetToolForVmill( const std::string& sTool, const std::string& sHead, int nExit, int nFlag,
+ double dPar1, double dPar2, const INTVECTOR& vVmill, bool bFirst) override ;
+ bool EnableToolsForVmill( bool bEnable) override ;
+ int MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt) override ;
+ bool SaveCmd( int nType, int nPar, const std::string& sPar) override ;
+
+ public :
+ SimulatorMP( void) ;
+
+ private :
+ bool UpdateMachiningTool( bool bFirst, bool& bDeselect, int& nErr) ;
+ bool UpdateDispositionTool( bool bFirst, int& nErr) ;
+ bool UpdateAxes( void) ;
+ bool UpdateAxesPos( void) ;
+ bool ResetInterpolation( void) ;
+ bool ResetAxes( void) ;
+ bool ResetAuxAxes( void) ;
+
+ private :
+ bool VerifySetup( void) ;
+ bool FindAndManageOperationStart( bool bStart, bool bFirst, bool& bChangedTool, int& nStatus) ;
+ bool ManageOperationEnd( int& nStatus) ;
+ bool FindAndManagePathStart( int& nStatus) ;
+ bool ManagePathEnd( int& nStatus) ;
+ bool ManagePathStartAux( int& nStatus) ;
+ bool ManagePathEndAux( int& nStatus) ;
+ bool ManageMove( int& nStatus) ;
+ bool ManageSingleMove( int& nStatus, double& dMove) ;
+ int CalcStatusOnError( int nErr) ;
+ bool GetHeadCurrPosDirAux( const std::string& sHead, int nExit, Point3d& ptH, Vector3d& vtH, Vector3d& vtA) ;
+ bool ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVmAdOffs,
+ const Point3d& ptHi, const Vector3d& vtHi, const Vector3d& vtAi, const Frame3d& frVzmI,
+ const Point3d& ptHf, const Vector3d& vtHf, const Vector3d& vtAf, const Frame3d& frVzmF) ;
+ bool NeedCollisionCheck( void) const
+ { return ( ! m_CollObj.empty() && ! m_CdId.empty()) ; }
+ bool Stopped( void)
+ { return ( m_nUiStatus == MCH_UISIM_STOP) ; }
+ bool SetCollisionMark( int nCdInd, int nObjInd) ;
+ bool ResetCollisionMark( void) ;
+ bool OnInit( void) ;
+ bool OnExit( void) ;
+ bool OnProgramStart( bool bFirst) ;
+ bool OnProgramEnd( void) ;
+ bool OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
+ const std::string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand) ;
+ bool OnDispositionStart( int nOpId, int nOpInd, int nPhase,
+ const std::string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand) ;
+ bool OnDispositionEnd( void) ;
+ bool OnToolSelect( const std::string& sTool, const std::string& sHead, int nExit, const std::string& sTcPos, bool bFirst, int& nErr) ;
+ bool OnToolDeselect( const std::string& sNextTool, const std::string& sNextHead, int nNextExit, const std::string& sNextTcPos, int& nErr) ;
+ bool OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax) ;
+ bool OnMachiningEnd( void) ;
+ bool OnPathStartAux( int nInd, const std::string& sAS, int& nErr) ;
+ bool OnPathEndAux( int nInd, const std::string& sAE, int& nErr) ;
+ bool OnPathStart( int nClPathId, int nClPathInd, int nAS, const Point3d& ptStart, const Point3d& ptEnd,
+ const Vector3d& vtExtr, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax, double dElev) ;
+ bool OnPathEnd( int nAE) ;
+ bool OnMoveStart( const CamData* pCamData, const CamData* pNextCamData, int& nErr) ;
+ bool OnMoveEnd( int& nErr) ;
+ bool OnResetMachine( void) ;
+ bool ExecCmdData( int& nStatus) ;
+ bool ExecAllCmdData( int& nStatus) ;
+
+ private :
+ struct CollObj {
+ int nInd ;
+ bool bToolOn ;
+ int nFrameId ;
+ int nType ;
+ Vector3d vtMove ;
+ double dPar1 ;
+ double dPar2 ;
+ double dPar3 ;
+ CollObj( void) : nInd( 0), bToolOn( false), nFrameId( -1), nType( 0), vtMove(), dPar1( 0), dPar2( 0), dPar3( 0) {}
+ CollObj( int nI, bool bTOn, int nF, int nT, const Vector3d& vtM, double dP1, double dP2, double dP3)
+ : nInd( nI), bToolOn( bTOn), nFrameId( nF), nType( nT), vtMove( vtM), dPar1( dP1), dPar2( dP2), dPar3( dP3) {}
+ } ;
+ typedef std::vector COBVECTOR ;
+ struct VmTool
+ {
+ std::string sName ;
+ std::string sHead ;
+ int nExit ;
+ double dTdOffs ;
+ double dAdOffs ;
+ VmTool( void) : nExit( 0), dTdOffs( 0), dAdOffs( 0) {}
+ VmTool( std::string sN, std::string sH, int nE, double dT, double dA)
+ : sName( sN), sHead( sH), nExit( nE), dTdOffs( dT), dAdOffs( dA) {}
+ } ;
+ typedef std::vector VMTVECTOR ;
+ enum { SIS_CREATED = 0,
+ SIS_INITIALIZED = 1,
+ SIS_READYTOSTART = 2,
+ SIS_READYTORUN = 3} ;
+
+ private :
+ struct CmdData {
+ int nType ;
+ int nMoveType ;
+ SAMVECTOR vAxNaEpSt ;
+ int nPar ;
+ std::string sPar ;
+ CmdData( void) : nType(0) {}
+ CmdData( int nM, const SAMVECTOR& vAx)
+ : nType( 1), nMoveType( nM), vAxNaEpSt( vAx) {}
+ CmdData( int nT, int nP, const std::string& sP)
+ : nType( nT), nPar( nP), sPar( sP) {}
+ } ;
+ typedef std::vector CMDVECTOR ;
+
+ private :
+ MachMgr* m_pMchMgr ; // puntatore al gestore di tutte le lavorazioni
+ IGeomDB* m_pGeomDB ; // puntatore al DB geometrico
+ Machine* m_pMachine ; // puntatore alla macchina
+ PerformanceCounter* m_pPerfCnt ; // timer per calcolo FPS
+ int m_nStatus ; // stato interno del simulatore (creato, inizializzato, pronto al movimento)
+ double m_dStep ; // lunghezza di riferimento per la velocità di simulazione
+ int m_nUiStatus ; // stato simulazione a livello utente
+ int m_nOpId ; // identificativo della operazione (lavoraz.) corrente
+ int m_nOpInd ; // contatore della operazione (lavoraz.) corrente
+ int m_nCLPathId ; // identificativo del percorso di lavoro corrente
+ int m_nCLPathInd ; // contatore del percorso di lavoro corrente nell'operazione
+ int m_nEntId ; // identificativo dell'entità corrente
+ int m_nEntInd ; // contatore dell'entità corrente nel percorso di lavoro
+ double m_dCoeff ; // coefficiente di esecuzione del movimento corrente (0...1)
+ bool m_bChangedTool ; // flag di utensile appena scaricato
+ int m_nAuxSTot ; // numero totale movimenti ausiliari di inizio percorso
+ int m_nAuxSInd ; // indice del movimento ausiliario di inizio percorso corrente
+ int m_nAuxETot ; // numero totale movimenti ausiliari di fine percorso
+ int m_nAuxEInd ; // indice del movimento ausiliario di fine percorso corrente
+ std::string m_sTool ; // nome dell'utensile corrente
+ std::string m_sHead ; // nome della testa corrente
+ int m_nExit ; // indice dell'uscita corrente
+ double m_dTDiam ; // diametro dell'utensile corrente
+ bool m_bCutOnTip ; // flag capacità di lavorare di testa dell'utensile corrente
+ bool m_bEnableVm ; // flag abilitazione Virtual Milling
+ INTVECTOR m_VmId ; // vettore identificativi Zmap per Virtual Milling
+ INTVECTOR m_CdId ; // vettore identificativi Zmap per Collision Detection
+ VMTVECTOR m_VmTool ; // vettore utensili attivi per virtual milling
+ COBVECTOR m_CollObj ; // vettore oggetti da testare per collisione con grezzo
+ double m_dSafeDist ; // distanza di sicurezza per verifica collisioni
+ INTVECTOR m_nCollMarkId ; // elenco oggetti marcati per visualizzare meglio la collisione rilevata
+ int m_nAxesMask ; // maschera a bit di abilitazione movimento assi (solo se rapido)
+ bool m_bEnabAxes ; // flag abilitazione movimento assi attivi
+ bool m_bShowAxes ; // flag visualizzazione assi attivi
+ STRVECTOR m_AxesName ; // nomi degli assi macchina attivi
+ STRVECTOR m_AxesToken ; // token degli assi macchina attivi
+ BOOLVECTOR m_AxesInvert ; // flag di asse con verso invertito degli assi macchina attivi
+ DBLVECTOR m_AxesOffset ; // valore di offset delgli assi macchina ttivi
+ BOOLVECTOR m_AxesLinear ; // flag di lineare degli assi macchina attivi
+ DBLVECTOR m_AxesVal ; // valori degli assi macchina all'inizio del movimento corrente
+ STRVECTOR m_AuxAxesName ; // nomi degli assi macchina ausiliari abilitati
+ STRVECTOR m_AuxAxesToken ; // token degli assi macchina ausiliari abilitati
+ BOOLVECTOR m_AuxAxesInvert ; // flag di asse con verso invertito degli assi macchina ausiliari abilitati
+ DBLVECTOR m_AuxAxesOffset ; // valore di offset degli assi macchina ausiliari abilitati
+ BOOLVECTOR m_AuxAxesLinear ; // flag di lineare degli assi macchina ausiliari abilitati
+ DBLVECTOR m_AuxAxesVal ; // valori degli assi macchina ausiliari all'inizio del movimento corrente
+ DBLVECTOR m_AuxAxesEnd ; // valori degli assi macchina ausiliari alla fine del movimento corrente
+ INTVECTOR m_AuxAxesLink ; // indice + 1 asse principale di aggancio (negativo valore opposto, 0 nessuno)
+ CMDVECTOR m_CmdData ; // vettore comandi in attesa di esecuzione
+ int m_nCmdInd ; // indice prossimo comando da eseguire
+ double m_dCmdCoeff ; // coefficiente di movimento nel comando
+} ;
diff --git a/Simulator.cpp b/SimulatorSP.cpp
similarity index 94%
rename from Simulator.cpp
rename to SimulatorSP.cpp
index 1fca5c7..39c7ea3 100644
--- a/Simulator.cpp
+++ b/SimulatorSP.cpp
@@ -1,2452 +1,2460 @@
-//----------------------------------------------------------------------------
-// EgalTech 2015-2016
-//----------------------------------------------------------------------------
-// File : Simulator.cpp Data : 04.01.17 Versione : 1.6x5
-// Contenuto : Implementazione della classe Simulator.
-//
-//
-//
-// Modifiche : 19.10.15 DS Creazione modulo.
-// 26.02.16 DS Aggiunta gestione archi.
-// 04.01.17 DS Riorganizzazione codice.
-//
-//----------------------------------------------------------------------------
-
-//--------------------------- Include ----------------------------------------
-#include "stdafx.h"
-#include "Simulator.h"
-#include "MachMgr.h"
-#include "Disposition.h"
-#include "Machining.h"
-#include "MachiningConst.h"
-#include "OutputConst.h"
-#include "DllMain.h"
-#include "/EgtDev/Include/EGkCDeBoxClosedSurfTm.h"
-#include "/EgtDev/Include/EGkCDeCylClosedSurfTm.h"
-#include "/EgtDev/Include/EGkCDeSpheClosedSurfTm.h"
-#include "/EgtDev/Include/EGkCDeConeFrustumClosedSurfTm.h"
-#include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h"
-#include "/EgtDev/Include/EGkVolZmap.h"
-#include "/EgtDev/Include/EGkGeoVector3d.h"
-#include "/EgtDev/Include/EGkStringUtils3d.h"
-#include "/EgtDev/Include/EGkSurfLocal.h"
-#include "/EgtDev/Include/EXeCmdLogOff.h"
-#include "/EgtDev/Include/EXeConst.h"
-#include "/EgtDev/Include/EMkToolConst.h"
-#include "/EgtDev/Include/EMkOperationConst.h"
-#include "/EgtDev/Include/EgtPerfCounter.h"
-#include "/EgtDev/Include/EgtNumUtils.h"
-
-using namespace std ;
-
-//------------------------------ Errors --------------------------------------
-// 1001 = "Error with setup : xxx"
-
-//----------------------------------------------------------------------------
-static const double MIN_STEP = 1.0 ;
-static const double MAX_STEP = 500.0 ;
-static const double MID_STEP = 50.0 ;
-static const double COLL_STEP = 10. ;
-static const double SQ_COEFF_ROT_MOVE = 100. ;
-static const double COEFF_LIM = 0.999 ;
-static const double SAFEDIST_STD = 5.0 ;
-static const int ERR_OUTSTROKE = 1 ;
-static const int ERR_COLLISION = 11 ;
-static const int ERR_TOOL_SEL = 21 ;
-
-//----------------------------------------------------------------------------
-Simulator::Simulator( void)
-{
- m_pMchMgr = nullptr ;
- m_pGeomDB = nullptr ;
- m_pMachine = nullptr ;
- m_pPerfCnt = nullptr ;
- m_nStatus = SIS_CREATED ;
- m_dStep = MID_STEP ;
- m_nUiStatus = MCH_UISIM_NULL ;
- m_nOpId = GDB_ID_NULL ;
- m_nOpInd = 0 ;
- m_nCLPathId = GDB_ID_NULL ;
- m_nCLPathInd = 0 ;
- m_nEntId = GDB_ID_NULL ;
- m_nEntInd = 0 ;
- m_dCoeff = 0 ;
- m_nAuxSTot = 0 ;
- m_nAuxSInd = 0 ;
- m_nAuxETot = 0 ;
- m_nAuxEInd = 0 ;
- m_nExit = 0 ;
- m_dTDiam = 0 ;
- m_bCutOnTip = false ;
- m_bEnableVm = false ;
- m_dSafeDist = SAFEDIST_STD ;
- m_nAxesMask = 0 ;
- m_bEnabAxes = true ;
- m_bShowAxes = true ;
- m_AxesName.reserve( 8) ;
- m_AxesToken.reserve( 8) ;
- m_AxesLinear.reserve( 8) ;
- m_AxesVal.reserve( 8) ;
-}
-
-//----------------------------------------------------------------------------
-Simulator::~Simulator( void)
-{
- // porto la macchina in posizione home
- GoHome() ;
- // gestione evento uscita dal simulatore
- OnExit() ;
- // rimuovo tavola variabili globali
- m_pMachine->LuaResetGlobVar( GLOB_VAR) ;
- // rimuovo performance counter
- if ( m_pPerfCnt != nullptr) {
- delete m_pPerfCnt ;
- m_pPerfCnt = nullptr ;
- }
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::Init( MachMgr* pMchMgr)
-{
- // verifico ambiente
- if ( pMchMgr == nullptr || pMchMgr->GetContextId() == 0 ||
- pMchMgr->GetGeomDB() == nullptr || pMchMgr->GetCurrMachine() == nullptr)
- return false ;
- m_pMchMgr = pMchMgr ;
- m_pGeomDB = m_pMchMgr->GetGeomDB() ;
- m_pMachine = m_pMchMgr->GetCurrMachine() ;
- m_pPerfCnt = new PerformanceCounter ;
- m_nStatus = SIS_INITIALIZED ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::Start( bool bFirst)
-{
- // Verifico ci sia una macchinata corrente
- if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr || m_pMachine == nullptr ||
- m_pMchMgr->GetCurrMachGroup() == GDB_ID_NULL)
- return false ;
- m_pMchMgr->ResetLastError() ;
- m_pMchMgr->ResetWarnings() ;
-
- bool bOk = true ;
-
- // Se appena entrati in simulazione
- if ( m_nStatus == SIS_INITIALIZED) {
- // Forzo aggiornamento attrezzaggio della macchinata
- if ( ! m_pMchMgr->UpdateCurrSetup())
- bOk = false ;
- // Verifico attrezzaggio
- if ( ! VerifySetup())
- bOk = false ;
- }
-
- // Reset utensile, interpolazione e assi correnti
- m_sTool.clear() ;
- m_sHead.clear() ;
- m_nExit = 0 ;
- m_dTDiam = 0 ;
- m_bCutOnTip = false ;
- ResetInterpolation() ;
- ResetAxes() ;
- ResetAuxAxes() ;
-
- // porto la macchina in home
- if ( ! GoHome())
- bOk = false ;
-
- // Verifico la disposizione iniziale della macchinata
- m_nOpId = m_pMchMgr->GetFirstActiveOperation() ;
- m_nOpInd = 1 ;
- if ( m_pMchMgr->GetOperationType( m_nOpId) != OPER_DISP)
- bOk = false ;
-
- // Definisco tabella variabili globali
- if ( ! m_pMachine->LuaCreateGlobTable( GLOB_VAR))
- bOk = false ;
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_INCHES, ! ExeUiUnitsAreMM()) ;
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep) ;
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_VER, GetEMkVer()) ;
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MACHNAME, m_pMachine->GetMachineName()) ;
-
- // Se appena entrati in simulazione
- if ( m_nStatus == SIS_INITIALIZED) {
- if ( ! OnInit())
- bOk = false ;
- m_nStatus = SIS_READYTOSTART ;
- }
-
- // Richiamo funzione per evento avvio simulazione
- if ( ! OnProgramStart( bFirst))
- bOk = false ;
-
- // Arrivo alla preparazione per la prima lavorazione
- int nStatus ;
- if ( ! FindAndManageOperationStart( true, bFirst, nStatus) && nStatus != MCH_SIM_STOP)
- bOk = false ;
- // se sono ancora su disposizione
- if ( m_pMchMgr->GetOperationType( m_nOpId) == OPER_DISP) {
- // ricerca e gestione inizio percorso di lavoro
- if ( ! FindAndManagePathStart( nStatus))
- return false ;
- // eventuali comandi ausiliari di inizio percorso
- while ( m_nAuxSInd < m_nAuxSTot) {
- if ( ! ManagePathStartAux( nStatus))
- return false ;
- }
- // aggiornamento assi per eventuali teste caricate
- UpdateAxes() ;
- }
-
- // Reset timer
- if ( m_pPerfCnt != nullptr)
- m_pPerfCnt->Start() ;
-
- // Imposto lo stato interno
- m_nStatus = ( bOk ? SIS_READYTORUN : SIS_READYTOSTART) ;
-
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::VerifySetup( void)
-{
- // se attrezzaggio non definito, nulla da verificare
- if ( ! m_pMchMgr->GetCurrSetupMgr().Exists())
- return true ;
-
- // lancio la verifica
- STRVECTOR vsErr ;
- if ( m_pMchMgr->VerifyCurrSetup( vsErr))
- return true ;
-
- // gestisco errore
- string sErr = "Error with setup :" ;
- for ( const auto& sTmp : vsErr)
- sErr += " " + sTmp ;
- m_pMchMgr->SetLastError( 1001, sErr) ;
- return false ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ResetInterpolation( void)
-{
- m_nOpId = GDB_ID_NULL ;
- m_nOpInd = 0 ;
- m_nCLPathId = GDB_ID_NULL ;
- m_nCLPathInd = 0 ;
- m_nEntId = GDB_ID_NULL ;
- m_nEntInd = 0 ;
- m_dCoeff = 0 ;
- m_nAuxSTot = 0 ;
- m_nAuxSInd = 0 ;
- m_nAuxETot = 0 ;
- m_nAuxEInd = 0 ;
- m_VmId.clear() ;
- m_CdId.clear() ;
- m_VmTool.clear() ;
- m_CollObj.clear() ;
- m_dSafeDist = SAFEDIST_STD ;
- m_nAxesMask = 0 ;
- m_bEnabAxes = true ;
- m_bShowAxes = true ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::Move( int& nStatus)
-{
- // Verifiche
- if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr || m_nStatus != SIS_READYTORUN) {
- nStatus = MCH_SIM_ERR ;
- return false ;
- }
-
- // Recupero tempo impiegato (calcolo + visualizzazione precedenti)
- if ( m_pPerfCnt != nullptr && ExeGetDebugLevel() >= 5) {
- double dElapsed = m_pPerfCnt->Stop() ;
- string sOut = "Elapsed=" + ToString( dElapsed, 1) ;
- LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
- m_pPerfCnt->Start() ;
- }
-
- // reset visualizzazione collisioni
- ResetCollisionMark() ;
-
- // Se arrivato alla fine dell'interpolazione
- if ( m_dCoeff > COEFF_LIM) {
- // recupero una nuova entità
- m_nEntId = m_pGeomDB->GetNext( m_nEntId) ;
- m_dCoeff = 0 ;
- }
-
- // Se appena arrivato alla fine di un percorso di lavoro (verifico anche completamento dei comandi aux di start per path vuote)
- if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd == 0 && m_nCLPathInd > 0 && m_nAuxSInd >= m_nAuxSTot) {
- // gestione fine percorso di lavoro
- if ( ! ManagePathEnd( nStatus))
- return false ;
- }
-
- // Se alla fine del percorso dopo esecuzione azioni ausiliarie (verifico anche completamento dei comandi aux di start per path vuote)
- if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd >= m_nAuxETot && m_nAuxSInd >= m_nAuxSTot) {
- // ricerca e gestione inizio percorso di lavoro
- if ( ! FindAndManagePathStart( nStatus))
- return false ;
- }
-
- // Se arrivato alla fine di una operazione
- if ( m_nCLPathId == GDB_ID_NULL) {
- // gestione fine operazione
- if ( ! ManageOperationEnd( nStatus))
- return false ;
- // ricerca e gestione nuova operazione
- if ( ! FindAndManageOperationStart( false, false, nStatus))
- return false ;
- // se non ce ne sono altre, sono alla fine
- if ( m_nOpId == GDB_ID_NULL) {
- OnProgramEnd() ;
- nStatus = MCH_SIM_END ;
- return false ;
- }
- // ricerca e gestione inizio percorso di lavoro
- if ( ! FindAndManagePathStart( nStatus))
- return false ;
- }
-
- // Se sto eseguendo i movimenti ausiliari di inizio percorso
- if ( m_nAuxSInd < m_nAuxSTot)
- return ManagePathStartAux( nStatus) ;
-
- // Se sto eseguendo i movimenti ausiliari di fine percorso
- if ( m_nAuxEInd < m_nAuxETot)
- return ManagePathEndAux( nStatus) ;
-
- // Gestione movimento assi
- return ManageMove( nStatus) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::GetAxisInfoPos( int nI, string& sName, string& sToken, bool& bLinear, double& dVal) const
-{
- // Verifiche
- if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
- return false ;
- // numero assi di calcolo e ausiliari
- int nAxisCount = ( m_bShowAxes ? int( m_AxesName.size()) : 0) ;
- int nAuxAxisCount = int( m_AuxAxesName.size()) ;
- // recupero i dati dell'asse
- if ( nI < 0 || nI >= nAxisCount + nAuxAxisCount)
- return false ;
- // se asse principale
- if ( nI < nAxisCount) {
- sName = m_AxesName[nI] ;
- sToken = m_AxesToken[nI] ;
- bLinear = m_AxesLinear[nI] ;
- }
- // altrimenti asse ausiliario
- else {
- sName = m_AuxAxesName[ nI - nAxisCount] ;
- sToken = m_AuxAxesToken[ nI - nAxisCount] ;
- bLinear = m_AuxAxesLinear[ nI - nAxisCount] ;
- }
- // recupero la posizione
- if ( ! m_pMchMgr->GetAxisPos( sName, dVal))
- return false ;
- // verifico se da invertire o offsettare
- if ( nI < nAxisCount) {
- if ( m_AxesInvert[nI])
- dVal = - dVal ;
- dVal += m_AxesOffset[nI] ;
- }
- else {
- if ( m_AuxAxesInvert[nI - nAxisCount])
- dVal = - dVal ;
- dVal += m_AxesOffset[nI - nAxisCount] ;
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::GetToolInfo( string& sName, double& dSpeed) const
-{
- // Inizializzo i parametri di ritorno
- sName.clear() ;
- dSpeed = 0 ;
- // Verifiche
- if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
- return false ;
- // Assegno il nome dell'utensile
- sName = m_sTool ;
- if ( sName.empty())
- return true ;
- // Recupero speed
- const Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
- return ( pMch != nullptr && pMch->GetParam( MPA_SPEED, dSpeed)) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::GetOperationInfo( string& sName, int& nType) const
-{
- // Inizializzo i parametri di ritorno
- sName.clear() ;
- nType = OPER_NULL ;
- // Verifiche
- if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
- return false ;
- // Recupero il tipo
- Operation* pOpe = GetOperation( m_pGeomDB->GetUserObj( m_nOpId)) ;
- if ( pOpe == nullptr)
- return false ;
- nType = pOpe->GetType() ;
- // Recupero il nome
- return m_pGeomDB->GetName( m_nOpId, sName) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::GetMoveInfo( int& nGmove, double& dFeed) const
-{
- // Verifiche
- if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
- return false ;
- // Recupero il movimento corrente
- const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
- if ( pCamData == nullptr)
- return false ;
- // Assegno feed
- dFeed = pCamData->GetFeed() ;
- // Assegno tipo di movimento
- nGmove = pCamData->GetMoveType() ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::SetStep( double dStep)
-{
- m_dStep = Clamp( dStep, MIN_STEP, MAX_STEP) ;
- // imposto step per movimenti gestiti nelle macro di simulazione ( con ripristino macchina Lua originale)
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep) ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::SetUiStatus( int nUiStatus)
-{
- m_nUiStatus = nUiStatus ;
- // imposto stato utente del simulatore per movimenti gestiti nelle macro di simulazione ( con ripristino macchina Lua originale)
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMUISTAT, m_nUiStatus) ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::GoHome( void)
-{
- // controllo validità stato
- if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr)
- return false ;
- // reset visualizzazione collisioni
- ResetCollisionMark() ;
- // reset stato macchina
- OnResetMachine() ;
- // porto la macchina in home
- m_pMchMgr->ResetAllAxesPos() ;
- // assegno valori home degli assi macchina attivi
- return m_pMchMgr->GetAllCurrAxesHomePos( m_AxesVal) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::UpdateTool( bool bFirst, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // Recupero l'utensile della lavorazione corrente
- Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
- if ( pMch != nullptr) {
- // recupero nome e dati nuovo utensile
- string sTuuid, sTool ;
- if ( ! pMch->GetParam( MPA_TUUID, sTuuid) ||
- ! m_pMchMgr->TdbGetToolFromUUID( sTuuid, sTool))
- return false ;
- string sTcPos ; string sHead ; int nExit ;
- if ( ! m_pMchMgr->GetCurrSetupMgr().GetToolData( sTool, sTcPos, sHead, nExit)) {
- if ( m_pMchMgr->TdbSetCurrTool( sTool)) {
- m_pMchMgr->TdbGetCurrToolParam( TPA_TCPOS, sTcPos) ;
- m_pMchMgr->TdbGetCurrToolParam( TPA_HEAD, sHead) ;
- m_pMchMgr->TdbGetCurrToolParam( TPA_EXIT, nExit) ;
- }
- // ripristino l'utensile corrente
- m_pMchMgr->TdbSetCurrTool( m_sTool) ;
- }
- // verifico se cambierà
- bool bDiffTool = ( sTool != m_sTool) ;
- // se cambierà ed esiste il corrente, lo scarico
- if ( bDiffTool && ! m_sTool.empty()) {
- // eventuale lancio script per scarico utensile
- int nCurrErr ;
- if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos, nCurrErr)) {
- nErr = ( nErr != 0 ? nErr : nCurrErr) ;
- if ( nCurrErr != ERR_COLLISION)
- return false ;
- }
- }
- // se prima volta, pulisco la testa
- if ( bFirst)
- m_pMchMgr->ResetHeadSet( sHead) ;
- // recupero la lavorazione corrente e imposto la nuova
- int nCurrMchId = m_pMchMgr->GetCurrMachining() ;
- m_pMchMgr->SetCurrMachining( m_nOpId) ;
- // carico l'utensile (e lo rendo corrente)
- if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
- return false ;
- m_sTool = sTool ;
- m_sHead = sHead ;
- m_nExit = nExit ;
- m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ;
- double dTipFeed = 0 ;
- m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ;
- m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ;
- // ripristino la lavorazione corrente
- m_pMchMgr->SetCurrMachining( nCurrMchId) ;
- // aggiorno gli assi macchina
- if ( ! UpdateAxes())
- return false ;
- // se cambiato oppure prima volta, lancio lo script di selezione
- if ( bDiffTool || bFirst) {
- int nCurrErr ;
- if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst, nCurrErr)) {
- nErr = ( nErr != 0 ? nErr : nCurrErr) ;
- if ( nCurrErr != ERR_COLLISION)
- return false ;
- }
- }
- return ( nErr == 0) ;
- }
- // Provo con una disposizione
- Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
- if ( pDisp != nullptr) {
- // recupero i dati
- string sTool ; string sHead ; int nExit ; string sTcPos ;
- pDisp->GetToolData( sTool, sHead, nExit, sTcPos) ;
- // se esiste utensile corrente e cambierà, lo scarico
- if ( ! m_sTool.empty() && sTool != m_sTool) {
- // eventuale lancio script per scarico utensile
- int nCurrErr ;
- if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos, nCurrErr)) {
- nErr = ( nErr != 0 ? nErr : nCurrErr) ;
- if ( nCurrErr != ERR_COLLISION)
- return false ;
- }
- }
- // carico l'utensile
- if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
- return false ;
- m_sTool = sTool ;
- m_sHead = sHead ;
- m_nExit = nExit ;
- m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ;
- double dTipFeed = 0 ;
- m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ;
- m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ;
- // aggiorno gli assi macchina
- if ( ! UpdateAxes())
- return false ;
- // eventuale lancio script
- int nCurrErr ;
- if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst, nCurrErr)) {
- nErr = ( nErr != 0 ? nErr : nCurrErr) ;
- if ( nCurrErr != ERR_COLLISION)
- return false ;
- }
- return ( nErr == 0) ;
- }
- return false ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::UpdateAxes( void)
-{
- ResetAxes() ;
- // Macchina corrente
- Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
- if ( pMachine == nullptr)
- return false ;
- // Carico i nomi e i token degli assi macchina attivi
- if ( ! pMachine->GetAllCurrAxesNames( m_AxesName) ||
- ! pMachine->GetAllCurrAxesTokens( m_AxesToken))
- return false ;
- // Aggiorno flag di invertito, offset, tipo e posizione corrente degli assi macchina attivi
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
- bool bInvert ;
- m_pMachine->GetAxisInvert( m_AxesName[i], bInvert) ;
- m_AxesInvert.push_back( bInvert) ;
- double dOffset ;
- m_pMachine->GetAxisOffset( m_AxesName[i], dOffset) ;
- m_AxesOffset.push_back( dOffset) ;
- bool bLinear ;
- m_pMachine->GetAxisType( m_AxesName[i], bLinear) ;
- m_AxesLinear.push_back( bLinear) ;
- double dVal ;
- m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
- m_AxesVal.emplace_back( dVal) ;
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::UpdateAxesPos( void)
-{
- // Macchina corrente
- Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
- if ( pMachine == nullptr)
- return false ;
- // Aggiorno la posizione corrente degli assi macchina attivi
- m_AxesVal.clear() ;
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
- double dVal ;
- m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
- m_AxesVal.emplace_back( dVal) ;
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ResetAxes( void)
-{
- // pulisco dati assi
- m_AxesName.clear() ;
- m_AxesToken.clear() ;
- m_AxesInvert.clear() ;
- m_AxesLinear.clear() ;
- m_AxesVal.clear() ;
- m_nAxesMask = 0 ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ResetAuxAxes( void)
-{
- // pulisco dati assi ausiliari
- m_AuxAxesName.clear() ;
- m_AuxAxesToken.clear() ;
- m_AuxAxesInvert.clear() ;
- m_AuxAxesOffset.clear() ;
- m_AuxAxesLinear.clear() ;
- m_AuxAxesVal.clear() ;
- m_AuxAxesEnd.clear() ;
- m_AuxAxesLink.clear() ;
- // abilito assi principali
- m_bEnabAxes = true ;
- m_bShowAxes = true ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::FindAndManageOperationStart( bool bStart, bool bFirst, int& nStatus)
-{
- // verifico parametri
- if ( ! bStart)
- bFirst = false ;
- // recupero la nuova operazione
- if ( bStart) {
- m_nOpId = m_pMchMgr->GetFirstActiveOperation() ;
- m_nOpInd = 0 ;
- }
- else
- m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ;
- // ciclo sulle successive operazioni
- while ( m_nOpId != GDB_ID_NULL) {
- // se lavorazione valida
- Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
- if ( pMch != nullptr && ! pMch->IsEmpty()) {
- bool bOk = true ;
- // aggiorno utensile e assi conseguenti
- int nErr ;
- if ( ! UpdateTool( bFirst, nErr)) {
- string sOut = "Err=" + ToString( nErr) ;
- LOG_INFO( GetEMkLogger(), sOut.c_str())
- nStatus = CalcStatusOnError( nErr) ;
- bOk = false ;
- }
- ++ m_nOpInd ;
- // imposto la lavorazione come corrente
- m_pMchMgr->SetCurrMachining( m_nOpId) ;
- // recupero punti di minimo e massimo ingombro
- int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ;
- Point3d ptMin, ptMax ;
- m_pGeomDB->GetInfo( nClId, KEY_MMIN, ptMin) ;
- m_pGeomDB->GetInfo( nClId, KEY_MMAX, ptMax) ;
- DBLVECTOR vAxMin, vAxMax ;
- m_pGeomDB->GetInfo( nClId, KEY_MAXMIN, vAxMin) ;
- m_pGeomDB->GetInfo( nClId, KEY_MAXMAX, vAxMax) ;
- // richiamo gestione evento inizio lavorazione
- if ( ! OnMachiningStart( m_nOpId, m_nOpInd, ptMin, ptMax, vAxMin, vAxMax)) {
- nStatus = CalcStatusOnError( 0) ;
- bOk = false ;
- }
- if ( ! bOk)
- return false ;
- break ;
- }
- // se disposizione con cambio di fase
- Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
- if ( pDisp != nullptr) {
- // in alcuni casi la disposizione non è inizializzata
- pDisp->Init( m_pMchMgr) ;
- // recupero dati tavola
- string sTable ;
- pDisp->GetTable( sTable) ;
- Point3d ptOri1 ;
- pDisp->GetTableRef1( ptOri1) ;
- // recupero la fase della disposizione
- int nPhase = pDisp->GetPhase() ;
- // recupero se con movimenti autonomi
- bool bEmpty = pDisp->IsEmpty() ;
- // recupero flag disposizione con movimenti manuali
- bool bSomeByHand = pDisp->GetSomeByHand() ;
- // se con movimenti autonomi
- if ( ! bEmpty) {
- // richiamo gestione evento appena prima di inizio disposizione
- if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
- nStatus = CalcStatusOnError( 0) ;
- return false ;
- }
- // cambio fase
- m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
- // se previsto, aggiorno utensile e assi conseguenti
- if ( pDisp->IsWithTool()) {
- int nErr ;
- if ( ! UpdateTool( bFirst, nErr)) {
- nStatus = CalcStatusOnError( nErr) ;
- return false ;
- }
- }
- ++ m_nOpInd ;
- // richiamo gestione evento inizio disposizione
- if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
- nStatus = CalcStatusOnError( 0) ;
- return false ;
- }
- // se ci sono movimenti manuali, aggiorno visualizzazione e breve pausa (200 ms)
- if ( bSomeByHand)
- Sleep( 200) ;
- break ;
- }
- // altrimenti disposizione passiva
- else {
- // richiamo gestione evento appena prima di inizio disposizione
- if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, true, bSomeByHand)) {
- nStatus = CalcStatusOnError( 0) ;
- return false ;
- }
- // cambio fase
- m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
- ++ m_nOpInd ;
- // richiamo gestione evento inizio e fine disposizione
- if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, true, bSomeByHand) ||
- ! OnDispositionEnd()) {
- nStatus = CalcStatusOnError( 0) ;
- return false ;
- }
- // se non è inizio, aggiorno visualizzazione e breve pausa (200 ms)
- if ( nPhase != 1) {
- ExeDraw() ;
- Sleep( 200) ;
- }
- }
- }
- // passo alla operazione successiva
- m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ;
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ManageOperationEnd( int& nStatus)
-{
- bool bOk = false ;
- // non c'è operazione in corso (solo prima disposizione senza lavorazioni)
- if ( m_nOpId == GDB_ID_NULL)
- bOk = true ;
- // se altrimenti è una lavorazione
- else if ( GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) {
- // richiamo gestione evento fine lavorazione
- bOk = OnMachiningEnd() ;
- }
- // se altrimenti è una disposizione
- else if ( GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) {
- // richiamo gestione evento fine disposizione
- bOk = OnDispositionEnd() ;
- }
- // gestione stato
- if ( ! bOk)
- nStatus = CalcStatusOnError( 0) ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::FindAndManagePathStart( int& nStatus)
-{
- // se devo cercare il primo nella nuova operazione
- if ( m_nCLPathId == GDB_ID_NULL) {
- // aggiorno gli altri dati
- int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ;
- m_nCLPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
- m_nCLPathInd = 0 ;
- m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ;
- m_nEntInd = 0 ;
- m_dCoeff = 0 ;
- }
- // altrimenti cerco il successivo nella stessa operazione
- else {
- // recupero un nuovo CLpath
- while ( m_nEntId == GDB_ID_NULL) {
- m_nCLPathId = m_pGeomDB->GetNextGroup( m_nCLPathId) ;
- // se non ce ne sono altri, devo passare a una nuova lavorazione
- if ( m_nCLPathId == GDB_ID_NULL)
- break ;
- m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ;
- m_nEntInd = 0 ;
- m_dCoeff = 0 ;
- }
- }
- // se trovato nuovo CLpath con entità, gestisco inizio percorso di lavoro
- if ( m_nEntId != GDB_ID_NULL) {
- ++ m_nCLPathInd ;
- // recupero punti di inizio e fine percorso
- Point3d ptStart ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ;
- Point3d ptEnd ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_END, ptEnd) ;
- // recupero versore estrusione associato al percorso (normale al piano di interpolazione)
- Vector3d vtExtr ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ;
- // recupero punti di minimo e massimo ingombro
- Point3d ptMin, ptMax ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ;
- // Recupero valori degli assi di minimo e massimo ingombro
- DBLVECTOR vAxMin, vAxMax ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_PAXMIN, vAxMin) ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_PAXMAX, vAxMax) ;
- // recupero massima elevazione
- double dElev = 0 ;
- m_pGeomDB->GetInfo( m_nCLPathId, KEY_ELEV, dElev) ;
- // recupero il numero di eventi ausiliari di inizio
- if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS_TOT, m_nAuxSTot))
- m_nAuxSTot = 0 ;
- m_nAuxSInd = 0 ;
- // reset numero eventi ausiliari di fine
- m_nAuxEInd = 0 ;
- m_nAuxETot = 0 ;
- // richiamo gestione evento inizio percorso di lavoro
- if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, m_nAuxSTot, ptStart, ptEnd, vtExtr, ptMin, ptMax, vAxMin, vAxMax, dElev)) {
- nStatus = CalcStatusOnError( 0) ;
- return false ;
- }
- }
- // se altrimenti trovato nuovo CL path vuoto
- else if ( m_nCLPathId != GDB_ID_NULL) {
- // recupero il numero di eventi ausiliari di inizio
- if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS_TOT, m_nAuxSTot))
- m_nAuxSTot = 0 ;
- m_nAuxSInd = 0 ;
- // recupero il numero di eventi ausiliari di fine
- if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE_TOT, m_nAuxETot))
- m_nAuxETot = 0 ;
- m_nAuxEInd = 0 ;
- }
-
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ManagePathEnd( int& nStatus)
-{
- // recupero il numero di eventi ausiliari di fine
- if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE_TOT, m_nAuxETot))
- m_nAuxETot = 0 ;
- m_nAuxEInd = 0 ;
- // richiamo gestione evento fine percorso di lavoro
- bool bOk = OnPathEnd( m_nAuxETot) ;
- // gestione stato
- if ( ! bOk)
- nStatus = CalcStatusOnError( 0) ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ManagePathStartAux( int& nStatus)
-{
- // aggiorno indice corrente
- ++ m_nAuxSInd ;
- // recupero i dati per l'evento corrente
- string sAS ;
- if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS + ToString( m_nAuxSInd), sAS)) {
- nStatus = MCH_SIM_ERR ;
- return false ;
- }
- // richiamo gestione evento ausiliario prima di inizio percorso di lavoro
- int nErr ;
- if ( ! OnPathStartAux( m_nAuxSInd, sAS, nErr)) {
- nStatus = CalcStatusOnError( nErr) ;
- return false ;
- }
- nStatus = MCH_SIM_END_STEP ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ManagePathEndAux( int& nStatus)
-{
- // aggiorno indice corrente
- ++ m_nAuxEInd ;
- // recupero i dati per l'evento corrente
- string sAE ;
- if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE + ToString( m_nAuxEInd), sAE)) {
- nStatus = MCH_SIM_ERR ;
- return false ;
- }
- // richiamo gestione evento ausiliario dopo fine percorso di lavoro
- int nErr ;
- if ( ! OnPathEndAux( m_nAuxEInd, sAE, nErr)) {
- nStatus = CalcStatusOnError( nErr) ;
- return false ;
- }
- nStatus = MCH_SIM_END_STEP ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ManageMove( int& nStatus)
-{
- // Imposto lunghezza di movimento effettuata
- double dCurrMove = 0 ;
- while ( m_nEntId != GDB_ID_NULL) {
- // eseguo movimento singolo
- double dMove ;
- if ( ! ManageSingleMove( nStatus, dMove))
- return false ;
- dCurrMove += dMove ;
- // se modalità play e fine entità e non raggiunta la lunghezza di movimento voluto
- if ( m_nUiStatus == MCH_UISIM_PLAY && nStatus == MCH_SIM_END_STEP && dCurrMove < 0.75 * m_dStep) {
- // recupero una nuova entità
- m_nEntId = m_pGeomDB->GetNext( m_nEntId) ;
- m_dCoeff = 0 ;
- }
- else
- break ;
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ManageSingleMove( int& nStatus, double& dMove)
-{
- // Recupero posizione finale
- const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
- if ( pCamData == nullptr) {
- nStatus = MCH_SIM_ERR ;
- return false ;
- }
- switch ( pCamData->GetAxesStatus()) {
- case CamData::AS_OK :
- break ;
- case CamData::AS_OUTSTROKE : {
- DBLVECTOR OutAxes = pCamData->GetAxesVal() ;
- for ( size_t i = OutAxes.size() ; i < 5 ; ++ i)
- OutAxes.emplace_back( 0) ;
- DBLVECTOR vAng( OutAxes.begin() + 3, OutAxes.end()) ;
- int nStat ;
- m_pMachine->VerifyOutstroke( OutAxes[0], OutAxes[1], OutAxes[2], vAng, true, nStat) ;
- nStatus = MCH_SIM_OUTSTROKE ;
- return false ; }
- case CamData::AS_DIR_ERR :
- nStatus = MCH_SIM_DIR_ERR ;
- return false ;
- default :
- nStatus = MCH_SIM_ERR ;
- return false ;
- }
- DBLVECTOR AxesEnd = pCamData->GetAxesVal() ;
- // Tipo di movimento
- int nMoveType = pCamData->GetMoveType() ;
- // Se inizio di nuova entità, mascheratura movimento
- if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO)
- m_nAxesMask = pCamData->GetAxesMask() ;
- // Se movimento in rapido muovo solo gli assi abilitati dal mask
- if ( nMoveType == 0) {
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
- if ( ( m_nAxesMask & 1 << i) == 0)
- AxesEnd[i] = m_AxesVal[i] ;
- }
- }
-
- // Se inizio di nuova entità
- if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO) {
- ++ m_nEntInd ;
- const CamData* pNextCamData = GetCamData( m_pGeomDB->GetUserObj( m_pGeomDB->GetNext( m_nEntId))) ;
- int nErr ;
- if ( ! OnMoveStart( pCamData, pNextCamData, nErr)) {
- nStatus = CalcStatusOnError( nErr) ;
- return false ;
- }
- // Se movimento in rapido aggiorno quote degli assi disabilitati dal mask
- if ( nMoveType == 0) {
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
- if ( ( m_nAxesMask & 1 << i) == 0)
- AxesEnd[i] = m_AxesVal[i] ;
- }
- }
- }
-
- // Posizione e direzione attuali degli utensili e riferimenti dei pezzi (per Vmill)
- bool bOkI = true ;
- PNTVECTOR vPtNoseI( m_VmTool.size()) ;
- VCT3DVECTOR vVtDirI( m_VmTool.size()) ;
- VCT3DVECTOR vVtAuxI( m_VmTool.size()) ;
- for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i)
- bOkI = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, vPtNoseI[i], vVtDirI[i], vVtAuxI[i]) && bOkI ;
- vector vFrVzmI( m_VmId.size()) ;
- for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
- bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
-
- // Dati per eventuale verifica di collisione
- int nCdInd, nObjInd ;
- bool bCollCheck = true ;
-
- // Eseguo movimento assi principali ed eventuali ausiliari
- if ( m_bEnabAxes) {
- // Calcolo distanza di movimento
- double dSqDist = 0 ;
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
- // coefficiente moltiplicativo per differenziare assi lineari e rotanti
- double dSqCoeff = ( m_AxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
- dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ;
- }
- // Calcolo distanza di movimento eventuali assi ausiliari
- double dSqDistAux = 0 ;
- for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
- if ( m_AuxAxesLink[i] != 0)
- continue ;
- // coefficiente moltiplicativo per differenziare assi lineari e rotanti
- double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
- dSqDistAux += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
- }
- // Considero il massimo delle due distanze
- double dPrevCoeff = m_dCoeff ;
- double dDist = sqrt( max( dSqDist, dSqDistAux)) ;
- if ( dDist > EPS_SMALL) {
- double dStep = min( ( nMoveType == 0 ? 2 : 1) * m_dStep, MAX_STEP) ;
- int nStep = max( int( dDist / dStep), 1) ;
- m_dCoeff += 1. / nStep ;
- if ( m_dCoeff > 1)
- m_dCoeff = 1 ;
- }
- else
- m_dCoeff = 1 ;
- dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
-
- // Log per debug
- if ( ExeGetDebugLevel() >= 10) {
- string sOut = "MoveType=" + ToString( nMoveType) + " Coeff=" + ToString( m_dCoeff) ;
- LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
- }
-
- // Eseguo movimento rapido o lineare (non arco)
- if ( nMoveType != 2 && nMoveType != 3) {
- // se attivo CollisionCheck approssimo movimento con più step
- int nStep = 1 ;
- if ( NeedCollisionCheck())
- nStep = max( int( dMove / COLL_STEP), 1) ;
- for ( int i = 1 ; i <= nStep ; ++ i) {
- double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
- DBLVECTOR vDeltaVal( m_AxesName.size()) ;
- // assegno posizioni finali
- for ( int j = 0 ; j < int( m_AxesName.size()) ; ++ j) {
- double dPrevVal ;
- m_pMachine->GetAxisPos( m_AxesName[j], dPrevVal) ;
- double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
- m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
- vDeltaVal[j] = dVal - dPrevVal ;
- }
- // muovo eventuali assi ausiliari
- for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
- double dVal = 0 ;
- if ( m_AuxAxesLink[j] == 0) {
- dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
- }
- else {
- m_pMachine->GetAxisPos( m_AuxAxesName[j], dVal) ;
- if ( m_AuxAxesLink[j] > 0)
- dVal += vDeltaVal[m_AuxAxesLink[j] - 1] ;
- else
- dVal -= vDeltaVal[-m_AuxAxesLink[j] - 1] ;
- }
- m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
- }
- // se abilitato e non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill
- if ( m_bEnableVm && ( nMoveType != 0 || ! NeedCollisionCheck())) {
- for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
- Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
- bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
- for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
- Frame3d frVzmF ;
- bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
- ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
- vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
- // se ultimo utensile, salvo riferimento per prossimo inizio
- if ( j == int( m_VmTool.size()) - 1)
- vFrVzmI[k] = frVzmF ;
- }
- // aggiorno prossimo inizio
- vPtNoseI[j] = ptNoseF ;
- vVtDirI[j] = vtDirF ;
- vVtAuxI[j] = vtAuxF ;
- }
- }
- // eseguo eventuale collision check
- bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
- }
- }
- // Eseguo movimento su arco
- else {
- // dati dell'arco
- Point3d ptCen = pCamData->GetAxesCen() ;
- double dAngCen = pCamData->GetAxesAngCen() ;
- double dRad = pCamData->GetAxesRad() ;
- Vector3d vtN = pCamData->GetAxesNormDir() ;
- double dDeltaN = ( Point3d( AxesEnd[0], AxesEnd[1], AxesEnd[2]) - ptCen) * vtN ;
- double dDiffAng = ( m_dCoeff - dPrevCoeff) * dAngCen ;
- Vector3d vtRot = Point3d( m_AxesVal[0], m_AxesVal[1], m_AxesVal[2]) - ptCen ;
- vtRot.Rotate( vtN, dPrevCoeff * dAngCen) ;
- // se attivi Vmill o CollisionCheck approssimo movimento con più step
- int nStep = 1 ;
- if ( ! m_VmId.empty() || NeedCollisionCheck()) {
- const double MIN_LEN_STEP = 2. ;
- const double MAX_LEN_STEP = 10. ;
- double dLenStep = Clamp( 0.1 * m_dTDiam, MIN_LEN_STEP, MAX_LEN_STEP) ;
- nStep = max( int( abs( dDiffAng * DEGTORAD * dRad) / dLenStep), 1) ;
- const double ANG_STEP = 5. ;
- if ( abs( dDiffAng) / nStep > ANG_STEP)
- nStep = int( abs( dDiffAng) / ANG_STEP) ;
- }
- for ( int i = 1 ; i <= nStep ; ++ i) {
- double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
- DBLVECTOR vDeltaVal( m_AxesName.size()) ;
- // assi lineari
- vtRot.Rotate( vtN, dDiffAng / nStep) ;
- double dPrevVal, dVal ;
- m_pMachine->GetAxisPos( m_AxesName[0], dPrevVal) ;
- dVal = ptCen.x + vtRot.x + dCurrCoeff * dDeltaN * vtN.x ;
- m_pMachine->SetAxisPos( m_AxesName[0], dVal) ;
- vDeltaVal[0] = dVal - dPrevVal ;
- m_pMachine->GetAxisPos( m_AxesName[1], dPrevVal) ;
- dVal = ptCen.y + vtRot.y + dCurrCoeff * dDeltaN * vtN.y ;
- m_pMachine->SetAxisPos( m_AxesName[1], dVal) ;
- vDeltaVal[1] = dVal - dPrevVal ;
- m_pMachine->GetAxisPos( m_AxesName[2], dPrevVal) ;
- dVal = ptCen.z + vtRot.z + dCurrCoeff * dDeltaN * vtN.z ;
- m_pMachine->SetAxisPos( m_AxesName[2], dVal) ;
- vDeltaVal[2] = dVal - dPrevVal ;
- // assi rotanti
- for ( int j = 3 ; j < int( m_AxesName.size()) ; ++ j) {
- double dPrevVal ; m_pMachine->GetAxisPos( m_AxesName[j], dPrevVal) ;
- double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
- m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
- vDeltaVal[j] = dVal - dPrevVal ;
- }
- // eventuali assi ausiliari
- for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
- double dVal = 0 ;
- if ( m_AuxAxesLink[j] == 0) {
- dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
- }
- else {
- m_pMachine->GetAxisPos( m_AuxAxesName[j], dVal) ;
- if ( m_AuxAxesLink[j] > 0)
- dVal += vDeltaVal[m_AuxAxesLink[j] - 1] ;
- else
- dVal -= vDeltaVal[-m_AuxAxesLink[j] - 1] ;
- }
- m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
- }
- // se abilitato, eseguo eventuale Vmill
- for ( int j = 0 ; m_bEnableVm && j < int( m_VmTool.size()) ; ++ j) {
- Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
- bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
- for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
- Frame3d frVzmF ;
- bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
- ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
- vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
- // se ultimo utensile, salvo riferimento per prossimo inizio
- if ( j == int( m_VmTool.size()) - 1)
- vFrVzmI[k] = frVzmF ;
- }
- // aggiorno prossimo inizio
- vPtNoseI[j] = ptNoseF ;
- vVtDirI[j] = vtDirF ;
- vVtAuxI[j] = vtAuxF ;
- }
- // eseguo eventuale collision check
- bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
- }
- }
- }
-
- // altrimenti eseguo movimento soli eventuali assi ausiliari
- else {
- // Calcolo distanza di movimento
- double dSqDist = 0 ;
- for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
- // coefficiente moltiplicativo per differenziare assi lineari e rotanti
- double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
- dSqDist += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
- }
- double dPrevCoeff = m_dCoeff ;
- double dDist = sqrt( dSqDist) ;
- if ( dDist > EPS_SMALL) {
- double dStep = min( ( nMoveType == 0 ? 2 : 1) * m_dStep, MAX_STEP) ;
- int nStep = max( int( dDist / dStep), 1) ;
- m_dCoeff += 1. / nStep ;
- if ( m_dCoeff > 1)
- m_dCoeff = 1 ;
- }
- else
- m_dCoeff = 1 ;
- dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
- // se attivo CollisionCheck approssimo movimento con più step
- int nStep = 1 ;
- if ( NeedCollisionCheck())
- nStep = max( int( dMove / COLL_STEP), 1) ;
- for ( int i = 1 ; i <= nStep ; ++ i) {
- double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
- // muovo eventuali assi ausiliari
- for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
- if ( m_AuxAxesLink[j] == 0) {
- double dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
- m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
- }
- }
- // se abilitato e non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill
- if ( m_bEnableVm && ( nMoveType != 0 || ! NeedCollisionCheck())) {
- for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
- Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
- bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
- for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
- Frame3d frVzmF ;
- bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
- ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
- vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
- // se ultimo utensile, salvo riferimento per prossimo inizio
- if ( j == int( m_VmTool.size()) - 1)
- vFrVzmI[k] = frVzmF ;
- }
- // aggiorno prossimo inizio
- vPtNoseI[j] = ptNoseF ;
- vVtDirI[j] = vtDirF ;
- vVtAuxI[j] = vtAuxF ;
- }
- }
- // eseguo eventuale collision check
- bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
- }
- }
-
- // Se riscontrata collisione
- if ( ! bCollCheck) {
- // Richiamo funzione di convalida collisione
- int nErr ;
- if ( ! OnCollision( nCdInd, nObjInd, nErr)) {
- nStatus = CalcStatusOnError( nErr) ;
- // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo
- if ( m_dCoeff > COEFF_LIM) {
- if ( m_bEnabAxes) {
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
- m_AxesVal[i] = AxesEnd[i] ;
- }
- // richiamo gestione evento fine entità, senza gestirne eventuali errori
- int nErr ;
- OnMoveEnd( nErr) ;
- }
- return false ;
- }
- }
-
- // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo
- if ( m_dCoeff > COEFF_LIM) {
- if ( m_bEnabAxes) {
- for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
- m_AxesVal[i] = AxesEnd[i] ;
- }
- nStatus = MCH_SIM_END_STEP ;
- // richiamo gestione evento fine entità
- int nErr ;
- if ( ! OnMoveEnd( nErr)) {
- nStatus = CalcStatusOnError( nErr) ;
- return false ;
- }
- }
- // Altrimenti sto muovendomi all'interno dell'entità
- else
- nStatus = MCH_SIM_OK ;
-
- return true ;
-}
-
-//----------------------------------------------------------------------------
-int
-Simulator::CalcStatusOnError( int nErr)
-{
- if ( Stopped())
- return MCH_SIM_STOP ;
- else if ( nErr == ERR_OUTSTROKE)
- return MCH_SIM_OUTSTROKE ;
- else if ( nErr == ERR_COLLISION)
- return MCH_SIM_COLLISION ;
- else
- return MCH_SIM_ERR ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::GetHeadCurrPosDirAux( const std::string& sHead, int nExit, Point3d& ptH, Vector3d& vtH, Vector3d& vtA)
-{
- int nHeadId = m_pMachine->GetHeadId( sHead) ;
- int nExitId = m_pMachine->GetExitId( sHead, nExit) ;
- if ( nHeadId == GDB_ID_NULL || nExitId == GDB_ID_NULL)
- return false ;
- Frame3d frExit ; m_pGeomDB->GetGroupGlobFrame( nExitId, frExit) ;
- ptH = frExit.Orig() ;
- vtH = frExit.VersZ() ;
- vtA = V_NULL ;
- int nDirAuxId = m_pGeomDB->GetFirstNameInGroup( nHeadId, MCH_AUX_VECT) ;
- if ( nDirAuxId != GDB_ID_NULL) {
- const IGeoVector3d* pGV = GetGeoVector3d( m_pGeomDB->GetGeoObj( nDirAuxId)) ;
- if ( pGV != nullptr) {
- Frame3d frHead ; m_pGeomDB->GetGroupGlobFrame( nHeadId, frHead) ;
- vtA = pGV->GetVector() ;
- vtA.ToGlob( frHead) ;
- }
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVmAdOffs,
- const Point3d& ptHi, const Vector3d& vtHi, const Vector3d& vtAi, const Frame3d& frVzmI,
- const Point3d& ptHf, const Vector3d& vtHf, const Vector3d& vtAf, const Frame3d& frVzmF)
-{
- // Recupero Zmap
- IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( nVmId)) ;
- if ( pVZM == nullptr) {
- string sOut = " --> GetVolZmap (" + ToString( nVmId) +") Error <--" ;
- LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
- return false ;
- }
- // Porto gli estremi nel riferimento opportuno dello Zmap
- Point3d ptHiL = ptHi ; ptHiL.ToLoc( frVzmI) ;
- Vector3d vtHiL = vtHi ; vtHiL.ToLoc( frVzmI) ;
- Vector3d vtAiL = vtAi ; vtAiL.ToLoc( frVzmI) ;
- Point3d ptHfL = ptHf ; ptHfL.ToLoc( frVzmF) ;
- Vector3d vtHfL = vtHf ; vtHfL.ToLoc( frVzmF) ;
- Vector3d vtAfL = vtAf ; vtAfL.ToLoc( frVzmF) ;
- // Eventuali offset
- ptHiL += dVmTdOffs * vtHiL + dVmAdOffs * vtAiL ;
- ptHfL += dVmTdOffs * vtHfL + dVmAdOffs * vtAfL ;
- // Log per debug
- if ( ExeGetDebugLevel() >= 10) {
- string sOut = "Zmap=" + ToString( nVmId) + " Tool=" + ToString( nCurrTool) +
- " Pi=(" + ToString( ptHiL) + ") Vi=(" + ToString( vtHiL) + ") Ai=(" + ToString( vtAiL) +
- ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ;
- LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
- }
- // Se utensile che non lavora di testa
- if ( ! m_bCutOnTip) {
- // se movimento di testa (angolo movimento verso la testa oltre 5.8deg), non eseguo asportazione
- Vector3d vtDirM = Media( vtHiL, vtHfL) ;
- vtDirM.Normalize() ;
- double dAxMove = ( ptHfL - ptHiL) * vtDirM ;
- if ( dAxMove < -EPS_SMALL) {
- double dMove = ( ptHfL - ptHiL).Len() ;
- if ( dAxMove < -0.1 * abs( dMove))
- return true ;
- }
- }
- // Eseguo
- bool bOk = pVZM->MillingStep( nCurrTool, ptHiL, vtHiL, vtAiL, ptHfL, vtHfL, vtAfL) ;
- if ( ! bOk) {
- if ( ExeGetDebugLevel() < 10) {
- string sOut = "Zmap=" + ToString( nVmId) + " Tool=" + ToString( nCurrTool) +
- " Pi=(" + ToString( ptHiL) + ") Vi=(" + ToString( vtHiL) + ") Ai=(" + ToString( vtAiL) +
- ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ;
- LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
- }
- LOG_DBG_INFO( GetEMkLogger(), " --> MillingStep Error <--")
- }
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType)
-{
- // se non ci sono oggetti da controllare o non ci sono grezzi o equivalenti, tutto bene
- if ( ! NeedCollisionCheck())
- return true ;
- // ciclo sui grezzi o equivalenti
- for ( int i = 0 ; i < int( m_CdId.size()) ; ++ i) {
- // se modo hidden è da saltare
- int nMode ;
- if ( m_pGeomDB->GetCalcMode( m_CdId[i], nMode) && nMode == GDB_MD_HIDDEN)
- continue ;
- // verifico se è il grezzo in lavorazione
- bool bIsRaw = ( find( m_VmId.begin(), m_VmId.end(), m_CdId[i]) != m_VmId.end()) ;
- // recupero solido o trimesh, se altro lo salto
- const IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
- const ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
- if ( pVZM == nullptr && pSTM == nullptr)
- continue ;
- // recupero il riferimento
- Frame3d frCd ; m_pGeomDB->GetGlobFrame( m_CdId[i], frCd) ;
- // ciclo sugli oggetti con cui verificare
- for ( int j = 0 ; j < int( m_CollObj.size()) ; ++ j) {
- // se modo hidden è da saltare
- int nMode ;
- if ( m_pGeomDB->GetCalcMode( m_CollObj[j].nFrameId, nMode) && nMode == GDB_MD_HIDDEN)
- continue ;
- // verifico se è l'utensile attivo
- string sHead ; m_pGeomDB->GetName( m_pGeomDB->GetParentId( m_CollObj[j].nFrameId), sHead) ;
- string sExit ; m_pGeomDB->GetName( m_CollObj[j].nFrameId, sExit) ;
- bool bIsTool = m_CollObj[j].bToolOn ||
- ( sHead == m_sHead && ( sExit == "_T" + ToString( m_nExit) || sExit == "_TT" + ToString( m_nExit))) ;
- // se utensile attivo su grezzo in lavoro e non è rapido, salto
- if ( bIsTool && bIsRaw && nMoveType != 0)
- continue ;
- // esecuzione controlli di collisione
- bool bOk = true ;
- // oggetti che richiedono frame associato (Box, Cylinder, Sphere, Cone)
- if ( m_CollObj[j].nType != MCH_SIM_COB_POLY) {
- // se riferimento non trovato, si salta
- const IGeoFrame3d* pGeoFrame = GetGeoFrame3d( m_pGeomDB->GetGeoObj( m_CollObj[j].nFrameId)) ;
- if ( pGeoFrame == nullptr)
- continue ;
- Frame3d frObj = pGeoFrame->GetFrame() ;
- if ( ! m_CollObj[j].vtMove.IsSmall())
- frObj.Translate( m_CollObj[j].vtMove.x * frObj.VersX() +
- m_CollObj[j].vtMove.y * frObj.VersY() +
- m_CollObj[j].vtMove.z * frObj.VersZ()) ;
- Frame3d frParent ; m_pGeomDB->GetGlobFrame( m_CollObj[j].nFrameId, frParent) ;
- frObj.LocToLoc( frParent, frCd) ;
- // controlli di collisione
- if ( m_CollObj[j].nType == MCH_SIM_COB_BOX) {
- Vector3d vtDiag( m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3) ;
- if ( pVZM != nullptr)
- bOk = ! pVZM->CDeBox( frObj, vtDiag, m_dSafeDist) ;
- else
- bOk = ! CDeBoxClosedSurfTm( frObj, vtDiag, *pSTM, m_dSafeDist) ;
- }
- else if ( m_CollObj[j].nType == MCH_SIM_COB_CYL) {
- if ( pVZM != nullptr)
- bOk = ! pVZM->CDeCylinder( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_dSafeDist) ;
- else
- bOk = ! CDeCylClosedSurfTm( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, *pSTM, m_dSafeDist) ;
- }
- else if ( m_CollObj[j].nType == MCH_SIM_COB_SPHE) {
- if ( pVZM != nullptr)
- bOk = ! pVZM->CDeSphere( frObj.Orig(), m_CollObj[j].dPar1, m_dSafeDist) ;
- else
- bOk = ! CDeSpheClosedSurfTm( frObj.Orig(), m_CollObj[j].dPar1, *pSTM, m_dSafeDist) ;
- }
- else if ( m_CollObj[j].nType == MCH_SIM_COB_CONE) {
- if ( pVZM != nullptr)
- bOk = ! pVZM->CDeConeFrustum( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3, m_dSafeDist) ;
- else
- bOk = ! CDeConeFrustumClosedSurfTm( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3, *pSTM, m_dSafeDist) ;
- }
- }
- // altrimenti poliedro
- else {
- SurfLocal SurfLoc( m_pGeomDB, m_CollObj[j].nFrameId, frCd) ;
- const ISurfTriMesh* pStmLoc = GetSurfTriMesh( SurfLoc) ;
- if ( pStmLoc != nullptr) {
- if ( pVZM != nullptr)
- bOk = ! pVZM->CDeSurfTm( *pStmLoc, m_dSafeDist) ;
- else
- bOk = ! CDeClosedSurfTmClosedSurfTm( *pStmLoc, *pSTM, m_dSafeDist) ;
- }
- else
- bOk = false ;
- }
- // se trovata collisione
- if ( ! bOk) {
- nCdInd = i ;
- nObjInd = j ;
- return false ;
- }
- }
- }
- return true ;
-}
-
-//----------------------------------------------------------------------------
-static int
-FindCollisionMarkId( const IGeomDB* pGeomDB, int nCollId)
-{
- int nCollParId = pGeomDB->GetParentId( nCollId) ;
- string sCollParName = "COLLISION" ;
- pGeomDB->GetName( nCollParId, sCollParName) ;
- if ( sCollParName != "COLLISION")
- return nCollParId ;
- else {
- int nCollGprId = pGeomDB->GetParentId( nCollParId) ;
- int nCollSolId = pGeomDB->GetFirstNameInGroup( nCollGprId, "SOLID") ;
- if ( nCollSolId != GDB_ID_NULL)
- return nCollSolId ;
- else
- return nCollGprId ;
- }
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::SetCollisionMark( int nCdInd, int nObjInd)
-{
- if ( m_pGeomDB == nullptr)
- return false ;
- m_nCollMarkId.clear() ;
- int nCdMarkId = FindCollisionMarkId( m_pGeomDB, m_CdId[nCdInd]) ;
- m_pGeomDB->SetMark( nCdMarkId, GDB_MK_ON) ;
- m_nCollMarkId.push_back( nCdMarkId) ;
- int nCoMarkId = FindCollisionMarkId( m_pGeomDB, m_CollObj[nObjInd].nFrameId) ;
- m_pGeomDB->SetMark( nCoMarkId, GDB_MK_ON_2) ;
- m_nCollMarkId.push_back( nCoMarkId) ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::ResetCollisionMark( void)
-{
- if ( m_pGeomDB == nullptr)
- return false ;
- for ( auto nId : m_nCollMarkId)
- m_pGeomDB->ResetMark( nId) ;
- m_nCollMarkId.clear() ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnInit( void)
-{
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_INIT))
- return true ;
- // chiamo la funzione di ingresso nella simulazione
- return m_pMachine->LuaCallFunction( ON_SIMUL_INIT) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnExit( void)
-{
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_EXIT))
- return true ;
- // chiamo la funzione di uscita dalla simulazione
- return m_pMachine->LuaCallFunction( ON_SIMUL_EXIT) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnProgramStart( bool bFirst)
-{
- // assegno flag inizio simulazione
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIM1ST, bFirst) ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_START))
- return true ;
- // chiamo la funzione di inizio simulazione
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_START) ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnProgramEnd( void)
-{
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_END))
- return true ;
- // chiamo la funzione di fine simulazione
- return m_pMachine->LuaCallFunction( ON_SIMUL_END) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
- const string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand)
-{
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
- // assegno nuovo indice di fase
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
- // assegno nome e valore riferimento della tavola corrente
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
- // assegno flag disposizione passiva
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
- // assegno flag disposizione con operazioni manuali
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SBH, bSomeByHand) ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_STARTING))
- return true ;
- // chiamo la funzione di inizio disposizione
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_STARTING) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnDispositionStart( int nOpId, int nOpInd, int nPhase,
- const string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand)
-{
- // assegno identificativo e indice disposizione
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
- // assegno nuovo indice di fase
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
- // assegno nome e valore riferimento della tavola corrente
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
- // assegno flag disposizione passiva
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
- // assegno flag disposizione con operazioni manuali
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SBH, bSomeByHand) ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_START))
- return true ;
- // chiamo la funzione di inizio disposizione
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_START) ;
- // recupero i dati di ritorno
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_VMILL, m_VmId) ;
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnDispositionEnd( void)
-{
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_END))
- return true ;
- // chiamo la funzione di fine disposizione
- bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_END) ;
- // recupero i dati di ritorno
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_VMILL, m_VmId) ;
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnToolSelect( const string& sTool, const string& sHead, int nExit, const string& sTcPos,
- bool bFirst, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // reset oggetti per verifica collisione con grezzo
- m_CollObj.clear() ;
- // assegno il nome dell'utensile, la testa e l'uscita
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TOOL, sTool) ||
- ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_HEAD, sHead) ||
- ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXIT, nExit) ||
- ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TCPOS, sTcPos))
- return false ;
- // assegno il token e il nome degli assi
- bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
- int nNumAxes = int( m_AxesName.size()) ;
- for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
- if ( i <= nNumAxes) {
- if ( ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisToken( i, bIsRobot), m_AxesToken[i-1]) ||
- ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisName( i, bIsRobot), m_AxesName[i-1]))
- return false ;
- }
- else {
- if ( ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisToken( i, bIsRobot)) ||
- ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisName( i, bIsRobot)))
- return false ;
- }
- }
- // assegno il flag di chiamata di utensile iniziale
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FIRST, bFirst))
- return false ;
- // reset errore
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
- return false ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_SELECT))
- return true ;
- // chiamo la funzione di selezione utensile
- bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_SELECT) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- // recupero dati per verifica collisione
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SAFEDIST, m_dSafeDist) ;
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
- // verifico codice di errore
- bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- // recupero i dati di ritorno per assi ausiliari
- ResetAuxAxes() ;
- int nNumAuxAxes = 0 ;
- if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
- return ( bOk && nErr == 0) ;
- m_AuxAxesName.reserve( nNumAuxAxes) ;
- m_AuxAxesToken.reserve( nNumAuxAxes) ;
- m_AuxAxesInvert.reserve( nNumAuxAxes) ;
- m_AuxAxesOffset.reserve( nNumAuxAxes) ;
- m_AuxAxesLinear.reserve( nNumAuxAxes) ;
- m_AuxAxesVal.reserve( nNumAuxAxes) ;
- m_AuxAxesEnd.reserve( nNumAuxAxes) ;
- for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
- string sName ; string sToken ; bool bInvert ; double dOffset ; bool bLinear ; double dVal ;
- string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
- if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
- m_pMachine->GetAxisToken( sName, sToken) &&
- m_pMachine->GetAxisInvert( sName, bInvert) &&
- m_pMachine->GetAxisOffset( sName, dOffset) &&
- m_pMachine->GetAxisType( sName, bLinear) &&
- m_pMachine->GetAxisPos( sName, dVal)) {
- // se non è già negli assi principali, lo aggiungo
- if ( find( m_AxesName.begin(), m_AxesName.end(), sName) == m_AxesName.end()) {
- m_AuxAxesName.emplace_back( sName) ;
- m_AuxAxesToken.emplace_back( sToken) ;
- m_AuxAxesInvert.push_back( bInvert) ;
- m_AuxAxesOffset.push_back( dOffset) ;
- m_AuxAxesLinear.push_back( bLinear) ;
- m_AuxAxesVal.emplace_back( dVal) ;
- m_AuxAxesEnd.emplace_back( dVal) ;
- m_AuxAxesLink.emplace_back( 0) ;
- }
- }
- else {
- bOk = false ;
- nErr = ERR_TOOL_SEL ;
- }
- }
-
- return ( bOk && nErr == 0) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnToolDeselect( const string& sNextTool, const string& sNextHead, int nNextExit, const string& sNextTcPos, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // assegno il prossimo utensile
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTOOL, sNextTool) ;
- // assegno la prossima testa
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTHEAD, sNextHead) ;
- // assegno la prossima uscita
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTEXIT, nNextExit) ;
- // assegno l'eventuale prossima posizione nel TC
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTCPOS, sNextTcPos) ;
- // reset errore
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_DESELECT))
- return bOk ;
- // chiamo la funzione di deselezione utensile
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_DESELECT) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- // verifico codice di errore
- bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- return ( bOk && nErr == 0) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax,
- const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax)
-{
- // assegno identificativo e indice lavorazione
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHID, nOpId) ||
- ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHIND, nOpInd))
- return false ;
- // assegno punti estremi dell'ingombro della lavorazione
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MMIN, ptMin) ||
- ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MMAX, ptMax))
- return false ;
- // assegno punti estremi dell'ingombro degli assi della lavorazione
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MAXMIN, vAxMin) ||
- ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MAXMAX, vAxMax))
- return false ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_START))
- return true ;
- // chiamo la funzione di inizio disposizione
- bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_START) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnMachiningEnd( void)
-{
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_END))
- return true ;
- // chiamo la funzione di fine lavorazione
- bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_END) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnPathStart( int nClPathId, int nClPathInd, int nAS, const Point3d& ptStart, const Point3d& ptEnd,
- const Vector3d& vtExtr, const Point3d& ptMin, const Point3d& ptMax,
- const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax, double dElev)
-{
- // assegno identificativo e indice percorso di lavorazione
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHID, nClPathId) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHIND, nClPathInd) ;
- // assegno numero di dati ausiliari iniziali
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXTOT, nAS) ;
- // assegno punti iniziale e finale e versore estrusione
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_START, ptStart) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_END, ptEnd) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXTR, vtExtr) ;
- // assegno punti estremi dell'ingombro del percorso di lavorazione
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMIN, ptMin) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMAX, ptMax) ;
- // assegno punti estremi dell'ingombro degli assi della lavorazione
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PAXMIN, vAxMin) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PAXMAX, vAxMax) ;
- // assegno la massima elevazione
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ELEV, dElev) ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START))
- return bOk ;
- // chiamo la funzione di inizio percorso di lavorazione
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnPathEnd( int nAE)
-{
- // assegno numero di dati ausiliari finali
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXTOT, nAE) ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END))
- return bOk ;
- // chiamo la funzione di fine percorso di lavorazione
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnPathStartAux( int nInd, const string& sAS, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START_AUX))
- return true ;
- // assegno indice, valore dato ausiliario e resetto errore
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXIND, nInd) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUX, sAS) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- // chiamo la funzione di evento ausiliario all'inizio del percorso
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START_AUX) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- // verifico codice di errore
- bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- return ( bOk && nErr == 0) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnPathEndAux( int nInd, const string& sAE, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END_AUX))
- return true ;
- // assegno indice, valore dato ausiliario e resetto errore
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXIND, nInd) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUX, sAE) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- // chiamo la funzione di evento ausiliario alla fine del percorso
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END_AUX) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- // verifico codice di errore
- bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- return ( bOk && nErr == 0) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnMoveStart( const CamData* pCamData, const CamData* pNextCamData, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // recupero e assegno i dati
- // dati generali e reset errore
- bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEID, m_nEntId) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEIND, m_nEntInd) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, pCamData->GetMoveType()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MASK, pCamData->GetAxesMask()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG, pCamData->GetFlag()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG2, pCamData->GetFlag2()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_INDEX, pCamData->GetIndex()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- // valore degli assi all'inizio e alla fine del movimento
- bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
- int nNumAxes = int( m_AxesName.size()) ;
- const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ;
- for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
- if ( i <= nNumAxes) {
- bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisPrev( i, GLOB_VAR, bIsRobot), m_AxesVal[i-1]) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisValue( i, GLOB_VAR, bIsRobot), AxesEnd[i-1]) ;
- }
- else {
- bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisPrev( i, GLOB_VAR, bIsRobot)) ;
- bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisValue( i, GLOB_VAR, bIsRobot)) ;
- }
- }
- // versori utensile, correzione e ausiliario alla fine del movimento
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TDIR, pCamData->GetToolDir()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_CDIR, pCamData->GetCorrDir()) ;
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ADIR, pCamData->GetBackAuxDir()) ;
- // anticipazione di alcuni dati dell'eventuale movimento successivo dello stesso percorso
- if ( pNextCamData != nullptr && pNextCamData->GetAxesStatus() == CamData::AS_OK) {
- bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVESUCC, pNextCamData->GetMoveType()) ;
- const DBLVECTOR& AxesNext = pNextCamData->GetAxesVal() ;
- for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
- if ( i <= nNumAxes)
- bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot), AxesNext[i-1]) ;
- else
- bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot)) ;
- }
- }
- else {
- bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_MOVESUCC) ;
- for ( int i = 1 ; i <= MAX_AXES ; ++ i)
- bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot)) ;
- }
- // reset abilitazione assi attivi
- bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_ENABAXES) ;
- // reset numero assi ausiliari
- bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_AUXAXES) ;
-
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_START)) {
- ResetAuxAxes() ;
- return bOk ;
- }
- // chiamo la funzione
- bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_START) ;
- // con errore, esco
- if ( ! bOk) {
- ResetAuxAxes() ;
- return false ;
- }
-
- // verifico codice di errore
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- if ( nErr != 0)
- return false ;
-
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
-
- // reset assi ausiliari
- ResetAuxAxes() ;
-
- // recupero i dati di ritorno
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_MASK, m_nAxesMask) ;
- if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ENABAXES, m_bEnabAxes))
- m_bEnabAxes = true ;
- if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SHOWAXES, m_bShowAxes))
- m_bShowAxes = m_bEnabAxes ;
- int nNumAuxAxes = 0 ;
- if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
- return true ;
- m_AuxAxesName.reserve( nNumAuxAxes) ;
- m_AuxAxesToken.reserve( nNumAuxAxes) ;
- m_AuxAxesInvert.reserve( nNumAuxAxes) ;
- m_AuxAxesOffset.reserve( nNumAuxAxes) ;
- m_AuxAxesLinear.reserve( nNumAuxAxes) ;
- m_AuxAxesVal.reserve( nNumAuxAxes) ;
- m_AuxAxesEnd.reserve( nNumAuxAxes) ;
- for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
- string sName ; string sToken ; bool bInvert ; double dOffset ; bool bLinear ; double dVal ; double dEnd ; string sLink ;
- string sAuxAxVal = GLOB_VAR + GVAR_AN ; ReplaceString( sAuxAxVal, "N", ToString( i)) ;
- string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
- string sAuxAxMaster = GLOB_VAR + GVAR_ANM ; ReplaceString( sAuxAxMaster, "N", ToString( i)) ;
- if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
- m_pMachine->GetAxisToken( sName, sToken) &&
- m_pMachine->GetAxisInvert( sName, bInvert) &&
- m_pMachine->GetAxisOffset( sName, dOffset) &&
- m_pMachine->GetAxisType( sName, bLinear) &&
- m_pMachine->GetAxisPos( sName, dVal)) {
- // se assi principali abilitati e da agganciare ad asse principale
- if ( m_bEnabAxes && m_pMachine->LuaGetGlobVar( sAuxAxMaster, sLink)) {
- bool bNeg = ( sLink.find( '-') != string::npos) ;
- string sMainAxis = sLink ; ReplaceString( sMainAxis, "-", "") ;
- int nInd = 0 ;
- for ( int i = 0 ; nInd == 0 && i < int( m_AxesName.size()) ; ++ i) {
- if ( m_AxesName[i] == sMainAxis)
- nInd = i + 1 ;
- }
- // se trovato asse principale di riferimento
- if ( nInd > 0) {
- m_AuxAxesName.emplace_back( sName) ;
- m_AuxAxesToken.emplace_back( sToken) ;
- m_AuxAxesInvert.push_back( bInvert) ;
- m_AuxAxesOffset.push_back( dOffset) ;
- m_AuxAxesLinear.push_back( bLinear) ;
- m_AuxAxesVal.emplace_back( 0) ;
- m_AuxAxesEnd.emplace_back( 0) ;
- m_AuxAxesLink.emplace_back( ( bNeg ? -nInd : nInd)) ;
- }
- }
- // se altrimenti specificato valore finale del movimento
- else if ( m_pMachine->LuaGetGlobVar( sAuxAxVal, dEnd)) {
- // se assi principali disabilitati o non è tra questi, lo aggiungo
- if ( ! m_bEnabAxes || find( m_AxesName.begin(), m_AxesName.end(), sName) == m_AxesName.end()) {
- m_AuxAxesName.emplace_back( sName) ;
- m_AuxAxesToken.emplace_back( sToken) ;
- m_AuxAxesInvert.push_back( bInvert) ;
- m_AuxAxesOffset.push_back( dOffset) ;
- m_AuxAxesLinear.push_back( bLinear) ;
- m_AuxAxesVal.emplace_back( dVal) ;
- m_AuxAxesEnd.emplace_back( dEnd) ;
- m_AuxAxesLink.emplace_back( 0) ;
- if ( ! m_pMachine->VerifyOutstroke( sName, dEnd)) {
- nErr = 1 ;
- bOk = false ;
- }
- }
- }
- // altrimenti errore
- else
- bOk = false ;
- }
- else
- bOk = false ;
- }
-
- return bOk ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnMoveEnd( int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_END))
- return true ;
- // reset errore
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
- return false ;
- // chiamo la funzione
- bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_END) ;
- // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
- UpdateAxesPos() ;
- // verifico codice di errore
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- return ( bOk && nErr == 0) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnCollision( int nCdInd, int nObjInd, int& nErr)
-{
- // reset stato di errore da script
- nErr = 0 ;
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_COLLISION))
- return true ;
- // reset stato di errore
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
- return false ;
- // assegno identificativi grezzo e oggetto in collisione
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMVMID, m_CdId[nCdInd]))
- return false ;
- if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMCOBIND, m_CollObj[nObjInd].nInd))
- return false ;
- // chiamo la funzione
- if ( ! m_pMachine->LuaCallFunction( ON_SIMUL_COLLISION))
- return false ;
- // verifico codice di errore
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- // l'errore standard di collisione è stato portato da 1 a 11 per non collidere con altri tipi di errori
- if ( nErr == 1) {
- nErr = ERR_COLLISION ;
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- }
- // evidenzio le geometrie in collisione
- if ( nErr == ERR_COLLISION) {
- SetCollisionMark( nCdInd, nObjInd) ;
- ExeDraw() ;
- }
-
- return ( nErr == 0) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::OnResetMachine( void)
-{
- // verifico esistenza funzione
- if ( ! m_pMachine->LuaExistsFunction( ON_RESET_MACHINE))
- return true ;
- // eseguo reset macchina
- return m_pMachine->LuaCallFunction( ON_RESET_MACHINE) ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType, const Vector3d& vtMove, double dPar1, double dPar2, double dPar3)
-{
- // verifiche sui parametri
- if ( nInd <= 0 || nFrameId <= GDB_ID_NULL)
- return false ;
- switch ( nType) {
- case MCH_SIM_COB_BOX :
- if ( abs( dPar1) < EPS_SMALL || abs( dPar2) < EPS_SMALL || abs( dPar3) < EPS_SMALL)
- return false ;
- break ;
- case MCH_SIM_COB_CYL :
- if ( dPar1 < EPS_SMALL || abs( dPar2) < EPS_SMALL)
- return false ;
- break ;
- case MCH_SIM_COB_SPHE :
- if ( dPar1 < EPS_SMALL)
- return false ;
- break ;
- case MCH_SIM_COB_CONE :
- if ( ( dPar1 < EPS_SMALL && dPar2 < EPS_SMALL) || dPar3 < EPS_SMALL)
- return false ;
- break ;
- case MCH_SIM_COB_POLY :
- if ( ! ExeSurfIsClosed( nFrameId))
- return false ;
- break ;
- default :
- return false ;
- }
- // aggiungo al vettore
- m_CollObj.emplace_back( nInd, bToolOn, nFrameId, nType, vtMove, dPar1, dPar2, dPar3) ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::SetToolForVmill( const string& sTool, const string& sHead, int nExit, int nFlag, double dPar1, double dPar2,
- const INTVECTOR& vVmill, bool bFirst)
-{
- // disabilito eventuale registrazione comandi EXE (riabilitazione automatica)
- CmdLogOff cmdLogOff ;
- // se vVmill vuoto, esco
- if ( vVmill.empty())
- return true ;
- // se utensile, testa o uscita non definiti, reset ed esco
- if ( IsEmptyOrSpaces( sTool) || IsEmptyOrSpaces( sHead) || nExit < 1) {
- ExeVolZmapResetTools( vVmill) ;
- if ( bFirst)
- m_bEnableVm = false ;
- return false ;
- }
- // imposto utensile come corrente
- string sOldTool ; m_pMchMgr->TdbGetCurrToolParam( TPA_NAME, sOldTool) ;
- if ( sTool != sOldTool && ! m_pMchMgr->TdbSetCurrTool( sTool)) {
- ExeVolZmapResetTools( vVmill) ;
- if ( bFirst)
- m_bEnableVm = false ;
- return false ;
- }
- // recupero dati utensile
- int nInd = 1 ;
- int nType ; m_pMchMgr->TdbGetCurrToolParam( TPA_TYPE, nType) ;
- double dLen ; m_pMchMgr->TdbGetCurrToolParam( TPA_LEN, dLen) ;
- double dDiam ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, dDiam) ;
- double dThick ; m_pMchMgr->TdbGetCurrToolParam( TPA_THICK, dThick) ;
- double dCornR ; m_pMchMgr->TdbGetCurrToolParam( TPA_CORNRAD, dCornR) ;
- double dSideAng ; m_pMchMgr->TdbGetCurrToolParam( TPA_SIDEANG, dSideAng) ;
- double dMaxMat ; m_pMchMgr->TdbGetCurrToolParam( TPA_MAXMAT, dMaxMat) ;
- string sNotes ; m_pMchMgr->TdbGetCurrToolParam( TPA_USERNOTES, sNotes) ;
- bool bAdditive = ( nFlag == 1) ;
- // ricerca dell'outline e del diametro gambo
- int nExitId = m_pMachine->GetExitId( sHead, nExit) ;
- int nToolId = m_pGeomDB->GetFirstNameInGroup( nExitId, sTool) ;
- int nOutlineId = m_pGeomDB->GetFirstNameInGroup( nToolId, "Outline") ;
- double dMaxStemDiam = dDiam ; m_pGeomDB->GetInfo( nToolId, "D_STEM", dMaxStemDiam) ;
- // imposto profilo utensile per Vmill
- if ( bAdditive)
- ExeVolZmapSetAdditiveTool( vVmill, sTool, dPar1, dPar2, 0, nInd, bFirst) ;
- else if ( nOutlineId != GDB_ID_NULL)
- ExeVolZmapSetGenTool( vVmill, sTool, nOutlineId, nInd, bFirst) ;
- else if ( nType == TT_MORTISE_STD)
- ExeVolZmapSetMortiserTool( vVmill, sTool, dLen, dDiam, dThick, dCornR, nInd, bFirst) ;
- else if ( nType == TT_CHISEL_STD)
- ExeVolZmapSetChiselTool( vVmill, sTool, dLen, dDiam, dDiam, nInd, bFirst) ;
- else if ( nType == TT_SAW_STD || nType == TT_SAW_FLAT)
- ExeVolZmapSetSawTool( vVmill, sTool, dLen, dDiam, dThick, 0, dCornR, nInd, bFirst) ;
- else if ( nType == TT_WATERJET)
- ExeVolZmapSetStdTool( vVmill, sTool, dLen + 50, dDiam, dCornR, dMaxMat, nInd, bFirst) ;
- else if ( abs( dSideAng) < EPS_ANG_SMALL || abs( dThick) < EPS_SMALL) {
- ExeVolZmapSetStdTool( vVmill, sTool, dLen, dDiam, dCornR, dMaxMat, nInd, bFirst) ;
- }
- else {
- bool bExtra = ( dThick > 0) ;
- double dTipLen = abs( dThick) ;
- double dTotLen = ( bExtra ? dLen + dTipLen : dLen) ;
- double dDelta ;
- if ( dSideAng > 0) {
- if ( dCornR < EPS_SMALL)
- dDelta = 2 * dTipLen * tan( dSideAng * DEGTORAD) ;
- else
- dDelta = 2 * ( dCornR * cos( dSideAng * DEGTORAD) + ( dTipLen - dCornR + dCornR * sin( dSideAng * DEGTORAD)) * tan( dSideAng * DEGTORAD)) ;
- }
- else
- dDelta = 2 * tan( dSideAng * DEGTORAD) * dTipLen ;
- double dStemDiam = ( bExtra ? dDiam : dDiam + dDelta) ;
- double dTipDiam = ( bExtra ? dDiam - dDelta : dDiam) ;
- ExeVolZmapSetAdvTool( vVmill, sTool, dTotLen, dStemDiam, dTipLen, dTipDiam, dCornR, dMaxMat, nInd, bFirst) ;
- }
- // eventuali offset per Vmill (per adattare lo ZeroT macchina con quello di Zmap)
- double dVmTdOffs = 0 ;
- double dVmAdOffs = 0 ;
- if ( nType == TT_MORTISE_STD) {
- dVmTdOffs = 0 ;
- dVmAdOffs = 0.5 * dThick ;
- }
- else if ( nType == TT_SAW_STD || nType == TT_SAW_FLAT) {
- dVmTdOffs = ( ( dLen <= dThick) ? -dLen + dThick : 0) ;
- dVmAdOffs = 0 ;
- }
- // inserisco in lista utensili per virtual milling
- if ( bFirst) {
- m_VmTool.resize( 1) ;
- m_VmTool[0] = VmTool( sTool, sHead, nExit, dVmTdOffs, dVmAdOffs) ;
- }
- else
- m_VmTool.emplace_back( sTool, sHead, nExit, dVmTdOffs, dVmAdOffs) ;
- // ripristino eventuale diverso utensile corrente
- if ( sTool != sOldTool)
- m_pMchMgr->TdbSetCurrTool( sOldTool) ;
-
- if ( bFirst)
- m_bEnableVm = true ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-bool
-Simulator::EnableToolsForVmill( bool bEnable)
-{
- m_bEnableVm = bEnable ;
- return true ;
-}
-
-//----------------------------------------------------------------------------
-int
-Simulator::MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt)
-{
- // Salvo lo step di simulazione corrente
- double dOrigStep = m_dStep ;
- // Verifico ci siano assi da muovere
- if ( vAxNaEpSt.empty())
- return SIM_AXMV_RES_ERR ;
- // Tipo di cinematica
- bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
- // Numero assi da muovere
- int nAxCount = int( vAxNaEpSt.size()) ;
- // Posizioni iniziali
- DBLVECTOR vPrev( nAxCount) ;
- for ( int i = 0 ; i < nAxCount ; ++ i) {
- if ( ! m_pMchMgr->GetAxisPos( vAxNaEpSt[i].sName, vPrev[i]))
- return SIM_AXMV_RES_ERR ;
- }
- // Posizione e direzione attuali degli utensili e riferimenti dei pezzi (per Vmill)
- bool bExecVmill = (( nMoveType != 0 || ! NeedCollisionCheck()) && ! m_VmTool.empty() && ! m_VmId.empty()) ;
- PNTVECTOR vPtNoseI ;
- VCT3DVECTOR vVtDirI ;
- VCT3DVECTOR vVtAuxI ;
- vector vFrVzmI ;
- if ( bExecVmill) {
- vPtNoseI.resize( m_VmTool.size()) ;
- vVtDirI.resize( m_VmTool.size()) ;
- vVtAuxI.resize( m_VmTool.size()) ;
- vFrVzmI.resize( m_VmId.size()) ;
- bool bOkI = true ;
- for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i)
- bOkI = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, vPtNoseI[i], vVtDirI[i], vVtAuxI[i]) && bOkI ;
- for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
- bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
- }
- // Determino gli step di movimento
- static const int STEP_FEED = -1 ;
- static const int STEP_RAPID = -2 ;
- static const int STEP_RAPROT = -3 ;
- static const int STEP_COLLROT = -4 ;
- bool bViewAllFrames = true ;
- int nStep = 1 ;
- for ( int i = 0 ; i < nAxCount ; ++ i) {
- double dMove = abs( vAxNaEpSt[i].dEndPos - vPrev[i]) ;
- double dStep = vAxNaEpSt[i].dStep ;
- if ( dStep < 0) {
- if ( abs( dStep - STEP_FEED) < EPS_SMALL)
- dStep = m_dStep ;
- else if ( abs( dStep - STEP_RAPID) < EPS_SMALL)
- dStep = 4 * m_dStep ;
- else if ( abs( dStep - STEP_RAPROT) < EPS_SMALL) {
- dStep = 0.4 * m_dStep ;
- bViewAllFrames = ( bIsRobot ? true : false) ;
- }
- else { // STEP_COLLROT
- dStep = min( 0.4 * m_dStep, 10.) ;
- bViewAllFrames = ( bIsRobot ? true : false) ;
- }
- }
- dStep = max( dStep, 1.) ;
- int nAxStep = int( dMove / dStep) + 1 ;
- nStep = max( nStep, nAxStep) ;
- }
- // Eseguo il movimento
- for ( int i = 1 ; i <= nStep ; ++ i) {
- // Muovo
- bool bMoveOk = true ;
- double dCoeff = double( i) / nStep ;
- for ( int j = 0 ; j < nAxCount ; ++ j) {
- bMoveOk = m_pMchMgr->SetAxisPos( vAxNaEpSt[j].sName, ( 1 - dCoeff) * vPrev[j] + dCoeff * vAxNaEpSt[j].dEndPos) && bMoveOk ;
- }
- // Se abilitato e richiesto, eseguo eventuale Vmill
- if ( m_bEnableVm && bExecVmill) {
- for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
- Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
- bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
- for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
- Frame3d frVzmF ;
- bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
- ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
- vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
- // se ultimo utensile, salvo riferimento per prossimo inizio
- if ( j == int( m_VmTool.size()) - 1)
- vFrVzmI[k] = frVzmF ;
- }
- // aggiorno prossimo inizio
- vPtNoseI[j] = ptNoseF ;
- vVtDirI[j] = vtDirF ;
- vVtAuxI[j] = vtAuxF ;
- }
- }
- // Aggiorno visualizzazione
- if ( bViewAllFrames || ( i % 4) == 0 || i == nStep)
- ExeDraw() ;
- // Verifico collisioni
- int nCdInd, nObjInd ;
- bool bCollCheck = ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
- if ( ! bCollCheck) {
- // Richiamo funzione di convalida collisione
- int nPrevErr ;
- m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nPrevErr) ;
- int nErr ;
- if ( ! OnCollision( nCdInd, nObjInd, nErr) && nErr == ERR_COLLISION) {
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
- if ( ExeGetEnableUI()) {
- // Box di messaggio : Collisione! AVVERTIMENTO
- ExeMessageBox( ExeGetMsg( 5319), ExeGetMsg( 5315), MB_OK | MB_ICONWARNING) ;
- // Gestione Pausa
- m_nUiStatus = MCH_UISIM_PAUSE ;
- while ( m_nUiStatus == MCH_UISIM_PAUSE) {
- // -11 notifica al simulatore pausa dopo collisione
- ExeProcessEvents( -11, 4) ;
- }
- }
- }
- else {
- m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nPrevErr) ;
- }
- }
- // In caso di errore esco
- if ( ! bMoveOk)
- return SIM_AXMV_RES_ERR ;
- // Gestione aggiornamenti...
- if ( ExeGetEnableUI()) {
- // Aggiornamento interfaccia
- ExeProcessEvents( 0, 4) ;
- while ( m_nUiStatus == MCH_UISIM_PAUSE) {
- ExeProcessEvents( 0, 4) ;
- }
- // Gestione Stop
- if ( m_nUiStatus == MCH_UISIM_STOP)
- return SIM_AXMV_RES_STOP ;
- // Se cambia lo step di simulazione in modo significativo ...
- if ( abs( m_dStep - dOrigStep) > 10 || abs( ( m_dStep - dOrigStep) / ( m_dStep + dOrigStep)) > 0.2) {
- double dRat = m_dStep / dOrigStep ;
- for ( int j = 0 ; j < nAxCount ; ++ j) {
- if ( vAxNaEpSt[j].dStep > 0)
- const_cast( vAxNaEpSt[j].dStep) *= dRat ;
- }
- return MoveAxes( nMoveType, vAxNaEpSt) ;
- }
- }
- }
-
- return SIM_AXMV_RES_OK ;
-}
+//----------------------------------------------------------------------------
+// EgalTech 2015-2024
+//----------------------------------------------------------------------------
+// File : SimulatorSP.cpp Data : 01.09.24 Versione : 2.6i1
+// Contenuto : Implementazione della classe SimulatorSP.
+// Simulatore singolo processo.
+//
+//
+// Modifiche : 19.10.15 DS Creazione modulo.
+// 26.02.16 DS Aggiunta gestione archi.
+// 04.01.17 DS Riorganizzazione codice.
+// 01.09.24 DS Rinominato.
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "SimulatorSP.h"
+#include "MachMgr.h"
+#include "Disposition.h"
+#include "Machining.h"
+#include "MachiningConst.h"
+#include "OutputConst.h"
+#include "DllMain.h"
+#include "/EgtDev/Include/EGkCDeBoxClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeCylClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeSpheClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeConeFrustumClosedSurfTm.h"
+#include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h"
+#include "/EgtDev/Include/EGkVolZmap.h"
+#include "/EgtDev/Include/EGkGeoVector3d.h"
+#include "/EgtDev/Include/EGkStringUtils3d.h"
+#include "/EgtDev/Include/EGkSurfLocal.h"
+#include "/EgtDev/Include/EXeCmdLogOff.h"
+#include "/EgtDev/Include/EXeConst.h"
+#include "/EgtDev/Include/EMkToolConst.h"
+#include "/EgtDev/Include/EMkOperationConst.h"
+#include "/EgtDev/Include/EgtPerfCounter.h"
+#include "/EgtDev/Include/EgtNumUtils.h"
+
+using namespace std ;
+
+//------------------------------ Errors --------------------------------------
+// 1001 = "Error with setup : xxx"
+
+//----------------------------------------------------------------------------
+static const double MIN_STEP = 1.0 ;
+static const double MAX_STEP = 500.0 ;
+static const double MID_STEP = 50.0 ;
+static const double COLL_STEP = 10. ;
+static const double SQ_COEFF_ROT_MOVE = 100. ;
+static const double COEFF_LIM = 0.999 ;
+static const double SAFEDIST_STD = 5.0 ;
+static const int ERR_OUTSTROKE = 1 ;
+static const int ERR_COLLISION = 11 ;
+static const int ERR_TOOL_SEL = 21 ;
+
+//----------------------------------------------------------------------------
+ISimulator*
+CreateSimulatorSP( void)
+{
+ return static_cast ( new( nothrow) SimulatorSP) ;
+}
+
+//----------------------------------------------------------------------------
+SimulatorSP::SimulatorSP( void)
+{
+ m_pMchMgr = nullptr ;
+ m_pGeomDB = nullptr ;
+ m_pMachine = nullptr ;
+ m_pPerfCnt = nullptr ;
+ m_nStatus = SIS_CREATED ;
+ m_dStep = MID_STEP ;
+ m_nUiStatus = MCH_UISIM_NULL ;
+ m_nOpId = GDB_ID_NULL ;
+ m_nOpInd = 0 ;
+ m_nCLPathId = GDB_ID_NULL ;
+ m_nCLPathInd = 0 ;
+ m_nEntId = GDB_ID_NULL ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ m_nExit = 0 ;
+ m_dTDiam = 0 ;
+ m_bCutOnTip = false ;
+ m_bEnableVm = false ;
+ m_dSafeDist = SAFEDIST_STD ;
+ m_nAxesMask = 0 ;
+ m_bEnabAxes = true ;
+ m_bShowAxes = true ;
+ m_AxesName.reserve( 8) ;
+ m_AxesToken.reserve( 8) ;
+ m_AxesLinear.reserve( 8) ;
+ m_AxesVal.reserve( 8) ;
+}
+
+//----------------------------------------------------------------------------
+SimulatorSP::~SimulatorSP( void)
+{
+ // porto la macchina in posizione home
+ GoHome() ;
+ // gestione evento uscita dal simulatore
+ OnExit() ;
+ // rimuovo tavola variabili globali
+ m_pMachine->LuaResetGlobVar( GLOB_VAR) ;
+ // rimuovo performance counter
+ if ( m_pPerfCnt != nullptr) {
+ delete m_pPerfCnt ;
+ m_pPerfCnt = nullptr ;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::Init( MachMgr* pMchMgr)
+{
+ // verifico ambiente
+ if ( pMchMgr == nullptr || pMchMgr->GetContextId() == 0 ||
+ pMchMgr->GetGeomDB() == nullptr || pMchMgr->GetCurrMachine() == nullptr)
+ return false ;
+ m_pMchMgr = pMchMgr ;
+ m_pGeomDB = m_pMchMgr->GetGeomDB() ;
+ m_pMachine = m_pMchMgr->GetCurrMachine() ;
+ m_pPerfCnt = new PerformanceCounter ;
+ m_nStatus = SIS_INITIALIZED ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::Start( bool bFirst)
+{
+ // Verifico ci sia una macchinata corrente
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr || m_pMachine == nullptr ||
+ m_pMchMgr->GetCurrMachGroup() == GDB_ID_NULL)
+ return false ;
+ m_pMchMgr->ResetLastError() ;
+ m_pMchMgr->ResetWarnings() ;
+
+ bool bOk = true ;
+
+ // Se appena entrati in simulazione
+ if ( m_nStatus == SIS_INITIALIZED) {
+ // Forzo aggiornamento attrezzaggio della macchinata
+ if ( ! m_pMchMgr->UpdateCurrSetup())
+ bOk = false ;
+ // Verifico attrezzaggio
+ if ( ! VerifySetup())
+ bOk = false ;
+ }
+
+ // Reset utensile, interpolazione e assi correnti
+ m_sTool.clear() ;
+ m_sHead.clear() ;
+ m_nExit = 0 ;
+ m_dTDiam = 0 ;
+ m_bCutOnTip = false ;
+ ResetInterpolation() ;
+ ResetAxes() ;
+ ResetAuxAxes() ;
+
+ // porto la macchina in home
+ if ( ! GoHome())
+ bOk = false ;
+
+ // Verifico la disposizione iniziale della macchinata
+ m_nOpId = m_pMchMgr->GetFirstActiveOperation() ;
+ m_nOpInd = 1 ;
+ if ( m_pMchMgr->GetOperationType( m_nOpId) != OPER_DISP)
+ bOk = false ;
+
+ // Definisco tabella variabili globali
+ if ( ! m_pMachine->LuaCreateGlobTable( GLOB_VAR))
+ bOk = false ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_INCHES, ! ExeUiUnitsAreMM()) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_VER, GetEMkVer()) ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MACHNAME, m_pMachine->GetMachineName()) ;
+
+ // Se appena entrati in simulazione
+ if ( m_nStatus == SIS_INITIALIZED) {
+ if ( ! OnInit())
+ bOk = false ;
+ m_nStatus = SIS_READYTOSTART ;
+ }
+
+ // Richiamo funzione per evento avvio simulazione
+ if ( ! OnProgramStart( bFirst))
+ bOk = false ;
+
+ // Arrivo alla preparazione per la prima lavorazione
+ int nStatus ;
+ if ( ! FindAndManageOperationStart( true, bFirst, nStatus) && nStatus != MCH_SIM_STOP)
+ bOk = false ;
+ // se sono ancora su disposizione
+ if ( m_pMchMgr->GetOperationType( m_nOpId) == OPER_DISP) {
+ // ricerca e gestione inizio percorso di lavoro
+ if ( ! FindAndManagePathStart( nStatus))
+ return false ;
+ // eventuali comandi ausiliari di inizio percorso
+ while ( m_nAuxSInd < m_nAuxSTot) {
+ if ( ! ManagePathStartAux( nStatus))
+ return false ;
+ }
+ // aggiornamento assi per eventuali teste caricate
+ UpdateAxes() ;
+ }
+
+ // Reset timer
+ if ( m_pPerfCnt != nullptr)
+ m_pPerfCnt->Start() ;
+
+ // Imposto lo stato interno
+ m_nStatus = ( bOk ? SIS_READYTORUN : SIS_READYTOSTART) ;
+
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::VerifySetup( void)
+{
+ // se attrezzaggio non definito, nulla da verificare
+ if ( ! m_pMchMgr->GetCurrSetupMgr().Exists())
+ return true ;
+
+ // lancio la verifica
+ STRVECTOR vsErr ;
+ if ( m_pMchMgr->VerifyCurrSetup( vsErr))
+ return true ;
+
+ // gestisco errore
+ string sErr = "Error with setup :" ;
+ for ( const auto& sTmp : vsErr)
+ sErr += " " + sTmp ;
+ m_pMchMgr->SetLastError( 1001, sErr) ;
+ return false ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ResetInterpolation( void)
+{
+ m_nOpId = GDB_ID_NULL ;
+ m_nOpInd = 0 ;
+ m_nCLPathId = GDB_ID_NULL ;
+ m_nCLPathInd = 0 ;
+ m_nEntId = GDB_ID_NULL ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ m_VmId.clear() ;
+ m_CdId.clear() ;
+ m_VmTool.clear() ;
+ m_CollObj.clear() ;
+ m_dSafeDist = SAFEDIST_STD ;
+ m_nAxesMask = 0 ;
+ m_bEnabAxes = true ;
+ m_bShowAxes = true ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::Move( int& nStatus)
+{
+ // Verifiche
+ if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr || m_nStatus != SIS_READYTORUN) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+
+ // Recupero tempo impiegato (calcolo + visualizzazione precedenti)
+ if ( m_pPerfCnt != nullptr && ExeGetDebugLevel() >= 5) {
+ double dElapsed = m_pPerfCnt->Stop() ;
+ string sOut = "Elapsed=" + ToString( dElapsed, 1) ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ m_pPerfCnt->Start() ;
+ }
+
+ // reset visualizzazione collisioni
+ ResetCollisionMark() ;
+
+ // Se arrivato alla fine dell'interpolazione
+ if ( m_dCoeff > COEFF_LIM) {
+ // recupero una nuova entità
+ m_nEntId = m_pGeomDB->GetNext( m_nEntId) ;
+ m_dCoeff = 0 ;
+ }
+
+ // Se appena arrivato alla fine di un percorso di lavoro (verifico anche completamento dei comandi aux di start per path vuote)
+ if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd == 0 && m_nCLPathInd > 0 && m_nAuxSInd >= m_nAuxSTot) {
+ // gestione fine percorso di lavoro
+ if ( ! ManagePathEnd( nStatus))
+ return false ;
+ }
+
+ // Se alla fine del percorso dopo esecuzione azioni ausiliarie (verifico anche completamento dei comandi aux di start per path vuote)
+ if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd >= m_nAuxETot && m_nAuxSInd >= m_nAuxSTot) {
+ // ricerca e gestione inizio percorso di lavoro
+ if ( ! FindAndManagePathStart( nStatus))
+ return false ;
+ }
+
+ // Se arrivato alla fine di una operazione
+ if ( m_nCLPathId == GDB_ID_NULL) {
+ // gestione fine operazione
+ if ( ! ManageOperationEnd( nStatus))
+ return false ;
+ // ricerca e gestione nuova operazione
+ if ( ! FindAndManageOperationStart( false, false, nStatus))
+ return false ;
+ // se non ce ne sono altre, sono alla fine
+ if ( m_nOpId == GDB_ID_NULL) {
+ OnProgramEnd() ;
+ nStatus = MCH_SIM_END ;
+ return false ;
+ }
+ // ricerca e gestione inizio percorso di lavoro
+ if ( ! FindAndManagePathStart( nStatus))
+ return false ;
+ }
+
+ // Se sto eseguendo i movimenti ausiliari di inizio percorso
+ if ( m_nAuxSInd < m_nAuxSTot)
+ return ManagePathStartAux( nStatus) ;
+
+ // Se sto eseguendo i movimenti ausiliari di fine percorso
+ if ( m_nAuxEInd < m_nAuxETot)
+ return ManagePathEndAux( nStatus) ;
+
+ // Gestione movimento assi
+ return ManageMove( nStatus) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::GetAxisInfoPos( int nI, string& sName, string& sToken, bool& bLinear, double& dVal) const
+{
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // numero assi di calcolo e ausiliari
+ int nAxisCount = ( m_bShowAxes ? int( m_AxesName.size()) : 0) ;
+ int nAuxAxisCount = int( m_AuxAxesName.size()) ;
+ // recupero i dati dell'asse
+ if ( nI < 0 || nI >= nAxisCount + nAuxAxisCount)
+ return false ;
+ // se asse principale
+ if ( nI < nAxisCount) {
+ sName = m_AxesName[nI] ;
+ sToken = m_AxesToken[nI] ;
+ bLinear = m_AxesLinear[nI] ;
+ }
+ // altrimenti asse ausiliario
+ else {
+ sName = m_AuxAxesName[ nI - nAxisCount] ;
+ sToken = m_AuxAxesToken[ nI - nAxisCount] ;
+ bLinear = m_AuxAxesLinear[ nI - nAxisCount] ;
+ }
+ // recupero la posizione
+ if ( ! m_pMchMgr->GetAxisPos( sName, dVal))
+ return false ;
+ // verifico se da invertire o offsettare
+ if ( nI < nAxisCount) {
+ if ( m_AxesInvert[nI])
+ dVal = - dVal ;
+ dVal += m_AxesOffset[nI] ;
+ }
+ else {
+ if ( m_AuxAxesInvert[nI - nAxisCount])
+ dVal = - dVal ;
+ dVal += m_AxesOffset[nI - nAxisCount] ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::GetToolInfo( string& sName, double& dSpeed) const
+{
+ // Inizializzo i parametri di ritorno
+ sName.clear() ;
+ dSpeed = 0 ;
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // Assegno il nome dell'utensile
+ sName = m_sTool ;
+ if ( sName.empty())
+ return true ;
+ // Recupero speed
+ const Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ return ( pMch != nullptr && pMch->GetParam( MPA_SPEED, dSpeed)) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::GetOperationInfo( string& sName, int& nType) const
+{
+ // Inizializzo i parametri di ritorno
+ sName.clear() ;
+ nType = OPER_NULL ;
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // Recupero il tipo
+ Operation* pOpe = GetOperation( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pOpe == nullptr)
+ return false ;
+ nType = pOpe->GetType() ;
+ // Recupero il nome
+ return m_pGeomDB->GetName( m_nOpId, sName) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::GetMoveInfo( int& nGmove, double& dFeed) const
+{
+ // Verifiche
+ if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
+ return false ;
+ // Recupero il movimento corrente
+ const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
+ if ( pCamData == nullptr)
+ return false ;
+ // Assegno feed
+ dFeed = pCamData->GetFeed() ;
+ // Assegno tipo di movimento
+ nGmove = pCamData->GetMoveType() ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::SetStep( double dStep)
+{
+ m_dStep = Clamp( dStep, MIN_STEP, MAX_STEP) ;
+ // imposto step per movimenti gestiti nelle macro di simulazione ( con ripristino macchina Lua originale)
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::SetUiStatus( int nUiStatus)
+{
+ m_nUiStatus = nUiStatus ;
+ // imposto stato utente del simulatore per movimenti gestiti nelle macro di simulazione ( con ripristino macchina Lua originale)
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMUISTAT, m_nUiStatus) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::GoHome( void)
+{
+ // controllo validità stato
+ if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr)
+ return false ;
+ // reset visualizzazione collisioni
+ ResetCollisionMark() ;
+ // reset stato macchina
+ OnResetMachine() ;
+ // porto la macchina in home
+ m_pMchMgr->ResetAllAxesPos() ;
+ // assegno valori home degli assi macchina attivi
+ return m_pMchMgr->GetAllCurrAxesHomePos( m_AxesVal) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::UpdateTool( bool bFirst, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // Recupero l'utensile della lavorazione corrente
+ Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pMch != nullptr) {
+ // recupero nome e dati nuovo utensile
+ string sTuuid, sTool ;
+ if ( ! pMch->GetParam( MPA_TUUID, sTuuid) ||
+ ! m_pMchMgr->TdbGetToolFromUUID( sTuuid, sTool))
+ return false ;
+ string sTcPos ; string sHead ; int nExit ;
+ if ( ! m_pMchMgr->GetCurrSetupMgr().GetToolData( sTool, sTcPos, sHead, nExit)) {
+ if ( m_pMchMgr->TdbSetCurrTool( sTool)) {
+ m_pMchMgr->TdbGetCurrToolParam( TPA_TCPOS, sTcPos) ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_HEAD, sHead) ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_EXIT, nExit) ;
+ }
+ // ripristino l'utensile corrente
+ m_pMchMgr->TdbSetCurrTool( m_sTool) ;
+ }
+ // verifico se cambierà
+ bool bDiffTool = ( sTool != m_sTool) ;
+ // se cambierà ed esiste il corrente, lo scarico
+ if ( bDiffTool && ! m_sTool.empty()) {
+ // eventuale lancio script per scarico utensile
+ int nCurrErr ;
+ if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos, nCurrErr)) {
+ nErr = ( nErr != 0 ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ }
+ // se prima volta, pulisco la testa
+ if ( bFirst)
+ m_pMchMgr->ResetHeadSet( sHead) ;
+ // recupero la lavorazione corrente e imposto la nuova
+ int nCurrMchId = m_pMchMgr->GetCurrMachining() ;
+ m_pMchMgr->SetCurrMachining( m_nOpId) ;
+ // carico l'utensile (e lo rendo corrente)
+ if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
+ return false ;
+ m_sTool = sTool ;
+ m_sHead = sHead ;
+ m_nExit = nExit ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ;
+ double dTipFeed = 0 ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ;
+ m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ;
+ // ripristino la lavorazione corrente
+ m_pMchMgr->SetCurrMachining( nCurrMchId) ;
+ // aggiorno gli assi macchina
+ if ( ! UpdateAxes())
+ return false ;
+ // se cambiato oppure prima volta, lancio lo script di selezione
+ if ( bDiffTool || bFirst) {
+ int nCurrErr ;
+ if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst, nCurrErr)) {
+ nErr = ( nErr != 0 ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ }
+ return ( nErr == 0) ;
+ }
+ // Provo con una disposizione
+ Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pDisp != nullptr) {
+ // recupero i dati
+ string sTool ; string sHead ; int nExit ; string sTcPos ;
+ pDisp->GetToolData( sTool, sHead, nExit, sTcPos) ;
+ // se esiste utensile corrente e cambierà, lo scarico
+ if ( ! m_sTool.empty() && sTool != m_sTool) {
+ // eventuale lancio script per scarico utensile
+ int nCurrErr ;
+ if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos, nCurrErr)) {
+ nErr = ( nErr != 0 ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ }
+ // carico l'utensile
+ if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
+ return false ;
+ m_sTool = sTool ;
+ m_sHead = sHead ;
+ m_nExit = nExit ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ;
+ double dTipFeed = 0 ;
+ m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ;
+ m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ;
+ // aggiorno gli assi macchina
+ if ( ! UpdateAxes())
+ return false ;
+ // eventuale lancio script
+ int nCurrErr ;
+ if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst, nCurrErr)) {
+ nErr = ( nErr != 0 ? nErr : nCurrErr) ;
+ if ( nCurrErr != ERR_COLLISION)
+ return false ;
+ }
+ return ( nErr == 0) ;
+ }
+ return false ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::UpdateAxes( void)
+{
+ ResetAxes() ;
+ // Macchina corrente
+ Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
+ if ( pMachine == nullptr)
+ return false ;
+ // Carico i nomi e i token degli assi macchina attivi
+ if ( ! pMachine->GetAllCurrAxesNames( m_AxesName) ||
+ ! pMachine->GetAllCurrAxesTokens( m_AxesToken))
+ return false ;
+ // Aggiorno flag di invertito, offset, tipo e posizione corrente degli assi macchina attivi
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ bool bInvert ;
+ m_pMachine->GetAxisInvert( m_AxesName[i], bInvert) ;
+ m_AxesInvert.push_back( bInvert) ;
+ double dOffset ;
+ m_pMachine->GetAxisOffset( m_AxesName[i], dOffset) ;
+ m_AxesOffset.push_back( dOffset) ;
+ bool bLinear ;
+ m_pMachine->GetAxisType( m_AxesName[i], bLinear) ;
+ m_AxesLinear.push_back( bLinear) ;
+ double dVal ;
+ m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
+ m_AxesVal.emplace_back( dVal) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::UpdateAxesPos( void)
+{
+ // Macchina corrente
+ Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
+ if ( pMachine == nullptr)
+ return false ;
+ // Aggiorno la posizione corrente degli assi macchina attivi
+ m_AxesVal.clear() ;
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ double dVal ;
+ m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
+ m_AxesVal.emplace_back( dVal) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ResetAxes( void)
+{
+ // pulisco dati assi
+ m_AxesName.clear() ;
+ m_AxesToken.clear() ;
+ m_AxesInvert.clear() ;
+ m_AxesLinear.clear() ;
+ m_AxesVal.clear() ;
+ m_nAxesMask = 0 ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ResetAuxAxes( void)
+{
+ // pulisco dati assi ausiliari
+ m_AuxAxesName.clear() ;
+ m_AuxAxesToken.clear() ;
+ m_AuxAxesInvert.clear() ;
+ m_AuxAxesOffset.clear() ;
+ m_AuxAxesLinear.clear() ;
+ m_AuxAxesVal.clear() ;
+ m_AuxAxesEnd.clear() ;
+ m_AuxAxesLink.clear() ;
+ // abilito assi principali
+ m_bEnabAxes = true ;
+ m_bShowAxes = true ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::FindAndManageOperationStart( bool bStart, bool bFirst, int& nStatus)
+{
+ // verifico parametri
+ if ( ! bStart)
+ bFirst = false ;
+ // recupero la nuova operazione
+ if ( bStart) {
+ m_nOpId = m_pMchMgr->GetFirstActiveOperation() ;
+ m_nOpInd = 0 ;
+ }
+ else
+ m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ;
+ // ciclo sulle successive operazioni
+ while ( m_nOpId != GDB_ID_NULL) {
+ // se lavorazione valida
+ Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pMch != nullptr && ! pMch->IsEmpty()) {
+ bool bOk = true ;
+ // aggiorno utensile e assi conseguenti
+ int nErr ;
+ if ( ! UpdateTool( bFirst, nErr)) {
+ string sOut = "Err=" + ToString( nErr) ;
+ LOG_INFO( GetEMkLogger(), sOut.c_str())
+ nStatus = CalcStatusOnError( nErr) ;
+ bOk = false ;
+ }
+ ++ m_nOpInd ;
+ // imposto la lavorazione come corrente
+ m_pMchMgr->SetCurrMachining( m_nOpId) ;
+ // recupero punti di minimo e massimo ingombro
+ int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ;
+ Point3d ptMin, ptMax ;
+ m_pGeomDB->GetInfo( nClId, KEY_MMIN, ptMin) ;
+ m_pGeomDB->GetInfo( nClId, KEY_MMAX, ptMax) ;
+ DBLVECTOR vAxMin, vAxMax ;
+ m_pGeomDB->GetInfo( nClId, KEY_MAXMIN, vAxMin) ;
+ m_pGeomDB->GetInfo( nClId, KEY_MAXMAX, vAxMax) ;
+ // richiamo gestione evento inizio lavorazione
+ if ( ! OnMachiningStart( m_nOpId, m_nOpInd, ptMin, ptMax, vAxMin, vAxMax)) {
+ nStatus = CalcStatusOnError( 0) ;
+ bOk = false ;
+ }
+ if ( ! bOk)
+ return false ;
+ break ;
+ }
+ // se disposizione con cambio di fase
+ Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
+ if ( pDisp != nullptr) {
+ // in alcuni casi la disposizione non è inizializzata
+ pDisp->Init( m_pMchMgr) ;
+ // recupero dati tavola
+ string sTable ;
+ pDisp->GetTable( sTable) ;
+ Point3d ptOri1 ;
+ pDisp->GetTableRef1( ptOri1) ;
+ // recupero la fase della disposizione
+ int nPhase = pDisp->GetPhase() ;
+ // recupero se con movimenti autonomi
+ bool bEmpty = pDisp->IsEmpty() ;
+ // recupero flag disposizione con movimenti manuali
+ bool bSomeByHand = pDisp->GetSomeByHand() ;
+ // se con movimenti autonomi
+ if ( ! bEmpty) {
+ // richiamo gestione evento appena prima di inizio disposizione
+ if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
+ nStatus = CalcStatusOnError( 0) ;
+ return false ;
+ }
+ // cambio fase
+ m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
+ // se previsto, aggiorno utensile e assi conseguenti
+ if ( pDisp->IsWithTool()) {
+ int nErr ;
+ if ( ! UpdateTool( bFirst, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ }
+ ++ m_nOpInd ;
+ // richiamo gestione evento inizio disposizione
+ if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
+ nStatus = CalcStatusOnError( 0) ;
+ return false ;
+ }
+ // se ci sono movimenti manuali, aggiorno visualizzazione e breve pausa (200 ms)
+ if ( bSomeByHand)
+ Sleep( 200) ;
+ break ;
+ }
+ // altrimenti disposizione passiva
+ else {
+ // richiamo gestione evento appena prima di inizio disposizione
+ if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, true, bSomeByHand)) {
+ nStatus = CalcStatusOnError( 0) ;
+ return false ;
+ }
+ // cambio fase
+ m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
+ ++ m_nOpInd ;
+ // richiamo gestione evento inizio e fine disposizione
+ if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, true, bSomeByHand) ||
+ ! OnDispositionEnd()) {
+ nStatus = CalcStatusOnError( 0) ;
+ return false ;
+ }
+ // se non è inizio, aggiorno visualizzazione e breve pausa (200 ms)
+ if ( nPhase != 1) {
+ ExeDraw() ;
+ Sleep( 200) ;
+ }
+ }
+ }
+ // passo alla operazione successiva
+ m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ManageOperationEnd( int& nStatus)
+{
+ bool bOk = false ;
+ // non c'è operazione in corso (solo prima disposizione senza lavorazioni)
+ if ( m_nOpId == GDB_ID_NULL)
+ bOk = true ;
+ // se altrimenti è una lavorazione
+ else if ( GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) {
+ // richiamo gestione evento fine lavorazione
+ bOk = OnMachiningEnd() ;
+ }
+ // se altrimenti è una disposizione
+ else if ( GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) {
+ // richiamo gestione evento fine disposizione
+ bOk = OnDispositionEnd() ;
+ }
+ // gestione stato
+ if ( ! bOk)
+ nStatus = CalcStatusOnError( 0) ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::FindAndManagePathStart( int& nStatus)
+{
+ // se devo cercare il primo nella nuova operazione
+ if ( m_nCLPathId == GDB_ID_NULL) {
+ // aggiorno gli altri dati
+ int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ;
+ m_nCLPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
+ m_nCLPathInd = 0 ;
+ m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ }
+ // altrimenti cerco il successivo nella stessa operazione
+ else {
+ // recupero un nuovo CLpath
+ while ( m_nEntId == GDB_ID_NULL) {
+ m_nCLPathId = m_pGeomDB->GetNextGroup( m_nCLPathId) ;
+ // se non ce ne sono altri, devo passare a una nuova lavorazione
+ if ( m_nCLPathId == GDB_ID_NULL)
+ break ;
+ m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ;
+ m_nEntInd = 0 ;
+ m_dCoeff = 0 ;
+ }
+ }
+ // se trovato nuovo CLpath con entità, gestisco inizio percorso di lavoro
+ if ( m_nEntId != GDB_ID_NULL) {
+ ++ m_nCLPathInd ;
+ // recupero punti di inizio e fine percorso
+ Point3d ptStart ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ;
+ Point3d ptEnd ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_END, ptEnd) ;
+ // recupero versore estrusione associato al percorso (normale al piano di interpolazione)
+ Vector3d vtExtr ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ;
+ // recupero punti di minimo e massimo ingombro
+ Point3d ptMin, ptMax ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ;
+ // Recupero valori degli assi di minimo e massimo ingombro
+ DBLVECTOR vAxMin, vAxMax ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PAXMIN, vAxMin) ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_PAXMAX, vAxMax) ;
+ // recupero massima elevazione
+ double dElev = 0 ;
+ m_pGeomDB->GetInfo( m_nCLPathId, KEY_ELEV, dElev) ;
+ // recupero il numero di eventi ausiliari di inizio
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS_TOT, m_nAuxSTot))
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ // reset numero eventi ausiliari di fine
+ m_nAuxEInd = 0 ;
+ m_nAuxETot = 0 ;
+ // richiamo gestione evento inizio percorso di lavoro
+ if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, m_nAuxSTot, ptStart, ptEnd, vtExtr, ptMin, ptMax, vAxMin, vAxMax, dElev)) {
+ nStatus = CalcStatusOnError( 0) ;
+ return false ;
+ }
+ }
+ // se altrimenti trovato nuovo CL path vuoto
+ else if ( m_nCLPathId != GDB_ID_NULL) {
+ // recupero il numero di eventi ausiliari di inizio
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS_TOT, m_nAuxSTot))
+ m_nAuxSTot = 0 ;
+ m_nAuxSInd = 0 ;
+ // recupero il numero di eventi ausiliari di fine
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE_TOT, m_nAuxETot))
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ManagePathEnd( int& nStatus)
+{
+ // recupero il numero di eventi ausiliari di fine
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE_TOT, m_nAuxETot))
+ m_nAuxETot = 0 ;
+ m_nAuxEInd = 0 ;
+ // richiamo gestione evento fine percorso di lavoro
+ bool bOk = OnPathEnd( m_nAuxETot) ;
+ // gestione stato
+ if ( ! bOk)
+ nStatus = CalcStatusOnError( 0) ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ManagePathStartAux( int& nStatus)
+{
+ // aggiorno indice corrente
+ ++ m_nAuxSInd ;
+ // recupero i dati per l'evento corrente
+ string sAS ;
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AS + ToString( m_nAuxSInd), sAS)) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // richiamo gestione evento ausiliario prima di inizio percorso di lavoro
+ int nErr ;
+ if ( ! OnPathStartAux( m_nAuxSInd, sAS, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ nStatus = MCH_SIM_END_STEP ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ManagePathEndAux( int& nStatus)
+{
+ // aggiorno indice corrente
+ ++ m_nAuxEInd ;
+ // recupero i dati per l'evento corrente
+ string sAE ;
+ if ( ! m_pGeomDB->GetInfo( m_nCLPathId, KEY_AE + ToString( m_nAuxEInd), sAE)) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ // richiamo gestione evento ausiliario dopo fine percorso di lavoro
+ int nErr ;
+ if ( ! OnPathEndAux( m_nAuxEInd, sAE, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ nStatus = MCH_SIM_END_STEP ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ManageMove( int& nStatus)
+{
+ // Imposto lunghezza di movimento effettuata
+ double dCurrMove = 0 ;
+ while ( m_nEntId != GDB_ID_NULL) {
+ // eseguo movimento singolo
+ double dMove ;
+ if ( ! ManageSingleMove( nStatus, dMove))
+ return false ;
+ dCurrMove += dMove ;
+ // se modalità play e fine entità e non raggiunta la lunghezza di movimento voluto
+ if ( m_nUiStatus == MCH_UISIM_PLAY && nStatus == MCH_SIM_END_STEP && dCurrMove < 0.75 * m_dStep) {
+ // recupero una nuova entità
+ m_nEntId = m_pGeomDB->GetNext( m_nEntId) ;
+ m_dCoeff = 0 ;
+ }
+ else
+ break ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ManageSingleMove( int& nStatus, double& dMove)
+{
+ // Recupero posizione finale
+ const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
+ if ( pCamData == nullptr) {
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ switch ( pCamData->GetAxesStatus()) {
+ case CamData::AS_OK :
+ break ;
+ case CamData::AS_OUTSTROKE : {
+ DBLVECTOR OutAxes = pCamData->GetAxesVal() ;
+ for ( size_t i = OutAxes.size() ; i < 5 ; ++ i)
+ OutAxes.emplace_back( 0) ;
+ DBLVECTOR vAng( OutAxes.begin() + 3, OutAxes.end()) ;
+ int nStat ;
+ m_pMachine->VerifyOutstroke( OutAxes[0], OutAxes[1], OutAxes[2], vAng, true, nStat) ;
+ nStatus = MCH_SIM_OUTSTROKE ;
+ return false ; }
+ case CamData::AS_DIR_ERR :
+ nStatus = MCH_SIM_DIR_ERR ;
+ return false ;
+ default :
+ nStatus = MCH_SIM_ERR ;
+ return false ;
+ }
+ DBLVECTOR AxesEnd = pCamData->GetAxesVal() ;
+ // Tipo di movimento
+ int nMoveType = pCamData->GetMoveType() ;
+ // Se inizio di nuova entità, mascheratura movimento
+ if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO)
+ m_nAxesMask = pCamData->GetAxesMask() ;
+ // Se movimento in rapido muovo solo gli assi abilitati dal mask
+ if ( nMoveType == 0) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ if ( ( m_nAxesMask & 1 << i) == 0)
+ AxesEnd[i] = m_AxesVal[i] ;
+ }
+ }
+
+ // Se inizio di nuova entità
+ if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO) {
+ ++ m_nEntInd ;
+ const CamData* pNextCamData = GetCamData( m_pGeomDB->GetUserObj( m_pGeomDB->GetNext( m_nEntId))) ;
+ int nErr ;
+ if ( ! OnMoveStart( pCamData, pNextCamData, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ // Se movimento in rapido aggiorno quote degli assi disabilitati dal mask
+ if ( nMoveType == 0) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ if ( ( m_nAxesMask & 1 << i) == 0)
+ AxesEnd[i] = m_AxesVal[i] ;
+ }
+ }
+ }
+
+ // Posizione e direzione attuali degli utensili e riferimenti dei pezzi (per Vmill)
+ bool bOkI = true ;
+ PNTVECTOR vPtNoseI( m_VmTool.size()) ;
+ VCT3DVECTOR vVtDirI( m_VmTool.size()) ;
+ VCT3DVECTOR vVtAuxI( m_VmTool.size()) ;
+ for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i)
+ bOkI = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, vPtNoseI[i], vVtDirI[i], vVtAuxI[i]) && bOkI ;
+ vector vFrVzmI( m_VmId.size()) ;
+ for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
+ bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
+
+ // Dati per eventuale verifica di collisione
+ int nCdInd, nObjInd ;
+ bool bCollCheck = true ;
+
+ // Eseguo movimento assi principali ed eventuali ausiliari
+ if ( m_bEnabAxes) {
+ // Calcolo distanza di movimento
+ double dSqDist = 0 ;
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
+ // coefficiente moltiplicativo per differenziare assi lineari e rotanti
+ double dSqCoeff = ( m_AxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
+ dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ;
+ }
+ // Calcolo distanza di movimento eventuali assi ausiliari
+ double dSqDistAux = 0 ;
+ for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
+ if ( m_AuxAxesLink[i] != 0)
+ continue ;
+ // coefficiente moltiplicativo per differenziare assi lineari e rotanti
+ double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
+ dSqDistAux += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
+ }
+ // Considero il massimo delle due distanze
+ double dPrevCoeff = m_dCoeff ;
+ double dDist = sqrt( max( dSqDist, dSqDistAux)) ;
+ if ( dDist > EPS_SMALL) {
+ double dStep = min( ( nMoveType == 0 ? 2 : 1) * m_dStep, MAX_STEP) ;
+ int nStep = max( int( dDist / dStep), 1) ;
+ m_dCoeff += 1. / nStep ;
+ if ( m_dCoeff > 1)
+ m_dCoeff = 1 ;
+ }
+ else
+ m_dCoeff = 1 ;
+ dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
+
+ // Log per debug
+ if ( ExeGetDebugLevel() >= 10) {
+ string sOut = "MoveType=" + ToString( nMoveType) + " Coeff=" + ToString( m_dCoeff) ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+
+ // Eseguo movimento rapido o lineare (non arco)
+ if ( nMoveType != 2 && nMoveType != 3) {
+ // se attivo CollisionCheck approssimo movimento con più step
+ int nStep = 1 ;
+ if ( NeedCollisionCheck())
+ nStep = max( int( dMove / COLL_STEP), 1) ;
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
+ DBLVECTOR vDeltaVal( m_AxesName.size()) ;
+ // assegno posizioni finali
+ for ( int j = 0 ; j < int( m_AxesName.size()) ; ++ j) {
+ double dPrevVal ;
+ m_pMachine->GetAxisPos( m_AxesName[j], dPrevVal) ;
+ double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
+ m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
+ vDeltaVal[j] = dVal - dPrevVal ;
+ }
+ // muovo eventuali assi ausiliari
+ for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
+ double dVal = 0 ;
+ if ( m_AuxAxesLink[j] == 0) {
+ dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
+ }
+ else {
+ m_pMachine->GetAxisPos( m_AuxAxesName[j], dVal) ;
+ if ( m_AuxAxesLink[j] > 0)
+ dVal += vDeltaVal[m_AuxAxesLink[j] - 1] ;
+ else
+ dVal -= vDeltaVal[-m_AuxAxesLink[j] - 1] ;
+ }
+ m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
+ }
+ // se abilitato e non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill
+ if ( m_bEnableVm && ( nMoveType != 0 || ! NeedCollisionCheck())) {
+ for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ }
+ // eseguo eventuale collision check
+ bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ }
+ }
+ // Eseguo movimento su arco
+ else {
+ // dati dell'arco
+ Point3d ptCen = pCamData->GetAxesCen() ;
+ double dAngCen = pCamData->GetAxesAngCen() ;
+ double dRad = pCamData->GetAxesRad() ;
+ Vector3d vtN = pCamData->GetAxesNormDir() ;
+ double dDeltaN = ( Point3d( AxesEnd[0], AxesEnd[1], AxesEnd[2]) - ptCen) * vtN ;
+ double dDiffAng = ( m_dCoeff - dPrevCoeff) * dAngCen ;
+ Vector3d vtRot = Point3d( m_AxesVal[0], m_AxesVal[1], m_AxesVal[2]) - ptCen ;
+ vtRot.Rotate( vtN, dPrevCoeff * dAngCen) ;
+ // se attivi Vmill o CollisionCheck approssimo movimento con più step
+ int nStep = 1 ;
+ if ( ! m_VmId.empty() || NeedCollisionCheck()) {
+ const double MIN_LEN_STEP = 2. ;
+ const double MAX_LEN_STEP = 10. ;
+ double dLenStep = Clamp( 0.1 * m_dTDiam, MIN_LEN_STEP, MAX_LEN_STEP) ;
+ nStep = max( int( abs( dDiffAng * DEGTORAD * dRad) / dLenStep), 1) ;
+ const double ANG_STEP = 5. ;
+ if ( abs( dDiffAng) / nStep > ANG_STEP)
+ nStep = int( abs( dDiffAng) / ANG_STEP) ;
+ }
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
+ DBLVECTOR vDeltaVal( m_AxesName.size()) ;
+ // assi lineari
+ vtRot.Rotate( vtN, dDiffAng / nStep) ;
+ double dPrevVal, dVal ;
+ m_pMachine->GetAxisPos( m_AxesName[0], dPrevVal) ;
+ dVal = ptCen.x + vtRot.x + dCurrCoeff * dDeltaN * vtN.x ;
+ m_pMachine->SetAxisPos( m_AxesName[0], dVal) ;
+ vDeltaVal[0] = dVal - dPrevVal ;
+ m_pMachine->GetAxisPos( m_AxesName[1], dPrevVal) ;
+ dVal = ptCen.y + vtRot.y + dCurrCoeff * dDeltaN * vtN.y ;
+ m_pMachine->SetAxisPos( m_AxesName[1], dVal) ;
+ vDeltaVal[1] = dVal - dPrevVal ;
+ m_pMachine->GetAxisPos( m_AxesName[2], dPrevVal) ;
+ dVal = ptCen.z + vtRot.z + dCurrCoeff * dDeltaN * vtN.z ;
+ m_pMachine->SetAxisPos( m_AxesName[2], dVal) ;
+ vDeltaVal[2] = dVal - dPrevVal ;
+ // assi rotanti
+ for ( int j = 3 ; j < int( m_AxesName.size()) ; ++ j) {
+ double dPrevVal ; m_pMachine->GetAxisPos( m_AxesName[j], dPrevVal) ;
+ double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
+ m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
+ vDeltaVal[j] = dVal - dPrevVal ;
+ }
+ // eventuali assi ausiliari
+ for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
+ double dVal = 0 ;
+ if ( m_AuxAxesLink[j] == 0) {
+ dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
+ }
+ else {
+ m_pMachine->GetAxisPos( m_AuxAxesName[j], dVal) ;
+ if ( m_AuxAxesLink[j] > 0)
+ dVal += vDeltaVal[m_AuxAxesLink[j] - 1] ;
+ else
+ dVal -= vDeltaVal[-m_AuxAxesLink[j] - 1] ;
+ }
+ m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
+ }
+ // se abilitato, eseguo eventuale Vmill
+ for ( int j = 0 ; m_bEnableVm && j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ // eseguo eventuale collision check
+ bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ }
+ }
+ }
+
+ // altrimenti eseguo movimento soli eventuali assi ausiliari
+ else {
+ // Calcolo distanza di movimento
+ double dSqDist = 0 ;
+ for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
+ // coefficiente moltiplicativo per differenziare assi lineari e rotanti
+ double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
+ dSqDist += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
+ }
+ double dPrevCoeff = m_dCoeff ;
+ double dDist = sqrt( dSqDist) ;
+ if ( dDist > EPS_SMALL) {
+ double dStep = min( ( nMoveType == 0 ? 2 : 1) * m_dStep, MAX_STEP) ;
+ int nStep = max( int( dDist / dStep), 1) ;
+ m_dCoeff += 1. / nStep ;
+ if ( m_dCoeff > 1)
+ m_dCoeff = 1 ;
+ }
+ else
+ m_dCoeff = 1 ;
+ dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
+ // se attivo CollisionCheck approssimo movimento con più step
+ int nStep = 1 ;
+ if ( NeedCollisionCheck())
+ nStep = max( int( dMove / COLL_STEP), 1) ;
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ double dCurrCoeff = dPrevCoeff + ( m_dCoeff - dPrevCoeff) / nStep * i ;
+ // muovo eventuali assi ausiliari
+ for ( int j = 0 ; j < int( m_AuxAxesName.size()) ; ++ j) {
+ if ( m_AuxAxesLink[j] == 0) {
+ double dVal = m_AuxAxesVal[j] * ( 1 - dCurrCoeff) + m_AuxAxesEnd[j] * dCurrCoeff ;
+ m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ;
+ }
+ }
+ // se abilitato e non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill
+ if ( m_bEnableVm && ( nMoveType != 0 || ! NeedCollisionCheck())) {
+ for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ }
+ // eseguo eventuale collision check
+ bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ }
+ }
+
+ // Se riscontrata collisione
+ if ( ! bCollCheck) {
+ // Richiamo funzione di convalida collisione
+ int nErr ;
+ if ( ! OnCollision( nCdInd, nObjInd, nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo
+ if ( m_dCoeff > COEFF_LIM) {
+ if ( m_bEnabAxes) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
+ m_AxesVal[i] = AxesEnd[i] ;
+ }
+ // richiamo gestione evento fine entità, senza gestirne eventuali errori
+ int nErr ;
+ OnMoveEnd( nErr) ;
+ }
+ return false ;
+ }
+ }
+
+ // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo
+ if ( m_dCoeff > COEFF_LIM) {
+ if ( m_bEnabAxes) {
+ for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
+ m_AxesVal[i] = AxesEnd[i] ;
+ }
+ nStatus = MCH_SIM_END_STEP ;
+ // richiamo gestione evento fine entità
+ int nErr ;
+ if ( ! OnMoveEnd( nErr)) {
+ nStatus = CalcStatusOnError( nErr) ;
+ return false ;
+ }
+ }
+ // Altrimenti sto muovendomi all'interno dell'entità
+ else
+ nStatus = MCH_SIM_OK ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+int
+SimulatorSP::CalcStatusOnError( int nErr)
+{
+ if ( Stopped())
+ return MCH_SIM_STOP ;
+ else if ( nErr == ERR_OUTSTROKE)
+ return MCH_SIM_OUTSTROKE ;
+ else if ( nErr == ERR_COLLISION)
+ return MCH_SIM_COLLISION ;
+ else
+ return MCH_SIM_ERR ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::GetHeadCurrPosDirAux( const std::string& sHead, int nExit, Point3d& ptH, Vector3d& vtH, Vector3d& vtA)
+{
+ int nHeadId = m_pMachine->GetHeadId( sHead) ;
+ int nExitId = m_pMachine->GetExitId( sHead, nExit) ;
+ if ( nHeadId == GDB_ID_NULL || nExitId == GDB_ID_NULL)
+ return false ;
+ Frame3d frExit ; m_pGeomDB->GetGroupGlobFrame( nExitId, frExit) ;
+ ptH = frExit.Orig() ;
+ vtH = frExit.VersZ() ;
+ vtA = V_NULL ;
+ int nDirAuxId = m_pGeomDB->GetFirstNameInGroup( nHeadId, MCH_AUX_VECT) ;
+ if ( nDirAuxId != GDB_ID_NULL) {
+ const IGeoVector3d* pGV = GetGeoVector3d( m_pGeomDB->GetGeoObj( nDirAuxId)) ;
+ if ( pGV != nullptr) {
+ Frame3d frHead ; m_pGeomDB->GetGroupGlobFrame( nHeadId, frHead) ;
+ vtA = pGV->GetVector() ;
+ vtA.ToGlob( frHead) ;
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVmAdOffs,
+ const Point3d& ptHi, const Vector3d& vtHi, const Vector3d& vtAi, const Frame3d& frVzmI,
+ const Point3d& ptHf, const Vector3d& vtHf, const Vector3d& vtAf, const Frame3d& frVzmF)
+{
+ // Recupero Zmap
+ IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( nVmId)) ;
+ if ( pVZM == nullptr) {
+ string sOut = " --> GetVolZmap (" + ToString( nVmId) +") Error <--" ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ return false ;
+ }
+ // Porto gli estremi nel riferimento opportuno dello Zmap
+ Point3d ptHiL = ptHi ; ptHiL.ToLoc( frVzmI) ;
+ Vector3d vtHiL = vtHi ; vtHiL.ToLoc( frVzmI) ;
+ Vector3d vtAiL = vtAi ; vtAiL.ToLoc( frVzmI) ;
+ Point3d ptHfL = ptHf ; ptHfL.ToLoc( frVzmF) ;
+ Vector3d vtHfL = vtHf ; vtHfL.ToLoc( frVzmF) ;
+ Vector3d vtAfL = vtAf ; vtAfL.ToLoc( frVzmF) ;
+ // Eventuali offset
+ ptHiL += dVmTdOffs * vtHiL + dVmAdOffs * vtAiL ;
+ ptHfL += dVmTdOffs * vtHfL + dVmAdOffs * vtAfL ;
+ // Log per debug
+ if ( ExeGetDebugLevel() >= 10) {
+ string sOut = "Zmap=" + ToString( nVmId) + " Tool=" + ToString( nCurrTool) +
+ " Pi=(" + ToString( ptHiL) + ") Vi=(" + ToString( vtHiL) + ") Ai=(" + ToString( vtAiL) +
+ ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ // Se utensile che non lavora di testa
+ if ( ! m_bCutOnTip) {
+ // se movimento di testa (angolo movimento verso la testa oltre 5.8deg), non eseguo asportazione
+ Vector3d vtDirM = Media( vtHiL, vtHfL) ;
+ vtDirM.Normalize() ;
+ double dAxMove = ( ptHfL - ptHiL) * vtDirM ;
+ if ( dAxMove < -EPS_SMALL) {
+ double dMove = ( ptHfL - ptHiL).Len() ;
+ if ( dAxMove < -0.1 * abs( dMove))
+ return true ;
+ }
+ }
+ // Eseguo
+ bool bOk = pVZM->MillingStep( nCurrTool, ptHiL, vtHiL, vtAiL, ptHfL, vtHfL, vtAfL) ;
+ if ( ! bOk) {
+ if ( ExeGetDebugLevel() < 10) {
+ string sOut = "Zmap=" + ToString( nVmId) + " Tool=" + ToString( nCurrTool) +
+ " Pi=(" + ToString( ptHiL) + ") Vi=(" + ToString( vtHiL) + ") Ai=(" + ToString( vtAiL) +
+ ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ;
+ LOG_DBG_INFO( GetEMkLogger(), sOut.c_str())
+ }
+ LOG_DBG_INFO( GetEMkLogger(), " --> MillingStep Error <--")
+ }
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType)
+{
+ // se non ci sono oggetti da controllare o non ci sono grezzi o equivalenti, tutto bene
+ if ( ! NeedCollisionCheck())
+ return true ;
+ // ciclo sui grezzi o equivalenti
+ for ( int i = 0 ; i < int( m_CdId.size()) ; ++ i) {
+ // se modo hidden è da saltare
+ int nMode ;
+ if ( m_pGeomDB->GetCalcMode( m_CdId[i], nMode) && nMode == GDB_MD_HIDDEN)
+ continue ;
+ // verifico se è il grezzo in lavorazione
+ bool bIsRaw = ( find( m_VmId.begin(), m_VmId.end(), m_CdId[i]) != m_VmId.end()) ;
+ // recupero solido o trimesh, se altro lo salto
+ const IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
+ const ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
+ if ( pVZM == nullptr && pSTM == nullptr)
+ continue ;
+ // recupero il riferimento
+ Frame3d frCd ; m_pGeomDB->GetGlobFrame( m_CdId[i], frCd) ;
+ // ciclo sugli oggetti con cui verificare
+ for ( int j = 0 ; j < int( m_CollObj.size()) ; ++ j) {
+ // se modo hidden è da saltare
+ int nMode ;
+ if ( m_pGeomDB->GetCalcMode( m_CollObj[j].nFrameId, nMode) && nMode == GDB_MD_HIDDEN)
+ continue ;
+ // verifico se è l'utensile attivo
+ string sHead ; m_pGeomDB->GetName( m_pGeomDB->GetParentId( m_CollObj[j].nFrameId), sHead) ;
+ string sExit ; m_pGeomDB->GetName( m_CollObj[j].nFrameId, sExit) ;
+ bool bIsTool = m_CollObj[j].bToolOn ||
+ ( sHead == m_sHead && ( sExit == "_T" + ToString( m_nExit) || sExit == "_TT" + ToString( m_nExit))) ;
+ // se utensile attivo su grezzo in lavoro e non è rapido, salto
+ if ( bIsTool && bIsRaw && nMoveType != 0)
+ continue ;
+ // esecuzione controlli di collisione
+ bool bOk = true ;
+ // oggetti che richiedono frame associato (Box, Cylinder, Sphere, Cone)
+ if ( m_CollObj[j].nType != MCH_SIM_COB_POLY) {
+ // se riferimento non trovato, si salta
+ const IGeoFrame3d* pGeoFrame = GetGeoFrame3d( m_pGeomDB->GetGeoObj( m_CollObj[j].nFrameId)) ;
+ if ( pGeoFrame == nullptr)
+ continue ;
+ Frame3d frObj = pGeoFrame->GetFrame() ;
+ if ( ! m_CollObj[j].vtMove.IsSmall())
+ frObj.Translate( m_CollObj[j].vtMove.x * frObj.VersX() +
+ m_CollObj[j].vtMove.y * frObj.VersY() +
+ m_CollObj[j].vtMove.z * frObj.VersZ()) ;
+ Frame3d frParent ; m_pGeomDB->GetGlobFrame( m_CollObj[j].nFrameId, frParent) ;
+ frObj.LocToLoc( frParent, frCd) ;
+ // controlli di collisione
+ if ( m_CollObj[j].nType == MCH_SIM_COB_BOX) {
+ Vector3d vtDiag( m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3) ;
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeBox( frObj, vtDiag, m_dSafeDist) ;
+ else
+ bOk = ! CDeBoxClosedSurfTm( frObj, vtDiag, *pSTM, m_dSafeDist) ;
+ }
+ else if ( m_CollObj[j].nType == MCH_SIM_COB_CYL) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeCylinder( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_dSafeDist) ;
+ else
+ bOk = ! CDeCylClosedSurfTm( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, *pSTM, m_dSafeDist) ;
+ }
+ else if ( m_CollObj[j].nType == MCH_SIM_COB_SPHE) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeSphere( frObj.Orig(), m_CollObj[j].dPar1, m_dSafeDist) ;
+ else
+ bOk = ! CDeSpheClosedSurfTm( frObj.Orig(), m_CollObj[j].dPar1, *pSTM, m_dSafeDist) ;
+ }
+ else if ( m_CollObj[j].nType == MCH_SIM_COB_CONE) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeConeFrustum( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3, m_dSafeDist) ;
+ else
+ bOk = ! CDeConeFrustumClosedSurfTm( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3, *pSTM, m_dSafeDist) ;
+ }
+ }
+ // altrimenti poliedro
+ else {
+ SurfLocal SurfLoc( m_pGeomDB, m_CollObj[j].nFrameId, frCd) ;
+ const ISurfTriMesh* pStmLoc = GetSurfTriMesh( SurfLoc) ;
+ if ( pStmLoc != nullptr) {
+ if ( pVZM != nullptr)
+ bOk = ! pVZM->CDeSurfTm( *pStmLoc, m_dSafeDist) ;
+ else
+ bOk = ! CDeClosedSurfTmClosedSurfTm( *pStmLoc, *pSTM, m_dSafeDist) ;
+ }
+ else
+ bOk = false ;
+ }
+ // se trovata collisione
+ if ( ! bOk) {
+ nCdInd = i ;
+ nObjInd = j ;
+ return false ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+static int
+FindCollisionMarkId( const IGeomDB* pGeomDB, int nCollId)
+{
+ int nCollParId = pGeomDB->GetParentId( nCollId) ;
+ string sCollParName = "COLLISION" ;
+ pGeomDB->GetName( nCollParId, sCollParName) ;
+ if ( sCollParName != "COLLISION")
+ return nCollParId ;
+ else {
+ int nCollGprId = pGeomDB->GetParentId( nCollParId) ;
+ int nCollSolId = pGeomDB->GetFirstNameInGroup( nCollGprId, "SOLID") ;
+ if ( nCollSolId != GDB_ID_NULL)
+ return nCollSolId ;
+ else
+ return nCollGprId ;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::SetCollisionMark( int nCdInd, int nObjInd)
+{
+ if ( m_pGeomDB == nullptr)
+ return false ;
+ m_nCollMarkId.clear() ;
+ int nCdMarkId = FindCollisionMarkId( m_pGeomDB, m_CdId[nCdInd]) ;
+ m_pGeomDB->SetMark( nCdMarkId, GDB_MK_ON) ;
+ m_nCollMarkId.push_back( nCdMarkId) ;
+ int nCoMarkId = FindCollisionMarkId( m_pGeomDB, m_CollObj[nObjInd].nFrameId) ;
+ m_pGeomDB->SetMark( nCoMarkId, GDB_MK_ON_2) ;
+ m_nCollMarkId.push_back( nCoMarkId) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::ResetCollisionMark( void)
+{
+ if ( m_pGeomDB == nullptr)
+ return false ;
+ for ( auto nId : m_nCollMarkId)
+ m_pGeomDB->ResetMark( nId) ;
+ m_nCollMarkId.clear() ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnInit( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_INIT))
+ return true ;
+ // chiamo la funzione di ingresso nella simulazione
+ return m_pMachine->LuaCallFunction( ON_SIMUL_INIT) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnExit( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_EXIT))
+ return true ;
+ // chiamo la funzione di uscita dalla simulazione
+ return m_pMachine->LuaCallFunction( ON_SIMUL_EXIT) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnProgramStart( bool bFirst)
+{
+ // assegno flag inizio simulazione
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIM1ST, bFirst) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_START))
+ return true ;
+ // chiamo la funzione di inizio simulazione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_START) ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnProgramEnd( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_END))
+ return true ;
+ // chiamo la funzione di fine simulazione
+ return m_pMachine->LuaCallFunction( ON_SIMUL_END) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
+ const string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand)
+{
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
+ // assegno nuovo indice di fase
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
+ // assegno nome e valore riferimento della tavola corrente
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
+ // assegno flag disposizione passiva
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
+ // assegno flag disposizione con operazioni manuali
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SBH, bSomeByHand) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_STARTING))
+ return true ;
+ // chiamo la funzione di inizio disposizione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_STARTING) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnDispositionStart( int nOpId, int nOpInd, int nPhase,
+ const string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand)
+{
+ // assegno identificativo e indice disposizione
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
+ // assegno nuovo indice di fase
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
+ // assegno nome e valore riferimento della tavola corrente
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
+ // assegno flag disposizione passiva
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
+ // assegno flag disposizione con operazioni manuali
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SBH, bSomeByHand) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_START))
+ return true ;
+ // chiamo la funzione di inizio disposizione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_START) ;
+ // recupero i dati di ritorno
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_VMILL, m_VmId) ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnDispositionEnd( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_END))
+ return true ;
+ // chiamo la funzione di fine disposizione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_END) ;
+ // recupero i dati di ritorno
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_VMILL, m_VmId) ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnToolSelect( const string& sTool, const string& sHead, int nExit, const string& sTcPos,
+ bool bFirst, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // reset oggetti per verifica collisione con grezzo
+ m_CollObj.clear() ;
+ // assegno il nome dell'utensile, la testa e l'uscita
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TOOL, sTool) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_HEAD, sHead) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXIT, nExit) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TCPOS, sTcPos))
+ return false ;
+ // assegno il token e il nome degli assi
+ bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
+ int nNumAxes = int( m_AxesName.size()) ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
+ if ( i <= nNumAxes) {
+ if ( ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisToken( i, bIsRobot), m_AxesToken[i-1]) ||
+ ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisName( i, bIsRobot), m_AxesName[i-1]))
+ return false ;
+ }
+ else {
+ if ( ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisToken( i, bIsRobot)) ||
+ ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisName( i, bIsRobot)))
+ return false ;
+ }
+ }
+ // assegno il flag di chiamata di utensile iniziale
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FIRST, bFirst))
+ return false ;
+ // reset errore
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
+ return false ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_SELECT))
+ return true ;
+ // chiamo la funzione di selezione utensile
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_SELECT) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // recupero dati per verifica collisione
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SAFEDIST, m_dSafeDist) ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_CODET, m_CdId) ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // recupero i dati di ritorno per assi ausiliari
+ ResetAuxAxes() ;
+ int nNumAuxAxes = 0 ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
+ return ( bOk && nErr == 0) ;
+ m_AuxAxesName.reserve( nNumAuxAxes) ;
+ m_AuxAxesToken.reserve( nNumAuxAxes) ;
+ m_AuxAxesInvert.reserve( nNumAuxAxes) ;
+ m_AuxAxesOffset.reserve( nNumAuxAxes) ;
+ m_AuxAxesLinear.reserve( nNumAuxAxes) ;
+ m_AuxAxesVal.reserve( nNumAuxAxes) ;
+ m_AuxAxesEnd.reserve( nNumAuxAxes) ;
+ for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
+ string sName ; string sToken ; bool bInvert ; double dOffset ; bool bLinear ; double dVal ;
+ string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
+ if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
+ m_pMachine->GetAxisToken( sName, sToken) &&
+ m_pMachine->GetAxisInvert( sName, bInvert) &&
+ m_pMachine->GetAxisOffset( sName, dOffset) &&
+ m_pMachine->GetAxisType( sName, bLinear) &&
+ m_pMachine->GetAxisPos( sName, dVal)) {
+ // se non è già negli assi principali, lo aggiungo
+ if ( find( m_AxesName.begin(), m_AxesName.end(), sName) == m_AxesName.end()) {
+ m_AuxAxesName.emplace_back( sName) ;
+ m_AuxAxesToken.emplace_back( sToken) ;
+ m_AuxAxesInvert.push_back( bInvert) ;
+ m_AuxAxesOffset.push_back( dOffset) ;
+ m_AuxAxesLinear.push_back( bLinear) ;
+ m_AuxAxesVal.emplace_back( dVal) ;
+ m_AuxAxesEnd.emplace_back( dVal) ;
+ m_AuxAxesLink.emplace_back( 0) ;
+ }
+ }
+ else {
+ bOk = false ;
+ nErr = ERR_TOOL_SEL ;
+ }
+ }
+
+ return ( bOk && nErr == 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnToolDeselect( const string& sNextTool, const string& sNextHead, int nNextExit, const string& sNextTcPos, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // assegno il prossimo utensile
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTOOL, sNextTool) ;
+ // assegno la prossima testa
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTHEAD, sNextHead) ;
+ // assegno la prossima uscita
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTEXIT, nNextExit) ;
+ // assegno l'eventuale prossima posizione nel TC
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTCPOS, sNextTcPos) ;
+ // reset errore
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_DESELECT))
+ return bOk ;
+ // chiamo la funzione di deselezione utensile
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_DESELECT) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax)
+{
+ // assegno identificativo e indice lavorazione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHID, nOpId) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHIND, nOpInd))
+ return false ;
+ // assegno punti estremi dell'ingombro della lavorazione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MMIN, ptMin) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MMAX, ptMax))
+ return false ;
+ // assegno punti estremi dell'ingombro degli assi della lavorazione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MAXMIN, vAxMin) ||
+ ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MAXMAX, vAxMax))
+ return false ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_START))
+ return true ;
+ // chiamo la funzione di inizio disposizione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_START) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnMachiningEnd( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_END))
+ return true ;
+ // chiamo la funzione di fine lavorazione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_END) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnPathStart( int nClPathId, int nClPathInd, int nAS, const Point3d& ptStart, const Point3d& ptEnd,
+ const Vector3d& vtExtr, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax, double dElev)
+{
+ // assegno identificativo e indice percorso di lavorazione
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHID, nClPathId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHIND, nClPathInd) ;
+ // assegno numero di dati ausiliari iniziali
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXTOT, nAS) ;
+ // assegno punti iniziale e finale e versore estrusione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_START, ptStart) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_END, ptEnd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXTR, vtExtr) ;
+ // assegno punti estremi dell'ingombro del percorso di lavorazione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMIN, ptMin) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMAX, ptMax) ;
+ // assegno punti estremi dell'ingombro degli assi della lavorazione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PAXMIN, vAxMin) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PAXMAX, vAxMax) ;
+ // assegno la massima elevazione
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ELEV, dElev) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START))
+ return bOk ;
+ // chiamo la funzione di inizio percorso di lavorazione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnPathEnd( int nAE)
+{
+ // assegno numero di dati ausiliari finali
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXTOT, nAE) ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END))
+ return bOk ;
+ // chiamo la funzione di fine percorso di lavorazione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnPathStartAux( int nInd, const string& sAS, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START_AUX))
+ return true ;
+ // assegno indice, valore dato ausiliario e resetto errore
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXIND, nInd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUX, sAS) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // chiamo la funzione di evento ausiliario all'inizio del percorso
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START_AUX) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnPathEndAux( int nInd, const string& sAE, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END_AUX))
+ return true ;
+ // assegno indice, valore dato ausiliario e resetto errore
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUXIND, nInd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_AUX, sAE) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // chiamo la funzione di evento ausiliario alla fine del percorso
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END_AUX) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ bOk = bOk && m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnMoveStart( const CamData* pCamData, const CamData* pNextCamData, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // recupero e assegno i dati
+ // dati generali e reset errore
+ bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEID, m_nEntId) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEIND, m_nEntInd) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, pCamData->GetMoveType()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MASK, pCamData->GetAxesMask()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG, pCamData->GetFlag()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG2, pCamData->GetFlag2()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_INDEX, pCamData->GetIndex()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // valore degli assi all'inizio e alla fine del movimento
+ bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
+ int nNumAxes = int( m_AxesName.size()) ;
+ const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
+ if ( i <= nNumAxes) {
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisPrev( i, GLOB_VAR, bIsRobot), m_AxesVal[i-1]) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisValue( i, GLOB_VAR, bIsRobot), AxesEnd[i-1]) ;
+ }
+ else {
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisPrev( i, GLOB_VAR, bIsRobot)) ;
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisValue( i, GLOB_VAR, bIsRobot)) ;
+ }
+ }
+ // versori utensile, correzione e ausiliario alla fine del movimento
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TDIR, pCamData->GetToolDir()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_CDIR, pCamData->GetCorrDir()) ;
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ADIR, pCamData->GetBackAuxDir()) ;
+ // anticipazione di alcuni dati dell'eventuale movimento successivo dello stesso percorso
+ if ( pNextCamData != nullptr && pNextCamData->GetAxesStatus() == CamData::AS_OK) {
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVESUCC, pNextCamData->GetMoveType()) ;
+ const DBLVECTOR& AxesNext = pNextCamData->GetAxesVal() ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
+ if ( i <= nNumAxes)
+ bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot), AxesNext[i-1]) ;
+ else
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot)) ;
+ }
+ }
+ else {
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_MOVESUCC) ;
+ for ( int i = 1 ; i <= MAX_AXES ; ++ i)
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisNext( i, GLOB_VAR, bIsRobot)) ;
+ }
+ // reset abilitazione assi attivi
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_ENABAXES) ;
+ // reset numero assi ausiliari
+ bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_AUXAXES) ;
+
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_START)) {
+ ResetAuxAxes() ;
+ return bOk ;
+ }
+ // chiamo la funzione
+ bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_START) ;
+ // con errore, esco
+ if ( ! bOk) {
+ ResetAuxAxes() ;
+ return false ;
+ }
+
+ // verifico codice di errore
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ if ( nErr != 0)
+ return false ;
+
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+
+ // reset assi ausiliari
+ ResetAuxAxes() ;
+
+ // recupero i dati di ritorno
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_MASK, m_nAxesMask) ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ENABAXES, m_bEnabAxes))
+ m_bEnabAxes = true ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SHOWAXES, m_bShowAxes))
+ m_bShowAxes = m_bEnabAxes ;
+ int nNumAuxAxes = 0 ;
+ if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
+ return true ;
+ m_AuxAxesName.reserve( nNumAuxAxes) ;
+ m_AuxAxesToken.reserve( nNumAuxAxes) ;
+ m_AuxAxesInvert.reserve( nNumAuxAxes) ;
+ m_AuxAxesOffset.reserve( nNumAuxAxes) ;
+ m_AuxAxesLinear.reserve( nNumAuxAxes) ;
+ m_AuxAxesVal.reserve( nNumAuxAxes) ;
+ m_AuxAxesEnd.reserve( nNumAuxAxes) ;
+ for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
+ string sName ; string sToken ; bool bInvert ; double dOffset ; bool bLinear ; double dVal ; double dEnd ; string sLink ;
+ string sAuxAxVal = GLOB_VAR + GVAR_AN ; ReplaceString( sAuxAxVal, "N", ToString( i)) ;
+ string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
+ string sAuxAxMaster = GLOB_VAR + GVAR_ANM ; ReplaceString( sAuxAxMaster, "N", ToString( i)) ;
+ if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
+ m_pMachine->GetAxisToken( sName, sToken) &&
+ m_pMachine->GetAxisInvert( sName, bInvert) &&
+ m_pMachine->GetAxisOffset( sName, dOffset) &&
+ m_pMachine->GetAxisType( sName, bLinear) &&
+ m_pMachine->GetAxisPos( sName, dVal)) {
+ // se assi principali abilitati e da agganciare ad asse principale
+ if ( m_bEnabAxes && m_pMachine->LuaGetGlobVar( sAuxAxMaster, sLink)) {
+ bool bNeg = ( sLink.find( '-') != string::npos) ;
+ string sMainAxis = sLink ; ReplaceString( sMainAxis, "-", "") ;
+ int nInd = 0 ;
+ for ( int i = 0 ; nInd == 0 && i < int( m_AxesName.size()) ; ++ i) {
+ if ( m_AxesName[i] == sMainAxis)
+ nInd = i + 1 ;
+ }
+ // se trovato asse principale di riferimento
+ if ( nInd > 0) {
+ m_AuxAxesName.emplace_back( sName) ;
+ m_AuxAxesToken.emplace_back( sToken) ;
+ m_AuxAxesInvert.push_back( bInvert) ;
+ m_AuxAxesOffset.push_back( dOffset) ;
+ m_AuxAxesLinear.push_back( bLinear) ;
+ m_AuxAxesVal.emplace_back( 0) ;
+ m_AuxAxesEnd.emplace_back( 0) ;
+ m_AuxAxesLink.emplace_back( ( bNeg ? -nInd : nInd)) ;
+ }
+ }
+ // se altrimenti specificato valore finale del movimento
+ else if ( m_pMachine->LuaGetGlobVar( sAuxAxVal, dEnd)) {
+ // se assi principali disabilitati o non è tra questi, lo aggiungo
+ if ( ! m_bEnabAxes || find( m_AxesName.begin(), m_AxesName.end(), sName) == m_AxesName.end()) {
+ m_AuxAxesName.emplace_back( sName) ;
+ m_AuxAxesToken.emplace_back( sToken) ;
+ m_AuxAxesInvert.push_back( bInvert) ;
+ m_AuxAxesOffset.push_back( dOffset) ;
+ m_AuxAxesLinear.push_back( bLinear) ;
+ m_AuxAxesVal.emplace_back( dVal) ;
+ m_AuxAxesEnd.emplace_back( dEnd) ;
+ m_AuxAxesLink.emplace_back( 0) ;
+ if ( ! m_pMachine->VerifyOutstroke( sName, dEnd)) {
+ nErr = 1 ;
+ bOk = false ;
+ }
+ }
+ }
+ // altrimenti errore
+ else
+ bOk = false ;
+ }
+ else
+ bOk = false ;
+ }
+
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnMoveEnd( int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_END))
+ return true ;
+ // reset errore
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
+ return false ;
+ // chiamo la funzione
+ bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_END) ;
+ // forzo aggiornamento posizione assi (possono essere stati mossi nello script)
+ UpdateAxesPos() ;
+ // verifico codice di errore
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ return ( bOk && nErr == 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnCollision( int nCdInd, int nObjInd, int& nErr)
+{
+ // reset stato di errore da script
+ nErr = 0 ;
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_COLLISION))
+ return true ;
+ // reset stato di errore
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr))
+ return false ;
+ // assegno identificativi grezzo e oggetto in collisione
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMVMID, m_CdId[nCdInd]))
+ return false ;
+ if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMCOBIND, m_CollObj[nObjInd].nInd))
+ return false ;
+ // chiamo la funzione
+ if ( ! m_pMachine->LuaCallFunction( ON_SIMUL_COLLISION))
+ return false ;
+ // verifico codice di errore
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ // l'errore standard di collisione è stato portato da 1 a 11 per non collidere con altri tipi di errori
+ if ( nErr == 1) {
+ nErr = ERR_COLLISION ;
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ }
+ // evidenzio le geometrie in collisione
+ if ( nErr == ERR_COLLISION) {
+ SetCollisionMark( nCdInd, nObjInd) ;
+ ExeDraw() ;
+ }
+
+ return ( nErr == 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::OnResetMachine( void)
+{
+ // verifico esistenza funzione
+ if ( ! m_pMachine->LuaExistsFunction( ON_RESET_MACHINE))
+ return true ;
+ // eseguo reset macchina
+ return m_pMachine->LuaCallFunction( ON_RESET_MACHINE) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType, const Vector3d& vtMove, double dPar1, double dPar2, double dPar3)
+{
+ // verifiche sui parametri
+ if ( nInd <= 0 || nFrameId <= GDB_ID_NULL)
+ return false ;
+ switch ( nType) {
+ case MCH_SIM_COB_BOX :
+ if ( abs( dPar1) < EPS_SMALL || abs( dPar2) < EPS_SMALL || abs( dPar3) < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_CYL :
+ if ( dPar1 < EPS_SMALL || abs( dPar2) < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_SPHE :
+ if ( dPar1 < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_CONE :
+ if ( ( dPar1 < EPS_SMALL && dPar2 < EPS_SMALL) || dPar3 < EPS_SMALL)
+ return false ;
+ break ;
+ case MCH_SIM_COB_POLY :
+ if ( ! ExeSurfIsClosed( nFrameId))
+ return false ;
+ break ;
+ default :
+ return false ;
+ }
+ // aggiungo al vettore
+ m_CollObj.emplace_back( nInd, bToolOn, nFrameId, nType, vtMove, dPar1, dPar2, dPar3) ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::SetToolForVmill( const string& sTool, const string& sHead, int nExit, int nFlag, double dPar1, double dPar2,
+ const INTVECTOR& vVmill, bool bFirst)
+{
+ // disabilito eventuale registrazione comandi EXE (riabilitazione automatica)
+ CmdLogOff cmdLogOff ;
+ // se vVmill vuoto, esco
+ if ( vVmill.empty())
+ return true ;
+ // se utensile, testa o uscita non definiti, reset ed esco
+ if ( IsEmptyOrSpaces( sTool) || IsEmptyOrSpaces( sHead) || nExit < 1) {
+ ExeVolZmapResetTools( vVmill) ;
+ if ( bFirst)
+ m_bEnableVm = false ;
+ return false ;
+ }
+ // imposto utensile come corrente
+ string sOldTool ; m_pMchMgr->TdbGetCurrToolParam( TPA_NAME, sOldTool) ;
+ if ( sTool != sOldTool && ! m_pMchMgr->TdbSetCurrTool( sTool)) {
+ ExeVolZmapResetTools( vVmill) ;
+ if ( bFirst)
+ m_bEnableVm = false ;
+ return false ;
+ }
+ // recupero dati utensile
+ int nInd = 1 ;
+ int nType ; m_pMchMgr->TdbGetCurrToolParam( TPA_TYPE, nType) ;
+ double dLen ; m_pMchMgr->TdbGetCurrToolParam( TPA_LEN, dLen) ;
+ double dDiam ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, dDiam) ;
+ double dThick ; m_pMchMgr->TdbGetCurrToolParam( TPA_THICK, dThick) ;
+ double dCornR ; m_pMchMgr->TdbGetCurrToolParam( TPA_CORNRAD, dCornR) ;
+ double dSideAng ; m_pMchMgr->TdbGetCurrToolParam( TPA_SIDEANG, dSideAng) ;
+ double dMaxMat ; m_pMchMgr->TdbGetCurrToolParam( TPA_MAXMAT, dMaxMat) ;
+ string sNotes ; m_pMchMgr->TdbGetCurrToolParam( TPA_USERNOTES, sNotes) ;
+ bool bAdditive = ( nFlag == 1) ;
+ // ricerca dell'outline e del diametro gambo
+ int nExitId = m_pMachine->GetExitId( sHead, nExit) ;
+ int nToolId = m_pGeomDB->GetFirstNameInGroup( nExitId, sTool) ;
+ int nOutlineId = m_pGeomDB->GetFirstNameInGroup( nToolId, "Outline") ;
+ double dMaxStemDiam = dDiam ; m_pGeomDB->GetInfo( nToolId, "D_STEM", dMaxStemDiam) ;
+ // imposto profilo utensile per Vmill
+ if ( bAdditive)
+ ExeVolZmapSetAdditiveTool( vVmill, sTool, dPar1, dPar2, 0, nInd, bFirst) ;
+ else if ( nOutlineId != GDB_ID_NULL)
+ ExeVolZmapSetGenTool( vVmill, sTool, nOutlineId, nInd, bFirst) ;
+ else if ( nType == TT_MORTISE_STD)
+ ExeVolZmapSetMortiserTool( vVmill, sTool, dLen, dDiam, dThick, dCornR, nInd, bFirst) ;
+ else if ( nType == TT_CHISEL_STD)
+ ExeVolZmapSetChiselTool( vVmill, sTool, dLen, dDiam, dDiam, nInd, bFirst) ;
+ else if ( nType == TT_SAW_STD || nType == TT_SAW_FLAT)
+ ExeVolZmapSetSawTool( vVmill, sTool, dLen, dDiam, dThick, 0, dCornR, nInd, bFirst) ;
+ else if ( nType == TT_WATERJET)
+ ExeVolZmapSetStdTool( vVmill, sTool, dLen + 50, dDiam, dCornR, dMaxMat, nInd, bFirst) ;
+ else if ( abs( dSideAng) < EPS_ANG_SMALL || abs( dThick) < EPS_SMALL) {
+ ExeVolZmapSetStdTool( vVmill, sTool, dLen, dDiam, dCornR, dMaxMat, nInd, bFirst) ;
+ }
+ else {
+ bool bExtra = ( dThick > 0) ;
+ double dTipLen = abs( dThick) ;
+ double dTotLen = ( bExtra ? dLen + dTipLen : dLen) ;
+ double dDelta ;
+ if ( dSideAng > 0) {
+ if ( dCornR < EPS_SMALL)
+ dDelta = 2 * dTipLen * tan( dSideAng * DEGTORAD) ;
+ else
+ dDelta = 2 * ( dCornR * cos( dSideAng * DEGTORAD) + ( dTipLen - dCornR + dCornR * sin( dSideAng * DEGTORAD)) * tan( dSideAng * DEGTORAD)) ;
+ }
+ else
+ dDelta = 2 * tan( dSideAng * DEGTORAD) * dTipLen ;
+ double dStemDiam = ( bExtra ? dDiam : dDiam + dDelta) ;
+ double dTipDiam = ( bExtra ? dDiam - dDelta : dDiam) ;
+ ExeVolZmapSetAdvTool( vVmill, sTool, dTotLen, dStemDiam, dTipLen, dTipDiam, dCornR, dMaxMat, nInd, bFirst) ;
+ }
+ // eventuali offset per Vmill (per adattare lo ZeroT macchina con quello di Zmap)
+ double dVmTdOffs = 0 ;
+ double dVmAdOffs = 0 ;
+ if ( nType == TT_MORTISE_STD) {
+ dVmTdOffs = 0 ;
+ dVmAdOffs = 0.5 * dThick ;
+ }
+ else if ( nType == TT_SAW_STD || nType == TT_SAW_FLAT) {
+ dVmTdOffs = ( ( dLen <= dThick) ? -dLen + dThick : 0) ;
+ dVmAdOffs = 0 ;
+ }
+ // inserisco in lista utensili per virtual milling
+ if ( bFirst) {
+ m_VmTool.resize( 1) ;
+ m_VmTool[0] = VmTool( sTool, sHead, nExit, dVmTdOffs, dVmAdOffs) ;
+ }
+ else
+ m_VmTool.emplace_back( sTool, sHead, nExit, dVmTdOffs, dVmAdOffs) ;
+ // ripristino eventuale diverso utensile corrente
+ if ( sTool != sOldTool)
+ m_pMchMgr->TdbSetCurrTool( sOldTool) ;
+
+ if ( bFirst)
+ m_bEnableVm = true ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SimulatorSP::EnableToolsForVmill( bool bEnable)
+{
+ m_bEnableVm = bEnable ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+int
+SimulatorSP::MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt)
+{
+ // Salvo lo step di simulazione corrente
+ double dOrigStep = m_dStep ;
+ // Verifico ci siano assi da muovere
+ if ( vAxNaEpSt.empty())
+ return SIM_AXMV_RES_ERR ;
+ // Tipo di cinematica
+ bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ;
+ // Numero assi da muovere
+ int nAxCount = int( vAxNaEpSt.size()) ;
+ // Posizioni iniziali
+ DBLVECTOR vPrev( nAxCount) ;
+ for ( int i = 0 ; i < nAxCount ; ++ i) {
+ if ( ! m_pMchMgr->GetAxisPos( vAxNaEpSt[i].sName, vPrev[i]))
+ return SIM_AXMV_RES_ERR ;
+ }
+ // Posizione e direzione attuali degli utensili e riferimenti dei pezzi (per Vmill)
+ bool bExecVmill = (( nMoveType != 0 || ! NeedCollisionCheck()) && ! m_VmTool.empty() && ! m_VmId.empty()) ;
+ PNTVECTOR vPtNoseI ;
+ VCT3DVECTOR vVtDirI ;
+ VCT3DVECTOR vVtAuxI ;
+ vector vFrVzmI ;
+ if ( bExecVmill) {
+ vPtNoseI.resize( m_VmTool.size()) ;
+ vVtDirI.resize( m_VmTool.size()) ;
+ vVtAuxI.resize( m_VmTool.size()) ;
+ vFrVzmI.resize( m_VmId.size()) ;
+ bool bOkI = true ;
+ for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i)
+ bOkI = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, vPtNoseI[i], vVtDirI[i], vVtAuxI[i]) && bOkI ;
+ for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
+ bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
+ }
+ // Determino gli step di movimento
+ static const int STEP_FEED = -1 ;
+ static const int STEP_RAPID = -2 ;
+ static const int STEP_RAPROT = -3 ;
+ static const int STEP_COLLROT = -4 ;
+ bool bViewAllFrames = true ;
+ int nStep = 1 ;
+ for ( int i = 0 ; i < nAxCount ; ++ i) {
+ double dMove = abs( vAxNaEpSt[i].dEndPos - vPrev[i]) ;
+ double dStep = vAxNaEpSt[i].dStep ;
+ if ( dStep < 0) {
+ if ( abs( dStep - STEP_FEED) < EPS_SMALL)
+ dStep = m_dStep ;
+ else if ( abs( dStep - STEP_RAPID) < EPS_SMALL)
+ dStep = 4 * m_dStep ;
+ else if ( abs( dStep - STEP_RAPROT) < EPS_SMALL) {
+ dStep = 0.4 * m_dStep ;
+ bViewAllFrames = ( bIsRobot ? true : false) ;
+ }
+ else { // STEP_COLLROT
+ dStep = min( 0.4 * m_dStep, 10.) ;
+ bViewAllFrames = ( bIsRobot ? true : false) ;
+ }
+ }
+ dStep = max( dStep, 1.) ;
+ int nAxStep = int( dMove / dStep) + 1 ;
+ nStep = max( nStep, nAxStep) ;
+ }
+ // Eseguo il movimento
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ // Muovo
+ bool bMoveOk = true ;
+ double dCoeff = double( i) / nStep ;
+ for ( int j = 0 ; j < nAxCount ; ++ j) {
+ bMoveOk = m_pMchMgr->SetAxisPos( vAxNaEpSt[j].sName, ( 1 - dCoeff) * vPrev[j] + dCoeff * vAxNaEpSt[j].dEndPos) && bMoveOk ;
+ }
+ // Se abilitato e richiesto, eseguo eventuale Vmill
+ if ( m_bEnableVm && bExecVmill) {
+ for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) {
+ Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
+ bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ;
+ for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) {
+ Frame3d frVzmF ;
+ bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ;
+ ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs,
+ vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
+ // se ultimo utensile, salvo riferimento per prossimo inizio
+ if ( j == int( m_VmTool.size()) - 1)
+ vFrVzmI[k] = frVzmF ;
+ }
+ // aggiorno prossimo inizio
+ vPtNoseI[j] = ptNoseF ;
+ vVtDirI[j] = vtDirF ;
+ vVtAuxI[j] = vtAuxF ;
+ }
+ }
+ // Aggiorno visualizzazione
+ if ( bViewAllFrames || ( i % 4) == 0 || i == nStep)
+ ExeDraw() ;
+ // Verifico collisioni
+ int nCdInd, nObjInd ;
+ bool bCollCheck = ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ;
+ if ( ! bCollCheck) {
+ // Richiamo funzione di convalida collisione
+ int nPrevErr ;
+ m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ERR, nPrevErr) ;
+ int nErr ;
+ if ( ! OnCollision( nCdInd, nObjInd, nErr) && nErr == ERR_COLLISION) {
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nErr) ;
+ if ( ExeGetEnableUI()) {
+ // Box di messaggio : Collisione! AVVERTIMENTO
+ ExeMessageBox( ExeGetMsg( 5319), ExeGetMsg( 5315), MB_OK | MB_ICONWARNING) ;
+ // Gestione Pausa
+ m_nUiStatus = MCH_UISIM_PAUSE ;
+ while ( m_nUiStatus == MCH_UISIM_PAUSE) {
+ // -11 notifica al simulatore pausa dopo collisione
+ ExeProcessEvents( -11, 4) ;
+ }
+ }
+ }
+ else {
+ m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_ERR, nPrevErr) ;
+ }
+ }
+ // In caso di errore esco
+ if ( ! bMoveOk)
+ return SIM_AXMV_RES_ERR ;
+ // Gestione aggiornamenti...
+ if ( ExeGetEnableUI()) {
+ // Aggiornamento interfaccia
+ ExeProcessEvents( 0, 4) ;
+ while ( m_nUiStatus == MCH_UISIM_PAUSE) {
+ ExeProcessEvents( 0, 4) ;
+ }
+ // Gestione Stop
+ if ( m_nUiStatus == MCH_UISIM_STOP)
+ return SIM_AXMV_RES_STOP ;
+ // Se cambia lo step di simulazione in modo significativo ...
+ if ( abs( m_dStep - dOrigStep) > 10 || abs( ( m_dStep - dOrigStep) / ( m_dStep + dOrigStep)) > 0.2) {
+ double dRat = m_dStep / dOrigStep ;
+ for ( int j = 0 ; j < nAxCount ; ++ j) {
+ if ( vAxNaEpSt[j].dStep > 0)
+ const_cast( vAxNaEpSt[j].dStep) *= dRat ;
+ }
+ return MoveAxes( nMoveType, vAxNaEpSt) ;
+ }
+ }
+ }
+
+ return SIM_AXMV_RES_OK ;
+}
diff --git a/SimulatorSP.h b/SimulatorSP.h
new file mode 100644
index 0000000..e67af91
--- /dev/null
+++ b/SimulatorSP.h
@@ -0,0 +1,188 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2024
+//----------------------------------------------------------------------------
+// File : SimulatorSP.h Data : 16.01.23 Versione : 2.5a2
+// Contenuto : Dichiarazione della classe Simulator.
+//
+//
+//
+// Modifiche : 19.10.15 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "Simulator.h"
+#include "CamData.h"
+
+class IGeomDB ;
+class Machine ;
+class PerformanceCounter ;
+
+//----------------------------------------------------------------------------
+ISimulator* CreateSimulatorSP( void) ;
+
+//----------------------------------------------------------------------------
+class SimulatorSP : public ISimulator
+{
+ public :
+ ~SimulatorSP( void) override ;
+ bool Init( MachMgr* pMchMgr) override ;
+ bool Start( bool bFirst) override ;
+ bool Move( int& nStatus) override ;
+ bool GoHome( void) override ;
+ bool SetStep( double dStep) override ;
+ bool SetUiStatus( int nUiStatus) override ;
+ bool GetAxisInfoPos( int nI, std::string& sName, std::string& sToken, bool& bLinear, double& dVal) const override ;
+ bool GetToolInfo( std::string& sName, double& dSpeed) const override ;
+ bool GetOperationInfo( std::string& sName, int& nType) const override ;
+ bool GetMoveInfo( int& nGmove, double& dFeed) const override ;
+ bool AddCollisionObj( int nInd, bool bToolOn, int nFrameId, int nType,
+ const Vector3d& vtMove, double dPar1, double dPar2, double dPar3) override ;
+ bool ExecCollisionCheck( int& nCdInd, int& nObjInd, int nMoveType) override ;
+ bool OnCollision( int nCdInd, int nObjInd, int& nErr) override ;
+ bool SetToolForVmill( const std::string& sTool, const std::string& sHead, int nExit, int nFlag,
+ double dPar1, double dPar2, const INTVECTOR& vVmill, bool bFirst) override ;
+ bool EnableToolsForVmill( bool bEnable) override ;
+ int MoveAxes( int nMoveType, const SAMVECTOR& vAxNaEpSt) override ;
+ bool SaveCmd( int nType, int nPar, const std::string& sPar) override
+ { return false ; }
+
+ public :
+ SimulatorSP( void) ;
+
+ private :
+ bool UpdateTool( bool bFirst, int& nErr) ;
+ bool UpdateAxes( void) ;
+ bool UpdateAxesPos( void) ;
+ bool ResetInterpolation( void) ;
+ bool ResetAxes( void) ;
+ bool ResetAuxAxes( void) ;
+
+ private :
+ bool VerifySetup( void) ;
+ bool FindAndManageOperationStart( bool bStart, bool bFirst, int& nStatus) ;
+ bool ManageOperationEnd( int& nStatus) ;
+ bool FindAndManagePathStart( int& nStatus) ;
+ bool ManagePathEnd( int& nStatus) ;
+ bool ManagePathStartAux( int& nStatus) ;
+ bool ManagePathEndAux( int& nStatus) ;
+ bool ManageMove( int& nStatus) ;
+ bool ManageSingleMove( int& nStatus, double& dMove) ;
+ int CalcStatusOnError( int nErr) ;
+ bool GetHeadCurrPosDirAux( const std::string& sHead, int nExit, Point3d& ptH, Vector3d& vtH, Vector3d& vtA) ;
+ bool ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVmAdOffs,
+ const Point3d& ptHi, const Vector3d& vtHi, const Vector3d& vtAi, const Frame3d& frVzmI,
+ const Point3d& ptHf, const Vector3d& vtHf, const Vector3d& vtAf, const Frame3d& frVzmF) ;
+ bool NeedCollisionCheck( void) const
+ { return ( ! m_CollObj.empty() && ! m_CdId.empty()) ; }
+ bool Stopped( void)
+ { return ( m_nUiStatus == MCH_UISIM_STOP) ; }
+ bool SetCollisionMark( int nCdInd, int nObjInd) ;
+ bool ResetCollisionMark( void) ;
+ bool OnInit( void) ;
+ bool OnExit( void) ;
+ bool OnProgramStart( bool bFirst) ;
+ bool OnProgramEnd( void) ;
+ bool OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
+ const std::string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand) ;
+ bool OnDispositionStart( int nOpId, int nOpInd, int nPhase,
+ const std::string& sTable, const Point3d& ptOri1, bool bEmpty, bool bSomeByHand) ;
+ bool OnDispositionEnd( void) ;
+ bool OnToolSelect( const std::string& sTool, const std::string& sHead, int nExit, const std::string& sTcPos, bool bFirst, int& nErr) ;
+ bool OnToolDeselect( const std::string& sNextTool, const std::string& sNextHead, int nNextExit, const std::string& sNextTcPos, int& nErr) ;
+ bool OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax) ;
+ bool OnMachiningEnd( void) ;
+ bool OnPathStartAux( int nInd, const std::string& sAS, int& nErr) ;
+ bool OnPathEndAux( int nInd, const std::string& sAE, int& nErr) ;
+ bool OnPathStart( int nClPathId, int nClPathInd, int nAS, const Point3d& ptStart, const Point3d& ptEnd,
+ const Vector3d& vtExtr, const Point3d& ptMin, const Point3d& ptMax,
+ const DBLVECTOR& vAxMin, const DBLVECTOR& vAxMax, double dElev) ;
+ bool OnPathEnd( int nAE) ;
+ bool OnMoveStart( const CamData* pCamData, const CamData* pNextCamData, int& nErr) ;
+ bool OnMoveEnd( int& nErr) ;
+ bool OnResetMachine( void) ;
+
+ private :
+ struct CollObj {
+ int nInd ;
+ bool bToolOn ;
+ int nFrameId ;
+ int nType ;
+ Vector3d vtMove ;
+ double dPar1 ;
+ double dPar2 ;
+ double dPar3 ;
+ CollObj( void) : nInd( 0), bToolOn( false), nFrameId( -1), nType( 0), vtMove(), dPar1( 0), dPar2( 0), dPar3( 0) {}
+ CollObj( int nI, bool bTOn, int nF, int nT, const Vector3d& vtM, double dP1, double dP2, double dP3)
+ : nInd( nI), bToolOn( bTOn), nFrameId( nF), nType( nT), vtMove( vtM), dPar1( dP1), dPar2( dP2), dPar3( dP3) {}
+ } ;
+ typedef std::vector COBVECTOR ;
+ struct VmTool
+ {
+ std::string sName ;
+ std::string sHead ;
+ int nExit ;
+ double dTdOffs ;
+ double dAdOffs ;
+ VmTool( void) : nExit( 0), dTdOffs( 0), dAdOffs( 0) {}
+ VmTool( std::string sN, std::string sH, int nE, double dT, double dA)
+ : sName( sN), sHead( sH), nExit( nE), dTdOffs( dT), dAdOffs( dA) {}
+ } ;
+ typedef std::vector VMTVECTOR ;
+ enum { SIS_CREATED = 0,
+ SIS_INITIALIZED = 1,
+ SIS_READYTOSTART = 2,
+ SIS_READYTORUN = 3} ;
+
+ private :
+ MachMgr* m_pMchMgr ; // puntatore al gestore di tutte le lavorazioni
+ IGeomDB* m_pGeomDB ; // puntatore al DB geometrico
+ Machine* m_pMachine ; // puntatore alla macchina
+ PerformanceCounter* m_pPerfCnt ; // timer per calcolo FPS
+ int m_nStatus ; // stato interno del simulatore (creato, inizializzato, pronto al movimento)
+ double m_dStep ; // lunghezza di riferimento per la velocità di simulazione
+ int m_nUiStatus ; // stato simulazione a livello utente
+ int m_nOpId ; // identificativo della operazione (lavoraz.) corrente
+ int m_nOpInd ; // contatore della operazione (lavoraz.) corrente
+ int m_nCLPathId ; // identificativo del percorso di lavoro corrente
+ int m_nCLPathInd ; // contatore del percorso di lavoro corrente nell'operazione
+ int m_nEntId ; // identificativo dell'entità corrente
+ int m_nEntInd ; // contatore dell'entità corrente nel percorso di lavoro
+ double m_dCoeff ; // coefficiente di esecuzione del movimento corrente (0...1)
+ int m_nAuxSTot ; // numero totale movimenti ausiliari di inizio percorso
+ int m_nAuxSInd ; // indice del movimento ausiliario di inizio percorso corrente
+ int m_nAuxETot ; // numero totale movimenti ausiliari di fine percorso
+ int m_nAuxEInd ; // indice del movimento ausiliario di fine percorso corrente
+ std::string m_sTool ; // nome dell'utensile corrente
+ std::string m_sHead ; // nome della testa corrente
+ int m_nExit ; // indice dell'uscita corrente
+ double m_dTDiam ; // diametro dell'utensile corrente
+ bool m_bCutOnTip ; // flag capacità di lavorare di testa dell'utensile corrente
+ bool m_bEnableVm ; // flag abilitazione Virtual Milling
+ INTVECTOR m_VmId ; // vettore identificativi Zmap per Virtual Milling
+ INTVECTOR m_CdId ; // vettore identificativi Zmap per Collision Detection
+ VMTVECTOR m_VmTool ; // vettore utensili attivi per virtual milling
+ COBVECTOR m_CollObj ; // vettore oggetti da testare per collisione con grezzo
+ double m_dSafeDist ; // distanza di sicurezza per verifica collisioni
+ INTVECTOR m_nCollMarkId ; // elenco oggetti marcati per visualizzare meglio la collisione rilevata
+ int m_nAxesMask ; // maschera a bit di abilitazione movimento assi (solo se rapido)
+ bool m_bEnabAxes ; // flag abilitazione movimento assi attivi
+ bool m_bShowAxes ; // flag visualizzazione assi attivi
+ STRVECTOR m_AxesName ; // nomi degli assi macchina attivi
+ STRVECTOR m_AxesToken ; // token degli assi macchina attivi
+ BOOLVECTOR m_AxesInvert ; // flag di asse con verso invertito degli assi macchina attivi
+ DBLVECTOR m_AxesOffset ; // valore di offset delgli assi macchina ttivi
+ BOOLVECTOR m_AxesLinear ; // flag di lineare degli assi macchina attivi
+ DBLVECTOR m_AxesVal ; // valori degli assi macchina all'inizio del movimento corrente
+ STRVECTOR m_AuxAxesName ; // nomi degli assi macchina ausiliari abilitati
+ STRVECTOR m_AuxAxesToken ; // token degli assi macchina ausiliari abilitati
+ BOOLVECTOR m_AuxAxesInvert ; // flag di asse con verso invertito degli assi macchina ausiliari abilitati
+ DBLVECTOR m_AuxAxesOffset ; // valore di offset degli assi macchina ausiliari abilitati
+ BOOLVECTOR m_AuxAxesLinear ; // flag di lineare degli assi macchina ausiliari abilitati
+ DBLVECTOR m_AuxAxesVal ; // valori degli assi macchina ausiliari all'inizio del movimento corrente
+ DBLVECTOR m_AuxAxesEnd ; // valori degli assi macchina ausiliari alla fine del movimento corrente
+ INTVECTOR m_AuxAxesLink ; // indice + 1 asse principale di aggancio (negativo valore opposto, 0 nessuno)
+} ;