Files
EgtGeomKernel/VolZmapCreation.cpp
T
Dario Sassi 52a09392c1 EgtGeomKernel 1.6w1 :
- modifiche e correzioni varie sugli Zmap.
2016-11-07 07:57:38 +00:00

258 lines
8.8 KiB
C++

//----------------------------------------------------------------------------
// 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 <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nNy = static_cast <unsigned int> ( 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 <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nNy = static_cast <unsigned int> ( 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 <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nNy = static_cast <unsigned int> ( 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 ;
}