diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 9669d67..f90dde0 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/HashGrids3d.cpp b/HashGrids3d.cpp index 2c552ae..80c7ace 100644 --- a/HashGrids3d.cpp +++ b/HashGrids3d.cpp @@ -684,7 +684,6 @@ HashGrids3d::Update( void) double dSize = 0 ; Obj.box.GetDiameter( dSize) ; double dCellSpan = pGrid->GetCellSpan() ; - if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) { pGrid->Remove( Obj) ; addGrid( Obj) ; diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 4fa8bab..ffbe5e3 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -1695,8 +1695,10 @@ SurfTriMesh::TestSealing( void) // verifico le adiacenze if ( m_vTria[i].nIdAdjac[0] == SVT_NULL || m_vTria[i].nIdAdjac[1] == SVT_NULL || - m_vTria[i].nIdAdjac[2] == SVT_NULL) + m_vTria[i].nIdAdjac[2] == SVT_NULL) { bClosed = false ; + break ; + } } } // aggiorno la chiusura della superficie @@ -1716,7 +1718,7 @@ SurfTriMesh::AdjustTopology( void) return true ; } // dichiaro sfaccettatura da ricalcolare - ResetFaceting() ; + m_bFaceted = false ; // invalido calcolo connessione m_nParts = - 1 ; // verifica indici @@ -2982,7 +2984,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou } int nVIdSize = int( vVId.size()) ; - // inserisco i triangoli dell'altra trimesh + // aggiungo i triangoli dell'altra trimesh for ( int nOtId = 0 ; nOtId < pOther->GetTriangleSize() ; ++ nOtId) { // recupero gli indici dei vertici del triangolo int vOId[3] ; diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 7853643..cdb651f 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -305,6 +305,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf, INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ; bool CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ; + bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ; bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ; const BBox3d& GetAllTriaBox( void) const override ; int GetPartCount( void) const override ; @@ -370,9 +371,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool MarchOneTria( int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ; bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ; bool AddBiTriangle( const int nIdVert[4]) ; - bool ResetFaceting( void) ; bool VerifyFaceting( void) const ; bool UpdateFaceting( void) ; + bool UpdateOneFace( int nFacet, int nT) ; bool UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) ; bool SetFacet( int nInd, int nT) ; bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ; @@ -411,7 +412,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool RemoveTripleTriangles( void) ; bool ScanForTripleTriangles( bool& bModified) ; bool FlipTriangles( int nTA, int nTB) ; - bool SimplifyFacets( double dMaxEdgeLen, bool bForced = false) ; + bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true) ; bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ; bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ; bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ; diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index bdda833..057ef8a 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -1763,6 +1763,10 @@ SurfTriMesh::FlipTriangles( int nTA, int nTB) bool SurfTriMesh::Add( const ISurfTriMesh& Other) { + // Le superfici devono essere valide + if ( ! IsValid() || ! Other.IsValid()) + return false ; + m_OGrMgr.Clear() ; SurfTriMesh SurfB ; @@ -1806,8 +1810,7 @@ SurfTriMesh::Add( const ISurfTriMesh& Other) Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ; - // cerco di semplificare le facce - if ( ! SimplifyFacets( 5000.0, true)) + if ( ! SimplifyFacets()) LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Add") return bOk ; @@ -1817,6 +1820,10 @@ SurfTriMesh::Add( const ISurfTriMesh& Other) bool SurfTriMesh::Intersect( const ISurfTriMesh& Other) { + // Le superfici devono essere valide + if ( ! IsValid() || ! Other.IsValid()) + return false ; + m_OGrMgr.Clear() ; SurfTriMesh SurfB ; @@ -1860,7 +1867,7 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other) Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ; - if ( ! SimplifyFacets( 5000.0, true)) + if ( ! SimplifyFacets()) LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect") return bOk ; @@ -1870,6 +1877,10 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other) bool SurfTriMesh::Subtract( const ISurfTriMesh& Other) { + // Le superfici devono essere valide + if ( ! IsValid() || ! Other.IsValid()) + return false ; + m_OGrMgr.Clear() ; SurfTriMesh SurfB ; @@ -1914,7 +1925,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other) Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ; - if ( ! SimplifyFacets( 5000.0, true)) + if ( ! SimplifyFacets()) LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect") return bOk ; @@ -1925,7 +1936,7 @@ bool SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf, INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) { - // Le superfici devono essere valide + // Le superfici devono essere valide if ( ! IsValid() || ! ClassifierSurf.IsValid()) return false ; if ( ClassifierSurf.GetVertexCount() == 0 || ClassifierSurf.GetTriangleCount() == 0) @@ -1975,18 +1986,23 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf, bool SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) { - // Le superfici devono essere valide + // Le superfici devono essere valide if ( ! IsValid() || ! CutterSurf.IsValid()) return false ; + m_OGrMgr.Clear() ; + SurfTriMesh SurfC ; SurfC.CopyFrom( &CutterSurf) ; + Frame3d frScalingRef ; frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ; Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ; SurfC.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ; + IntersectTriMeshTriangle( SurfC) ; IdentifyParts() ; + int nPartToRemove = ( bInVsOut ? -1 : 1) ; int nCoplanarPartToRemove = ( bSaveOnEq ? ( nPartToRemove ? -2 : 2) : 5) ; int nTriaNum = GetTriangleSize() ; @@ -1994,11 +2010,45 @@ SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bo if ( m_vTria[nT].nTempPart == nPartToRemove || m_vTria[nT].nTempPart == nCoplanarPartToRemove) RemoveTriangle( nT) ; } + bool bOk = ( AdjustVertices() && DoCompacting()) ; + + bOk = bOk && RemoveTJunctions() ; + bOk = bOk && ( AdjustVertices() && DoCompacting()) ; + Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ; + + if ( ! SimplifyFacets()) + LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::CutWithOtherSurf") + return bOk ; } +//---------------------------------------------------------------------------- +bool +SurfTriMesh::Repair( double dMaxEdgeLen) +{ + // La superficie deve essere valida + if ( ! IsValid()) + return false ; + + // Forzo aggiornamento grafica + m_OGrMgr.Clear() ; + + // Inserisco triangoli per rimuovere giunzioni a T + RemoveTJunctions() ; + + // Sistemo + if ( ! AdjustVertices() || ! DoCompacting()) + return false ; + + // Ritriangolo le facce + if ( ! SimplifyFacets( dMaxEdgeLen, true)) + LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect") + + return true ; +} + //---------------------------------------------------------------------------- int SurfTriMesh::VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane) diff --git a/SurfTriMeshCuts.cpp b/SurfTriMeshCuts.cpp index 124ce0e..c467cdc 100644 --- a/SurfTriMeshCuts.cpp +++ b/SurfTriMeshCuts.cpp @@ -57,7 +57,7 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) // se superficie originale a facce, cerco di semplificarle in ogni caso if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) { - if ( ! SimplifyFacets( 5000.0)) + if ( ! SimplifyFacets()) LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Cut") } @@ -866,7 +866,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) // se superficie originale a facce, cerco di semplificarle in ogni caso if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) { - if ( ! SimplifyFacets( 5000.0)) + if ( ! SimplifyFacets()) LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::GeneralizedCut") } diff --git a/SurfTriMeshFaceting.cpp b/SurfTriMeshFaceting.cpp index 4c48646..e22f0fc 100644 --- a/SurfTriMeshFaceting.cpp +++ b/SurfTriMeshFaceting.cpp @@ -22,15 +22,6 @@ using namespace std ; -//---------------------------------------------------------------------------- -bool -SurfTriMesh::ResetFaceting( void) -{ - m_bFaceted = false ; - m_vFacet.clear() ; - return true ; -} - //---------------------------------------------------------------------------- bool SurfTriMesh::VerifyFaceting( void) const @@ -44,15 +35,36 @@ SurfTriMesh::VerifyFaceting( void) const bool SurfTriMesh::UpdateFaceting( void) { + // salvo vecchio vettore facce + INTVECTOR vOldFacet = m_vFacet ; + // reset faceting m_bFaceted = false ; m_vFacet.clear() ; for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) m_vTria[i].nIdFacet = SVT_NULL ; - // ricostruisco le sfaccettature - bool bOk = true ; + // indice faccia corrente int nFacet = -1 ; + + // ricostruisco le sfaccettature come definite in precedenza (dove possibile) + bool bOk = true ; + for ( int j = 0 ; j < int( vOldFacet.size()) ; ++ j) { + int i = vOldFacet[j] ; + // salto triangoli inesistenti o già assegnati + if ( i >= int( m_vTria.size()) || + 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) ; + // aggiorno faccia + if ( ! UpdateOneFace( nFacet, i)) + bOk = false ; + } + + // ricostruisco le altre sfaccettature for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) { // salto triangoli cancellati o già assegnati if ( m_vTria[i].nIdVert[0] == SVT_DEL || @@ -61,32 +73,9 @@ SurfTriMesh::UpdateFaceting( void) // 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) ; - } - } - } + // aggiorno faccia + if ( ! UpdateOneFace( nFacet, i)) + bOk = false ; } // se ci sono stati problemi, salvo nel log @@ -98,6 +87,40 @@ SurfTriMesh::UpdateFaceting( void) return true ; } +//---------------------------------------------------------------------------- +bool +SurfTriMesh::UpdateOneFace( int nFacet, int nT) +{ + // piano del triangolo + Plane3d plPlane ; + if ( ! plPlane.Set( m_vVert[m_vTria[nT].nIdVert[0]].ptP, m_vTria[nT].vtN)) { + LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data") + return false ; + } + // set di triangoli da aggiornare + set stTria ; + stTria.insert( nT) ; + // finchè set non vuoto + bool bOk = true ; + 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) ; + } + } + } + return bOk ; +} + //---------------------------------------------------------------------------- bool SurfTriMesh::UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) diff --git a/SurfTriMeshUtilities.cpp b/SurfTriMeshUtilities.cpp index 039d5f4..b56af72 100644 --- a/SurfTriMeshUtilities.cpp +++ b/SurfTriMeshUtilities.cpp @@ -168,8 +168,8 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced) // La trimesh deve essere valida if ( ! IsValid()) return false ; - // Se la lunghezza massima del lato del triangolo sul bordo della faccia è nulla, non devo fare alcunché - if ( dMaxEdgeLen < EPS_SMALL) + // Se la lunghezza massima del lato del triangolo sul bordo della faccia è nulla e non forzata, non devo fare alcunché + if ( dMaxEdgeLen < EPS_SMALL && ! bForced) return true ; // Recupero il numero delle facce (esegue anche una verifica delle stesse) @@ -202,7 +202,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced) bToRetriangulate = true ; } - // Se non richiesta ritriangolazione dai bordi, verifico se ci sono vertici di triangoli interni + // Se non richiesta ritriangolazione dai bordi, verifico se ci sono vertici di triangoli interni (*** disabilitato ***) if ( false && ! bToRetriangulate) { // numero dei triangoli nella faccia INTVECTOR vFacetTria ; @@ -214,7 +214,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced) nSideCnt += LoopVec[nL].GetLineNbr() ; // numero dei buchi della faccia int nHoleCnt = int( LoopVec.size()) - 1 ; - // dalla formula di Eulero adattata al caso ( nTriaCnt = nSideCnt + 2 * ( nHoleCnt -1)) + // dalla formula di Eulero adattata al caso ( nTriaCnt = nSideCnt + 2 * ( nHoleCnt - 1)) if ( nTriaCnt != nSideCnt + 2 * ( nHoleCnt - 1)) bToRetriangulate = true ; } @@ -253,6 +253,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced) const PNTVECTOR& vPt = itF->second.first ; const INTVECTOR& vTr = itF->second.second ; // Inserisco i nuovi triangoli + bool bFirstTria = true ; for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewId[3] = { AddVertex( vPt[vTr[n]]), AddVertex( vPt[vTr[n + 1]]), @@ -260,6 +261,13 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced) auto itCol = ColorMap.find( itF->first) ; int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ; int nNewTriaId = AddTriangle( nNewId, nTFlag) ; + if ( nNewTriaId != SVT_NULL && nNewTriaId != SVT_DEL) { + m_vTria[nNewTriaId].nIdFacet = itF->first ; + if ( bFirstTria) { + m_vFacet[itF->first] = nNewTriaId ; + bFirstTria = false ; + } + } } }