//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : Drilling.cpp Data : 21.05.15 Versione : 1.6e7 // Contenuto : Implementazione gestione forature. // // // // Modifiche : 21.05.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "MachMgr.h" #include "DllMain.h" #include "Disposition.h" #include "Table.h" #include "/EgtDev/Include/EMkDispositionConst.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EGnFileUtils.h" using namespace std ; //---------------------------------------------------------------------------- static std::string DIS_TABLE = "Tab" ; static std::string DIS_FXD_TOT = "FxT" ; static std::string DIS_FXD_NAME = "FxN" ; static std::string DIS_FXD_POS = "FxP" ; static std::string DIS_FXD_ANG = "FxA" ; static std::string DIS_MVD_TOT = "MvT" ; static std::string DIS_MVD_ID = "MvI" ; static std::string DIS_MVD_TYPE = "MvT" ; static std::string DIS_MVD_PNT = "MvP" ; static std::string DIS_MVD_ANG = "MvA" ; static std::string DIS_MVD_FLAG = "MvF" ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkDisposition", Disposition) ; //---------------------------------------------------------------------------- const string& Disposition::GetClassName( void) const { return USEROBJ_GETNAME( Disposition) ; } //---------------------------------------------------------------------------- Disposition* Disposition::Clone( void) const { // alloco oggetto Disposition* pDisp = new(nothrow) Disposition ; // eseguo copia dei dati if ( pDisp != nullptr) { try { pDisp->m_nOwnerId = GDB_ID_NULL ; pDisp->m_pGeomDB = nullptr ; pDisp->m_sTabName = m_sTabName ; pDisp->m_bTabOk = m_bTabOk ; pDisp->m_vFixData = m_vFixData ; pDisp->m_vMvrData = m_vMvrData ; } catch( ...) { delete pDisp ; return nullptr ; } } // ritorno l'oggetto return pDisp ; } //---------------------------------------------------------------------------- bool Disposition::Dump( string& sOut, bool bMM, const char* szNewLine) const { sOut += GetClassName() + "[mm]" + szNewLine ; sOut += "Tab=" + m_sTabName + ( m_bTabOk ? " (ok)" : " (to verify)") + szNewLine ; for ( const auto& FixData : m_vFixData) { sOut += "FxD=" + FixData.sName + "," + ToString( FixData.nId) + ",(" + ToString( FixData.ptPos) + ")," + ToString( FixData.dAng) + szNewLine ; } for ( const auto& MvrData : m_vMvrData) { sOut += "MvD=" + ToString( MvrData.nRawId) + "," ; switch ( MvrData.nType) { case MoveRawData::NONE : sOut += string( " NONE") + szNewLine ; break ; case MoveRawData::COR : sOut += " COR,(" + ToString( MvrData.ptP) + ")," + ToString( MvrData.nFlag) + szNewLine ; break ; case MoveRawData::CEN : sOut += " CEN,(" + ToString( MvrData.ptP) + ")," + ToString( MvrData.nFlag) + szNewLine ; break ; case MoveRawData::ROT : sOut += " ROT,(" + ToString( MvrData.ptP) + ")" + szNewLine ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::Save( STRVECTOR& vString) const { try { int k = - 1 ; int nFxdTot = int( m_vFixData.size()) ; int nFxdLines = 1 + 3 * nFxdTot ; int nMvdTot = int( m_vMvrData.size()) ; int nMvdLines = 1 + 4 * nMvdTot ; vString.insert( vString.begin(), 1 + nFxdLines + nMvdLines, "") ; // nome if ( ! SetVal( DIS_TABLE, m_sTabName, vString[++k])) return false ; // dati sottopezzi if ( ! SetVal( DIS_FXD_TOT, nFxdTot, vString[++k])) return false ; for ( const auto& FixData : m_vFixData) { if ( ! SetVal( DIS_FXD_NAME, FixData.sName, vString[++k]) || ! SetVal( DIS_FXD_POS, FixData.ptPos, vString[++k]) || ! SetVal( DIS_FXD_ANG, FixData.dAng, vString[++k])) return false ; } // dati posizionamento grezzi if ( ! SetVal( DIS_MVD_TOT, nMvdTot, vString[++k])) return false ; for ( const auto& MvrData : m_vMvrData) { if ( ! SetVal( DIS_MVD_ID, MvrData.nRawId, vString[++k]) || ! SetVal( DIS_MVD_TYPE, MvrData.nType, vString[++k]) || ! SetVal( DIS_MVD_PNT, MvrData.ptP, vString[++k]) || ! SetVal( DIS_MVD_FLAG, MvrData.nFlag, vString[++k])) return false ; } } catch( ...) { return false ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::Load( const STRVECTOR& vString) { if ( vString.size() < 3) return false ; int k = - 1 ; // nome if ( ! GetVal( vString[++k], DIS_TABLE, m_sTabName)) return false ; // dati sottopezzi int nFxdTot ; if ( ! GetVal( vString[++k], DIS_FXD_TOT, nFxdTot)) return false ; int nFxdLines = 1 + 3 * nFxdTot ; if ( int( vString.size()) < 1 + nFxdLines + 1) return false ; m_vFixData.insert( m_vFixData.begin(), nFxdTot, FixtureData()) ; for ( auto& FixData : m_vFixData) { if ( ! GetVal( vString[++k], DIS_FXD_NAME, FixData.sName) || ! GetVal( vString[++k], DIS_FXD_POS, FixData.ptPos) || ! GetVal( vString[++k], DIS_FXD_ANG, FixData.dAng)) return false ; } // dati posizionamento grezzi int nMvdTot ; if ( ! GetVal( vString[++k], DIS_MVD_TOT, nMvdTot)) return false ; int nMvdLines = 1 + 4 * nMvdTot ; if ( int( vString.size()) < 1 + nFxdLines + nMvdLines) return false ; m_vMvrData.insert( m_vMvrData.begin(), nMvdTot, MoveRawData()) ; for ( auto& MvrData : m_vMvrData) { if ( ! GetVal( vString[++k], DIS_MVD_ID, MvrData.nRawId) || ! GetVal( vString[++k], DIS_MVD_TYPE, MvrData.nType) || ! GetVal( vString[++k], DIS_MVD_PNT, MvrData.ptP) || ! GetVal( vString[++k], DIS_MVD_FLAG, MvrData.nFlag)) return false ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::SetOwner( int nId, IGeomDB* pGDB) { m_nOwnerId = nId ; m_pGeomDB = pGDB ; return ( m_nOwnerId != GDB_ID_NULL && m_pGeomDB != nullptr) ; } //---------------------------------------------------------------------------- int Disposition::GetOwner( void) const { return m_nOwnerId ; } //---------------------------------------------------------------------------- IGeomDB* Disposition::GetGeomDB( void) const { return m_pGeomDB ; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Disposition::Disposition( void) { m_nOwnerId = GDB_ID_NULL ; m_pGeomDB = nullptr ; m_pMchMgr = nullptr ; m_bTabOk = false ; } //---------------------------------------------------------------------------- bool Disposition::Init( MachMgr* pMchMgr) { m_pMchMgr = pMchMgr ; if ( m_pMchMgr == nullptr) return false ; if ( m_pMchMgr->GetGeomDB() != m_pGeomDB) return false ; return true ; } //---------------------------------------------------------------------------- bool Disposition::SetTable( const string& sTable) { // dichiaro tavola non verificata m_bTabOk = false ; // verifico il gestore lavorazioni if ( m_pMchMgr == nullptr) return false ; // recupero la macchina corrente Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr) return false ; // imposta questa tavola come corrente if ( ! pMch->SetCurrTable( sTable)) return false ; // recupero il primo riferimento della tavola Table* pTab = pMch->GetTable( sTable) ; if ( pTab == nullptr) return false ; m_ptRef1 = pTab->GetRef1() ; // salvo il nome e dichiaro tavola verificata m_sTabName = sTable ; m_bTabOk = true ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetTable( string& sTable) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico tavola if ( ! m_bTabOk && ! const_cast(this)->SetTable( m_sTabName)) return false ; // recupero il nome della tavola sTable = m_sTabName ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetTableRef1( Point3d& ptRef1) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico tavola if ( ! m_bTabOk && ! const_cast(this)->SetTable( m_sTabName)) return false ; // recupero il primo riferimento della tavola ptRef1 = m_ptRef1 ; return true ; } //---------------------------------------------------------------------------- bool Disposition::Apply(void) { // verifico tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // aggiornamento sottopezzi for ( auto& FixData : m_vFixData) { // se sottopezzo da caricare if ( FixData.nId == GDB_ID_NULL) { int nId = AddFixture( FixData.sName, FixData.ptPos, FixData.dAng, false) ; if ( nId == GDB_ID_NULL) { string sOut = "Error adding fixture " + FixData.sName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } else FixData.nId = nId ; } } // aggiornamento movimento pezzi for ( const auto& vMvrData : m_vMvrData) { switch ( vMvrData.nType) { case MoveRawData::COR : if ( ! MoveToCornerRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false)) { string sOut = "Error in MoveToCornerRawPart " + ToString( vMvrData.nRawId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } break ; case MoveRawData::CEN : if ( ! MoveToCenterRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false)) { string sOut = "Error in MoveToCenterRawPart " + ToString( vMvrData.nRawId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } break ; case MoveRawData::ROT : if ( ! ApplyRotationToRawPart( vMvrData.nRawId, vMvrData.ptP.x, vMvrData.ptP.y, vMvrData.ptP.z)) { string sOut = "Error in ApplyRotationToRawPart " + ToString( vMvrData.nRawId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } break ; } } return true ; } //---------------------------------------------------------------------------- int Disposition::AddFixture( const string& sName, const Point3d& ptPos, double dAngDeg, bool bAddToList) { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return GDB_ID_NULL ; // verifico tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return GDB_ID_NULL ; // recupero il gruppo delle fixtures nella macchinata corrente int nFixtGrpId = m_pMchMgr->GetCurrFixtGroupId() ; if ( nFixtGrpId == GDB_ID_NULL) return GDB_ID_NULL ; // verifico esistenza file sottopezzo string sFixtFile = m_pMchMgr->GetCurrFixtDir() + "\\" + sName + ".Nge" ; if ( ! ExistsFile( sFixtFile)) return GDB_ID_NULL ; // inserisco il sottopezzo nel gruppo if ( ! m_pGeomDB->Load( sFixtFile, nFixtGrpId)) return GDB_ID_NULL ; int nFixtId = m_pGeomDB->GetLastGroupInGroup( nFixtGrpId) ; if ( nFixtId == GDB_ID_NULL) return GDB_ID_NULL ; // imposto il livello a temporaneo m_pGeomDB->SetLevel( nFixtId, GDB_LV_TEMP) ; // la muovo nella posizione voluta Vector3d vtMove = ( m_ptRef1 + ptPos) - ORIG ; m_pGeomDB->TranslateGlob( nFixtId, vtMove) ; // la ruoto if ( fabs( dAngDeg) > EPS_ANG_SMALL) m_pGeomDB->RotateGroup( nFixtId, ORIG, Z_AX, dAngDeg) ; // se da aggiungere alla lista if ( bAddToList) m_vFixData.emplace_back( sName, nFixtId, ptPos, dAngDeg) ; return nFixtId ; } //---------------------------------------------------------------------------- bool Disposition::MoveFixture( int nId, const Vector3d& vtMove) { // verifica validità sottopezzo if ( ! VerifyFixture( nId)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // muovo l'oggetto m_pGeomDB->TranslateGlob( nId, vtMove) ; // aggiorno la posizione dell'oggetto nel vettore dei comandi for ( auto iIter = m_vFixData.begin() ; iIter != m_vFixData.end() ; ++ iIter) { if ( iIter->nId == nId) { iIter->ptPos += vtMove ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::RotateFixture( int nId, double dAngDeg) { // verifica validità sottopezzo if ( ! VerifyFixture( nId)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // muovo l'oggetto m_pGeomDB->RotateGroup( nId, ORIG, Z_AX, dAngDeg) ; // aggiorno la posizione dell'oggetto nel vettore dei comandi for ( auto& FixData : m_vFixData) { if ( FixData.nId == nId) { FixData.dAng += dAngDeg ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::RemoveFixture( int nId) { // verifica validità sottopezzo if ( ! VerifyFixture( nId)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // rimuovo l'oggetto dal DB m_pGeomDB->Erase( nId) ; // rimuovo l'oggetto dal vettore dei comandi while ( true) { auto iIter = find_if( m_vFixData.begin(), m_vFixData.end(), [ nId]( const FixtureData& Fxt) { return ( Fxt.nId == nId) ; }) ; if ( iIter == m_vFixData.end()) break ; else m_vFixData.erase( iIter) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; // determino il box del grezzo (solo il solido ovviamente) BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return false ; // calcolo il movimento necessario Vector3d vtMove ; switch ( nFlag) { case MCH_CR_TL : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMin().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ; break ; case MCH_CR_TR : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ; break ; default : // RPCP_BL vtMove = ( m_ptRef1 + ptP) - b3Raw.GetMin() ; break ; case MCH_CR_BR : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, b3Raw.GetMin().y, b3Raw.GetMin().z) ; break ; } // eseguo traslazione in globale if ( ! vtMove.IsSmall()) m_pGeomDB->TranslateGlob( nRawId, vtMove) ; // se da aggiungere alla lista if ( bAddToList) { auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; if ( iIter == m_vMvrData.end()) m_vMvrData.emplace_back( nRawId, MoveRawData::COR, ptP, nFlag) ; else *iIter = MoveRawData( nRawId, MoveRawData::COR, ptP, nFlag) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; // determino il box del grezzo (solo il solido ovviamente) BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return false ; // ricavo il centro dal box (in generale non è il centro geometrico) Point3d ptCen ; b3Raw.GetCenter( ptCen) ; // calcolo il movimento necessario Vector3d vtMove ; switch ( nFlag) { case MCH_CE_TC : vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, b3Raw.GetMax().y, ptCen.z) ; break ; default : // RPCE_ML vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMin().x, ptCen.y, ptCen.z) ; break ; case MCH_CE_MR : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, ptCen.y, ptCen.z) ; break ; case MCH_CE_BC : vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, b3Raw.GetMin().y, ptCen.z) ; break ; case MCH_CE_MC : vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, ptCen.y, b3Raw.GetMin().z) ; break ; } // eseguo traslazione in globale if ( ! vtMove.IsSmall()) m_pGeomDB->TranslateGlob( nRawId, vtMove) ; // se da aggiungere alla lista if ( bAddToList) { auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; if ( iIter == m_vMvrData.end()) m_vMvrData.emplace_back( nRawId, MoveRawData::CEN, ptP, nFlag) ; else *iIter = MoveRawData( nRawId, MoveRawData::CEN, ptP, nFlag) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveRawPart( int nRawId, const Vector3d& vtMove) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // se movimento nullo, non devo fare alcunché if ( vtMove.IsSmall()) return true ; // verifico ci sia già un movimento assoluto di questo grezzo auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; if ( iIter == m_vMvrData.end()) return false ; // eseguo traslazione in globale m_pGeomDB->TranslateGlob( nRawId, vtMove) ; // aggiorno comando di movimento iIter->ptP += vtMove ; return true ; } //---------------------------------------------------------------------------- bool Disposition::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero centro del grezzo Point3d ptAx ; if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptAx)) return false ; // eseguo rotazione in globale attorno al centro del grezzo if ( ! m_pGeomDB->RotateGlob( nRawId, ptAx, vtAx, dAngRotDeg)) return false ; // recupero riferimento globale del grezzo Frame3d frRaw ; m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ; // ne calcolo gli angoli di Eulero double dAngCDeg, dAngADeg, dAngC1Deg ; frRaw.GetRotationsCAC1( dAngCDeg, dAngADeg, dAngC1Deg) ; // aggiungo o modifico nella lista auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && Mrv.nType == MoveRawData::ROT) ; }) ; if ( iIter == m_vMvrData.end()) m_vMvrData.emplace_back( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; else *iIter = MoveRawData( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; return true ; } //---------------------------------------------------------------------------- bool Disposition::ApplyRotationToRawPart( int nRawId, double dAngCDeg, double dAngADeg, double dAngC1Deg) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero riferimento del grezzo (coincide con quello globale) Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ; // lo trasformo nel nuovo riferimento pfrRaw->Set( pfrRaw->Orig(), dAngCDeg, dAngADeg, dAngC1Deg) ; return true ; } //---------------------------------------------------------------------------- bool Disposition::RemoveRawPart( int nRawId) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // elimino i movimenti registrati per questo grezzo while ( true) { auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId) ; }) ; if ( iIter == m_vMvrData.end()) break ; else m_vMvrData.erase( iIter) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::VerifyFixture( int nFixtId) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // recupero il gruppo delle fixtures nella macchinata corrente int nFixtGrpId = m_pMchMgr->GetCurrFixtGroupId() ; if ( nFixtGrpId == GDB_ID_NULL) return false ; // verifico che l'oggetto appartenga al gruppo delle fixtures if ( m_pGeomDB->GetParentId( nFixtId) != nFixtGrpId) return false ; return true ; } //---------------------------------------------------------------------------- bool Disposition::VerifyRawPart( int nRawId) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = m_pMchMgr->GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return false ; // verifico che questo grezzo ne faccia parte if ( m_pGeomDB->GetParentId( nRawId) != nRawGroupId) return false ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetFixtureData( int nInd, string& sName, int& nId, Point3d& ptPos, double& dAngDeg) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico l'indice if ( nInd < 0 || nInd >= int( m_vFixData.size())) return false ; // recupero i dati sName = m_vFixData[nInd].sName ; nId = m_vFixData[nInd].nId ; ptPos = m_vFixData[nInd].ptPos ; dAngDeg = m_vFixData[nInd].dAng ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetMoveRawData( int nInd, int& nRawId, int& nType, Point3d& ptPos, int& nFlag) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico l'indice if ( nInd < 0 || nInd >= int( m_vMvrData.size())) return false ; // recupero i dati nRawId = m_vMvrData[nInd].nRawId ; nType = m_vMvrData[nInd].nType ; ptPos = m_vMvrData[nInd].ptP ; nFlag = m_vMvrData[nInd].nFlag ; return true ; }