EgtGeomKernel 2.1c2 :
- migliorata assegnazione normali ai triangoli feature.
This commit is contained in:
+244
-204
@@ -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 ;
|
||||
|
||||
Reference in New Issue
Block a user