EgtGeomKernel 1.8j4 :
- aggiunta classe Polygon3d (da EgtExchange) - razionalizzata classe Plane3d - corretta funzione IntersLineTria.
This commit is contained in:
+296
-1
@@ -614,6 +614,285 @@ VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Poin
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// I triangoli sono espressi nel sistema Zmap
|
||||
bool
|
||||
VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, int& nCubeIndex, TRIA3DLIST& lstTria) const
|
||||
{
|
||||
// Se il voxel non esiste, vi è un errore.
|
||||
if ( nVoxI + 1 < 0 || nVoxI + 1 > int( m_nNx[0]) ||
|
||||
nVoxJ + 1 < 0 || nVoxJ + 1 > int( m_nNy[0]) ||
|
||||
nVoxK + 1 < 0 || nVoxK + 1 > int( m_nNy[1]))
|
||||
return false ;
|
||||
|
||||
// Classificazione dei vertici: interni o esterni al materiale o di frontiera
|
||||
int nIndex = CalcIndex( nVoxI, nVoxJ, nVoxK) ;
|
||||
if ( nIndex == 0)
|
||||
nCubeIndex = VOX_EXTERN ;
|
||||
else if ( nIndex == 255)
|
||||
nCubeIndex = VOX_INNER ;
|
||||
else
|
||||
nCubeIndex = VOX_ON_BOUNDARY ;
|
||||
|
||||
if ( nCubeIndex == VOX_ON_BOUNDARY) {
|
||||
|
||||
// Indici i,j,k dei vertici
|
||||
int IndexCorner[8][3] = {
|
||||
{ nVoxI, nVoxJ, nVoxK},
|
||||
{ nVoxI + 1, nVoxJ, nVoxK},
|
||||
{ nVoxI + 1, nVoxJ + 1, nVoxK},
|
||||
{ nVoxI, nVoxJ + 1, nVoxK},
|
||||
{ nVoxI, nVoxJ, nVoxK + 1},
|
||||
{ nVoxI + 1, nVoxJ, nVoxK + 1},
|
||||
{ nVoxI + 1, nVoxJ + 1, nVoxK + 1},
|
||||
{ nVoxI, nVoxJ + 1, nVoxK + 1}
|
||||
} ;
|
||||
|
||||
static int intersections[12][2] = {
|
||||
{ 0, 1 }, { 1, 2 }, { 3, 2 }, { 0, 3 }, { 4, 5 }, { 5, 6 },
|
||||
{ 7, 6 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
|
||||
} ;
|
||||
|
||||
// Array di strutture punto di intersezione e normale alla superficie in esso.
|
||||
VectorField VecField[12] ;
|
||||
|
||||
// Flag di regolarità dei campi scalare e vettoriale
|
||||
bool bReg = true ;
|
||||
|
||||
// Ciclo sui segmenti
|
||||
for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) {
|
||||
// Se il segmento non attraversa la superficie passo al successivo
|
||||
if ( ( EdgeTable[nIndex] & ( 1 << EdgeIndex)) == 0)
|
||||
continue ;
|
||||
// Indici per linee di griglia sui vertici
|
||||
int n1 = intersections[EdgeIndex][0] ;
|
||||
int n2 = intersections[EdgeIndex][1] ;
|
||||
// Flag posizione corner
|
||||
bool bN1 = ( ( nIndex & ( 1 << n1)) != 0) ;
|
||||
// Determino con precisione il punto di intersezione sullo spigolo,
|
||||
// se i campi scalare e vettoriale non sono regolari bReg diviene falso.
|
||||
if ( ! IntersPos( IndexCorner[n1], IndexCorner[n2], bN1,
|
||||
VecField[EdgeIndex].ptInt, VecField[EdgeIndex].vtNorm))
|
||||
bReg = false ;
|
||||
}
|
||||
|
||||
// Determino il numero di componenti connesse nel voxel in caso di configurazione standard
|
||||
int nComponents = TriangleTableEn[nIndex][1][0] ;
|
||||
|
||||
// Matrici di campi vettoriali:
|
||||
// CompoVert[i] ha i vertici della base del triangle fan della (i+1)-esima componente connessa;
|
||||
// CompoTriVert[i] ha i vertici di tutti i triangoli, nel caso di assenza di sharp feature,
|
||||
// della (i+1)-esima componente connessa.
|
||||
VectorField CompoVert[6][12] ;
|
||||
VectorField CompoTriVert[6][17] ;
|
||||
|
||||
// Arrey numero di vertici della base del fan per componente
|
||||
// connessa: nVertComp[i] contiene il numero di vertici
|
||||
// della base del fan della (i+1)-esima componente connessa.
|
||||
int nVertComp[6] ;
|
||||
|
||||
|
||||
int nExtTabOff = nComponents ;
|
||||
int nStdTabOff = 0 ;
|
||||
|
||||
// Carico le matrici CompoVert e CompoTriVert
|
||||
for ( int nCompCount = 1 ; nCompCount <= nComponents ; ++ nCompCount) {
|
||||
|
||||
// Numero vertici per componenti
|
||||
nVertComp[nCompCount - 1] = TriangleTableEn[nIndex][1][nCompCount] ;
|
||||
|
||||
// Riempio il nCompCount-esimo vettore di vertici dei triangoli in assenza di
|
||||
// sharp feature: in una mesh di triangoli con n vertici vi sono n - 2 triangoli.
|
||||
for ( int nVertCount = 0 ; nVertCount < 3 * ( nVertComp[nCompCount - 1] - 2) ; nVertCount += 3) {
|
||||
CompoTriVert[nCompCount - 1][nVertCount] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount+2]] ;
|
||||
CompoTriVert[nCompCount - 1][nVertCount+1] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount+1]] ;
|
||||
CompoTriVert[nCompCount - 1][nVertCount+2] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount]] ;
|
||||
}
|
||||
|
||||
// Aggiorno gli offsets per raggiungere i
|
||||
// vertici della componente successiva.
|
||||
nExtTabOff += nVertComp[nCompCount - 1] ;
|
||||
nStdTabOff += 3 * ( nVertComp[nCompCount - 1] - 2) ;
|
||||
}
|
||||
|
||||
// Test sulla topologia: dal momento che il nostro test
|
||||
// si fonda sugli angoli compresi fra le normali, esso ha
|
||||
// senso solo se il campo è regolare.
|
||||
if ( bReg && nAllConfig[nIndex] == 3) {
|
||||
|
||||
Vector3d vtCmpAvg0, vtCmpAvg1 ;
|
||||
|
||||
// Verifico se i versori delle componenti sono tutti
|
||||
// più o meno concordi (per esserlo non devono esserci
|
||||
// due vettori di una medesima componente con prodotto
|
||||
// scalare inferiore a 0.7).
|
||||
bool bTest0 = DotTest( CompoVert[0], 3, vtCmpAvg0, 0.7) ;
|
||||
bool bTest1 = DotTest( CompoVert[1], 3, vtCmpAvg1, 0.7) ;
|
||||
|
||||
// Se i versori di entrambe le componenti sono concordi
|
||||
// ha senso parlare di vettori medi, altrimenti non ha
|
||||
// senso. Se non ha senso parlare di vettori medi non
|
||||
// ha senso parlare di prodotti scalari fra loro,
|
||||
// quindi pongo il loro prodotto a un valore assurdo -2
|
||||
// (il prodotto scalare fra versori ha modulo non superiore
|
||||
// a uno).
|
||||
double dScProd = - 2 ;
|
||||
|
||||
if ( bTest0 && bTest1)
|
||||
dScProd = vtCmpAvg0 * vtCmpAvg1 ;
|
||||
|
||||
double dThreshold = 0.7 ;
|
||||
|
||||
if ( ! ( bTest0 && bTest1) || ( bTest0 && bTest1 && dScProd > dThreshold)) {
|
||||
|
||||
int nt = 0 ;
|
||||
|
||||
while ( nIndexVsIndex3[nt][0] != nIndex)
|
||||
++ nt ;
|
||||
|
||||
int nRotCase = nIndexVsIndex3[nt][1] ;
|
||||
|
||||
nComponents = Cases3Plus[nRotCase][1][0] ;
|
||||
|
||||
// Riaggiorno gli offsets
|
||||
nExtTabOff = nComponents ;
|
||||
nStdTabOff = 0 ;
|
||||
|
||||
// Modifico le matrici
|
||||
for ( int nC = 1 ; nC <= nComponents ; ++ nC) {
|
||||
|
||||
// Numero vertici per componenti
|
||||
nVertComp[nC - 1] = Cases3Plus[nRotCase][1][nC] ;
|
||||
|
||||
// Matrici dei vertici dei triangoli in assenza di sharp feature
|
||||
for ( int nTriVert = 0 ; nTriVert < 3 * ( nVertComp[nC - 1] - 2) ; nTriVert += 3) {
|
||||
|
||||
CompoTriVert[nC - 1][nTriVert] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert+2]] ;
|
||||
CompoTriVert[nC - 1][nTriVert+1] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert+1]] ;
|
||||
CompoTriVert[nC - 1][nTriVert+2] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert]] ;
|
||||
}
|
||||
|
||||
// Aggiorno gli offsets per raggiungere i
|
||||
// vertici della componente successiva.
|
||||
nExtTabOff += nVertComp[nC - 1] ;
|
||||
nStdTabOff += 3 * ( nVertComp[nC - 1] - 2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( bReg && nAllConfig[nIndex] == 6) {
|
||||
|
||||
// Procedura analoga a quella della configurazione 3
|
||||
Vector3d vtCmpAvg0, vtCmpAvg1 ;
|
||||
|
||||
bool bTest0 = DotTest( CompoVert[0], 4, vtCmpAvg0, 0.7) ;
|
||||
bool bTest1 = DotTest( CompoVert[1], 3, vtCmpAvg1, 0.7) ;
|
||||
|
||||
double dScProd = - 2 ;
|
||||
|
||||
if ( bTest0 && bTest1)
|
||||
dScProd = vtCmpAvg0 * vtCmpAvg1 ;
|
||||
|
||||
double dThreshold = 0.7 ;
|
||||
|
||||
if ( ! ( bTest0 && bTest1) || ( bTest0 && bTest1 && dScProd > dThreshold)) {
|
||||
|
||||
int nt = 0 ;
|
||||
|
||||
while ( nIndexVsIndex6[nt][0] != nIndex)
|
||||
++ nt ;
|
||||
|
||||
int nRotCase = nIndexVsIndex6[nt][1] ;
|
||||
|
||||
nComponents = 1 ;
|
||||
|
||||
// Riaggiorno gli offsets
|
||||
nExtTabOff = nComponents ;
|
||||
nStdTabOff = 0 ;
|
||||
|
||||
// Modifico le matrici
|
||||
for ( int nC = 1 ; nC <= nComponents ; ++ nC) {
|
||||
|
||||
// Numero vertici per componenti
|
||||
nVertComp[nC - 1] = 7 ;
|
||||
|
||||
// Matrici dei vertici dei triangoli in assenza di sharp feature
|
||||
for ( int nTriVert = 0 ; nTriVert < 3 * ( nVertComp[nC - 1] - 2) ; nTriVert += 3) {
|
||||
|
||||
CompoTriVert[nC - 1][nTriVert] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert+2]] ;
|
||||
CompoTriVert[nC - 1][nTriVert+1] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert+1]] ;
|
||||
CompoTriVert[nC - 1][nTriVert+2] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert]] ;
|
||||
}
|
||||
|
||||
// Aggiorno gli offsets per raggiungere i
|
||||
// vertici della componente successiva.
|
||||
nExtTabOff += nVertComp[nC - 1] ;
|
||||
nStdTabOff += 3 * ( nVertComp[nC - 1] - 2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( bReg && nAllConfig[nIndex] == 10) {
|
||||
|
||||
Vector3d vtCmpAvg0, vtCmpAvg1 ;
|
||||
|
||||
// Verifico se i versori delle componenti sono tutti
|
||||
// più o meno concordi (per esserlo non devono esserci
|
||||
// due vettori di una medesima componente con prodotto
|
||||
// scalare inferiore a 0). decidere se 0.0 o 0.7
|
||||
bool bTest0 = DotTest( CompoVert[0], 4, vtCmpAvg0) ;
|
||||
bool bTest1 = DotTest( CompoVert[1], 4, vtCmpAvg1) ;
|
||||
|
||||
if ( ! ( bTest0 && bTest1)) {
|
||||
|
||||
int nt = 0 ;
|
||||
while ( nIndexVsIndex10[nt][0] != nIndex)
|
||||
++ nt ;
|
||||
|
||||
int nRotCase = nIndexVsIndex10[nt][1] ;
|
||||
|
||||
// Riaggiorno gli offsets
|
||||
nExtTabOff = 2 ;
|
||||
nStdTabOff = 0 ;
|
||||
|
||||
// Modifico le matrici
|
||||
for ( int nC = 1 ; nC <= 2 ; ++ nC) {
|
||||
// Numero vertici per componenti
|
||||
nVertComp[nC - 1] = Cases10Plus[nRotCase][1][nC] ;
|
||||
|
||||
|
||||
// Matrici dei vertici dei triangoli in assenza di sharp feature
|
||||
for ( int nTriVert = 0 ; nTriVert < 6 ; nTriVert += 3) {
|
||||
CompoTriVert[nC - 1][nTriVert] = VecField[Cases10Plus[nRotCase][0][nStdTabOff + nTriVert+2]] ;
|
||||
CompoTriVert[nC - 1][nTriVert+1] = VecField[Cases10Plus[nRotCase][0][nStdTabOff + nTriVert+1]] ;
|
||||
CompoTriVert[nC - 1][nTriVert+2] = VecField[Cases10Plus[nRotCase][0][nStdTabOff + nTriVert]] ;
|
||||
}
|
||||
|
||||
// Aggiorno gli offsets per raggiungere i vertici della componente successiva.
|
||||
nExtTabOff += nVertComp[nC - 1] ;
|
||||
nStdTabOff += 3 * ( nVertComp[nC - 1] - 2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ciclo sulle componenti
|
||||
for ( int nCompCount = 1 ; nCompCount <= nComponents ; ++ nCompCount) {
|
||||
// Costruzione dei triangoli
|
||||
for ( int TriIndex = 0; TriIndex < ( nVertComp[nCompCount - 1] - 2) * 3 ; TriIndex += 3) {
|
||||
// Il triangolo è pronto
|
||||
Triangle3d CurrentTriangle ;
|
||||
CurrentTriangle.Set( CompoTriVert[nCompCount - 1][TriIndex].ptInt,
|
||||
CompoTriVert[nCompCount - 1][TriIndex+1].ptInt,
|
||||
CompoTriVert[nCompCount - 1][TriIndex+2].ptInt) ;
|
||||
bool bV = CurrentTriangle.Validate( true) ;
|
||||
// Aggiungo alla lista
|
||||
lstTria.emplace_back( CurrentTriangle) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::MarchingCubes( int nBlock, TRIA3DLIST& lstTria) const
|
||||
@@ -1289,7 +1568,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DLIST& lstTria, TriHolder& triHold)
|
||||
}
|
||||
|
||||
// Flag ExtMC
|
||||
bool bExtMC = ( nFeatureType != NO_FEATURE) && bGridControl ;
|
||||
bool bExtMC = ( nFeatureType != NO_FEATURE && bGridControl) ;
|
||||
|
||||
// Extended MC
|
||||
if ( bExtMC) {
|
||||
@@ -2510,6 +2789,22 @@ VolZmap::IntersPos( int nVec1[], int nVec2[], bool bFirstCorner, Point3d& ptInt,
|
||||
return bFound ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::IsValidVoxel( int nN) const
|
||||
{
|
||||
return ( nN >= 0 && nN < int( ( m_nNx[0] + 1) * ( m_nNy[0] + 1) * ( m_nNy[1] + 1))) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::IsValidVoxel( int nI, int nJ, int nK) const
|
||||
{
|
||||
return ( nI >= - 1 && nI < int( m_nNx[0]) &&
|
||||
nJ >= - 1 && nJ < int( m_nNy[0]) &&
|
||||
nK >= - 1 && nK < int( m_nNy[1]) ) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::GetVoxIJKFromN( int nN, int& nI, int& nJ, int& nK) const
|
||||
|
||||
Reference in New Issue
Block a user