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).
This commit is contained in:
+224
-7
@@ -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 ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user