EgtGeomKernel 1.8j4 :

- aggiunta classe Polygon3d (da EgtExchange)
- razionalizzata classe Plane3d
- corretta funzione IntersLineTria.
This commit is contained in:
Dario Sassi
2017-10-16 07:56:04 +00:00
parent 31658bb165
commit 5bcd4bb67d
26 changed files with 969 additions and 105 deletions
+296 -1
View File
@@ -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