From 8fddd69c4ac903ee8b444ecaf5cf8c697c9962df Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Thu, 7 Mar 2019 12:29:12 +0000 Subject: [PATCH] EgtGeomKernel 2.1c2 : - migliorata assegnazione normali ai triangoli feature. --- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes VolZmap.h | 7 +- VolZmapGraphics.cpp | 448 ++++++++++++++++++++++++-------------------- 3 files changed, 247 insertions(+), 208 deletions(-) diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index c67fb9b6b6eaa2d1d671ac97353a3340f90baee4..9ddec8f51094769764ad9f11f41cb7669eb4859f 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&P_&A-_cnHh~HD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-Vf-5U delta 94 zcmdlNy)SyhFE&QQ&A-_cnHdcyD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-U|t&X diff --git a/VolZmap.h b/VolZmap.h index 5e409e2..ac7ee67 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- // EgalTech 2015-2019 //---------------------------------------------------------------------------- -// File : VolZmap.h Data : 11.02.19 Versione : 2.1b1 +// File : VolZmap.h Data : 07.03.19 Versione : 2.1c2 // Contenuto : Dichiarazione della classe Volume Zmap. // // @@ -65,9 +65,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW const IObjGraphics* GetObjGraphics( void) const override { return m_OGrMgr.GetObjGraphics() ; } void SetTempProp( int nProp) override - { m_nTempProp = nProp ; } + { m_nTempProp = nProp ; } int GetTempProp( void) override - { return m_nTempProp ; } + { return m_nTempProp ; } public : // IVolZmap bool CopyFrom( const IGeoObj* pGObjSrc) override ; @@ -194,7 +194,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const ; bool RegulateFeaturesChain( std::vector& vVecVox) const ; bool CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVox) const ; - bool CreateSharpFeatureTriangle( const VoxelContainer& vVox, SharpTriHolder& triHold) const ; bool CreateSmoothTriangle( int nIndex, int nVertNum, AppliedVector TriVert[], bool bWasSharp, SmoothTriaStruct& VoxSmoothTria) const ; bool FlipEdgesII( int nBlock) const ; bool FlipEdgesBB() const ; diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 85a68f7..fa75e8a 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -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 ;