4252497bb3
- miglioramenti a Zmap.
1145 lines
44 KiB
C++
1145 lines
44 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 "VolZmap.h"
|
|
#include "GeoObjFactory.h"
|
|
#include "NgeWriter.h"
|
|
#include "NgeReader.h"
|
|
#include "GeoConst.h"
|
|
#include "/EgtDev/Include/EGkUiUnits.h"
|
|
#include "/EgtDev/Include/EGkIntervals.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap::VolZmap(void)
|
|
: m_nStatus( TO_VERIFY), m_dStep( EPS_SMALL), m_nTempProp( 0), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG),
|
|
m_nVoxNumPerBlock( N_VOXBLOCK)
|
|
{
|
|
m_nMapNum = 0 ;
|
|
m_nNumBlock = 0 ;
|
|
m_nConnectedCompoCount = 0 ;
|
|
for ( int i = 0 ; i < N_MAPS ; ++ i) {
|
|
m_nNx[i] = 0 ;
|
|
m_nNy[i] = 0 ;
|
|
m_nDim[i] = 0 ;
|
|
m_dMinZ[i] = 0 ;
|
|
m_dMaxZ[i] = 0 ;
|
|
m_nFracLin[i] = 0 ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap::~VolZmap( void)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Clear( void)
|
|
{
|
|
m_nStatus = TO_VERIFY ;
|
|
m_nMapNum = 0 ;
|
|
m_nNumBlock = 0 ;
|
|
m_nConnectedCompoCount = 0 ;
|
|
m_MapFrame.Reset() ;
|
|
for ( int i = 0 ; i < N_MAPS ; ++ i) {
|
|
m_nNx[i] = 0 ;
|
|
m_nNy[i] = 0 ;
|
|
m_nDim[i] = 0 ;
|
|
m_dMinZ[i] = 0 ;
|
|
m_dMaxZ[i] = 0 ;
|
|
m_Values[i].clear() ;
|
|
}
|
|
m_dStep = EPS_SMALL ;
|
|
m_dLinTol = LIN_TOL_STD ;
|
|
m_dAngTolDeg = ANG_TOL_APPROX_DEG;
|
|
|
|
m_nTempProp = 0 ;
|
|
|
|
// imposto ricalcolo della grafica
|
|
m_OGrMgr.Reset() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap*
|
|
VolZmap::Clone( void) const
|
|
{
|
|
// alloco oggetto
|
|
VolZmap* pVzm = new(nothrow) VolZmap ;
|
|
if ( pVzm != nullptr) {
|
|
if ( ! pVzm->CopyFrom( *this)) {
|
|
delete pVzm ;
|
|
return nullptr ;
|
|
}
|
|
}
|
|
|
|
return pVzm ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CopyFrom( const IGeoObj* pGObjSrc)
|
|
{
|
|
const VolZmap* pVzm = dynamic_cast<const VolZmap*>( pGObjSrc) ;
|
|
if ( pVzm == nullptr)
|
|
return false ;
|
|
return CopyFrom( *pVzm) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CopyFrom( const VolZmap& vzmSrc)
|
|
{
|
|
if ( &vzmSrc == this)
|
|
return true ;
|
|
|
|
m_nMapNum = vzmSrc.m_nMapNum ;
|
|
m_nNumBlock = vzmSrc.m_nNumBlock ;
|
|
m_nVoxNumPerBlock = vzmSrc.m_nVoxNumPerBlock ;
|
|
m_nFracLin[0] = vzmSrc.m_nFracLin[0] ;
|
|
m_nFracLin[1] = vzmSrc.m_nFracLin[1] ;
|
|
m_nFracLin[2] = vzmSrc.m_nFracLin[2] ;
|
|
m_nConnectedCompoCount = vzmSrc.m_nConnectedCompoCount ;
|
|
|
|
m_MapFrame = vzmSrc.m_MapFrame ;
|
|
|
|
for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
|
|
|
|
m_nNx[i] = vzmSrc.m_nNx[i] ;
|
|
m_nNy[i] = vzmSrc.m_nNy[i] ;
|
|
m_nDim[i] = vzmSrc.m_nDim[i] ;
|
|
|
|
m_dMinZ[i] = vzmSrc.m_dMinZ[i] ;
|
|
m_dMaxZ[i] = vzmSrc.m_dMaxZ[i] ;
|
|
|
|
m_Values[i] = vzmSrc.m_Values[i] ;
|
|
}
|
|
|
|
m_dStep = vzmSrc.m_dStep ;
|
|
m_nStatus = vzmSrc.m_nStatus ;
|
|
m_nTempProp = vzmSrc.m_nTempProp ;
|
|
|
|
// dimensiono membri legati ai blocchi
|
|
m_BlockToUpdate.resize( m_nNumBlock) ;
|
|
m_InterBlockTria.resize( m_nNumBlock) ;
|
|
|
|
// imposto ricalcolo grafica
|
|
ResetGraphics() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ResetGraphics( void)
|
|
{
|
|
m_OGrMgr.Reset() ;
|
|
for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount)
|
|
m_BlockToUpdate[nCount] = true ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeoObjType
|
|
VolZmap::GetType( void) const
|
|
{
|
|
return static_cast<GeoObjType>( GEOOBJ_GETTYPE( VolZmap)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
VolZmap::GetTitle( void) const
|
|
{
|
|
static const string sTitle = "VolZm" ;
|
|
return sTitle ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
|
{
|
|
// tipo
|
|
sOut += "Type=" + string( m_nMapNum == 1 ? "dexel" : "tridexel") + szNewLine ;
|
|
// passo
|
|
sOut += "Step=" + ToString( GetInUiUnits( m_dStep, bMM), 3) + szNewLine ;
|
|
// dimensioni
|
|
if ( m_nMapNum == 1)
|
|
sOut += "Dim=" + ToString( m_nDim[0]) +
|
|
"(" + ToString( m_nNx[0]) + "x" + ToString( m_nNy[0]) + ")" + szNewLine ;
|
|
else {
|
|
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
|
|
sOut += "Dim" + ToString( i+1) + "=" + ToString( m_nDim[i]) +
|
|
"(" + ToString( m_nNx[i]) + "x" + ToString( m_nNy[i]) + ")" + szNewLine ;
|
|
}
|
|
// numero di blocchi
|
|
sOut += "Blocks=" + ToString( m_nNumBlock) + " (" + ToString( m_nFracLin[0]) + "x" +
|
|
ToString( m_nFracLin[1]) + "x" + ToString( m_nFracLin[2]) + ")" + szNewLine ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
VolZmap::GetNgeId( void) const
|
|
{
|
|
return GEOOBJ_GETNGEID( VolZmap) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Save( NgeWriter& ngeOut) const
|
|
{
|
|
// numero di mappe
|
|
if ( ! ngeOut.WriteInt( m_nMapNum, ",", false))
|
|
return false ;
|
|
// numero di blocchi
|
|
if ( ! ngeOut.WriteInt( m_nNumBlock, ",", false))
|
|
return false ;
|
|
// numero di dexel per blocco
|
|
if ( ! ngeOut.WriteInt( m_nVoxNumPerBlock, ",", false))
|
|
return false ;
|
|
// numero di blocchi per ogni asse
|
|
for ( int i = 0 ; i < 3 ; ++ i) {
|
|
if ( ! ngeOut.WriteInt( m_nFracLin[i], ",", false))
|
|
return false ;
|
|
}
|
|
// numero di componenti connesse
|
|
if ( ! ngeOut.WriteInt( m_nConnectedCompoCount, ",", false))
|
|
return false ;
|
|
// passo di campionamento (distanza tra spilloni)
|
|
if ( ! ngeOut.WriteDouble( m_dStep, ";", true))
|
|
return false ;
|
|
// sistema di riferimento
|
|
if ( ! ngeOut.WriteFrame( m_MapFrame, ";", true))
|
|
return false ;
|
|
// per ogni mappa : numero di passi in X e Y e quote z estremali
|
|
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
|
|
if ( ! ngeOut.WriteInt( m_nNx[i], ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_nNy[i], ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_dMinZ[i], ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_dMaxZ[i], ";", true))
|
|
return false ;
|
|
}
|
|
// ciclo sulle mappe
|
|
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
|
|
// ciclo sui dexel
|
|
for ( unsigned int j = 0 ; j < m_nDim[i] ; ++ j) {
|
|
// numero di estremi
|
|
unsigned int nDim = unsigned int( m_Values[i][j].size()) ;
|
|
if ( ! ngeOut.WriteInt( nDim, ":", false))
|
|
return false ;
|
|
// se dexel nullo
|
|
if ( nDim == 0) {
|
|
// scrivo un valore dummy
|
|
if ( ! ngeOut.WriteDouble( 0, ";", true))
|
|
return false ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
for ( unsigned int k = 0 ; k < nDim ; ++ k) {
|
|
if ( ! ngeOut.WriteDouble( m_Values[i][j][k].dMin, ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_Values[i][j][k].nToolMin, ";", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteVector( m_Values[i][j][k].vtMinN, ";", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_Values[i][j][k].dMax, ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_Values[i][j][k].nToolMax, ";", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteVector( m_Values[i][j][k].vtMaxN, ";", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_Values[i][j][k].nCompo, ";", true))
|
|
return false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Load( NgeReader& ngeIn)
|
|
{
|
|
Clear() ;
|
|
// numero di mappe
|
|
if ( ! ngeIn.ReadInt( m_nMapNum, ",", false))
|
|
return false ;
|
|
// numero di blocchi
|
|
if ( ! ngeIn.ReadInt( m_nNumBlock, ",", false))
|
|
return false ;
|
|
// numero di dexel per blocco
|
|
if ( ! ngeIn.ReadInt( m_nVoxNumPerBlock, ",", false))
|
|
return false ;
|
|
// numero di blocchi per ogni asse
|
|
for ( int i = 0 ; i < 3 ; ++ i) {
|
|
if ( ! ngeIn.ReadInt( m_nFracLin[i], ",", false))
|
|
return false ;
|
|
}
|
|
// numero di componenti connesse
|
|
if ( ! ngeIn.ReadInt( m_nConnectedCompoCount, ",", false))
|
|
return false ;
|
|
// passo di campionamento (distanza tra spilloni)
|
|
if ( ! ngeIn.ReadDouble( m_dStep, ";", true))
|
|
return false ;
|
|
// sistema di riferimento
|
|
if ( ! ngeIn.ReadFrame( m_MapFrame, ";", true))
|
|
return false ;
|
|
// per ogni mappa : numero di passi in X e Y e quote z estremali
|
|
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
|
|
if ( ! ngeIn.ReadInt( m_nNx[i], ",", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadInt( m_nNy[i], ",", false))
|
|
return false ;
|
|
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
|
|
if ( ! ngeIn.ReadDouble( m_dMinZ[i], ",", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadDouble( m_dMaxZ[i], ";", true))
|
|
return false ;
|
|
}
|
|
// ciclo sulle mappe
|
|
for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
|
|
// dimensiono i vettori
|
|
m_Values[i].resize( m_nDim[i]) ;
|
|
// ciclo sui dexel
|
|
for ( unsigned int j = 0 ; j < m_nDim[i] ; ++ j) {
|
|
// leggo il numero di estremi nel dexel
|
|
unsigned int nDim ;
|
|
if ( ! ngeIn.ReadInt( nDim, ":", false))
|
|
return false ;
|
|
// se dexel nullo
|
|
if ( nDim == 0) {
|
|
// leggo un valore dummy
|
|
double dDummy ;
|
|
if ( ! ngeIn.ReadDouble( dDummy, ";", true))
|
|
return false ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
// dimensiono l'array
|
|
m_Values[i][j].resize( nDim) ;
|
|
// leggo i valori
|
|
for ( unsigned int k = 0 ; k < nDim ; ++ k) {
|
|
if ( ! ngeIn.ReadDouble( m_Values[i][j][k].dMin, ",", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadInt( m_Values[i][j][k].nToolMin, ";", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadVector( m_Values[i][j][k].vtMinN, ";", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadDouble( m_Values[i][j][k].dMax, ",", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadInt( m_Values[i][j][k].nToolMax, ";", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadVector( m_Values[i][j][k].vtMaxN, ";", false))
|
|
return false ;
|
|
if ( ! ngeIn.ReadInt( m_Values[i][j][k].nCompo, ";", true))
|
|
return false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// imposto aggiornamento obbligatorio su tutti i blocchi
|
|
m_BlockToUpdate.resize( m_nNumBlock) ;
|
|
for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount)
|
|
m_BlockToUpdate[nCount] = true ;
|
|
|
|
// per triangoli di feature di frontiera tra blocchi
|
|
m_InterBlockTria.resize( m_nNumBlock) ;
|
|
|
|
m_nStatus = OK ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// reset box
|
|
b3Loc.Reset() ;
|
|
// se richiesto approssimato
|
|
if ( ( nFlag & BBF_EXACT) == 0) {
|
|
b3Loc.Add( ORIG) ;
|
|
b3Loc.Add( Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
|
|
b3Loc.ToGlob( m_MapFrame) ;
|
|
return true ;
|
|
}
|
|
// calcolo preciso
|
|
// ciclo sui dexel (punti in basso con ciclo aggiunto per punti in alto di ultima riga)
|
|
double dY = 0 ;
|
|
for ( size_t j = 0 ; j <= m_nNy[0] ; ++ j) {
|
|
size_t jc = ( ( j != m_nNy[0]) ? j : m_nNy[0] - 1) ;
|
|
double dX = 0 ;
|
|
// punto a sinistra di ogni dexel (aggiungo un ciclo per fare punto a destra di ultimo)
|
|
for ( size_t i = 0 ; i <= m_nNx[0] ; ++ i) {
|
|
size_t ic = ( ( i != m_nNx[0]) ? i : m_nNx[0] - 1) ;
|
|
size_t nPos = ic + jc * m_nNx[0] ;
|
|
if ( m_Values[0][nPos].size() > 0) {
|
|
Point3d ptP = m_MapFrame.Orig() + dX * m_MapFrame.VersX() + dY * m_MapFrame.VersY() ;
|
|
b3Loc.Add( ptP + m_Values[0][nPos][0].dMin * m_MapFrame.VersZ()) ;
|
|
b3Loc.Add( ptP + m_Values[0][nPos][m_Values[0][nPos].size()-1].dMax * m_MapFrame.VersZ()) ;
|
|
}
|
|
// passo al punto successivo
|
|
dX += m_dStep ;
|
|
}
|
|
// passo alla riga successiva
|
|
dY += m_dStep ;
|
|
}
|
|
//
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// reset box
|
|
b3Ref.Reset() ;
|
|
// trasformo il riferimento locale tramite quello passato
|
|
Frame3d frUse = m_MapFrame ;
|
|
frUse.ToGlob( frRef) ;
|
|
// se richiesto approssimato
|
|
if ( ( nFlag & BBF_EXACT) == 0) {
|
|
b3Ref.Add( ORIG) ;
|
|
b3Ref.Add( Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
|
|
b3Ref.ToGlob( frUse) ;
|
|
return true ;
|
|
}
|
|
// calcolo preciso
|
|
// ciclo sui dexel (punti in basso con ciclo aggiunto per punti in alto di ultima riga)
|
|
double dY = 0 ;
|
|
for ( size_t j = 0 ; j <= m_nNy[0] ; ++ j) {
|
|
size_t jc = ( ( j != m_nNy[0]) ? j : m_nNy[0] -1) ;
|
|
double dX = 0 ;
|
|
// punto a sinistra di ogni dexel (aggiungo un ciclo per fare punto a destra di ultimo)
|
|
for ( size_t i = 0 ; i <= m_nNx[0] ; ++ i) {
|
|
size_t ic = ( ( i != m_nNx[0]) ? i : m_nNx[0] -1) ;
|
|
size_t nPos = ic + jc * m_nNx[0] ;
|
|
if ( m_Values[0][nPos].size() > 0) {
|
|
Point3d ptP = frUse.Orig() + dX * frUse.VersX() + dY * frUse.VersY() ;
|
|
b3Ref.Add( ptP + m_Values[0][nPos][0].dMin * frUse.VersZ()) ;
|
|
b3Ref.Add( ptP + m_Values[0][nPos][m_Values[0][nPos].size()-1].dMax * frUse.VersZ()) ;
|
|
}
|
|
// passo al punto successivo
|
|
dX += m_dStep ;
|
|
}
|
|
// passo alla riga successiva
|
|
dY += m_dStep ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Translate( const Vector3d& vtMove)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
ResetGraphics() ;
|
|
// traslo il riferimento
|
|
m_MapFrame.Translate( vtMove) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
ResetGraphics() ;
|
|
// ruoto il riferimento
|
|
m_MapFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ToGlob( const Frame3d& frRef)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
ResetGraphics() ;
|
|
// trasformo il riferimento
|
|
m_MapFrame.ToGlob( frRef) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ToLoc( const Frame3d& frRef)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
ResetGraphics() ;
|
|
// trasformo il riferimento
|
|
m_MapFrame.ToLoc( frRef) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
ResetGraphics() ;
|
|
// trasformo il riferimento
|
|
m_MapFrame.LocToLoc( frOri, frDest) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
VolZmap::GetPartCount( void) const
|
|
{
|
|
// Se mono-dexel la connessione � incalcolabile.
|
|
if ( m_nMapNum == 1)
|
|
return - 1 ;
|
|
// Se il numero delle componenti � indefinito
|
|
// lo ricalcolo e restituisco il risultato.
|
|
if ( m_nConnectedCompoCount == - 1) {
|
|
const_cast<VolZmap*>(this)->CheckMapConnection() ;
|
|
return m_nConnectedCompoCount ;
|
|
}
|
|
// Altrimenti restituisco direttamente il numero di componenti.
|
|
else
|
|
return m_nConnectedCompoCount ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CheckMapConnection( void)
|
|
{
|
|
// Imposto il numero di componenti connesse a 0
|
|
m_nConnectedCompoCount = 0 ;
|
|
// Imposto a 0 tutti il valore del numero della componente
|
|
// connessa di ciascun tratto di ciascun dexel.
|
|
for ( size_t tMap = 0 ; tMap < m_nMapNum ; ++ tMap) {
|
|
for ( size_t tDex = 0 ; tDex < m_nDim[tMap] ; ++ tDex) {
|
|
for ( size_t tInt = 0 ; tInt < m_Values[tMap][tDex].size() ; ++ tInt) {
|
|
|
|
m_Values[tMap][tDex][tInt].nCompo = 0 ;
|
|
// Controlli sui tratti di dexel non incidenti su nodi del reticolo
|
|
if ( tMap == 0) {
|
|
// Z degli estremi del segmento
|
|
double dZMin = m_Values[tMap][tDex][tInt].dMin ;
|
|
double dZMax = m_Values[tMap][tDex][tInt].dMax ;
|
|
// Indici k dei voxels in cui cadono le Z
|
|
int nKmin = int( floor( ( dZMin - EPS_SMALL) / m_dStep - 0.5)) ;
|
|
int nKmax = int( floor( ( dZMax + EPS_SMALL) / m_dStep - 0.5)) ;
|
|
// Se cadono nello stesso voxel imposto a -1 il valore della componente connessa
|
|
if ( nKmax - nKmin == 0)
|
|
m_Values[tMap][tDex][tInt].nCompo = -1 ;
|
|
}
|
|
else if ( tMap == 1) {
|
|
// X degli estremi del segmento
|
|
double dXMin = m_Values[tMap][tDex][tInt].dMin ;
|
|
double dXMax = m_Values[tMap][tDex][tInt].dMax ;
|
|
// Indici i dei voxels in cui cadono le X
|
|
int nImin = int( floor( ( dXMin - EPS_SMALL) / m_dStep - 0.5)) ;
|
|
int nImax = int( floor( ( dXMax + EPS_SMALL) / m_dStep - 0.5)) ;
|
|
// Se cadono nello stesso voxel imposto a -1 il valore della componente connessa
|
|
if ( nImax - nImin == 0)
|
|
m_Values[tMap][tDex][tInt].nCompo = -1 ;
|
|
}
|
|
else {
|
|
// Y degli estremi del segmento
|
|
double dYMin = m_Values[tMap][tDex][tInt].dMin ;
|
|
double dYMax = m_Values[tMap][tDex][tInt].dMax ;
|
|
// Indici j dei voxels in cui cadono le X
|
|
int nJmin = int( floor( ( dYMin - EPS_SMALL) / m_dStep - 0.5)) ;
|
|
int nJmax = int( floor( ( dYMax + EPS_SMALL) / m_dStep - 0.5)) ;
|
|
// Se cadono nello stesso voxel imposto a -1 il valore della componente connessa
|
|
if ( nJmax - nJmin == 0)
|
|
m_Values[tMap][tDex][tInt].nCompo = -1 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ciclo sui dexel lungo Z
|
|
for ( size_t tI = 0 ; tI < m_nNx[0] ; ++ tI) {
|
|
for ( size_t tJ = 0 ; tJ < m_nNy[0] ; ++ tJ) {
|
|
// Numero del dexel lungo Z
|
|
size_t tDexZ = tJ * m_nNx[0] + tI ;
|
|
// Numero di intervalli nel dexel
|
|
size_t tStopIntZ = m_Values[0][tDexZ].size() ;
|
|
// Ciclo sugli intervalli del dexel
|
|
for ( size_t tIntZ = 0 ; tIntZ < tStopIntZ ; ++ tIntZ) {
|
|
|
|
if ( m_Values[0][tDexZ][tIntZ].nCompo == 0) {
|
|
++ m_nConnectedCompoCount ;
|
|
m_Values[0][tDexZ][tIntZ].nCompo = m_nConnectedCompoCount ;
|
|
// Espando in tutta la componente
|
|
// Segmento corrente
|
|
IntervalIndexes NewInt ;
|
|
NewInt.tMap = 0 ;
|
|
NewInt.tDex = tJ * m_nNx[0] + tI ;
|
|
NewInt.tInt = tIntZ ;
|
|
// Stack di segmenti
|
|
IntContaier IntervalsToProcess ;
|
|
// Aggiungo il segmento corrente
|
|
IntervalsToProcess.push( NewInt) ;
|
|
|
|
// Processo gli intervalli trovati
|
|
while ( ! IntervalsToProcess.empty()) {
|
|
|
|
switch ( IntervalsToProcess.top().tMap) {
|
|
case 0 :
|
|
ExpandFromZInterval( IntervalsToProcess) ;
|
|
break ;
|
|
case 1 :
|
|
ExpandFromXInterval( IntervalsToProcess) ;
|
|
break ;
|
|
case 2 :
|
|
ExpandFromYInterval( IntervalsToProcess) ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
// Se l'intervallo non attraversa un nodo o ha gi�
|
|
// un indice assegnato salto questa iterazione.
|
|
else
|
|
continue ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ExpandFromXInterval( IntContaier& IntCont)
|
|
{
|
|
// Copio i dati dell'intervallo corrente
|
|
IntervalIndexes CurrInterval = IntCont.top() ;
|
|
IntCont.pop() ;
|
|
size_t tDex = CurrInterval.tDex ;
|
|
size_t tGrIndex1 = CurrInterval.tDex % m_nNx[1] ;
|
|
size_t tGrIndex2 = CurrInterval.tDex / m_nNx[1] ;
|
|
size_t tInt = CurrInterval.tInt ;
|
|
// Quote estreme del segmento lungo X
|
|
double dMinX = m_Values[1][tDex][tInt].dMin ;
|
|
double dMaxX = m_Values[1][tDex][tInt].dMax ;
|
|
double dMinDX = max( floor( ( dMinX - EPS_SMALL) / m_dStep - 0.5), 0.) ;
|
|
double dMaxDX = max( floor( ( dMaxX + EPS_SMALL) / m_dStep - 0.5), 0.) ;
|
|
// Indici estremi dei dei dexel ortogonali
|
|
// che possono intersecare il segmento di partenza
|
|
size_t tStartI = min( size_t( dMinDX), size_t( m_nNx[0] - 1)) ;
|
|
size_t tStopI = min( size_t( dMaxDX), size_t( m_nNx[0] - 1)) ;
|
|
// Posizione YZ del dexel
|
|
double dY = ( tGrIndex1 + 0.5) * m_dStep ;
|
|
double dZ = ( tGrIndex2 + 0.5) * m_dStep ;
|
|
// Ciclo sugli indici dei dexel che potrebbero
|
|
// intersecare il segmento di partenza
|
|
for ( size_t tI = tStartI ; tI <= tStopI ; ++ tI) {
|
|
// Analizzo i dexel della griglia 0.
|
|
size_t tStopZ = m_Values[0][tGrIndex1 * m_nNx[0] + tI].size() ;
|
|
for ( size_t tIntZ = 0 ; tIntZ < tStopZ ; ++ tIntZ) {
|
|
// Estremi del dexel lunog Z
|
|
double dZmin = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMin ;
|
|
double dZmax = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMax ;
|
|
// Se i segmenti si incrociano e il nuovo trovato non
|
|
// ha gi� un indice assegnato, assegno l'indice e
|
|
// aggiungo l'intervallo trovato allo stack.
|
|
if ( dZmin - EPS_SMALL < dZ &&
|
|
dZmax + EPS_SMALL > dZ &&
|
|
m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].nCompo == 0) {
|
|
m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].nCompo = m_Values[1][tDex][tInt].nCompo ;
|
|
IntervalIndexes NewInterval ;
|
|
NewInterval.tMap = 0 ;
|
|
NewInterval.tDex = tGrIndex1 * m_nNx[0] + tI ;
|
|
NewInterval.tInt = tIntZ ;
|
|
IntCont.push( NewInterval) ;
|
|
}
|
|
}
|
|
// Analizzo i dexel della griglia 2
|
|
size_t tStopY = m_Values[2][tI * m_nNx[2] + tGrIndex2].size() ;
|
|
for ( size_t tIntY = 0 ; tIntY < tStopY ; ++ tIntY) {
|
|
// Estremi del segmento del dexel lungo Y
|
|
double dYmin = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMin ;
|
|
double dYmax = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMax ;
|
|
// Se i segmenti si incrociano e il nuovo trovato non
|
|
// ha gi� un indice assegnato, assegno l'indice e
|
|
// aggiungo l'intervallo trovato allo stack.
|
|
if ( dYmin - EPS_SMALL < dY &&
|
|
dYmax + EPS_SMALL > dY &&
|
|
m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].nCompo == 0) {
|
|
m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].nCompo = m_Values[1][tDex][tInt].nCompo ;
|
|
IntervalIndexes NewInterval ;
|
|
NewInterval.tMap = 2 ;
|
|
NewInterval.tDex = tI * m_nNx[2] + tGrIndex2 ;
|
|
NewInterval.tInt = tIntY ;
|
|
IntCont.push( NewInterval) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ExpandFromYInterval( IntContaier& IntCont)
|
|
{
|
|
// Copio i dati dell'intervallo corrente
|
|
IntervalIndexes CurrInterval = IntCont.top() ;
|
|
IntCont.pop() ;
|
|
size_t tDex = CurrInterval.tDex ;
|
|
size_t tGrIndex1 = CurrInterval.tDex % m_nNx[2] ;
|
|
size_t tGrIndex2 = CurrInterval.tDex / m_nNx[2] ;
|
|
size_t tInt = CurrInterval.tInt ;
|
|
// Quote estreme del segmento lungo Y
|
|
double dMinY = m_Values[2][tDex][tInt].dMin ;
|
|
double dMaxY = m_Values[2][tDex][tInt].dMax ;
|
|
double dMinDY = max( floor( ( dMinY - EPS_SMALL) / m_dStep - 0.5), 0.) ;
|
|
double dMaxDY = max( floor( ( dMaxY + EPS_SMALL) / m_dStep - 0.5), 0.) ;
|
|
// Indici estremi dei dei dexel ortogonali
|
|
// che possono intersecare il segmento di partenza
|
|
size_t tStartJ = min( size_t( dMinDY), size_t( m_nNy[0] - 1)) ;
|
|
size_t tStopJ = min( size_t( dMaxDY), size_t( m_nNy[0] - 1)) ;
|
|
// Posizione XZ del dexel
|
|
double dX = ( tGrIndex2 + 0.5) * m_dStep ;
|
|
double dZ = ( tGrIndex1 + 0.5) * m_dStep ;
|
|
// Ciclo sugli indici dei dexel che potrebbero
|
|
// intersecare il segmento di partenza
|
|
for ( size_t tJ = tStartJ ; tJ <= tStopJ ; ++ tJ) {
|
|
// Analizzo i dexel della griglia 0.
|
|
size_t tStopZ = m_Values[0][tJ * m_nNx[0] + tGrIndex2].size() ;
|
|
for ( size_t tIntZ = 0 ; tIntZ < tStopZ ; ++ tIntZ) {
|
|
// Estremi del dexel lunog Z
|
|
double dZmin = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMin ;
|
|
double dZmax = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMax ;
|
|
// Se i segmenti si incrociano e il nuovo trovato non
|
|
// ha gi� un indice assegnato, assegno l'indice e
|
|
// aggiungo l'intervallo trovato allo stack.
|
|
if ( dZmin - EPS_SMALL < dZ &&
|
|
dZmax + EPS_SMALL > dZ &&
|
|
m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].nCompo == 0) {
|
|
m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].nCompo = m_Values[2][tDex][tInt].nCompo ;
|
|
IntervalIndexes NewInterval ;
|
|
NewInterval.tMap = 0 ;
|
|
NewInterval.tDex = tJ * m_nNx[0] + tGrIndex2 ;
|
|
NewInterval.tInt = tIntZ ;
|
|
IntCont.push( NewInterval) ;
|
|
}
|
|
}
|
|
// Analizzo i dexel della griglia 1
|
|
size_t tStopX = m_Values[1][tGrIndex1 * m_nNx[1] + tJ].size() ;
|
|
for ( size_t tIntX = 0 ; tIntX < tStopX ; ++ tIntX) {
|
|
// Estremi del segmento del dexel lungo X
|
|
double dXmin = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMin ;
|
|
double dXmax = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMax ;
|
|
// Se i segmenti si incrociano e il nuovo trovato non
|
|
// ha gi� un indice assegnato, assegno l'indice e
|
|
// aggiungo l'intervallo trovato allo stack.
|
|
if ( dXmin - EPS_SMALL < dX &&
|
|
dXmax + EPS_SMALL > dX &&
|
|
m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].nCompo == 0) {
|
|
m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].nCompo = m_Values[2][tDex][tInt].nCompo ;
|
|
IntervalIndexes NewInterval ;
|
|
NewInterval.tMap = 1 ;
|
|
NewInterval.tDex = tGrIndex1 * m_nNx[1] + tJ ;
|
|
NewInterval.tInt = tIntX ;
|
|
IntCont.push( NewInterval) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ExpandFromZInterval( IntContaier& IntCont)
|
|
{
|
|
// Copio i dati dell'intervallo corrente
|
|
IntervalIndexes CurrInterval = IntCont.top() ;
|
|
IntCont.pop() ;
|
|
size_t tDex = CurrInterval.tDex ;
|
|
size_t tGrIndex1 = CurrInterval.tDex % m_nNx[0] ;
|
|
size_t tGrIndex2 = CurrInterval.tDex / m_nNx[0] ;
|
|
size_t tInt = CurrInterval.tInt ;
|
|
// Quote estreme del segmento lungo Z
|
|
double dMinZ = m_Values[0][tDex][tInt].dMin ;
|
|
double dMaxZ = m_Values[0][tDex][tInt].dMax ;
|
|
double dMinDZ = max( floor( ( dMinZ - EPS_SMALL) / m_dStep - 0.5), 0.) ;
|
|
double dMaxDZ = max( floor( ( dMaxZ + EPS_SMALL) / m_dStep - 0.5), 0.) ;
|
|
// Indici estremi dei dexel ortogonali
|
|
// che possono intersecare il segmento di partenza
|
|
size_t tStartK = min( size_t( dMinDZ), size_t( m_nNy[1] - 1)) ;
|
|
size_t tStopK = min( size_t( dMaxDZ), size_t( m_nNy[1] - 1)) ;
|
|
// Posizione XY del dexel
|
|
double dX = ( tGrIndex1 + 0.5) * m_dStep ;
|
|
double dY = ( tGrIndex2 + 0.5) * m_dStep ;
|
|
// Ciclo sugli indici dei dexel che potrebbero
|
|
// intersecare il segmento di partenza
|
|
for ( size_t tK = tStartK ; tK <= tStopK ; ++ tK) {
|
|
// Analizzo i dexel della griglia 1.
|
|
size_t tStopX = m_Values[1][tK * m_nNx[1] + tGrIndex2].size() ;
|
|
for ( size_t tIntX = 0 ; tIntX < tStopX ; ++ tIntX) {
|
|
// Estremi del segmento del dexel lungo X
|
|
double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ;
|
|
double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ;
|
|
// Se i segmenti si incrociano e il nuovo trovato non
|
|
// ha gi� un indice assegnato, assegno l'indice e
|
|
// aggiungo l'intervallo trovato allo stack.
|
|
if ( dXmin - EPS_SMALL < dX &&
|
|
dXmax + EPS_SMALL > dX &&
|
|
m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo == 0) {
|
|
m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo = m_Values[0][tDex][tInt].nCompo ;
|
|
IntervalIndexes NewInterval ;
|
|
NewInterval.tMap = 1 ;
|
|
NewInterval.tDex = tK * m_nNx[1] + tGrIndex2 ;
|
|
NewInterval.tInt = tIntX ;
|
|
IntCont.push( NewInterval) ;
|
|
}
|
|
}
|
|
// Analizzo i dexel della griglia 2
|
|
size_t tStopY = m_Values[2][tGrIndex1 * m_nNx[2] + tK].size() ;
|
|
for ( size_t tIntY = 0 ; tIntY < tStopY ; ++ tIntY) {
|
|
// Estremi del segmento del dexel lungo Y
|
|
double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ;
|
|
double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ;
|
|
// Se i segmenti si incrociano e il nuovo trovato non
|
|
// ha gi� un indice assegnato, assegno l'indice e
|
|
// aggiungo l'intervallo trovato allo stack.
|
|
if ( dYmin - EPS_SMALL < dY &&
|
|
dYmax + EPS_SMALL > dY &&
|
|
m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo == 0) {
|
|
m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo = m_Values[0][tDex][tInt].nCompo ;
|
|
IntervalIndexes NewInterval ;
|
|
NewInterval.tMap = 2 ;
|
|
NewInterval.tDex = tGrIndex1 * m_nNx[2] + tK ;
|
|
NewInterval.tInt = tIntY ;
|
|
IntCont.push( NewInterval) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap*
|
|
VolZmap::ClonePart( int nPart) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return nullptr ;
|
|
// Se � definita una sola griglia non sono definibili le parti, errore
|
|
if ( m_nMapNum == 1)
|
|
return nullptr ;
|
|
// Se � richiesta una componente fuori intervallo, errore
|
|
if ( nPart < 0 || nPart >= m_nConnectedCompoCount)
|
|
return nullptr ;
|
|
// Se il numero di componenti � indefinito, lo ricalcolo.
|
|
if ( m_nConnectedCompoCount == - 1)
|
|
const_cast<VolZmap*>(this)->CheckMapConnection() ;
|
|
// Se non vi sono componenti, errore
|
|
if ( m_nConnectedCompoCount == 0)
|
|
return nullptr ;
|
|
// Creo nuovo oggetto Zmap
|
|
PtrOwner<VolZmap> pVolume( CreateBasicVolZmap()) ;
|
|
if ( IsNull( pVolume))
|
|
return nullptr ;
|
|
// Setto per il nuovo Zmap le seguenti variabili
|
|
pVolume->m_nConnectedCompoCount = 1 ;
|
|
pVolume->m_dStep = m_dStep ;
|
|
pVolume->m_nMapNum = m_nMapNum ;
|
|
|
|
// Minimi e massimi indici i,j della componente per le tre griglie
|
|
int nMinIndI[N_MAPS] ;
|
|
int nMaxIndI[N_MAPS] ;
|
|
int nMinIndJ[N_MAPS] ;
|
|
int nMaxIndJ[N_MAPS] ;
|
|
// Coordinate dell'origine del sistema di riferimento
|
|
// del nuovo Zmap
|
|
double dNewOx, dNewOy, dNewOz ;
|
|
// Ciclo sulle mappe
|
|
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
|
nMinIndI[nMap] = m_nNx[nMap] ;
|
|
nMinIndJ[nMap] = m_nNy[nMap] ;
|
|
nMaxIndI[nMap] = 0 ;
|
|
nMaxIndJ[nMap] = 0 ;
|
|
pVolume->m_dMinZ[nMap] = m_dMaxZ[nMap] ;
|
|
pVolume->m_dMaxZ[nMap] = m_dMinZ[nMap] ;
|
|
// Della componente connessa in questione calcolo indici i e j massimi e minimi.
|
|
// Inoltre cerco la minima e massima Z.
|
|
for ( int nIndI = 0 ; nIndI < int( m_nNx[nMap]) ; ++ nIndI) {
|
|
for ( int nIndJ = 0 ; nIndJ < int( m_nNy[nMap]) ; ++ nIndJ) {
|
|
int nDex = nIndJ * m_nNx[nMap] + nIndI ;
|
|
for ( int nInt = 0 ; nInt < int( m_Values[nMap][nDex].size()) ; ++ nInt) {
|
|
if ( m_Values[nMap][nDex][nInt].nCompo == nPart + 1) {
|
|
if ( nIndI < nMinIndI[nMap])
|
|
nMinIndI[nMap] = nIndI ;
|
|
if ( nIndJ < nMinIndJ[nMap])
|
|
nMinIndJ[nMap] = nIndJ ;
|
|
if ( nIndI > nMaxIndI[nMap])
|
|
nMaxIndI[nMap] = nIndI ;
|
|
if ( nIndJ > nMaxIndJ[nMap])
|
|
nMaxIndJ[nMap] = nIndJ ;
|
|
if ( m_Values[nMap][nDex][nInt].dMin < pVolume->m_dMinZ[nMap])
|
|
pVolume->m_dMinZ[nMap] = m_Values[nMap][nDex][nInt].dMin ;
|
|
if ( m_Values[nMap][nDex][nInt].dMax > pVolume->m_dMaxZ[nMap])
|
|
pVolume->m_dMaxZ[nMap] = m_Values[nMap][nDex][nInt].dMax ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
|
if ( nMinIndI[nMap] > 0)
|
|
-- nMinIndI[nMap] ;
|
|
if ( nMaxIndI[nMap] < int( m_nNx[nMap]) - 1)
|
|
++ nMaxIndI[nMap] ;
|
|
if ( nMinIndJ[nMap] > 0)
|
|
-- nMinIndJ[nMap] ;
|
|
if ( nMaxIndJ[nMap] < int( m_nNy[nMap]) - 1)
|
|
++ nMaxIndJ[nMap] ;
|
|
pVolume->m_nNx[nMap] = nMaxIndI[nMap] - nMinIndI[nMap] + 1 ;
|
|
pVolume->m_nNy[nMap] = nMaxIndJ[nMap] - nMinIndJ[nMap] + 1 ;
|
|
pVolume->m_nDim[nMap] = pVolume->m_nNx[nMap] * pVolume->m_nNy[nMap] ;
|
|
pVolume->m_Values[nMap].resize( pVolume->m_nDim[nMap]) ;
|
|
}
|
|
|
|
// Copio gli intervalli nelle griglie del nuovo oggetto:
|
|
// Griglia 0
|
|
for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[0]) ; ++ nIndJ) {
|
|
for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[0]) ; ++ nIndI) {
|
|
int nNewDex = nIndJ * pVolume->m_nNx[0] + nIndI ;
|
|
int nOldDex = ( nIndJ + nMinIndJ[0]) * m_nNx[0] + nIndI + nMinIndI[0] ;
|
|
for ( int nInt = 0 ; nInt < int( m_Values[0][nOldDex].size()) ; ++ nInt) {
|
|
if ( m_Values[0][nOldDex][nInt].nCompo == nPart + 1) {
|
|
pVolume->m_Values[0][nNewDex].emplace_back( m_Values[0][nOldDex][nInt]) ;
|
|
pVolume->m_Values[0][nNewDex].back().nCompo = 1 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Griglia 1
|
|
for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[1]) ; ++ nIndJ) {
|
|
for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[1]) ; ++ nIndI) {
|
|
int nNewDex = nIndJ * pVolume->m_nNx[1] + nIndI ;
|
|
int nOldDex = ( nIndJ + nMinIndJ[1]) * m_nNx[1] + nIndI + nMinIndI[1] ;
|
|
for ( int nInt = 0 ; nInt < int( m_Values[1][nOldDex].size()) ; ++ nInt) {
|
|
if ( m_Values[1][nOldDex][nInt].nCompo == nPart + 1) {
|
|
pVolume->m_Values[1][nNewDex].emplace_back( m_Values[1][nOldDex][nInt]) ;
|
|
pVolume->m_Values[1][nNewDex].back().nCompo = 1 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Griglia 2
|
|
for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[2]) ; ++ nIndJ) {
|
|
for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[2]) ; ++ nIndI) {
|
|
int nNewDex = nIndJ * pVolume->m_nNx[2] + nIndI ;
|
|
int nOldDex = ( nIndJ + nMinIndJ[2]) * m_nNx[2] + nIndI + nMinIndI[2] ;
|
|
for ( int nInt = 0 ; nInt < int( m_Values[2][nOldDex].size()) ; ++ nInt) {
|
|
if ( m_Values[2][nOldDex][nInt].nCompo == nPart + 1) {
|
|
pVolume->m_Values[2][nNewDex].emplace_back( m_Values[2][nOldDex][nInt]) ;
|
|
pVolume->m_Values[2][nNewDex].back().nCompo = 1 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Coordinate x,y dell'origine del sistema di riferimento
|
|
dNewOx = nMinIndI[0] * m_dStep ;
|
|
dNewOy = nMinIndJ[0] * m_dStep ;
|
|
dNewOz = nMinIndJ[1] * m_dStep ;
|
|
|
|
// Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'� bisogno di trasformare le normali,
|
|
// infatti i sistemi di riferimento in gioco differiscono al pi� per una traslazione.
|
|
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
|
// Quote estreme Z
|
|
switch ( nMap) {
|
|
case 0 :
|
|
pVolume->m_dMinZ[nMap] -= dNewOz ;
|
|
pVolume->m_dMaxZ[nMap] -= dNewOz ;
|
|
break ;
|
|
case 1 :
|
|
pVolume->m_dMinZ[nMap] -= dNewOx ;
|
|
pVolume->m_dMaxZ[nMap] -= dNewOx ;
|
|
break ;
|
|
case 2 :
|
|
pVolume->m_dMinZ[nMap] -= dNewOy ;
|
|
pVolume->m_dMaxZ[nMap] -= dNewOy ;
|
|
break ;
|
|
}
|
|
// Dexel
|
|
for ( int nDex = 0 ; nDex < int( pVolume->m_nDim[nMap]) ; ++ nDex) {
|
|
for ( int nInt = 0 ; nInt < int( pVolume->m_Values[nMap][nDex].size()) ; ++ nInt) {
|
|
switch ( nMap) {
|
|
case 0 :
|
|
pVolume->m_Values[nMap][nDex][nInt].dMin -= dNewOz ;
|
|
pVolume->m_Values[nMap][nDex][nInt].dMax -= dNewOz ;
|
|
break ;
|
|
case 1 :
|
|
pVolume->m_Values[nMap][nDex][nInt].dMin -= dNewOx ;
|
|
pVolume->m_Values[nMap][nDex][nInt].dMax -= dNewOx ;
|
|
break ;
|
|
case 2 :
|
|
pVolume->m_Values[nMap][nDex][nInt].dMin -= dNewOy ;
|
|
pVolume->m_Values[nMap][nDex][nInt].dMax -= dNewOy ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Calcolo il numero di voxel lungo x,y e z
|
|
unsigned int nVoxNumX = pVolume->m_nNx[0] / pVolume->N_DEXVOXRATIO +
|
|
( pVolume->m_nNx[0] % pVolume->N_DEXVOXRATIO == 0 ? 1 : 2) ;
|
|
unsigned int nVoxNumY = pVolume->m_nNy[0] / pVolume->N_DEXVOXRATIO +
|
|
( pVolume->m_nNy[0] / pVolume->N_DEXVOXRATIO == 0 ? 1 : 2) ;
|
|
unsigned int nVoxNumZ = pVolume->m_nNy[1] / pVolume->N_DEXVOXRATIO +
|
|
( pVolume->m_nNy[1] % pVolume->N_DEXVOXRATIO == 0 ? 1 : 2) ;
|
|
|
|
// Definisco il numero di blocchi lungo x,y e z
|
|
pVolume->m_nFracLin[0] = max( 1u, nVoxNumX / pVolume->m_nVoxNumPerBlock +
|
|
( nVoxNumX % pVolume->m_nVoxNumPerBlock >= pVolume->m_nVoxNumPerBlock / 2 ? 1 : 0)) ;
|
|
pVolume->m_nFracLin[1] = max( 1u, nVoxNumY / pVolume->m_nVoxNumPerBlock +
|
|
( nVoxNumY % pVolume->m_nVoxNumPerBlock >= pVolume->m_nVoxNumPerBlock / 2 ? 1 : 0)) ;
|
|
pVolume->m_nFracLin[2] = max( 1u, nVoxNumZ / pVolume->m_nVoxNumPerBlock +
|
|
( nVoxNumZ % pVolume->m_nVoxNumPerBlock >= pVolume->m_nVoxNumPerBlock / 2 ? 1 : 0)) ;
|
|
|
|
// Dimensiono il vettore dei blocchi
|
|
pVolume->m_nNumBlock = pVolume->m_nFracLin[0] * pVolume->m_nFracLin[1] * pVolume->m_nFracLin[2] ;
|
|
pVolume->m_BlockToUpdate.resize( pVolume->m_nNumBlock) ;
|
|
// Setto tutti i blocchi come da aggiornare per la grafica
|
|
for ( unsigned int nCount = 0 ; nCount < pVolume->m_nNumBlock ; ++ nCount)
|
|
pVolume->m_BlockToUpdate[nCount] = true ;
|
|
|
|
// Dimensiono raccolta triangoli di feature tra blocchi
|
|
pVolume->m_InterBlockTria.resize( pVolume->m_nNumBlock) ;
|
|
|
|
// Sistema di riferimento intrinseco del nuovo solido
|
|
Point3d ptNewO( dNewOx, dNewOy, dNewOz) ;
|
|
pVolume->m_MapFrame.Set( ptNewO, X_AX, Y_AX, Z_AX) ;
|
|
|
|
// Setto lo stato del nuovo Solido
|
|
pVolume->m_nStatus = m_nStatus ;
|
|
|
|
// Restituisco il nuovo solido
|
|
return Release( pVolume) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::RemovePart( int nPart)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// Se � definita una sola griglia non sono definibili le parti, errore
|
|
if ( m_nMapNum == 1)
|
|
return false ;
|
|
// Se il numero di componenti � indefinito, lo ricalcolo
|
|
if ( m_nConnectedCompoCount == - 1)
|
|
CheckMapConnection() ;
|
|
// Se non vi sono componenti, abbiamo finito
|
|
if ( m_nConnectedCompoCount == 0)
|
|
return true ;
|
|
|
|
// Elimino i segmenti con indice nPart + 1 e aggiorno quelli con indice superiore
|
|
// Ciclo sulle mappe.
|
|
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
|
// Ciclo sui dexel della mappa.
|
|
for ( int nDex = 0 ; nDex < int( m_Values[nMap].size()) ; ++ nDex) {
|
|
// Ciclo sugli intervalli del dexel.
|
|
for ( int nInt = 0 ; nInt < int( m_Values[nMap][nDex].size()) ; ++ nInt) {
|
|
// Se l'intervallo appartiene alla componente da eliminare, lo cancello.
|
|
if ( m_Values[nMap][nDex][nInt].nCompo == nPart + 1) {
|
|
m_Values[nMap][nDex].erase( m_Values[nMap][nDex].begin() + nInt) ;
|
|
-- nInt ;
|
|
}
|
|
else if ( m_Values[nMap][nDex][nInt].nCompo > nPart + 1)
|
|
m_Values[nMap][nDex][nInt].nCompo -= 1 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Decremento il numero di componenti.
|
|
m_nConnectedCompoCount -= 1 ;
|
|
|
|
// Imposto ricalcolo grafica
|
|
m_OGrMgr.Reset() ;
|
|
|
|
return true ;
|
|
}
|
|
|