708fe02b9b
- correzione a funzione SpecialLink e aggiunto parametro a funzione GetDoubleToolData.
1314 lines
52 KiB
C++
1314 lines
52 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : Machining.cpp Data : 10.06.15 Versione : 1.6f2
|
|
// Contenuto : Implementazione gestione base lavorazioni.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 10.06.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "DllMain.h"
|
|
#include "MachMgr.h"
|
|
#include "Machining.h"
|
|
#include "OperUserNotesConst.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGkCurve.h"
|
|
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
|
#include <algorithm>
|
|
#include <deque>
|
|
|
|
using namespace std ;
|
|
|
|
#define DEBUG 0
|
|
|
|
const string KEY_AXIS_GROUP = "PreviewAxisGroup" ;
|
|
const string KEY_ROT_AXIS_VAL = "PreviewRotAxisVal" ; // salvata per ogni gruppo di Preview
|
|
|
|
// struttura per informazioni sugli assi
|
|
struct PreviewAxisInfo {
|
|
string sName ;
|
|
double dVal ;
|
|
bool bLinear ;
|
|
PreviewAxisInfo( string sN, double dV, bool bL)
|
|
: sName( sN), dVal( dV), bLinear( bL) {}
|
|
} ;
|
|
typedef vector<PreviewAxisInfo> VPREVIEWAXISINFO ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
Machining::Machining( void)
|
|
{
|
|
m_nLookFlag = MCH_LOOK_TAB_HEAD ;
|
|
m_nPreviewHeadId = GDB_ID_NULL ;
|
|
m_nPreviewHeadIdDBL = GDB_ID_NULL ;
|
|
m_nPreviewToolTip = GDB_ID_NULL ;
|
|
m_nPreviewToolTipDBL = GDB_ID_NULL ;
|
|
m_vPreviewAxisIds = {} ;
|
|
m_vPreviewAxisIdsBBL = {} ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Machining::~Machining( void)
|
|
{
|
|
m_nLookFlag = MCH_LOOK_NONE ;
|
|
m_nPreviewHeadId = GDB_ID_NULL ;
|
|
m_nPreviewHeadIdDBL = GDB_ID_NULL ;
|
|
m_nPreviewToolTip = GDB_ID_NULL ;
|
|
m_nPreviewToolTipDBL = GDB_ID_NULL ;
|
|
m_vPreviewAxisIds.clear() ;
|
|
m_vPreviewAxisIdsBBL.clear() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
Machining::GetToolName( void) const
|
|
{
|
|
return GetToolData().m_sName ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
Machining::GetHeadName( void) const
|
|
{
|
|
return GetToolData().m_sHead ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Machining::GetExitNbr( void) const
|
|
{
|
|
return GetToolData().m_nExit ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
Machining::GetToolTcPos( void) const
|
|
{
|
|
return GetToolData().m_sTcPos ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining:: NeedPrevHome( void) const
|
|
{
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::GetStartPoint( Point3d& ptStart) const
|
|
{
|
|
// verifico validità gestore DB geometrico
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero gruppo per geometria di lavorazione (Cutter Location)
|
|
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ;
|
|
if ( nClId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero la prima entità del primo sottogruppo
|
|
int nEntId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstGroupInGroup( nClId)) ;
|
|
if ( nEntId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il punto iniziale di questa entità
|
|
const IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nEntId) ;
|
|
if ( pGeoObj->GetType() == GEO_PNT3D) {
|
|
ptStart = GetGeoPoint3d( pGeoObj)->GetPoint() ;
|
|
return true ;
|
|
}
|
|
else if ( ( pGeoObj->GetType() & GEO_CURVE) != 0)
|
|
return GetCurve( pGeoObj)->GetStartPoint( ptStart) ;
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::GetEndPoint( Point3d& ptEnd) const
|
|
{
|
|
// verifico validità gestore DB geometrico
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
// recupero gruppo per geometria di lavorazione (Cutter Location)
|
|
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ;
|
|
if ( nClId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero l'ultima entità dell'ultimo sottogruppo
|
|
int nEntId = m_pGeomDB->GetLastInGroup( m_pGeomDB->GetLastGroupInGroup( nClId)) ;
|
|
if ( nEntId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il punto finale di questa entità
|
|
const IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nEntId) ;
|
|
if ( pGeoObj->GetType() == GEO_PNT3D) {
|
|
ptEnd = GetGeoPoint3d( pGeoObj)->GetPoint() ;
|
|
return true ;
|
|
}
|
|
else if ( ( pGeoObj->GetType() & GEO_CURVE) != 0)
|
|
return GetCurve( pGeoObj)->GetEndPoint( ptEnd) ;
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::MyChangeToolPreviewShow( int nLookFlag, bool bDouble)
|
|
{
|
|
// verifico validità del Flag
|
|
if ( nLookFlag != MCH_LOOK_NONE && nLookFlag != MCH_LOOK_TAB_TOOL && nLookFlag != MCH_LOOK_TAB_HEAD)
|
|
return false ;
|
|
|
|
// se non esiste il gruppo di Preview, errore
|
|
int nCurrStdId = GDB_ID_NULL ;
|
|
int nCurrHeadId = GDB_ID_NULL ;
|
|
if ( ! bDouble) {
|
|
nCurrStdId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST) ;
|
|
if ( nCurrStdId == GDB_ID_NULL || m_nPreviewHeadId == GDB_ID_NULL)
|
|
return false ;
|
|
nCurrHeadId = m_nPreviewHeadId ;
|
|
}
|
|
else {
|
|
nCurrStdId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST_DBL) ;
|
|
if ( nCurrStdId == GDB_ID_NULL || m_nPreviewHeadIdDBL == GDB_ID_NULL)
|
|
return false ;
|
|
nCurrHeadId = m_nPreviewHeadIdDBL ;
|
|
}
|
|
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
|
|
// recupero l'identificativo del gruppo di base della macchina
|
|
int nMBaseId = m_pGeomDB->GetFirstInGroup( pMch->GetMachineId()) ;
|
|
|
|
// se non devo visualizzare nulla, allora spengo il gruppo "ST"
|
|
if ( nLookFlag == MCH_LOOK_NONE)
|
|
m_pGeomDB->SetStatus( nCurrStdId, GDB_ST_OFF) ;
|
|
// altrimenti
|
|
else {
|
|
m_pGeomDB->SetStatus( nCurrStdId, GDB_ST_ON) ;
|
|
// contatori locali
|
|
const int MAX_ITER = 50 ;
|
|
bool bStop = false ;
|
|
int nIter = 0 ;
|
|
// se devo visualizzare solamente il gruppo della testa corrente
|
|
if ( nLookFlag == MCH_LOOK_TAB_TOOL) {
|
|
// la testa diventa visibile
|
|
m_pGeomDB->SetStatus( nCurrHeadId, GDB_ST_ON) ;
|
|
// tutti i gruppi che contengono la testa diventano visibili fino a "ST", l'unico loro
|
|
// figlio visibile deve essere quello che contiene la testa corrente
|
|
int nCurrId = nCurrHeadId ;
|
|
while ( ! bStop && nIter < MAX_ITER) {
|
|
int nParentId = m_pGeomDB->GetParentId( nCurrId) ;
|
|
if ( nParentId == GDB_ID_NULL) {
|
|
RemoveToolPreview() ;
|
|
return false ;
|
|
}
|
|
m_pGeomDB->SetStatus( nParentId, GDB_ST_ON) ;
|
|
int nChildId = m_pGeomDB->GetFirstGroupInGroup( nParentId) ;
|
|
while ( nChildId != GDB_ID_NULL) {
|
|
if ( m_pGeomDB->GetGdbType( nChildId) == GDB_TY_GROUP && nChildId == nCurrId)
|
|
m_pGeomDB->SetStatus( nChildId, GDB_ST_ON) ;
|
|
else
|
|
m_pGeomDB->SetStatus( nChildId, GDB_ST_OFF) ;
|
|
nChildId = m_pGeomDB->GetNextGroup( nChildId) ;
|
|
}
|
|
bStop = ( nParentId == nCurrStdId || nParentId == nMBaseId) ;
|
|
nCurrId = nParentId ;
|
|
++ nIter ;
|
|
}
|
|
}
|
|
// se devo visualizzare tutta la gerarchia
|
|
else {
|
|
deque<int> dqHierarchy ;
|
|
dqHierarchy.push_front( nCurrStdId) ;
|
|
while ( ! bStop && nIter < MAX_ITER) {
|
|
// recupero ed elimino dalla deque il primo Id memorizzato
|
|
int nCurrId = dqHierarchy.front() ;
|
|
dqHierarchy.pop_front() ;
|
|
if ( nCurrId == GDB_ID_NULL) {
|
|
RemoveToolPreview() ;
|
|
return false ;
|
|
}
|
|
// rendo visibile tale Layer
|
|
m_pGeomDB->SetStatus( nCurrId, GDB_ST_ON) ;
|
|
// se il gruppo corrente è la testa, ho finito
|
|
bStop = ( nCurrId == nCurrHeadId) ;
|
|
if ( ! bStop) {
|
|
// tutti i gruppi figli diventano visibili
|
|
int nChildId = m_pGeomDB->GetFirstInGroup( nCurrId) ;
|
|
while ( nChildId != GDB_ID_NULL) {
|
|
if ( m_pGeomDB->GetGdbType( nChildId) == GDB_TY_GROUP)
|
|
dqHierarchy.push_back( nChildId) ;
|
|
nChildId = m_pGeomDB->GetNext( nChildId) ;
|
|
}
|
|
}
|
|
else {
|
|
for ( auto Iter = dqHierarchy.begin() ; Iter != dqHierarchy.end() ; ++ Iter) {
|
|
if ( m_pGeomDB->GetGdbType( *Iter) == GDB_TY_GROUP)
|
|
m_pGeomDB->SetStatus( *Iter, GDB_ST_ON) ;
|
|
}
|
|
}
|
|
++ nIter ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::ChangeToolPreviewShow( int nLookFlag)
|
|
{
|
|
// verifico validità del Flag
|
|
if ( nLookFlag != MCH_LOOK_NONE && nLookFlag != MCH_LOOK_TAB_TOOL && nLookFlag != MCH_LOOK_TAB_HEAD)
|
|
return false ;
|
|
|
|
// se stesso Flag, non faccio nulla
|
|
if ( m_nLookFlag == nLookFlag)
|
|
return true ;
|
|
|
|
// aggiorno il flag
|
|
m_nLookFlag = nLookFlag ;
|
|
|
|
// recupero il gruppo di Preview
|
|
int nStdId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST) ;
|
|
if ( nStdId != GDB_ID_NULL) {
|
|
if ( ! MyChangeToolPreviewShow( nLookFlag, false))
|
|
return false ;
|
|
}
|
|
|
|
// se lavorazione in doppio aggiorno anche la Preview della
|
|
int nStdDBLId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST_DBL) ;
|
|
if ( nStdDBLId != GDB_ID_NULL) {
|
|
if ( ! MyChangeToolPreviewShow( nLookFlag, true))
|
|
return false ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::MyPrepareToolPreview( bool bDouble)
|
|
{
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
|
|
// se necessario, imposto l'utensile corrente
|
|
string sTool, sTcPos, sHead ;
|
|
int nExitDBLId ;
|
|
if ( ! bDouble) {
|
|
sTool = GetToolName() ;
|
|
sHead = GetHeadName() ;
|
|
}
|
|
else {
|
|
if ( ! GetDoubleToolData( sTool, sTcPos, sHead, nExitDBLId))
|
|
return false ;
|
|
}
|
|
|
|
// recupero l'identificativo del gruppo di base della macchina
|
|
int nMBaseId = m_pGeomDB->GetFirstInGroup( pMch->GetMachineId()) ;
|
|
|
|
// recupero l'identificativo della testa della lavorazione corrente e il set di teste associato
|
|
int nHeadId = m_pMchMgr->GetHeadId( sHead) ;
|
|
const STRVECTOR& vSetHead = pMch->GetHSet( sHead) ;
|
|
INTVECTOR vSetHeadIds ; vSetHeadIds.reserve( ssize( vSetHead)) ;
|
|
for ( const string& sSetHead : vSetHead)
|
|
vSetHeadIds.push_back( pMch->GetHeadId( sSetHead)) ;
|
|
|
|
// se presenti altre teste che non compaiono nell'headset le memorizzo
|
|
int nHeadParentId = m_pGeomDB->GetParentId( nHeadId) ;
|
|
INTVECTOR vOtherHeadIds ;
|
|
if ( nHeadParentId != GDB_ID_NULL) {
|
|
int nChildId = m_pGeomDB->GetFirstGroupInGroup( nHeadParentId) ;
|
|
while ( nChildId != GDB_ID_NULL) {
|
|
if ( nChildId != nHeadId && pMch->IsHeadGroup( nChildId) &&
|
|
find( vSetHeadIds.begin(), vSetHeadIds.end(), nChildId) == vSetHeadIds.end())
|
|
vOtherHeadIds.push_back( nChildId) ;
|
|
nChildId = m_pGeomDB->GetNextGroup( nChildId) ;
|
|
}
|
|
}
|
|
|
|
// recupero la tavola corrente
|
|
int nCurrTab = pMch->GetCurrTable() ;
|
|
|
|
// il gruppo iniziale di costruzione della gerarchia è "ST"
|
|
int nCurrHierarchyId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), ( ! bDouble ? MCH_ST : MCH_ST_DBL)) ;
|
|
if ( nCurrHierarchyId == GDB_ID_NULL)
|
|
return false ;
|
|
|
|
// Per prima cosa verifico se ci sono degli assi rotativi associati alla tavola, questi devono
|
|
// essere inseriti in ordine inverso all'interno del gruppo "ST" e il loro versore associato
|
|
// deve essere invertito
|
|
// NB. Per il momento viene memorizzato solo l'inverso del vettore; le geometrie vengono scartate
|
|
if ( nCurrTab != GDB_ID_NULL) {
|
|
// scorro i gruppi rotativi che influenzano tale tavola
|
|
bool bStop = false ;
|
|
int nCurrGrp = nCurrTab ;
|
|
const int MAX_ITER = 50 ;
|
|
int nIter = 0 ;
|
|
while ( ! bStop && nIter < MAX_ITER) {
|
|
// recupero il Parent Id del gruppo corrente
|
|
int nParentId = m_pGeomDB->GetParentId( nCurrGrp) ;
|
|
bStop = ( nParentId == GDB_ID_NULL || nParentId == nMBaseId ||
|
|
! pMch->IsRotaryAxisGroup( nParentId)) ;
|
|
if ( ! bStop) {
|
|
// recupero il suo Name, il suo Frame e creo il nuovo gruppo rotativo di Tavola
|
|
string sName ;
|
|
bool bOk = ( m_pGeomDB->GetName( nParentId, sName) && ! sName.empty()) ;
|
|
Frame3d* pFrame = ( bOk ? m_pGeomDB->GetGroupFrame( nParentId) : nullptr) ;
|
|
bOk = bOk && ( pFrame != nullptr) ;
|
|
int nNewTabRotAxisId = ( bOk ? m_pGeomDB->AddGroup( GDB_ID_NULL, nCurrHierarchyId, pFrame) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewTabRotAxisId != GDB_ID_NULL) &&
|
|
m_pGeomDB->SetName( nNewTabRotAxisId, sName) ;
|
|
double dAxisPos = 0. ;
|
|
bOk = bOk && pMch->GetAxisPos( sName, dAxisPos) &&
|
|
m_pGeomDB->SetInfo( nNewTabRotAxisId, KEY_ROT_AXIS_VAL, dAxisPos) ;
|
|
if ( ! bOk)
|
|
return false ;
|
|
nCurrHierarchyId = nNewTabRotAxisId ;
|
|
if ( ! bDouble)
|
|
m_vPreviewAxisIds.push_back( nNewTabRotAxisId) ;
|
|
else
|
|
m_vPreviewAxisIdsBBL.push_back( nNewTabRotAxisId) ;
|
|
// aggiungo il versore invertito
|
|
int nChildId = m_pGeomDB->GetFirstInGroup( nParentId) ;
|
|
while ( nChildId != GDB_ID_NULL) {
|
|
const IGeoVector3d* pGV = GetGeoVector3d( m_pGeomDB->GetGeoObj( nChildId)) ;
|
|
if ( pGV != nullptr) {
|
|
PtrOwner<IGeoVector3d> pGVInv( CloneGeoVector3d( pGV)) ;
|
|
if ( ! IsNull( pGVInv)) {
|
|
pGVInv->Mirror( pGV->GetBase(), pGV->GetVector()) ;
|
|
string sName ; m_pGeomDB->GetName( nChildId, sName) ;
|
|
int nNewGVId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nNewTabRotAxisId, Release( pGVInv)) ;
|
|
if ( nNewGVId == GDB_ID_NULL || ! m_pGeomDB->SetName( nNewGVId, sName) || ! m_pGeomDB->SetStatus( nNewGVId, GDB_ST_OFF))
|
|
return false ;
|
|
break ;
|
|
}
|
|
}
|
|
nChildId = m_pGeomDB->GetNext( nChildId) ;
|
|
}
|
|
nCurrGrp = nParentId ;
|
|
}
|
|
++ nIter ;
|
|
}
|
|
}
|
|
|
|
// A partire dal gruppo corrente della gerarchia devo inserire tutti gli assi angolari
|
|
// che contengono la testa attuale.
|
|
// - Gli assi Lineari vengono scartati.
|
|
// - Gli assi Angolari sono rappresentati solo ed esclusivamente dal loro vettore.
|
|
// - I Gruppi Figli degli assi Angolari che non sono altri assi Angolari vengono memorizzati
|
|
// solamente se presentano il flag "PreviewShow" a 1.
|
|
// - I Gruppi figli degli assi Angolari che non sono presenti nell'HeadSet corrente vengono visualizzati
|
|
// - Se percorrendo la Catena cinamentica dalla Head al Gruppo Base incontro un asse Lineare, allora
|
|
// tutti gli assi Angolari successivi non presenteranno Geometrie Attive, solamente il vettore.
|
|
struct HierarchyAxis {
|
|
int nId ;
|
|
string sName ;
|
|
bool bRotary ;
|
|
HierarchyAxis( int nI, const string& sN, bool bR)
|
|
: nId( nI), sName( sN), bRotary( bR) {} ;
|
|
} ;
|
|
vector<HierarchyAxis> vHierarchyAxis ;
|
|
set<int> setAxisIdNoPreview ;
|
|
// parto dal gruppo HeadId e a ritroso recupero la gerarchia
|
|
int nCurrGrp = nHeadId ;
|
|
const int MAX_ITER = 50 ;
|
|
int nIter = 0 ;
|
|
bool bFoundLinear = false ;
|
|
while ( nIter < MAX_ITER) {
|
|
// recupero il Parent Id del gruppo corrente
|
|
int nParentId = m_pGeomDB->GetParentId( nCurrGrp) ;
|
|
if ( nParentId == GDB_ID_NULL || nParentId == nMBaseId)
|
|
break ;
|
|
// verifico se asse Lineare o Rotativo
|
|
bool bRotary = pMch->IsRotaryAxisGroup( nParentId) ;
|
|
if ( ! bFoundLinear && ! bRotary)
|
|
bFoundLinear = true ;
|
|
// recupero il nome dell'Asse
|
|
string sAxName ; m_pGeomDB->GetName( nParentId, sAxName) ;
|
|
// memorizzo l'asse
|
|
vHierarchyAxis.emplace_back( nParentId, sAxName, bRotary) ;
|
|
// aggiorno i controlli
|
|
if ( bFoundLinear)
|
|
setAxisIdNoPreview.insert( nParentId) ;
|
|
nCurrGrp = nParentId ;
|
|
++ nIter ;
|
|
}
|
|
|
|
// se non c'è alcuna gerarchia, allora inserisco solo la testa corrente
|
|
if ( vHierarchyAxis.empty()) {
|
|
if ( ! bDouble) {
|
|
m_nPreviewHeadId = m_pGeomDB->CopyGlob( nHeadId, GDB_ID_NULL, nCurrHierarchyId) ;
|
|
if ( m_nPreviewHeadId == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
else {
|
|
m_nPreviewHeadIdDBL = m_pGeomDB->CopyGlob( nHeadId, GDB_ID_NULL, nCurrHierarchyId) ;
|
|
if ( m_nPreviewHeadIdDBL == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
}
|
|
// se esiste una gerarchia, allora la ricreo l'albero
|
|
else {
|
|
for ( auto Iter = vHierarchyAxis.rbegin() ; Iter != vHierarchyAxis.rend() ; ++ Iter) {
|
|
int nParentId = Iter->nId ;
|
|
// recupero il suo Name, il Frame e creo il nuovo gruppo
|
|
string sParentName ;
|
|
bool bOk = ( m_pGeomDB->GetName( nParentId, sParentName) && ! sParentName.empty()) ;
|
|
Frame3d* pParentFrame = ( bOk ? m_pGeomDB->GetGroupFrame( nParentId) : nullptr) ;
|
|
bOk = bOk && ( pParentFrame != nullptr) ;
|
|
int nNewParentId = ( bOk ? m_pGeomDB->AddGroup( GDB_ID_NULL, nCurrHierarchyId, *pParentFrame) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewParentId != GDB_ID_NULL) &&
|
|
m_pGeomDB->SetName( nNewParentId, sParentName) ;
|
|
if ( bOk) {
|
|
// recupero il tipo di asse
|
|
bool bRotary = ( pMch->IsRotaryAxisGroup( nParentId)) ;
|
|
if ( bRotary) {
|
|
if ( ! bDouble)
|
|
m_vPreviewAxisIds.push_back( nNewParentId) ;
|
|
else
|
|
m_vPreviewAxisIdsBBL.push_back( nNewParentId) ;
|
|
// memorizzo la sua posizione iniziale
|
|
double dAxisPos = 0. ;
|
|
bOk = bOk && pMch->GetAxisPos( sParentName, dAxisPos) &&
|
|
m_pGeomDB->SetInfo( nNewParentId, KEY_ROT_AXIS_VAL, dAxisPos) ;
|
|
}
|
|
// scorro i suoi figli
|
|
int nChildId = m_pGeomDB->GetFirstInGroup( nParentId) ;
|
|
while ( bOk && nChildId != GDB_ID_NULL) {
|
|
// se vettore ausiliario lo inserisco solo se asse padre rotativo
|
|
if ( m_pGeomDB->GetGdbType( nChildId) == GDB_TY_GEO) {
|
|
if ( bRotary) {
|
|
const IGeoVector3d* pGV = GetGeoVector3d( m_pGeomDB->GetGeoObj( nChildId)) ;
|
|
if ( pGV != nullptr) {
|
|
int nNewChildId = m_pGeomDB->CopyGlob( nChildId, GDB_ID_NULL, nNewParentId) ;
|
|
bOk = ( nNewChildId != GDB_ID_NULL && m_pGeomDB->SetStatus( nNewChildId, GDB_ST_OFF)) ;
|
|
}
|
|
}
|
|
}
|
|
// se gruppo
|
|
else if ( m_pGeomDB->GetGdbType( nChildId) == GDB_TY_GROUP) {
|
|
// se gruppo testa lo inserisco a prescindere
|
|
if ( nChildId == nHeadId) {
|
|
if ( ! bDouble) {
|
|
m_nPreviewHeadId = m_pGeomDB->CopyGlob( nHeadId, GDB_ID_NULL, nNewParentId) ;
|
|
bOk = ( m_nPreviewHeadId != GDB_ID_NULL) ;
|
|
}
|
|
else {
|
|
m_nPreviewHeadIdDBL = m_pGeomDB->CopyGlob( nHeadId, GDB_ID_NULL, nNewParentId) ;
|
|
bOk = ( m_nPreviewHeadIdDBL != GDB_ID_NULL) ;
|
|
}
|
|
}
|
|
// se altra testa non presente nell'HeadSet la inserisco
|
|
else if ( find( vOtherHeadIds.begin(), vOtherHeadIds.end(), nChildId) != vOtherHeadIds.end()) {
|
|
int nOtherHeadId = m_pGeomDB->CopyGlob( nChildId, GDB_ID_NULL, nNewParentId) ;
|
|
bOk = ( nOtherHeadId != GDB_ID_NULL) ;
|
|
}
|
|
else {
|
|
// se asse successivo nella catena cinematica, sarà il nuovo gruppo padre
|
|
auto NextIter = Iter ; ++ NextIter ;
|
|
if ( NextIter != vHierarchyAxis.rend() && NextIter->nId == nChildId)
|
|
;
|
|
// altrimenti
|
|
else {
|
|
// se asse precedente ad un asse lineare, non lo inserisco
|
|
auto Iter = setAxisIdNoPreview.find( nParentId) ;
|
|
if ( Iter != setAxisIdNoPreview.end())
|
|
;
|
|
// altrimenti controllo il valore del Flag di visualizzazione
|
|
else {
|
|
bool bPreviewShow = false ;
|
|
if ( m_pGeomDB->GetInfo( nChildId, KEY_PREVIEWSHOW, bPreviewShow) && bPreviewShow) {
|
|
int nNewChildId = m_pGeomDB->CopyGlob( nChildId, GDB_ID_NULL, nNewParentId) ;
|
|
bOk = ( nNewChildId != GDB_ID_NULL) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
nChildId = m_pGeomDB->GetNext( nChildId) ;
|
|
}
|
|
nCurrHierarchyId = nNewParentId ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// recupero il punto Tip dell'utensile e lo inserisco dentro al gruppo testa corrente
|
|
int nExitGrpId = ( ! bDouble ? pMch->GetCurrExit() : pMch->GetExitId( sHead, nExitDBLId)) ;
|
|
bool bOk = ( nExitGrpId != GDB_ID_NULL) ;
|
|
string sExitGrpName ;
|
|
bOk = bOk && m_pGeomDB->GetName( nExitGrpId, sExitGrpName) ;
|
|
int nFrId = GDB_ID_NULL ;
|
|
if ( bOk) {
|
|
if ( ! bDouble)
|
|
nFrId = m_pGeomDB->GetFirstNameInGroup( m_nPreviewHeadId, "_" + sExitGrpName) ;
|
|
else
|
|
nFrId = m_pGeomDB->GetFirstNameInGroup( m_nPreviewHeadIdDBL, "_" + sExitGrpName) ;
|
|
}
|
|
bOk = bOk && ( nFrId != GDB_ID_NULL) ;
|
|
const IGeoFrame3d* frExit = ( bOk ? GetGeoFrame3d( m_pGeomDB->GetGeoObj( nFrId)) : nullptr) ;
|
|
bOk = bOk && ( frExit != nullptr) ;
|
|
Point3d ptToolTip = ( bOk ? ( frExit->GetFrame()).Orig() - GetToolData().m_dLen * ( frExit->GetFrame()).VersZ() : P_INVALID) ;
|
|
bOk = bOk && ptToolTip.IsValid() ;
|
|
if ( bOk) {
|
|
PtrOwner<IGeoPoint3d> ptGToolTip( CreateGeoPoint3d()) ;
|
|
bOk = ( ! IsNull( ptGToolTip) && ptGToolTip->Set( ptToolTip)) ;
|
|
if ( bOk) {
|
|
if ( ! bDouble) {
|
|
m_nPreviewToolTip = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPreviewHeadId, Release( ptGToolTip)) ;
|
|
bOk = bOk && ( m_nPreviewToolTip != GDB_ID_NULL) ;
|
|
}
|
|
else {
|
|
m_nPreviewToolTipDBL = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPreviewHeadIdDBL, Release( ptGToolTip)) ;
|
|
bOk = bOk && ( m_nPreviewToolTipDBL != GDB_ID_NULL) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::PrepareToolPreview( void)
|
|
{
|
|
// verifico validità gestori DB geometrico e CAM
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
|
|
// se non esite il Gruppo di Preview, lo aggiungo
|
|
int nStId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST) ;
|
|
if ( nStId == GDB_ID_NULL) {
|
|
nStId = m_pGeomDB->AddGroup( GDB_ID_NULL, GetOwner(), Frame3d()) ;
|
|
if ( nStId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nStId, MCH_ST) ;
|
|
m_pGeomDB->SetLevel( nStId, GDB_LV_TEMP) ;
|
|
m_nLookFlag = MCH_LOOK_TAB_TOOL ;
|
|
}
|
|
// altrimenti lo svuoto
|
|
else
|
|
m_pGeomDB->EmptyGroup( nStId) ;
|
|
|
|
// controllo se presente un gruppo di lavorazione in doppio
|
|
int nStdIdDBL = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST_DBL) ;
|
|
if ( nStdIdDBL == GDB_ID_NULL) {
|
|
// verifico se esiste la lavorazione in doppio associata
|
|
int nDBLId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_DBL) ;
|
|
if ( nDBLId != GDB_ID_NULL) {
|
|
nStdIdDBL = m_pGeomDB->AddGroup( GDB_ID_NULL, GetOwner(), Frame3d()) ;
|
|
if ( nDBLId == GDB_ID_NULL) {
|
|
RemoveToolPreview() ;
|
|
return false ;
|
|
}
|
|
m_pGeomDB->SetName( nStdIdDBL, MCH_ST_DBL) ;
|
|
m_pGeomDB->SetLevel( nStdIdDBL, GDB_LV_TEMP) ;
|
|
}
|
|
}
|
|
// altrimenti lo svuoto
|
|
else
|
|
m_pGeomDB->EmptyGroup( nStdIdDBL) ;
|
|
|
|
// reset delle variabili membro
|
|
m_nPreviewHeadId = GDB_ID_NULL ;
|
|
m_nPreviewHeadIdDBL = GDB_ID_NULL ;
|
|
m_nPreviewToolTip = GDB_ID_NULL ;
|
|
m_nPreviewToolTipDBL = GDB_ID_NULL ;
|
|
m_vPreviewAxisIds.clear() ;
|
|
m_vPreviewAxisIdsBBL.clear() ;
|
|
|
|
// preparo l'anteprima per il gruppo ST
|
|
bool bOk = true ;
|
|
if ( nStId != GDB_ID_NULL) {
|
|
// imposto l'utensile corrente per impostare il gruppo ST
|
|
string sTool ; m_pMchMgr->GetCalcTool( sTool) ;
|
|
const_cast<Machining*>( this)->UpdateToolData() ;
|
|
if ( ! EqualNoCase( sTool, GetToolName()))
|
|
bOk = ( m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) ;
|
|
// creo la preview
|
|
bOk = bOk && MyPrepareToolPreview( false) && MyChangeToolPreviewShow( m_nLookFlag, false) ;
|
|
}
|
|
if ( bOk && nStdIdDBL != GDB_ID_NULL) {
|
|
// imposto l'utensile per la lavorazione in doppio
|
|
string sTool, sTcPos, sHead ; int nDblExit ;
|
|
bOk = ( GetDoubleToolData( sTool, sTcPos, sHead, nDblExit)) ;
|
|
if ( bOk) {
|
|
bool bOkToolSet = ( m_pMchMgr->SetCalcTool( sTool, sHead, nDblExit)) ;
|
|
bOk = bOkToolSet && MyPrepareToolPreview( true) && MyChangeToolPreviewShow( m_nLookFlag, true) ;
|
|
if ( bOkToolSet)
|
|
bOk = ( m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) && bOk ;
|
|
}
|
|
}
|
|
if ( ! bOk)
|
|
RemoveToolPreview() ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::RemoveToolPreview( void)
|
|
{
|
|
// verifico validità gestore DB geometrico
|
|
if ( m_pGeomDB == nullptr)
|
|
return false ;
|
|
#if DEBUG
|
|
return true ;
|
|
#endif
|
|
// recupero i gruppi per l'anteprima utensile
|
|
int nStId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST) ;
|
|
int nStIdDBL = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST_DBL) ;
|
|
// li svuoto
|
|
m_pGeomDB->EmptyGroup( nStId) ;
|
|
m_pGeomDB->EmptyGroup( nStIdDBL) ;
|
|
// reset delle variabili membro
|
|
m_nPreviewHeadId = GDB_ID_NULL ;
|
|
m_nPreviewHeadIdDBL = GDB_ID_NULL ;
|
|
m_nPreviewToolTip = GDB_ID_NULL ;
|
|
m_nPreviewToolTipDBL = GDB_ID_NULL ;
|
|
m_vPreviewAxisIds.clear() ;
|
|
m_vPreviewAxisIdsBBL.clear() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Machining::GetToolPreviewStepCount( void) const
|
|
{
|
|
// verifico validità gestori DB geometrico e CAM
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return 0 ;
|
|
// recupero gruppo per geometria di lavorazione (Cutter Location)
|
|
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ;
|
|
if ( nClId == GDB_ID_NULL)
|
|
return 0 ;
|
|
// determino il numero di entità di tutti i sottogruppi, escludendo CLIMB, RISE ed HOME
|
|
int nCount = 0 ;
|
|
int nPxId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
|
|
while ( nPxId != GDB_ID_NULL) {
|
|
// aggiungo tutte le entità del truppo
|
|
nCount += m_pGeomDB->GetGroupObjs( nPxId) ;
|
|
// tolgo le entità CLIMB
|
|
int nClimbId = m_pGeomDB->GetFirstNameInGroup( nPxId, MCH_CL_CLIMB) ;
|
|
while ( nClimbId != GDB_ID_NULL) {
|
|
-- nCount ;
|
|
nClimbId = m_pGeomDB->GetNextName( nClimbId, MCH_CL_CLIMB) ;
|
|
}
|
|
// tolgo le entità RISE
|
|
int nRiseId = m_pGeomDB->GetFirstNameInGroup( nPxId, MCH_CL_RISE) ;
|
|
while ( nRiseId != GDB_ID_NULL) {
|
|
-- nCount ;
|
|
nRiseId = m_pGeomDB->GetNextName( nRiseId, MCH_CL_RISE) ;
|
|
}
|
|
// tolgo le entità HOME
|
|
int nHomeId = m_pGeomDB->GetFirstNameInGroup( nPxId, MCH_CL_HOME) ;
|
|
while ( nHomeId != GDB_ID_NULL) {
|
|
-- nCount ;
|
|
nHomeId = m_pGeomDB->GetNextName( nHomeId, MCH_CL_HOME) ;
|
|
}
|
|
// passo al successivo sottogruppo
|
|
nPxId = m_pGeomDB->GetNextGroup( nPxId) ;
|
|
}
|
|
|
|
return nCount ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Machining::GetToolPreviewNext( int nEntId, int nParentId, int nStId) const
|
|
{
|
|
// recupero la successiva
|
|
int nNewId = ( ( nEntId != GDB_ID_NULL) ? m_pGeomDB->GetNext( nEntId) : m_pGeomDB->GetFirstInGroup( nParentId)) ;
|
|
int nNewParentId = nParentId ;
|
|
// ciclo nei gruppi successivi
|
|
do {
|
|
// ciclo nel gruppo
|
|
while ( nNewId != GDB_ID_NULL) {
|
|
string sName ; m_pGeomDB->GetName( nNewId, sName) ;
|
|
if ( sName != MCH_CL_CLIMB && sName != MCH_CL_RISE && sName != MCH_CL_HOME)
|
|
break ;
|
|
nNewId = m_pGeomDB->GetNext( nNewId) ;
|
|
}
|
|
// se trovata, esco
|
|
if ( nNewId != GDB_ID_NULL) {
|
|
// se prima entità, eventuale attivazione uscite di gruppo a forare
|
|
if ( nEntId == GDB_ID_NULL && m_pGeomDB->ExistsInfo( nNewParentId, KEY_DRACEX)) {
|
|
INTVECTOR vActExit ;
|
|
if ( m_pGeomDB->GetInfo( nNewParentId, KEY_DRACEX, vActExit))
|
|
ActivateDrillingUnit( m_nPreviewHeadId, vActExit) ;
|
|
}
|
|
return nNewId ;
|
|
}
|
|
// passo al gruppo successivo
|
|
nNewParentId = m_pGeomDB->GetNextGroup( nNewParentId) ;
|
|
// eventuale attivazione uscite di gruppo a forare
|
|
if ( m_pGeomDB->ExistsInfo( nNewParentId, KEY_DRACEX)) {
|
|
INTVECTOR vActExit ;
|
|
if ( m_pGeomDB->GetInfo( nNewParentId, KEY_DRACEX, vActExit))
|
|
ActivateDrillingUnit( m_nPreviewHeadId, vActExit) ;
|
|
}
|
|
// recupero la prima entità del successivo gruppo
|
|
nNewId = m_pGeomDB->GetFirstInGroup( nNewParentId) ;
|
|
} while ( nNewId != GDB_ID_NULL) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Machining::GetToolPreviewPrev( int nEntId, int nParentId, int nStId) const
|
|
{
|
|
// recupero la precedente
|
|
int nNewId = ( ( nEntId != GDB_ID_NULL) ? m_pGeomDB->GetPrev( nEntId) : m_pGeomDB->GetLastInGroup( nParentId)) ;
|
|
int nNewParentId = nParentId ;
|
|
// ciclo nei gruppi precedenti
|
|
do {
|
|
// ciclo nel gruppo
|
|
while ( nNewId != GDB_ID_NULL) {
|
|
string sName ; m_pGeomDB->GetName( nNewId, sName) ;
|
|
if ( sName != MCH_CL_CLIMB && sName != MCH_CL_RISE && sName != MCH_CL_HOME)
|
|
break ;
|
|
nNewId = m_pGeomDB->GetPrev( nNewId) ;
|
|
}
|
|
// se trovata, esco
|
|
if ( nNewId != GDB_ID_NULL)
|
|
return nNewId ;
|
|
// passo al gruppo precedente
|
|
nNewParentId = m_pGeomDB->GetPrevGroup( nNewParentId) ;
|
|
// eventuale attivazione uscite di gruppo a forare
|
|
if ( m_pGeomDB->ExistsInfo( nNewParentId, KEY_DRACEX)) {
|
|
INTVECTOR vActExit ;
|
|
if ( m_pGeomDB->GetInfo( nNewParentId, KEY_DRACEX, vActExit))
|
|
ActivateDrillingUnit( m_nPreviewHeadId, vActExit) ;
|
|
}
|
|
// recupero l'ultima entità del precedente gruppo
|
|
nNewId = m_pGeomDB->GetLastInGroup( nNewParentId) ;
|
|
} while ( nNewId != GDB_ID_NULL) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::MyToolPreview( int nEntId, bool bDouble) const
|
|
{
|
|
// verifico validità gestori DB geometrico e CAM
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
|
|
// verifico l'esistenza del gruppo di Preview
|
|
int nCurrStId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), ( ! bDouble ? MCH_ST : MCH_ST_DBL)) ;
|
|
if ( nCurrStId == GDB_ID_NULL)
|
|
return false ;
|
|
|
|
// recupero i dati dell'entità CamData corrrente
|
|
const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nEntId)) ;
|
|
if ( pCamData == nullptr)
|
|
return false ;
|
|
Point3d ptEnd = pCamData->GetEndPoint() ;
|
|
AdjustEndPointForAxesCalc( pCamData, ptEnd) ;
|
|
|
|
// recupero gli assi e i loro valori per la posizione corrente
|
|
const DBLVECTOR& vAxVal = pCamData->GetAxesVal() ;
|
|
STRVECTOR vAxNames ;
|
|
if ( ! bDouble)
|
|
m_pMchMgr->GetAllCurrAxesNames( vAxNames) ;
|
|
else {
|
|
string sDBLTool, sDBLTcPos, sDBLHead ; int nDBLExit ;
|
|
bool bOk = ( GetDoubleToolData( sDBLTool, sDBLTcPos, sDBLHead, nDBLExit) && m_pMchMgr->SetCalcTool( sDBLTool, sDBLHead, nDBLExit)) ;
|
|
if ( bOk)
|
|
m_pMchMgr->GetAllCurrAxesNames( vAxNames) ;
|
|
m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr()) ;
|
|
if ( ! bOk)
|
|
return false ;
|
|
}
|
|
if ( ssize( vAxVal) != ssize( vAxNames))
|
|
return GDB_ID_NULL ;
|
|
int nAxSize = ssize( vAxVal) ;
|
|
VPREVIEWAXISINFO vAxisInfo ; vAxisInfo.reserve( nAxSize) ;
|
|
for ( int i = 0 ; i < nAxSize ; ++ i) {
|
|
bool bLinear = false ;
|
|
pMch->GetAxisType( vAxNames[i], bLinear) ;
|
|
vAxisInfo.emplace_back( vAxNames[i], vAxVal[i], bLinear) ;
|
|
}
|
|
|
|
// scorro gli assi dentro al gruppo "ST" ( considero solo quelli rotativi)
|
|
const INTVECTOR& vCurrPreviewAxisIds = ( ! bDouble ? m_vPreviewAxisIds : m_vPreviewAxisIdsBBL) ;
|
|
for ( auto Iter = vCurrPreviewAxisIds.begin() ; Iter != vCurrPreviewAxisIds.end() ; ++ Iter) {
|
|
// recupero l'Id dell'asse corrente
|
|
int nAxisId = *Iter ;
|
|
if ( nAxisId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il nome di tale asse
|
|
string sAxisName ;
|
|
if ( ! m_pGeomDB->GetName( nAxisId, sAxisName))
|
|
return false ;
|
|
// recupero il valore corrente dell'asse
|
|
double dCurrAxisVal = 0. ;
|
|
m_pGeomDB->GetInfo( nAxisId, KEY_ROT_AXIS_VAL, dCurrAxisVal) ;
|
|
// recupero il valore dell'asse
|
|
bool bFound = false ;
|
|
double dAxisVal = 0 ;
|
|
for ( int i = 0 ; ! bFound && i < nAxSize ; ++ i) {
|
|
if ( ! vAxisInfo[i].bLinear && EqualNoCase( sAxisName, vAxisInfo[i].sName)) {
|
|
bFound = true ;
|
|
dAxisVal = vAxisInfo[i].dVal ;
|
|
}
|
|
}
|
|
if ( ! bFound)
|
|
return GDB_ID_NULL ;
|
|
// recupero il vettore dell'asse
|
|
int nV = m_pGeomDB->GetFirstNameInGroup( nAxisId, sAxisName) ;
|
|
const IGeoVector3d* pGV = GetGeoVector3d( m_pGeomDB->GetGeoObj( nV)) ;
|
|
if ( pGV == nullptr)
|
|
return GDB_ID_NULL ;
|
|
Point3d ptPos = pGV->GetBase() ;
|
|
Vector3d vtDir = pGV->GetVector() ;
|
|
vtDir.Normalize() ;
|
|
m_pGeomDB->RotateGroup( nAxisId, ptPos, vtDir, ( dAxisVal - dCurrAxisVal)) ;
|
|
m_pGeomDB->SetInfo( nAxisId, KEY_ROT_AXIS_VAL, dAxisVal) ;
|
|
}
|
|
|
|
// recupero la posizione del tip dell'utensile per movimento assi lineari
|
|
int nCurrPreviewToolTipId = ( ( ! bDouble ? m_nPreviewToolTip : m_nPreviewToolTipDBL)) ;
|
|
if ( nCurrPreviewToolTipId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
const IGeoPoint3d* pToolTip = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nCurrPreviewToolTipId)) ;
|
|
if ( pToolTip == nullptr)
|
|
return GDB_ID_NULL ;
|
|
Point3d ptToolTipLoc = pToolTip->GetPoint() ;
|
|
Frame3d frGlob ; m_pGeomDB->GetGlobFrame( nCurrPreviewToolTipId, frGlob) ;
|
|
Point3d ptToolTipGlob = GetToGlob( ptToolTipLoc, frGlob) ;
|
|
Vector3d vtMoveGlob = ptEnd - ptToolTipGlob ;
|
|
m_pGeomDB->GetGroupGlobFrame( nCurrStId, frGlob) ;
|
|
Vector3d vtMoveLoc = GetToLoc( vtMoveGlob, frGlob) ;
|
|
m_pGeomDB->TranslateGroup( nCurrStId, vtMoveLoc) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Machining::ToolPreview( int nEntId, int nStep) const
|
|
{
|
|
// verifico validità gestori DB geometrico e CAM
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return GDB_ID_NULL ;
|
|
|
|
// recupero il gruppo per anteprima utensile
|
|
int nStId = m_pGeomDB->GetFirstGroupInGroup( m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST)) ;
|
|
if ( nStId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
m_pGeomDB->SetStatus( nStId, GDB_ST_OFF) ;
|
|
|
|
// se esiste il gruppo per la lavorazione in doppio, lo recupero
|
|
int nStIdDBL = m_pGeomDB->GetFirstGroupInGroup( m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST_DBL)) ;
|
|
if ( nStIdDBL != GDB_ID_NULL)
|
|
m_pGeomDB->SetStatus( nStIdDBL, GDB_ST_OFF) ;
|
|
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
|
|
// recupero il gruppo per geometria di lavorazione (Cutter Location)
|
|
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ;
|
|
if ( nClId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
int nParentId ;
|
|
// se entità nulla
|
|
if ( nEntId == GDB_ID_NULL || ! m_pGeomDB->ExistsObj( nEntId)) {
|
|
// recupero il gruppo di appartenenza
|
|
nParentId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
|
|
// se richiesta successiva
|
|
if ( nStep > 0)
|
|
nEntId = GetToolPreviewNext( nEntId, nParentId, nStId) ;
|
|
// se richiesta precedente
|
|
else if ( nStep < 0)
|
|
nEntId = GetToolPreviewPrev( nEntId, nParentId, nStId) ;
|
|
// altrimenti richiesta corrente
|
|
else
|
|
nEntId = GDB_ID_NULL ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
// verifico che l'entità stia in un sottogruppo di CL
|
|
nParentId = m_pGeomDB->GetParentId( nEntId) ;
|
|
if ( m_pGeomDB->GetParentId( nParentId) == nClId) {
|
|
// se richiesta successiva
|
|
if ( nStep > 0) {
|
|
while ( nStep > 0) {
|
|
int nOldId = nEntId ;
|
|
nEntId = GetToolPreviewNext( nEntId, nParentId, nStId) ;
|
|
-- nStep ;
|
|
if ( nEntId == GDB_ID_NULL) {
|
|
nEntId = nOldId ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
// se richiesta precedente
|
|
else if ( nStep < 0) {
|
|
while ( nStep < 0) {
|
|
int nOldId = nEntId ;
|
|
nEntId = GetToolPreviewPrev( nEntId, nParentId, nStId) ;
|
|
++ nStep ;
|
|
if ( nEntId == GDB_ID_NULL) {
|
|
nEntId = nOldId ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
nEntId = GDB_ID_NULL ;
|
|
}
|
|
// se esiste il gruppo genitore, visualizzo preview
|
|
if ( nParentId != GDB_ID_NULL) {
|
|
m_pGeomDB->SetStatus( nStId, GDB_ST_ON) ;
|
|
if ( nStIdDBL != GDB_ID_NULL)
|
|
m_pGeomDB->SetStatus( nStIdDBL, GDB_ST_ON) ;
|
|
}
|
|
|
|
// aggiorno la preview dell'utensile
|
|
if ( ! MyToolPreview( nEntId, false))
|
|
return GDB_ID_NULL ;
|
|
// se lavorazione in doppio, aggiorno la sua preview
|
|
if ( nStIdDBL != GDB_ID_NULL) {
|
|
// recupero l'entità associata
|
|
int nEntDBLId = GDB_ID_NULL ;
|
|
if ( m_pGeomDB->GetInfo( nEntId, KEY_CL_DOUBLE, nEntDBLId) && nEntDBLId != GDB_ID_NULL) {
|
|
if ( ! MyToolPreview( nEntDBLId, true))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
}
|
|
|
|
// ritorno l'Id dell'entità CamData corrente
|
|
return nEntId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Machining::GetDoubleType( const string& sUserNotes)
|
|
{
|
|
int nDouble ;
|
|
if ( ! GetValInNotes( sUserNotes, UN_DOUBLE, nDouble) ||
|
|
( nDouble != 1 && nDouble != 2 && nDouble != 3))
|
|
return 0 ;
|
|
else
|
|
return nDouble ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::GetDoubleToolData( string& sDblTool, string& sDblTcPos, string& sDblHead, int& nDblExit) const
|
|
{
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero il gestore DB utensili della macchina corrente
|
|
ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ;
|
|
if ( pTMgr == nullptr)
|
|
return false ;
|
|
// recupero dati utensile in doppio
|
|
if ( ! GetValInNotes( GetToolData().m_sUserNotes, "DOUBLE", sDblTool))
|
|
return false ;
|
|
if ( ! m_pMchMgr->GetCurrSetupMgr().GetToolData( sDblTool, sDblTcPos, sDblHead, nDblExit)) {
|
|
const ToolData* pTdata = pTMgr->GetTool( sDblTool) ;
|
|
if ( pTdata == nullptr)
|
|
return false ;
|
|
sDblHead = pTdata->m_sHead ;
|
|
nDblExit = pTdata->m_nExit ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::CalcMirrorByDouble( int nClId, const string& sUserNotes)
|
|
{
|
|
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr)
|
|
return false ;
|
|
|
|
// verifico se prevista lavorazione in doppio
|
|
int nDouble = GetDoubleType( sUserNotes) ;
|
|
if ( nDouble == 0)
|
|
return true ;
|
|
|
|
// assegno Id entità originali
|
|
int nPathId = m_pGeomDB->GetFirstNameInGroup( nClId, MCH_PATH + "*") ;
|
|
while ( nPathId != GDB_ID_NULL) {
|
|
int nEntId = m_pGeomDB->GetFirstInGroup( nPathId) ;
|
|
while ( nEntId != GDB_ID_NULL) {
|
|
string sName ;
|
|
if ( ! m_pGeomDB->GetName( nEntId, sName) ||
|
|
( sName != MCH_CL_CLIMB && sName != MCH_CL_RISE && sName != MCH_CL_HOME))
|
|
m_pGeomDB->SetInfo( nEntId, KEY_DBL_MAIN, nEntId) ;
|
|
nEntId = m_pGeomDB->GetNext( nEntId) ;
|
|
}
|
|
nPathId = m_pGeomDB->GetNextName( nPathId, MCH_PATH + "*") ;
|
|
}
|
|
|
|
// copio gruppo di lavorazione e cambio nome
|
|
int nDblId = m_pGeomDB->Copy( nClId, GDB_ID_NULL, nClId, GDB_AFTER) ;
|
|
if ( nDblId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nDblId, MCH_DBL) ;
|
|
// assegno colore di copia
|
|
int nClPathId = m_pGeomDB->GetFirstGroupInGroup( nDblId) ;
|
|
while ( nClPathId != GDB_ID_NULL) {
|
|
m_pGeomDB->SetMaterial( nClPathId, GRAY) ;
|
|
nClPathId = m_pGeomDB->GetNextGroup( nClPathId) ;
|
|
}
|
|
// assegno Id entità double
|
|
nPathId = m_pGeomDB->GetFirstNameInGroup( nDblId, MCH_PATH + "*") ;
|
|
while ( nPathId != GDB_ID_NULL) {
|
|
int nEntId = m_pGeomDB->GetFirstInGroup( nPathId) ;
|
|
while ( nEntId != GDB_ID_NULL) {
|
|
int nMainEntId ;
|
|
if ( m_pGeomDB->GetInfo( nEntId, KEY_DBL_MAIN, nMainEntId)) {
|
|
m_pGeomDB->RemoveInfo( nMainEntId, KEY_DBL_MAIN) ;
|
|
m_pGeomDB->SetInfo( nMainEntId, KEY_CL_DOUBLE, nEntId) ;
|
|
}
|
|
nEntId = m_pGeomDB->GetNext( nEntId) ;
|
|
}
|
|
nPathId = m_pGeomDB->GetNextName( nPathId, MCH_PATH + "*") ;
|
|
}
|
|
|
|
// determino posizione del piano di mirroring
|
|
BBox3d b3Raw ;
|
|
Point3d ptOn ;
|
|
if ( ! GetCurrRawsGlobBox( b3Raw) || ! b3Raw.GetCenter( ptOn))
|
|
return false ;
|
|
Vector3d vtNorm ;
|
|
switch ( nDouble) {
|
|
case 1 : vtNorm = X_AX ; break ;
|
|
case 2 : vtNorm = Y_AX ; break ;
|
|
case 3 : vtNorm = Z_AX ; break ;
|
|
}
|
|
double dPlanePos ;
|
|
if ( GetValInNotes( sUserNotes, UN_MIRRORAX, dPlanePos))
|
|
ptOn = b3Raw.GetMin() + dPlanePos * vtNorm ;
|
|
|
|
// eseguo mirroring rispetto a piano opportuno
|
|
nPathId = m_pGeomDB->GetFirstNameInGroup( nDblId, MCH_PATH + "*") ;
|
|
while ( nPathId != GDB_ID_NULL) {
|
|
int nEntId = m_pGeomDB->GetFirstInGroup( nPathId) ;
|
|
while ( nEntId != GDB_ID_NULL) {
|
|
string sName ; m_pGeomDB->GetName( nEntId, sName) ;
|
|
// nel caso di fuorature in doppio, il movimento deve essere sincronizzato
|
|
if ( sName == MCH_CL_DBP) {
|
|
INTVECTOR vSyncEntId ;
|
|
do {
|
|
vSyncEntId.push_back( nEntId) ;
|
|
nEntId = m_pGeomDB->GetNext( nEntId) ;
|
|
sName.clear() ;
|
|
m_pGeomDB->GetName( nEntId, sName) ;
|
|
} while ( sName == MCH_CL_DBP) ;
|
|
Vector3d vtRef ;
|
|
bool bOk = true ;
|
|
for ( int i = 0 ; bOk && i < ssize( vSyncEntId) ; ++ i) {
|
|
// curva corrente di sincronizzazione
|
|
const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( vSyncEntId[i])) ;
|
|
bOk = ( pCrv != nullptr && pCrv->IsValid()) ;
|
|
if ( bOk) {
|
|
if ( i == 0) {
|
|
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
|
|
Point3d ptE ; pCrv->GetEndPoint( ptE) ;
|
|
Point3d ptSMirror = ptS ; ptSMirror.Mirror( ptOn, vtNorm) ;
|
|
vtRef = ( ptSMirror - ptS) ;
|
|
}
|
|
m_pGeomDB->Translate( vSyncEntId[i], vtRef) ;
|
|
CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( vSyncEntId[i])) ;
|
|
bOk = ( pCamData != nullptr) ;
|
|
if ( bOk) {
|
|
Vector3d vtTool = pCamData->GetToolDir() ;
|
|
vtTool.Mirror( vtNorm) ;
|
|
pCamData->SetToolDir( vtTool) ;
|
|
}
|
|
}
|
|
}
|
|
if ( ! bOk) {
|
|
m_pGeomDB->Erase( nPathId) ;
|
|
return false ;
|
|
}
|
|
}
|
|
// per tutti gli altri casi si fa il mirror
|
|
else {
|
|
m_pGeomDB->Mirror( nEntId, ptOn, vtNorm) ;
|
|
nEntId = m_pGeomDB->GetNext( nEntId) ;
|
|
}
|
|
}
|
|
nPathId = m_pGeomDB->GetNextName( nPathId, MCH_PATH + "*") ;
|
|
}
|
|
|
|
// se presente una differenza in Z, eseguo spostamento
|
|
double dDeltaZ = 0. ;
|
|
if ( GetValInNotes( sUserNotes, UN_DELTAZ, dDeltaZ) && abs( dDeltaZ) > EPS_SMALL)
|
|
m_pGeomDB->TranslateGlob( nDblId, Vector3d( 0, 0, dDeltaZ)) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::ActivateDrillingUnit( int nHeadId, const INTVECTOR& vActExit) const
|
|
{
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
// costanti
|
|
static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo
|
|
static const string EVAR_VER = ".VER" ; // IN (string) versione della Dll
|
|
static const string EVAR_HEADID = ".HEADID" ; // IN (int) identificativo testa
|
|
static const string EVAR_DRACEX = ".DRACEX" ; // IN (ints) vettore indici uscite attive
|
|
static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok, > 0 errore)
|
|
static const string ON_ACTIVATE_DRILLING_UNIT = "OnActivateDrillingUnit" ;
|
|
|
|
// se non esiste la funzione, esco
|
|
if ( ! pMch->LuaExistsFunction( ON_ACTIVATE_DRILLING_UNIT))
|
|
return true ;
|
|
|
|
// eseguo l'azione
|
|
bool bOk = true ;
|
|
int nErr = 99 ;
|
|
// imposto valori parametri
|
|
bOk = bOk && pMch->LuaCreateGlobTable( EMC_VAR) ;
|
|
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_VER, GetEMkVer()) ;
|
|
bOk = bOk && ( nHeadId != GDB_ID_NULL) && pMch->LuaSetGlobVar( EMC_VAR + EVAR_HEADID, nHeadId) ;
|
|
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_DRACEX, vActExit) ;
|
|
// eseguo
|
|
bOk = bOk && pMch->LuaCallFunction( ON_ACTIVATE_DRILLING_UNIT) ;
|
|
// recupero valori parametri obbligatori
|
|
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ;
|
|
// reset
|
|
bOk = pMch->LuaResetGlobVar( EMC_VAR) && bOk ;
|
|
// segnalo errori
|
|
return ( bOk && nErr == 0) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::SpecialApply( string& sErr)
|
|
{
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
// costanti
|
|
static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo
|
|
static const string EVAR_PHASE = ".PHASE" ; // IN (int) indice fase
|
|
static const string EVAR_MCHID = ".MCHID" ; // IN (int) identificativo della lavorazione
|
|
static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok, > 0 errore, < 0 warning)
|
|
static const string EVAR_MSG = ".MSG" ; // OUT (string) stringa di errore ( opzionale)
|
|
static const string ON_SPECIAL_APPLY = "OnSpecialApplyMachining" ;
|
|
|
|
// se non esiste la funzione, esco
|
|
if ( ! pMch->LuaExistsFunction( ON_SPECIAL_APPLY))
|
|
return true ;
|
|
|
|
// eseguo l'azione
|
|
bool bOk = true ;
|
|
int nErr = 99 ;
|
|
// imposto valori parametri
|
|
bOk = bOk && pMch->LuaCreateGlobTable( EMC_VAR) ;
|
|
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_PHASE, m_nPhase) ;
|
|
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_MCHID, m_nOwnerId) ;
|
|
// eseguo
|
|
bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_APPLY, false) ;
|
|
// recupero valori parametri obbligatori
|
|
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ;
|
|
// recupero valori parametri opzionali
|
|
string sMsg ;
|
|
bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_MSG, sMsg) ;
|
|
// reset
|
|
bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ;
|
|
// segnalo errori
|
|
if ( ! bOk || nErr > 0) {
|
|
bOk = false ;
|
|
sErr = sMsg ;
|
|
if ( IsEmptyOrSpaces( sErr))
|
|
sErr = " Error in " + ON_SPECIAL_APPLY + " (" + ToString( nErr) + ")" ;
|
|
}
|
|
// recupero eventuale warning
|
|
else if ( nErr < 0) {
|
|
string sOut = sMsg ;
|
|
if ( IsEmptyOrSpaces( sOut))
|
|
sOut = " Warning in " + ON_SPECIAL_APPLY + " (" + ToString( abs( nErr)) + ")" ;
|
|
m_pMchMgr->SetWarning( abs( nErr), sOut) ;
|
|
}
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Machining::PostApply( string& sErr)
|
|
{
|
|
// recupero la macchina corrente
|
|
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
|
|
if ( pMch == nullptr)
|
|
return false ;
|
|
// costanti
|
|
static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo
|
|
static const string EVAR_PHASE = ".PHASE" ; // IN (int) indice fase
|
|
static const string EVAR_MCHID = ".MCHID" ; // IN (int) identificativo della lavorazione
|
|
static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok, > 0 errore, < 0 warning)
|
|
static const string EVAR_MSG = ".MSG" ; // OUT (string) stringa di errore ( opzionale)
|
|
static const string ON_POST_APPLY = "OnPostApplyMachining" ;
|
|
|
|
// se non esiste la funzione, esco
|
|
if ( ! pMch->LuaExistsFunction( ON_POST_APPLY))
|
|
return true ;
|
|
|
|
// eseguo l'azione
|
|
bool bOk = true ;
|
|
int nErr = 99 ;
|
|
// imposto valori parametri
|
|
bOk = bOk && pMch->LuaCreateGlobTable( EMC_VAR) ;
|
|
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_PHASE, m_nPhase) ;
|
|
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_MCHID, m_nOwnerId) ;
|
|
// eseguo
|
|
bOk = bOk && pMch->LuaCallFunction( ON_POST_APPLY, false) ;
|
|
// recupero valori parametri obbligatori
|
|
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ;
|
|
// recupero valori parametri opzionali
|
|
string sMsg ;
|
|
bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_MSG, sMsg) ;
|
|
// reset
|
|
bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ;
|
|
// segnalo errori
|
|
if ( ! bOk || nErr > 0) {
|
|
bOk = false ;
|
|
sErr = sMsg ;
|
|
if ( IsEmptyOrSpaces( sErr))
|
|
sErr = " Error in " + ON_POST_APPLY + " (" + ToString( nErr) + ")" ;
|
|
}
|
|
// recupero eventuale warning
|
|
else if ( nErr < 0) {
|
|
string sOut = sMsg ;
|
|
if ( IsEmptyOrSpaces( sOut))
|
|
sOut = " Warning in " + ON_POST_APPLY + " (" + ToString( abs( nErr)) + ")" ;
|
|
m_pMchMgr->SetWarning( abs( nErr), sOut) ;
|
|
}
|
|
return bOk ;
|
|
}
|