From 0b50dc348c879ca60d477a2dfed80ca037044e43 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 14 Mar 2017 12:04:30 +0000 Subject: [PATCH] EgtGeomKernel 1.8c2 : - Validate e DoCompacting di SurfTrimesh eliminano i triangoli degeneri (punto o segmento di retta) - a SurfTrimesh aggiunta Cut (taglio con un piano). --- CurveBezier.cpp | 2 +- CurveComposite.cpp | 2 +- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes PolyArc.cpp | 5 + SfrCreate.cpp | 4 +- StmFromCurves.cpp | 4 +- StmStandard.cpp | 2 +- SurfFlatRegion.cpp | 2 +- SurfTriMesh.cpp | 231 +++++++++++++++++++++++++++++++++++++++++++-- SurfTriMesh.h | 8 +- VolZmap.cpp | 2 +- 11 files changed, 243 insertions(+), 19 deletions(-) diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 78cded3..585ac40 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -347,7 +347,7 @@ CurveBezier::GetType( void) const const string& CurveBezier::GetTitle( void) const { - static const string sTitle = "CBezier" ; + static const string sTitle = "CurveBezier" ; return sTitle ; } diff --git a/CurveComposite.cpp b/CurveComposite.cpp index a956de0..8ab5d9d 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -575,7 +575,7 @@ CurveComposite::GetType( void) const const string& CurveComposite::GetTitle( void) const { - static const string sTitle = "CComposite" ; + static const string sTitle = "CurveCompo" ; return sTitle ; } diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index dd5362538d9c160c5c28c7d54e3c0690aa093e3e..0bf55eb667e39b8abe2a4ed68408bd84bae8745f 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&P_&A-_cnHh~HD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-Vf-5U delta 94 zcmdlNy)SyhFE&QQ&A-_cnHdcyD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-U|t&X diff --git a/PolyArc.cpp b/PolyArc.cpp index 3c0b921..17cee6c 100644 --- a/PolyArc.cpp +++ b/PolyArc.cpp @@ -58,9 +58,14 @@ PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge) { // se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok if ( m_lUPointBs.size() > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) { + // assegno parametro e bulge + m_lUPointBs.back().dU = dPar ; + m_lUPointBs.back().dB = dBulge ; + // incremento contatore rifiutati ed esco ++ m_nRejected ; return true ; } + // aggiungo il punto try { m_lUPointBs.emplace_back( dPar, ptP, dBulge) ; } diff --git a/SfrCreate.cpp b/SfrCreate.cpp index cf9e4f7..b71e176 100644 --- a/SfrCreate.cpp +++ b/SfrCreate.cpp @@ -136,7 +136,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b // fondo le curve allineate pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ; // ne faccio una copia e la inverto - PtrOwner pCompo2( GetCurveComposite( pCompo1->Clone())) ; + PtrOwner pCompo2( pCompo1->Clone()) ; if ( IsNull( pCompo2) || ! pCompo2->Invert()) return nullptr ; // per creare la regione @@ -168,7 +168,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b // fondo le curve allineate pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ; // ne faccio una copia e la inverto - PtrOwner pCompo2( GetCurveComposite( pCompo1->Clone())) ; + PtrOwner pCompo2( pCompo1->Clone()) ; if ( IsNull( pCompo2) || ! pCompo2->Invert()) return nullptr ; // offset della prima curva a destra del raggio diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index dc24414..57c4bd6 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -107,7 +107,7 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL)) return nullptr ; // la copio - PtrOwner pSTM2( GetSurfTriMesh( pSTM1->Clone())) ; + PtrOwner pSTM2( pSTM1->Clone()) ; if ( IsNull( pSTM2)) return nullptr ; // inverto la prima superficie @@ -154,7 +154,7 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d& return nullptr ; // creo la seconda superficie e la unisco alla prima { // copio la prima superficie - PtrOwner pSTM2( GetSurfTriMesh( pSTM->Clone())) ; + PtrOwner pSTM2( pSTM->Clone()) ; if ( IsNull( pSTM2)) return nullptr ; // inverto la prima superficie diff --git a/StmStandard.cpp b/StmStandard.cpp index 5f4d0d0..afa72d7 100644 --- a/StmStandard.cpp +++ b/StmStandard.cpp @@ -47,7 +47,7 @@ GetSurfTriMeshBox( double dDimX, double dDimY, double dHeight) if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL)) return nullptr ; // la copio - PtrOwner pSTM2( GetSurfTriMesh( pSTM1->Clone())) ; + PtrOwner pSTM2( pSTM1->Clone()) ; if ( IsNull( pSTM2)) return nullptr ; // inverto la prima superficie diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index 4c8783e..324c1be 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -375,7 +375,7 @@ SurfFlatRegion::GetType( void) const const string& SurfFlatRegion::GetTitle( void) const { - static const string sTitle = "FlatRegion" ; + static const string sTitle = "SurfFr" ; return sTitle ; } diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 676db0c..9a7d982 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -35,7 +35,8 @@ 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(), m_nTempProp() + m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false), + m_nTimeStamp( 0), m_nTempProp( 0) { m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ; m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ; @@ -925,7 +926,7 @@ SurfTriMesh::GetType( void) const const string& SurfTriMesh::GetTitle( void) const { - static const string sTitle = "TriMesh" ; + static const string sTitle = "SurfTm" ; return sTitle ; } @@ -1146,8 +1147,10 @@ SurfTriMesh::Validate( void) m_nStatus = ERR ; } // calcolo eventuale normale mancante - if ( m_nStatus == OK && m_vTria[i].vtN.IsSmall()) - CalcTriangleNormal( i) ; + if ( m_nStatus == OK && m_vTria[i].vtN.IsSmall()) { + if ( ! CalcTriangleNormal( i)) + RemoveTriangle( i) ; + } } } @@ -2216,6 +2219,11 @@ SurfTriMesh::DoCompacting( void) m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ; m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ; m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ; + // se due vertici coincidono, cancello il triangolo + if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[1] || + m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[2] || + m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2]) + RemoveTriangle( nId) ; } // ricalcolo le adiacenze @@ -2295,9 +2303,11 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther) vId[0] = vVId[vOId[0]] ; vId[1] = vVId[vOId[1]] ; vId[2] = vVId[vOId[2]] ; - // inserisco il triangolo - if ( AddTriangle( vId) == SVT_NULL) - return false ; + // se triangolo ancora valido, lo inserisco + if ( vId[0] != vId[1] && vId[0] != vId[2] && vId[1] != vId[2]) { + if ( AddTriangle( vId) == SVT_NULL) + return false ; + } } // ricalcolo le adiacenze @@ -2673,3 +2683,210 @@ SurfTriMesh::Invert( void) return true ; } + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // classifico i vertici rispetto al piano + for ( int i = 0 ; i < GetVertexSize() ; ++ i) { + double dDist = DistPointPlane( m_vVert[i].ptP, plPlane) ; + if ( abs( dDist) < EPS_SMALL) + m_vVert[i].nTemp = 0 ; + else if ( dDist > 0) + m_vVert[i].nTemp = +1 ; + else + m_vVert[i].nTemp = -1 ; + } + + // aggiorno timestamp dei triangoli + for ( auto& Tria : m_vTria) + Tria.nTemp = m_nTimeStamp ; + ++ m_nTimeStamp ; + + // sistemo i triangoli (eventualmente li elimino) + bool bModif = false ; + for ( int i = 0 ; i < GetTriangleSize() ; ++ i) { + // salto i triangoli cancellati e quelli aggiunti + if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp) + continue ; + // se flag abilita e giace sul piano ed equiverso, lo salvo + if ( bSaveOnEq && + m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 0 && + m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 0 && + m_vVert[ m_vTria[i].nIdVert[2]].nTemp == 0 && + AreSameVectorApprox( m_vTria[i].vtN, plPlane.vtN)) + ; + // se giace sul piano o dalla parte esterna del piano, lo cancello + else if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp != -1 && + m_vVert[ m_vTria[i].nIdVert[1]].nTemp != -1 && + m_vVert[ m_vTria[i].nIdVert[2]].nTemp != -1) { + bModif = true ; + RemoveTriangle( i) ; + } + // se giace dalla parte interna con al massimo un lato sul piano, lo conservo + else if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp != 1 && + m_vVert[ m_vTria[i].nIdVert[1]].nTemp != 1 && + m_vVert[ m_vTria[i].nIdVert[2]].nTemp != 1) + ; + // altrimenti attraversa il piano, devo modificarlo + else { + bModif = true ; + int nDisc = m_vVert[ m_vTria[i].nIdVert[0]].nTemp + + m_vVert[ m_vTria[i].nIdVert[1]].nTemp + + m_vVert[ m_vTria[i].nIdVert[2]].nTemp ; + // se ha un vertice all'interno e uno sul piano -> 1 nuovo vertice e 1 nuovo triangolo + if ( nDisc == 0) { + // classifico i vertici + int nVertOn, nVertIn, nVertOut ; + if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 0) { + nVertOn = 0 ; + nVertIn = 1 ; + nVertOut = 2 ; + if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp > 0) + swap( nVertIn, nVertOut) ; + } + else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 0) { + nVertOn = 1 ; + nVertIn = 2 ; + nVertOut = 0 ; + if ( m_vVert[ m_vTria[i].nIdVert[2]].nTemp > 0) + swap( nVertIn, nVertOut) ; + } + else { + nVertOn = 2 ; + nVertIn = 0 ; + nVertOut = 1 ; + if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp > 0) + swap( nVertIn, nVertOut) ; + } + // calcolo il punto di intersezione del lato che attraversa il piano + double dDistIn = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, plPlane) ; + double dDistOut = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, plPlane) ; + Point3d ptInt = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, + m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, + dDistIn / ( dDistIn + dDistOut)) ; + // inserisco il nuovo vertice + int nNewV = AddVertex( ptInt) ; + // inserisco il nuovo triangolo + int nIdVert[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ; + nIdVert[nVertOut] = nNewV ; + int nIdTria = AddTriangle( nIdVert) ; + if ( ! IsValidSvt( nIdTria)) + return false ; + m_vTria[nIdTria].nTemp = m_nTimeStamp ; + // cancello il vecchio triangolo + RemoveTriangle( i) ; + } + // se ha un vertice all'interno e due all'esterno -> 2 nuovi vertici e 1 nuovo triangolo + else if ( nDisc == 1) { + // classifico i vertici + int nVertIn, nVertOut1, nVertOut2 ; + if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == -1) { + nVertIn = 0 ; + nVertOut1 = 1 ; + nVertOut2 = 2 ; + } + else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == -1) { + nVertIn = 1 ; + nVertOut1 = 2 ; + nVertOut2 = 0 ; + } + else { + nVertIn = 2 ; + nVertOut1 = 0 ; + nVertOut2 = 1 ; + } + // calcolo i punti di intersezione dei lati che attraversano il piano + double dDistIn = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, plPlane) ; + double dDistOut1 = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut1]].ptP, plPlane) ; + double dDistOut2 = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut2]].ptP, plPlane) ; + Point3d ptInt1 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, + m_vVert[m_vTria[i].nIdVert[nVertOut1]].ptP, + dDistIn / ( dDistIn + dDistOut1)) ; + Point3d ptInt2 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, + m_vVert[m_vTria[i].nIdVert[nVertOut2]].ptP, + dDistIn / ( dDistIn + dDistOut2)) ; + // inserisco i nuovi vertici + int nNewV1 = AddVertex( ptInt1) ; + int nNewV2 = AddVertex( ptInt2) ; + // inserisco il nuovo triangolo + int nIdVert[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ; + nIdVert[nVertOut1] = nNewV1 ; + nIdVert[nVertOut2] = nNewV2 ; + int nIdTria = AddTriangle( nIdVert) ; + if ( ! IsValidSvt( nIdTria)) + return false ; + m_vTria[nIdTria].nTemp = m_nTimeStamp ; + // cancello il vecchio triangolo + RemoveTriangle( i) ; + } + // altrimenti ha due vertici allinterno e uno all'esterno -> 2 nuovi vertici e 2 nuovi triangoli + else { + // classifico i vertici + int nVertIn1, nVertIn2, nVertOut ; + if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 1) { + nVertOut = 0 ; + nVertIn1 = 1 ; + nVertIn2 = 2 ; + } + else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 1) { + nVertOut = 1 ; + nVertIn1 = 2 ; + nVertIn2 = 0 ; + } + else { + nVertOut = 2 ; + nVertIn1 = 0 ; + nVertIn2 = 1 ; + } + // calcolo i punti di intersezione dei lati che attraversano il piano + double dDistIn1 = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, plPlane) ; + double dDistIn2 = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, plPlane) ; + double dDistOut = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, plPlane) ; + Point3d ptInt1 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, + m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, + dDistIn1 / ( dDistIn1 + dDistOut)) ; + Point3d ptInt2 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, + m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, + dDistIn2 / ( dDistIn2 + dDistOut)) ; + // inserisco i nuovi vertici + int nNewV1 = AddVertex( ptInt1) ; + int nNewV2 = AddVertex( ptInt2) ; + // inserisco i nuovi triangoli + int nIdVert1[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ; + int nIdVert2[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ; + double dSqDist1 = SqDist( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, ptInt2) ; + double dSqDist2 = SqDist( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, ptInt1) ; + if ( dSqDist1 <= dSqDist2) { + nIdVert1[nVertOut] = nNewV1 ; + nIdVert1[nVertIn2] = nNewV2 ; + nIdVert2[nVertOut] = nNewV2 ; + } + else { + nIdVert1[nVertOut] = nNewV1 ; + nIdVert2[nVertOut] = nNewV2 ; + nIdVert2[nVertIn1] = nNewV1 ; + } + int nIdTria1 = AddTriangle( nIdVert1) ; + int nIdTria2 = AddTriangle( nIdVert2) ; + if ( ! IsValidSvt( nIdTria1) || ! IsValidSvt( nIdTria2)) + return false ; + m_vTria[nIdTria1].nTemp = m_nTimeStamp ; + m_vTria[nIdTria2].nTemp = m_nTimeStamp ; + // cancello il vecchio triangolo + RemoveTriangle( i) ; + } + } + } + + // se necessario, aggiorno tutto + if ( bModif) + return DoCompacting() ; + + return true ; +} diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 000030c..cc90400 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -25,13 +25,14 @@ class StmVert { public : - StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0) {} - StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0) {} - StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF) {} + StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {} + StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {} + StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0) {} public : Point3d ptP ; int nIdTria ; int nFlag ; + mutable int nTemp ; } ; //---------------------------------------------------------------------------- @@ -177,6 +178,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool GetFacetNormal( int nF, Vector3d& vtN) const override ; bool GetFacetArea( int nF, double& dArea) const override ; SurfTriMesh* CloneFacet( int nF) const override ; + bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ; public : // IGeoObjRW int GetNgeId( void) const override ; diff --git a/VolZmap.cpp b/VolZmap.cpp index 5feb9c8..3681e1c 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -142,7 +142,7 @@ VolZmap::GetType( void) const const string& VolZmap::GetTitle( void) const { - static const string sTitle = "Zmap" ; + static const string sTitle = "VolZm" ; return sTitle ; }