Files
EgtGeomKernel/VolTriZmapCreation.cpp
T
Dario Sassi 7ee899b0a2 EgtGeomKernel 1.6x2 :
- modifiche a Zmap per tridexel.
2016-12-19 14:35:10 +00:00

595 lines
19 KiB
C++

//----------------------------------------------------------------------------
// 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 "IntersLineSurfTm.h"
#include "\EgtDev\Include\EgtNumUtils.h"
using namespace std ;
// ------------------------- CREAZIONE MAPPA --------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool
VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec, bool bFlag)
{
// Controlli l'ammissibilità delle dimensioni lineari del grezzo e del passo
if ( dPrec < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
return false ;
// Aggiorno il passo
m_dStep = dPrec ;
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bFlag ? 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 i sistemi di riferimento
m_MapFrame[0].Set( ptO, X_AX, Y_AX, Z_AX) ;
// Definisco i vettori dei limiti su indici
m_nVNx[0] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nVNy[0] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
if ( m_nMapNum > 1) {
m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ;
m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ;
m_nVNx[1] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
m_nVNy[1] = static_cast <unsigned int> ( ceil( dLengthZ / m_dStep)) ;
m_nVNx[2] = static_cast <unsigned int> ( ceil( dLengthZ / m_dStep)) ;
m_nVNy[2] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
}
else {
m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ;
m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ;
m_nVNx[1] = 0 ;
m_nVNy[1] = 0 ;
m_nVNx[2] = 0 ;
m_nVNy[2] = 0 ;
}
// Definizione della mappa
// Creazione delle mappe
// Calcolo del numero di celle per ogni mappa
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
m_nVDim[i] = m_nVNx[i] * m_nVNy[i] ;
// Creazione delle celle per ogni mappa
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
m_TriZValues[i].resize( m_nVDim[i]) ;
// Riempimento delle celle
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) {
m_TriZValues[i][j].resize(2) ;
m_TriZValues[i][j][0] = 0 ;
if ( i == 0)
m_TriZValues[i][j][1] = dLengthZ ;
else if ( i == 1)
m_TriZValues[i][j][1] = dLengthX ;
else if ( i == 2)
m_TriZValues[i][j][1] = dLengthY ;
}
// Definizione delle limitazioni iniziali in Z per ogni mappa
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
m_dVMinZ[i] = 0 ;
if ( i == 0)
m_dVMaxZ[i] = dLengthZ ;
else if ( i == 1)
m_dVMaxZ[i] = dLengthX ;
else if ( i == 2)
m_dVMaxZ[i] = dLengthY ;
}
// Aggiornamento dello stato
m_nStatus = OK ;
return true ;
}
bool
VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec, bool bFlag)
{
Point3d ptMapOrig, ptMapEnd ;
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bFlag ? 3 : 1) ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dPrec, 100 * EPS_SMALL) ;
// 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_MapFrame[0].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_nVNx[0] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nVNy[0] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
m_nVDim[0] = m_nVNx[0] * m_nVNy[0] ;
// Ridimensiono il vettore di dexel e creo lo Zmap
m_TriZValues[0].resize( m_nVDim[0]) ;
// Se Tridexel ridimensiono anche gli altri vettori
if ( bFlag) {
m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
m_nVNx[1] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
m_nVNy[1] = static_cast <unsigned int> ( ceil( dDimZ / m_dStep)) ;
m_nVDim[1] = m_nVNx[1] * m_nVNy[1] ;
m_nVNx[2] = static_cast <unsigned int> ( ceil( dDimZ / m_dStep)) ;
m_nVNy[2] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nVDim[2] = m_nVNx[2] * m_nVNy[2] ;
m_TriZValues[1].resize( m_nVDim[1]) ;
m_TriZValues[2].resize( m_nVDim[2]) ;
}
else {
m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
m_nVNx[1] = 0 ;
m_nVNy[1] = 0 ;
m_nVDim[1] = 0 ;
m_nVNx[2] = 0 ;
m_nVNy[2] = 0 ;
m_nVDim[2] = 0 ;
}
// Determinazione e ridimensionamento dei dexel
// interni alla regione
// Griglia 0
for ( unsigned int i = 0 ; i < m_nVNx[0] ; ++ 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 ;
// Parametri iniziale e finale
double dt1 = IntersectionResults[k].dParS ;
double dt2 = IntersectionResults[k].dParE ;
// 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) {
// Indici corrispondenti alle coordinate dei punti
int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nVNy[0] - 1) ;
int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nVNy[0] - 1) ;
// Ridimensiono e riempio i dexel
for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
// Determino il dexel
int nPos0 = j * m_nVNx[0] + i ;
m_TriZValues[0][nPos0].resize( 2) ;
// Aggiorno le quote estreme del segmento
m_TriZValues[0][nPos0][0] = 0 ;
m_TriZValues[0][nPos0][1] = dDimZ ;
}
// Se tridexel riempio i singoli dexel della
// griglia 2 con gli intervalli
if ( bFlag) {
for ( size_t a = 0 ; a < m_nVNx[2] ; ++ a) {
size_t nPos2 = i * m_nVNx[2] + a ;
size_t nCurrentSize = m_TriZValues[2][nPos2].size( ) ;
m_TriZValues[2][nPos2].resize( nCurrentSize + 2) ;
m_TriZValues[2][nPos2][nCurrentSize] = dt1 * dLengthY ;
m_TriZValues[2][nPos2][nCurrentSize + 1] = dt2 * dLengthY ;
}
}
}
}
}
// Se tridexel resta la griglia 1
if ( bFlag) {
for ( unsigned int i = 0 ; i < m_nVNx[1] ; ++ i) {
// Definisco la retta da intersecare con la regione
double dX = ( i + 0.5) * m_dStep ;
Point3d ptP0 = ptMapOrig + Vector3d( 0, dX, 0) ;
CurveLine GridLine ;
GridLine.SetPVL( ptP0, X_AX, dLengthX) ;
// 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 ;
for ( size_t j = 0 ; j < m_nVNy[1] ; ++ j) {
size_t nPos1 = j * m_nVNx[1] + i ;
size_t nCurrentSize = m_TriZValues[1][nPos1].size( ) ;
m_TriZValues[1][nPos1].resize( nCurrentSize + 2) ;
m_TriZValues[1][nPos1][nCurrentSize] = dt1 * dLengthX ;
m_TriZValues[1][nPos1][nCurrentSize + 1] = dt2 * dLengthX ;
}
}
}
}
}
m_dVMinZ[0] = 0 ;
m_dVMaxZ[0] = dDimZ ;
if ( bFlag) {
m_dVMinZ[1] = 0 ;
m_dVMaxZ[1] = dLengthX ;
m_dVMinZ[2] = 0 ;
m_dVMaxZ[2] = dLengthY ;
}
else {
m_dVMinZ[1] = 0 ;
m_dVMaxZ[1] = 0 ;
m_dVMinZ[2] = 0 ;
m_dVMaxZ[2] = 0 ;
}
// Aggiornamento dello stato
m_nStatus = OK ;
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bFlag)
{
// Se la superficie non è chiusa non ha senso continuare
if ( ! Surf.IsClosed())
return false ;
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bFlag ? 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) ;
// Sistema di riferimento mappa
m_MapFrame[0].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 del BBox
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_nVNx[0] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nVNy[0] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
m_nVDim[0] = m_nVNx[0] * m_nVNy[0] ;
// Ridimensiono il vettore di dexel e creo lo Zmap
m_TriZValues[0].resize( m_nVDim[0]) ;
// Se Tridexel ridimensiono anche gli altri vettori
if ( bFlag) {
m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; // Sarà Front Left
m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
m_nVNx[1] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
m_nVNy[1] = static_cast <unsigned int> ( ceil( dLengthZ / m_dStep)) ;
m_nVDim[1] = m_nVNx[1] * m_nVNy[1] ;
m_nVNx[2] = static_cast <unsigned int> ( ceil( dLengthZ / m_dStep)) ;
m_nVNy[2] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
m_nVDim[2] = m_nVNx[2] * m_nVNy[2] ;
m_TriZValues[1].resize( m_nVDim[1]) ;
m_TriZValues[2].resize( m_nVDim[2]) ;
}
// Oggetto per calcolo massivo intersezioni
IntersParLinesSurfTm intPLSTM( m_MapFrame[0], Surf) ;
// Determinazione e ridimensionamento dei dexel interni alla trimesh
for ( unsigned int i = 0 ; i < m_nVNx[0] ; ++ i) {
for ( unsigned int j = 0 ; j < m_nVNy[0] ; ++ 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_nVNx[0] + 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_TriZValues[0][nPos].size()) ;
m_TriZValues[0][nPos].resize( nCurrentSize + 2) ;
m_TriZValues[0][nPos][nCurrentSize] = ptIn.z - ptMapOrig.z ;
m_TriZValues[0][nPos][nCurrentSize + 1] = ptOut.z - ptMapOrig.z ;
bInside = false ;
}
}
}
}
}
if ( bFlag) {
IntersParLinesSurfTm intPLSTM1( m_MapFrame[1], Surf) ;
// Determinazione e ridimensionamento dei dexel interni alla trimesh
for ( unsigned int i = 0 ; i < m_nVNx[1] ; ++ i) {
for ( unsigned int j = 0 ; j < m_nVNy[1] ; ++ 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 ;
intPLSTM1.GetInters( ptP0, dLengthX, IntersectionResults) ;
int nInt = int( IntersectionResults.size()) ;
unsigned int nPos = j * m_nVNx[1] + 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_TriZValues[1][nPos].size()) ;
m_TriZValues[1][nPos].resize( nCurrentSize + 2) ;
m_TriZValues[1][nPos][nCurrentSize] = ptIn.x - ptMapOrig.x ;
m_TriZValues[1][nPos][nCurrentSize + 1] = ptOut.x - ptMapOrig.x ;
bInside = false ;
}
}
}
}
}
IntersParLinesSurfTm intPLSTM2( m_MapFrame[2], Surf) ;
// Determinazione e ridimensionamento dei dexel interni alla trimesh
for ( unsigned int i = 0 ; i < m_nVNx[2] ; ++ i) {
for ( unsigned int j = 0 ; j < m_nVNy[2] ; ++ 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 ;
intPLSTM2.GetInters( ptP0, dLengthY, IntersectionResults) ;
int nInt = int( IntersectionResults.size()) ;
unsigned int nPos = j * m_nVNx[2] + 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_TriZValues[2][nPos].size()) ;
m_TriZValues[2][nPos].resize( nCurrentSize + 2) ;
m_TriZValues[2][nPos][nCurrentSize] = ptIn.y - ptMapOrig.y ;
m_TriZValues[2][nPos][nCurrentSize + 1] = ptOut.y - ptMapOrig.y ;
bInside = false ;
}
}
}
}
}
}
// Assegno il minimo e massimo valore di Z della mappa
m_dVMinZ[0] = 0 ;
m_dVMaxZ[0] = dLengthZ ;
if ( bFlag) {
m_dVMinZ[1] = 0 ;
m_dVMaxZ[1] = dLengthX ;
m_dVMinZ[2] = 0 ;
m_dVMaxZ[2] = dLengthY ;
}
else {
m_dVMinZ[1] = 0 ;
m_dVMaxZ[1] = 0 ;
m_dVMinZ[2] = 0 ;
m_dVMaxZ[2] = 0 ;
}
m_nStatus = OK ;
return true ;
}