diff --git a/Drilling.cpp b/Drilling.cpp index d65cd58..20f9f40 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -31,6 +31,7 @@ #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EGkGeoFrame3d.h" +#include "/EgtDev/Include/EgtIniFile.h" using namespace std ; @@ -3575,6 +3576,28 @@ Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId, double dMHO // parametri per foro in doppio bool bDouble = ( GetDoubleType( m_Params.m_sUserNotes) != 0) ; double dDoubleLastStep = GetDoubleLastStep() ; + bool dDoubleParallel = false ; + if ( bDouble) { + // nel caso di lavorazione in doppio con flag nel file .ini abilitato, prima della risalita finale, risalgo dell'ultimo step compiuto + // se il piano di mirror presenta una normale circa parallela alla direzione del foro ( da BTL 1 grado di tolleranza) + Machine* pMch = m_pMchMgr->GetCurrMachine() ; + if ( pMch != nullptr) { + string sMachIni = pMch->GetMachineDir() + "\\" + pMch->GetMachineName() + ".ini" ; + const char* SEC_MACH = "Customizations" ; + const char* KEY_DRILLING_DOUBLE = "DrillingDoubleNT" ; + int nDrillingDouble = GetPrivateProfileInt( SEC_MACH, KEY_DRILLING_DOUBLE, 0, sMachIni.c_str()) ; + if ( nDrillingDouble == 1) { + int nDouble = GetDoubleType( m_Params.m_sUserNotes) ; + Vector3d vtNorm = V_INVALID ; + switch ( nDouble) { + case 1 : vtNorm = X_AX ; break ; + case 2 : vtNorm = Y_AX ; break ; + case 3 : vtNorm = Z_AX ; break ; + } + dDoubleParallel = ( vtNorm.IsValid() && hole.vtDir * vtNorm > cos( 1. * DEGTORAD)) ; + } + } + } // ciclo di affondamento a step const double MIN_STEP = 1 ; const double APPR_STEP = 1 ; @@ -3625,8 +3648,14 @@ Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId, double dMHO Point3d ptP3 = hole.ptIni - hole.vtDir * dLen ; if ( bHoleEnd) ptP3 -= hole.vtDir * dAddLen ; - if ( AddLinearMove( ptP3, bSplitArcs) == GDB_ID_NULL) - return false ; + if ( dDoubleParallel && i == nStep) { + if ( AddLinearMove( ptP3, bSplitArcs, MCH_CL_DBP) == GDB_ID_NULL) + return false ; + } + else { + if ( AddLinearMove( ptP3, bSplitArcs) == GDB_ID_NULL) + return false ; + } // aggiorno posizione e verifico se step completato dCurrLen = dLen ; if ( bHoleEnd || bStepEnd) @@ -3650,8 +3679,14 @@ Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId, double dMHO Point3d ptP4 = hole.ptIni - hole.vtDir * dLen ; if ( bHoleEnd) ptP4 -= hole.vtDir * dAddLen ; - if ( AddLinearMove( ptP4, bSplitArcs) == GDB_ID_NULL) - return false ; + if ( dDoubleParallel && i == nStep) { + if ( AddLinearMove( ptP4, bSplitArcs, MCH_CL_DBP) == GDB_ID_NULL) + return false ; + } + else { + if ( AddLinearMove( ptP4, bSplitArcs) == GDB_ID_NULL) + return false ; + } // aggiorno posizione e verifico se step completato dCurrLen = dLen ; if ( bHoleEnd || bStepEnd) @@ -3674,8 +3709,14 @@ Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId, double dMHO Point3d ptP5 = hole.ptIni - hole.vtDir * dLen ; if ( bHoleEnd) ptP5 -= hole.vtDir * dAddLen ; - if ( AddLinearMove( ptP5, bSplitArcs) == GDB_ID_NULL) - return false ; + if ( dDoubleParallel && i == nStep) { + if ( AddLinearMove( ptP5, bSplitArcs, MCH_CL_DBP) == GDB_ID_NULL) + return false ; + } + else { + if ( AddLinearMove( ptP5, bSplitArcs) == GDB_ID_NULL) + return false ; + } // aggiorno posizione dCurrLen = dLen ; } @@ -3684,6 +3725,16 @@ Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId, double dMHO // 6 -> ritorno all'approccio del foro SetFeed( GetEndFeed()) ; SetFlag( 104) ; // risalita sopra il foro + if ( dDoubleParallel) { + // aggiungo risalita aggiuntiva per lavorazione in doppio pari a due volte il LastStep + Point3d ptEnd ; GetCurrPos( ptEnd) ; + if ( AddLinearMove( ptEnd + min( 2. * dLastStep, dCurrLen) * hole.vtDir, bSplitArcs, MCH_CL_DBP) == GDB_ID_NULL) + return false ; + // aggiungo discensa di LastStep per simmetria con secondo utensile + GetCurrPos( ptEnd) ; + if ( AddLinearMove( ptEnd - dLastStep * hole.vtDir, bSplitArcs, MCH_CL_DBP) == GDB_ID_NULL) + return false ; + } if ( AddLinearMove( ptP1, bSplitArcs) == GDB_ID_NULL) return false ; diff --git a/Machine.h b/Machine.h index f8f89a1..52b991e 100644 --- a/Machine.h +++ b/Machine.h @@ -100,6 +100,7 @@ class Machine bool LoadAllTools( void) ; bool UnloadAllTools( void) ; bool ResetHeadSet( const std::string& sHead) ; + const STRVECTOR& GetHSet( const std::string& sHead) const ; bool GetAxisToken( const std::string& sAxis, std::string& sToken) const ; bool GetAxisInvert( const std::string& sAxis, bool& bInvert) const ; bool GetAxisOffset( const std::string& sAxis, double& dOffset) const ; @@ -267,7 +268,6 @@ class Machine TcPos* GetTcPos( int nGroup) const ; Exit* GetExit( int nGroup) const ; bool AddHeadToSet( const std::string& sHSet, const std::string& sName) ; - const STRVECTOR& GetHSet( const std::string& sHead) const ; bool EnableHeadInSet( const std::string& sHead) ; bool LoadTool( Exit* pExit, const std::string& sTool) ; bool ModifyMachineHeadAuxDirection( const std::string& sHead, const Vector3d& vtADir) ; diff --git a/Machining.cpp b/Machining.cpp index ba49633..8d56406 100644 --- a/Machining.cpp +++ b/Machining.cpp @@ -19,13 +19,48 @@ #include "OperUserNotesConst.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurve.h" +#include "/EgtDev/Include/EGkGeoVector3d.h" +#include +#include using namespace std ; +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_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() ; } //---------------------------------------------------------------------------- @@ -67,18 +102,18 @@ Machining:: NeedPrevHome( void) const bool Machining::GetStartPoint( Point3d& ptStart) const { - // verifico validità gestore DB geometrico + // 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 + // 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à + // recupero il punto iniziale di questa entità const IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nEntId) ; if ( pGeoObj->GetType() == GEO_PNT3D) { ptStart = GetGeoPoint3d( pGeoObj)->GetPoint() ; @@ -94,18 +129,18 @@ Machining::GetStartPoint( Point3d& ptStart) const bool Machining::GetEndPoint( Point3d& ptEnd) const { - // verifico validità gestore DB geometrico + // 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 + // 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à + // recupero il punto finale di questa entità const IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nEntId) ; if ( pGeoObj->GetType() == GEO_PNT3D) { ptEnd = GetGeoPoint3d( pGeoObj)->GetPoint() ; @@ -119,14 +154,426 @@ Machining::GetEndPoint( Point3d& ptEnd) const //---------------------------------------------------------------------------- bool -Machining::PrepareToolPreview( void) const +Machining::MyChangeToolPreviewShow( int nLookFlag, bool bDouble) { - // verifico validità gestori DB geometrico e CAM + // 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 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, sHead ; + int nExitDBLId ; + if ( ! bDouble) { + sTool = GetToolName() ; + sHead = GetHeadName() ; + } + else { + if ( ! GetDoubleToolData( sTool, 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)) ; + + // 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 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_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) ; + } + } + 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 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() +{ + // verifico validità gestori DB geometrico e CAM if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr) return false ; - // creo o svuoto gruppo per anteprima utensile + + // 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) ; - // se non c'è, lo aggiungo if ( nStId == GDB_ID_NULL) { nStId = m_pGeomDB->AddGroup( GDB_ID_NULL, GetOwner(), Frame3d()) ; if ( nStId == GDB_ID_NULL) @@ -134,44 +581,86 @@ Machining::PrepareToolPreview( void) const m_pGeomDB->SetName( nStId, MCH_ST) ; m_pGeomDB->SetLevel( nStId, GDB_LV_TEMP) ; } - // altrimenti lo svuoto + // altrimenti lo svuoto else m_pGeomDB->EmptyGroup( nStId) ; - // se necessario, imposto l'utensile corrente - string sCurrTool ; m_pMchMgr->GetCalcTool( sCurrTool) ; - const_cast( this)->UpdateToolData() ; - if ( ! EqualNoCase( sCurrTool, GetToolName())) { - if ( ! m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) - return false ; + + // 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) ; + } } - // copio la testa della lavorazione nel gruppo - int nHeadId = m_pMchMgr->GetHeadId( GetHeadName()) ; - int nId = m_pGeomDB->CopyGlob( nHeadId, GDB_ID_NULL, nStId) ; - m_pGeomDB->SetMode( nId, GDB_MD_STD) ; - m_pGeomDB->SetStatus( nId, GDB_ST_OFF) ; - // elimino eventuali gruppi opportunamente indicati - int nSubId = m_pGeomDB->GetFirstGroupInGroup( nId) ; - while ( nSubId != GDB_ID_NULL) { - int nNextSubId = m_pGeomDB->GetNextGroup( nSubId) ; - bool bShow = true ; - if ( m_pGeomDB->GetInfo( nSubId, KEY_PREVIEWSHOW, bShow) && ! bShow) - m_pGeomDB->Erase( nSubId) ; - nSubId = nNextSubId ; + // 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( this)->UpdateToolData() ; + if ( ! EqualNoCase( sTool, GetToolName())) + bOk = ( m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) ; + // creo la preview + bOk = bOk && MyPrepareToolPreview( false) && MyChangeToolPreviewShow( MCH_LOOK_TAB_TOOL, false) ; } - return ( nId != GDB_ID_NULL) ; + if ( bOk && nStdIdDBL != GDB_ID_NULL) { + // imposto l'utensile per la lavorazione in doppio + string sTool, sHead ; int nDblExit ; + bOk = ( GetDoubleToolData( sTool, sHead, nDblExit)) ; + if ( bOk) { + bool bOkToolSet = ( m_pMchMgr->SetCalcTool( sTool, sHead, nDblExit)) ; + bOk = bOkToolSet && MyPrepareToolPreview( true) && MyChangeToolPreviewShow( MCH_LOOK_TAB_TOOL, true) ; + if ( bOkToolSet) + bOk = ( m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) && bOk ; + } + } + if ( ! bOk) + RemoveToolPreview() ; + + return bOk ; } //---------------------------------------------------------------------------- bool -Machining::RemoveToolPreview( void) const +Machining::RemoveToolPreview( void) { - // verifico validità gestore DB geometrico + // verifico validità gestore DB geometrico if ( m_pGeomDB == nullptr) return false ; - // recupero gruppo per anteprima utensile + // recupero i gruppi per l'anteprima utensile int nStId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_ST) ; - // lo svuoto + 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() ; + m_nLookFlag = MCH_LOOK_NONE ; return true ; } @@ -179,32 +668,32 @@ Machining::RemoveToolPreview( void) const int Machining::GetToolPreviewStepCount( void) const { - // verifico validità gestori DB geometrico e CAM + // 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 e RISE + // determino il numero di entità di tutti i sottogruppi, escludendo CLIMB e RISE int nCount = 0 ; int nPxId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; while ( nPxId != GDB_ID_NULL) { - // aggiungo tutte le entità del truppo + // aggiungo tutte le entità del truppo nCount += m_pGeomDB->GetGroupObjs( nPxId) ; - // tolgo le entità CLIMB + // 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 + // 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 + // tolgo le entità HOME int nHomeId = m_pGeomDB->GetFirstNameInGroup( nPxId, MCH_CL_HOME) ; while ( nHomeId != GDB_ID_NULL) { -- nCount ; @@ -222,7 +711,7 @@ 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 nNewId = ( ( nEntId != GDB_ID_NULL) ? m_pGeomDB->GetNext( nEntId) : m_pGeomDB->GetFirstInGroup( nParentId)) ; int nNewParentId = nParentId ; // ciclo nei gruppi successivi do { @@ -235,11 +724,11 @@ Machining::GetToolPreviewNext( int nEntId, int nParentId, int nStId) const } // se trovata, esco if ( nNewId != GDB_ID_NULL) { - // se prima entità, eventuale attivazione uscite di gruppo a forare + // 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( nStId, vActExit) ; + ActivateDrillingUnit( m_nPreviewHeadId, vActExit) ; } return nNewId ; } @@ -249,9 +738,9 @@ Machining::GetToolPreviewNext( int nEntId, int nParentId, int nStId) const if ( m_pGeomDB->ExistsInfo( nNewParentId, KEY_DRACEX)) { INTVECTOR vActExit ; if ( m_pGeomDB->GetInfo( nNewParentId, KEY_DRACEX, vActExit)) - ActivateDrillingUnit( nStId, vActExit) ; + ActivateDrillingUnit( m_nPreviewHeadId, vActExit) ; } - // recupero la prima entità del successivo gruppo + // recupero la prima entità del successivo gruppo nNewId = m_pGeomDB->GetFirstInGroup( nNewParentId) ; } while ( nNewId != GDB_ID_NULL) ; return GDB_ID_NULL ; @@ -262,7 +751,7 @@ 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 nNewId = ( ( nEntId != GDB_ID_NULL) ? m_pGeomDB->GetPrev( nEntId) : m_pGeomDB->GetLastInGroup( nParentId)) ; int nNewParentId = nParentId ; // ciclo nei gruppi precedenti do { @@ -282,32 +771,148 @@ Machining::GetToolPreviewPrev( int nEntId, int nParentId, int nStId) const if ( m_pGeomDB->ExistsInfo( nNewParentId, KEY_DRACEX)) { INTVECTOR vActExit ; if ( m_pGeomDB->GetInfo( nNewParentId, KEY_DRACEX, vActExit)) - ActivateDrillingUnit( nStId, vActExit) ; + ActivateDrillingUnit( m_nPreviewHeadId, vActExit) ; } - // recupero l'ultima entità del precedente gruppo + // 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, sDBLHead ; int nDBLExit ; + bool bOk = ( GetDoubleToolData( sDBLTool, 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 + // verifico validità gestori DB geometrico e CAM if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr) return GDB_ID_NULL ; - // recupero la testa nel gruppo per anteprima utensile + + // 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) ; - // recupero gruppo per geometria di lavorazione (Cutter Location) + + // 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 + // se entità nulla if ( nEntId == GDB_ID_NULL || ! m_pGeomDB->ExistsObj( nEntId)) { // recupero il gruppo di appartenenza nParentId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; @@ -323,7 +928,7 @@ Machining::ToolPreview( int nEntId, int nStep) const } // altrimenti else { - // verifico che l'entità stia in un sottogruppo di CL + // verifico che l'entità stia in un sottogruppo di CL nParentId = m_pGeomDB->GetParentId( nEntId) ; if ( m_pGeomDB->GetParentId( nParentId) == nClId) { // se richiesta successiva @@ -354,47 +959,27 @@ Machining::ToolPreview( int nEntId, int nStep) const else nEntId = GDB_ID_NULL ; } - // se esiste il gruppo genitore, visualizzo testa preview - if ( nParentId != GDB_ID_NULL) + // se esiste il gruppo genitore, visualizzo preview + if ( nParentId != GDB_ID_NULL) { m_pGeomDB->SetStatus( nStId, GDB_ST_ON) ; - // recupero i dati di questa entità - const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nEntId)) ; - if ( pCamData == nullptr) - return GDB_ID_NULL ; - Point3d ptEnd = pCamData->GetEndPoint() ; - AdjustEndPointForAxesCalc( pCamData, ptEnd) ; - Vector3d vtTool = pCamData->GetToolDir() ; - Vector3d vtBAux = pCamData->GetBackAuxDir() ; - // dati correnti testa/uscita - int nExitId = m_pGeomDB->GetFirstNameInGroup( nStId, MCH_EXIT + ToString( GetExitNbr())) ; - Frame3d frExit ; - m_pGeomDB->GetGroupGlobFrame( nExitId, frExit) ; - // correggo eventuale movimento di disattivazione sempre in Z globale - double dVal ; - if ( m_pGeomDB->GetInfo( nExitId, MCH_EXIT_VAL, dVal)) - frExit.Translate( -dVal * Z_AX) ; - Point3d ptOrig = frExit.Orig() ; - Vector3d vtDir = frExit.VersZ() ; - Vector3d vtAux ; - int nAvId = m_pGeomDB->GetFirstNameInGroup( nStId, MCH_AUX_VECT) ; - ExeStartVector( nAvId, GDB_ID_ROOT, vtAux) ; - // rototraslo opportunamente - Frame3d frHead ; - m_pGeomDB->GetGroupGlobFrame( nStId, frHead) ; - Frame3d frRef ; - if ( vtAux.IsSmall() || AreSameOrOppositeVectorApprox( vtAux, vtDir)) - frRef.Set( ptOrig, vtDir) ; - else - frRef.Set( ptOrig, vtDir, vtAux) ; - Frame3d frShow ; - if ( vtBAux.IsSmall() || AreSameOrOppositeVectorApprox( vtBAux, vtTool)) - frShow.Set( ptEnd + vtTool * GetToolData().m_dLen, vtTool) ; - else - frShow.Set( ptEnd + vtTool * GetToolData().m_dLen, vtTool, vtBAux) ; - frHead.ToLoc( frRef) ; - frHead.ToGlob( frShow) ; - *(m_pGeomDB->GetGroupFrame( nStId)) = frHead ; + 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 ; } @@ -412,7 +997,7 @@ Machining::GetDoubleType( const string& sUserNotes) //---------------------------------------------------------------------------- bool -Machining::GetDoubleToolData( string& sDblTool, string& sDblHead, int& nDblExit) +Machining::GetDoubleToolData( string& sDblTool, string& sDblHead, int& nDblExit) const { if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr) return false ; @@ -446,7 +1031,7 @@ Machining::CalcMirrorByDouble( int nClId, const string& sUserNotes) if ( nDouble == 0) return true ; - // assegno Id entità originali + // assegno Id entità originali int nPathId = m_pGeomDB->GetFirstNameInGroup( nClId, MCH_PATH + "*") ; while ( nPathId != GDB_ID_NULL) { int nEntId = m_pGeomDB->GetFirstInGroup( nPathId) ; @@ -471,7 +1056,7 @@ Machining::CalcMirrorByDouble( int nClId, const string& sUserNotes) m_pGeomDB->SetMaterial( nClPathId, GRAY) ; nClPathId = m_pGeomDB->GetNextGroup( nClPathId) ; } - // assegno Id entità double + // assegno Id entità double nPathId = m_pGeomDB->GetFirstNameInGroup( nDblId, MCH_PATH + "*") ; while ( nPathId != GDB_ID_NULL) { int nEntId = m_pGeomDB->GetFirstInGroup( nPathId) ; @@ -506,14 +1091,55 @@ Machining::CalcMirrorByDouble( int nClId, const string& sUserNotes) while ( nPathId != GDB_ID_NULL) { int nEntId = m_pGeomDB->GetFirstInGroup( nPathId) ; while ( nEntId != GDB_ID_NULL) { - m_pGeomDB->Mirror( nEntId, ptOn, vtNorm) ; - nEntId = m_pGeomDB->GetNext( nEntId) ; + 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 ; + double dDeltaZ = 0. ; if ( GetValInNotes( sUserNotes, UN_DELTAZ, dDeltaZ) && abs( dDeltaZ) > EPS_SMALL) m_pGeomDB->TranslateGlob( nDblId, Vector3d( 0, 0, dDeltaZ)) ; @@ -546,7 +1172,7 @@ Machining::ActivateDrillingUnit( int nHeadId, const INTVECTOR& vActExit) const // imposto valori parametri bOk = bOk && pMch->LuaCreateGlobTable( EMC_VAR) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_VER, GetEMkVer()) ; - bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_HEADID, nHeadId) ; + 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) ; diff --git a/Machining.h b/Machining.h index 0be8395..ea81632 100644 --- a/Machining.h +++ b/Machining.h @@ -8,6 +8,7 @@ // // // Modifiche : 07.06.15 DS Creazione modulo. +// 24.02.26 RE Aggiunta Gestione Preview per Utensile e Testa // // //---------------------------------------------------------------------------- @@ -49,23 +50,39 @@ class Machining : public Operation public : bool GetStartPoint( Point3d& ptStart) const ; bool GetEndPoint( Point3d& ptEnd) const ; - bool PrepareToolPreview( void) const ; - bool RemoveToolPreview( void) const ; + bool ChangeToolPreviewShow( int nFlag) ; + bool PrepareToolPreview( void) ; + bool RemoveToolPreview( void) ; int GetToolPreviewStepCount( void) const ; int ToolPreview( int nEntId, int nStep) const ; protected : Machining( void) ; + ~Machining( void) ; bool SpecialApply( std::string& sErr) ; bool PostApply( std::string& sErr) ; int GetDoubleType( const std::string& sUserNotes) ; - bool GetDoubleToolData( std::string& sDblTool, std::string& sDblHead, int& nDblExit) ; + bool GetDoubleToolData( std::string& sDblTool, std::string& sDblHead, int& nDblExit) const ; bool CalcMirrorByDouble( int nClId, const std::string& sUserNotes) ; bool ActivateDrillingUnit( int nHeadId, const INTVECTOR& vActExit) const ; private : int GetToolPreviewNext( int nEntId, int nParentId, int nStId) const ; int GetToolPreviewPrev( int nEntId, int nParentId, int nStId) const ; + bool MyPrepareToolPreview( bool bDouble) ; + bool MyChangeToolPreviewShow( int nLookFlag, bool bDouble) ; + bool MyToolPreview( int nEntId, bool bDouble) const ; + + private : + int m_nLookFlag ; // flag di Visualizzazione per Preview + // lavorazione singola + int m_nPreviewHeadId ; // Id del gruppo testa di Preview + int m_nPreviewToolTip ; // Id del gruppo contenente il punto ToolTip + INTVECTOR m_vPreviewAxisIds ; // indici degli assi di Preview + // lavorazione in doppio + int m_nPreviewHeadIdDBL ; // Id della testa di Preview + int m_nPreviewToolTipDBL ; // Id del gruppo contenente il punto di ToolTip + INTVECTOR m_vPreviewAxisIdsBBL ; // indici degli assi di Preview } ; //----------------------------------------------------------------------------