From e1785a70055b7a777cefad39fc2c92fc776428a2 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Thu, 3 Jan 2019 08:00:38 +0000 Subject: [PATCH] EgtGeomKernel : - aggiunta gestione parti connesse in SurfTriMesh. --- GdbExecutor.cpp | 74 ++++++++++++++++++ GdbExecutor.h | 3 + SurfTriMesh.cpp | 161 ++++++++++++++++++++++++++++++++++++++-- SurfTriMesh.h | 13 +++- SurfTriMeshFaceting.cpp | 60 +++++++-------- 5 files changed, 269 insertions(+), 42 deletions(-) diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 8912b54..a0585ec 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -2165,6 +2165,15 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) else if ( sCmd2 == "SEW" || sCmd2 == "DOSEWING") { return SurfTriMeshDoSewing( vsParams) ; } + else if ( sCmd2 == "CHECKCONNECTION") { + return SurfTrimeshCheckConnection( vsParams) ; + } + else if ( sCmd2 == "REMOVEPART") { + return SurfTrimeshRemovePart( vsParams) ; + } + else if ( sCmd2 == "CLONEPART") { + return SurfTrimeshClonePart( vsParams) ; + } else return false ; } @@ -2575,6 +2584,71 @@ GdbExecutor::SurfTriMeshDoSewing( const STRVECTOR& vsParams) return true ; } +//---------------------------------------------------------------------------- +bool +GdbExecutor::SurfTrimeshCheckConnection( const STRVECTOR& vsParams) +{ + // Parametri: SurfId + if ( vsParams.size() != 1) + return false ; + // recupero id superficie + int nIdSurf = GetIdParam( vsParams[0]) ; + ISurfTriMesh* pStmM = GetSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ; + SurfTriMesh* pStmF = static_cast ( pStmM) ; + int nCompo = pStmF->GetPartCount() ; + m_pGDB->SetInfo( nIdSurf, "CompoCount", nCompo) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::SurfTrimeshRemovePart( const STRVECTOR& vsParams) +{ + // Parametri: SurfId, nPart + if ( vsParams.size() != 2) + return false ; + // Recupero Id superficie + int nIdSurf = GetIdParam( vsParams[0]) ; + ISurfTriMesh* pStmM = GetSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ; + SurfTriMesh* pStmF = static_cast ( pStmM) ; + // Recupero parte da rimuovere + int nPart ; + if ( ! FromString( vsParams[1], nPart)) + return false ; + if ( ! pStmF->RemovePart( nPart)) + return false ; + /*const*/ STRVECTOR vsNewParams ; + vsNewParams.emplace_back( vsParams[0]) ; + SurfTrimeshCheckConnection( vsNewParams) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::SurfTrimeshClonePart( const STRVECTOR& vsParams) +{ + // Parametri : IdNew, IdOld, IdParent, nPart + if ( vsParams.size() != 4) + return false ; + // Recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[2]), frRef)) + return false ; + // Recupero parte da rimuovere + int nPart ; + if ( ! FromString( vsParams[3], nPart)) + return false ; + // Recupero id superficie vecchia + int nIdSurf = GetIdParam( vsParams[1]) ; + SurfTriMesh* pSurf = GetBasicSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ; + if ( pSurf == nullptr) + return false ; + // Clono la componente + PtrOwner pNewSurf( pSurf->ClonePart( nPart)) ; + // Inserisco nel DB + return AddGeoObj(vsParams[0], vsParams[2], Release( pNewSurf)) ; +} + /* //---------------------------------------------------------------------------- bool diff --git a/GdbExecutor.h b/GdbExecutor.h index 71c238f..012acd2 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -114,6 +114,9 @@ class GdbExecutor : public IGdbExecutor bool SurfTriMeshChangeSmoothAng( const STRVECTOR& vsParams) ; bool SurfTriMeshDoCompacting( const STRVECTOR& vsParams) ; bool SurfTriMeshDoSewing( const STRVECTOR& vsParams) ; + bool SurfTrimeshCheckConnection( const STRVECTOR& vsParams) ; + bool SurfTrimeshRemovePart( const STRVECTOR& vsParams) ; + bool SurfTrimeshClonePart( const STRVECTOR& vsParams) ; //bool ExecuteVolZmap( const std::string& sCmd2, const STRVECTOR& vsParams) ; //bool VolZmapCreate( const STRVECTOR& vsParams) ; //bool VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) ; diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 1cdce68..7260a87 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -1,13 +1,14 @@ //---------------------------------------------------------------------------- -// EgalTech 2014-2015 +// EgalTech 2014-2019 //---------------------------------------------------------------------------- -// File : SurfTriMesh.cpp Data : 15.05.14 Versione : 1.5e5 +// File : SurfTriMesh.cpp Data : 02.01.19 Versione : 1.9l4 // Contenuto : Implementazione della classe Superfici TriMesh. // // // // Modifiche : 26.03.14 DS Creazione modulo. // 15.05.14 DS Corr. errore CreateByTwoCurves che dava loop infinito. +// 02.01.19 LM Aggiunta gestione connessione. // //---------------------------------------------------------------------------- @@ -26,6 +27,7 @@ #include "/EgtDev/Include/EGkUiUnits.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include +#include using namespace std ; @@ -36,7 +38,7 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ; SurfTriMesh::SurfTriMesh( void) : m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dBoundaryAng( STM_STD_BOUNDARY_ANG), m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false), - m_nTimeStamp( 0), m_nTempProp( 0), m_pHGrd3d( nullptr) + m_nTimeStamp( 0), m_nTempProp( 0), m_pHGrd3d( nullptr), m_nParts( -1) { m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ; m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ; @@ -81,6 +83,7 @@ SurfTriMesh::AddVertex( const Point3d& ptVert) { // imposto ricalcolo m_nStatus = TO_VERIFY ; + m_nParts = - 1 ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; // inserisco il vertice @@ -146,6 +149,7 @@ SurfTriMesh::AddTriangle( const int nIdVert[3]) return SVT_DEL ; // imposto ricalcolo m_nStatus = TO_VERIFY ; + m_nParts = - 1 ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; // inserisco il triangolo @@ -230,6 +234,8 @@ SurfTriMesh::RemoveTriangle( int nId) m_vTria[nId].nIdVert[0] = SVT_DEL ; // invalido calcolo facce m_bFaceted = false ; + // invalido calcolo connettività + m_nParts = - 1 ; return true ; } @@ -926,6 +932,7 @@ SurfTriMesh::CopyFrom( const SurfTriMesh& stmSrc) m_nTempProp = stmSrc.m_nTempProp ; m_bFaceted = stmSrc.m_bFaceted ; m_vFacet = stmSrc.m_vFacet ; + m_nParts = stmSrc.m_nParts ; return true ; } @@ -958,9 +965,13 @@ SurfTriMesh::Dump( string& sOut, bool bMM, const char* szNewLine) const GetVolume( dVolume) ; sOut += "Closed Volume=" + ToString( GetVolumeInUiUnits( dVolume, bMM), 1) + szNewLine ; } - // se segnalo eventuale incongruenza di orientamento + // segnalo eventuale incongruenza di orientamento if ( ! m_bOriented) sOut += string( "Inconsistent Orientation") + szNewLine ; + // segnalo numero di parti se più di una + int nParts = GetPartCount() ; + if ( nParts > 1) + sOut += string( "Parts =") + ToString( nParts) + szNewLine ; // numero di vertici sOut += "Vert : Nbr=" + ToString( GetVertexCount()) + " Size=" + ToString( GetVertexSize()) + szNewLine ; @@ -1046,8 +1057,9 @@ SurfTriMesh::Save( NgeWriter& ngeOut) const bool SurfTriMesh::Load( NgeReader& ngeIn) { - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica, della connessione e di hashgrids3d m_OGrMgr.Reset() ; + m_nParts = -1 ; ResetHashGrids3d() ; // leggo la prossima linea ( 2 parametri : dLinTol e dSmoothAng) // tolleranza lineare di costruzione @@ -1063,7 +1075,6 @@ SurfTriMesh::Load( NgeReader& ngeIn) m_dCosSmAng = cos( dSmoothAng * DEGTORAD) ; // leggo la prossima linea // prima di versione 1010 3 parametri : flag di chiusa, num vertici, num tria - // da versione 1010 leggo flag di orientata bool bOriented ; bool bClosed ; int nNumVert ; @@ -1193,6 +1204,9 @@ SurfTriMesh::Validate( bool bCorrect) m_bFaceted = false ; } + // invalido calcolo connessione + m_nParts = - 1 ; + return ( m_nStatus == OK) ; } @@ -1446,6 +1460,8 @@ SurfTriMesh::AdjustTopology( void) { // dichiaro sfaccettatura da ricalcolare ResetFaceting() ; + // invalido calcolo connessione + m_nParts = - 1 ; // verifica indici if ( ! Validate( true)) return false ; @@ -3085,9 +3101,8 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) } // se necessario, aggiorno tutto - if ( bModif) { + if ( bModif) return AdjustVertices() && DoCompacting() ; - } return true ; } @@ -3152,3 +3167,133 @@ SurfTriMesh::GetAllTriaBox( void) const VerifyHashGrids3d() ; return m_b3HGrd3d ; } + +//---------------------------------------------------------------------------- +int +SurfTriMesh::GetPartCount( void) const +{ + if ( ! IsValid()) + return 0 ; + if ( m_nParts == - 1 && ! VerifyConnection()) + return 0 ; + return m_nParts ; +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::VerifyConnection( void) const +{ + if ( ! IsValid()) + return false ; + + // reset connessione + for ( auto Tria : m_vTria) + Tria.nPart = SVT_NULL ; + + // ciclo sui triangoli + m_nParts = 0 ; + for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) { + // salto triangoli cancellati o già assegnati + if ( m_vTria[i].nIdVert[0] == SVT_DEL || + m_vTria[i].nPart != SVT_NULL) + continue ; + // assegno indice di parte connessa al triangolo + m_vTria[i].nPart = m_nParts ; + ++ m_nParts ; + // set di triangoli da aggiornare + set stTria ; + stTria.insert( i) ; + while ( ! stTria.empty()) { + // tolgo un triangolo dal set + const auto iIt = stTria.begin() ; + int nT = *iIt ; + stTria.erase( iIt) ; + // aggiorno i triangoli adiacenti + for ( int j = 0 ; j < 3 ; ++ j) { + int nAdjT = m_vTria[nT].nIdAdjac[j] ; + if ( nAdjT != SVT_NULL && m_vTria[nAdjT].nPart == SVT_NULL) { + m_vTria[nAdjT].nPart = m_vTria[nT].nPart ; + stTria.insert( nAdjT) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::RemovePart( int nPart) +{ + if ( ! IsValid()) + return false ; + + // Il numero delle componenti deve essere maggiore di zero o calcolabile + if ( m_nParts == -1 && ! VerifyConnection()) + return false ; + + // Se la componente non esiste, errore + if ( m_nParts <= 0 || nPart < 0 || nPart >= m_nParts) + return false ; + + int nPartsOld = m_nParts ; + // Rimuovo i triangoli della componente nPart + for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) { + if ( m_vTria[i].nPart == nPart) + RemoveTriangle( i) ; + } + + // Aggiorno il numero di componenti + m_nParts = nPartsOld - 1 ; + + // imposto ricalcolo della grafica e di hashgrids3d + m_OGrMgr.Reset() ; + ResetHashGrids3d() ; + + return true ; +} + +//---------------------------------------------------------------------------- +SurfTriMesh* +SurfTriMesh::ClonePart( int nPart) const +{ + if ( ! IsValid()) + return nullptr ; + + // Il numero delle componenti deve essere maggiore di zero o calcolabile + if ( m_nParts == -1 && ! VerifyConnection()) + return nullptr ; + + // Se la componente non esiste, errore + if ( m_nParts <= 0 || nPart < 0 || nPart >= m_nParts) + return nullptr ; + + // Creo nuovo oggetto SurfTriMesh + PtrOwner pSurfTM( new( nothrow) SurfTriMesh) ; + if ( IsNull( pSurfTM)) + return nullptr ; + + // Copio il valore dei membri + pSurfTM->m_dLinTol = m_dLinTol ; + pSurfTM->m_dBoundaryAng = m_dBoundaryAng ; + pSurfTM->m_dCosBndAng = m_dCosBndAng ; + pSurfTM->m_dSmoothAng = m_dSmoothAng ; + pSurfTM->m_dCosSmAng = m_dCosSmAng ; + pSurfTM->m_nParts = 1 ; + + // Copio i triangoli + for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) { + if ( m_vTria[i].nIdVert[0] != SVT_DEL && m_vTria[i].nPart == nPart) { + int nNewInd[3] = { pSurfTM->AddVertex( m_vVert[m_vTria[i].nIdVert[0]].ptP), + pSurfTM->AddVertex( m_vVert[m_vTria[i].nIdVert[1]].ptP), + pSurfTM->AddVertex( m_vVert[m_vTria[i].nIdVert[2]].ptP)} ; + pSurfTM->AddTriangle( nNewInd) ; + } + } + + // Aggiusto la superficie + pSurfTM->DoCompacting() ; + + // Restituisco la nuova superficie + return Release( pSurfTM) ; +} diff --git a/SurfTriMesh.h b/SurfTriMesh.h index bbbf647..97b13f0 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -18,7 +18,6 @@ #include "GeoObjRW.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkHashGrids3d.h" -#include #include //---------------------------------------------------------------------------- @@ -41,14 +40,14 @@ class StmVert class StmTria { public : - StmTria( void) : vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nTemp( 0) + StmTria( void) : vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nPart( SVT_NULL), nTemp( 0) { nIdVert[0] = SVT_NULL ; nIdVert[1] = SVT_NULL ; nIdVert[2] = SVT_NULL ; nIdAdjac[0] = SVT_NULL ; nIdAdjac[1] = SVT_NULL ; nIdAdjac[2] = SVT_NULL ; } - StmTria( const int nIdV[3]) : vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nTemp( 0) + StmTria( const int nIdV[3]) : vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nPart( SVT_NULL), nTemp( 0) { nIdVert[0] = nIdV[0] ; nIdVert[1] = nIdV[1] ; nIdVert[2] = nIdV[2] ; nIdAdjac[0] = SVT_NULL ; nIdAdjac[1] = SVT_NULL ; nIdAdjac[2] = SVT_NULL ; } StmTria( const int nIdV[3], const int nIdA[3], const Vector3d& vtV, int nTF, int nEF) - : vtN( vtV), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( nEF), nTemp( 0) + : vtN( vtV), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( nEF), nPart( SVT_NULL), nTemp( 0) { nIdVert[0] = nIdV[0] ; nIdVert[1] = nIdV[1] ; nIdVert[2] = nIdV[2] ; nIdAdjac[0] = nIdA[0] ; nIdAdjac[1] = nIdA[1] ; nIdAdjac[2] = nIdA[2] ; } public : @@ -58,6 +57,7 @@ class StmTria int nIdFacet ; int nTFlag ; int nEFlag ; + mutable int nPart ; mutable int nTemp ; } ; @@ -184,6 +184,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ; bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ; const BBox3d& GetAllTriaBox( void) const override ; + int GetPartCount( void) const override ; + bool RemovePart( int nPart) override ; + SurfTriMesh* ClonePart( int nPart) const override ; public : // IGeoObjRW int GetNgeId( void) const override ; @@ -245,6 +248,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ; void ResetHashGrids3d( void) const ; bool VerifyHashGrids3d( void) const ; + bool VerifyConnection( void) const ; private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto @@ -262,6 +266,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW INTVECTOR m_vFacet ; // vettore delle sfaccettature mutable int m_nTimeStamp ; // orologio locale int m_nTempProp ; // proprietà temporanea + mutable int m_nParts ; // numero di parti connesse (-1 se da calcolare) mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d } ; diff --git a/SurfTriMeshFaceting.cpp b/SurfTriMeshFaceting.cpp index ea67f31..b6040e2 100644 --- a/SurfTriMeshFaceting.cpp +++ b/SurfTriMeshFaceting.cpp @@ -53,36 +53,36 @@ SurfTriMesh::UpdateFaceting( void) bool bOk = true ; int nFacet = -1 ; for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) { - if ( m_vTria[i].nIdVert[0] != SVT_DEL && - m_vTria[i].nIdFacet == SVT_NULL) { - // assegno indice di faccia al triangolo - m_vTria[i].nIdFacet = ++ nFacet ; - m_vFacet.push_back( i) ; - // piano del triangolo - Plane3d plPlane ; - if ( ! plPlane.Set( m_vVert[m_vTria[i].nIdVert[0]].ptP, m_vTria[i].vtN)) { - LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data") - return false ; - } - // set di triangoli da aggiornare - set stTria ; - stTria.insert( i) ; - // finchè set non vuoto - while ( ! stTria.empty()) { - // tolgo un triangolo dal set - const auto iIt = stTria.begin() ; - int nT = *iIt ; - stTria.erase( iIt) ; - // aggiorno i triangoli adiacenti - for ( int j = 0 ; j < 3 ; ++ j) { - int nAdjT = m_vTria[nT].nIdAdjac[j] ; - if ( nAdjT != SVT_NULL && - m_vTria[nAdjT].nIdFacet == SVT_NULL) { - if ( ! UpdateTriaFaceting( nT, nFacet, plPlane, nAdjT)) - bOk = false ; - if ( m_vTria[nAdjT].nIdFacet == nFacet) - stTria.insert( nAdjT) ; - } + // salto triangoli cancellati o già assegnati + if ( m_vTria[i].nIdVert[0] == SVT_DEL || + m_vTria[i].nIdFacet != SVT_NULL) + continue ; + // assegno indice di faccia al triangolo + m_vTria[i].nIdFacet = ++ nFacet ; + m_vFacet.push_back( i) ; + // piano del triangolo + Plane3d plPlane ; + if ( ! plPlane.Set( m_vVert[m_vTria[i].nIdVert[0]].ptP, m_vTria[i].vtN)) { + LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data") + return false ; + } + // set di triangoli da aggiornare + set stTria ; + stTria.insert( i) ; + // finchè set non vuoto + while ( ! stTria.empty()) { + // tolgo un triangolo dal set + const auto iIt = stTria.begin() ; + int nT = *iIt ; + stTria.erase( iIt) ; + // aggiorno i triangoli adiacenti + for ( int j = 0 ; j < 3 ; ++ j) { + int nAdjT = m_vTria[nT].nIdAdjac[j] ; + if ( nAdjT != SVT_NULL && m_vTria[nAdjT].nIdFacet == SVT_NULL) { + if ( ! UpdateTriaFaceting( nT, nFacet, plPlane, nAdjT)) + bOk = false ; + if ( m_vTria[nAdjT].nIdFacet == nFacet) + stTria.insert( nAdjT) ; } } }