Files
EgtMachKernel/Machine.cpp
T
Dario Sassi 3076dccb4b EgtMachKernel 1.6e7 :
- introdotto uso ObjUser per gruppi di macchina
- prima versione prototipo delle forature
- migliorie al calolo angoli e posizioni macchina.
2015-05-26 06:49:55 +00:00

456 lines
17 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : Machine.cpp Data : 06.05.15 Versione : 1.6e3
// Contenuto : Implementazione gestione macchina.
//
//
//
// Modifiche : 06.05.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "MachMgr.h"
#include "DllMain.h"
#include "Table.h"
#include "Axis.h"
#include "Head.h"
#include "Exit.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
Machine::Machine( void)
{
m_pMchMgr = nullptr ;
m_nGroupId = GDB_ID_NULL ;
}
//----------------------------------------------------------------------------
Machine::~Machine( void)
{
Clear() ;
}
//----------------------------------------------------------------------------
void
Machine::Clear( void)
{
// cancellazione eventuali gruppi geometrici associati
if ( m_pMchMgr != nullptr && m_pMchMgr->m_pGeomDB != nullptr) {
if ( m_nGroupId != GDB_ID_NULL)
m_pMchMgr->m_pGeomDB->Erase( m_nGroupId) ;
if ( m_nTempGroupId != GDB_ID_NULL)
m_pMchMgr->m_pGeomDB->Erase( m_nTempGroupId) ;
}
// pulizia interprete lua di macchina
LuaExit() ;
// reset membri
m_pMchMgr = nullptr ;
m_sName.clear() ;
m_sMachineDir.clear() ;
m_nGroupId = GDB_ID_NULL ;
m_nTempGroupId = GDB_ID_NULL ;
m_mapGroups.clear() ;
m_mapGroups.rehash( 20) ;
}
//----------------------------------------------------------------------------
bool
Machine::Init( const std::string& sMachineName, MachMgr* pMchMgr)
{
// pulisco
Clear() ;
// verifico ambiente
if ( pMchMgr == nullptr || pMchMgr->m_nContextId == 0 || pMchMgr->m_pGeomDB == nullptr)
return false ;
m_pMchMgr = pMchMgr ;
// verifico direttorio dati macchina
m_sMachineDir = pMchMgr->m_sMachinesDir + "\\" + sMachineName ;
if ( ! ExistsDirectory( m_sMachineDir))
return false ;
// creo il gruppo per la macchina
int nId = pMchMgr->m_pGeomDB->InsertGroup( GDB_ID_NULL, pMchMgr->m_nMachAuxId, GDB_LAST_SON, GLOB_FRM) ;
if ( nId == GDB_ID_NULL)
return false ;
// imposto nome del gruppo
pMchMgr->m_pGeomDB->SetName( nId, sMachineName) ;
// carico l'interprete lua dedicato alla macchina
if ( ! LuaInit( sMachineName)) {
pMchMgr->m_pGeomDB->Erase( nId) ;
return false ;
}
// salvo i dati
m_nGroupId = nId ;
m_sName = sMachineName ;
// carico la macchina {
string sMachineMde = m_sMachineDir + "\\" + sMachineName + ".Mde" ;
bool bOk = LuaExecFile( sMachineMde) ;
// cancello il gruppo temporaneo
pMchMgr->m_pGeomDB->Erase( m_nTempGroupId) ;
m_nTempGroupId = GDB_ID_NULL ;
// in caso di errore, cancello tutta la geometria
if ( ! bOk) {
pMchMgr->m_pGeomDB->Erase( m_nGroupId) ;
pMchMgr->m_pGeomDB->Erase( m_nTempGroupId) ;
m_nGroupId = GDB_ID_NULL ;
m_nTempGroupId = GDB_ID_NULL ;
m_sName.clear() ;
m_sMachineDir.clear() ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
Machine::LoadMachineGeometry( const string& sMGeoName, const Vector3d& vtOffset)
{
// creo un sotto gruppo temporaneo in cui caricare la macchina
m_nTempGroupId = m_pMchMgr->m_pGeomDB->AddGroup( GDB_ID_NULL, m_pMchMgr->m_nMachAuxId, GLOB_FRM) ;
if ( m_nTempGroupId == GDB_ID_NULL)
return false ;
// carico la macchina
string sMachineNge = m_sMachineDir + "\\" + sMGeoName ;
if ( ! m_pMchMgr->m_pGeomDB->Load( sMachineNge, m_nTempGroupId))
return false ;
// applico offset
return m_pMchMgr->m_pGeomDB->TranslateGlob( m_nTempGroupId, vtOffset) ;
}
//----------------------------------------------------------------------------
bool
Machine::LoadMachineBase( const string& sName, const string& sGeo)
{
// recupero pezzo e layer della geometria originale della base
string sPart, sLay ;
Split( sGeo, "/", true, sPart, sLay) ;
// cerco il gruppo nella geometria originale
int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
if ( nLay == GDB_ID_NULL)
return false ;
// lo sposto nella radice della macchina
if ( ! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, m_nGroupId, GDB_FIRST_SON))
return false ;
// gli assegno il nome
m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ;
// lo inserisco nel dizionario dei gruppi della macchina
return m_mapGroups.emplace( sName, nLay).second ;
}
//----------------------------------------------------------------------------
bool
Machine::LoadMachineTable( const string& sName, const string& sParent, int nType, const string& sGeo)
{
// recupero pezzo e layer della geometria originale della tavola
string sPart, sLay ;
Split( sGeo, "/", true, sPart, sLay) ;
// cerco il gruppo nella geometria originale
int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
if ( nLay == GDB_ID_NULL)
return false ;
// cerco il gruppo padre per spostarvelo
int nParentId = GetGroup( sParent) ;
if ( nParentId == GDB_ID_NULL ||
! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON))
return false ;
// gli assegno il nome
m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ;
// installo e inizializzo il gestore della tavola
Table* pTab = new(nothrow) Table ;
if ( pTab == nullptr)
return false ;
pTab->Set( sName, nType) ;
m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pTab) ;
// lo inserisco nel dizionario dei gruppi della macchina
return m_mapGroups.emplace( sName, nLay).second ;
}
//----------------------------------------------------------------------------
bool
Machine::LoadMachineAxis( const string& sName, const string& sParent, int nType,
const Point3d& ptPos, const Vector3d& vtDir,
const STROKE& Stroke, const string& sGeo, double dVal)
{
// recupero pezzo e layer della geometria originale dell'asse
string sPart, sLay ;
Split( sGeo, "/", true, sPart, sLay) ;
// cerco il gruppo nella geometria originale
int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
if ( nLay == GDB_ID_NULL)
return false ;
// cerco il gruppo padre per spostarvelo
int nParentId = GetGroup( sParent) ;
if ( nParentId == GDB_ID_NULL ||
! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON))
return false ;
// verifico che il valore sia nei limiti di corsa
if ( dVal < Stroke.Min || dVal > Stroke.Max)
return false ;
// gli assegno il nome
m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ;
// installo e inizializzo il gestore dell'asse
Axis* pAxis = new(nothrow) Axis ;
if ( pAxis == nullptr)
return false ;
pAxis->Set( sName, nType, ptPos, vtDir, Stroke, dVal) ;
m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pAxis) ;
// inserisco il vettore rappresentativo dell'asse
if ( ! AddAxisVector( nLay, ptPos, vtDir, sName))
return false ;
// lo inserisco nel dizionario dei gruppi della macchina
return m_mapGroups.emplace( sName, nLay).second ;
}
//----------------------------------------------------------------------------
bool
Machine::AddAxisVector( int nLay, const Point3d& ptPos, const Vector3d& vtDir, const string& sName)
{
// riferimento globale del gruppo asse
Frame3d frFrame ;
m_pMchMgr->m_pGeomDB->GetGroupGlobFrame( nLay, frFrame) ;
// punto base e vettore in locale
Point3d ptBase = ptPos ;
ptBase.ToLoc( frFrame) ;
Vector3d vtAxis = vtDir ;
if ( ! vtAxis.Normalize())
return false ;
vtAxis *= AXIS_LEN ;
vtAxis.ToLoc( frFrame) ;
// vettore geometrico
PtrOwner<IGeoVector3d> pGeoVct( CreateGeoVector3d()) ;
if ( IsNull( pGeoVct) || ! pGeoVct->Set( vtAxis, ptBase))
return false ;
// lo inserisco al primo posto nel gruppo
int nId = m_pMchMgr->m_pGeomDB->InsertGeoObj( GDB_ID_NULL, nLay, GDB_FIRST_SON, Release( pGeoVct)) ;
if ( nId == GDB_ID_NULL)
return false ;
// gli assegno il nome di axis
if ( ! m_pMchMgr->m_pGeomDB->SetName( nId, sName))
return false ;
// gli assegno il colore blu
if ( ! m_pMchMgr->m_pGeomDB->SetMaterial( nId, BLUE))
return false ;
// lo nascondo
if ( ! m_pMchMgr->m_pGeomDB->SetStatus( nId, GDB_ST_OFF))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
Machine::LoadMachineStdHead( const string& sName, const string& sParent, const std::string& sHSet,
const Point3d& ptPos, const Vector3d& vtTDir,
const Vector3d& vtADir, const string& sGeo)
{
// recupero pezzo e layer della geometria originale dell'asse
string sPart, sLay ;
Split( sGeo, "/", true, sPart, sLay) ;
// cerco il gruppo nella geometria originale
int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
if ( nLay == GDB_ID_NULL)
return false ;
// cerco il gruppo padre per spostarvelo
int nParentId = GetGroup( sParent) ;
if ( nParentId == GDB_ID_NULL ||
! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON))
return false ;
// sistemo lo stato di visualizzazione
bool bShow = ( sHSet == sName) ;
m_pMchMgr->m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
// gli assegno il nome
m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ;
// installo e inizializzo il gestore della testa
Head* pHead = new(nothrow) Head ;
if ( pHead == nullptr)
return false ;
pHead->Set( sName, MCH_HT_STD, sHSet, vtADir) ;
m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pHead) ;
// aggiorno la testa capostipite
if ( ! AddHeadToSet( sHSet, sName))
return false ;
// trasformazione del riferimento di uscita in gruppo di uscita
MUEXITVECTOR vMuExit ;
vMuExit.emplace_back( ptPos, vtTDir) ;
if ( ! CreateExitGroups( nLay, vMuExit))
return false ;
// lo inserisco nel dizionario dei gruppi della macchina
return m_mapGroups.emplace( sName, nLay).second ;
}
//----------------------------------------------------------------------------
bool
Machine::LoadMachineMultiHead( const string& sName, const string& sParent, const std::string& sHSet,
const MUEXITVECTOR& vMuExit,
const Vector3d& vtADir, const string& sGeo)
{
// recupero pezzo e layer della geometria originale dell'asse
string sPart, sLay ;
Split( sGeo, "/", true, sPart, sLay) ;
// cerco il gruppo nella geometria originale
int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
if ( nLay == GDB_ID_NULL)
return false ;
// cerco il gruppo padre per spostarvelo
int nParentId = GetGroup( sParent) ;
if ( nParentId == GDB_ID_NULL ||
! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON))
return false ;
// sistemo lo stato di visualizzazione
bool bShow = ( sHSet == sName) ;
m_pMchMgr->m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
// gli assegno il nome
m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ;
// installo e inizializzo il gestore della testa
Head* pHead = new(nothrow) Head ;
if ( pHead == nullptr)
return false ;
pHead->Set( sName, MCH_HT_MULTI, sHSet, vtADir) ;
m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pHead) ;
// aggiorno la testa capostipite
if ( ! AddHeadToSet( sHSet, sName))
return false ;
// trasformazione dei riferimenti di uscita in gruppi di uscita
if ( ! CreateExitGroups( nLay, vMuExit))
return false ;
// lo inserisco nel dizionario dei gruppi della macchina
return m_mapGroups.emplace( sName, nLay).second ;
}
//----------------------------------------------------------------------------
int
Machine::GetGroup( const string& sGroup)
{
STRINT_UMAP::const_iterator Iter = m_mapGroups.find( sGroup) ;
return (( Iter != m_mapGroups.end()) ? Iter->second : GDB_ID_NULL) ;
}
//----------------------------------------------------------------------------
Axis*
Machine::GetAxis( int nGroup)
{
return ( dynamic_cast<Axis*>( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ;
}
//----------------------------------------------------------------------------
Table*
Machine::GetTable( int nGroup)
{
return ( dynamic_cast<Table*>( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ;
}
//----------------------------------------------------------------------------
Head*
Machine::GetHead( int nGroup)
{
return ( dynamic_cast<Head*>( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ;
}
//----------------------------------------------------------------------------
Exit*
Machine::GetExit( int nGroup)
{
return ( dynamic_cast<Exit*>( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ;
}
//----------------------------------------------------------------------------
bool
Machine::AddHeadToSet( const string& sHSet, const string& sName)
{
// se il capo-insieme coincide con la testa, non devo fare alcunchè
if ( sHSet == sName)
return true ;
// recupero la testa capo-insieme
Head* pHead = GetHead( GetGroup( sHSet)) ;
if ( pHead == nullptr)
return false ;
// aggiungo questa testa all'insieme
return pHead->AddHeadToHSet( sName) ;
}
//----------------------------------------------------------------------------
const STRVECTOR&
Machine::GetHSet( const string& sHead)
{
// vettore di stringhe vuoto, da restituire in caso di errore
static const STRVECTOR vsNull ;
// recupero la testa
Head* pHead = GetHead( GetGroup( sHead)) ;
if ( pHead == nullptr)
return vsNull ;
// recupero l'insieme di teste a cui appartiene
const STRVECTOR& vsTmp = pHead->GetHSet() ;
if ( vsTmp.empty())
return vsNull ;
// se il primo membro coincide con la testa, allora è già l'insieme di teste
if ( vsTmp[0] == sHead)
return vsTmp ;
// altrimenti cerco l'insieme della prima testa
return GetHSet( vsTmp[0]) ;
}
//----------------------------------------------------------------------------
bool
Machine::EnableHeadInSet( const string& sHead)
{
// recupero l'insieme di teste
const STRVECTOR& vsHSet = GetHSet( sHead) ;
if ( vsHSet.empty())
return false ;
// spengo tutte le teste tranne questa
for ( size_t i = 0 ; i < vsHSet.size() ; ++ i) {
int nH = GetGroup( vsHSet[i]) ;
bool bShow = ( vsHSet[i] == sHead) ;
m_pMchMgr->m_pGeomDB->SetStatus( nH, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Machine::CreateExitGroups( int nLay, const MUEXITVECTOR& vMuExit)
{
// ciclo sulle uscite
for ( int i = 0 ; i < int( vMuExit.size()) ; ++ i) {
string sName = MCH_EXIT + ToString( i+1) ;
// se trovo riferimento per uscita, lo sostituisco con gruppo equivalente
int nT = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nLay, sName) ;
if ( nT != GDB_ID_NULL && m_pMchMgr->m_pGeomDB->GetGeoType( nT) == GEO_FRAME3D) {
const Frame3d& frFrame = GetGeoFrame3d( m_pMchMgr->m_pGeomDB->GetGeoObj( nT))->GetFrame() ;
int nGT = m_pMchMgr->m_pGeomDB->InsertGroup( GDB_ID_NULL, nT, GDB_AFTER, frFrame) ;
if ( nGT == GDB_ID_NULL) {
string sOut = "Error inserting group " + sName ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
return false ;
}
m_pMchMgr->m_pGeomDB->Erase( nT) ;
// assegno nome
m_pMchMgr->m_pGeomDB->SetName( nGT, sName) ;
// installo e inizializzo il gestore dell'uscita
Exit* pExit = new(nothrow) Exit ;
if ( pExit == nullptr)
return false ;
pExit->Set( sName, vMuExit[i].ptPos, vMuExit[i].vtTDir) ;
m_pMchMgr->m_pGeomDB->SetObjUser( nGT, pExit) ;
}
else {
string sOut = "Error finding frame " + sName ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
return false ;
}
}
return true ;
}