//---------------------------------------------------------------------------- // 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 "ToolUserNotesConst.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EGkGeoVector3d.h" #include #include 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 VPREVIEWAXISINFO ; //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Machining::Machining( void) { m_nLookFlag = MCH_LOOK_TAB_HEAD ; m_nPreviewHeadId = GDB_ID_NULL ; m_nPreviewHeadIdDBL = GDB_ID_NULL ; m_nPreviewExitId = GDB_ID_NULL ; m_nPreviewExitIdDBL = GDB_ID_NULL ; m_nPreviewToolTip = GDB_ID_NULL ; m_nPreviewToolTipDBL = GDB_ID_NULL ; m_vPreviewAxisIds = {} ; m_vPreviewAxisIdsDBL = {} ; } //---------------------------------------------------------------------------- Machining::~Machining( void) { m_nLookFlag = MCH_LOOK_NONE ; m_nPreviewHeadId = GDB_ID_NULL ; m_nPreviewHeadIdDBL = GDB_ID_NULL ; m_nPreviewExitId = GDB_ID_NULL ; m_nPreviewExitIdDBL = GDB_ID_NULL ; m_nPreviewToolTip = GDB_ID_NULL ; m_nPreviewToolTipDBL = GDB_ID_NULL ; m_vPreviewAxisIds.clear() ; m_vPreviewAxisIdsDBL.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 ; int nCurrExitId = 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 ; nCurrExitId = m_nPreviewExitId ; } else { nCurrStdId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST_DBL) ; if ( nCurrStdId == GDB_ID_NULL || m_nPreviewHeadIdDBL == GDB_ID_NULL) return false ; nCurrHeadId = m_nPreviewHeadIdDBL ; nCurrExitId = m_nPreviewExitIdDBL ; } // 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 ( solamente il gruppo dell'uscita corrente) m_pGeomDB->SetStatus( nCurrHeadId, GDB_ST_ON) ; int nHeadChildId = m_pGeomDB->GetFirstGroupInGroup( nCurrHeadId) ; while ( nHeadChildId != GDB_ID_NULL) { if ( nHeadChildId != nCurrExitId) m_pGeomDB->SetStatus( nHeadChildId, GDB_ST_OFF) ; nHeadChildId = m_pGeomDB->GetNext( nHeadChildId) ; } // 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 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 { // visualizzo tutti i gruppi in coda for ( auto Iter = dqHierarchy.begin() ; Iter != dqHierarchy.end() ; ++ Iter) { if ( m_pGeomDB->GetGdbType( *Iter) == GDB_TY_GROUP) m_pGeomDB->SetStatus( *Iter, GDB_ST_ON) ; } // visualizzo tutti i sottogruppi della testa int nHeadChild = m_pGeomDB->GetFirstGroupInGroup( nCurrHeadId) ; while ( nHeadChild != GDB_ID_NULL) { m_pGeomDB->SetStatus( nHeadChild, GDB_ST_ON) ; nHeadChild = m_pGeomDB->GetNextGroup( nHeadChild) ; } } ++ 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 ; double dTLen ; int nExitDBLId ; if ( ! bDouble) { sTool = GetToolName() ; sHead = GetHeadName() ; dTLen = GetToolData().m_dLen ; } else { if ( ! GetDoubleToolData( sTool, sTcPos, sHead, nExitDBLId, dTLen)) 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_vPreviewAxisIdsDBL.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 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 vHierarchyAxis ; set 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_vPreviewAxisIdsDBL.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) ; m_nPreviewExitId = m_pGeomDB->GetFirstNameInGroup( m_nPreviewHeadId, sExitGrpName) ; } else { nFrId = m_pGeomDB->GetFirstNameInGroup( m_nPreviewHeadIdDBL, "_" + sExitGrpName) ; m_nPreviewExitIdDBL = 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() - dTLen * ( frExit->GetFrame()).VersZ() : P_INVALID) ; bOk = bOk && ptToolTip.IsValid() ; if ( bOk) { PtrOwner 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_vPreviewAxisIdsDBL.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( 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) ; // svuoto il gruppo dell'utensile principale m_pGeomDB->EmptyGroup( nStId) ; // rimuovo il gruppo dell'utensile secondario ( non lo svuoto, in quanto potrei ricalcolare la stessa lavorazione // come singola, ritrovandomi un gruppo per il DBL in ToolPreview()) m_pGeomDB->Erase( nStIdDBL) ; // reset delle variabili membro m_nPreviewHeadId = GDB_ID_NULL ; m_nPreviewHeadIdDBL = GDB_ID_NULL ; m_nPreviewExitId = GDB_ID_NULL ; m_nPreviewExitIdDBL = GDB_ID_NULL ; m_nPreviewToolTip = GDB_ID_NULL ; m_nPreviewToolTipDBL = GDB_ID_NULL ; m_vPreviewAxisIds.clear() ; m_vPreviewAxisIdsDBL.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) ; MyShowMultiDrillingTool( 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) ; MyShowMultiDrillingTool( 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) ; MyShowMultiDrillingTool( 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_vPreviewAxisIdsDBL) ; 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) const { 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 { double dDummy ; return GetDoubleToolData( sDblTool, sDblTcPos, sDblHead, nDblExit, dDummy) ; } //---------------------------------------------------------------------------- bool Machining::GetDoubleToolData( string& sDblTool, string& sDblTcPos, string& sDblHead, int& nDblExit, double& dDblLen) 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, TUN_DOUBLE, sDblTool)) return false ; const ToolData* pTdata = pTMgr->GetTool( sDblTool) ; if ( pTdata == nullptr) return false ; dDblLen = pTdata->m_dLen ; if ( ! m_pMchMgr->GetCurrSetupMgr().GetToolData( sDblTool, sDblTcPos, sDblHead, nDblExit)) { sDblHead = pTdata->m_sHead ; nDblExit = pTdata->m_nExit ; } return true ; } //---------------------------------------------------------------------------- bool Machining::CalcMirrorPlaneByDouble( int nDouble, const string& sUserNotes, Point3d& ptOn, Vector3d& vtNorm) const { // verifico parametro per lavorazione in doppio if ( nDouble != 1 && nDouble != 2 && nDouble != 3) return false ; // determino posizione del piano di mirroring mediante centro del Box del grezzo BBox3d b3Raw ; if ( ! GetCurrRawsGlobBox( b3Raw) || ! b3Raw.GetCenter( ptOn)) return false ; switch ( nDouble) { case 1 : vtNorm = X_AX ; break ; case 2 : vtNorm = Y_AX ; break ; case 3 : vtNorm = Z_AX ; break ; } // se presente nota utente con posizione del piano, allora dal punto più basso salgo di tale valore per individuare la quota double dPlanePos ; if ( GetValInNotes( sUserNotes, UN_MIRRORAX, dPlanePos)) ptOn = b3Raw.GetMin() + dPlanePos * vtNorm ; return true ; } //---------------------------------------------------------------------------- bool Machining::CalcMirrorByDouble( int nClId, const string& sUserNotes) const { 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 + "*") ; } // calcolo il piano di Mirroring Point3d ptOn ; Vector3d vtNorm ; if ( ! CalcMirrorPlaneByDouble( nDouble, sUserNotes, ptOn, vtNorm)) return false ; // 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 forature in doppio, il movimento deve essere sincronizzato if ( sName == MCH_CL_PARALLEL_DBL) { INTVECTOR vSyncEntId ; do { vSyncEntId.push_back( nEntId) ; nEntId = m_pGeomDB->GetNext( nEntId) ; sName.clear() ; m_pGeomDB->GetName( nEntId, sName) ; } while ( sName == MCH_CL_PARALLEL_DBL) ; 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::MyShowMultiDrillingTool( const INTVECTOR& vActExit) const { // verifico validità del Flag if ( m_nLookFlag != MCH_LOOK_NONE && m_nLookFlag != MCH_LOOK_TAB_TOOL && m_nLookFlag != MCH_LOOK_TAB_HEAD) return false ; // se non ho visibilità solo utensile, non faccio nulla if ( m_nLookFlag != MCH_LOOK_TAB_TOOL) return false ; // verifico che il gruppo di preview della testa sia valido if ( m_nPreviewHeadId == GDB_ID_NULL) return false ; // recupero i nomi delle uscite da visualizzare nella preview STRVECTOR vsExit ; vsExit.resize( vActExit.size()) ; for ( int i = 0 ; i < ssize( vActExit) ; ++ i) vsExit[i] = MCH_EXIT + ToString( vActExit[i]) ; // rendo visibili solo i gruppi nella preview inerenti int nChildHeadId = m_pGeomDB->GetFirstInGroup( m_nPreviewHeadId) ; while ( nChildHeadId != GDB_ID_NULL) { // recupero il nome del gruppo corrente string sName ; m_pGeomDB->GetName( nChildHeadId, sName) ; // verifico se attivare o meno il gruppo corrente bool bStatusOn = ( find_if( vsExit.begin(), vsExit.end(), [&]( const string& sExitName) { return EqualNoCase( sExitName, sName) ; }) != vsExit.end()) ; m_pGeomDB->SetStatus( nChildHeadId, bStatusOn ? GDB_ST_ON : GDB_ST_OFF) ; // passo al gruppo successivo nChildHeadId = m_pGeomDB->GetNextGroup( nChildHeadId) ; } 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 ; }