Files
EgtGeomKernel/VolZmap.cpp
T
Dario Sassi 4252497bb3 EgtGeomKernel 1.8k3 :
- miglioramenti a Zmap.
2017-11-25 18:50:54 +00:00

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 ;
}