//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 // Contenuto : Implementazione della classe Volume Zmap (tre griglie) // // // // Modifiche : 22.01.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" #include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EgtNumUtils.h" using namespace std ; // ------------------------- CREAZIONE MAPPA -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) { // Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) return false ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dStep, 100 * EPS_SMALL) ; // Aggiorno la dimensione della mappa 1 o 3 m_nMapNum = ( bTriDex ? 3 : 1) ; // Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z // di uno si ottengono da una permutazione ciclica di quelle del precedente sistema. // es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1) // Definisco il sistema di riferimento intrinseco m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; // Definisco i vettori dei limiti su indici m_nNx[0] = unsigned int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5) ; m_nNy[0] = unsigned int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5) ; // Calcolo il numero di voxel lungo X e Y unsigned int nVoxNumX = m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2) ; unsigned int nVoxNumY = m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] % N_DEXVOXRATIO == 0 ? 1 : 2) ; // Definisco il numero di blocchi lungo x e y m_nFracLin[0] = max( 1u, unsigned int( nVoxNumX * 1.0 / m_nVoxNumPerBlock + 0.7)) ; m_nFracLin[1] = max( 1u, unsigned int( nVoxNumY * 1.0 / m_nVoxNumPerBlock + 0.7)) ; // Numero di componenti connesse m_nConnectedCompoCount = 1 ; // Se tridexel if ( bTriDex) { m_nNx[1] = m_nNy[0] ; m_nNy[1] = unsigned int( ( dLengthZ + EPS_SMALL) / m_dStep + 0.5) ; m_nNx[2] = m_nNy[1] ; m_nNy[2] = m_nNx[0] ; // Calcolo il numero di voxel lungo Z unsigned int nVoxNumZ = m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2) ; // Definisco il numero di blocchi lungo z m_nFracLin[2] = max( 1u, unsigned int( nVoxNumZ * 1.0 / m_nVoxNumPerBlock + 0.7)) ; } // altrimenti mono dexel else { m_nNx[1] = 0 ; m_nNy[1] = 0 ; m_nNx[2] = 0 ; m_nNy[2] = 0 ; // Definisco il numero di blocchi lungo z m_nFracLin[2] = 1 ; } // Definizione della mappa // Creazione delle mappe // Calcolo del numero di celle per ogni mappa for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) m_nDim[i] = m_nNx[i] * m_nNy[i] ; // Creazione delle celle per ogni mappa for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) m_Values[i].resize( m_nDim[i]) ; // Riempimento delle celle for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) for ( unsigned int j = 0 ; j < m_nDim[i] ; ++ j) { // Aggiungo il tratto al dexel vuoto m_Values[i][j].resize( 1) ; m_Values[i][j][0].dMin = 0 ; m_Values[i][j][0].nToolMin = 0 ; m_Values[i][j][0].nCompo = 1 ; switch ( i) { case 0 : m_Values[i][j][0].vtMinN = - Z_AX ; m_Values[i][j][0].dMax = dLengthZ ; m_Values[i][j][0].vtMaxN = Z_AX ; m_Values[i][j][0].nToolMax = 0 ; break ; case 1 : m_Values[i][j][0].vtMinN = - X_AX ; m_Values[i][j][0].dMax = dLengthX ; m_Values[i][j][0].vtMaxN = X_AX ; m_Values[i][j][0].nToolMax = 0 ; break ; case 2 : m_Values[i][j][0].vtMinN = - Y_AX ; m_Values[i][j][0].dMax = dLengthY ; m_Values[i][j][0].vtMaxN = Y_AX ; m_Values[i][j][0].nToolMax = 0 ; break ; } } // Definizione delle limitazioni iniziali in Z per ogni mappa m_dMinZ[0] = 0 ; m_dMaxZ[0] = dLengthZ ; m_dMinZ[1] = 0 ; m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ; m_dMinZ[2] = 0 ; m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ; // Dimensiono e setto il vettore dei blocchi a da ricalcolare m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ; m_BlockToUpdate.clear() ; m_BlockToUpdate.resize( m_nNumBlock, true) ; // Tipologia m_nShape = BOX ; // Dimensiono raccolta di voxel, triangoli di feature tra blocchi e di segnalatori di materiale fra voxel m_InterBlockVox.resize( m_nNumBlock) ; m_InterBlockTria.resize( m_nNumBlock) ; m_SliceXY.resize( m_nNumBlock) ; m_SliceXZ.resize( m_nNumBlock) ; m_SliceYZ.resize( m_nNumBlock) ; // Aggiornamento dello stato m_nStatus = OK ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) { // Aggiorno la dimensione della mappa 1 o 3 m_nMapNum = ( bTriDex ? 3 : 1) ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dStep, 100 * EPS_SMALL) ; // Determino il bounding box della flat region BBox3d SurfBBox ; Surf.GetLocalBBox( SurfBBox, BBF_EXACT) ; // Determino i punti estremi del bounding box Point3d ptMapOrig, ptMapEnd ; SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 0) ; // Sistema di riferimento intrinseco dello Zmap m_MapFrame.Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; // Determino le dimensioni lineari X Y della griglia double dLengthX = ptMapEnd.x - ptMapOrig.x ; double dLengthY = ptMapEnd.y - ptMapOrig.y ; // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe // della griglia Zmap e da questi la dimensione del vettore di dexel m_nNx[0] = unsigned int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5) ; m_nNy[0] = unsigned int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5) ; m_nDim[0] = m_nNx[0] * m_nNy[0] ; // Ridimensiono il vettore di dexel e creo lo Zmap m_Values[0].resize( m_nDim[0]) ; // Calcolo il numero di voxel lungo X e Y unsigned int nVoxNumX = m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2) ; unsigned int nVoxNumY = m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] % N_DEXVOXRATIO == 0 ? 1 : 2) ; // Definisco il numero di blocchi lungo x e y m_nFracLin[0] = max( 1u, unsigned int( nVoxNumX * 1.0 / m_nVoxNumPerBlock + 0.7)) ; m_nFracLin[1] = max( 1u, unsigned int( nVoxNumY * 1.0 / m_nVoxNumPerBlock + 0.7)) ; // Numero di componenti connesse m_nConnectedCompoCount = Surf.GetChunkCount() ; // Se Tridexel ridimensiono anche gli altri vettori if ( bTriDex) { m_nNx[1] = m_nNy[0] ; m_nNy[1] = unsigned int( ( dDimZ + EPS_SMALL) / m_dStep + 0.5) ; m_nDim[1] = m_nNx[1] * m_nNy[1] ; m_Values[1].resize( m_nDim[1]) ; m_nNx[2] = m_nNy[1] ; m_nNy[2] = m_nNx[0] ; m_nDim[2] = m_nNx[2] * m_nNy[2] ; m_Values[2].resize( m_nDim[2]) ; // Calcolo il numero di voxel lungo Z unsigned int nVoxNumZ = m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2) ; // Definisco il numero di blocchi lungo z m_nFracLin[2] = max( 1u, unsigned int( nVoxNumZ * 1.0 / m_nVoxNumPerBlock + 0.7)) ; } else { m_nNx[1] = 0 ; m_nNy[1] = 0 ; m_nDim[1] = 0 ; m_nNx[2] = 0 ; m_nNy[2] = 0 ; m_nDim[2] = 0 ; // Definisco il numero di blocchi lungo z m_nFracLin[2] = 1 ; } // Metto in cache le curve di contorno della regione ICURVEPOVECTOR vpCrvs ; INTVECTOR vnCompo ; int nChunkNum = Surf.GetChunkCount() ; for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) { int nLoopNum = Surf.GetLoopCount( nChunk) ; for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) { ICurve* pCrv = Surf.GetLoop( nChunk, nLoop) ; if ( pCrv != nullptr) { vpCrvs.emplace_back( pCrv) ; vnCompo.emplace_back( nChunk + 1) ; } } } // Calcolo griglia 0=XY ( se tridexel anche griglia 2=ZX) for ( unsigned int i = 0 ; i < m_nNx[0] ; ++ i) { // Definisco la retta diretta come Y da intersecare con la regione double dX = ( i + 0.5) * m_dStep ; Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; CurveLine GridLine ; GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; // Determino le intersezioni della retta con la regione CRVCVECTOR IntersectionResults ; Surf.GetCurveClassification( GridLine, IntersectionResults) ; // Analizzo le parti in cui la retta è stata divisa int nPart = int( IntersectionResults.size()) ; for ( int k = 0 ; k < nPart ; ++ k) { // Se la retta è interna alla regione o coincidente con parte della sua frontiera int nType = IntersectionResults[k].nClass ; if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { // Lunghezze dei tratti di retta corrente double dLen1 = IntersectionResults[k].dParS * dLengthY ; double dLen2 = IntersectionResults[k].dParE * dLengthY ; // Punti estremi della parte di retta corrente Point3d ptP1 = ptP0 + dLen1 * Y_AX ; Point3d ptP2 = ptP0 + dLen2 * Y_AX ; // Ricerca di questi punti sui contorni della regione, per avere le normali e il numero di componente connesso int nFind = 0 ; int nCompo = 0 ; Vector3d vtN1 = - Y_AX ; Vector3d vtN2 = Y_AX ; for ( size_t m = 0 ; m < vpCrvs.size() ; ++ m) { // recupero la curva ICurve* pCurve = vpCrvs[m] ; // determino posizione primo punto su curva double dP1 ; if ( ( nFind & 1) == 0 && pCurve->GetParamAtPoint( ptP1, dP1, 10 * EPS_SMALL)) { Point3d ptTemp1 ; Vector3d vtT1 ; pCurve->GetPointTang( dP1, ICurve::FROM_MINUS, ptTemp1, vtT1) ; vtN1 = vtT1 ^ Z_AX ; nFind += 1 ; } // determino posizione secondo punto su curva double dP2 ; if ( ( nFind & 2) == 0 && pCurve->GetParamAtPoint( ptP2, dP2, 10 * EPS_SMALL)) { Point3d ptTemp2 ; Vector3d vtT2 ; pCurve->GetPointTang( dP2, ICurve::FROM_MINUS, ptTemp2, vtT2) ; vtN2 = vtT2 ^ Z_AX ; nFind += 2 ; } // Se trovati entrambi gli estremi, esco dal ciclo if ( nFind == 3) { nCompo = vnCompo[m] ; break ; } } // Verifico di aver trovato i punti sulle curve if ( nFind != 3) LOG_ERROR( GetEGkLogger(), "Error in VolZmap::CreateFromFlatRegion : point not on baundary") // Ridimensiono e riempio i dexel della griglia 0 int nStartJ = Clamp( int( floor( dLen1 / m_dStep - EPS_SMALL + 0.5)), 0, m_nNy[0] - 1) ; int nEndJ = Clamp( int( floor( dLen2 / m_dStep + EPS_SMALL - 0.5)), 0, m_nNy[0] - 1) ; for ( int j = nStartJ ; j <= nEndJ ; ++ j) { // Determino il dexel int nPos0 = j * m_nNx[0] + i ; // Aggiungo il tratto al dexel vuoto m_Values[0][nPos0].resize( 1) ; // Aggiorno i dati del tratto di dexel m_Values[0][nPos0][0].dMin = 0 ; m_Values[0][nPos0][0].vtMinN = - Z_AX ; m_Values[0][nPos0][0].nToolMin = 0 ; m_Values[0][nPos0][0].dMax = dDimZ ; m_Values[0][nPos0][0].vtMaxN = Z_AX ; m_Values[0][nPos0][0].nToolMax = 0 ; m_Values[0][nPos0][0].nCompo = nCompo ; } // Se tridexel riempio i singoli dexel della griglia 2 con gli intervalli if ( bTriDex) { for ( size_t n = 0 ; n < m_nNx[2] ; ++ n) { size_t nPos2 = i * m_nNx[2] + n ; size_t nCurrSize = m_Values[2][nPos2].size( ) ; // Aggiungo un tratto al dexel m_Values[2][nPos2].resize( nCurrSize + 1) ; // Aggiorno i dati del tratto di dexel m_Values[2][nPos2][nCurrSize].dMin = dLen1 ; m_Values[2][nPos2][nCurrSize].vtMinN = vtN1 ; m_Values[2][nPos2][nCurrSize].nToolMin = 0 ; m_Values[2][nPos2][nCurrSize].dMax = dLen2 ; m_Values[2][nPos2][nCurrSize].vtMaxN = vtN2 ; m_Values[2][nPos2][nCurrSize].nToolMax = 0 ; m_Values[2][nPos2][nCurrSize].nCompo = nCompo ; } } } } } // Se tridexel calcolo griglia 1=YZ if ( bTriDex) { // ciclo sul lato orizzontale della griglia for ( unsigned int i = 0 ; i < m_nNx[1] ; ++ i) { // Definisco la retta diretta come X da intersecare con la regione double dY = ( i + 0.5) * m_dStep ; Point3d ptP0 = ptMapOrig + Vector3d( 0, dY, 0) ; CurveLine GridLine ; GridLine.SetPVL( ptP0, X_AX, dLengthX) ; // Determino le intersezioni della retta con la regione CRVCVECTOR IntersectionResults ; Surf.GetCurveClassification( GridLine, IntersectionResults) ; // Analizzo le parti int nPart = int( IntersectionResults.size()) ; for ( int k = 0 ; k < nPart ; ++ k) { // Se la retta è interna alla regione o coincidente con parte della sua frontiera int nType = IntersectionResults[k].nClass ; if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { // Lunghezze dei tratti di retta double dLen1 = IntersectionResults[k].dParS * dLengthX ; double dLen2 = IntersectionResults[k].dParE * dLengthX ; // Punti estremi Point3d ptP1 = ptP0 + dLen1 * X_AX ; Point3d ptP2 = ptP0 + dLen2 * X_AX ; // Ricerca di questi punti sui contorni della regione, per avere le normali e il numero di componente connesso int nFind = 0 ; int nCompo = 0 ; Vector3d vtN1 = -X_AX ; Vector3d vtN2 = X_AX ; for ( size_t m = 0 ; m < vpCrvs.size() ; ++ m) { // recupero la curva ICurve* pCurve = vpCrvs[m] ; // determino posizione primo punto su curva double dP1 ; if ( ( nFind & 1) == 0 && pCurve->GetParamAtPoint( ptP1, dP1, 10 * EPS_SMALL)) { Point3d ptTemp1 ; Vector3d vtT1 ; pCurve->GetPointTang( dP1, ICurve::FROM_MINUS, ptTemp1, vtT1) ; vtN1 = vtT1 ^ Z_AX ; nFind += 1 ; } // determino posizione secondo punto su curva double dP2 ; if ( ( nFind & 2) == 0 && pCurve->GetParamAtPoint( ptP2, dP2, 10 * EPS_SMALL)) { Point3d ptTemp2 ; Vector3d vtT2 ; pCurve->GetPointTang( dP2, ICurve::FROM_MINUS, ptTemp2, vtT2) ; vtN2 = vtT2 ^ Z_AX ; nFind += 2 ; } // Se trovati entrambi gli estremi, esco dal ciclo if ( nFind == 3) { nCompo = vnCompo[m] ; break ; } } // Verifico di aver trovato i punti sulle curve if ( nFind != 3) LOG_ERROR( GetEGkLogger(), "Error in VolZmap::CreateFromFlatRegion : point not on baundary") // aggiorno i dexel impilati for ( size_t j = 0 ; j < m_nNy[1] ; ++ j) { size_t nPos1 = j * m_nNx[1] + i ; size_t nCurrSize = m_Values[1][nPos1].size() ; // Aggiungo un tratto al dexel m_Values[1][nPos1].resize( nCurrSize + 1) ; // Assegno i dati m_Values[1][nPos1][nCurrSize].dMin = dLen1 ; m_Values[1][nPos1][nCurrSize].vtMinN = vtN1 ; m_Values[1][nPos1][nCurrSize].nToolMin = 0 ; m_Values[1][nPos1][nCurrSize].dMax = dLen2 ; m_Values[1][nPos1][nCurrSize].vtMaxN = vtN2 ; m_Values[1][nPos1][nCurrSize].nToolMax = 0 ; m_Values[1][nPos1][nCurrSize].nCompo = nCompo ; } } } } } // Definizione delle limitazioni iniziali in Z per ogni mappa m_dMinZ[0] = 0 ; m_dMaxZ[0] = dDimZ ; m_dMinZ[1] = 0 ; m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ; m_dMinZ[2] = 0 ; m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ; // Dimensiono e setto il vettore dei blocchi a da ricalcolare m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ; m_BlockToUpdate.clear() ; m_BlockToUpdate.resize( m_nNumBlock, true) ; // Dimensiono raccolta di voxel, triangoli di feature tra blocchi e di segnalatori di materiale fra voxel m_InterBlockVox.resize( m_nNumBlock) ; m_InterBlockTria.resize( m_nNumBlock) ; m_SliceXY.resize( m_nNumBlock) ; m_SliceXZ.resize( m_nNumBlock) ; m_SliceYZ.resize( m_nNumBlock) ; // Tipologia m_nShape = ( IsBox() ? BOX : EXTRUSION) ; // Aggiornamento dello stato m_nStatus = OK ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) { // Se la superficie non è chiusa non ha senso continuare if ( ! Surf.IsClosed()) return false ; // Assegno la dimensione della mappa 1 o 3 m_nMapNum = ( bTriDex ? 3 : 1) ; // Determino il bounding box della TriMesh BBox3d SurfBBox ; Surf.GetLocalBBox( SurfBBox) ; // Determino i punti estremi del bounding box Point3d ptMapOrig, ptMapEnd ; SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; // Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione, // quindi espandiamo il bounding box per ovviare al problema. SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ; // Sistema di riferimento intrinseco dello Zmap m_MapFrame.Set( ptMapOrig, Frame3d::TOP) ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dStep, 100 * EPS_SMALL) ; // Determino le dimensioni lineari del BBox Vector3d vtLen = ptMapEnd - ptMapOrig ; // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe // della griglia Zmap e da questi la dimensione del vettore di dexel m_nNx[0] = unsigned int( ( vtLen.x + EPS_SMALL) / m_dStep + 0.5) ; m_nNy[0] = unsigned int( ( vtLen.y + EPS_SMALL) / m_dStep + 0.5) ; m_nDim[0] = m_nNx[0] * m_nNy[0] ; // Ridimensiono il vettore di dexel e creo lo Zmap m_Values[0].resize( m_nDim[0]) ; // Calcolo il numero di voxel lungo X e Y unsigned int nVoxNumX = m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2) ; unsigned int nVoxNumY = m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] % N_DEXVOXRATIO == 0 ? 1 : 2) ; // Definisco il numero di blocchi lungo x e y m_nFracLin[0] = max( 1u, unsigned int( nVoxNumX * 1.0 / m_nVoxNumPerBlock + 0.7)) ; m_nFracLin[1] = max( 1u, unsigned int( nVoxNumY * 1.0 / m_nVoxNumPerBlock + 0.7)) ; // Numero di componenti connesse da calcolare m_nConnectedCompoCount = - 1 ; // Se Tridexel ridimensiono anche gli altri vettori if ( bTriDex) { m_nNx[1] = m_nNy[0] ; m_nNy[1] = unsigned int( ( vtLen.z + EPS_SMALL) / m_dStep + 0.5) ; m_nDim[1] = m_nNx[1] * m_nNy[1] ; m_Values[1].resize( m_nDim[1]) ; m_nNx[2] = m_nNy[1] ; m_nNy[2] = m_nNx[0] ; m_nDim[2] = m_nNx[2] * m_nNy[2] ; m_Values[2].resize( m_nDim[2]) ; // Calcolo il numero di voxel lungo Z unsigned int nVoxNumZ = m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2) ; // Definisco il numero di blocchi lungo z m_nFracLin[2] = max( 1u, unsigned int( nVoxNumZ * 1.0 / m_nVoxNumPerBlock + 0.7)) ; } else { m_nNx[1] = 0 ; m_nNy[1] = 0 ; m_nDim[1] = 0 ; m_nNx[2] = 0 ; m_nNy[2] = 0 ; m_nDim[2] = 0 ; // Definisco il numero di blocchi lungo z m_nFracLin[2] = 1 ; } // ciclo sulle griglie for ( unsigned int g = 0 ; g < m_nMapNum ; ++ g) { // Definisco dei sistemi di riferimento ausiliari Frame3d frMapFrame ; if ( g == 0) frMapFrame = m_MapFrame ; else if ( g == 1) frMapFrame.Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; else if ( g == 2) frMapFrame.Set( ptMapOrig, Z_AX, X_AX, Y_AX) ; // Oggetto per calcolo massivo intersezioni IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ; // Determinazione e ridimensionamento dei dexel interni alla trimesh for ( unsigned int i = 0 ; i < m_nNx[g] ; ++ i) { for ( unsigned int j = 0 ; j < m_nNy[g] ; ++ j) { // Definisco la retta da intersecare con la trimesh double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptP0( dX, dY, 0) ; // Determino le intersezioni della retta con la TriMesh ILSIVECTOR IntersectionResults ; intPLSTM.GetInters( ptP0, vtLen.v[(g+2)%3], IntersectionResults) ; int nInt = int( IntersectionResults.size()) ; unsigned int nPos = j * m_nNx[g] + i ; bool bInside = false ; Point3d ptIn ; Vector3d vtInN ; for ( int k = 0 ; k < nInt ; ++ k) { int nIntType = IntersectionResults[k].nILTT ; // Se c'è intersezione if ( nIntType != ILTT_NO) { double dCos = IntersectionResults[k].dCosDN ; // entro nella superficie trimesh if ( dCos < - EPS_SMALL) { ptIn = IntersectionResults[k].ptI ; int nT = IntersectionResults[k].nT ; int nF = Surf.GetFacetFromTria( nT) ; Surf.GetFacetNormal( nF, vtInN) ; bInside = true ; } // esco dalla superficie trimesh else if ( dCos > EPS_SMALL && bInside) { Point3d ptOut = IntersectionResults[k].ptI ; int nT = IntersectionResults[k].nT ; int nF = Surf.GetFacetFromTria( nT) ; Vector3d vtOutN ; Surf.GetFacetNormal( nF, vtOutN) ; unsigned int nCurrentSize = unsigned int( m_Values[g][nPos].size()) ; // Aggiungo un tratto al dexel m_Values[g][nPos].resize( nCurrentSize + 1) ; // Aggiorno dati del tratto di dexel m_Values[g][nPos][nCurrentSize].dMin = ptIn.v[(g+2)%3] - ptMapOrig.v[(g+2)%3] ; m_Values[g][nPos][nCurrentSize].dMax = ptOut.v[(g+2)%3] - ptMapOrig.v[(g+2)%3] ; m_Values[g][nPos][nCurrentSize].vtMinN = vtInN ; m_Values[g][nPos][nCurrentSize].vtMaxN = vtOutN ; m_Values[g][nPos][nCurrentSize].nToolMin = 0 ; m_Values[g][nPos][nCurrentSize].nToolMax = 0 ; m_Values[g][nPos][nCurrentSize].nCompo = 0 ; bInside = false ; } } } } } } // Assegno il minimo e massimo valore di Z della mappa m_dMinZ[0] = 0 ; m_dMaxZ[0] = vtLen.z ; m_dMinZ[1] = 0 ; m_dMaxZ[1] = ( bTriDex ? vtLen.x : 0) ; m_dMinZ[2] = 0 ; m_dMaxZ[2] = ( bTriDex ? vtLen.y : 0) ; // Dimensiono e setto il vettore dei blocchi a da ricalcolare m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ; m_BlockToUpdate.clear() ; m_BlockToUpdate.resize( m_nNumBlock, true) ; // Dimensiono raccolta di voxel, triangoli di feature tra blocchi e di segnalatori di materiale fra voxel m_InterBlockVox.resize( m_nNumBlock) ; m_InterBlockTria.resize( m_nNumBlock) ; m_SliceXY.resize( m_nNumBlock) ; m_SliceXZ.resize( m_nNumBlock) ; m_SliceYZ.resize( m_nNumBlock) ; // Tipologia m_nShape = ( IsBox() ? BOX : EXTRUSION) ; // Aggiornamento dello stato m_nStatus = OK ; return true ; }