0a98461e3e
- miglioramenti a Zmap (aggiunto blocco per triangoli di frontiera blocchi con possibilità di flip).
829 lines
29 KiB
C++
829 lines
29 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 ;
|
|
|
|
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
|
|
m_dStep = max( dPrec, 100 * EPS_SMALL) ;
|
|
|
|
// 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_nNx[0] = static_cast <unsigned int> ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[0] = static_cast <unsigned int> ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
// Definisco il numero di blocchi lungo x e y
|
|
unsigned int nMinBlockNum = 1 ;
|
|
|
|
m_nFracLin[0] = max( nMinBlockNum,
|
|
m_nNx[0] / m_nDexNumPBlock +
|
|
( m_nNx[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
m_nFracLin[1] = max( nMinBlockNum,
|
|
m_nNy[0] / m_nDexNumPBlock +
|
|
( m_nNy[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
|
|
if ( bFlag) {
|
|
|
|
m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ;
|
|
m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ;
|
|
|
|
m_nNx[1] = static_cast <unsigned int> ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[1] = static_cast <unsigned int> ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
m_nNx[2] = static_cast <unsigned int> ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[2] = static_cast <unsigned int> ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
// Definisco il numero di blocchi lungo z
|
|
m_nFracLin[2] = max( nMinBlockNum,
|
|
m_nNy[1] / m_nDexNumPBlock +
|
|
( m_nNy[1] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
}
|
|
else {
|
|
|
|
m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ;
|
|
m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ;
|
|
|
|
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) {
|
|
|
|
m_Values[i][j].resize(2) ;
|
|
|
|
m_Values[i][j][0].dZVal = 0 ;
|
|
|
|
switch ( i) {
|
|
case 0 :
|
|
m_Values[i][j][1].dZVal = dLengthZ ;
|
|
m_Values[i][j][0].vtN = Vector3d( 0, 0, - 1) ;
|
|
m_Values[i][j][1].vtN = Vector3d( 0, 0, 1) ;
|
|
break ;
|
|
case 1 :
|
|
m_Values[i][j][1].dZVal = dLengthX ;
|
|
m_Values[i][j][0].vtN = Vector3d( - 1, 0, 0) ;
|
|
m_Values[i][j][1].vtN = Vector3d( 1, 0, 0) ;
|
|
break ;
|
|
case 2 :
|
|
m_Values[i][j][1].dZVal = dLengthY ;
|
|
m_Values[i][j][0].vtN = Vector3d( 0, - 1, 0) ;
|
|
m_Values[i][j][1].vtN = Vector3d( 0, 1, 0) ;
|
|
break ;
|
|
}
|
|
}
|
|
|
|
// Definizione delle limitazioni iniziali in Z per ogni mappa
|
|
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
|
|
|
|
m_dMinZ[i] = 0 ;
|
|
|
|
if ( i == 0)
|
|
m_dMaxZ[i] = dLengthZ ;
|
|
else if ( i == 1)
|
|
m_dMaxZ[i] = dLengthX ;
|
|
else if ( i == 2)
|
|
m_dMaxZ[i] = dLengthY ;
|
|
}
|
|
|
|
// Ridimensiono e setto il vettore dei blocchi a falso
|
|
m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ;
|
|
|
|
m_BlockToUpdate.resize( m_nNumBlock) ;
|
|
|
|
for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount)
|
|
|
|
m_BlockToUpdate[nCount] = true ;
|
|
|
|
m_InterBlockTria.resize( m_nNumBlock) ;
|
|
|
|
// 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_nNx[0] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
|
|
//m_nNy[0] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
|
|
m_nNx[0] = static_cast <unsigned int> ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[0] = static_cast <unsigned int> ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
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]) ;
|
|
|
|
// Definisco il numero di blocchi lungo x e y
|
|
unsigned int nMinBlockNum = 1 ;
|
|
|
|
m_nFracLin[0] = max( nMinBlockNum,
|
|
m_nNx[0] / m_nDexNumPBlock +
|
|
( m_nNx[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
m_nFracLin[1] = max( nMinBlockNum,
|
|
m_nNy[0] / m_nDexNumPBlock +
|
|
( m_nNy[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 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_nNx[1] = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
|
|
//m_nNy[1] = static_cast <unsigned int> ( ceil( dDimZ / m_dStep)) ;
|
|
|
|
//m_nNx[2] = static_cast <unsigned int> ( ceil( dDimZ / m_dStep)) ;
|
|
//m_nNy[2] = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
|
|
|
|
m_nNx[1] = static_cast <unsigned int> ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[1] = static_cast <unsigned int> ( floor( ( dDimZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
m_nNx[2] = static_cast <unsigned int> ( floor( ( dDimZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[2] = static_cast <unsigned int> ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
m_nDim[1] = m_nNx[1] * m_nNy[1] ;
|
|
|
|
m_nDim[2] = m_nNx[2] * m_nNy[2] ;
|
|
|
|
m_Values[1].resize( m_nDim[1]) ;
|
|
m_Values[2].resize( m_nDim[2]) ;
|
|
|
|
// Definisco il numero di blocchi lungo z
|
|
m_nFracLin[2] = max( nMinBlockNum,
|
|
m_nNy[1] / m_nDexNumPBlock +
|
|
( m_nNy[1] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
}
|
|
else {
|
|
|
|
m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
|
|
m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
|
|
|
|
m_nNx[1] = 0 ;
|
|
m_nNy[1] = 0 ;
|
|
|
|
m_nDim[1] = 0 ;
|
|
|
|
m_nNx[2] = 0 ;
|
|
m_nNy[2] = 0 ;
|
|
|
|
m_nDim[2] = 0 ;
|
|
}
|
|
|
|
// Determinazione e ridimensionamento dei dexel
|
|
// interni alla regione
|
|
|
|
// Griglia 0
|
|
for ( unsigned int i = 0 ; i < m_nNx[0] ; ++ i) {
|
|
|
|
// Definisco la retta da intersecare con la regione
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; // CAMBIATO CON EPS
|
|
CurveLine GridLine ;
|
|
GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; // CAMBIATO CON EPS
|
|
|
|
// 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 - EPS_SMALL + 0.5)), 0, m_nNy[0] - 1) ; // CAMBIATO CON EPS
|
|
int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep + EPS_SMALL - 0.5)), 0, m_nNy[0] - 1) ; // CAMBIATO CON EPS
|
|
|
|
// Ridimensiono e riempio i dexel
|
|
for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
// Determino il dexel
|
|
int nPos0 = j * m_nNx[0] + i ;
|
|
|
|
m_Values[0][nPos0].resize( 2) ;
|
|
// Aggiorno le quote estreme del segmento
|
|
m_Values[0][nPos0][0].dZVal = 0 ;
|
|
m_Values[0][nPos0][1].dZVal = dDimZ ;
|
|
m_Values[0][nPos0][0].vtN = - Z_AX ;
|
|
m_Values[0][nPos0][1].vtN = Z_AX ;
|
|
}
|
|
|
|
// Se tridexel riempio i singoli dexel della
|
|
// griglia 2 con gli intervalli
|
|
if ( bFlag) {
|
|
|
|
for ( size_t a = 0 ; a < m_nNx[2] ; ++ a) {
|
|
|
|
size_t nPos2 = i * m_nNx[2] + a ;
|
|
|
|
size_t nCurrentSize = m_Values[2][nPos2].size( ) ;
|
|
|
|
m_Values[2][nPos2].resize( nCurrentSize + 2) ;
|
|
|
|
m_Values[2][nPos2][nCurrentSize].dZVal = dt1 * dLengthY ;
|
|
m_Values[2][nPos2][nCurrentSize + 1].dZVal = dt2 * dLengthY ;
|
|
|
|
Point3d ptP1 = ptP0 + dt1 * dLengthY * Y_AX ;//+ ( a + 0.5) * Z_AX ; // CAMBIATO CON EPS
|
|
Point3d ptP2 = ptP0 + dt2 * dLengthY * Y_AX ;//+ ( a + 0.5) * Z_AX ; // CAMBIATO CON EPS
|
|
|
|
int nChunkNum = Surf.GetChunkCount() ;
|
|
|
|
for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) {
|
|
|
|
int nLoopNum = Surf.GetLoopCount( nChunk) ;
|
|
|
|
for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) {
|
|
|
|
ICurve * pCurve = Surf.GetLoop( nChunk, nLoop) ;
|
|
|
|
if ( pCurve -> IsPointOn( ptP1)) {
|
|
|
|
double dP1 ;
|
|
Vector3d vtT1, vtN1 ;
|
|
|
|
pCurve -> GetParamAtPoint(ptP1, dP1) ;
|
|
pCurve -> GetPointTang( dP1, ICurve::FROM_MINUS, ptP1, vtT1) ;
|
|
|
|
vtN1 = vtT1 ^ Z_AX ;
|
|
|
|
m_Values[2][nPos2][nCurrentSize].vtN = vtN1 ;
|
|
|
|
}
|
|
|
|
if ( pCurve -> IsPointOn( ptP2)) {
|
|
|
|
double dP2 ;
|
|
Vector3d vtT2, vtN2 ;
|
|
|
|
pCurve -> GetParamAtPoint(ptP2, dP2) ;
|
|
pCurve -> GetPointTang( dP2, ICurve::FROM_MINUS, ptP1, vtT2) ;
|
|
|
|
vtN2 = vtT2 ^ Z_AX ;
|
|
|
|
m_Values[2][nPos2][nCurrentSize+1].vtN = vtN2 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Se tridexel resta la griglia 1
|
|
if ( bFlag) {
|
|
|
|
for ( unsigned int i = 0 ; i < m_nNx[1] ; ++ i) {
|
|
|
|
// Definisco la retta da intersecare con la regione
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
Point3d ptP0 = ptMapOrig + Vector3d( 0, dX, 0) ; ////// // CAMBIATO CON EPS
|
|
CurveLine GridLine ;
|
|
GridLine.SetPVL( ptP0, X_AX, dLengthX ) ; //// // CAMBIATO CON EPS
|
|
|
|
// 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_nNy[1] ; ++ j) {
|
|
|
|
size_t nPos1 = j * m_nNx[1] + i ;
|
|
|
|
size_t nCurrentSize = m_Values[1][nPos1].size( ) ;
|
|
|
|
m_Values[1][nPos1].resize( nCurrentSize + 2) ;
|
|
|
|
m_Values[1][nPos1][nCurrentSize].dZVal = dt1 * dLengthX ; // CAMBIATO CON EPS
|
|
m_Values[1][nPos1][nCurrentSize + 1].dZVal = dt2 * dLengthX ; // CAMBIATO CON EPS
|
|
|
|
Point3d ptP1 = ptP0 + dt1 * dLengthX * X_AX ; /// cAMBIO
|
|
Point3d ptP2 = ptP0 + dt2 * dLengthX * X_AX ; // CAMBIATO CON EPS
|
|
|
|
int nChunkNum = Surf.GetChunkCount() ;
|
|
|
|
for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) {
|
|
|
|
int nLoopNum = Surf.GetLoopCount( nChunk) ;
|
|
|
|
for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) {
|
|
|
|
ICurve * pCurve = Surf.GetLoop( nChunk, nLoop) ;
|
|
|
|
if ( pCurve -> IsPointOn( ptP1)) {
|
|
|
|
double dP1 ;
|
|
Vector3d vtT1, vtN1 ;
|
|
|
|
pCurve -> GetParamAtPoint(ptP1, dP1) ;
|
|
pCurve -> GetPointTang( dP1, ICurve::FROM_MINUS, ptP1, vtT1) ;
|
|
|
|
vtN1 = vtT1 ^ Z_AX ;
|
|
|
|
m_Values[1][nPos1][nCurrentSize].vtN = vtN1 ;
|
|
|
|
}
|
|
|
|
if ( pCurve -> IsPointOn( ptP2)) {
|
|
|
|
double dP2 ;
|
|
Vector3d vtT2, vtN2 ;
|
|
|
|
pCurve -> GetParamAtPoint(ptP2, dP2) ;
|
|
pCurve -> GetPointTang( dP2, ICurve::FROM_MINUS, ptP1, vtT2) ;
|
|
|
|
vtN2 = vtT2 ^ Z_AX ;
|
|
|
|
m_Values[1][nPos1][nCurrentSize+1].vtN = vtN2 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
m_dMinZ[0] = 0 ;
|
|
m_dMaxZ[0] = dDimZ ;
|
|
|
|
if ( bFlag) {
|
|
|
|
m_dMinZ[1] = 0 ;
|
|
m_dMaxZ[1] = dLengthX ;
|
|
m_dMinZ[2] = 0 ;
|
|
m_dMaxZ[2] = dLengthY ;
|
|
}
|
|
else {
|
|
|
|
m_dMinZ[1] = 0 ;
|
|
m_dMaxZ[1] = 0 ;
|
|
m_dMinZ[2] = 0 ;
|
|
m_dMaxZ[2] = 0 ;
|
|
}
|
|
|
|
// Ridimensiono e setto il vettore dei blocchi a falso
|
|
m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ;
|
|
|
|
m_BlockToUpdate.resize( m_nNumBlock) ;
|
|
|
|
for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount)
|
|
|
|
m_BlockToUpdate[nCount] = true ;
|
|
|
|
m_InterBlockTria.resize( m_nNumBlock) ;
|
|
|
|
// 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_nNx[0] = static_cast <unsigned int> ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[0] = static_cast <unsigned int> ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
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]) ;
|
|
|
|
// Definisco il numero di blocchi lungo x e y
|
|
unsigned int nMinBlockNum = 1 ;
|
|
|
|
m_nFracLin[0] = max( nMinBlockNum,
|
|
m_nNx[0] / m_nDexNumPBlock +
|
|
( m_nNx[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
m_nFracLin[1] = max( nMinBlockNum,
|
|
m_nNy[0] / m_nDexNumPBlock +
|
|
( m_nNy[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 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_nNx[1] = static_cast <unsigned int> ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[1] = static_cast <unsigned int> ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
m_nDim[1] = m_nNx[1] * m_nNy[1] ;
|
|
|
|
m_nNx[2] = static_cast <unsigned int> ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
m_nNy[2] = static_cast <unsigned int> ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ;
|
|
|
|
m_nDim[2] = m_nNx[2] * m_nNy[2] ;
|
|
|
|
m_Values[1].resize( m_nDim[1]) ;
|
|
m_Values[2].resize( m_nDim[2]) ;
|
|
|
|
// Definisco il numero di blocchi lungo z
|
|
m_nFracLin[2] = max( nMinBlockNum,
|
|
m_nNy[1] / m_nDexNumPBlock +
|
|
( m_nNy[1] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ;
|
|
}
|
|
|
|
|
|
// 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_nNx[0] ; ++ i) {
|
|
for ( unsigned int j = 0 ; j < m_nNy[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_nNx[0] + 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 ;
|
|
|
|
Vector3d vtOutN ;
|
|
|
|
int nT = IntersectionResults[k].nT ;
|
|
int nF = Surf.GetFacetFromTria( nT) ;
|
|
|
|
Surf.GetFacetNormal( nF, vtOutN) ;
|
|
|
|
unsigned int nCurrentSize = unsigned int( m_Values[0][nPos].size()) ;
|
|
|
|
m_Values[0][nPos].resize( nCurrentSize + 2) ;
|
|
|
|
m_Values[0][nPos][nCurrentSize].dZVal = ptIn.z - ptMapOrig.z ;
|
|
m_Values[0][nPos][nCurrentSize + 1].dZVal = ptOut.z - ptMapOrig.z ;
|
|
|
|
m_Values[0][nPos][nCurrentSize].vtN = vtInN ;
|
|
m_Values[0][nPos][nCurrentSize + 1].vtN = vtOutN ;
|
|
|
|
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_nNx[1] ; ++ i) {
|
|
for ( unsigned int j = 0 ; j < m_nNy[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_nNx[1] + 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 ;
|
|
|
|
Vector3d vtOutN ;
|
|
|
|
int nT = IntersectionResults[k].nT ;
|
|
int nF = Surf.GetFacetFromTria( nT) ;
|
|
|
|
Surf.GetFacetNormal( nF, vtOutN) ;
|
|
|
|
unsigned int nCurrentSize = unsigned int( m_Values[1][nPos].size()) ;
|
|
|
|
m_Values[1][nPos].resize( nCurrentSize + 2) ;
|
|
|
|
m_Values[1][nPos][nCurrentSize].dZVal = ptIn.x - ptMapOrig.x ;
|
|
m_Values[1][nPos][nCurrentSize + 1].dZVal = ptOut.x - ptMapOrig.x ;
|
|
|
|
m_Values[1][nPos][nCurrentSize].vtN = vtInN ;
|
|
m_Values[1][nPos][nCurrentSize + 1].vtN = vtOutN ;
|
|
|
|
bInside = false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IntersParLinesSurfTm intPLSTM2( m_MapFrame[2], Surf) ;
|
|
|
|
// Determinazione e ridimensionamento dei dexel interni alla trimesh
|
|
for ( unsigned int i = 0 ; i < m_nNx[2] ; ++ i) {
|
|
for ( unsigned int j = 0 ; j < m_nNy[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_nNx[2] + 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 ;
|
|
|
|
Vector3d vtOutN ;
|
|
|
|
int nT = IntersectionResults[k].nT ;
|
|
int nF = Surf.GetFacetFromTria( nT) ;
|
|
|
|
Surf.GetFacetNormal( nF, vtOutN) ;
|
|
|
|
unsigned int nCurrentSize = unsigned int( m_Values[2][nPos].size()) ;
|
|
|
|
m_Values[2][nPos].resize( nCurrentSize + 2) ;
|
|
|
|
m_Values[2][nPos][nCurrentSize].dZVal = ptIn.y - ptMapOrig.y ;
|
|
m_Values[2][nPos][nCurrentSize + 1].dZVal = ptOut.y - ptMapOrig.y ;
|
|
|
|
m_Values[2][nPos][nCurrentSize].vtN = vtInN ;
|
|
m_Values[2][nPos][nCurrentSize + 1].vtN = vtOutN ;
|
|
|
|
bInside = false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Assegno il minimo e massimo valore di Z della mappa
|
|
m_dMinZ[0] = 0 ;
|
|
m_dMaxZ[0] = dLengthZ ;
|
|
|
|
if ( bFlag) {
|
|
|
|
m_dMinZ[1] = 0 ;
|
|
m_dMaxZ[1] = dLengthX ;
|
|
m_dMinZ[2] = 0 ;
|
|
m_dMaxZ[2] = dLengthY ;
|
|
}
|
|
else {
|
|
|
|
m_dMinZ[1] = 0 ;
|
|
m_dMaxZ[1] = 0 ;
|
|
m_dMinZ[2] = 0 ;
|
|
m_dMaxZ[2] = 0 ;
|
|
}
|
|
|
|
// Ridimensiono e setto il vettore dei blocchi a falso
|
|
m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ;
|
|
|
|
m_BlockToUpdate.resize( m_nNumBlock) ;
|
|
|
|
for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount)
|
|
|
|
m_BlockToUpdate[nCount] = true ;
|
|
|
|
m_InterBlockTria.resize( m_nNumBlock) ;
|
|
|
|
m_nStatus = OK ;
|
|
|
|
return true ;
|
|
} |