diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 59bb725..0545ff1 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index ffa979b..b7547d9 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -308,6 +308,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index d29cc3d..68d9fdd 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -297,6 +297,9 @@ File di origine\GeoCreate + + File di origine\Base + diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index c3a454f..0a98d85 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -5006,6 +5006,10 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams) // verifico che la seconda sia chiusa if ( ! pCloCrv->IsClosed()) return false ; + // verifico anche che non si autointersechi con attraversamento + SelfIntersCurve sintC( *pCloCrv) ; + if ( sintC.GetNumCrossInters() > 0) + return false ; // recupero i riferimenti in cui sono immerse Frame3d frCrv ; if ( ! m_pGDB->GetGlobFrame( nIdCrv, frCrv)) diff --git a/GeomDB.cpp b/GeomDB.cpp index 666859d..9a32766 100644 --- a/GeomDB.cpp +++ b/GeomDB.cpp @@ -35,13 +35,22 @@ using namespace std ; IGeomDB* CreateGeomDB( void) { - // verifico la chiave - int nRet = VerifyKey( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV) ; + // verifico la chiave e le opzioni + unsigned int nOpt1, nOpt2 ; + int nOptExpDays ; + int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, + nOpt1, nOpt2, nOptExpDays) ; if ( nRet != KEY_OK) { string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; - return nullptr ; + return false ; } + if ( (nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) { + string sErr = "Error on Key (GKC/OPT)" ; + LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; + return false ; + } + // creo il GeomDB return static_cast ( new(nothrow) GeomDB) ; } @@ -99,22 +108,6 @@ GeomDB::Clear( void) bool GeomDB::Load( const string& sFileIn, int nGroupId) { - // verifico la chiave e le opzioni - unsigned int nOpt1, nOpt2 ; - int nOptExpDays ; - int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, - nOpt1, nOpt2, nOptExpDays) ; - if ( nRet != KEY_OK) { - string sErr = "Error on Key (GKL/" + ToString( nRet) + ")" ; - LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; - return false ; - } - if ( (nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) { - string sErr = "Error on Key (GKL/OPT)" ; - LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; - return false ; - } - // recupero massimo Id (diventa Id base per entità da caricare) int nBaseGdbId = m_IdManager.GetMaxId() ; @@ -581,6 +574,25 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj return nId ; } +//---------------------------------------------------------------------------- +bool +GeomDB::ReplaceGeoObj( int nId, IGeoObj* pGeoObj) +{ + // assegno GeoObj a gestore puntatore con rilascio automatico + PtrOwner pRPGeoObj( pGeoObj) ; + if ( IsNull( pRPGeoObj)) + return false ; + // recupero l'oggetto Gdb + GdbGeo* pGdbGeo = GetGdbGeo( nId) ; + if ( pGdbGeo == nullptr) + return false ; + // elimino il vecchio oggetto e lo sostituisco con il nuovo + delete pGdbGeo->m_pGeoObj ; + pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ; + + return true ; +} + //---------------------------------------------------------------------------- int GeomDB::GetFirstInGroup( int nGroupId) const diff --git a/GeomDB.h b/GeomDB.h index 2aab785..024433a 100644 --- a/GeomDB.h +++ b/GeomDB.h @@ -41,6 +41,7 @@ class GeomDB : public IGeomDB virtual int InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& frFrame) ; virtual int AddGeoObj( int nId, int nParentId, IGeoObj* pGeoObj) ; virtual int InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj) ; + virtual bool ReplaceGeoObj( int nId, IGeoObj* pGeoObj) ; virtual int GetFirstInGroup( int nGroupId) const ; virtual int GetNext( int nId) const ; virtual int GetLastInGroup( int nGroupId) const ; diff --git a/Intervals.cpp b/Intervals.cpp new file mode 100644 index 0000000..52a75ca --- /dev/null +++ b/Intervals.cpp @@ -0,0 +1,185 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2015 +//---------------------------------------------------------------------------- +// File : Intervals.cpp Data : 03.08.15 Versione : 1.6h1 +// Contenuto : Implementazione della classe insieme di intervalli Intervals. +// +// +// +// Modifiche : 03.08.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "\EgtDev\Include\EGkGeoConst.h" +#include "\EgtDev\Include\EGkIntervals.h" +#include + +using namespace std ; + +//---------------------------------------------------------------------------- +void +Intervals::Reset( void) +{ + m_lInts.clear() ; +} + +//---------------------------------------------------------------------------- +void +Intervals::Set( double dMin, double dMax) +{ + Reset() ; + // verifico ordine + if ( dMin > dMax) + swap( dMin, dMax) ; + // aggiungo + m_lInts.emplace_back( dMin, dMax) ; +} + +//---------------------------------------------------------------------------- +void +Intervals::Add( double dMin, double dMax) +{ + // verifico ordine + if ( dMin > dMax) + swap( dMin, dMax) ; + + // aggiungo, tenendo conto di interazioni con eventuali intervalli già presenti + auto iInsert = m_lInts.end() ; + auto iIter = m_lInts.begin() ; + while ( iIter != m_lInts.end()) { + // se interseca l'intervallo corrente + if ( dMin < iIter->second + EPS_SMALL && dMax > iIter->first - EPS_SMALL) { + // se ha già interessato un intervallo precedente + if ( iInsert != m_lInts.end()) { + // aggiorno il massimo dell'intervallo già interessato + iInsert->second = max( dMax, iIter->second) ; + // cancello il corrente + iIter = m_lInts.erase( iIter) ; + // il nuovo iteratore è già il successivo + } + // altrimenti modifico il corrente + else { + // salvo l'intervallo di inserimento + iInsert = iIter ; + // lo modifico + iInsert->first = min( iInsert->first, dMin) ; + iInsert->second = max( iInsert->second, dMax) ; + // passo al successivo + ++ iIter ; + } + } + // se il nuovo intervallo finisce prima + else if ( dMax <= iIter->first - EPS_SMALL) { + // se non già inserito, lo faccio ora + if ( iInsert == m_lInts.end()) + iInsert = m_lInts.emplace( iIter, dMin, dMax) ; + // termino + break ; + } + // se il nuovo intervallo inizia dopo + if ( dMin > iIter->second + EPS_SMALL) + // passo al successivo + ++ iIter ; + } + // se non ancora inserito, va aggiunto alla fine + if ( iInsert == m_lInts.end()) + m_lInts.emplace_back( dMin, dMax) ; +} + +//---------------------------------------------------------------------------- +void +Intervals::Remove( double dMin, double dMax) +{ + // verifico ordine + if ( dMin > dMax) + swap( dMin, dMax) ; + + // scorro gli intervalli + auto iIter = m_lInts.begin() ; + while ( iIter != m_lInts.end()) { + // se interseca l'intervallo corrente + if ( dMin < iIter->second && dMax > iIter->first) { + // se devo limitarlo inferiormente + if ( dMin < ( iIter->first + EPS_SMALL) && dMax < ( iIter->second - EPS_SMALL)) { + iIter->first = dMax ; + // passo al successivo + ++ iIter ; + } + // se devo limitarlo superiormente + else if ( dMin > ( iIter->first + EPS_SMALL) && dMax > ( iIter->second - EPS_SMALL)) { + iIter->second = dMin ; + // passo al successivo + ++ iIter ; + } + // se devo dividerlo in due parti + else if ( dMin > ( iIter->first + EPS_SMALL) && dMax < ( iIter->second - EPS_SMALL)) { + // inserisco il nuovo intervallo che corrisponde alla parte inferiore + iIter = m_lInts.emplace( iIter, iIter->first, dMin) ; + // modifico l'intervallo successivo + ++ iIter ; + iIter->first = dMax ; + // passo al successivo + ++ iIter ; + } + // altrimenti devo eliminarlo + else { + iIter = m_lInts.erase( iIter) ; + // il nuovo iteratore è già il successivo + } + } + // se è tutto minore dell'intervallo corrente, ho finito + else if ( dMax <= iIter->first) + break ; + // altrimenti è tutto maggiore dell'intervallo corrente, passo al successivo + else // dMin >= iIter->second + ++ iIter ; + } +} + +//---------------------------------------------------------------------------- +bool +Intervals::GetMinMax( double& dMin, double& dMax) +{ + // verifico ci siano intervalli + if ( m_lInts.empty()) + return false ; + // l'estensione va dall'inizio del primo intervallo alla fine dell'ultimo + dMin = m_lInts.front().first ; + dMax = m_lInts.back().second ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +Intervals::GetFirst( double& dMin, double& dMax) +{ + // vado all'inizio + m_Iter = m_lInts.begin() ; + // verifico sia definito + if ( m_Iter == m_lInts.end()) + return false ; + // recupero i dati + dMin = m_Iter->first ; + dMax = m_Iter->second ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +Intervals::GetNext( double& dMin, double& dMax) +{ + // vado al successivo + if ( m_Iter == m_lInts.end()) + return false ; + ++ m_Iter ; + // verifico sia definito + if ( m_Iter == m_lInts.end()) + return false ; + // recupero i dati + dMin = m_Iter->first ; + dMax = m_Iter->second ; + return true ; +} diff --git a/SelfIntersCurve.cpp b/SelfIntersCurve.cpp index 014a0d9..a27fbeb 100644 --- a/SelfIntersCurve.cpp +++ b/SelfIntersCurve.cpp @@ -98,6 +98,26 @@ SelfIntersCurve::GetNumInters( void) return m_nNumInters ; } +//---------------------------------------------------------------------------- +int +SelfIntersCurve::GetNumCrossInters( void) +{ + int nNumCrossInters = 0 ; + for ( int i = 0 ; i < m_nNumInters ; ++ i) { + // se con sovrapposizione + if ( m_Info[i].bOverlap) { + if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[1].nNextTy) + ++ nNumCrossInters ; + } + // altrimenti + else { + if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[0].nNextTy) + ++ nNumCrossInters ; + } + } + return nNumCrossInters ; +} + //---------------------------------------------------------------------------- bool SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)