//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 // Contenuto : Implementazione della classe Volume Zmap (singola griglia) // // // // Modifiche : 22.01.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "VolZmap.h" #include "GeoConst.h" #include "\EgtDev\Include\EGkIntervals.h" using namespace std ; //---------------------------------------------------------------------------- bool VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const { // per ora solo perpendicolari a XY (1) if ( nDir != 1) return false ; // verifiche sugli indici if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) return false ; int nPos = nPos1 + nPos2 * m_nNx ; if ( nPos < 0 || nPos >= int( m_ZValues.size())) return false ; // calcolo coordinate punto double dX = m_dStep * ( 0.5 + nPos1) ; double dY = m_dStep * ( 0.5 + nPos2) ; Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; // creo le polilinee for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { // aggiungo polilinea a lista lstPL.emplace_back() ; // inserisco punti estremi lstPL.back().AddUPoint( 0, ptP + m_ZValues[nPos][i-1] * m_LocalFrame.VersZ()) ; lstPL.back().AddUPoint( 1, ptP + m_ZValues[nPos][i] * m_LocalFrame.VersZ()) ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const { const int MAX_DIM_CHUNK = 128 ; for ( int i = 0 ; i < int( m_nNx) ; i += MAX_DIM_CHUNK) { int nDimChunkX = min( MAX_DIM_CHUNK, int( m_nNx) - i) ; for ( int j = 0 ; j < int( m_nNy) ; j += MAX_DIM_CHUNK) { int nDimChunkY = min( MAX_DIM_CHUNK, int( m_nNy) - j) ; GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, MAX_DIM_CHUNK, lstTria) ; } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk, TRIA3DLIST& lstTria) const { // determino se è un semplice parallelepipedo bool bIsSimple = true ; double dBotZ ; double dTopZ ; for ( int i = 0 ; i < nDim1 && bIsSimple ; ++ i) { for ( int j = 0 ; j < nDim2 && bIsSimple ; ++ j) { int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nNx ; if ( nPos > int( m_nDim) || int( m_ZValues[nPos].size()) != 2) bIsSimple = false ; else if ( i == 0 && j == 0) { dBotZ = m_ZValues[nPos][0] ; dTopZ = m_ZValues[nPos][1] ; } else if ( abs( m_ZValues[nPos][0] - dBotZ) > EPS_SMALL || abs( m_ZValues[nPos][1] - dTopZ) > EPS_SMALL) bIsSimple = false ; } } // se semplice parallelepipedo if ( bIsSimple) { CalcChunkPrisms( nPos1, nPos2, nDim1, nDim2, lstTria) ; } // se chunk di dimensioni accettabili else if ( nDimChk >= 4) { int nNewDimChk = nDimChk / 2 ; for ( int i = nPos1 ; i < int( nPos1 + nDim1) ; i += nNewDimChk) { int nDimChunkX = min( nNewDimChk, int( nPos1 + nDim1) - i) ; for ( int j = nPos2 ; j < int( nPos2 + nDim2) ; j += nNewDimChk) { int nDimChunkY = min( nNewDimChk, int( nPos2 + nDim2) - j) ; GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, nNewDimChk, lstTria) ; } } } // altrimenti else { // elaboro ogni singolo dexel for ( int i = 0 ; i < nDim1 ; ++ i) { for ( int j = 0 ; j < nDim2 ; ++ j) { CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const { // verifiche sugli indici if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nNx) || nPos2 < 0 || nPos2 + nDim2 > int( m_nNy)) return false ; int nPos = nPos1 + nPos2 * m_nNx ; if ( nPos < 0 || nPos >= int( m_nDim)) return false ; // calcolo coordinate punti double dX = m_dStep * nPos1 ; double dY = m_dStep * nPos2 ; Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_LocalFrame.VersX() ; Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_LocalFrame.VersY() ; Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_LocalFrame.VersY() ; // creo le facce sopra e sotto Vector3d vtDZt = m_ZValues[nPos][1] * m_LocalFrame.VersZ() ; Vector3d vtDZb = m_ZValues[nPos][0] * m_LocalFrame.VersZ() ; // faccia superiore P1t->P2t->P3t->P4t : sempre visibile lstTria.emplace_back() ; lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; lstTria.emplace_back() ; lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile lstTria.emplace_back() ; lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; lstTria.emplace_back() ; lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; // creo le facce laterali for ( int j = 0 ; j < nDim2 ; ++ j) { int nPosD = nPos + nDim1 - 1 + j * m_nNx ; int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nNx - 1) ? nPosD + 1 : - 1) ; Point3d ptP2D = ptP2 + j * m_dStep * m_LocalFrame.VersY() ; Point3d ptP3D = ptP2D + m_dStep * m_LocalFrame.VersY() ; AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; } for ( int i = 0 ; i < nDim1 ; ++ i) { int nPosD = nPos + ( nDim2 - 1) * m_nNx + i ; int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nNy - 1) ? nPosD + m_nNx : - 1) ; Point3d ptP4D = ptP4 + i * m_dStep * m_LocalFrame.VersX() ; Point3d ptP3D = ptP4D + m_dStep * m_LocalFrame.VersX() ; AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; } for ( int j = 0 ; j < nDim2 ; ++ j) { int nPosD = nPos + j * m_nNx ; int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ; Point3d ptP1D = ptP1 + j * m_dStep * m_LocalFrame.VersY() ; Point3d ptP4D = ptP1D + m_dStep * m_LocalFrame.VersY() ; AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; } for ( int i = 0 ; i < nDim1 ; ++ i) { int nPosD = nPos + i ; int nPosSud = ( nPos2 > 0 ? nPosD - m_nNx : - 1) ; Point3d ptP1D = ptP1 + i * m_dStep * m_LocalFrame.VersX() ; Point3d ptP2D = ptP1D + m_dStep * m_LocalFrame.VersX() ; AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const { // verifiche sugli indici if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) return false ; int nPos = nPos1 + nPos2 * m_nNx ; if ( nPos < 0 || nPos >= int( m_nDim)) return false ; // calcolo coordinate punto double dX = m_dStep * nPos1 ; double dY = m_dStep * nPos2 ; Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; Point3d ptP2 = ptP1 + m_dStep * m_LocalFrame.VersX() ; Point3d ptP3 = ptP2 + m_dStep * m_LocalFrame.VersY() ; Point3d ptP4 = ptP1 + m_dStep * m_LocalFrame.VersY() ; // creo le facce sopra e sotto di ogni intervallo (sempre visibili) for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { Vector3d vtDZt = m_ZValues[nPos][i] * m_LocalFrame.VersZ() ; Vector3d vtDZb = m_ZValues[nPos][i-1] * m_LocalFrame.VersZ() ; // faccia superiore P1t->P2t->P3t->P4t : sempre visibile lstTria.emplace_back() ; lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; lstTria.emplace_back() ; lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile lstTria.emplace_back() ; lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; lstTria.emplace_back() ; lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; } // creo le facce laterali int nPosEst = ( nPos1 < int( m_nNx - 1) ? nPos + 1 : - 1) ; AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; int nPosNord = ( nPos2 < int( m_nNy - 1) ? nPos + m_nNx : - 1) ; AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ; AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; int nPosSud = ( nPos2 > 0 ? nPos - m_nNx : - 1) ; AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const { Intervals intFace ; for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) intFace.Add( m_ZValues[nPos][i-1], m_ZValues[nPos][i]) ; if ( nPosAdj > 0) { for ( int i = 1 ; i < int( m_ZValues[nPosAdj].size()) ; i += 2) intFace.Subtract( m_ZValues[nPosAdj][i-1], m_ZValues[nPosAdj][i]) ; } double dMin, dMax ; bool bFound = intFace.GetFirst( dMin, dMax) ; while ( bFound) { Vector3d vtDZt = dMax * vtZ ; Vector3d vtDZb = dMin * vtZ ; lstTria.emplace_back() ; lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ; lstTria.emplace_back() ; lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ; bFound = intFace.GetNext( dMin, dMax) ; } return true ; }