//---------------------------------------------------------------------------- // 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 "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" #include "IntersLineSurfTm.h" #include "\EgtDev\Include\EgtNumUtils.h" using namespace std ; //---------- Creazione da parallelepipedo ------------------------------------ //---------------------------------------------------------------------------- bool VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec) { // Controlli sui parametri if ( dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) return false ; // Definisco il sistema di riferimento in trinseco dello Zmap m_LocalFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dPrec, 100 * EPS_SMALL) ; // 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 = static_cast ( ceil( dLengthX / m_dStep)) ; m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; m_nDim = m_nNx * m_nNy ; // Ridimensiono il vettore di dexel e creo lo Zmap m_ZValues.resize( m_nDim) ; for ( int i = 0 ; i < int( m_nDim) ; i++) { m_ZValues[i].resize(2) ; m_ZValues[i][0] = 0 ; m_ZValues[i][1] = dLengthZ ; } // Assegno il minimo e massimo valore di Z della mappa m_dMinZ = 0 ; m_dMaxZ = dLengthZ ; m_nStatus = OK ; return true ; } //---------- Creazione da flat region ---------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dLengthZ, double dPrec) { Point3d ptMapOrig, ptMapEnd ; // Determino il bounding box della flat region BBox3d SurfBBox ; Surf.GetLocalBBox( SurfBBox, BBF_EXACT) ; // Determino i punti estremi del bounding box SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; // Sistema di riferimento mappa m_LocalFrame.Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dPrec, 100 * EPS_SMALL) ; // 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 = static_cast ( ceil( dLengthX / m_dStep)) ; m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; m_nDim = m_nNx * m_nNy ; // Ridimensiono il vettore di dexel e creo lo Zmap m_ZValues.resize( m_nDim) ; // Determinazione e ridimensionamento dei dexel // interni alla regione for ( unsigned int i = 0 ; i < m_nNx ; ++ i) { // Definisco la retta 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) ; // Parti di cui la retta analizzata è composta int nPart = int( IntersectionResults.size()) ; // Analizzo le parti for ( int k = 0 ; k < nPart ; ++ k) { // Tipo di curva int nType = IntersectionResults[k].nClass ; // Se la retta è interna alla regione o coincidente con parte della sua frontiera if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { // Parametri iniziale e finale double dt1 = IntersectionResults[k].dParS ; double dt2 = IntersectionResults[k].dParE ; // Indici corrispondenti alle coordinate dei punti int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nNy - 1) ; int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nNy - 1) ; // Ridimensiono e riempio i dexel for ( int j = nStartJ ; j <= nEndJ ; ++ j) { // Determino il dexel int nPos = j * m_nNx + i ; m_ZValues[nPos].resize( 2) ; // Aggiorno le quote estreme del segmento m_ZValues[nPos][0] = 0 ; m_ZValues[nPos][1] = dLengthZ ; } } } } // Assegno il minimo e massimo valore di Z della mappa m_dMinZ = 0 ; m_dMaxZ = dLengthZ ; m_nStatus = OK ; return true ; } //---------- Creazione da trimesh -------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec) { // Se la superficie non è chiusa non ha senso continuare if ( ! Surf.IsClosed()) return false ; // 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) ; // Sistema di riferimento mappa m_LocalFrame.Set( ptMapOrig, Frame3d::TOP) ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dPrec, 100 * EPS_SMALL) ; // Determino le dimensioni lineari X Y della griglia double dLengthX = ptMapEnd.x - ptMapOrig.x ; double dLengthY = ptMapEnd.y - ptMapOrig.y ; double dLengthZ = ptMapEnd.z - ptMapOrig.z ; // 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 = static_cast ( ceil( dLengthX / m_dStep)) ; m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; m_nDim = m_nNx * m_nNy ; // Ridimensiono il vettore di dexel e creo lo Zmap m_ZValues.resize( m_nDim) ; // Oggetto per calcolo massivo intersezioni IntersParLinesSurfTm intPLSTM( m_LocalFrame, Surf) ; // Determinazione e ridimensionamento dei dexel interni alla trimesh for ( unsigned int i = 0 ; i < m_nNx ; ++ i) { for ( unsigned int j = 0 ; j < m_nNy ; ++ 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, dLengthZ, IntersectionResults) ; int nInt = int( IntersectionResults.size()) ; unsigned int nPos = j * m_nNx + i ; bool bInside = false ; Point3d ptIn ; 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 ; bInside = true ; } // esco dalla superficie trimesh else if ( dCos > EPS_SMALL && bInside) { Point3d ptOut = IntersectionResults[k].ptI ; unsigned int nCurrentSize = unsigned int( m_ZValues[nPos].size()) ; m_ZValues[nPos].resize( nCurrentSize + 2) ; m_ZValues[nPos][nCurrentSize] = ptIn.z - ptMapOrig.z ; m_ZValues[nPos][nCurrentSize + 1] = ptOut.z - ptMapOrig.z ; bInside = false ; } } } } } // Assegno il minimo e massimo valore di Z della mappa m_dMinZ = 0 ; m_dMaxZ = dLengthZ ; m_nStatus = OK ; return true ; }