//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : MachMgr.cpp Data : 23.03.15 Versione : 1.6c6 // Contenuto : Implementazione della classe MachMgr. // // // // Modifiche : 23.03.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "DllMain.h" #include "MachMgr.h" #include "MachConst.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkGdbConst.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/SELkKeyProc.h" #include using namespace std ; //---------------------------------------------------------------------------- IMachMgr* CreateMachMgr( void) { // verifico la chiave e le opzioni unsigned int nOpt1, nOpt2 ; int nOptExpDays ; int nRet = GetKeyOptions( GetEMkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; if ( nRet != KEY_OK) { string sErr = "Error on Key (MKC/" + ToString( nRet) + ")" ; LOG_ERROR( GetEMkLogger(), sErr.c_str()) ; return false ; } if ( (nOpt1 & KEYOPT_EMK_BASE) == 0 || nOptExpDays < GetCurrDay()) { string sErr = "Error on Key (MKC/OPT)" ; LOG_ERROR( GetEMkLogger(), sErr.c_str()) ; return false ; } // creo il MachMgr return static_cast ( new(nothrow) MachMgr) ; } //---------------------------------------------------------------------------- // MachMgr //---------------------------------------------------------------------------- MachMgr::MachMgr( void) { m_pGeomDB = nullptr ; m_nMachBaseId = GDB_ID_NULL ; m_nCurrMGrpId = GDB_ID_NULL ; } //---------------------------------------------------------------------------- bool MachMgr::Init( IGeomDB* pGeomDB) { m_pGeomDB = pGeomDB ; m_nMachBaseId = GDB_ID_NULL ; m_nCurrMGrpId = GDB_ID_NULL ; return ( m_pGeomDB != nullptr) ; } //---------------------------------------------------------------------------- bool MachMgr::Update( void) { // ricerca del gruppo base per le lavorazioni m_nMachBaseId = FindMachBase( GDB_ID_ROOT) ; // imposto gruppo di lavorazione corrente a nessuno m_nCurrMGrpId = GDB_ID_NULL ; // verifico i gruppi di lavorazione int nId = m_pGeomDB->GetFirstGroupInGroup( m_nMachBaseId) ; while ( nId != GDB_ID_NULL) { // recupero successivo int nNextId = m_pGeomDB->GetNextGroup( nId) ; // se non è gruppo di lavoro, lo elimino MachGrp mgData ; if ( ! VerifyMachGroup( nId, mgData)) m_pGeomDB->Erase( nId) ; // passo al successivo nId = nNextId ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::Insert( int nInsGrp) { // verifica ed eventuale creazione del gruppo base per le lavorazioni if ( ! CreateMachBase()) return false ; // cerco MachBase nel gruppo di inserimento int nInsMachBaseId = FindMachBase( nInsGrp) ; if ( nInsMachBaseId == GDB_ID_NULL) return true ; // ciclo sui suoi gruppi int nId = m_pGeomDB->GetFirstGroupInGroup( nInsMachBaseId) ; while ( nId != GDB_ID_NULL) { // prossimo gruppo int nNextId = m_pGeomDB->GetNextGroup( nId) ; // se gruppo di lavoro MachGrp mgData ; if ( VerifyMachGroup( nId, mgData)) { // recupero il nome e se già presente lo modifico string sName ; if ( ! m_pGeomDB->GetName( nId, sName) || ! GetMachGroupNewName( sName) || ! m_pGeomDB->SetName( nId, sName)) return false ; // sposto il gruppo if ( ! m_pGeomDB->Relocate( nId, m_nMachBaseId, GDB_LAST_SON)) return false ; } // passo al prossimo nId = nNextId ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::IsMachBase( int nId) const { int nLevel ; std::string sName ; return ( m_pGeomDB != nullptr && m_pGeomDB->GetLevel( nId, nLevel) && nLevel == GDB_LV_SYSTEM && m_pGeomDB->GetName( nId, sName) && sName == MACH_BASE) ; } //---------------------------------------------------------------------------- int MachMgr::FindMachBase( int nGroup) const { // verifica collegamento a DB geometrico if ( m_pGeomDB == nullptr) return GDB_ID_NULL ; // cerco il gruppo di base delle macchinate nel gruppo passato int nId = m_pGeomDB->GetFirstGroupInGroup( nGroup) ; while ( nId != GDB_ID_NULL) { // verifico se gruppo cercato if ( IsMachBase( nId)) return nId ; // passo al successivo nId = m_pGeomDB->GetNextGroup( nId) ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- bool MachMgr::VerifyMachBase( void) const { // verifica collegamento a DB geometrico if ( m_pGeomDB == nullptr) return false ; // verifica validità indice del gruppo base if ( m_nMachBaseId == GDB_ID_NULL) return false ; // verifica esistenza gruppo di base per macchinate if ( ! IsMachBase( m_nMachBaseId)) { const_cast( m_nMachBaseId) = GDB_ID_NULL ; return false ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::CreateMachBase( void) { // se già esiste, esco con successo if ( VerifyMachBase()) return true ; // non trovato, devo creare il gruppo di base delle lavorazioni m_nMachBaseId = m_pGeomDB->InsertGroup( GDB_ID_NULL, GDB_ID_ROOT, GDB_FIRST_SON, GLOB_FRM) ; if ( m_nMachBaseId == GDB_ID_NULL) return false ; // imposto nome del gruppo m_pGeomDB->SetName( m_nMachBaseId, MACH_BASE) ; // imposto livello del gruppo a System m_pGeomDB->SetLevel( m_nMachBaseId, GDB_LV_SYSTEM) ; return true ; } //---------------------------------------------------------------------------- int MachMgr::GetMachGroupNbr( void) const { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return 0 ; // ritorno numero di gruppi di lavorazione return m_pGeomDB->GetGroupObjs( m_nMachBaseId) ; } //---------------------------------------------------------------------------- int MachMgr::GetFirstMachGroup( void) const { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return GDB_ID_NULL ; // recupero il primo sottogruppo int nId = m_pGeomDB->GetFirstGroupInGroup( m_nMachBaseId) ; return nId ; } //---------------------------------------------------------------------------- int MachMgr::GetNextMachGroup( int nId) const { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return GDB_ID_NULL ; // verifico che il gruppo ricevuto sia corretto if ( m_pGeomDB->GetParentId( nId) != m_nMachBaseId) return GDB_ID_NULL ; // recupero il successivo sottogruppo int nNextId = m_pGeomDB->GetNextGroup( nId) ; return nNextId ; } //---------------------------------------------------------------------------- bool MachMgr::GetMachGroupNewName( string& sName) const { // il parametro nome deve essere valido if ( &sName == nullptr) return false ; // se gruppo base per le lavorazioni assente if ( ! VerifyMachBase()) { if ( sName.empty()) sName = "Mach01" ; return true ; } // verifico che il nome sia unico int nCount = 1 ; string sOrigName = sName ; while ( GetMachGroupId( sName) != GDB_ID_NULL) { ++ nCount ; sName = sOrigName + "_" + ToString( nCount) ; } return true ; } //---------------------------------------------------------------------------- int MachMgr::AddMachGroup( const string& sName, const string& sMachineName) { // verifica ed eventuale creazione del gruppo base per le lavorazioni if ( ! CreateMachBase()) return GDB_ID_NULL ; // verifico nome non vuoto e non esista già un gruppo con lo stesso nome if ( sName.empty() || GetMachGroupId( sName) != GDB_ID_NULL) return GDB_ID_NULL ; // verifico esistenza della macchina // !!!! TO DO !!!! // inserisco il gruppo in coda int nNewId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nMachBaseId, GLOB_FRM) ; if ( nNewId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome m_pGeomDB->SetName( nNewId, sName) ; // assegno la macchina m_pGeomDB->SetInfo( nNewId, MACH_MACHINE_KEY, sMachineName) ; // creo il sottogruppo per la macchina int nGeoMachId = m_pGeomDB->AddGroup( GDB_ID_NULL, nNewId, GLOB_FRM) ; m_pGeomDB->SetName( nGeoMachId, MACH_GEOM_GROUP) ; // creo il sottogruppo per l'attrezzaggio int nSetupId = m_pGeomDB->AddGroup( GDB_ID_NULL, nNewId, GLOB_FRM) ; m_pGeomDB->SetName( nSetupId, MACH_SETUP_GROUP) ; // creo il sottogruppo per i grezzi int nRawGroupId = m_pGeomDB->AddGroup( GDB_ID_NULL, nNewId, GLOB_FRM) ; m_pGeomDB->SetName( nRawGroupId, MACH_RAW_GROUP) ; // creo il sottogruppo per le operazioni int nOperGroupId = m_pGeomDB->AddGroup( GDB_ID_NULL, nNewId, GLOB_FRM) ; m_pGeomDB->SetName( nOperGroupId, MACH_OPER_GROUP) ; // rendo corrente il gruppo if ( ! SetCurrMachGroup( nNewId)) { m_pGeomDB->Erase( nNewId) ; return GDB_ID_NULL ; } // restituisco l'identificativo del gruppo return nNewId ; } //---------------------------------------------------------------------------- bool MachMgr::RemoveMachGroup( int nId) { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return false ; // verifico sia veramente un gruppo di lavoro if ( m_pGeomDB->GetParentId( nId) != m_nMachBaseId) return false ; // se gruppo corrente, devo definire nuovo corrente if ( m_nCurrMGrpId == nId) { // passo al successivo e se non trovato al precedente int nNextId = m_pGeomDB->GetNextGroup( nId) ; if ( nNextId == GDB_ID_NULL) nNextId = m_pGeomDB->GetPrevGroup( nId) ; // imposto il nuovo corrente (potrebbe essere anche nessuno) if ( nNextId != GDB_ID_NULL) SetCurrMachGroup( nNextId) ; else ResetCurrMachGroup() ; } // eseguo rimozione m_pGeomDB->Erase( nId) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::VerifyMachGroup( int nId, MachGrp& mgData) const { // verifica del parametro if ( &mgData == nullptr) return false ; // verifica collegamento a DB geometrico if ( m_pGeomDB == nullptr) return false ; // scansiono i sottogruppi PtrOwner pIter( CreateGdbIterator( m_pGeomDB)) ; if ( IsNull( pIter)) return false ; bool bMGeo = false ; bool bSetup = false ; bool bRaw = false ; bool bOper = false ; bool bIter = pIter->GoToFirstGroupInGroup( nId) ; while ( bIter) { string sName ; if ( pIter->GetName( sName)) { if ( sName == MACH_GEOM_GROUP) { if ( ! bMGeo) mgData.MGeoGroupId = pIter->GetId() ; bMGeo = true ; } else if ( sName == MACH_SETUP_GROUP) { if ( ! bSetup) mgData.SetupGroupId = pIter->GetId() ; bSetup = true ; } else if ( sName == MACH_RAW_GROUP) { if ( ! bRaw) mgData.RawGroupId = pIter->GetId() ; bRaw = true ; } else if ( sName == MACH_OPER_GROUP) { if ( ! bOper) mgData.OperGroupId = pIter->GetId() ; bOper = true ; } } // passo al successivo bIter = pIter->GoToNextGroup() ; } return ( bMGeo && bSetup && bRaw && bOper) ; } //---------------------------------------------------------------------------- string MachMgr::GetMachGroupName( int nId) const { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return "" ; // recupero il nome del gruppo riferito string sName ; m_pGeomDB->GetName( nId, sName) ; return sName ; } //---------------------------------------------------------------------------- int MachMgr::GetMachGroupId( const string& sName) const { // verifica dei parametri if ( &sName == nullptr || sName.empty()) return false ; // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return false ; // recupero l'identificativo del gruppo con il nome indicato PtrOwner pIter( CreateGdbIterator( m_pGeomDB)) ; if ( IsNull( pIter)) return false ; bool bIter = pIter->GoToFirstGroupInGroup( m_nMachBaseId) ; while( bIter) { // verifico il nome string sMGroupName ; if ( pIter->GetName( sMGroupName) && sMGroupName == sName) return pIter->GetId() ; // passo al successivo bIter = pIter->GoToNextGroup() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- bool MachMgr::SetCurrMachGroup( int nId) { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return false ; // verifico sia veramente un gruppo di lavoro if ( m_pGeomDB->GetParentId( nId) != m_nMachBaseId) return false ; // recupero i suoi dati MachGrp mgData ; if ( ! VerifyMachGroup( nId, mgData)) { m_nCurrMGrpId = GDB_ID_NULL ; return false ; } // se esiste gruppo corrente, lo disabilito if ( m_nCurrMGrpId != GDB_ID_NULL) { // riporto i pezzi nei grezzi precedenti nella loro posizione standard SwapParts( false) ; // nascondo precedente gruppo corrente m_pGeomDB->SetStatus( m_nCurrMGrpId, GDB_ST_OFF) ; } // imposto i dati del nuovo gruppo corrente m_nCurrMGrpId = nId ; m_cCurrMGrp = mgData ; // porto i pezzi dalla loro posizione standard nei grezzi nuovi SwapParts( true) ; // nascondo pezzi rimasti sotto la radice ShowRootParts( false) ; // rendo visibile il nuovo gruppo corrente m_pGeomDB->SetStatus( m_nCurrMGrpId, GDB_ST_ON) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::ResetCurrMachGroup( void) { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return false ; // se non c'è gruppo corrente, posso uscire subito if ( m_nCurrMGrpId == GDB_ID_NULL) return true ; // riporto i pezzi nei grezzi nella loro posizione standard SwapParts( false) ; // visualizzo pezzi rimasti sotto la radice ShowRootParts( true) ; // nascondo gruppo corrente m_pGeomDB->SetStatus( m_nCurrMGrpId, GDB_ST_OFF) ; // dichiaro nessun gruppo corrente m_nCurrMGrpId = GDB_ID_NULL ; return true ; } //---------------------------------------------------------------------------- int MachMgr::GetCurrMachGroup( void) const { // verifica del gruppo base per le lavorazioni if ( ! VerifyMachBase()) return GDB_ID_NULL ; // recupero l'indice del gruppo corrente return m_nCurrMGrpId ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPart( const Point3d& ptOrig, double dWidth, double dLen, double dHeight, Color cCol) { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // creo il solido PtrOwner pStm( GetSurfTriMeshBox( dWidth, dLen, dHeight)) ; if ( IsNull( pStm)) return GDB_ID_NULL ; // inserisco il gruppo del grezzo nella macchinata int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, Frame3d( ptOrig)) ; if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome al gruppo bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ; // inserisco il solido nel gruppo int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ; bOk = bOk && ( nId != GDB_ID_NULL) ; // assegno il nome al solido bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ; // assegno il colore al solido bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; return GDB_ID_NULL ; } // tutto ok return nRawId ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPart( int nCrvId, double dOverMat, double dZmin, double dHeight, Color cCol) { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // recupero l'ingombro della curva in globale BBox3d b3Crv ; if ( ! m_pGeomDB->GetGlobalBBox( nCrvId, b3Crv)) return GDB_ID_NULL ; // recupero il riferimento della curva Frame3d frCrv ; if ( ! m_pGeomDB->GetGlobFrame( nCrvId, frCrv)) return GDB_ID_NULL ; // recupero la curva const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // copio la curva in una composita PtrOwner pMyCrv( CreateCurveComposite()) ; if ( IsNull( pMyCrv) || ! pMyCrv->AddCurve( *pCrv)) return GDB_ID_NULL ; // determino il riferimento del grezzo Point3d ptOrig = b3Crv.GetMin() ; ptOrig.z = dZmin ; Frame3d frRaw( ptOrig) ; // porto la curva in questo riferimento pMyCrv->LocToLoc( frCrv, frRaw) ; // la schiaccio a Z = 0 if ( ! pMyCrv->Scale( Frame3d(), 1, 1, 0)) return GDB_ID_NULL ; // se non è chiusa, la chiudo if ( ! pMyCrv->IsClosed()) pMyCrv->Close() ; // la oriento in senso CCW double dAreaXY ; if ( ! pMyCrv->GetAreaXY( dAreaXY)) return GDB_ID_NULL ; if ( dAreaXY < 0) pMyCrv->Invert() ; // ne eseguo l'offset if ( ! pMyCrv->SimpleOffset( dOverMat, ICurve::OFF_EXTEND)) return GDB_ID_NULL ; // creo il solido PtrOwner pStm( GetSurfTriMeshByExtrusion( Get( pMyCrv), Vector3d(0,0,dHeight), true)) ; if ( IsNull( pStm)) return GDB_ID_NULL ; // inserisco il gruppo del grezzo nella macchinata int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ; if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome al gruppo bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ; // inserisco il solido nel gruppo int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ; bOk = bOk && ( nId != GDB_ID_NULL) ; // assegno il nome al solido bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ; // assegno il colore al solido bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; return GDB_ID_NULL ; } // tutto ok return nRawId ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPart( int nSurfId, Color cCol) { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // recupero l'ingombro della superficie in globale BBox3d b3Crv ; if ( ! m_pGeomDB->GetGlobalBBox( nSurfId, b3Crv)) return GDB_ID_NULL ; // inserisco il gruppo del grezzo nella macchinata Frame3d frRaw( b3Crv.GetMin()) ; int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ; if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome al gruppo bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ; // copio la superficie nel gruppo int nId = m_pGeomDB->CopyGlob( nSurfId, GDB_ID_NULL, nRawId) ; bOk = bOk && ( nId != GDB_ID_NULL) ; // assegno il nome al solido bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ; // assegno il colore al solido bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ; // rendo visibile il solido bOk = bOk && m_pGeomDB->SetStatus( nId, GDB_ST_ON) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; return GDB_ID_NULL ; } // nascondo la superficie originale m_pGeomDB->SetStatus( nSurfId, GDB_ST_OFF) ; // tutto ok return nRawId ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPartWithPart( int nPartId, int nCrvSrfId, double dOverMat, Color cCol) { // verifico il gruppo dei grezzi nella macchinata corrente if ( GetCurrRawGroupId() == GDB_ID_NULL) return GDB_ID_NULL ; // verifico che il pezzo non sia già usato nella macchinata corrente if ( m_pGeomDB->GetParentId( nPartId) != GDB_ID_ROOT) return GDB_ID_NULL ; // recupero il tipo di oggetto per definire il grezzo int nGtype = m_pGeomDB->GetGeoType( nCrvSrfId) ; // costruzione del grezzo int nRawId = GDB_ID_NULL ; // se grezzo da superficie (per ora senza possibilità di offset) if ( ( nGtype & GEO_SURF) != 0) { // inserisco il grezzo nRawId = AddRawPart( nCrvSrfId, cCol) ; } // se altrimenti grezzo da contorno else if ( ( nGtype & GEO_CURVE) != 0) { // determino l'ingombro del pezzo BBox3d b3Part ; if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part)) return GDB_ID_NULL ; // inserisco il grezzo double dZmin = b3Part.GetMin().z ; double dH = ( b3Part.GetMax() - b3Part.GetMin()).z ; if ( dH < RAW_MIN_H) dH = RAW_MIN_H ; nRawId = AddRawPart( nCrvSrfId, dOverMat, dZmin, dH, cCol) ; } // altrimenti grezzo rettangolare da ingombro pezzo else { // determino l'ingombro del pezzo BBox3d b3Part ; if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part)) return GDB_ID_NULL ; // deduco i dati del grezzo Point3d ptMin = b3Part.GetMin() - Vector3d( dOverMat, dOverMat, 0) ; Point3d ptMax = b3Part.GetMax() + Vector3d( dOverMat, dOverMat, 0) ; Vector3d vtDiff = ptMax - ptMin ; if ( vtDiff.z < RAW_MIN_H) vtDiff.z = RAW_MIN_H ; // inserisco il grezzo nRawId = AddRawPart( ptMin, vtDiff.x, vtDiff.y, vtDiff.z, cCol) ; } // verifico il grezzo appena calcolato if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // recupero il riferimento del grezzo Frame3d frRaw ; m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ; // determino il riferimento del pezzo rispetto al grezzo Frame3d frPart ; m_pGeomDB->GetGroupGlobFrame( nPartId, frPart) ; frPart.ToLoc( frRaw) ; // inserisco il pezzo int nGroup = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawId, frPart) ; if ( nGroup == GDB_ID_NULL || ! m_pGeomDB->GroupSwap( nPartId, nGroup, true, true)) return GDB_ID_NULL ; // mi assicuro sia visibile il pezzo e nascosto il gruppo m_pGeomDB->SetStatus( nPartId, GDB_ST_ON) ; m_pGeomDB->SetStatus( nGroup, GDB_ST_OFF) ; return nRawId ; } //---------------------------------------------------------------------------- bool MachMgr::AddPartToRawPart( int nPartId, const Point3d& ptPos, int nRawId) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // verifico che il pezzo non sia già usato nella macchinata corrente if ( m_pGeomDB->GetParentId( nPartId) != GDB_ID_ROOT) return false ; // recupero il riferimento del grezzo Frame3d frRaw ; m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ; // recupero box del pezzo BBox3d b3Part ; if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part)) return false ; // recupero il riferimento del pezzo Frame3d frPart ; m_pGeomDB->GetGroupGlobFrame( nPartId, frPart) ; // muovo riferimento del pezzo per posizionare correttamente nel grezzo Vector3d vtMove = ptPos - b3Part.GetMin() ; frPart.Translate( vtMove) ; // esprimo questo riferimento rispetto al grezzo frPart.ToLoc( frRaw) ; // inserisco il pezzo int nGroup = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawId, frPart) ; if ( nGroup == GDB_ID_NULL || ! m_pGeomDB->GroupSwap( nPartId, nGroup, true, true)) return false ; // mi assicuro sia visibile il pezzo e nascosto il gruppo m_pGeomDB->SetStatus( nPartId, GDB_ST_ON) ; m_pGeomDB->SetStatus( nGroup, GDB_ST_OFF) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::ModifyRawPartHeight( int nRawId, double dHeight) { // la nuova altezza non può essere nulla if ( dHeight < EPS_SMALL) return false ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero il solido del grezzo int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( nRawSolId == GDB_ID_NULL) return false ; // recupero il box del grezzo BBox3d b3Raw ; if ( ! m_pGeomDB->GetLocalBBox( nRawSolId, b3Raw)) return false ; // determino il coefficente di scalatura in Z double dOldH = b3Raw.GetMax().z - b3Raw.GetMin().z ; if ( dOldH < EPS_SMALL) return false ; double dCoeff = dHeight / dOldH ; // eseguo scalatura bool bOk = m_pGeomDB->Scale( nRawSolId, Frame3d( b3Raw.GetMin()), 1, 1, dCoeff) ; // dichiaro centro da ricalcolare ResetRawPartCenter( nRawId) ; return bOk ; } //---------------------------------------------------------------------------- bool MachMgr::RemoveRawPart( int nRawId) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // devo estrarre i pezzi e riportarli in lista generale SwapRawPartParts( nRawId, false) ; // cancello il grezzo m_pGeomDB->Erase( nRawId) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::VerifyRawPart( int nRawId) const { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = 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 MachMgr::TranslateRawPart( int nRawId, const Vector3d& vtMove) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // eseguo traslazione in globale return m_pGeomDB->TranslateGlob( nRawId, vtMove) ; } //---------------------------------------------------------------------------- bool MachMgr::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero centro del grezzo Point3d ptAx ; if ( ! GetRawPartCenter( nRawId, ptAx)) return false ; // eseguo rotazione in globale attorno al centro del grezzo return m_pGeomDB->RotateGlob( nRawId, ptAx, vtAx, dAngRotDeg) ; } //---------------------------------------------------------------------------- bool MachMgr::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag) { // 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 RPCR_TL : vtMove = ptP - Point3d( b3Raw.GetMin().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ; break ; case RPCR_TR : vtMove = ptP - b3Raw.GetMax() ; break ; default : // RPCP_BL vtMove = ptP - b3Raw.GetMin() ; break ; case RPCR_BR : vtMove = ptP - Point3d( b3Raw.GetMax().x, b3Raw.GetMin().y, b3Raw.GetMin().z) ; break ; } // eseguo traslazione in globale return m_pGeomDB->TranslateGlob( nRawId, vtMove) ; } //---------------------------------------------------------------------------- bool MachMgr::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag) { // 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 RPCE_TC : vtMove = ptP - Point3d( ptCen.x, b3Raw.GetMax().y, ptCen.z) ; break ; default : // RPCE_ML vtMove = ptP - Point3d( b3Raw.GetMin().x, ptCen.y, ptCen.z) ; break ; case RPCE_MR : vtMove = ptP - Point3d( b3Raw.GetMax().x, ptCen.y, ptCen.z) ; break ; case RPCE_BC : vtMove = ptP - Point3d( ptCen.x, b3Raw.GetMin().y, ptCen.z) ; break ; case RPCE_MC : vtMove = ptP - Point3d( ptCen.x, ptCen.y, b3Raw.GetMin().z) ; break ; } // eseguo traslazione in globale return m_pGeomDB->TranslateGlob( nRawId, vtMove) ; } //---------------------------------------------------------------------------- bool MachMgr::RemovePartFromRawPart( int nPartId) { // verifico DB geometrico if ( m_pGeomDB == nullptr) return false ; // recupero l'indice del grezzo int nRawId = m_pGeomDB->GetParentId( nPartId) ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // devo riportare il pezzo in lista generale int nBase ; if ( m_pGeomDB->GetInfo( nPartId, GDB_SI_BASE, nBase)) { // eseguo lo scambio m_pGeomDB->GroupSwap( nPartId, nBase, true, true) ; // mi assicuro sia nascosto m_pGeomDB->SetStatus( nPartId, GDB_ST_OFF) ; // cancello il gruppo di riferimento m_pGeomDB->Erase( nBase) ; return true ; } return false ; } //---------------------------------------------------------------------------- bool MachMgr::TranslatePartInRawPart( int nPartId, const Vector3d& vtMove) { // verifico DB geometrico if ( m_pGeomDB == nullptr) return false ; // recupero l'indice del grezzo int nRawId = m_pGeomDB->GetParentId( nPartId) ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // eseguo traslazione in globale return m_pGeomDB->TranslateGlob( nPartId, vtMove) ; } //---------------------------------------------------------------------------- bool MachMgr::RotatePartInRawPart( int nPartId, const Vector3d& vtAx, double dAngRotDeg) { // verifico DB geometrico if ( m_pGeomDB == nullptr) return false ; // recupero l'indice del grezzo int nRawId = m_pGeomDB->GetParentId( nPartId) ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero riferimento globale del pezzo Frame3d frRef ; if ( ! m_pGeomDB->GetGroupGlobFrame( nPartId, frRef)) return false ; // recupero box del pezzo in locale (non cambia con la giacitura globale) BBox3d b3Box ; if ( ! m_pGeomDB->GetLocalBBox( nPartId, b3Box)) return false ; // ne calcolo il centro e lo porto in globale Point3d ptCen ; b3Box.GetCenter( ptCen) ; ptCen.ToGlob( frRef) ; // eseguo rotazione in globale attorno al centro del pezzo return m_pGeomDB->RotateGlob( nPartId, ptCen, vtAx, dAngRotDeg) ; } //---------------------------------------------------------------------------- bool MachMgr::SetRawPartCenter( int nRawId) { // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolId)) ; if ( pStm == nullptr) return false ; // recupero il punto centro, se non esiste lo creo int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; if ( nGPntId == GDB_ID_NULL) { PtrOwner pGeoPnt( CreateGeoPoint3d()) ; nGPntId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pGeoPnt)) ; m_pGeomDB->SetName( nGPntId, MACH_RAW_CENTER) ; Color cCol ; if ( m_pGeomDB->GetCalcMaterial( nRawSolId, cCol)) m_pGeomDB->SetMaterial( nGPntId, cCol) ; } IGeoPoint3d* pGeoPnt = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nGPntId)) ; if ( pGeoPnt == nullptr) return false ; // calcolo il valore del centro Point3d ptCen ; if ( ! pStm->GetCentroid( ptCen)) return false ; // aggiorno e imposto modo a standard return ( pGeoPnt->Set( ptCen) && m_pGeomDB->SetMode( nGPntId, GDB_MD_STD)) ; } //---------------------------------------------------------------------------- bool MachMgr::ResetRawPartCenter( int nRawId) { // recupero il punto centro int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; if ( nGPntId == GDB_ID_NULL) return true ; // imposto modo a bloccato return m_pGeomDB->SetMode( nGPntId, GDB_MD_LOCKED) ; } //---------------------------------------------------------------------------- bool MachMgr::GetRawPartCenter( int nRawId, Point3d& ptCen) { // cerco di recuperare l'oggetto int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; // ne verifico la validità int nMode ; if ( nGPntId == GDB_ID_NULL || ! m_pGeomDB->GetMode( nGPntId, nMode) || nMode != GDB_MD_STD) { // provo a crearlo SetRawPartCenter( nRawId) ; nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; // se c'è ancora errore if ( nGPntId == GDB_ID_NULL) return false ; } // ne recupero il riferimento globale Frame3d frGPnt ; if ( ! m_pGeomDB->GetGlobFrame( nGPntId, frGPnt)) return false ; // recupero il punto IGeoPoint3d* pGeoPnt = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nGPntId)) ; if ( pGeoPnt == nullptr) return false ; ptCen = pGeoPnt->GetPoint() ; ptCen.ToGlob( frGPnt) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::SwapParts( bool bToRawPart) { // recupero il gruppo dei grezzi correnti int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return true ; // ciclo sui grezzi int nRawId = m_pGeomDB->GetFirstGroupInGroup( nRawGroupId) ; while ( nRawId != GDB_ID_NULL) { // sistemo i pezzi del grezzo SwapRawPartParts( nRawId, bToRawPart) ; // passo al successivo nRawId = m_pGeomDB->GetNextGroup( nRawId) ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::SwapRawPartParts( int nRawId, bool bToRawPart) { // ciclo sui gruppi nel grezzo int nId = m_pGeomDB->GetFirstGroupInGroup( nRawId) ; while ( nId != GDB_ID_NULL) { // recupero il successivo int nNextId = m_pGeomDB->GetNextGroup( nId) ; // se devo portare i pezzi dalla radice al grezzo if ( bToRawPart) { // se è un riferimento al pezzo int nSou ; if ( m_pGeomDB->GetInfo( nId, GDB_SI_SOURCE, nSou)) { m_pGeomDB->GroupSwap( nSou, nId, true, true) ; // mi assicuro sia visibile m_pGeomDB->SetStatus( nSou, GDB_ST_ON) ; } } // altrimenti dal grezzo alla radice else { // se è un pezzo spostato int nBase ; if ( m_pGeomDB->GetInfo( nId, GDB_SI_BASE, nBase)) { m_pGeomDB->GroupSwap( nId, nBase, true, true) ; // mi assicuro sia nascosto m_pGeomDB->SetStatus( nId, GDB_ST_OFF) ; } } // passo al successivo nId = nNextId ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::ShowRootParts( bool bShow) { // ciclo sui gruppi in radice int nId = m_pGeomDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; while ( nId != GDB_ID_NULL) { // se pezzo, lo nascondo if ( ! IsMachBase( nId)) m_pGeomDB->SetStatus( nId, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ; // passo al successivo nId = m_pGeomDB->GetNextGroup( nId) ; } return true ; }