EgtGeomKernel 2.1c2 :

- migliorata assegnazione normali ai triangoli feature.
This commit is contained in:
Dario Sassi
2019-03-07 12:29:12 +00:00
parent 39809116d3
commit 8fddd69c4a
3 changed files with 247 additions and 208 deletions
+244 -204
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2018
// EgalTech 2015-2019
//----------------------------------------------------------------------------
// File : VolZmap.cpp Data : 22.05.18 Versione : 1.9e4
// File : VolZmap.cpp Data : 07.03.19 Versione : 2.1c2
// Contenuto : Implementazione della classe Volume Zmap (tre griglie)
//
//
@@ -2780,12 +2780,10 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c
CurrTri.SetGrade( 0) ;
// Setto le normali a ogni vertice
CurrTri.SetVertexNorm( 1, it->second.Compo[nComp].CompVecField[nNextVert].vtVec) ;
CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ;
if ( CurrTri.GetVertexNorm( 1) * CurrTri.GetVertexNorm( 2) > 0.5)
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) +
CurrTri.GetVertexNorm( 2))) ;
CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ;
// Valido il triangolo
CurrTri.Validate( true) ;
if ( ! CurrTri.Validate( true))
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) + CurrTri.GetVertexNorm( 2))) ;
m_BlockSharpTria[nBlock][tOldSize].vCompoTria[tOldCompNum].emplace_back( CurrTri) ;
m_BlockSharpTria[nBlock][tOldSize].vCompoTria[tOldCompNum].back().ToGlob( m_MapFrame) ;
int nTri = int( m_BlockSharpTria[nBlock][tOldSize].vbFlipped[tOldCompNum].size()) ;
@@ -2844,11 +2842,9 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c
// Setto le normali a ogni vertice
CurrTri.SetVertexNorm( 1, itVox->second.Compo[nComp].CompVecField[nNextVert].vtVec) ;
CurrTri.SetVertexNorm( 2, itVox->second.Compo[nComp].CompVecField[nVert].vtVec) ;
if ( CurrTri.GetVertexNorm( 1) * CurrTri.GetVertexNorm( 2) > 0.5)
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) +
CurrTri.GetVertexNorm( 2))) ;
// Valido il triangolo
CurrTri.Validate( true) ;
if ( ! CurrTri.Validate(true))
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) + CurrTri.GetVertexNorm( 2)));
// Smisto i triangoli fra di frontiera e interni
bool bTriOnBorder = IsTriangleOnBorder( CurrTri, nLimits, nVoxIJK) ;
// Triangolo di frontiera
@@ -2894,64 +2890,6 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateSharpFeatureTriangle( const VoxelContainer& vVoxel, SharpTriHolder& triHold) const
{
// Ciclo sui voxel interni
for ( auto it = vVoxel.begin() ; it != vVoxel.end() ; ++ it) {
int tOldSize = int( triHold.size()) ;
triHold.resize( tOldSize + 1) ;
triHold[tOldSize].i = it->second.i ;
triHold[tOldSize].j = it->second.j ;
triHold[tOldSize].k = it->second.k ;
// Ciclo sulle componenti connesse del voxel
for ( int nComp = 0 ; nComp < it->second.nNumComp ; ++ nComp) {
triHold[tOldSize].ptCompoVert.emplace_back( it->second.Compo[nComp].ptVert) ;
int tOldCompNum = int( triHold[tOldSize].vCompoTria.size()) ;
triHold[tOldSize].vCompoTria.resize( tOldCompNum + 1) ;
triHold[tOldSize].vbFlipped.resize( tOldCompNum + 1) ;
// ciclo sui vertici della componente connessa
int nNumVert = it->second.Compo[nComp].nVertNum ;
for ( int nVert = 0 ; nVert < nNumVert ; ++ nVert) {
int nNextVert = ( nVert + 1 < nNumVert ? nVert + 1 : 0) ;
// Definisco il triangolo
Triangle3dEx CurrTri ;
CurrTri.Set( it->second.Compo[nComp].ptVert,
it->second.Compo[nComp].CompVecField[nNextVert].ptPApp,
it->second.Compo[nComp].CompVecField[nVert].ptPApp) ;
// Setto il numero di utensile ai vertici di base del fan
CurrTri.SetAttrib( 1, it->second.Compo[nComp].CompVecField[nNextVert].nPropIndex) ;
CurrTri.SetAttrib( 2, it->second.Compo[nComp].CompVecField[nVert].nPropIndex) ;
// Setto il numero di utensile al triangolo nel complesso
if ( CurrTri.GetAttrib( 1) < 0 ||
CurrTri.GetAttrib( 2) < 0)
CurrTri.SetGrade( - 1) ;
else if ( CurrTri.GetAttrib( 1) > 0 ||
CurrTri.GetAttrib( 2) > 0)
CurrTri.SetGrade( 1) ;
else
CurrTri.SetGrade( 0) ;
// Setto le normali a ogni vertice
CurrTri.SetVertexNorm( 1, it->second.Compo[nComp].CompVecField[nNextVert].vtVec) ;
CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ;
if ( CurrTri.GetVertexNorm( 1) * CurrTri.GetVertexNorm( 2) > 0.5)
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) +
CurrTri.GetVertexNorm( 2))) ;
// Valido il triangolo
CurrTri.Validate( true) ;
triHold[tOldSize].vCompoTria[tOldCompNum].emplace_back( CurrTri) ;
//triHold[tOldSize].vCompoTria[tOldCompNum].back().ToGlob( m_MapFrame) ;
int nTri = int( triHold[tOldSize].vbFlipped[tOldCompNum].size()) ;
triHold[tOldSize].vbFlipped[tOldCompNum].resize( nTri + 1) ;
triHold[tOldSize].vbFlipped[tOldCompNum][nTri] = false ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateSmoothTriangle( int nIndex, int nVertNum, AppliedVector TriVert[], bool bWasSharp, SmoothTriaStruct& VoxSmoothTria) const
@@ -3013,149 +2951,250 @@ VolZmap::FlipEdgesII( int nBlock) const
{
// Numero di voxel in cui si presentano sharp feature
int nVoxelNum = int( m_BlockSharpTria[nBlock].size()) ;
// Ciclo sui voxel con sharp feature
for ( int n1 = 0 ; n1 < nVoxelNum ; ++ n1) {
SharpTriaStruct& SharpTria1 = m_BlockSharpTria[nBlock][n1] ;
for ( int n2 = n1 ; n2 < nVoxelNum ; ++ n2) {
// Se i voxel sono adiacenti proseguo
if ( abs( m_BlockSharpTria[nBlock][n2].i - m_BlockSharpTria[nBlock][n1].i) <= 1 ||
abs( m_BlockSharpTria[nBlock][n2].j - m_BlockSharpTria[nBlock][n1].j) <= 1 ||
abs( m_BlockSharpTria[nBlock][n2].k - m_BlockSharpTria[nBlock][n1].k) <= 1 ) {
// Numero delle componenti connesse nei due voxel
int nNumCompo1 = int( m_BlockSharpTria[nBlock][n1].ptCompoVert.size()) ;
int nNumCompo2 = int( m_BlockSharpTria[nBlock][n2].ptCompoVert.size()) ;
// Ciclo sulle componenti
int nCompo1 = 0 ;
for ( ; nCompo1 < nNumCompo1 ; ++ nCompo1) {
int nCompo2 = ( n1 == n2 ? nCompo1 + 1 : 0) ;
for ( ; nCompo2 < nNumCompo2 ; ++ nCompo2) {
// Numero di triangoli per le componenti connesse
int nTriNum1 = int( m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1].size()) ;
int nTriNum2 = int( m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2].size()) ;
for ( int nTri1 = 0 ; nTri1 < nTriNum1 ; ++ nTri1) {
bool bModified = false ;
for ( int nTri2 = 0 ; nTri2 < nTriNum2 ; ++ nTri2) {
// Punti che devono essere in comune fra i due triangoli
Point3d ptP11 = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetP( 1) ;
Point3d ptP12 = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetP( 2) ;
Point3d ptP21 = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetP( 1) ;
Point3d ptP22 = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetP( 2) ;
// I triangoli sono da flippare
if ( AreSamePointEpsilon( ptP11, ptP22, EPS_ZERO) &&
AreSamePointEpsilon( ptP12, ptP21, EPS_ZERO) &&
! ( m_BlockSharpTria[nBlock][n1].vbFlipped[nCompo1][nTri1] ||
m_BlockSharpTria[nBlock][n2].vbFlipped[nCompo2][nTri2])) {
// Assegno l'array dei punti di contorno
Point3d vPnt[4] ;
vPnt[0] = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetP( 1) ;
vPnt[1] = m_BlockSharpTria[nBlock][n1].ptCompoVert[nCompo1] ;
vPnt[2] = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetP( 2) ;
vPnt[3] = m_BlockSharpTria[nBlock][n2].ptCompoVert[nCompo2] ;
// Valuto se i triangoli giacciono su un piano
PolygonPlane Polygon ;
for ( int i = 0 ; i < 4 ; ++ i)
Polygon.AddPoint( vPnt[i]) ;
Plane3d plPlane ;
bool bOnPlane = Polygon.GetPlane( plPlane) ;
for ( int i = 0 ; i < 4 && bOnPlane ; ++ i)
bOnPlane = PointInPlaneApprox( vPnt[i], plPlane) ;
// Se sono su un piano controllo se avviene inversione
bool bInv = false ;
if ( bOnPlane) {
Triangle3d trT1 = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1] ;
Triangle3d trT2 = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2] ;
int nVert1, nVert2 ;
// Determino gli indici dei punti sharp-feature
for ( int nP = 0 ; nP < 3 ; ++ nP) {
if ( nP != 1 && nP != 2)
nVert1 = nP ;
if ( nP != 2 && nP != 1)
nVert2 = nP ;
}
trT1.SetP( 1, trT2.GetP( nVert2)) ;
trT2.SetP( 1, trT1.GetP( nVert1)) ;
trT1.Validate( true) ;
trT2.Validate( true) ;
bInv = ( trT1.GetN() * trT2.GetN() < 0) ;
SharpTriaStruct& SharpTria2 = m_BlockSharpTria[nBlock][n2] ;
// Se non adiacenti o coincidenti vado oltre
if ( abs( SharpTria2.i - SharpTria1.i) > 1 ||
abs( SharpTria2.j - SharpTria1.j) > 1 ||
abs( SharpTria2.k - SharpTria1.k) > 1 )
continue ;
// Ciclo sulle componenti connesse del primo voxel
int nNumCompo1 = int( SharpTria1.ptCompoVert.size()) ;
for ( int nCompo1 = 0 ; nCompo1 < nNumCompo1 ; ++ nCompo1) {
TRIA3DEXVECTOR& vTria1 = SharpTria1.vCompoTria[nCompo1] ;
// Numero di triangoli della componente connessa
int nTriNum1 = int( vTria1.size()) ;
// Ciclo sulle componenti connesse del secondo voxel
int nNumCompo2 = int( SharpTria2.ptCompoVert.size()) ;
int nCompo2 = ( n1 == n2 ? nCompo1 + 1 : 0) ;
for ( ; nCompo2 < nNumCompo2 ; ++ nCompo2) {
TRIA3DEXVECTOR& vTria2 = SharpTria2.vCompoTria[nCompo2] ;
// Numero di triangoli della componente connessa
int nTriNum2 = int( vTria2.size()) ;
for ( int nTri1 = 0 ; nTri1 < nTriNum1 ; ++ nTri1) {
bool bModified = false ;
for ( int nTri2 = 0 ; nTri2 < nTriNum2 ; ++ nTri2) {
// Punti che devono essere in comune fra i due triangoli
const Point3d& ptP11 = vTria1[nTri1].GetP( 1) ;
const Point3d& ptP12 = vTria1[nTri1].GetP( 2) ;
const Point3d& ptP21 = vTria2[nTri2].GetP( 1) ;
const Point3d& ptP22 = vTria2[nTri2].GetP( 2) ;
// I triangoli sono da flippare
if ( AreSamePointEpsilon( ptP11, ptP22, EPS_ZERO) &&
AreSamePointEpsilon( ptP12, ptP21, EPS_ZERO) &&
! ( SharpTria1.vbFlipped[nCompo1][nTri1] ||
SharpTria2.vbFlipped[nCompo2][nTri2])) {
// Assegno l'array dei punti di contorno
Point3d vPnt[4] ;
vPnt[0] = vTria1[nTri1].GetP( 1) ;
vPnt[1] = SharpTria1.ptCompoVert[nCompo1] ;
vPnt[2] = vTria1[nTri1].GetP( 2) ;
vPnt[3] = SharpTria2.ptCompoVert[nCompo2] ;
// Valuto se i triangoli giacciono su un piano
PolygonPlane Polygon ;
for ( int i = 0 ; i < 4 ; ++ i)
Polygon.AddPoint( vPnt[i]) ;
Plane3d plPlane ;
bool bOnPlane = Polygon.GetPlane( plPlane) ;
for ( int i = 0 ; i < 4 && bOnPlane ; ++ i)
bOnPlane = PointInPlaneApprox( vPnt[i], plPlane) ;
// Se sono su un piano controllo se avviene inversione
bool bInv = false ;
if ( bOnPlane) {
Triangle3d trT1 = vTria1[nTri1] ;
Triangle3d trT2 = vTria2[nTri2] ;
int nVert1, nVert2 ;
// Determino gli indici dei punti sharp-feature
for ( int nP = 0 ; nP < 3 ; ++ nP) {
if ( nP != 1 && nP != 2)
nVert1 = nP ;
if ( nP != 2 && nP != 1)
nVert2 = nP ;
}
// Se non vi è inversione eseguo il flipping
if ( ! bInv) {
// Vertice condiviso fra nTri1 e quello del suo fan
int nCol1 = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetAttrib( 2) ;
int nCol2 = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetAttrib( 2) ;
// Modifico i punti e gli indici
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].SetP( 1, m_BlockSharpTria[nBlock][n2].ptCompoVert[nCompo2]) ;
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].SetP( 1, m_BlockSharpTria[nBlock][n1].ptCompoVert[nCompo1]) ;
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol1) ;
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol2) ;
// Setto le normali
Vector3d vtN1 = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( 2) ;
Vector3d vtN2 = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( 2) ;
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( 0, vtN1) ;
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( 1, vtN1) ;
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( 0, vtN2) ;
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( 1, vtN2) ;
// Setto i triangoli come flippati
m_BlockSharpTria[nBlock][n1].vbFlipped[nCompo1][nTri1] = true ;
m_BlockSharpTria[nBlock][n2].vbFlipped[nCompo2][nTri2] = true ;
// Valido i triangoli
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].Validate( true) ;
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].Validate( true) ;
// Avvenuto flipping
bModified = true ;
trT1.SetP( 1, trT2.GetP( nVert2)) ;
trT2.SetP( 1, trT1.GetP( nVert1)) ;
trT1.Validate( true) ;
trT2.Validate( true) ;
bInv = ( trT1.GetN() * trT2.GetN() < 0) ;
}
// Se non vi è inversione eseguo il flipping
if ( ! bInv) {
// Vertice condiviso fra nTri1 e quello del suo fan
int nCol1 = vTria1[nTri1].GetAttrib( 2) ;
int nCol2 = vTria2[nTri2].GetAttrib( 2) ;
// Modifico i punti e gli indici
vTria1[nTri1].SetP( 1, SharpTria2.ptCompoVert[nCompo2]) ;
vTria2[nTri2].SetP( 1, SharpTria1.ptCompoVert[nCompo1]) ;
vTria1[nTri1].SetGrade( nCol1) ;
vTria2[nTri2].SetGrade( nCol2) ;
// Setto le normali
Vector3d vtN1 = vTria1[nTri1].GetVertexNorm( 2) ;
Vector3d vtN2 = vTria2[nTri2].GetVertexNorm( 2) ;
vTria1[nTri1].SetVertexNorm( 0, V_NULL) ;
vTria1[nTri1].SetVertexNorm( 1, V_NULL) ;
vTria2[nTri2].SetVertexNorm( 0, V_NULL) ;
vTria2[nTri2].SetVertexNorm( 1, V_NULL) ;
// Setto i triangoli come flippati
SharpTria1.vbFlipped[nCompo1][nTri1] = true ;
SharpTria2.vbFlipped[nCompo2][nTri2] = true ;
// Avvenuto flipping
bModified = true ;
break ;
}
else {
// In questo caso i due triangoli sono necessariamente su un piano,
// quindi hanno normali concordi. A entrambi assegno il colore del vertice con
// normale più concorde a quella del triangolo
double dDotVec[4] ;
dDotVec[0] = vTria1[nTri1].GetN() * vTria1[nTri1].GetVertexNorm( 1) ;
dDotVec[1] = vTria2[nTri2].GetN() * vTria2[nTri2].GetVertexNorm( 2) ;
dDotVec[2] = vTria1[nTri1].GetN() * vTria1[nTri1].GetVertexNorm( 2) ;
dDotVec[3] = vTria2[nTri2].GetN() * vTria2[nTri2].GetVertexNorm( 1) ;
// Cerco il massimo dei prodotti scalari
int nMaxPos = 0 ;
double dMaxDot = - 1 ;
for ( int nPos = 0 ; nPos < 4 && dMaxDot < 1 ; ++ nPos) {
if ( dDotVec[nPos] > dMaxDot) {
dMaxDot = dDotVec[nPos] ;
nMaxPos = nPos ;
}
}
// Trovo il colore associato al vertice di massimo prodotto scalare
int nCol ;
switch ( nMaxPos) {
case 0 :
nCol = vTria1[nTri1].GetAttrib( 1) ;
break ;
case 1 :
nCol = vTria2[nTri2].GetAttrib( 2) ;
break ;
case 2 :
nCol = vTria1[nTri1].GetAttrib( 2) ;
break ;
case 3 :
nCol = vTria2[nTri2].GetAttrib( 1) ;
break ;
}
else {
// In questo caso i due triangoli sono necessariamente su un piano,
// quindi hanno normali concordi. A entrambi assegno il colore del vertice con
// normale più concorde a quella del triangolo
double dDotVec[4] ;
dDotVec[0] = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetN() *
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( 1) ;
dDotVec[1] = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetN() *
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( 2) ;
dDotVec[2] = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetN() *
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( 2) ;
dDotVec[3] = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetN() *
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( 1) ;
// Cerco il massimo dei prodotti scalari
int nMaxPos = 0 ;
double dMaxDot = - 1 ;
for ( int nPos = 0 ; nPos < 4 && dMaxDot < 1 ; ++ nPos) {
if ( dDotVec[nPos] > dMaxDot) {
dMaxDot = dDotVec[nPos] ;
nMaxPos = nPos ;
}
}
// Trovo il colore associato al vertice di massimo prodotto scalare
int nCol ;
switch ( nMaxPos) {
case 0 :
nCol = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetAttrib( 1) ;
break ;
case 1 :
nCol = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetAttrib( 2) ;
break ;
case 2 :
nCol = m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].GetAttrib( 2) ;
break ;
case 3 :
nCol = m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].GetAttrib( 1) ;
break ;
}
// Assegno il colore ai triangoli
m_BlockSharpTria[nBlock][n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ;
m_BlockSharpTria[nBlock][n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ;
}
// Assegno il colore ai triangoli
vTria1[nTri1].SetGrade( nCol) ;
vTria2[nTri2].SetGrade( nCol) ;
}
}
if ( bModified)
break ;
}
if ( bModified)
break ;
}
}
}
}
}
// Ciclo sui voxel con sharp feature
for ( int nVox = 0 ; nVox < nVoxelNum ; ++nVox) {
SharpTriaStruct& SharpTria = m_BlockSharpTria[nBlock][nVox] ;
// Ciclo sulle componenti connesse del voxel
int nCompNum = int( SharpTria.ptCompoVert.size()) ;
for ( int nComp = 0 ; nComp < nCompNum ; ++ nComp) {
TRIA3DEXVECTOR& vTria = SharpTria.vCompoTria[nComp] ;
// Ciclo sui triangoli della componente connessa
int nTriaNum = int( vTria.size()) ;
for ( int nTria = 0 ; nTria < nTriaNum ; ++ nTria) {
// Lunghezza del segmento opposto al vertice
double dDist = Dist( vTria[nTria].GetP( 1), vTria[nTria].GetP( 2)) ;
// Se è quasi nullo
if ( dDist < 2 * EPS_SMALL && ! SharpTria.vbFlipped[nComp][nTria]) {
// Cerco triangolo adiacente con normale più vicina
int nPrevTria = ( nTria - 1 >= 0 ? nTria - 1 : nTriaNum - 1) ;
int nNextTria = ( nTria + 1 < nTriaNum ? nTria + 1 : 0) ;
double dDotPrev = vTria[nTria].GetN() * vTria[nPrevTria].GetN() ;
double dDotNext = vTria[nTria].GetN() * vTria[nNextTria].GetN() ;
if ( dDotPrev > dDotNext) {
double dAdjDist = Dist( vTria[nPrevTria].GetP( 1), vTria[nPrevTria].GetP( 2)) ;
// Se normale sufficientemente vicina e lato opposto al vertice abbastanza lungo assegno normale al vertice del triangolo corrente
if ( dDotPrev > 0.5 && dAdjDist > 2 * EPS_SMALL)
vTria[nTria].SetVertexNorm( 0, vTria[nPrevTria].GetVertexNorm( 0)) ;
}
else {
double dAdjDist = Dist( vTria[nNextTria].GetP( 1), vTria[nNextTria].GetP( 2)) ;
// Se normale sufficientemente vicina e lato opposto al vertice abbastanza lungo assegno normale al vertice del triangolo corrente
if ( dDotNext > 0.5 && dAdjDist > 2 * EPS_SMALL)
vTria[nTria].SetVertexNorm( 0, vTria[nNextTria].GetVertexNorm( 0)) ;
}
}
}
}
}
// Ciclo sui voxel con sharp feature
for ( int nVox = 0 ; nVox < nVoxelNum ; ++ nVox) {
SharpTriaStruct& SharpTria = m_BlockSharpTria[nBlock][nVox] ;
// Ciclo sulle componenti connesse del voxel
int nCompNum = int( SharpTria.ptCompoVert.size()) ;
for ( int nComp = 0 ; nComp < nCompNum ; ++ nComp) {
TRIA3DEXVECTOR& vTria = SharpTria.vCompoTria[nComp] ;
// Ciclo sui triangoli della componente connessa
int nTriaNum = int( vTria.size()) ;
for ( int nTria = 0 ; nTria < nTriaNum ; ++ nTria) {
// Se il triangolo ha partecipato a un flipping
if ( vTria[nTria].GetVertexNorm( 0).IsSmall() &&
vTria[nTria].GetVertexNorm( 1).IsSmall()) {
const Point3d& ptP0 = vTria[nTria].GetP( 0) ;
const Point3d& ptP1 = vTria[nTria].GetP( 1) ;
const Point3d& ptP2 = vTria[nTria].GetP( 2) ;
int nPrevTria = ( nTria - 1 >= 0 ? nTria - 1 : nTriaNum - 1) ;
const Point3d& ptPrevP0 = vTria[nPrevTria].GetP( 0) ;
const Point3d& ptPrevP1 = vTria[nPrevTria].GetP( 1) ;
if ( AreSamePointApprox( ptP0, ptPrevP0) && AreSamePointApprox( ptP2, ptPrevP1) &&
vTria[nPrevTria].GetVertexNorm( 0).IsNormalized())
vTria[nTria].SetVertexNorm( 0, vTria[nPrevTria].GetVertexNorm( 0)) ;
else {
vTria[nTria].Validate( true) ;
vTria[nTria].SetVertexNorm( 1, V_NULL) ;
}
// Ciclo su voxel adiacenti
bool bFound = false ;
for ( int nAdjVox = 0 ; nAdjVox < nVoxelNum ; ++ nAdjVox) {
SharpTriaStruct& AdjSharpTria = m_BlockSharpTria[nBlock][nAdjVox] ;
// Se coincidenti o non adiacenti vado oltre
if ( nAdjVox == nVox ||
abs( AdjSharpTria.i - SharpTria.i) > 1 ||
abs( AdjSharpTria.j - SharpTria.j) > 1 ||
abs( AdjSharpTria.k - SharpTria.k) > 1)
continue ;
// Ciclo sulle componenti connesse del voxel adiacente
int nAdjCompNum = int( AdjSharpTria.ptCompoVert.size()) ;
for ( int nAdjComp = 0 ; nAdjComp < nAdjCompNum ; ++ nAdjComp) {
TRIA3DEXVECTOR& vAdjTria = AdjSharpTria.vCompoTria[nAdjComp] ;
// Ciclo sui triangoli della componente connessa
int nAdjTriaNum = int( vAdjTria.size()) ;
for ( int nAdjTria = 0 ; nAdjTria < nAdjTriaNum ; ++ nAdjTria) {
const Point3d& ptAdjP0 = vAdjTria[nAdjTria].GetP( 0) ;
const Point3d& ptAdjP2 = vAdjTria[nAdjTria].GetP( 2) ;
if ( AreSamePointApprox( ptP1, ptAdjP0) && AreSamePointApprox( ptP2, ptAdjP2)) {
if ( vAdjTria[nAdjTria].GetVertexNorm( 0).IsNormalized())
vTria[nTria].SetVertexNorm( 1, vAdjTria[nAdjTria].GetVertexNorm( 0)) ;
else
vTria[nTria].Validate( true) ;
bFound = true ;
break ;
}
}
if ( bFound)
break ;
}
if ( bFound)
break ;
}
vTria[nTria].Validate( true) ;
}
}
}
}
return true ;
}
@@ -3409,6 +3448,7 @@ bool
VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector& vfField) const
{
const double dEps = 2 * EPS_SMALL ;
const double dEpsClamp = EPS_SMALL ; // EPS_SMALL ; 0
bool bFound = false ;
@@ -3431,7 +3471,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector&
double dX = m_Values[1][nDexel][n].dMax ;
while ( n >= 0 && dX > dMinX - dEps) {
if ( dX < dMaxX + dEps) {
vfField.ptPApp.x = Clamp( dX, dMinX + EPS_SMALL, dMaxX - EPS_SMALL) ;
vfField.ptPApp.x = Clamp( dX, dMinX + dEpsClamp, dMaxX - dEpsClamp) ;
vfField.vtVec = m_Values[1][nDexel][n].vtMaxN ;
vfField.nPropIndex = m_Values[1][nDexel][n].nToolMax ;
bFound = true ;
@@ -3448,7 +3488,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector&
double dX = m_Values[1][nDexel][n].dMin ;
while ( n < nSize && dX < dMaxX + dEps) {
if ( dX > dMinX - dEps) {
vfField.ptPApp.x = Clamp( dX, dMinX + EPS_SMALL, dMaxX - EPS_SMALL) ;
vfField.ptPApp.x = Clamp( dX, dMinX + dEpsClamp, dMaxX - dEpsClamp) ;
vfField.vtVec = m_Values[1][nDexel][n].vtMinN ;
vfField.nPropIndex = m_Values[1][nDexel][n].nToolMin ;
bFound = true ;
@@ -3483,7 +3523,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector&
double dY = m_Values[2][nDexel][n].dMax ;
while ( n >= 0 && dY > dMinY - dEps) {
if ( dY < dMaxY + dEps) {
vfField.ptPApp.y = Clamp( dY, dMinY + EPS_SMALL, dMaxY - EPS_SMALL) ;
vfField.ptPApp.y = Clamp( dY, dMinY + dEpsClamp, dMaxY - dEpsClamp) ;
vfField.vtVec = m_Values[2][nDexel][n].vtMaxN ;
vfField.nPropIndex = m_Values[2][nDexel][n].nToolMax;
bFound = true ;
@@ -3500,7 +3540,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector&
double dY = m_Values[2][nDexel][n].dMin ;
while ( n < nSize && dY < dMaxY + dEps) {
if ( dY > dMinY - dEps) {
vfField.ptPApp.y = Clamp( dY, dMinY + EPS_SMALL, dMaxY - EPS_SMALL) ;
vfField.ptPApp.y = Clamp( dY, dMinY + dEpsClamp, dMaxY - dEpsClamp) ;
vfField.vtVec = m_Values[2][nDexel][n].vtMinN ;
vfField.nPropIndex = m_Values[2][nDexel][n].nToolMin ;
bFound = true ;
@@ -3535,7 +3575,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector&
double dZ = m_Values[0][nDexel][n].dMax ;
while ( n >= 0 && dZ > dMinZ - dEps) {
if ( dZ < dMaxZ + dEps) {
vfField.ptPApp.z = Clamp( dZ, dMinZ + EPS_SMALL, dMaxZ - EPS_SMALL) ;
vfField.ptPApp.z = Clamp( dZ, dMinZ + dEpsClamp, dMaxZ - dEpsClamp) ;
vfField.vtVec = m_Values[0][nDexel][n].vtMaxN ;
vfField.nPropIndex = m_Values[0][nDexel][n].nToolMax ;
bFound = true ;
@@ -3552,7 +3592,7 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, AppliedVector&
double dZ = m_Values[0][nDexel][n].dMin ;
while ( n < nSize && dZ < dMaxZ + dEps) {
if ( dZ > dMinZ - dEps) {
vfField.ptPApp.z = Clamp( dZ, dMinZ + EPS_SMALL, dMaxZ - EPS_SMALL) ;
vfField.ptPApp.z = Clamp( dZ, dMinZ + dEpsClamp, dMaxZ - dEpsClamp) ;
vfField.vtVec = m_Values[0][nDexel][n].vtMinN ;
vfField.nPropIndex = m_Values[0][nDexel][n].nToolMin ;
bFound = true ;