diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 371ed0b..e229ca9 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/PolyLine.cpp b/PolyLine.cpp index b3ca97f..09047f0 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -1036,7 +1036,7 @@ PolyLine::GetConvexHullXY( PNTVECTOR& vConvHull) const for each ( const auto& Pnt in m_lUPoints) vPnt[k++] = Point3d( Pnt.first.x, Pnt.first.y, 0) ; // ordino secondo le X crescenti - std::sort( vPnt.begin(), vPnt.end(), + sort( vPnt.begin(), vPnt.end(), []( const Point3d& a, const Point3d& b) { return ( a.x < b.x) ; }) ; // elimino eventuali punti coincidenti for ( int i = 0 ; i < nSize ; ++ i) { diff --git a/VolZmap.h b/VolZmap.h index f9d46b0..dc647d7 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -30,8 +30,9 @@ //---------------------------------------------------------------------------- struct TriaStruct { int i, j, k ; - std::vector ptCompoVert ; + PNTVECTOR ptCompoVert ; std::vector vCompoTria ; + std::vector> vbFlipped ; } ; // Vettore di TriaStruct con sharp fature interni a un blocco @@ -176,7 +177,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax) ; bool AddIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax) ; - // SOTTRAZIONI // UTENSILI @@ -322,7 +322,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; static const int N_MAPS = 3 ; static const int N_VOXBLOCK = 32 ; - static const int N_DEXVOXRATIO = 2 ; + static const int N_DEXVOXRATIO = 1 ; private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index f23212c..21f9b5b 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -218,10 +218,10 @@ VolZmap::GetDepth( const Point3d& ptPLoc, const Vector3d& vtDLoc, double& dInLen ptP.ToLoc( m_MapFrame) ; vtD.ToLoc( m_MapFrame) ; - if ( bExact) - return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ; + if ( bExact && m_nMapNum == 3) + return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ; else - return GetDepthWithDexel( ptP, vtD, dInLength, dOutLength) ; + return GetDepthWithDexel( ptP, vtD, dInLength, dOutLength) ; } //---------------------------------------------------------------------------- @@ -272,7 +272,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn swap( ptI.y, ptI.z) ; swap( ptI.x, ptI.z) ; swap( ptF.y, ptF.z) ; - swap( ptF.x, ptF.z) ; + swap( ptF.x, ptF.z) ; } else if ( nGrid == 2) { swap( ptP0.x, ptP0.z) ; @@ -281,21 +281,21 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn swap( vtV0.y, vtV0.z) ; swap( ptI.x, ptI.z) ; swap( ptI.y, ptI.z) ; - swap( ptF.x, ptF.z) ; - swap( ptF.y, ptF.z) ; + swap( ptF.x, ptF.z) ; + swap( ptF.y, ptF.z) ; } - + // Inizializzo distanze dInLen[nGrid] = INFINITO ; dOutLen[nGrid] = - INFINITO ; - + // Determino asse di spostamento maggiore bool bOnX = ( abs( ptF.y - ptI.y) <= abs( ptF.x - ptI.x)) ; - + // Movimento crescente su asse di movimento principale if ( ( bOnX && ptF.x < ptI.x) || ( ! bOnX && ptF.y < ptI.y) ) swap( ptI, ptF) ; - + // Pendenza double dDeltaX = ( ptF.x - ptI.x) ; double dDeltaY = ( ptF.y - ptI.y) ; @@ -304,24 +304,24 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn dM = dDeltaY / dDeltaX ; else if ( ! bOnX && abs( dDeltaY) > EPS_SMALL) dM = dDeltaX / dDeltaY ; - - // Determinazione degli indici i j dei punti ptI e ptF + + // Determinazione degli indici i j dei punti ptI e ptF int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nNx[nGrid] - 1) ; int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy[nGrid] - 1) ; int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx[nGrid] - 1) ; int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy[nGrid] - 1) ; - + // mi muovo int i = nIi ; int j = nIj ; while ( ( bOnX && i <= nFi) || ( ! bOnX && j <= nFj)) { - + // Eseguo controllo double dU1, dU2 ; if ( IntersRayDexel( ptP0, vtV0, nGrid, i, j, dU1, dU2)) { dInLen[nGrid] = min( dInLen[nGrid], dU1) ; dOutLen[nGrid] = max( dOutLen[nGrid], dU2) ; } - + // Calcolo spostamento (a destra o sopra) if ( bOnX) { double dMoveX = ( ( i + 1) * m_dStep - ptI.x) ; @@ -344,11 +344,11 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn ++ j ; } } - + // Se non abbiamo incontrato materiale if ( dInLen[nGrid] > dOutLen[nGrid] - EPS_SMALL) { dInLen[nGrid] = - 2 ; - dOutLen[nGrid] = - 2 ; + dOutLen[nGrid] = - 2 ; } // Se parto dall'interno else if ( dInLen[nGrid] < - EPS_SMALL) @@ -361,7 +361,6 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn return true ; } - if ( abs( dInLen[0] + 2) < EPS_SMALL && abs( dInLen[1] + 2) < EPS_SMALL && abs( dInLen[2] + 2) < EPS_SMALL) { @@ -370,7 +369,6 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn return true ; } else { - dInLength = INFINITO ; dOutLength = - INFINITO ; for ( int nGr = 0 ; nGr < 3 ; ++ nGr) { @@ -380,8 +378,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn dOutLength = dOutLen[nGr] ; } } - - + return true ; } @@ -394,11 +391,10 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn bool VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bEnh) const { - // Parametri di intersezione retta BBox dello Zmap - double dU1, dU2 ; - // Intersezione fra semiretta e BBox dello Zmap + double dU1, dU2 ; bool bLineBBoxInters = IntersLineZMapBBox( ptP, vtD, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ; + // Semiretta esterna al box dello Zmap quindi esterna anche allo Zmap if ( ! bLineBBoxInters) { dInLength = - 2 ; @@ -406,28 +402,24 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn return true ; } - // Indici del voxel corrente - int nVoxI, nVoxJ, nVoxK ; // Determino il voxel di partenza + int nVoxI, nVoxJ, nVoxK ; if ( ! GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) { if ( ! GetPointVoxel( ptP + dU1 * vtD, nVoxI, nVoxJ, nVoxK)) return false ; } - - // Vettore di voxel - vector vVox ; // Incrementi degli indici per sguire la retta int nDeltaI = ( vtD.x > 0 ? 1 : ( vtD.x < 0 ? - 1 : 0)) ; int nDeltaJ = ( vtD.y > 0 ? 1 : ( vtD.y < 0 ? - 1 : 0)) ; int nDeltaK = ( vtD.z > 0 ? 1 : ( vtD.z < 0 ? - 1 : 0)) ; - // Scelgo i piani del voxel con cui intersecare la retta, - // per determinare il voxel successivo + // Scelgo i piani del voxel con cui intersecare la retta, per determinare il voxel successivo int nPlaneI = ( vtD.x >= 0 ? 1 : 0) ; int nPlaneJ = ( vtD.y >= 0 ? 1 : 0) ; int nPlaneK = ( vtD.z >= 0 ? 1 : 0) ; // Ciclo sui voxel + vector vVox ; while ( IsValidVoxel( nVoxI, nVoxJ, nVoxK)) { // Estremi della diagonale del voxel corrente Point3d ptMin( ( nVoxI * N_DEXVOXRATIO + 0.5) * m_dStep, @@ -451,7 +443,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn abs( ( ( ( nVoxJ + nPlaneJ) * N_DEXVOXRATIO + 0.5) * m_dStep - ptP.y) / vtD.y) : INFINITO) ; double dMaxTZ = ( abs( vtD.z) > EPS_ZERO ? abs( ( ( ( nVoxK + nPlaneK) * N_DEXVOXRATIO + 0.5) * m_dStep - ptP.z) / vtD.z) : INFINITO) ; - + // Determino gli incrementi if ( dMaxTX < dMaxTY) { if ( dMaxTX < dMaxTZ) nVoxI += nDeltaI ; @@ -466,76 +458,54 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn } } + // Triangoli di frontiera dei voxel TRIA3DEXLIST lstTria ; ExtMarchingCubes( vVox, lstTria, bEnh) ; - // Struttura studio dell'intersezione + // Dati dell'intersezione struct LineTriaInt { - double dPar ; - double dDot ; + int nNum ; + double dPar1 ; + double dPar2 ; + double dDot ; + LineTriaInt( void) : nNum( 0) {} + LineTriaInt( double dP, double dD) : nNum( 1), dPar1( dP), dDot( dD) {} + LineTriaInt( double dP1, double dP2, double dD) + : nNum( 2), dPar1( dP1), dPar2( dP2), dDot( dD) {} } ; - vector> IntMatrix ; + vector vInt ; - // Ciclo sui triangoli del voxel + // Ciclo sui triangoli dei voxel for ( auto it = lstTria.begin() ; it != lstTria.end() ; ++it ) { - // Triangolo corrente e suoi punti di intersezione con la retta - Triangle3d CurrTria = *it ; + // Triangolo corrente e suoi punti di intersezione con la retta + const Triangle3d& CurrTria = *it ; Point3d ptLineTria1, ptLineTria2 ; - // Studio dell'intersezione della retta con il triangolo corrente + // Studio dell'intersezione della retta con il triangolo corrente int nIntType = IntersLineTria( ptP, vtD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ; - // Se non ci sono intersezioni passo al prossimo triangolo + // Se non ci sono intersezioni passo al prossimo triangolo if ( nIntType == ILTT_NO) continue ; - // se altrimenti c'è una sola intersezione + // se altrimenti c'è una sola intersezione else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) { - LineTriaInt NewInt ; - NewInt.dPar = ( ptLineTria1 - ptP) * vtD ; - NewInt.dDot = vtD * CurrTria.GetN() ; - vector vSing ; - vSing.emplace_back( NewInt) ; - - IntMatrix.emplace_back( vSing) ; + vInt.emplace_back( ( ptLineTria1 - ptP) * vtD, vtD * CurrTria.GetN()) ; } - // altrimenti ci sono due intersezioni + // altrimenti ci sono due intersezioni else { - LineTriaInt NewInt1, NewInt2 ; - vector vCouple ; double dP1 = ( ptLineTria1 - ptP) * vtD ; double dP2 = ( ptLineTria2 - ptP) * vtD ; - NewInt1.dPar = ( dP1 < dP2 ? dP1 : dP2) ; - NewInt2.dPar = ( dP1 < dP2 ? dP2 : dP1) ; - NewInt1.dDot = vtD * CurrTria.GetN() ; - NewInt2.dDot = NewInt1.dDot ; - - vCouple.emplace_back( NewInt1) ; - vCouple.emplace_back( NewInt2) ; - IntMatrix.emplace_back( vCouple) ; + double dD = vtD * CurrTria.GetN() ; + vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ; } } - + // Ordino le intersezioni in base al parametro distanza con segno da ptP - for ( int nN = 0 ; nN < int( IntMatrix.size()) - 1 ; ++ nN) { - for ( int nM = nN + 1 ; nM < int( IntMatrix.size()) ; ++ nM) { - - double dFP = ( IntMatrix[nN].size() == 2 ? 0.5 * ( IntMatrix[nN][0].dPar + IntMatrix[nN][1].dPar) : - IntMatrix[nN][0].dPar) ; - double dLP = ( IntMatrix[nM].size() == 2 ? 0.5 * ( IntMatrix[nM][0].dPar + IntMatrix[nM][1].dPar) : - IntMatrix[nM][0].dPar) ; - - if ( dFP > dLP) - swap( IntMatrix[nN], IntMatrix[nM]) ; - } - } - - vector vInt ; - - for ( int nN = 0 ; nN < int( IntMatrix.size()) ; ++ nN) { - vInt.emplace_back( IntMatrix[nN][0]) ; - if ( IntMatrix[nN].size() == 2) - vInt.emplace_back( IntMatrix[nN][1]) ; - } + sort( vInt.begin(), vInt.end(), + []( const LineTriaInt& a, const LineTriaInt& b) + { double dFP = ( a.nNum == 2 ? 0.5 * ( a.dPar1 + a.dPar2) : a.dPar1) ; + double dLP = ( b.nNum == 2 ? 0.5 * ( b.dPar1 + b.dPar2) : b.dPar1) ; + return ( dLP > dFP) ; }) ; // Inizializzo le distanze di ingresso e uscita: // dInLength diminuisce, dOutLength aumenta. @@ -545,7 +515,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn int nFirstPosN ; int nN = 0 ; for ( ; nN < int( vInt.size()) ; ++ nN) { - if ( /*vInt[nN].dPar >= 0*/vInt[nN].dPar > - EPS_SMALL) { // SCEGLIERE FRA LE DUE OPZIONI + if ( vInt[nN].dPar1 > - EPS_SMALL) { nFirstPosN = nN ; break ; } @@ -562,10 +532,9 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn dInLength = -1 ; } else if ( nFirstPosN == 0) { - - if ( vInt[nFirstPosN].dDot > EPS_ZERO) // + if ( vInt[nFirstPosN].dDot > EPS_ZERO) dInLength = -1 ; - else if ( GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) { + else if ( GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) { int nCubeType = CalcIndex( nVoxI, nVoxJ, nVoxK) ; if ( nCubeType == 255) dInLength = -1 ; @@ -573,14 +542,15 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn } for ( int nN = nFirstPosN ; nN < int( vInt.size()) ; ++ nN) { - - if ( vInt[nN].dDot > - EPS_ZERO && - dOutLength < vInt[nN].dPar) - dOutLength = vInt[nN].dPar ; - + if ( vInt[nN].dDot > - EPS_ZERO) { + if ( vInt[nN].nNum == 2 && dOutLength < vInt[nN].dPar2) + dOutLength = vInt[nN].dPar2 ; + else if ( dOutLength < vInt[nN].dPar1) + dOutLength = vInt[nN].dPar1 ; + } if ( vInt[nN].dDot < EPS_ZERO && - dInLength > vInt[nN].dPar) - dInLength = vInt[nN].dPar ; + dInLength > vInt[nN].dPar1) + dInLength = vInt[nN].dPar1 ; } return true ; @@ -620,23 +590,28 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const // Ciclo di intersezione dei dexel con il BBox for ( int i = nStI ; i <= nEnI ; ++ i) { - for ( int j = nStJ ; j <= nEnJ ; ++ j) { - int nPos = j * m_nNx[0] + i ; int nSize = int( m_Values[0][nPos].size()) ; if ( nSize == 0) continue ; - - Point3d ptC = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ; - - double dZmin, dZmax ; - if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) { - - for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) { - if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL || - dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL)) - return false ; + for ( int k = 0 ; k < 4 ; ++ k) { + Point3d ptC = ptO + i * m_dStep * vtX + j * m_dStep * vtY ; + if ( k == 0) + ptC += 0.1 * m_dStep * vtX + 0.1 * m_dStep * vtY ; + else if ( k == 1) + ptC += 0.9 * m_dStep * vtX + 0.1 * m_dStep * vtY ; + else if ( k == 2) + ptC += 0.9 * m_dStep * vtX + 0.9 * m_dStep * vtY ; + else if ( k == 3) + ptC += 0.1 * m_dStep * vtX + 0.9 * m_dStep * vtY ; + double dZmin, dZmax ; + if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) { + for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) { + if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL || + dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL)) + return false ; + } } } } diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 22c28db..1048726 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -2062,12 +2062,14 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold CurrentTriangle.SetGrade( 1) ; else CurrentTriangle.SetGrade( 0) ; - // Valido il triangolo - CurrentTriangle.Validate( true) ; // Setto le normali a ogni vertice - CurrentTriangle.SetVertexNorm( 0, CurrentTriangle.GetN()) ; CurrentTriangle.SetVertexNorm( 1, CompoVert[nCompCount - 1][nj].vtNorm) ; CurrentTriangle.SetVertexNorm( 2, CompoVert[nCompCount - 1][ni].vtNorm) ; + if ( CurrentTriangle.GetVertexNorm( 1) * CurrentTriangle.GetVertexNorm( 2) > 0) + CurrentTriangle.SetVertexNorm( 0, 0.5 * ( CurrentTriangle.GetVertexNorm( 1) + + CurrentTriangle.GetVertexNorm( 2))) ; + // Valido il triangolo + CurrentTriangle.Validate( true) ; // Aggiungo triangolo al vettore temporaneo triContainer.emplace_back( CurrentTriangle) ; } @@ -2155,6 +2157,12 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold CurrentTriangle.SetAttrib( 2, CompoVert[nCompCount - 1][ni].nToolFlag) ; CurrentTriangle.SetVertexNorm( 1, CompoVert[nCompCount - 1][nj].vtNorm) ; CurrentTriangle.SetVertexNorm( 2, CompoVert[nCompCount - 1][ni].vtNorm) ; + if ( CurrentTriangle.GetVertexNorm( 1) * CurrentTriangle.GetVertexNorm( 2) > 0) + CurrentTriangle.SetVertexNorm( 0, 0.5 * ( CurrentTriangle.GetVertexNorm( 1) + + CurrentTriangle.GetVertexNorm( 2))) ; + // Valido il triangolo + CurrentTriangle.Validate( true) ; + // Assegno i colori if ( CurrentTriangle.GetAttrib( 1) < 0 || CurrentTriangle.GetAttrib( 2) < 0) CurrentTriangle.SetGrade( - 1) ; @@ -2163,7 +2171,6 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold CurrentTriangle.SetGrade( 1) ; else CurrentTriangle.SetGrade( 0) ; - CurrentTriangle.Validate( true) ; // Aggiungo triangolo al vettore temporaneo triContainer.emplace_back( CurrentTriangle) ; } @@ -2232,13 +2239,18 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Costruisco triangoli di prova for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ; - // Il triangolo è pronto + // Il triangolo è pronto Triangle3dEx CurrentTriangle ; CurrentTriangle.Set( ptSol, CompoVert[nCompCount - 1][nj].ptInt, CompoVert[nCompCount - 1][ni].ptInt) ; CurrentTriangle.SetAttrib( 1, CompoVert[nCompCount - 1][nj].nToolFlag) ; CurrentTriangle.SetAttrib( 2, CompoVert[nCompCount - 1][ni].nToolFlag) ; CurrentTriangle.SetVertexNorm( 1, CompoVert[nCompCount - 1][nj].vtNorm) ; CurrentTriangle.SetVertexNorm( 2, CompoVert[nCompCount - 1][ni].vtNorm) ; + if ( CurrentTriangle.GetVertexNorm( 1) * CurrentTriangle.GetVertexNorm( 2) > 0) + CurrentTriangle.SetVertexNorm( 0, 0.5 * ( CurrentTriangle.GetVertexNorm( 1) + + CurrentTriangle.GetVertexNorm( 2))) ; + CurrentTriangle.Validate( true) ; + // Assegno i colori if ( CurrentTriangle.GetAttrib( 1) < 0 || CurrentTriangle.GetAttrib( 2) < 0) CurrentTriangle.SetGrade( - 1) ; @@ -2247,8 +2259,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold CurrentTriangle.SetGrade( 1) ; else CurrentTriangle.SetGrade( 0) ; - CurrentTriangle.Validate( true) ; - // Aggiungo triangolo al vettore temporaneo + // Aggiungo triangolo al vettore temporaneo triContainer.emplace_back( CurrentTriangle) ; } } @@ -2346,11 +2357,16 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Aggiungo una componente per il vettore // dei triangoli della componente connessa. triHold[nCurrent].vCompoTria.resize( nNewFeatureNum) ; + triHold[nCurrent].vbFlipped.resize( nNewFeatureNum) ; for ( int ni = 0 ; ni < int( vInnerTriaTemp.size()) ; ++ ni) { // Riporto le coordinate nel sistema in cui è immerso lo Zmap vInnerTriaTemp[ni].ToGlob( m_MapFrame) ; triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( vInnerTriaTemp[ni]) ; } + triHold[nCurrent].vbFlipped[nOldFeatureNum].resize( vInnerTriaTemp.size()) ; + for ( int ni = 0 ; ni < int( vInnerTriaTemp.size()) ; ++ ni) { + triHold[nCurrent].vbFlipped[nOldFeatureNum][ni] = false ; + } } // Triangoli di frontiera @@ -2585,182 +2601,134 @@ VolZmap::FlipEdgesII( TriHolder& TriHold) const { // Numero di voxel in cui si presentano sharp feature int nVoxelNum = int( TriHold.size()) ; - // Ciclo sui voxel con sharp feature for ( int n1 = 0 ; n1 < nVoxelNum ; ++ n1) { for ( int n2 = n1 ; n2 < nVoxelNum ; ++ n2) { - // Se i voxel sono adiacenti proseguo if ( abs( TriHold[n2].i - TriHold[n1].i) <= 1 || abs( TriHold[n2].j - TriHold[n1].j) <= 1 || abs( TriHold[n2].k - TriHold[n1].k) <= 1 ) { - // Numero delle componenti connesse nei due voxel int nNumCompo1 = int( TriHold[n1].ptCompoVert.size()) ; int nNumCompo2 = int( TriHold[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( TriHold[n1].vCompoTria[nCompo1].size()) ; int nTriNum2 = int( TriHold[n2].vCompoTria[nCompo2].size()) ; - for ( int nTri1 = 0 ; nTri1 < nTriNum1 ; ++ nTri1) { - bool bModified = false ; - for ( int nTri2 = 0 ; nTri2 < nTriNum2 ; ++ nTri2) { - - INTVECTOR SharedIndex ; - - for ( int nVert1 = 0 ; nVert1 < 3 ; ++ nVert1) { - - for ( int nVert2 = 0 ; nVert2 < 3 ; ++ nVert2) { - - Point3d ptP1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( nVert1) ; - Point3d ptP2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetP( nVert2) ; - - if ( AreSamePointEpsilon( ptP1, ptP2, EPS_ZERO)) { - - Point3d ptVert1 = TriHold[n1].ptCompoVert[nCompo1] ; - Point3d ptVert2 = TriHold[n2].ptCompoVert[nCompo2] ; - - if ( ! ( AreSamePointEpsilon( ptP1, ptVert1, EPS_ZERO) || - AreSamePointEpsilon( ptP2, ptVert2, EPS_ZERO))) { - SharedIndex.emplace_back( nVert1) ; - SharedIndex.emplace_back( nVert2) ; - } + // Punti che devono essere in comune fra i due triangoli + Point3d ptP11 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 1) ; + Point3d ptP12 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 2) ; + Point3d ptP21 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetP( 1) ; + Point3d ptP22 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetP( 2) ; + // I triangoli sono da flippare + if ( AreSamePointEpsilon( ptP11, ptP22, EPS_ZERO) && + AreSamePointEpsilon( ptP12, ptP21, EPS_ZERO)) { + // Assegno l'array dei punti di contorno + Point3d vPnt[4] ; + vPnt[0] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 1) ; + vPnt[1] = TriHold[n1].ptCompoVert[nCompo1] ; + vPnt[2] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 2) ; + vPnt[3] = TriHold[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 = TriHold[n1].vCompoTria[nCompo1][nTri1] ; + Triangle3d trT2 = TriHold[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 ; } - if ( SharedIndex.size() > 2) - break ; + trT1.SetP( 1, trT2.GetP( nVert2)) ; + trT2.SetP( 1, trT1.GetP( nVert1)) ; + trT1.Validate( true) ; + trT2.Validate( true) ; + bInv = ( trT1.GetN() * trT2.GetN() < 0) ; } - if ( SharedIndex.size() > 2) + // Se non vi è inversione eseguo il flipping + if ( ! bInv) { + // Vertice condiviso fra nTri1 e quello del suo fan + int nCol1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetAttrib( 2) ; + int nCol2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetAttrib( 2) ; + // Modifico i punti e gli indici + TriHold[n1].vCompoTria[nCompo1][nTri1].SetP( 1, TriHold[n2].ptCompoVert[nCompo2]) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].SetP( 1, TriHold[n1].ptCompoVert[nCompo1]) ; + TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol1) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol2) ; + // Setto le normali + Vector3d vtN1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( 2) ; + Vector3d vtN2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( 2) ; + TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( 0, vtN1) ; + TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( 1, vtN1) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( 0, vtN2) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( 1, vtN2) ; + // Valido i triangoli + TriHold[n1].vCompoTria[nCompo1][nTri1].Validate( true) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].Validate( true) ; + // Avvenuto flipping + bModified = true ; break ; - } - - // Si deve operare la modifica dei triangoli - if ( SharedIndex.size() > 2) { - - // Verifico che i due lati adiacenti siano controversi - int nProd = ( SharedIndex[2] - SharedIndex[0]) * ( SharedIndex[3] - SharedIndex[1]) ; - if ( nProd != 1 && nProd != - 2 && nProd != 4 && nProd != 0) { - // Assegno l'array dei punti di contorno - Point3d vPnt[4] ; - vPnt[0] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( SharedIndex[0]) ; - vPnt[1] = TriHold[n1].ptCompoVert[nCompo1] ; - vPnt[2] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( SharedIndex[2]) ; - vPnt[3] = TriHold[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 = TriHold[n1].vCompoTria[nCompo1][nTri1] ; - Triangle3d trT2 = TriHold[n2].vCompoTria[nCompo2][nTri2] ; - int nVert1, nVert2 ; - // Determino gli indici dei punti sharp-feature - for ( int nP = 0 ; nP < 3 ; ++ nP) { - if ( nP != SharedIndex[0] && nP != SharedIndex[2]) - nVert1 = nP ; - if ( nP != SharedIndex[1] && nP != SharedIndex[3]) - nVert2 = nP ; - } - trT1.SetP( SharedIndex[0], trT2.GetP( nVert2)) ; - trT2.SetP( SharedIndex[3], trT1.GetP( nVert1)) ; - trT1.Validate( true) ; - trT2.Validate( true) ; - bInv = ( trT1.GetN() * trT2.GetN() < 0) ; + } + else { + // In questo caso i due triangoli sono necessariamente su un piano, + // quindi hanno normali concordi. Per ognuno dei due cerco nei rispettivi + // ventagli un triangolo con normale concorde con colore definito. Assegno + // tale colore ai triangoli. + int nPrv1 = ( nTri1 != 0 ? nTri1 : int( TriHold[n1].vCompoTria[nCompo1].size())) - 1 ; + int nNxt1 = ( nTri1 != TriHold[n1].vCompoTria[nCompo1].size() - 1 ? nTri1 + 1 : 0) ; + int nPrv2 = ( nTri2 != 0 ? nTri2 : int( TriHold[n2].vCompoTria[nCompo2].size())) - 1 ; + int nNxt2 = ( nTri2 != TriHold[n2].vCompoTria[nCompo2].size() - 1 ? nTri2 + 1 : 0) ; + // Prodotti scalari del primo triangolo con i suoi adiacenti + double dDotP1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() * + TriHold[n1].vCompoTria[nCompo1][nPrv1].GetN() ; + double dDotN1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() * + TriHold[n1].vCompoTria[nCompo1][nNxt1].GetN() ; + // Prendo il maggiore fra i due, e comunque maggiore di 0.5 + int nAdjT1 = - 1 ; + if ( dDotP1 > 0.5 || dDotN1 > 0.5) + nAdjT1 = ( dDotP1 > dDotN1 ? nPrv1 : nNxt1) ; + // Prodotti scalari del primo triangolo con i suoi adiacenti + double dDotP2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() * + TriHold[n2].vCompoTria[nCompo2][nPrv2].GetN() ; + double dDotN2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() * + TriHold[n2].vCompoTria[nCompo2][nNxt2].GetN() ; + // Prendo il maggiore fra i due, e comunque maggiore di 0.5 + int nAdjT2 = - 1 ; + if ( dDotP2 > 0.5 || dDotN2 > 0.5) + nAdjT2 = ( dDotP2 > dDotN2 ? nPrv2 : nNxt2) ; + // Se abbiamo trovato triangoli adiacenti validi + // assegnamo il colorea quelli correnti. + if ( nAdjT1 != - 1) { + int nCol = TriHold[n1].vCompoTria[nCompo1][nAdjT1].GetGrade() ; + TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ; } - // Se non vi è inversione eseguo il flipping - if ( ! bInv) { - // Vertice condiviso fra nTri1 e quello del suo fan - int nCol1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetAttrib( SharedIndex[2]) ; - int nCol2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetAttrib( SharedIndex[1]) ; - // Modifico i punti e gli indici - TriHold[n1].vCompoTria[nCompo1][nTri1].SetP( SharedIndex[0], - TriHold[n2].ptCompoVert[nCompo2]) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].SetP( SharedIndex[3], - TriHold[n1].ptCompoVert[nCompo1]) ; - TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol1) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol2) ; - // Valido i triangoli - TriHold[n1].vCompoTria[nCompo1][nTri1].Validate( true) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].Validate( true) ; - // Setto le normali a ogni vertice - Vector3d vtNorm1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( SharedIndex[2]) ; - Vector3d vtNorm2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( SharedIndex[1]) ; - - int nFeatureIndex1 = 0 ; - int nFeatureIndex2 = 0 ; - for ( ; nFeatureIndex1 < 3 && nFeatureIndex2 < 3 ; ) { - if ( ! ( nFeatureIndex1 != SharedIndex[0] && - nFeatureIndex1 != SharedIndex[2])) - ++ nFeatureIndex1 ; - else if ( ! ( nFeatureIndex2 != SharedIndex[1] && - nFeatureIndex2 != SharedIndex[3])) - ++ nFeatureIndex2 ; - else - break ; - } - TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( SharedIndex[0], vtNorm1) ; - TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( nFeatureIndex1, vtNorm1) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( SharedIndex[3], vtNorm2) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( nFeatureIndex2, vtNorm2) ; - - bModified = true ; - break ; - } - else { - // In questo caso i due triangoli sono necessariamente su un piano, - // quindi hanno normali concordi. Per ognuno dei due cerco nei rispettivi - // ventagli un triangolo con normale concorde con colore definito. Assegno - // tale colore ai triangoli. - int nPrv1 = ( nTri1 != 0 ? nTri1 : int( TriHold[n1].vCompoTria[nCompo1].size())) - 1 ; - int nNxt1 = ( nTri1 != TriHold[n1].vCompoTria[nCompo1].size() - 1 ? nTri1 + 1 : 0) ; - int nPrv2 = ( nTri2 != 0 ? nTri2 : int( TriHold[n2].vCompoTria[nCompo2].size())) - 1 ; - int nNxt2 = ( nTri2 != TriHold[n2].vCompoTria[nCompo2].size() - 1 ? nTri2 + 1 : 0) ; - - double dDotP1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() * - TriHold[n1].vCompoTria[nCompo1][nPrv1].GetN() ; - double dDotN1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() * - TriHold[n1].vCompoTria[nCompo1][nNxt1].GetN() ; - int nAdjT1 = - 1 ; - if ( dDotP1 > 0.5 || dDotN1 > 0.5) - nAdjT1 = ( dDotP1 > dDotN1 ? nPrv1 : nNxt1) ; - - double dDotP2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() * - TriHold[n2].vCompoTria[nCompo2][nPrv2].GetN() ; - double dDotN2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() * - TriHold[n2].vCompoTria[nCompo2][nNxt2].GetN() ; - int nAdjT2 = - 1 ; - if ( dDotP2 > 0.5 || dDotN2 > 0.5) - nAdjT2 = ( dDotP2 > dDotN2 ? nPrv2 : nNxt2) ; - - if ( nAdjT1 != - 1) { - int nCol = TriHold[n1].vCompoTria[nCompo1][nAdjT1].GetGrade() ; - TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ; - } - else if ( nAdjT2 != - 1) { - int nCol = TriHold[n2].vCompoTria[nCompo2][nAdjT2].GetGrade() ; - TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ; - TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ; - } - } - } - } - } + else if ( nAdjT2 != - 1) { + int nCol = TriHold[n2].vCompoTria[nCompo2][nAdjT2].GetGrade() ; + TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ; + TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ; + } + } + } + } if ( bModified) break ; } @@ -2778,28 +2746,21 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const { // Numero di blocchi size_t nBlocksNum = InterTria.size() ; - // ciclo sui blocchi for ( size_t tFB = 0 ; tFB < nBlocksNum ; ++ tFB) { - int nFBijk[3] ; GetBlockIJKFromN( int( tFB), nFBijk) ; - for ( size_t tLB = tFB ; tLB < nBlocksNum ; ++ tLB) { - int nLBijk[3] ; GetBlockIJKFromN( int( tLB), nLBijk) ; - // Se i blocchi non sono adiacenti salto l'iterazione if ( ! ( abs( nFBijk[0] - nLBijk[0]) <= 1 && abs( nFBijk[1] - nLBijk[1]) <= 1 && abs( nFBijk[2] - nLBijk[2]) <= 1)) continue ; - // Numero di voxel nei blocchi correnti size_t nVoxelNumFB = InterTria[tFB].size() ; size_t nVoxelNumLB = InterTria[tLB].size() ; - // Ciclo sui voxel dei due blocchi for ( size_t tVFB = 0 ; tVFB < nVoxelNumFB ; ++ tVFB) { for ( size_t tVLB = 0 ; tVLB < nVoxelNumLB ; ++ tVLB) { @@ -2817,118 +2778,73 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const // Numero di triangoli delle componenti connesse size_t nTriFBNum = InterTria[tFB][tVFB].vCompoTria[tCmpF].size() ; size_t nTriLBNum = InterTria[tLB][tVLB].vCompoTria[tCmpL].size() ; - + // Ciclo sui triangoli for ( size_t tTriFB = 0 ; tTriFB < nTriFBNum ; ++ tTriFB) { - bool bModified = false ; - for ( size_t tTriLB = 0 ; tTriLB < nTriLBNum ; ++ tTriLB) { - - INTVECTOR SharedIndex ; - - for ( int nVertF = 0 ; nVertF < 3 ; ++ nVertF) { - for ( int nVertL = 0 ; nVertL < 3 ; ++ nVertL) { - - Point3d ptPF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( nVertF) ; - Point3d ptPL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( nVertL) ; - - if ( AreSamePointEpsilon( ptPF, ptPL, EPS_ZERO)) { - - Point3d ptVertF = InterTria[tFB][tVFB].ptCompoVert[tCmpF] ; - Point3d ptVertL = InterTria[tLB][tVLB].ptCompoVert[tCmpL] ; - - if ( ! ( AreSamePointEpsilon( ptPF, ptVertF, EPS_ZERO) || - AreSamePointEpsilon( ptPL, ptVertL, EPS_ZERO))) { - - SharedIndex.emplace_back( nVertF) ; - SharedIndex.emplace_back( nVertL) ; - } - } - - if ( SharedIndex.size() > 2) - break ; - } - - if ( SharedIndex.size() > 2) - break ; - } - + // Punti che devono essere in comune fra i due triangoli + Point3d ptPF1 = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) ; + Point3d ptPF2 = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 2) ; + Point3d ptPL1 = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 1) ; + Point3d ptPL2 = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 2) ; // Si deve operare la modifica dei triangoli - if ( SharedIndex.size() > 2) { - // Verifico che i due lati adiacenti siano controversi - int nProd = ( SharedIndex[2] - SharedIndex[0]) * ( SharedIndex[3] - SharedIndex[1]) ; - if ( nProd != 1 && nProd != - 2 && nProd != 4 && nProd != 0) { - // Assegno l'array dei punti di contorno - Point3d vPnt[4] ; - vPnt[0] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( SharedIndex[0]) ; - vPnt[1] = InterTria[tFB][tVFB].ptCompoVert[tCmpF] ; - vPnt[2] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( SharedIndex[2]) ; - vPnt[3] = InterTria[tLB][tVLB].ptCompoVert[tCmpL] ; - // 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) { - Triangle3dEx trTF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB] ; - Triangle3dEx trTL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB] ; - int nVertF, nVertL ; - // Determino gli indici dei punti sharp-feature - for ( int nP = 0 ; nP < 3 ; ++ nP) { - if ( nP != SharedIndex[0] && nP != SharedIndex[2]) - nVertF = nP ; - if ( nP != SharedIndex[1] && nP != SharedIndex[3]) - nVertL = nP ; - } - trTF.SetP( SharedIndex[0], trTL.GetP( nVertL)) ; - trTF.Validate( true) ; - trTL.SetP( SharedIndex[3], trTF.GetP( nVertF)) ; - trTL.Validate( true) ; - bInv = ( trTF.GetN() * trTL.GetN() < 0) ; - } - // Se non vi è inversione eseguo il flipping - if ( ! bInv) { - // Vertice condiviso fra nTri1 e quello del suo fan - int nColF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetAttrib( SharedIndex[2]) ; - int nColL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetAttrib( SharedIndex[1]) ; - // modifico punti e colori - InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetP( SharedIndex[0], - InterTria[tLB][tVLB].ptCompoVert[tCmpL]) ; - InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetP( SharedIndex[3], - InterTria[tFB][tVFB].ptCompoVert[tCmpF]) ; - InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetGrade( nColF) ; - InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetGrade( nColL) ; - // Valido i triangoli - InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].Validate( true) ; - InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].Validate( true) ; - - // Setto le normali a ogni vertice - Vector3d vtNormF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetVertexNorm( SharedIndex[2]) ; - Vector3d vtNormL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetVertexNorm( SharedIndex[1]) ; - int nFeatureIndexF = 0 ; - int nFeatureIndexL = 0 ; - for ( ; nFeatureIndexF < 3 && nFeatureIndexL < 3 ; ) { - if ( ! ( nFeatureIndexF != SharedIndex[0] && - nFeatureIndexF != SharedIndex[2])) - ++ nFeatureIndexF ; - else if ( ! ( nFeatureIndexL != SharedIndex[1] && - nFeatureIndexL != SharedIndex[3])) - ++ nFeatureIndexL ; - else - break ; - } - InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( SharedIndex[0], vtNormF) ; - InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( nFeatureIndexF, vtNormF) ; - InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( SharedIndex[3], vtNormL) ; - InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( nFeatureIndexL, vtNormL) ; - bModified = true ; - break ; + if ( AreSamePointEpsilon( ptPF1, ptPL2, EPS_ZERO) && + AreSamePointEpsilon( ptPF2, ptPL1, EPS_ZERO)) { + // Assegno l'array dei punti di contorno + Point3d vPnt[4] ; + vPnt[0] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) ; + vPnt[1] = InterTria[tFB][tVFB].ptCompoVert[tCmpF] ; + vPnt[2] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 2) ; + vPnt[3] = InterTria[tLB][tVLB].ptCompoVert[tCmpL] ; + // 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) { + Triangle3dEx trTF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB] ; + Triangle3dEx trTL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB] ; + int nVertF, nVertL ; + // Determino gli indici dei punti sharp-feature + for ( int nP = 0 ; nP < 3 ; ++ nP) { + if ( nP != 1 && nP != 2) + nVertF = nP ; + if ( nP != 2 && nP != 1) + nVertL = nP ; } + trTF.SetP( 1, trTL.GetP( nVertL)) ; + trTF.Validate( true) ; + trTL.SetP( 1, trTF.GetP( nVertF)) ; + trTL.Validate( true) ; + bInv = ( trTF.GetN() * trTL.GetN() < 0) ; + } + // Se non vi è inversione eseguo il flipping + if ( ! bInv) { + // Vertice condiviso fra nTri1 e quello del suo fan + int nColF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetAttrib( 2) ; + int nColL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetAttrib( 2) ; + // modifico punti e colori + InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetP( 1, InterTria[tLB][tVLB].ptCompoVert[tCmpL]) ; + InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetP( 1, InterTria[tFB][tVFB].ptCompoVert[tCmpF]) ; + InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetGrade( nColF) ; + InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetGrade( nColL) ; + // Valido i triangoli + InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].Validate( true) ; + InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].Validate( true) ; + // Setto le normali a ogni vertice + Vector3d vtNormF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetVertexNorm( 2) ; + Vector3d vtNormL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetVertexNorm( 2) ; + InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( 1, vtNormF) ; + InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( 0, vtNormF) ; + InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 1, vtNormL) ; + InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 0, vtNormL) ; + bModified = true ; + break ; } } }