06261b64be
- adattamenti e ricompilazione per passaggio a C++ 20.
1380 lines
52 KiB
C++
1380 lines
52 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2021
|
|
//----------------------------------------------------------------------------
|
|
// File : Machine.cpp Data : 14.10.21 Versione : 2.3j5
|
|
// 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 "TcPos.h"
|
|
#include "Exit.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
#include "/EgtDev/Include/EGnFileUtils.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
Machine::Machine( void)
|
|
{
|
|
m_pMchMgr = nullptr ;
|
|
m_pGeomDB = nullptr ;
|
|
m_nContextId = 0 ;
|
|
m_nGroupId = GDB_ID_NULL ;
|
|
m_nTempGroupId = GDB_ID_NULL ;
|
|
m_dAxisMaxAdjust = EPS_SMALL ;
|
|
m_dAxisMaxRotAdj = 10 * EPS_ANG_SMALL ;
|
|
m_dExitMaxAdjust = EPS_SMALL ;
|
|
m_dExitMaxRotAdj = 10 * EPS_ANG_SMALL ;
|
|
m_dAngDeltaMinForHome = INFINITO ;
|
|
m_nMultiProcess = 0 ;
|
|
m_nLinkAxesMoveOrder = 0 ;
|
|
m_nNewLinkMgr = 0 ;
|
|
m_nCalcTabId = GDB_ID_NULL ;
|
|
m_nCalcHeadId = GDB_ID_NULL ;
|
|
m_nCalcExitId = GDB_ID_NULL ;
|
|
m_nCalcToolId = GDB_ID_NULL ;
|
|
m_dCalcRot1W = ROT1_WEIGHT_DFLT ;
|
|
m_dSingConeAng = SING_CONE_ANG_DFLT ;
|
|
m_bCalcMaxDeltaR2On1 = true ;
|
|
m_nCalcSolCh = MCH_SCC_NONE ;
|
|
m_bSolChExact = false ;
|
|
m_dCalcTLen = 0 ;
|
|
m_dCalcTRad = 0 ;
|
|
m_dCalcTOvLen = 0 ;
|
|
m_dCalcTOvRad = 0 ;
|
|
m_nTabLinAxes = 0 ;
|
|
m_nTabRotAxes = 0 ;
|
|
m_nHeadLinAxes = 0 ;
|
|
m_nHeadRotAxes = 0 ;
|
|
m_nHeadSpecRotAxis = -1 ;
|
|
m_frLinAx.Reset( false) ;
|
|
m_frRobot.Reset( false) ;
|
|
m_nCalcChainType = KIN_CHAIN_NONE ;
|
|
m_nMachineLook = MCH_LOOK_NONE ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Machine::~Machine( void)
|
|
{
|
|
Clear() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
Machine::Clear( void)
|
|
{
|
|
// cancellazione eventuali gruppi geometrici associati
|
|
if ( m_pGeomDB != nullptr) {
|
|
if ( m_nGroupId != GDB_ID_NULL)
|
|
m_pGeomDB->Erase( m_nGroupId) ;
|
|
if ( m_nTempGroupId != GDB_ID_NULL)
|
|
m_pGeomDB->Erase( m_nTempGroupId) ;
|
|
}
|
|
// pulizia interprete lua di macchina
|
|
LuaExit() ;
|
|
// reset membri
|
|
m_pMchMgr = nullptr ;
|
|
m_pGeomDB = nullptr ;
|
|
m_nContextId = 0 ;
|
|
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 string& sMachineName, const string& sMachineDir, MachMgr* pMchMgr)
|
|
{
|
|
// pulisco
|
|
Clear() ;
|
|
// verifico ambiente
|
|
if ( pMchMgr == nullptr || pMchMgr->GetContextId() == 0 || pMchMgr->GetGeomDB() == nullptr)
|
|
return false ;
|
|
m_pMchMgr = pMchMgr ;
|
|
m_pGeomDB = m_pMchMgr->GetGeomDB() ;
|
|
m_nContextId = m_pMchMgr->GetContextId() ;
|
|
// verifico direttorio dati macchina
|
|
m_sMachineDir = sMachineDir ;
|
|
if ( ! ExistsDirectory( m_sMachineDir))
|
|
return false ;
|
|
// creo il gruppo per la macchina
|
|
int nId = m_pGeomDB->InsertGroup( GDB_ID_NULL, pMchMgr->GetMachAuxId(), GDB_LAST_SON, GLOB_FRM) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// imposto nome del gruppo
|
|
m_pGeomDB->SetName( nId, sMachineName) ;
|
|
// carico l'interprete lua dedicato alla macchina
|
|
if ( ! LuaInit( sMachineName)) {
|
|
m_pGeomDB->Erase( nId) ;
|
|
return false ;
|
|
}
|
|
// salvo i dati
|
|
m_nGroupId = nId ;
|
|
m_sName = sMachineName ;
|
|
// carico la macchina {
|
|
string sMachineMlde = m_sMachineDir + "\\" + sMachineName + ".Mlde" ;
|
|
if ( ! ExistsFile( sMachineMlde))
|
|
sMachineMlde = m_sMachineDir + "\\" + sMachineName + ".Mde" ;
|
|
bool bOk = LuaLoadMachine( sMachineMlde) ;
|
|
// cancello il gruppo temporaneo
|
|
m_pGeomDB->Erase( m_nTempGroupId) ;
|
|
m_nTempGroupId = GDB_ID_NULL ;
|
|
// in caso di errore, cancello tutta la geometria
|
|
if ( ! bOk) {
|
|
m_pGeomDB->Erase( m_nGroupId) ;
|
|
m_nGroupId = GDB_ID_NULL ;
|
|
m_sName.clear() ;
|
|
m_sMachineDir.clear() ;
|
|
}
|
|
// imposto stato di visualizzazione
|
|
m_nMachineLook = ( bOk ? MCH_LOOK_ALL : MCH_LOOK_NONE) ;
|
|
// metto tutti gli assi in posizione home
|
|
bOk = bOk && ResetAllAxesPos( true, true) ;
|
|
// reset catena cinematica corrente
|
|
m_nCalcChainType = KIN_CHAIN_NONE ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineGeometry( const string& sMGeoName, const Vector3d& vtOffset)
|
|
{
|
|
// creo un sotto gruppo temporaneo in cui caricare la macchina
|
|
m_nTempGroupId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_pMchMgr->GetMachAuxId(), GLOB_FRM) ;
|
|
if ( m_nTempGroupId == GDB_ID_NULL)
|
|
return false ;
|
|
// carico la macchina
|
|
string sMachineNge = m_sMachineDir + "\\" + sMGeoName ;
|
|
if ( ! m_pGeomDB->Load( sMachineNge, m_nTempGroupId))
|
|
return false ;
|
|
// applico offset
|
|
return m_pGeomDB->TranslateGlob( m_nTempGroupId, vtOffset) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineBase( const string& sName, const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// 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_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
|
|
if ( nLay == GDB_ID_NULL)
|
|
return false ;
|
|
// lo sposto nella radice della macchina
|
|
if ( ! m_pGeomDB->RelocateGlob( nLay, m_nGroupId, GDB_LAST_SON))
|
|
return false ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// lo inserisco nel dizionario dei gruppi della macchina
|
|
return m_mapGroups.emplace( sName, nLay).second ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::AdjustAuxGeometry( const STRVECTOR& vsAux, int nLay)
|
|
{
|
|
// sistemo la geometria ausiliaria
|
|
for ( const auto& sAux : vsAux) {
|
|
// recupero pezzo e layer della geometria ausiliaria
|
|
string sAuxPart, sAuxLay ;
|
|
Split( sAux, "/", true, sAuxPart, sAuxLay) ;
|
|
// cerco il gruppo nella geometria originale
|
|
int nAuxPart = m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sAuxPart) ;
|
|
int nAuxLay = m_pGeomDB->GetFirstNameInGroup( nAuxPart, sAuxLay) ;
|
|
if ( nAuxLay == GDB_ID_NULL)
|
|
return false ;
|
|
// lo sposto nel gruppo
|
|
if ( ! m_pGeomDB->RelocateGlob( nAuxLay, nLay, GDB_LAST_SON))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineTable( const string& sName, const string& sParent, int nType,
|
|
const Point3d& ptRef1, double dCoeffX, double dCoeffY, double dCoeffZ,
|
|
const STRVECTOR& vsColl, const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// 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_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = 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_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON))
|
|
return false ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// aggiusto la posizione della tavola
|
|
if ( ! AdjustTable( nLay, ptRef1))
|
|
return false ;
|
|
// eseguo eventuale scalatura
|
|
if ( abs( dCoeffX - 1.0) > EPS_ZERO ||
|
|
abs( dCoeffY - 1.0) > EPS_ZERO ||
|
|
abs( dCoeffZ - 1.0) > EPS_ZERO) {
|
|
if ( ! m_pGeomDB->ScaleGlob( nLay, Frame3d( ptRef1), dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
}
|
|
// recupero l'area valida
|
|
int nAreaId = m_pGeomDB->GetFirstNameInGroup( nLay, MCH_TAREA + "1") ;
|
|
BBox3d b3Area1 ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nAreaId, b3Area1))
|
|
return false ;
|
|
// installo e inizializzo il gestore della tavola
|
|
Table* pTab = new(nothrow) Table ;
|
|
if ( pTab == nullptr)
|
|
return false ;
|
|
pTab->Set( sName, nType, ptRef1, b3Area1, vsColl) ;
|
|
m_pGeomDB->SetUserObj( nLay, pTab) ;
|
|
// lo inserisco nel dizionario dei gruppi della macchina
|
|
return m_mapGroups.emplace( sName, nLay).second ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::AdjustTable( int nLay, const Point3d& ptRef1)
|
|
{
|
|
// riferimento globale del gruppo tavola
|
|
Frame3d frTable ;
|
|
m_pGeomDB->GetGroupGlobFrame( nLay, frTable) ;
|
|
// recupero il primo riferimento della tavola
|
|
int nRef1 = m_pGeomDB->GetFirstNameInGroup( nLay, MCH_TREF + "1") ;
|
|
if ( nRef1 == GDB_ID_NULL || m_pGeomDB->GetGeoType( nRef1) != GEO_FRAME3D) {
|
|
string sOut = " Missing " + MCH_TREF + "1" ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
// recupero frame
|
|
const Frame3d& frFrame = GetGeoFrame3d( m_pGeomDB->GetGeoObj( nRef1))->GetFrame() ;
|
|
// ne calcolo l'origine in globale
|
|
Point3d ptPos = frFrame.Orig() ;
|
|
ptPos.ToGlob( frTable) ;
|
|
// verifico eventuale aggiustamento di posizione
|
|
Vector3d vtMove = ptRef1 - ptPos ;
|
|
if ( ! vtMove.IsSmall()) {
|
|
string sOut = " Move = (" + ToString( vtMove) + ")" ;
|
|
LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) ;
|
|
return m_pGeomDB->TranslateGlob( nLay, vtMove) ;
|
|
}
|
|
else
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineAxis( const string& sName, const string& sParent, const string& sToken, bool bInvert,
|
|
double dOffset, int nType, int nUse, const Point3d& ptPos, const Vector3d& vtDir,
|
|
const STROKE& Stroke, double dHome, bool bAdjustAux, const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// verifico sia di tipo ammesso
|
|
if ( nType != MCH_AT_LINEAR && nType != MCH_AT_ROTARY) {
|
|
LOG_ERROR( GetEMkLogger(), " Wrong Axis Type") ;
|
|
return false ;
|
|
}
|
|
// 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_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ;
|
|
if ( nLay == GDB_ID_NULL) {
|
|
string sOut = " Missing Axis Part " + sPart ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
// cerco il gruppo padre per spostarvelo
|
|
int nParentId = GetGroup( sParent) ;
|
|
if ( nParentId == GDB_ID_NULL ||
|
|
! m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON)) {
|
|
string sOut = " Missing Parent Group " + sParent ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
// verifico che il valore di home sia nei limiti di corsa
|
|
if ( dHome < Stroke.Min || dHome > Stroke.Max) {
|
|
LOG_ERROR( GetEMkLogger(), " Home Position Out of stroke") ;
|
|
return false ;
|
|
}
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// installo e inizializzo il gestore dell'asse
|
|
Axis* pAxis = new(nothrow) Axis ;
|
|
if ( pAxis == nullptr)
|
|
return false ;
|
|
pAxis->Set( sName, sToken, bInvert, dOffset, nType, nUse, ptPos, vtDir, Stroke, dHome) ;
|
|
m_pGeomDB->SetUserObj( nLay, pAxis) ;
|
|
// verifico il vettore rappresentativo dell'asse
|
|
if ( ! AdjustAxis( nLay, sPart, sName, nType, ptPos, vtDir, bAdjustAux))
|
|
return false ;
|
|
// lo inserisco nel dizionario dei gruppi della macchina
|
|
return m_mapGroups.emplace( sName, nLay).second ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::AdjustAxis( int nLay, const string& sPart, const string& sName,
|
|
int nType, const Point3d& ptPos, const Vector3d& vtDir, bool bAdjustAux)
|
|
{
|
|
// verifico presenza vettore asse
|
|
int nId = m_pGeomDB->GetFirstNameInGroup( nLay, sPart) ;
|
|
if ( nId == GDB_ID_NULL || m_pGeomDB->GetGeoType( nId) != GEO_VECT3D) {
|
|
string sOut = " Missing Axis Vector " + sPart ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
// lo sposto all'inizio del suo gruppo
|
|
if ( ! m_pGeomDB->Relocate( nId, nLay, GDB_FIRST_SON))
|
|
return false ;
|
|
// lo rinomino come l'asse
|
|
if ( ! m_pGeomDB->SetName( nId, sName))
|
|
return false ;
|
|
// lo nascondo
|
|
if ( ! m_pGeomDB->SetMode( nId, GDB_MD_HIDDEN))
|
|
return false ;
|
|
|
|
// riferimento globale del gruppo asse
|
|
Frame3d frFrame ;
|
|
m_pGeomDB->GetGroupGlobFrame( nLay, frFrame) ;
|
|
// recupero punto base e vettore direzione
|
|
IGeoVector3d* pGeoVct = GetGeoVector3d( m_pGeomDB->GetGeoObj( nId)) ;
|
|
Point3d ptBase = pGeoVct->GetBase() ;
|
|
Vector3d vtAxis = pGeoVct->GetVector() ;
|
|
vtAxis.Normalize() ;
|
|
// riassegno il vettore normalizzato
|
|
pGeoVct->ChangeVector( vtAxis) ;
|
|
// li porto in globale
|
|
ptBase.ToGlob( frFrame) ;
|
|
vtAxis.ToGlob( frFrame) ;
|
|
|
|
// se asse lineare devo verificarne solo la direzione
|
|
if ( nType == MCH_AT_LINEAR) {
|
|
Vector3d vtDirN = vtDir ;
|
|
if ( ! vtDirN.Normalize() || ! AreSameVectorApprox( vtAxis, vtDirN)) {
|
|
string sOut = " Wrong Axis Vector or Dir " + sPart ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
// altrimenti asse rotante, devo verificarne direzione e coassialità (questa solo se non abilitato movimento)
|
|
else {
|
|
Vector3d vtDirN = vtDir ;
|
|
if ( ! vtDirN.Normalize() || ! AreSameVectorEpsilon( vtAxis, vtDirN, 10 * SIN_EPS_ANG_SMALL)) {
|
|
double dAngRot ;
|
|
if ( ! vtAxis.GetAngle( vtDirN, dAngRot) || abs( dAngRot) > m_dAxisMaxRotAdj) {
|
|
string sOut = " Wrong Axis Vector or Dir " + sPart ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
else {
|
|
Vector3d vtRotAx = vtAxis ^ vtDirN ; vtRotAx.Normalize() ;
|
|
string sOut = " Axis " + sName + " rotation = (" + ToString( dAngRot) + "/" + ToString( vtRotAx) + ")" ;
|
|
LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) ;
|
|
m_pGeomDB->RotateGlob( nId, ptBase, vtRotAx, dAngRot) ;
|
|
}
|
|
}
|
|
Vector3d vtDelta = ptPos - ptBase ;
|
|
Vector3d vtDeltaPerp = vtDelta - ( vtDelta * vtDirN) * vtDirN ;
|
|
if ( ! vtDeltaPerp.IsSmall()) {
|
|
if ( vtDeltaPerp.Len() > m_dAxisMaxAdjust && ! bAdjustAux) {
|
|
string sOut = " Wrong Axis Base move = (" + ToString( vtDeltaPerp) + ")" ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
else {
|
|
string sOut = " Axis " + sName + " move = (" + ToString( vtDelta) + ")" ;
|
|
LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) ;
|
|
m_pGeomDB->TranslateGlob( nId, vtDelta) ;
|
|
}
|
|
}
|
|
}
|
|
// se richiesto, muovo la geometria ausiliaria
|
|
if ( bAdjustAux) {
|
|
Vector3d vtDelta = ptPos - ptBase ;
|
|
int nIdAux = m_pGeomDB->GetFirstInGroup( nLay) ;
|
|
while ( nIdAux != GDB_ID_NULL) {
|
|
if ( nIdAux != nId)
|
|
m_pGeomDB->TranslateGlob( nIdAux, vtDelta) ;
|
|
nIdAux = m_pGeomDB->GetNext( nIdAux) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::ModifyMachineAxisPosition( const string& sName, const Point3d& ptPos)
|
|
{
|
|
// controllo GeomDB
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero il gruppo dell'asse
|
|
int nAxGrp = GetGroup( sName) ;
|
|
// recupero il relativo gestore
|
|
Axis* pAx = GetAxis( nAxGrp) ;
|
|
if ( pAx == nullptr)
|
|
return false ;
|
|
// se valore dell'asse non nullo, lo annullo
|
|
double dCurrVal = pAx->GetCurrVal() ;
|
|
if ( abs( dCurrVal) > EPS_ZERO)
|
|
SetAxisPos( sName, 0, false) ;
|
|
// eseguo la modifica
|
|
bool bOk = pAx->Modify( ptPos, m_dAxisMaxAdjust) ;
|
|
// ripristino l'asse al valore corrente
|
|
if ( abs( dCurrVal) > EPS_ZERO)
|
|
SetAxisPos( sName, dCurrVal, false) ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::ModifyMachineAxisDirection( const string& sName, const Vector3d& vtDir)
|
|
{
|
|
// controllo GeomDB
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero il gruppo dell'asse
|
|
int nAxGrp = GetGroup( sName) ;
|
|
// recupero il relativo gestore
|
|
Axis* pAx = GetAxis( nAxGrp) ;
|
|
if ( pAx == nullptr)
|
|
return false ;
|
|
// se valore dell'asse non nullo, lo annullo
|
|
double dCurrVal = pAx->GetCurrVal() ;
|
|
if ( abs( dCurrVal) > EPS_ZERO)
|
|
SetAxisPos( sName, 0, false) ;
|
|
// eseguo la modifica
|
|
bool bOk = pAx->Modify( vtDir, m_dAxisMaxRotAdj) ;
|
|
// ripristino l'asse al valore corrente
|
|
if ( abs( dCurrVal) > EPS_ZERO)
|
|
SetAxisPos( sName, dCurrVal, false) ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::ModifyMachineAxisStroke( const string& sName, const STROKE& Stroke)
|
|
{
|
|
// controllo GeomDB
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero il gruppo dell'asse
|
|
int nAxGrp = GetGroup( sName) ;
|
|
// recupero il relativo gestore
|
|
Axis* pAx = GetAxis( nAxGrp) ;
|
|
if ( pAx == nullptr)
|
|
return false ;
|
|
// eseguo la modifica
|
|
return pAx->Modify( Stroke) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::ModifyMachineAxisHome( const string& sName, double dHome)
|
|
{
|
|
// controllo GeomDB
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero il gruppo dell'asse
|
|
int nAxGrp = GetGroup( sName) ;
|
|
// recupero il relativo gestore
|
|
Axis* pAx = GetAxis( nAxGrp) ;
|
|
if ( pAx == nullptr)
|
|
return false ;
|
|
// eseguo la modifica
|
|
return pAx->Modify( dHome) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineStdHead( const string& sName, const string& sParent, const string& sHSet,
|
|
const Point3d& ptPos, const Vector3d& vtTDir, const Vector3d& vtADir,
|
|
double dRot1W, bool bMaxDeltaR2On1, const STROKE& Rot2Stroke, int nSolCh, const STRVECTOR& vsOthColl,
|
|
const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// recupero pezzo e layer della geometria originale della testa
|
|
string sPart, sLay ;
|
|
Split( sGeo, "/", true, sPart, sLay) ;
|
|
// cerco il gruppo nella geometria originale
|
|
int nPart = m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = 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_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON))
|
|
return false ;
|
|
// sistemo lo stato di visualizzazione
|
|
bool bShow = ( sHSet == sName) ;
|
|
m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// installo e inizializzo il gestore della testa
|
|
Head* pHead = new(nothrow) Head ;
|
|
if ( pHead == nullptr)
|
|
return false ;
|
|
pHead->Set( sName, MCH_HT_STD, 1, sHSet, 0, vtADir, dRot1W, bMaxDeltaR2On1, Rot2Stroke, nSolCh, vsOthColl) ;
|
|
m_pGeomDB->SetUserObj( nLay, pHead) ;
|
|
// aggiorno la testa capostipite
|
|
if ( ! AddHeadToSet( sHSet, sName))
|
|
return false ;
|
|
// sistemo il riferimento dell'uscita rispetto alla direzione ausiliaria
|
|
MUEXITVECTOR vMuExit ;
|
|
vMuExit.emplace_back( ptPos, vtTDir) ;
|
|
if ( ! AdjustExitFrames( nLay, vMuExit, vtADir))
|
|
return false ;
|
|
// trasformazione del riferimento di uscita in gruppo di uscita
|
|
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 string& sHSet,
|
|
int nSelectType, const MUEXITVECTOR& vMuExit, const Vector3d& vtADir,
|
|
double dRot1W, bool bMaxDeltaR2On1, const STROKE& Rot2Stroke, int nSolCh, const STRVECTOR& vsOthColl,
|
|
const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// recupero pezzo e layer della geometria originale della testa
|
|
string sPart, sLay ;
|
|
Split( sGeo, "/", true, sPart, sLay) ;
|
|
// cerco il gruppo nella geometria originale
|
|
int nPart = m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = 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_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON))
|
|
return false ;
|
|
// sistemo lo stato di visualizzazione
|
|
bool bShow = ( sHSet == sName) ;
|
|
m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// installo e inizializzo il gestore della testa
|
|
Head* pHead = new(nothrow) Head ;
|
|
if ( pHead == nullptr)
|
|
return false ;
|
|
pHead->Set( sName, MCH_HT_MULTI, int( vMuExit.size()), sHSet, nSelectType,
|
|
vtADir, dRot1W, bMaxDeltaR2On1, Rot2Stroke, nSolCh, vsOthColl) ;
|
|
m_pGeomDB->SetUserObj( nLay, pHead) ;
|
|
// aggiorno la testa capostipite
|
|
if ( ! AddHeadToSet( sHSet, sName))
|
|
return false ;
|
|
// sistemo i riferimenti delle uscite rispetto alla direzione ausiliaria
|
|
if ( ! AdjustExitFrames( nLay, vMuExit, vtADir))
|
|
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 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineSpecialHead( const string& sName, const string& sParent, const string& sHSet,
|
|
const Point3d& ptPos, const Vector3d& vtTDir, const Vector3d& vtADir,
|
|
double dRot1W, bool bMaxDeltaR2On1, const STROKE& Rot2Stroke, int nSolCh, const STRVECTOR& vsOthColl,
|
|
const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// recupero pezzo e layer della geometria originale della testa
|
|
string sPart, sLay ;
|
|
Split( sGeo, "/", true, sPart, sLay) ;
|
|
// cerco il gruppo nella geometria originale
|
|
int nPart = m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = 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_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON))
|
|
return false ;
|
|
// sistemo lo stato di visualizzazione
|
|
bool bShow = ( sHSet == sName) ;
|
|
m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// installo e inizializzo il gestore della testa
|
|
Head* pHead = new(nothrow) Head ;
|
|
if ( pHead == nullptr)
|
|
return false ;
|
|
pHead->Set( sName, MCH_HT_SPECIAL, 1, sHSet, 0, vtADir, dRot1W, bMaxDeltaR2On1, Rot2Stroke, nSolCh, vsOthColl) ;
|
|
m_pGeomDB->SetUserObj( nLay, pHead) ;
|
|
// aggiorno la testa capostipite
|
|
if ( ! AddHeadToSet( sHSet, sName))
|
|
return false ;
|
|
// sistemo il riferimento dell'uscita rispetto alla direzione ausiliaria
|
|
MUEXITVECTOR vMuExit ;
|
|
vMuExit.emplace_back( ptPos, vtTDir) ;
|
|
if ( ! AdjustExitFrames( nLay, vMuExit, vtADir))
|
|
return false ;
|
|
// trasformazione del riferimento di uscita in gruppo di uscita
|
|
if ( ! CreateExitGroups( nLay, vMuExit))
|
|
return false ;
|
|
// lo inserisco nel dizionario dei gruppi della macchina
|
|
return m_mapGroups.emplace( sName, nLay).second ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineStdTcPos( const string& sName, const string& sParent,
|
|
const Point3d& ptPos, const Vector3d& vtTDir, const Vector3d& vtADir,
|
|
const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// recupero pezzo e layer della geometria originale della posizione nel cambio utensile
|
|
string sPart, sLay ;
|
|
Split( sGeo, "/", true, sPart, sLay) ;
|
|
// cerco il gruppo nella geometria originale
|
|
int nPart = m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = 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_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON))
|
|
return false ;
|
|
// sistemo lo stato di visualizzazione
|
|
m_pGeomDB->SetStatus( nLay, GDB_ST_ON) ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// installo e inizializzo il gestore della posizione nel cambio utensile
|
|
TcPos* pTcPos = new(nothrow) TcPos ;
|
|
if ( pTcPos == nullptr)
|
|
return false ;
|
|
pTcPos->Set( sName, vtADir) ;
|
|
m_pGeomDB->SetUserObj( nLay, pTcPos) ;
|
|
// sistemo il riferimento dell'uscita rispetto alla direzione ausiliaria
|
|
MUEXITVECTOR vMuExit ;
|
|
vMuExit.emplace_back( ptPos, vtTDir) ;
|
|
if ( ! AdjustExitFrames( nLay, vMuExit, vtADir))
|
|
return false ;
|
|
// trasformazione del riferimento di uscita in gruppo di uscita
|
|
if ( ! CreateExitGroups( nLay, vMuExit))
|
|
return false ;
|
|
// lo inserisco nel dizionario dei gruppi della macchina
|
|
return m_mapGroups.emplace( sName, nLay).second ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LoadMachineMultiTcPos( const string& sName, const string& sParent,
|
|
const MUEXITVECTOR& vMuExit, const Vector3d& vtADir,
|
|
const string& sGeo, const STRVECTOR& vsAux)
|
|
{
|
|
// recupero pezzo e layer della geometria originale della posizione nel cambio utensile
|
|
string sPart, sLay ;
|
|
Split( sGeo, "/", true, sPart, sLay) ;
|
|
// cerco il gruppo nella geometria originale
|
|
int nPart = m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ;
|
|
int nLay = 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_pGeomDB->RelocateGlob( nLay, nParentId, GDB_LAST_SON))
|
|
return false ;
|
|
// sistemo lo stato di visualizzazione
|
|
m_pGeomDB->SetStatus( nLay, GDB_ST_ON) ;
|
|
// gli assegno il nome
|
|
m_pGeomDB->SetName( nLay, sName) ;
|
|
// sistemo la geometria ausiliaria
|
|
if ( ! AdjustAuxGeometry( vsAux, nLay))
|
|
return false ;
|
|
// installo e inizializzo il gestore della posizione nel cambio utensile
|
|
TcPos* pTcPos = new(nothrow) TcPos ;
|
|
if ( pTcPos == nullptr)
|
|
return false ;
|
|
pTcPos->Set( sName, vtADir) ;
|
|
m_pGeomDB->SetUserObj( nLay, pTcPos) ;
|
|
// sistemo il riferimento dell'uscita rispetto alla direzione ausiliaria
|
|
if ( ! AdjustExitFrames( nLay, vMuExit, vtADir))
|
|
return false ;
|
|
// trasformazione del riferimento di uscita in gruppo 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) const
|
|
{
|
|
STRINT_UMAP::const_iterator Iter = m_mapGroups.find( sGroup) ;
|
|
return (( Iter != m_mapGroups.end()) ? Iter->second : GDB_ID_NULL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::IsBaseGroup( int nGroup) const
|
|
{
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// deve essere nel primo gruppo della macchina
|
|
return ( m_pGeomDB->GetParentId( nGroup) == m_nGroupId) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Table*
|
|
Machine::GetTable( int nGroup) const
|
|
{
|
|
return ( dynamic_cast<Table*>( m_pGeomDB->GetUserObj( nGroup))) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Axis*
|
|
Machine::GetAxis( int nGroup) const
|
|
{
|
|
return ( dynamic_cast<Axis*>( m_pGeomDB->GetUserObj( nGroup))) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::IsLinearAxisGroup( int nGroup) const
|
|
{
|
|
Axis* pAx = GetAxis( nGroup) ;
|
|
return ( pAx != nullptr && pAx->GetType() == MCH_AT_LINEAR) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::IsRotaryAxisGroup( int nGroup) const
|
|
{
|
|
Axis* pAx = GetAxis( nGroup) ;
|
|
return ( pAx != nullptr && pAx->GetType() == MCH_AT_ROTARY) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Head*
|
|
Machine::GetHead( int nGroup) const
|
|
{
|
|
return ( dynamic_cast<Head*>( m_pGeomDB->GetUserObj( nGroup))) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
TcPos*
|
|
Machine::GetTcPos( int nGroup) const
|
|
{
|
|
return ( dynamic_cast<TcPos*>( m_pGeomDB->GetUserObj( nGroup))) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Exit*
|
|
Machine::GetExit( int nGroup) const
|
|
{
|
|
return ( dynamic_cast<Exit*>( m_pGeomDB->GetUserObj( 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) const
|
|
{
|
|
// 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 dell'insieme tranne questa
|
|
for ( size_t i = 0 ; i < vsHSet.size() ; ++ i) {
|
|
int nH = GetGroup( vsHSet[i]) ;
|
|
bool bShow = ( vsHSet[i] == sHead) ;
|
|
m_pGeomDB->SetMode( nH, ( bShow ? GDB_MD_STD : GDB_MD_HIDDEN)) ;
|
|
m_pGeomDB->SetStatus( nH, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::ModifyMachineHeadAuxDirection( const string& sHead, const Vector3d& vtADir)
|
|
{
|
|
// controllo GeomDB
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero testa
|
|
int nHeadId = GetGroup( sHead) ;
|
|
Head* pHead = GetHead( nHeadId) ;
|
|
if ( pHead == nullptr)
|
|
return false ;
|
|
// eseguo la modifica
|
|
return pHead->ModifyHeadAuxDirection( vtADir) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::AdjustExitFrames( int nLay, const MUEXITVECTOR& vMuExit, const Vector3d& vtADir)
|
|
{
|
|
// se il versore ausiliario non è definito, non sono necessari controlli
|
|
if ( vtADir.IsSmall())
|
|
return true ;
|
|
// riferimento globale del gruppo testa
|
|
Frame3d frHead ;
|
|
m_pGeomDB->GetGroupGlobFrame( nLay, frHead) ;
|
|
// porto il vettore ausiliario nel riferimento testa
|
|
Vector3d vtAuxL = vtADir ;
|
|
vtAuxL.ToLoc( frHead) ;
|
|
// 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 verifico
|
|
int nT = m_pGeomDB->GetFirstNameInGroup( nLay, sName) ;
|
|
if ( nT != GDB_ID_NULL && m_pGeomDB->GetGeoType( nT) == GEO_FRAME3D) {
|
|
// recupero frame
|
|
IGeoFrame3d* pGF = GetGeoFrame3d( m_pGeomDB->GetGeoObj( nT)) ;
|
|
Frame3d frFrame = pGF->GetFrame() ;
|
|
// determino rotazione attorno a RifAxZ per massimo allineamento RifAxX con direzione ausiliaria
|
|
bool bDet ;
|
|
double dAngRotDeg ;
|
|
if ( frFrame.VersX().GetRotation( vtAuxL, frFrame.VersZ(), dAngRotDeg, bDet) && bDet) {
|
|
if ( abs( dAngRotDeg) > EPS_ANG_SMALL) {
|
|
frFrame.Rotate( frFrame.Orig(), frFrame.VersZ(), dAngRotDeg) ;
|
|
pGF->Set( frFrame) ;
|
|
}
|
|
}
|
|
else {
|
|
string sOut = " Exit " + sName + " with frame not adjustable for AuxDir" ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
}
|
|
// se prima uscita, aggiungo vettore ausiliario
|
|
if ( i == 0) {
|
|
PtrOwner<IGeoVector3d> pGVec( CreateGeoVector3d()) ;
|
|
if ( ! IsNull( pGVec) && pGVec->Set( vtAuxL, frFrame.Orig())) {
|
|
int nAvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, Release( pGVec)) ;
|
|
m_pGeomDB->SetName( nAvId, MCH_AUX_VECT) ;
|
|
m_pGeomDB->SetMode( nAvId, GDB_MD_HIDDEN) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::CreateExitGroups( int nLay, const MUEXITVECTOR& vMuExit)
|
|
{
|
|
// riferimento globale del gruppo testa
|
|
Frame3d frHead ;
|
|
m_pGeomDB->GetGroupGlobFrame( nLay, frHead) ;
|
|
// 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_pGeomDB->GetFirstNameInGroup( nLay, sName) ;
|
|
if ( nT != GDB_ID_NULL && m_pGeomDB->GetGeoType( nT) == GEO_FRAME3D) {
|
|
// recupero frame
|
|
Frame3d frFrame = GetGeoFrame3d( m_pGeomDB->GetGeoObj( nT))->GetFrame() ;
|
|
// verifico dati frame rispetto ad uscita (in globale)
|
|
Point3d ptPos = frFrame.Orig() ;
|
|
ptPos.ToGlob( frHead) ;
|
|
Vector3d vtTDir = frFrame.VersZ() ;
|
|
vtTDir.ToGlob( frHead) ;
|
|
vtTDir.Normalize() ;
|
|
Vector3d vtDelta = vMuExit[i].ptPos - ptPos ;
|
|
if ( ! vtDelta.IsSmall()) {
|
|
if ( vtDelta.Len() > m_dExitMaxAdjust) {
|
|
string sOut = " Wrong Exit Position " + sName + " move = (" + ToString( vtDelta) + ")" ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
else {
|
|
string sOut = " Exit " + sName + " move = (" + ToString( vtDelta) + ")" ;
|
|
LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) ;
|
|
vtDelta.ToLoc( frHead) ;
|
|
frFrame.Translate( vtDelta) ;
|
|
GetGeoFrame3d( m_pGeomDB->GetGeoObj( nT))->Set( frFrame) ;
|
|
}
|
|
}
|
|
Vector3d vtDirN = vMuExit[i].vtTDir ;
|
|
if ( ! vtDirN.Normalize() || ! AreSameVectorEpsilon( vtTDir, vtDirN, 10 * SIN_EPS_ANG_SMALL)) {
|
|
double dAngRot ;
|
|
if ( ! vtTDir.GetAngle( vtDirN, dAngRot) || abs( dAngRot) > m_dExitMaxRotAdj) {
|
|
string sOut = " Wrong Exit Vector " + sName ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
else {
|
|
Vector3d vtRotAx = vtTDir ^ vtDirN ; vtRotAx.Normalize( EPS_ZERO) ;
|
|
string sOut = " Exit " + sName + " rotation = (" + ToString( dAngRot) + "/" + ToString( vtRotAx) + ")" ;
|
|
LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) ;
|
|
vtRotAx.ToLoc( frHead) ;
|
|
frFrame.Rotate( frFrame.Orig(), vtRotAx, dAngRot) ;
|
|
GetGeoFrame3d( m_pGeomDB->GetGeoObj( nT))->Set( frFrame) ;
|
|
}
|
|
}
|
|
// inserisco gruppo con riferimento del frame
|
|
int nGT = m_pGeomDB->InsertGroup( GDB_ID_NULL, nT, GDB_BEFORE, frFrame) ;
|
|
if ( nGT == GDB_ID_NULL) {
|
|
string sOut = " Error inserting group " + sName ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
// cambio nome al riferimento e lo nascondo
|
|
m_pGeomDB->SetName( nT, "_" + sName) ;
|
|
m_pGeomDB->SetStatus( nT, GDB_ST_OFF) ;
|
|
// assegno nome al gruppo
|
|
m_pGeomDB->SetName( nGT, sName) ;
|
|
// copio le info
|
|
m_pGeomDB->CopyAllInfoFrom( nGT, nT) ;
|
|
// assegno info per eventuale movimento (sempre in Z globale)
|
|
m_pGeomDB->SetInfo( nGT, MCH_EXIT_VAL, 0) ;
|
|
// 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_pGeomDB->SetUserObj( nGT, pExit) ;
|
|
}
|
|
else {
|
|
string sOut = " Error finding frame " + sName ;
|
|
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::ModifyMachineExitPosition( const string& sHead, int nExit, const Point3d& ptPos)
|
|
{
|
|
// controllo GeomDB
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero testa
|
|
int nHeadId = GetGroup( sHead) ;
|
|
Head* pHead = GetHead( nHeadId) ;
|
|
if ( pHead == nullptr)
|
|
return false ;
|
|
// recupero uscita
|
|
int nExitId = m_pGeomDB->GetFirstNameInGroup( nHeadId, MCH_EXIT + ToString( nExit)) ;
|
|
Exit* pExit = GetExit( nExitId) ;
|
|
if ( pExit == nullptr)
|
|
return false ;
|
|
// eseguo la modifica
|
|
if ( ! pExit->Modify( ptPos, m_dExitMaxAdjust))
|
|
return false ;
|
|
// eventuale aggiornamento variabile lua EMC.EXITPOS con la nuova posizione
|
|
LuaSetGlobVar( "EMC.EXITPOS", ptPos) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::SetLook( int nFlag)
|
|
{
|
|
// verifico validità flag
|
|
if ( nFlag < MCH_LOOK_TAB || nFlag > MCH_LOOK_ALL)
|
|
return false ;
|
|
|
|
// verifico DB geometrico
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
|
|
// recupero l'identificativo del gruppo di base della macchina
|
|
int nMBaseId = m_pGeomDB->GetFirstInGroup( GetMachineId()) ;
|
|
|
|
// recupero la tavola corrente (se non definita, prendo la prima)
|
|
int nTabId = GetCurrTable() ;
|
|
if ( nTabId == GDB_ID_NULL)
|
|
nTabId = GetFirstTable() ;
|
|
if ( nTabId == GDB_ID_NULL)
|
|
return false ;
|
|
// il gruppo tavola corrente deve essere sempre visibile
|
|
m_pGeomDB->SetStatus( nTabId, GDB_ST_ON) ;
|
|
// nascondo o visualizzo i fratelli e tutti i fratelli degli ascendenti della tavola
|
|
bool bTabOnly = ( nFlag != MCH_LOOK_ALL) ;
|
|
int nTabCurrId = nTabId ;
|
|
int nParentId = m_pGeomDB->GetParentId( nTabCurrId) ;
|
|
while ( nParentId != GDB_ID_NULL && nParentId != nMBaseId) {
|
|
int nId = m_pGeomDB->GetFirstInGroup( nParentId) ;
|
|
while ( nId != GDB_ID_NULL) {
|
|
if ( nId != nTabCurrId) {
|
|
if ( m_pGeomDB->GetGeoType( nId) != GEO_FRAME3D)
|
|
m_pGeomDB->SetStatus( nId, ( bTabOnly ? GDB_ST_OFF : GDB_ST_ON)) ;
|
|
else
|
|
m_pGeomDB->SetStatus( nId, GDB_ST_OFF) ;
|
|
}
|
|
nId = m_pGeomDB->GetNext( nId) ;
|
|
}
|
|
nTabCurrId = nParentId ;
|
|
nParentId = m_pGeomDB->GetParentId( nParentId) ;
|
|
}
|
|
|
|
// recupero l'utensile e l'uscita correnti (per gestire casi senza utensile)
|
|
int nToolId = GetCurrTool() ;
|
|
int nExitId = m_nCalcExitId ;
|
|
// nascondo o visualizzo i fratelli e tutti i fratelli degli ascendenti
|
|
bool bToolOnly = ( nFlag > MCH_LOOK_TAB && nFlag < MCH_LOOK_ALL) ;
|
|
int nToolCurrId = ( nToolId != GDB_ID_NULL ? nToolId : nExitId) ;
|
|
nParentId = m_pGeomDB->GetParentId( nToolCurrId) ;
|
|
while ( nParentId != GDB_ID_NULL && nParentId != nMBaseId) {
|
|
bool bHide = bToolOnly ;
|
|
if ( nFlag == MCH_LOOK_TAB_HEAD ||
|
|
( nFlag == MCH_LOOK_TAB_TOOL && nToolId == GDB_ID_NULL)) {
|
|
if ( IsHeadGroup( nParentId) || IsRotaryAxisGroup( nParentId))
|
|
bHide = false ;
|
|
}
|
|
int nId = m_pGeomDB->GetFirstInGroup( nParentId) ;
|
|
while ( nId != GDB_ID_NULL) {
|
|
if ( m_pGeomDB->GetGeoType( nId) != GEO_FRAME3D) {
|
|
if ( nId != nToolCurrId)
|
|
m_pGeomDB->SetStatus( nId, ( bHide ? GDB_ST_OFF : GDB_ST_ON)) ;
|
|
else
|
|
m_pGeomDB->SetStatus( nId, GDB_ST_ON) ;
|
|
}
|
|
else
|
|
m_pGeomDB->SetStatus( nId, GDB_ST_OFF) ;
|
|
nId = m_pGeomDB->GetNext( nId) ;
|
|
}
|
|
nToolCurrId = nParentId ;
|
|
nParentId = m_pGeomDB->GetParentId( nParentId) ;
|
|
}
|
|
|
|
// sistemo gli oggetti del gruppo di base
|
|
int nId = m_pGeomDB->GetFirstInGroup( nMBaseId) ;
|
|
while ( nId != GDB_ID_NULL) {
|
|
if ( m_pGeomDB->GetGeoType( nId) != GEO_FRAME3D) {
|
|
if ( nId != nTabCurrId && nId != nToolCurrId)
|
|
m_pGeomDB->SetStatus( nId, ( nFlag != MCH_LOOK_ALL ? GDB_ST_OFF : GDB_ST_ON)) ;
|
|
else if ( nId == nTabCurrId)
|
|
m_pGeomDB->SetStatus( nId, GDB_ST_ON) ;
|
|
else
|
|
m_pGeomDB->SetStatus( nId, ( nFlag == MCH_LOOK_TAB ? GDB_ST_OFF : GDB_ST_ON)) ;
|
|
}
|
|
else
|
|
m_pGeomDB->SetStatus( nId, GDB_ST_OFF) ;
|
|
nId = m_pGeomDB->GetNext( nId) ;
|
|
}
|
|
|
|
// aggiorno stato di visualizzazione
|
|
m_nMachineLook = nFlag ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LinkRawPartToGroup( int nRawPartId, const string& sGroupName)
|
|
{
|
|
// verifico DB geometrico e gestore lavorazioni
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero l'identificativo del gruppo di base dei grezzi
|
|
int nRawGrpId = m_pMchMgr->GetCurrRawGroupId() ;
|
|
if ( nRawGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// verifico che il grezzo appartenga a questo gruppo
|
|
if ( m_pGeomDB->GetParentId( nRawPartId) != nRawGrpId)
|
|
return false ;
|
|
// recupero il gruppo di macchina indicato
|
|
int nGrpId = GetGroup( sGroupName) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// aggancio il grezzo al gruppo
|
|
if ( ! m_pGeomDB->RelocateGlob( nRawPartId, nGrpId))
|
|
return false ;
|
|
// inserisco il grezzo nell'elenco dei linkati
|
|
m_vLinkedRawParts.push_back( nRawPartId) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::IsLinkedRawPart( int nRawId) const
|
|
{
|
|
return ( find( m_vLinkedRawParts.begin(), m_vLinkedRawParts.end(), nRawId) != m_vLinkedRawParts.end()) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const INTVECTOR&
|
|
Machine:: GetAllLinkedRawParts( void) const
|
|
{
|
|
return m_vLinkedRawParts ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::UnlinkRawPartFromGroup( int nRawPartId)
|
|
{
|
|
// verifico DB geometrico e gestore lavorazioni
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero il gruppo dei grezzi dalla macchina
|
|
int nRawGrpId = m_pMchMgr->GetCurrRawGroupId() ;
|
|
if ( nRawGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// verifico che il grezzo indicato sia nell'elenco dei linkati
|
|
auto iIter = find( m_vLinkedRawParts.begin(), m_vLinkedRawParts.end(), nRawPartId) ;
|
|
if ( iIter == m_vLinkedRawParts.end())
|
|
return false ;
|
|
// riporto il grezzo nel gruppo dei grezzi (conservando l'ordine di definizione quindi Id crescenti)
|
|
int nCurrId = m_pGeomDB->GetFirstInGroup( nRawGrpId) ;
|
|
while ( nCurrId != GDB_ID_NULL && nCurrId < nRawPartId)
|
|
nCurrId = m_pGeomDB->GetNext( nCurrId) ;
|
|
if ( nCurrId == GDB_ID_NULL) {
|
|
if ( ! m_pGeomDB->RelocateGlob( nRawPartId, nRawGrpId, GDB_LAST_SON))
|
|
return false ;
|
|
}
|
|
else {
|
|
if ( ! m_pGeomDB->RelocateGlob( nRawPartId, nCurrId, GDB_BEFORE))
|
|
return false ;
|
|
}
|
|
// tolgo il grezzo dall'elenco dei linkati
|
|
m_vLinkedRawParts.erase( iIter) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::UnlinkAllRawPartsFromGroups( void)
|
|
{
|
|
while ( m_vLinkedRawParts.size() > 0) {
|
|
int nRawId = m_vLinkedRawParts.back() ;
|
|
if ( ! UnlinkRawPartFromGroup( nRawId))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LinkFixtureToGroup( int nFxtId, const string& sGroupName)
|
|
{
|
|
// verifico DB geometrico e gestore lavorazioni
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero il gruppo delle fixtures nella macchinata corrente
|
|
int nFixtGrpId = m_pMchMgr->GetCurrFixtGroupId() ;
|
|
if ( nFixtGrpId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// verifico che il bloccaggio appartenga a questo gruppo
|
|
if ( m_pGeomDB->GetParentId( nFxtId) != nFixtGrpId)
|
|
return false ;
|
|
// recupero il gruppo di macchina indicato
|
|
int nGrpId = GetGroup( sGroupName) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// aggancio il bloccaggio al gruppo
|
|
if ( ! m_pGeomDB->RelocateGlob( nFxtId, nGrpId))
|
|
return false ;
|
|
// inserisco il bloccaggio nell'elenco dei linkati
|
|
m_vLinkedFixtures.push_back( nFxtId) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::IsLinkedFixture( int nFxtId) const
|
|
{
|
|
return ( find( m_vLinkedFixtures.begin(), m_vLinkedFixtures.end(), nFxtId) != m_vLinkedFixtures.end()) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::UnlinkFixtureFromGroup( int nFxtId)
|
|
{
|
|
// verifico DB geometrico e gestore lavorazioni
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero il gruppo delle fixtures nella macchinata corrente
|
|
int nFixtGrpId = m_pMchMgr->GetCurrFixtGroupId() ;
|
|
if ( nFixtGrpId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// verifico che il bloccaggio indicato sia nell'elenco dei linkati
|
|
auto iIter = find( m_vLinkedFixtures.begin(), m_vLinkedFixtures.end(), nFxtId) ;
|
|
if ( iIter == m_vLinkedFixtures.end())
|
|
return false ;
|
|
// riporto il bloccaggio nel gruppo delle fixtures
|
|
if ( ! m_pGeomDB->RelocateGlob( nFxtId, nFixtGrpId))
|
|
return false ;
|
|
// tolgo il bloccaggio dall'elenco dei linkati
|
|
m_vLinkedFixtures.erase( iIter) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::UnlinkAllFixturesFromGroups( void)
|
|
{
|
|
while ( m_vLinkedFixtures.size() > 0) {
|
|
int nFxtId = m_vLinkedFixtures.back() ;
|
|
if ( ! UnlinkFixtureFromGroup( nFxtId))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string KEY_SOURCE_RAW_ID = "SouRawId" ;
|
|
const string KEY_ORIG_REF = "OrigRef" ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::LinkPartToGroup( int nPartId, const string& sGroupName)
|
|
{
|
|
// verifico DB geometrico e gestore lavorazioni
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// verifico appartenenza del pezzo ad un grezzo
|
|
int nRawId = m_pMchMgr->GetRawPartFromPart( nPartId) ;
|
|
if ( nRawId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il gruppo di macchina indicato
|
|
int nGrpId = GetGroup( sGroupName) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// scrivo nel pezzo l'identificativo del grezzo di origine
|
|
m_pGeomDB->SetInfo( nPartId, KEY_SOURCE_RAW_ID, nRawId) ;
|
|
// scrivo nel pezzo il suo riferimento originale
|
|
m_pGeomDB->SetInfo( nPartId, KEY_ORIG_REF, *m_pGeomDB->GetGroupFrame( nPartId)) ;
|
|
// aggancio il pezzo al gruppo
|
|
if ( ! m_pGeomDB->RelocateGlob( nPartId, nGrpId))
|
|
return false ;
|
|
// inserisco il pezzo nell'elenco dei linkati
|
|
m_vLinkedParts.push_back( nPartId) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::IsLinkedPart( int nPartId) const
|
|
{
|
|
return ( find( m_vLinkedParts.begin(), m_vLinkedParts.end(), nPartId) != m_vLinkedParts.end()) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::UnlinkPartFromGroup( int nPartId)
|
|
{
|
|
// verifico DB geometrico e gestore lavorazioni
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero il riferimento originale del pezzo
|
|
Frame3d frPart ;
|
|
if ( ! m_pGeomDB->GetInfo( nPartId, KEY_ORIG_REF, frPart))
|
|
return false ;
|
|
m_pGeomDB->RemoveInfo( nPartId, KEY_ORIG_REF) ;
|
|
// recupero il grezzo di origine dalle info del pezzo
|
|
int nRawId ;
|
|
if ( ! m_pGeomDB->GetInfo( nPartId, KEY_SOURCE_RAW_ID, nRawId))
|
|
return false ;
|
|
m_pGeomDB->RemoveInfo( nPartId, KEY_SOURCE_RAW_ID) ;
|
|
// verifico che il pezzo indicato sia nell'elenco dei linkati
|
|
auto iIter = find( m_vLinkedParts.begin(), m_vLinkedParts.end(), nPartId) ;
|
|
if ( iIter == m_vLinkedParts.end())
|
|
return false ;
|
|
// riporto il pezzo nel suo grezzo
|
|
if ( ! m_pGeomDB->Relocate( nPartId, nRawId))
|
|
return false ;
|
|
*m_pGeomDB->GetGroupFrame( nPartId) = frPart ;
|
|
// tolgo il pezzo dall'elenco dei linkati
|
|
m_vLinkedParts.erase( iIter) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machine::UnlinkAllPartsFromGroups( void)
|
|
{
|
|
while ( m_vLinkedParts.size() > 0) {
|
|
int nPartId = m_vLinkedParts.back() ;
|
|
if ( ! UnlinkPartFromGroup( nPartId))
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|