EgtGeomKernel 2.3i2 :

- modificata completamente SurfTriMesh::GetSilhouette ora richiede un parametro per la tolleranza nel calcolo (diminuita sensibilità a problemi topologici)
- aggiunta funzione GetSurfFlatRegionFromTriangle.
This commit is contained in:
DarioS
2021-09-26 16:27:31 +02:00
parent e7d0b00e0f
commit 4731df3702
4 changed files with 85 additions and 11 deletions
+54 -1
View File
@@ -991,7 +991,7 @@ SurfTriMesh::MarchOneTria( int& nT, int& nV, int nTimeStamp,
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const
SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL) const
{
// Verifico lo stato
if ( m_nStatus != OK)
@@ -1002,6 +1002,57 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const
if ( ! vtVers.Normalize())
return false ;
// Controlli su tolleranza
dTol = max( dTol, 100 * EPS_SMALL) ;
// Determino il riferimento di proiezione
Frame3d frOCS ; frOCS.Set( ORIG, vtVers) ;
Frame3d frBox = frOCS ; frBox.Invert() ;
BBox3d b3Box ;
GetBBox( frBox, b3Box) ;
frOCS.Translate( b3Box.GetMin().z * frOCS.VersZ()) ;
// calcolo la regione dei triangoli proiettati
PtrOwner<ISurfFlatRegion> pSfr ;
Triangle3d Tria ;
int nT = GetFirstTriangle( Tria) ;
while ( nT != SVT_NULL) {
// verifico la normale e il triangolo proiettato
if ( Tria.GetN() * vtVers > EPS_ZERO &&
Tria.Scale( frOCS, 1, 1, 0) && Tria.GetSqMinHeight() > SQ_EPS_SMALL) {
PtrOwner<ISurfFlatRegion> pSfrTria( GetSurfFlatRegionFromTriangle( Tria)) ;
if ( ! IsNull( pSfrTria)) {
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
if ( IsNull( pSfr))
pSfr.Set( Release( 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 ;
#if 0
// Copio la superficie
PtrOwner<SurfTriMesh> pStm( Clone()) ;
if ( IsNull( pStm))
@@ -1021,6 +1072,8 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const
// Recupero i loop della nuova superficie
return pStm->GetLoops( vPL) ;
#endif
}
//----------------------------------------------------------------------------