Files
EgtMachKernel/Simulator.cpp
T
Dario Sassi bff983e12c EgtMachKernel :
- prime modifiche per tagli inclinati su esterno archi.
2020-01-20 06:52:47 +00:00

1651 lines
62 KiB
C++

//----------------------------------------------------------------------------
// 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/EGkVolZmap.h"
#include "/EgtDev/Include/EGkStringUtils3d.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 = 100.0 ;
static const double MID_STEP = 50.0 ;
static const double COEFF_LIM = 0.999 ;
static const double SAFEDIST_STD = 5.0 ;
//----------------------------------------------------------------------------
Simulator::Simulator( void)
{
m_pMchMgr = nullptr ;
m_pGeomDB = nullptr ;
m_pMachine = nullptr ;
m_pPerfCnt = nullptr ;
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_dVmTdOffs = 0 ;
m_dVmAdOffs = 0 ;
m_dSafeDist = SAFEDIST_STD ;
m_bEnabAxes = 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() ;
// 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 ;
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() ;
// Forzo aggiornamento attrezzaggio della macchinata
bool bOk = m_pMchMgr->UpdateSetup() ;
// Se avvio vero, verifico attrezzaggio
if ( bFirst && ! VerifySetup())
bOk = false ;
// Reset utensile, interpolazione e assi correnti
m_sTool.clear() ;
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(), true) ;
m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_SIMSTEP, m_dStep, true) ;
// Richiamo funzione su avvio simulazione
if ( ! OnStart( bFirst))
bOk = false ;
// Arrivo alla preparazione per la prima lavorazione
int nStatus ;
if ( ! FindAndManageOperationStart( true, bFirst, nStatus))
bOk = false ;
// Reset timer
if ( m_pPerfCnt != nullptr)
m_pPerfCnt->Start() ;
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_dVmTdOffs = 0 ;
m_dVmAdOffs = 0 ;
m_dSafeDist = SAFEDIST_STD ;
m_bEnabAxes = true ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::Move( int& nStatus)
{
// Verifiche
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr) {
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() ;
}
// 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
if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd == 0 && m_nCLPathInd > 0) {
// gestione fine percorso di lavoro
if ( ! ManagePathEnd( nStatus))
return false ;
}
// Se alla fine del percorso dopo esecuzione azioni ausiliarie
if ( m_nEntId == GDB_ID_NULL && m_nAuxEInd >= m_nAuxETot) {
// 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) {
OnEnd() ;
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_bEnabAxes ? 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
if ( nI < nAxisCount) {
if ( m_AxesInvert[nI])
dVal = - dVal ;
}
else {
if ( m_AuxAxesInvert[nI - nAxisCount])
dVal = - dVal ;
}
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, true) ;
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, true) ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::GoHome( void)
{
// controllo validità stato
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr)
return false ;
// porto la macchina in home
m_pMchMgr->ResetAllAxesPos() ;
// reset stato macchina
OnResetMachine() ;
// assegno valori home degli assi macchina attivi
return m_pMchMgr->GetAllCurrAxesHomePos( m_AxesVal) ;
}
//----------------------------------------------------------------------------
bool
Simulator::UpdateTool( bool bFirst)
{
// 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) ;
}
// se cambierà ed esiste il corrente, lo scarico
if ( sTool != m_sTool && ! m_sTool.empty()) {
// eventuale lancio script per scarico utensile
if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos))
return false ;
}
// se cambiato oppure prima volta, attivo l'utensile della lavorazione
if ( sTool != m_sTool || bFirst) {
// se prima volta, pulisco la testa
if ( bFirst)
m_pMchMgr->ResetHeadSet( sHead) ;
// carico l'utensile (e lo rendo corrente)
if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
return false ;
m_sTool = sTool ;
// aggiorno gli assi macchina
if ( ! UpdateAxes())
return false ;
// eventuali offset per Vmill (per adattare lo ZeroT macchina con quello di Zmap)
int nToolType ; m_pMchMgr->TdbGetCurrToolParam( TPA_TYPE, nToolType) ;
if ( nToolType == TT_MORTISE_STD) {
double dThick ; m_pMchMgr->TdbGetCurrToolParam( TPA_THICK, dThick) ;
m_dVmTdOffs = 0 ;
m_dVmAdOffs = 0.5 * dThick ;
}
else if ( nToolType == TT_SAW_STD || nToolType == TT_SAW_FLAT) {
double dLen ; m_pMchMgr->TdbGetCurrToolParam( TPA_LEN, dLen) ;
double dThick ; m_pMchMgr->TdbGetCurrToolParam( TPA_THICK, dThick) ;
m_dVmTdOffs = - dLen + dThick ;
m_dVmAdOffs = 0 ;
}
else {
m_dVmTdOffs = 0 ;
m_dVmAdOffs = 0 ;
}
// eventuale lancio script
if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst))
return false ;
}
return true ;
}
// 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
if ( ! OnToolDeselect( sTool, sHead, nExit, sTcPos))
return false ;
}
// carico l'utensile
if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
return false ;
m_sTool = sTool ;
// aggiorno gli assi macchina
if ( ! UpdateAxes())
return false ;
// eventuale lancio script
if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos, bFirst))
return false ;
return true ;
}
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->GetAllCurrAxesName( m_AxesName) ||
! pMachine->GetAllCurrAxesToken( m_AxesToken))
return false ;
// Aggiorno flag invertito, il tipo e la 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) ;
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() ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::ResetAuxAxes( void)
{
// pulisco dati assi ausiliari
m_AuxAxesName.clear() ;
m_AuxAxesToken.clear() ;
m_AuxAxesInvert.clear() ;
m_AuxAxesLinear.clear() ;
m_AuxAxesVal.clear() ;
m_AuxAxesEnd.clear() ;
// abilito assi principali
m_bEnabAxes = 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()) {
// aggiorno utensile e assi conseguenti
if ( ! UpdateTool( bFirst)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
return 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) ;
// richiamo gestione evento inizio lavorazione
if ( ! OnMachiningStart( m_nOpId, m_nOpInd, ptMin, ptMax)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
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 = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
return false ;
}
// cambio fase
m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ;
// aggiorno utensile e assi conseguenti
if ( ! UpdateTool( bFirst)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
return false ;
}
++ m_nOpInd ;
// richiamo gestione evento inizio disposizione
if ( ! OnDispositionStart( m_nOpId, m_nOpInd, nPhase, sTable, ptOri1, false, bSomeByHand)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
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 = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
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 = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
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 = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
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 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, dElev)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
return false ;
}
}
// se altrimenti trovato nuovo CL path vuoto
else if ( m_nCLPathId != GDB_ID_NULL) {
// non ci possono essere eventi ausiliari di inizio
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 = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
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 = ( Stopped() ? MCH_SIM_STOP : ( nErr == 1 ? MCH_SIM_OUTSTROKE : MCH_SIM_ERR)) ;
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 = ( Stopped() ? MCH_SIM_STOP : ( nErr == 1 ? MCH_SIM_OUTSTROKE : MCH_SIM_ERR)) ;
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 movimento in rapido muovo solo gli assi abilitati dal mask
if ( nMoveType == 0) {
for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
if ( ( pCamData->GetAxesMask() & 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 ;
int nErr ;
if ( ! OnMoveStart( pCamData, nErr)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : ( nErr == 1 ? MCH_SIM_OUTSTROKE : MCH_SIM_ERR)) ;
return false ;
}
}
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 (primi 3) e rotanti (altri)
double dSqCoeff = (( i < 3) ? 1 : 100) ;
dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ;
}
double dPrevCoeff = m_dCoeff ;
double dDist = sqrt( dSqDist) ;
if ( dDist > EPS_SMALL) {
int nStep = int( max( dDist / ( ( nMoveType == 0 ? 2 : 1) * m_dStep), 1.)) ;
m_dCoeff += 1. / nStep ;
if ( m_dCoeff > 1)
m_dCoeff = 1 ;
}
else
m_dCoeff = 1 ;
dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
// Posizione e direzione attuali dell'utensile e riferimento attuale del pezzo (per Vmill)
Point3d ptNoseI ; Vector3d vtDirI ; Vector3d vtAuxI ;
bool bOkI = GetHeadCurrPosDirAux( ptNoseI, vtDirI, vtAuxI) ;
vector<Frame3d> vFrVzmI( m_VmId.size()) ;
for ( int i = 0 ; i < int( m_VmId.size()) ; ++ i)
bOkI = m_pGeomDB->GetGlobFrame( m_VmId[i], vFrVzmI[i]) && bOkI ;
// Eseguo movimento rapido o lineare
if ( nMoveType != 2 && nMoveType != 3) {
// assegno posizioni finali
for ( int i = 0 ; i < int( m_AxesName.size()) ; ++ i) {
double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ;
m_pMachine->SetAxisPos( m_AxesName[i], dVal) ;
}
// eseguo eventuale Vmill
Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
bool bOkF = GetHeadCurrPosDirAux( ptNoseF, vtDirF, vtAuxF) ;
for ( int j = 0 ; j < int( m_VmId.size()) ; ++ j) {
Frame3d frVzmF ;
bOkF = m_pGeomDB->GetGlobFrame( m_VmId[j], frVzmF) && bOkF ;
ExecLineVmill( m_VmId[j], ptNoseI, vtDirI, vtAuxI, vFrVzmI[j], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
}
}
// 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) ;
// approssimo movimento con 1 o più step a seconda ci sia Vmill
int nStep = 1 ;
if ( ! m_VmId.empty()) {
const double LEN_STEP = 2. ;
nStep = max( int( abs( dDiffAng * DEGTORAD * dRad) / LEN_STEP), 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 ;
// assi lineari
vtRot.Rotate( vtN, dDiffAng / nStep) ;
m_pMachine->SetAxisPos( m_AxesName[0], ptCen.x + vtRot.x + dCurrCoeff * dDeltaN * vtN.x) ;
m_pMachine->SetAxisPos( m_AxesName[1], ptCen.y + vtRot.y + dCurrCoeff * dDeltaN * vtN.y) ;
m_pMachine->SetAxisPos( m_AxesName[2], ptCen.z + vtRot.z + dCurrCoeff * dDeltaN * vtN.z) ;
// assi rotanti
for ( int j = 3 ; j < int( m_AxesName.size()) ; ++ j) {
double dVal = m_AxesVal[j] * ( 1 - dCurrCoeff) + AxesEnd[j] * dCurrCoeff ;
m_pMachine->SetAxisPos( m_AxesName[j], dVal) ;
}
// eseguo eventuale Vmill
Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ;
bool bOkF = GetHeadCurrPosDirAux( 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], ptNoseI, vtDirI, vtAuxI, vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ;
// salvo riferimento per prossimo inizio
vFrVzmI[k] = frVzmF ;
}
// aggiorno prossimo inizio
ptNoseI = ptNoseF ;
vtDirI = vtDirF ;
}
}
}
else {
// Calcolo distanza di movimento
double dSqDist = 0 ;
for ( size_t i = 0 ; i < m_AuxAxesName.size() ; ++ i) {
// coefficiente moltiplicativo per differenziare assi lineari e rotanti
double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : 100) ;
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) {
int nStep = int( max( dDist / ( ( nMoveType == 0 ? 4 : 1) * m_dStep), 1.)) ;
m_dCoeff += 1. / nStep ;
if ( m_dCoeff > 1)
m_dCoeff = 1 ;
}
else
m_dCoeff = 1 ;
dMove = ( m_dCoeff - dPrevCoeff) * dDist ;
}
// Muovo eventuali assi ausiliari
for ( size_t i = 0 ; i < m_AuxAxesName.size() ; ++ i) {
double dVal = m_AuxAxesVal[i] * ( 1 - m_dCoeff) + m_AuxAxesEnd[i] * m_dCoeff ;
m_pMachine->SetAxisPos( m_AuxAxesName[i], dVal) ;
}
// Eseguo eventuale verifica di collisione
int nCdInd, nObjInd ;
if ( ! ExecCollisionCheck( nCdInd, nObjInd)) {
// Richiamo funzione di convalida collisione
int nErr ;
if ( ! OnCollision( nCdInd, nObjInd, nErr)) {
nStatus = ( Stopped() ? MCH_SIM_STOP : ( nErr == 1 ? MCH_SIM_COLLISION : MCH_SIM_ERR)) ;
// Se arrivato a fine interpolazione movimento, salvo posizioni
if ( m_dCoeff > COEFF_LIM && m_bEnabAxes) {
for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i)
m_AxesVal[i] = AxesEnd[i] ;
}
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à
if ( ! OnMoveEnd()) {
nStatus = ( Stopped() ? MCH_SIM_STOP : MCH_SIM_ERR) ;
return false ;
}
}
// Altrimenti sto muovendomi all'interno dell'entità
else
nStatus = MCH_SIM_OK ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::GetHeadCurrPosDirAux( Point3d& ptH, Vector3d& vtH, Vector3d& vtA)
{
// ci devono essere almeno i tre assi lineari
if ( m_AxesName.size() < 3)
return false ;
// recupero le posizioni degli assi lineari
DBLVECTOR vLinAx( 3) ;
for ( size_t i = 0 ; i < 3 ; ++ i)
m_pMachine->GetAxisPos( m_AxesName[i], vLinAx[i]) ;
// recupero le posizioni degli eventuali assi rotanti
DBLVECTOR vRotAx( m_AxesName.size() - 3) ;
for ( size_t i = 3 ; i < m_AxesName.size() ; ++ i)
m_pMachine->GetAxisPos( m_AxesName[i], vRotAx[i-3]) ;
// determino posizione e orientamento della testa
m_pMachine->GetNoseFromPositions( vLinAx[0], vLinAx[1], vLinAx[2], vRotAx, ptH) ;
m_pMachine->GetToolDirFromAngles( vRotAx, vtH) ;
m_pMachine->GetAuxDirFromAngles( vRotAx, vtA) ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::ExecLineVmill( int nVmId, 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)
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 += m_dVmTdOffs * vtHiL + m_dVmAdOffs * vtAiL ;
ptHfL += m_dVmTdOffs * vtHfL + m_dVmAdOffs * vtAfL ;
// Log per debug
if ( ExeGetDebugLevel() >= 10) {
string sOut = "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())
}
// Eseguo
return pVZM->MillingStep( ptHiL, vtHiL, vtAiL, ptHfL, vtHfL, vtAfL) ;
}
//----------------------------------------------------------------------------
bool
Simulator::ExecCollisionCheck( int& nCdInd, int& nObjInd)
{
// se non ci sono oggetti da controllare o non c'è il grezzo lavorato, tutto bene
if ( m_CollObj.empty() || m_CdId.empty())
return true ;
// ciclo sui grezzi
for ( int i = 0 ; i < int( m_CdId.size()) ; ++ i) {
const IVolZmap* pVZM = GetVolZmap( m_pGeomDB->GetGeoObj( m_CdId[i])) ;
if ( pVZM == nullptr)
continue ;
Frame3d frZM ; m_pGeomDB->GetGlobFrame( m_CdId[i], frZM) ;
// ciclo sugli oggetti da verificare
for ( int j = 0 ; j < int( m_CollObj.size()) ; ++ j) {
bool bOk = true ;
const IGeoFrame3d* pGeoFrame = GetGeoFrame3d( m_pGeomDB->GetGeoObj( m_CollObj[j].nFrameId)) ;
if ( pGeoFrame == nullptr)
continue ;
Frame3d frObj = pGeoFrame->GetFrame() ;
Frame3d frParent ; m_pGeomDB->GetGlobFrame( m_CollObj[j].nFrameId, frParent) ;
frObj.LocToLoc( frParent, frZM) ;
if ( m_CollObj[j].nType == MCH_SIM_COB_BOX) {
Vector3d vtDiag( m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_CollObj[j].dPar3) ;
bOk = pVZM->AvoidBox( frObj, vtDiag, m_dSafeDist) ;
}
else if ( m_CollObj[j].nType == MCH_SIM_COB_CYL) {
bOk = pVZM->AvoidCylinder( frObj, m_CollObj[j].dPar1, m_CollObj[j].dPar2, m_dSafeDist) ;
}
else if ( m_CollObj[j].nType == MCH_SIM_COB_SPHE) {
bOk = pVZM->AvoidSphere( frObj.Orig(), m_CollObj[j].dPar1, m_dSafeDist) ;
}
if ( ! bOk) {
nCdInd = i ;
nObjInd = j ;
return false ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnStart( 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::OnEnd( 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)
{
// 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
int nNumAxes = int( m_AxesName.size()) ;
for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
if ( i <= nNumAxes) {
if ( ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisToken(i), m_AxesToken[i-1]) ||
! m_pMachine->LuaSetGlobVar( GetGlobVarAxisName(i), m_AxesName[i-1]))
return false ;
}
else {
if ( ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisToken(i)) ||
! m_pMachine->LuaResetGlobVar( GetGlobVarAxisName(i)))
return false ;
}
}
// assegno il flag di chiamata di utensile iniziale
if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FIRST, bFirst))
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 distanza di sicurezza per verifica collisione
m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_SAFEDIST, m_dSafeDist) ;
// recupero i dati di ritorno per assi ausiliari
ResetAuxAxes() ;
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_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 ; 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->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_AuxAxesLinear.push_back( bLinear) ;
m_AuxAxesVal.emplace_back( dVal) ;
m_AuxAxesEnd.emplace_back( dVal) ;
}
}
else
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnToolDeselect( const string& sNextTool, const string& sNextHead, int nNextExit, const string& sNextTcPos)
{
// 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) ;
// 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() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnMachiningStart( int nOpId, int nOpInd, const Point3d& ptMin, const Point3d& ptMax)
{
// 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 ;
// 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, 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 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, 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_FLAG, pCamData->GetFlag()) ;
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
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), m_AxesVal[i-1]) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisValue( i), AxesEnd[i-1]) ;
}
else {
bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisPrev( i)) ;
bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisValue( i)) ;
}
}
// 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
if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_ENABAXES, m_bEnabAxes))
m_bEnabAxes = true ;
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_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 ; bool bLinear ; double dVal ; double dEnd ;
string sAuxAxVal = GLOB_VAR + GVAR_AN ; ReplaceString( sAuxAxVal, "N", ToString( i)) ;
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->GetAxisType( sName, bLinear) &&
m_pMachine->GetAxisPos( sName, dVal) &&
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_AuxAxesLinear.push_back( bLinear) ;
m_AuxAxesVal.emplace_back( dVal) ;
m_AuxAxesEnd.emplace_back( dEnd) ;
if ( ! m_pMachine->VerifyOutstroke( sName, dEnd)) {
nErr = 1 ;
bOk = false ;
}
}
}
else
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnMoveEnd( void)
{
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_END))
return true ;
// chiamo la funzione
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_END) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
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) ;
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, int nFrameId, int nType, 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 ( abs( dPar1) < EPS_SMALL || abs( dPar2) < EPS_SMALL)
return false ;
break ;
case MCH_SIM_COB_SPHE :
if ( abs( dPar1) < EPS_SMALL)
return false ;
break ;
default :
return false ;
}
// aggiungo al vettore
m_CollObj.emplace_back( nInd, nFrameId, nType, dPar1, dPar2, dPar3) ;
return true ;
}