EgtGeomKernel 1.9i3 :

- versione NGE portata a 1014
- modifiche per velocizzare il calcolo della grafica di un VolZmap se box.
This commit is contained in:
Dario Sassi
2018-09-18 09:48:54 +00:00
parent 4f0a5e600f
commit c809b8e6bc
9 changed files with 512 additions and 84 deletions
BIN
View File
Binary file not shown.
+6 -3
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2015
// EgalTech 2014-2018
//----------------------------------------------------------------------------
// File : NgeConst.h Data : 04.10.15 Versione : 1.6j1
// File : NgeConst.h Data : 18.09.18 Versione : 1.9i3
// Contenuto : Costanti per file Nge.
//
//
@@ -14,6 +14,7 @@
// 22.05.15 DS 1011 -> Aggiunta possibilità estensione oggetti con IUserObj.
// 05.08.15 DS 1012 -> Aggiunta FlatRegion.
// 04.10.15 DS 1013 -> Aggiunto TextureData.
// 18.09.18 DS 1014 -> Aggiunto falg Shape a Zmap.
//
//----------------------------------------------------------------------------
@@ -41,7 +42,9 @@ const int NGE_VER_1012 = 1012 ;
// 1012 : aggiunta superficie FlatRegion
const int NGE_VER_1013 = 1013 ;
// 1013 : aggiunto TextureData (Keyword T)
const int NGE_VER_LAST = NGE_VER_1013 ;
const int NGE_VER_1014 = 1014 ;
// 1014 : aggiunto Shape a Zmap
const int NGE_VER_LAST = NGE_VER_1014 ;
// Indici KeyWord
const int NGE_START = 0 ;
const int NGE_END = 1 ;
+21
View File
@@ -37,6 +37,27 @@ Tool::~Tool( void)
{
}
//----------------------------------------------------------------------------
bool
Tool::Clear( void)
{
m_dLinTol = LIN_TOL_STD ;
m_dAngTolDeg = ANG_TOL_APPROX_DEG ;
m_nType = UNDEF ;
m_nCurrentNum = 0 ;
m_dHeight = 0 ;
m_dTipHeight = 0 ;
m_dRadius = 0 ;
m_dRCorner = 0 ;
m_dTipRadius = 0 ;
m_dRefRadius = 0 ;
m_dMrtChsWidth = 0 ;
m_dMrtChsThickness = 0 ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
return true ;
}
//---------- Tolleranza nell'approssimazione di curve profilo ----------------
//----------------------------------------------------------------------------
bool
+3 -9
View File
@@ -23,7 +23,8 @@ class Tool
~Tool( void) ;
public :
bool SetTolerances( double dLinTol, double dAngTolDeg = 90) ;
bool Clear( void) ;
bool SetTolerances( double dLinTol, double dAngTolDeg = 45) ;
bool SetStdTool( const std::string& sToolName, double dH, double dR, double dCornR, int nToolNum) ;
bool SetAdvTool( const std::string& sToolName,
double dH, double dR, double dTipH, double dTipR, double dCornR, int nToolNum) ;
@@ -53,14 +54,7 @@ class Tool
double GetMrtChsThickness() const
{ return m_dMrtChsThickness ; }
const CurveComposite* GetOutline() const
{
// Se l'utensile non è stato approssimato uso l'originale
if ( m_ArcLineApprox.GetCurveCount() == 0)
return ( &m_Outline) ;
// altrimenti uso l'approssimazione
else
return ( &m_ArcLineApprox) ;
}
{ return ( m_ArcLineApprox.GetCurveCount() == 0 ? &m_Outline : &m_ArcLineApprox) ; }
public :
enum ToolType { UNDEF = 0, // Utensile indefinito
+52 -8
View File
@@ -30,11 +30,9 @@ GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ;
//----------------------------------------------------------------------------
VolZmap::VolZmap(void)
: m_nStatus( TO_VERIFY), m_dStep( EPS_SMALL), m_nTempProp( 0), m_nVoxNumPerBlock( N_VOXBLOCK), m_Tool( true)
: m_nStatus( TO_VERIFY), m_nMapNum( 0), m_nNumBlock( 0), m_nConnectedCompoCount( 0), m_dStep( 10.0),
m_nVoxNumPerBlock( N_VOXBLOCK), m_nShape( GENERIC), m_nTempProp( 0), m_Tool( true)
{
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 ;
@@ -56,6 +54,7 @@ VolZmap::Clear( void)
{
m_nStatus = TO_VERIFY ;
m_nMapNum = 0 ;
m_nShape = GENERIC ;
m_nNumBlock = 0 ;
m_nConnectedCompoCount = 0 ;
m_MapFrame.Reset() ;
@@ -68,9 +67,8 @@ VolZmap::Clear( void)
m_Values[i].clear() ;
}
m_dStep = EPS_SMALL ;
m_nTempProp = 0 ;
m_Tool.Clear() ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -111,6 +109,7 @@ VolZmap::CopyFrom( const VolZmap& vzmSrc)
return true ;
m_nMapNum = vzmSrc.m_nMapNum ;
m_nShape = vzmSrc.m_nShape ;
m_nNumBlock = vzmSrc.m_nNumBlock ;
m_nVoxNumPerBlock = vzmSrc.m_nVoxNumPerBlock ;
m_nFracLin[0] = vzmSrc.m_nFracLin[0] ;
@@ -181,6 +180,13 @@ VolZmap::Dump( string& sOut, bool bMM, const char* szNewLine) const
{
// tipo
sOut += "Type=" + string( m_nMapNum == 1 ? "dexel" : "tridexel") + szNewLine ;
// forma
switch ( m_nShape) {
default : sOut += "Shape=generic" ; break ;
case BOX : sOut += "Shape=box" ; break ;
case EXTRUSION : sOut += "Shape=extrusion" ; break ;
}
sOut += szNewLine ;
// passo
sOut += "Step=" + ToString( GetInUiUnits( m_dStep, bMM), 3) + szNewLine ;
// dimensioni
@@ -230,6 +236,9 @@ VolZmap::Save( NgeWriter& ngeOut) const
// passo di campionamento (distanza tra spilloni)
if ( ! ngeOut.WriteDouble( m_dStep, ";", true))
return false ;
// forma
if ( ! ngeOut.WriteInt( m_nShape, ";", true))
return false ;
// sistema di riferimento
if ( ! ngeOut.WriteFrame( m_MapFrame, ";", true))
return false ;
@@ -301,12 +310,17 @@ VolZmap::Load( NgeReader& ngeIn)
if ( ! ngeIn.ReadInt( m_nFracLin[i], ",", false))
return false ;
}
// numero di componenti connesse
if ( ! ngeIn.ReadInt( m_nConnectedCompoCount, ",", 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 ;
// da versione 1014 : aggiunto flag Shape
if ( ngeIn.GetFileVersion() >= NGE_VER_1014) {
if ( ! ngeIn.ReadInt( m_nShape, ";", true))
return false ;
}
// sistema di riferimento
if ( ! ngeIn.ReadFrame( m_MapFrame, ";", true))
return false ;
@@ -1102,6 +1116,9 @@ VolZmap::ClonePart( int nPart) const
Point3d ptNewO = m_MapFrame.Orig() + Vector3d( dNewOx, dNewOy, dNewOz) ;
pVolume->m_MapFrame.Set( ptNewO, X_AX, Y_AX, Z_AX) ;
// Determino la forma
pVolume->m_nShape = ( pVolume->IsBox() ? BOX : GENERIC) ;
// Setto lo stato del nuovo Solido
pVolume->m_nStatus = m_nStatus ;
@@ -1310,6 +1327,33 @@ VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::IsBox( void)
{
for ( int nMap = 0 ; nMap < 3 ; ++ nMap) {
double dMinZ = m_dMaxZ[nMap] ;
double dMaxZ = m_dMinZ[nMap] ;
for ( int n = 0 ; n < int( m_nDim[nMap]) ; ++ n) {
int nSize = int( m_Values[nMap][n].size()) ;
if ( nSize > 1)
return false ;
else if ( nSize > 0) {
if ( dMinZ > dMaxZ) {
dMinZ = m_Values[nMap][n][0].dMin ;
dMaxZ = m_Values[nMap][n][0].dMax ;
}
else {
if ( abs( m_Values[nMap][n][0].dMin - dMinZ) > EPS_SMALL ||
abs( m_Values[nMap][n][0].dMax - dMaxZ) > EPS_SMALL)
return false ;
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::SetTolerances( double dLinTol, double dAngTolDeg)
+8 -3
View File
@@ -164,7 +164,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
typedef std::unordered_map <int, Voxel> VoxelContainer ;
// Unordered map per la coerenza topologica
typedef std::unordered_map <int, bool> InterVoxMatter ;
private :
bool CopyFrom( const VolZmap& clSrc) ;
@@ -313,8 +312,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool GetAdjBlockToBlock( int nBlockN, int nDeltaI, int nDeltaJ, int nDeltaK, int& nAdjBlockN) const ;
bool IsAVoxelOnBoundary( const int nLimits[], const int nIJK[], bool bType) const ;
bool IsAVoxelOnBoundary( const int nLimits[], const int nIJK[], int nDeltaIndex[]) const ;
bool IsATriangleOnBorder( const Triangle3dEx& trTria, const Point3d& ptVert,
const int nBlockLimits[], const int nVoxIJK[]) const ;
bool GetFirstVoxIJK( int& i, int& j, int& k) const ;
bool GetLastVoxIJK( int& i, int& j, int& k) const ;
bool IsVoxelOnBoxEdge( int i, int j, int k) const ;
bool IsTriangleOnBorder( const Triangle3dEx& trTria, const int nBlockLimits[], const int nVoxIJK[]) const ;
// Funzioni per facce canoniche con grandi triangoli
bool ProcessVoxContXY( FlatVoxelContainer& VoxContXY, bool bPlus, TRIA3DEXLIST& lstTria) const ;
bool ProcessVoxContYZ( FlatVoxelContainer& VoxContYZ, bool bPlus, TRIA3DEXLIST& lstTria) const ;
@@ -332,9 +333,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool ExpandFromXInterval( IntContaier& IntCont) ;
bool ExpandFromYInterval( IntContaier& IntCont) ;
bool ExpandFromZInterval( IntContaier& IntCont) ;
bool IsBox( void) ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
enum Shape { GENERIC = 0, BOX = 1, EXTRUSION = 2} ;
static const int N_MAPS = 3 ;
static const int N_VOXBLOCK = 32 ;
static const int N_DEXVOXRATIO = 1 ;
@@ -363,6 +366,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
} ;
std::vector<std::vector<Data>> m_Values[N_MAPS] ; // dexel delle 3 griglie
int m_nShape ; // Forma : 0 generica, 1 box, 2 estrusione
unsigned int m_nVoxNumPerBlock ; // Numero di voxel per blocco
unsigned int m_nFracLin[3] ; // Numero di blocchi per ogni asse
unsigned int m_nNumBlock ; // Numero totale di blocchi
+9
View File
@@ -138,6 +138,9 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
m_BlockToUpdate.clear() ;
m_BlockToUpdate.resize( m_nNumBlock, true) ;
// Tipologia
m_nShape = BOX ;
// Dimensiono raccolta di voxel, triangoli di feature tra blocchi e di segnalatori di materiale fra voxel
m_InterBlockVox.resize( m_nNumBlock) ;
m_InterBlockTria.resize( m_nNumBlock) ;
@@ -449,6 +452,9 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
m_SliceXZ.resize( m_nNumBlock) ;
m_SliceYZ.resize( m_nNumBlock) ;
// Tipologia
m_nShape = ( IsBox() ? BOX : EXTRUSION) ;
// Aggiornamento dello stato
m_nStatus = OK ;
@@ -642,6 +648,9 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
m_SliceXZ.resize( m_nNumBlock) ;
m_SliceYZ.resize( m_nNumBlock) ;
// Tipologia
m_nShape = ( IsBox() ? BOX : EXTRUSION) ;
// Aggiornamento dello stato
m_nStatus = OK ;
+410 -61
View File
@@ -166,6 +166,90 @@ DotTest( const AppliedVector CompoField[], int nCompoElem, Vector3d& vtAvg, doub
return true ;
}
//----------------------------------------------------------------------------
bool
CreateBigTriangleXY( double dMinX, double dMaxX, double dMinY, double dMaxY, double dZ,
bool bNormZPlus, int nGrade, Triangle3dEx& trTria1, Triangle3dEx& trTria2)
{
// Punti che definiscono il perimetro del rettangolo
Point3d ptP0( dMinX, dMinY, dZ) ;
Point3d ptP1( dMinX, dMaxY, dZ) ;
Point3d ptP2( dMaxX, dMaxY, dZ) ;
Point3d ptP3( dMaxX, dMinY, dZ) ;
// Versore normale diretto come Z+
if ( bNormZPlus) {
trTria1.Set( ptP0, ptP2, ptP1) ;
trTria2.Set( ptP0, ptP3, ptP2) ;
}
// Versore normale diretto come Z-
else {
trTria1.Set( ptP0, ptP1, ptP2) ;
trTria2.Set( ptP0, ptP2, ptP3) ;
}
trTria1.SetGrade( nGrade) ;
trTria2.SetGrade( nGrade) ;
return trTria1.Validate( true) && trTria2.Validate( true) ;
}
//----------------------------------------------------------------------------
bool
CreateBigTriangleXZ( double dMinX, double dMaxX, double dMinZ, double dMaxZ, double dY,
bool bNormYPlus, int nGrade, Triangle3dEx& trTria1, Triangle3dEx& trTria2)
{
// Punti che definiscono il perimetro del rettangolo
Point3d ptP0( dMinX, dY, dMinZ) ;
Point3d ptP1( dMinX, dY, dMaxZ) ;
Point3d ptP2( dMaxX, dY, dMaxZ) ;
Point3d ptP3( dMaxX, dY, dMinZ) ;
// Versore normale diretto come Y+
if ( bNormYPlus) {
trTria1.Set( ptP0, ptP1, ptP2) ;
trTria2.Set( ptP0, ptP2, ptP3) ;
}
// Versore normale diretto come Y-
else {
trTria1.Set( ptP0, ptP2, ptP1) ;
trTria2.Set( ptP0, ptP3, ptP2) ;
}
trTria1.SetGrade( nGrade) ;
trTria2.SetGrade( nGrade) ;
return trTria1.Validate( true) && trTria2.Validate( true) ;
}
//----------------------------------------------------------------------------
bool
CreateBigTriangleYZ( double dMinY, double dMaxY, double dMinZ, double dMaxZ, double dX,
bool bNormXPlus, int nGrade, Triangle3dEx& trTria1, Triangle3dEx& trTria2)
{
// Punti che definiscono il perimetro del rettangolo
Point3d ptP0( dX, dMinY, dMinZ) ;
Point3d ptP1( dX, dMinY, dMaxZ) ;
Point3d ptP2( dX, dMaxY, dMaxZ) ;
Point3d ptP3( dX, dMaxY, dMinZ) ;
// Versore normale diretto come X+
if ( bNormXPlus) {
trTria1.Set( ptP0, ptP2, ptP1) ;
trTria2.Set( ptP0, ptP3, ptP2) ;
}
// Versore normale diretto come X-
else {
trTria1.Set( ptP0, ptP1, ptP2) ;
trTria2.Set( ptP0, ptP2, ptP3) ;
}
trTria1.SetGrade( nGrade) ;
trTria2.SetGrade( nGrade) ;
return trTria1.Validate( true) && trTria2.Validate( true) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::FindAdjComp( const vector<VoxelContainer>& vVecVox, int nCurBlock, int nCurVox, int nCurComp,
@@ -1304,7 +1388,10 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, VoxelContainer& vV
for ( int i = nLimits[0] ; i < nLimits[1] ; ++ i) {
for ( int j = nLimits[2] ; j < nLimits[3] ; ++ j) {
for ( int k = nLimits[4] ; k < nLimits[5] ; ++ k) {
if ( m_nShape == BOX && ! IsVoxelOnBoxEdge( i, j, k))
continue ;
// Classificazione dei vertici: interni o esterni al materiale
int nIndex = CalcIndex( i, j, k) ;
@@ -1393,58 +1480,60 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, VoxelContainer& vV
}
// Controllo se il voxel ha una sola faccia che giace in un piano canonico e quindi ha gestione speciale
// Faccia XY normale Z+
if ( nIndex == 15) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Z_PLUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXYSup.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
if ( m_nShape != BOX) {
// Faccia XY normale Z+
if ( nIndex == 15) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Z_PLUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXYSup.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
}
}
}
// Faccia YZ normale X+
else if ( nIndex == 153) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], X_PLUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContYZSup.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
// Faccia YZ normale X+
else if ( nIndex == 153) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], X_PLUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContYZSup.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
}
}
}
// Faccia ZX normale Y+
else if ( nIndex == 51) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Y_PLUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXZSup.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
// Faccia ZX normale Y+
else if ( nIndex == 51) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Y_PLUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXZSup.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
}
}
}
// Faccia YX normale Z-
else if ( nIndex == 240) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Z_MINUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXYInf.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
// Faccia YX normale Z-
else if ( nIndex == 240) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Z_MINUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXYInf.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
}
}
}
// Faccia ZY normale X-
else if ( nIndex == 102) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], X_MINUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContYZInf.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
// Faccia ZY normale X-
else if ( nIndex == 102) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], X_MINUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContYZInf.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
}
}
}
// Faccia XZ normale Y-
else if ( nIndex == 204) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Y_MINUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXZInf.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
// Faccia XZ normale Y-
else if ( nIndex == 204) {
int nTool ; double dPos ;
if ( CanonicPlaneTest( CompoVert[0], Y_MINUS, dPos, nTool)) {
int nN ; GetVoxNFromIJK( i, j, k, nN) ;
VoxContXZInf.emplace( nN, HeigthAndColor( nTool, dPos)) ;
continue ;
}
}
}
@@ -1938,7 +2027,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, VoxelContainer& vV
VoxConf.Compo[tOldCompo].bCorner = ( nFeatureType == CORNER) ;
}
// Standard MC
else {
else if ( m_nShape != BOX) {
vector<Triangle3dEx> vTria ;
// Costruzione dei triangoli
for ( int TriIndex = 0; TriIndex < ( nVertComp[nComp] - 2) * 3 ; TriIndex += 3) {
@@ -2004,14 +2093,165 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, VoxelContainer& vV
}
}
// Se il solido è un parallelepipedo creo direttamente i triangoli grandi
if ( m_nShape == BOX) {
int nBlockIJK[3] ;
GetBlockIJKFromN( nBlock, nBlockIJK) ;
// Determino il primo nodo pieno della mappa
int nFirstVoxI, nFirstVoxJ, nFirstVoxK ;
GetFirstVoxIJK( nFirstVoxI, nFirstVoxJ, nFirstVoxK) ;
// Determino il primo nodo pieno della mappa
int nLastVoxI, nLastVoxJ, nLastVoxK ;
GetLastVoxIJK( nLastVoxI, nLastVoxJ, nLastVoxK) ;
// Costruisco i triangoli paralleli al piano YZ
if ( nBlockIJK[0] == 0 || nBlockIJK[0] + 1 == m_nFracLin[0]) {
// Determino coordinate minime dei punti dei triangoli
double dYMin, dZMin ;
if ( nBlockIJK[1] > 0)
dYMin = ( nBlockIJK[1] * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dYMin = ( ( nFirstVoxJ + 1) * N_DEXVOXRATIO + 0.5) * m_dStep ;
if ( nBlockIJK[2] > 0)
dZMin = ( nBlockIJK[2] * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dZMin = ( ( nFirstVoxK + 1) * N_DEXVOXRATIO + 0.5) * m_dStep ; ;
// Determino le coordinate massime dei punti dei triangoli
double dYMax, dZMax ;
if ( nBlockIJK[1] + 1 < int( m_nFracLin[1]))
dYMax = ( ( nBlockIJK[1] + 1) * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dYMax = ( nLastVoxJ * N_DEXVOXRATIO + 0.5) * m_dStep ;
if ( nBlockIJK[2] + 1 < int( m_nFracLin[2]))
dZMax = ( ( nBlockIJK[2] + 1) * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dZMax = ( nLastVoxK * N_DEXVOXRATIO + 0.5) * m_dStep ;
// Determino colore dei triangoli
int nDexMinJ = N_DEXVOXRATIO * ( nFirstVoxJ + 1) ;
int nDexMinK = N_DEXVOXRATIO * ( nFirstVoxK + 1) ;
int nFaceInfGrade = m_Values[1][nDexMinK * m_nNx[1] + nDexMinJ][0].nToolMin ;
int nFaceSupGrade = m_Values[1][nDexMinK * m_nNx[1] + nDexMinJ][0].nToolMax ;
// Piano di coordinata x inferiore: versore normale rivolto come X-
if ( nBlockIJK[0] == 0) {
Triangle3dEx trTria1, trTria2 ;
CreateBigTriangleYZ( dYMin, dYMax, dZMin, dZMax, m_dMinZ[1], false, nFaceInfGrade, trTria1, trTria2) ;
trTria1.ToGlob( m_MapFrame) ;
trTria2.ToGlob( m_MapFrame) ;
lstTria.emplace_back( trTria1) ;
lstTria.emplace_back( trTria2) ;
}
// Piano di coordinata x superiore: versore normale rivolto come X+
if ( nBlockIJK[0] + 1 == m_nFracLin[0]) {
Triangle3dEx trTria1, trTria2 ;
CreateBigTriangleYZ( dYMin, dYMax, dZMin, dZMax, m_dMaxZ[1], true, nFaceSupGrade, trTria1, trTria2) ;
trTria1.ToGlob( m_MapFrame) ;
trTria2.ToGlob( m_MapFrame) ;
lstTria.emplace_back( trTria1) ;
lstTria.emplace_back( trTria2) ;
}
}
// Costruisco i triangoli paralleli al piano XZ
if ( nBlockIJK[1] == 0 || nBlockIJK[1] + 1 == m_nFracLin[1]) {
// Determino coordinate minime dei punti dei triangoli
double dXMin, dZMin ;
if ( nBlockIJK[0] > 0)
dXMin = ( nBlockIJK[0] * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dXMin = ( ( nFirstVoxI + 1) * N_DEXVOXRATIO + 0.5) * m_dStep ;
if ( nBlockIJK[2] > 0)
dZMin = ( nBlockIJK[2] * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dZMin = ( ( nFirstVoxK + 1) * N_DEXVOXRATIO + 0.5) * m_dStep ; ;
// Determino le coordinate massime dei punti dei triangoli
double dXMax, dZMax ;
if ( nBlockIJK[0] + 1 < int( m_nFracLin[0]))
dXMax = ( ( nBlockIJK[0] + 1) * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dXMax = ( nLastVoxI * N_DEXVOXRATIO + 0.5) * m_dStep ;
if ( nBlockIJK[2] + 1 < int( m_nFracLin[2]))
dZMax = ( ( nBlockIJK[2] + 1) * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dZMax = ( nLastVoxK * N_DEXVOXRATIO + 0.5) * m_dStep ;
// Determino colore dei triangoli
int nDexMinI = N_DEXVOXRATIO * ( nFirstVoxI + 1) ;
int nDexMinK = N_DEXVOXRATIO * ( nFirstVoxK + 1) ;
int nFaceInfGrade = m_Values[2][nDexMinI * m_nNx[2] + nDexMinK][0].nToolMin ;
int nFaceSupGrade = m_Values[2][nDexMinI * m_nNx[2] + nDexMinK][0].nToolMax ;
// Piano di coordinata y inferiore: versore normale rivolto come Y-
if ( nBlockIJK[1] == 0) {
Triangle3dEx trTria1, trTria2 ;
CreateBigTriangleXZ( dXMin, dXMax, dZMin, dZMax, m_dMinZ[2], false, nFaceInfGrade, trTria1, trTria2) ;
trTria1.ToGlob( m_MapFrame) ;
trTria2.ToGlob( m_MapFrame) ;
lstTria.emplace_back( trTria1) ;
lstTria.emplace_back( trTria2) ;
}
// Piano di coordinata y superiore: versore normale rivolto come Y+
if ( nBlockIJK[1] + 1 == m_nFracLin[1]) {
Triangle3dEx trTria1, trTria2 ;
CreateBigTriangleXZ( dXMin, dXMax, dZMin, dZMax, m_dMaxZ[2], true, nFaceSupGrade, trTria1, trTria2) ;
trTria1.ToGlob( m_MapFrame) ;
trTria2.ToGlob( m_MapFrame) ;
lstTria.emplace_back( trTria1) ;
lstTria.emplace_back( trTria2) ;
}
}
// Costruisco i triangoli paralleli al piano XY
if ( nBlockIJK[2] == 0 || nBlockIJK[2] + 1 == m_nFracLin[2]) {
// Determino coordinate minime dei punti dei triangoli
double dXMin, dYMin ;
if ( nBlockIJK[0] > 0)
dXMin = ( nBlockIJK[0] * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dXMin = ( ( nFirstVoxI + 1) * N_DEXVOXRATIO + 0.5) * m_dStep ;
if ( nBlockIJK[1] > 0)
dYMin = ( nBlockIJK[1] * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dYMin = ( ( nFirstVoxJ + 1) * N_DEXVOXRATIO + 0.5) * m_dStep ;
// Determino le coordinate massime dei punti dei triangoli
double dXMax, dYMax ;
if ( nBlockIJK[0] + 1 < int( m_nFracLin[0]))
dXMax = ( ( nBlockIJK[0] + 1) * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dXMax = ( nLastVoxI * N_DEXVOXRATIO + 0.5) * m_dStep ;
if ( nBlockIJK[1] + 1 < int( m_nFracLin[1]))
dYMax = ( ( nBlockIJK[1] + 1) * m_nVoxNumPerBlock * N_DEXVOXRATIO + 0.5) * m_dStep ;
else
dYMax = ( nLastVoxJ * N_DEXVOXRATIO + 0.5) * m_dStep ;
// Determino colore dei triangoli
int nDexMinI = N_DEXVOXRATIO * ( nFirstVoxI + 1) ;
int nDexMinJ = N_DEXVOXRATIO * ( nFirstVoxJ + 1) ;
int nFaceInfGrade = m_Values[0][nDexMinJ * m_nNx[0] + nDexMinI][0].nToolMin ;
int nFaceSupGrade = m_Values[0][nDexMinJ * m_nNx[0] + nDexMinI][0].nToolMax ;
// Piano di coordinata Z inferiore: versore normale rivolto come Z-
if ( nBlockIJK[2] == 0) {
Triangle3dEx trTria1, trTria2 ;
CreateBigTriangleXY( dXMin, dXMax, dYMin, dYMax, m_dMinZ[0], false, nFaceInfGrade, trTria1, trTria2) ;
trTria1.ToGlob( m_MapFrame) ;
trTria2.ToGlob( m_MapFrame) ;
lstTria.emplace_back( trTria1) ;
lstTria.emplace_back( trTria2) ;
}
// Piano di coordinata Z superiore: versore normale rivolto come Z+
if ( nBlockIJK[2] + 1 == m_nFracLin[2]) {
Triangle3dEx trTria1, trTria2 ;
CreateBigTriangleXY( dXMin, dXMax, dYMin, dYMax, m_dMaxZ[0], true, nFaceSupGrade, trTria1, trTria2) ;
trTria1.ToGlob( m_MapFrame) ;
trTria2.ToGlob( m_MapFrame) ;
lstTria.emplace_back( trTria1) ;
lstTria.emplace_back( trTria2) ;
}
}
}
// Processo i Voxel con possibile superficie piana
ProcessVoxContXY( VoxContXYInf, false, lstTria) ;
ProcessVoxContXY( VoxContXYSup, true, lstTria) ;
ProcessVoxContYZ( VoxContYZInf, false, lstTria) ;
ProcessVoxContYZ( VoxContYZSup, true, lstTria) ;
ProcessVoxContXZ( VoxContXZInf, false, lstTria) ;
ProcessVoxContXZ( VoxContXZSup, true, lstTria) ;
else {
ProcessVoxContXY( VoxContXYInf, false, lstTria) ;
ProcessVoxContXY( VoxContXYSup, true, lstTria) ;
ProcessVoxContYZ( VoxContYZInf, false, lstTria) ;
ProcessVoxContYZ( VoxContYZSup, true, lstTria) ;
ProcessVoxContXZ( VoxContXZInf, false, lstTria) ;
ProcessVoxContXZ( VoxContXZSup, true, lstTria) ;
}
return true ;
}
@@ -2412,8 +2652,7 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel, T
// Valido il triangolo
CurrTri.Validate( true) ;
// Smisto i triangoli fra di frontiera e interni
bool bTriOnBorder = IsATriangleOnBorder( CurrTri, itVox->second.Compo[nComp].ptVert,
nLimits, nVoxIJK) ;
bool bTriOnBorder = IsTriangleOnBorder( CurrTri, nLimits, nVoxIJK) ;
// Triangolo di frontiera
if ( bTriOnBorder) {
if ( bNewCompBor) {
@@ -3491,9 +3730,119 @@ VolZmap::IsAVoxelOnBoundary( const int nLimits[], const int nIJK[], int nDeltaIn
}
//----------------------------------------------------------------------------
// Per riferimento restituisce i minimi degli indici ijk riferiti ai Voxel.
// Si assume che il volume sia un parallelepipedo.
bool
VolZmap::IsATriangleOnBorder( const Triangle3dEx& trTria, const Point3d& ptVert,
const int nBlockLimits[], const int nVoxIJK[]) const
VolZmap::GetFirstVoxIJK( int& i, int& j, int& k) const
{
// Se non è un parallelepipedo, errore
if ( m_nShape != BOX)
return false ;
// Calcolo indici
int ni, nj ;
for ( ni = 0 ; ni < 2 ; ++ ni) {
bool bNotEmpty = false ;
for ( nj = 0 ; nj < 2 ; ++ nj) {
int nDex = nj * int( m_nNx[0]) + ni ;
if ( m_Values[0][nDex].size() > 0) {
bNotEmpty = true ;
break ;
}
}
if ( bNotEmpty)
break ;
}
int mi, mj ;
for ( mi = 0 ; mi < 2 ; ++ mi) {
bool bNotEmpty = false ;
for ( mj = 0 ; mj < 2 ; ++ mj) {
int nDex = mj * int( m_nNx[1]) + mi ;
if ( m_Values[1][nDex].size() > 0) {
bNotEmpty = true ;
break ;
}
}
if ( bNotEmpty)
break ;
}
i = ni / N_DEXVOXRATIO - ( ni % N_DEXVOXRATIO) - 1 ;
j = nj / N_DEXVOXRATIO - ( nj % N_DEXVOXRATIO) - 1 ;
k = mj / N_DEXVOXRATIO - ( mj % N_DEXVOXRATIO) - 1 ;
return true ;
}
//----------------------------------------------------------------------------
// Per riferimento restituisce i massimi degli indici ijk riferiti ai Voxel.
// Si assume che il volume sia un parallelepipedo.
bool
VolZmap::GetLastVoxIJK( int& i, int& j, int& k) const
{
// Se non è un parallelepipedo, errore
if ( m_nShape != BOX)
return false ;
// Calcolo indici
int ni, nj ;
for ( ni = int( m_nNx[0]) - 1 ; ni > int( m_nNx[0]) - 3 ; -- ni) {
bool bNotEmpty = false ;
for ( nj = int( m_nNy[0]) - 1 ; nj > int( m_nNy[0]) - 3 ; -- nj) {
int nDex = nj * int( m_nNx[0]) + ni ;
if ( m_Values[0][nDex].size() > 0) {
bNotEmpty = true ;
break ;
}
}
if ( bNotEmpty)
break ;
}
int mi, mj ;
for ( mi = int( m_nNx[1]) - 1 ; mi > int( m_nNx[1]) - 3 ; -- mi) {
bool bNotEmpty = false ;
for ( mj = int( m_nNy[1]) - 1 ; mj > int( m_nNy[1]) - 3 ; -- mj) {
int nDex = mj * int( m_nNx[1]) + mi ;
if ( m_Values[1][nDex].size() > 0) {
bNotEmpty = true ;
break ;
}
}
if ( bNotEmpty)
break ;
}
i = ni / N_DEXVOXRATIO ;
j = nj / N_DEXVOXRATIO ;
k = mj / N_DEXVOXRATIO ;
return true ;
}
//----------------------------------------------------------------------------
// Il volume deve essere un parallelepipedo.
// Verifica se il voxel contiene uno dei dodici spigoli del parallelepipedo.
bool
VolZmap::IsVoxelOnBoxEdge( int i, int j, int k) const
{
// Se non è un parallelepipedo, errore
if ( m_nShape != BOX)
return false ;
// Determino il primo nodo pieno della mappa
int nFirstVoxI, nFirstVoxJ, nFirstVoxK ;
GetFirstVoxIJK( nFirstVoxI, nFirstVoxJ, nFirstVoxK) ;
// Determino il primo nodo pieno della mappa
int nLastVoxI, nLastVoxJ, nLastVoxK ;
GetLastVoxIJK( nLastVoxI, nLastVoxJ, nLastVoxK) ;
// Determino se il voxel è su un edge del box
int nIndexOnLimitNum = 0 ;
if ( i == nFirstVoxI || i == nLastVoxI)
++ nIndexOnLimitNum ;
if ( j == nFirstVoxJ || j == nLastVoxJ)
++ nIndexOnLimitNum ;
if ( k == nFirstVoxK || k == nLastVoxK)
++ nIndexOnLimitNum ;
return ( nIndexOnLimitNum >= 2) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::IsTriangleOnBorder( const Triangle3dEx& trTria, const int nBlockLimits[], const int nVoxIJK[]) const
{
// Punti del triangolo sulla griglia
Point3d ptFirstGrPt = trTria.GetP( 1) ;
@@ -3522,7 +3871,7 @@ VolZmap::IsATriangleOnBorder( const Triangle3dEx& trTria, const Point3d& ptVert,
bool
VolZmap::ProcessVoxContXY( FlatVoxelContainer& VoxContXY, bool bPlus, TRIA3DEXLIST& lstTria) const
{
for ( auto it = VoxContXY.begin() ;
for ( auto it = VoxContXY.cbegin() ;
it != VoxContXY.end() ;
it = VoxContXY.begin()) {
+3
View File
@@ -176,6 +176,9 @@ VolZmap::SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ
// Se eseguita modifica, imposto ricalcolo della grafica
if ( bModified) {
// Imposto forma generica
m_nShape = GENERIC ;
// Dichiaro numero di componenti connesse da ricalcolare
m_nConnectedCompoCount = - 1 ;