diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index e3a99f0..1e45dc8 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -26,6 +26,7 @@ #include "/EgtDev/Include/EGkDistLineLine.h" #include "/EgtDev/Include/EGkIntersLinePlane.h" #include "/EgtDev/Include/EGkPointGrid3d.h" +#include "/EgtDev/Include/EGkPolygon3d.h" #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" @@ -1177,6 +1178,78 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& return true ; } +//---------------------------------------------------------------------------- +bool +SurfTriMesh::GetSilhouette( const Plane3d& plPlane, double dTol, POLYLINEVECTOR& vPL, bool bAllTria) const +{ + // Verifico lo stato + if ( m_nStatus != OK) + return false ; + + // Verifico la direzione + Vector3d vtVers = plPlane.GetVersN() ; + if ( ! vtVers.Normalize()) + return false ; + + // Controlli su tolleranza + dTol = max( dTol, 100 * EPS_SMALL) ; + + // Determino il riferimento di proiezione + Frame3d frOCS ; frOCS.Set( plPlane.GetPoint(), vtVers) ; + + // Ottengo la Silhouette come unione delle regioni dei triangoli proiettati (solo parti sopra il piano) + // calcolo la regione dei triangoli proiettati + PtrOwner pSfr ; + Triangle3d Tria ; + int nT = GetFirstTriangle( Tria) ; + while ( nT != SVT_NULL) { + // verifico la normale + if ( ( bAllTria && abs( Tria.GetN() * vtVers) > EPS_ZERO) || + ( ! bAllTria && Tria.GetN() * vtVers > EPS_ZERO)) { + // ricavo il poligono equivalente al triangolo + Polygon3d pgTria ; + pgTria.FromTriangle( Tria) ; + // taglio il poligono con il piano + pgTria.Trim( plPlane, false, true, bAllTria) ; + // se rimasto qualcosa + if ( pgTria.GetSideCount() > 0) { + // lo proietto sul piano e creo la regione + pgTria.Scale( frOCS, 1, 1, 0) ; + PtrOwner pSfrTria( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLine( pgTria.GetPolyLine()))) ; + if ( ! IsNull( pSfrTria)) { + if ( bAllTria && Tria.GetN() * vtVers < 0) + pSfrTria->Invert() ; + pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ; + if ( IsNull( pSfr)) + pSfr.Set( pSfrTria) ; + else + pSfr->Add( *pSfrTria) ; + } + } + } + // passo al successivo + nT = GetNextTriangle( nT, Tria) ; + } + + // Se non esiste la regione + if ( IsNull( pSfr)) + return false ; + + // Effettuo contro-offset + pSfr->Offset( -dTol, ICurve::OFF_EXTEND) ; + + // Recupero i contorni della regione + for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) { + for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) { + PolyLine PL ; + if ( pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + vPL.emplace_back( PL) ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- SurfTriMesh* SurfTriMesh::Clone( void) const diff --git a/SurfTriMesh.h b/SurfTriMesh.h index fe80811..c7eb88f 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -279,6 +279,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW SurfTriMesh* CloneTriangle( int nT) const override ; bool GetLoops( POLYLINEVECTOR& vPL) const override ; bool GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ; + bool GetSilhouette( const Plane3d& plPlane, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ; int GetFacetCount( void) const override ; int GetFacetSize( void) const override { return int( m_vFacet.size()) ; }