EgtGeomKernel 2.1b1 :

- modifiche a Zmap per mantenimento liste triangoli.
This commit is contained in:
Dario Sassi
2019-02-11 11:55:33 +00:00
parent 48ae6e5da5
commit fca22fc56b
7 changed files with 1576 additions and 1412 deletions
+184 -43
View File
@@ -16,11 +16,11 @@
#include "CurveLine.h"
#include "VolZmap.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkIntersLineSphere.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#include "/EgtDev/Include/EgtNumUtils.h"
using namespace std ;
@@ -122,12 +122,12 @@ VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU
// con quello intrinseco dello Zmap solo nel caso della prima griglia. Per le altre griglie
// è necessario permutare ciclicamente le coordinate.
bool
VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ,
VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, int nGrid, int nI, int nJ,
double& dU1, double& dU2) const
{
// Determino l'indice del dexel e il numero di suoi intervalli
unsigned int nDexelPos = nJ * m_nNx[nGrid] + nI ;
unsigned int nDexelSize = unsigned int( m_Values[nGrid][nDexelPos].size()) ;
int nDexelPos = nJ * m_nNx[nGrid] + nI ;
int nDexelSize = int( m_Values[nGrid][nDexelPos].size()) ;
// Se non c'è materiale non devo fare alcunché
if ( nDexelSize == 0)
@@ -143,7 +143,7 @@ VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int
dU1 = INFINITO ;
dU2 = - INFINITO ;
bool bInters = false ;
for ( unsigned int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 1) {
for ( int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 1) {
// estremi del box del singolo intervallo
Point3d ptE1( dXmin, dYmin, m_Values[nGrid][nDexelPos][nIndex].dMin) ;
Point3d ptE2( dXmax, dYmax, m_Values[nGrid][nDexelPos][nIndex].dMax) ;
@@ -164,12 +164,12 @@ VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int
// con quello intrinseco dello Zmap solo nel caso della prima griglia. Per le altre griglie
// è necessario permutare ciclicamente le coordinate.
bool
VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ,
VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, int nGrid, int nI, int nJ,
double& dU1, double& dU2) const
{
// Determino l'indice del dexel e il numero di suoi intervalli
unsigned int nDexelPos = nJ * m_nNx[nGrid] + nI ;
unsigned int nDexelSize = unsigned int( m_Values[nGrid][nDexelPos].size()) ;
int nDexelPos = nJ * m_nNx[nGrid] + nI ;
int nDexelSize = int( m_Values[nGrid][nDexelPos].size()) ;
// Se non c'è materiale non devo fare alcunché
if ( nDexelSize == 0)
@@ -185,7 +185,7 @@ VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int n
dU1 = INFINITO ;
dU2 = - INFINITO ;
bool bInters = false ;
for ( unsigned int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 1) {
for ( int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 1) {
// estremi del box del singolo intervallo
Point3d ptE1( dXmin, dYmin, m_Values[nGrid][nDexelPos][nIndex].dMin) ;
Point3d ptE2( dXmax, dYmax, m_Values[nGrid][nDexelPos][nIndex].dMax) ;
@@ -391,6 +391,13 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
bool
VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bEnh) const
{
// Serve che punto e vettore siano espressi sia nel sistema intrinseco dello Zmap (m_MapFrame) sia in quello
// in cui esso è immerso; questo perché i dexel sono espressi in quello intrinseco e i triangoli in quello
// in cui esso è immerso.
Point3d ptOutP = ptP ;
Vector3d vtOutD = vtD ;
ptOutP.ToGlob( m_MapFrame) ;
vtOutD.ToGlob( m_MapFrame) ;
// Intersezione fra semiretta e BBox dello Zmap
double dU1, dU2 ;
bool bLineBBoxInters = IntersLineZMapBBox( ptP, vtD, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
@@ -402,6 +409,15 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
return true ;
}
// Se la grafica non è aggiornata la ricalcolo
bool bUpGrade = false ;
for ( int nBl = 0 ; nBl < int( m_nNumBlock) ; ++ nBl) {
bUpGrade = bUpGrade || m_BlockToUpdate[nBl] ;
}
INTVECTOR nModifiedBlocks ;
if ( bUpGrade)
UpGradeGraphics( false, nModifiedBlocks) ;
// Determino il voxel di partenza
int nVoxI, nVoxJ, nVoxK ;
if ( ! GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
@@ -429,12 +445,15 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
( ( nVoxJ + 1) * N_DEXVOXRATIO + 0.5) * m_dStep,
( ( nVoxK + 1) * N_DEXVOXRATIO + 0.5) * m_dStep) ;
// Studio il voxel corrente
if ( IntersLineBox( ptP, vtD, ptMin, ptMax)) {
VoxelIndexes NewVox ;
NewVox.nI = nVoxI ;
NewVox.nJ = nVoxJ ;
NewVox.nK = nVoxK ;
vVox.emplace_back( NewVox) ;
if ( IntersLineBox( ptP, vtD, ptMin, ptMax)) {
int nCurVoxIndex = CalcIndex( nVoxI, nVoxJ, nVoxK) ;
if ( nCurVoxIndex != 0 && nCurVoxIndex != 255) {
VoxelIndexes NewVox ;
NewVox.nI = nVoxI ;
NewVox.nJ = nVoxJ ;
NewVox.nK = nVoxK ;
vVox.emplace_back( NewVox) ;
}
}
// Interseco la retta con i piani frontiera del voxel
double dMaxTX = ( abs( vtD.x) > EPS_ZERO ?
@@ -458,10 +477,6 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
}
}
// Triangoli di frontiera dei voxel
TRIA3DEXLIST lstTria ;
ExtMarchingCubes( vVox, lstTria, bEnh) ;
// Dati dell'intersezione
struct LineTriaInt {
int nNum ;
@@ -474,31 +489,157 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
: nNum( 2), dPar1( dP1), dPar2( dP2), dDot( dD) {}
} ;
vector<LineTriaInt> vInt ;
// Ciclo sui triangoli dei voxel
for ( auto it = lstTria.begin() ; it != lstTria.end() ; ++it ) {
// Triangolo corrente e suoi punti di intersezione con la retta
const Triangle3d& CurrTria = *it ;
Point3d ptLineTria1, ptLineTria2 ;
// Studio dell'intersezione della retta con il triangolo corrente
int nIntType = IntersLineTria( ptP, vtD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
// Se non ci sono intersezioni passo al prossimo triangolo
if ( nIntType == ILTT_NO)
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
vInt.emplace_back( ( ptLineTria1 - ptP) * vtD, vtD * CurrTria.GetN()) ;
}
// altrimenti ci sono due intersezioni
else {
double dP1 = ( ptLineTria1 - ptP) * vtD ;
double dP2 = ( ptLineTria2 - ptP) * vtD ;
double dD = vtD * CurrTria.GetN() ;
vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
int nPrevBlockN = - 1 ;
// Ciclo sui voxel
for ( int nVx = 0 ; nVx < int( vVox.size()) ; ++ nVx) {
int nCurVoxIJK[3] = { vVox[nVx].nI, vVox[nVx].nJ, vVox[nVx].nK} ;
int nCurBlockIJK[3] ;
if ( GetVoxelBlockIJK( nCurVoxIJK, nCurBlockIJK)) {
int nCurBlockN ;
GetBlockNFromIJK( nCurBlockIJK, nCurBlockN) ;
// Triangoli sharp fra blocchi
for ( int nBlVx = 0 ; nBlVx < int( m_InterBlockToBeFlippedSharpTria[nCurBlockN].size()) ; ++ nBlVx) {
if ( m_InterBlockToBeFlippedSharpTria[nCurBlockN][nBlVx].i == nCurVoxIJK[0] &&
m_InterBlockToBeFlippedSharpTria[nCurBlockN][nBlVx].j == nCurVoxIJK[1] &&
m_InterBlockToBeFlippedSharpTria[nCurBlockN][nBlVx].k == nCurVoxIJK[2]) {
for ( int nBlCm = 0 ; nBlCm < int( m_InterBlockToBeFlippedSharpTria[nCurBlockN][nBlVx].vCompoTria.size()) ; ++ nBlCm) {
for ( int nBlTr = 0 ; nBlTr < int( m_InterBlockToBeFlippedSharpTria[nCurBlockN][nBlVx].vCompoTria[nBlCm].size()) ; ++ nBlTr) {
Triangle3d CurrTria = m_InterBlockToBeFlippedSharpTria[nCurBlockN][nBlVx].vCompoTria[nBlCm][nBlTr] ;
Point3d ptLineTria1, ptLineTria2 ;
// Studio dell'intersezione della retta con il triangolo corrente
int nIntType = IntersLineTria( ptOutP, vtOutD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
// Se non ci sono intersezioni passo al prossimo triangolo
if ( nIntType == ILTT_NO)
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
vInt.emplace_back( ( ptLineTria1 - ptOutP) * vtOutD, vtOutD * CurrTria.GetN()) ;
}
// altrimenti ci sono due intersezioni
else {
double dP1 = ( ptLineTria1 - ptOutP) * vtOutD ;
double dP2 = ( ptLineTria2 - ptOutP) * vtOutD ;
double dD = vtOutD * CurrTria.GetN() ;
vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
}
}
}
}
}
// Triangoli sharp interni
for ( int nBlVx = 0 ; nBlVx < int( m_BlockSharpTria[nCurBlockN].size()) ; ++ nBlVx) {
if ( m_BlockSharpTria[nCurBlockN][nBlVx].i == nCurVoxIJK[0] &&
m_BlockSharpTria[nCurBlockN][nBlVx].j == nCurVoxIJK[1] &&
m_BlockSharpTria[nCurBlockN][nBlVx].k == nCurVoxIJK[2]) {
for ( int nBlCm = 0 ; nBlCm < int( m_BlockSharpTria[nCurBlockN][nBlVx].vCompoTria.size()) ; ++ nBlCm) {
for ( int nBlTr = 0 ; nBlTr < int( m_BlockSharpTria[nCurBlockN][nBlVx].vCompoTria[nBlCm].size()) ; ++ nBlTr) {
Triangle3d CurrTria = m_BlockSharpTria[nCurBlockN][nBlVx].vCompoTria[nBlCm][nBlTr] ;
Point3d ptLineTria1, ptLineTria2 ;
// Studio dell'intersezione della retta con il triangolo corrente
int nIntType = IntersLineTria( ptOutP, vtOutD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
// Se non ci sono intersezioni passo al prossimo triangolo
if ( nIntType == ILTT_NO)
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
vInt.emplace_back( ( ptLineTria1 - ptOutP) * vtOutD, vtOutD * CurrTria.GetN()) ;
}
// altrimenti ci sono due intersezioni
else {
double dP1 = ( ptLineTria1 - ptOutP) * vtOutD ;
double dP2 = ( ptLineTria2 - ptOutP) * vtOutD ;
double dD = vtOutD * CurrTria.GetN() ;
vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
}
}
}
}
}
// Triangoli smooth
for ( int nBlVx = 0 ; nBlVx < int( m_BlockSmoothTria[nCurBlockN].size()) ; ++ nBlVx) {
if ( m_BlockSmoothTria[nCurBlockN][nBlVx].i == nCurVoxIJK[0] &&
m_BlockSmoothTria[nCurBlockN][nBlVx].j == nCurVoxIJK[1] &&
m_BlockSmoothTria[nCurBlockN][nBlVx].k == nCurVoxIJK[2]) {
for ( int nBlTr = 0 ; nBlTr < int( m_BlockSmoothTria[nCurBlockN][nBlVx].vTria.size()) ; ++ nBlTr) {
Triangle3d CurrTria = m_BlockSmoothTria[nCurBlockN][nBlVx].vTria[nBlTr] ;
Point3d ptLineTria1, ptLineTria2 ;
// Studio dell'intersezione della retta con il triangolo corrente
int nIntType = IntersLineTria( ptOutP, vtOutD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
// Se non ci sono intersezioni passo al prossimo triangolo
if ( nIntType == ILTT_NO)
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
vInt.emplace_back( ( ptLineTria1 - ptOutP) * vtOutD, vtOutD * CurrTria.GetN()) ;
}
// altrimenti ci sono due intersezioni
else {
double dP1 = ( ptLineTria1 - ptOutP) * vtOutD ;
double dP2 = ( ptLineTria2 - ptOutP) * vtOutD ;
double dD = vtOutD * CurrTria.GetN() ;
vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
}
}
}
}
// Triangoli grandi
if ( nCurBlockN != nPrevBlockN) {
for ( int nBlTr = 0 ; nBlTr < int( m_BlockBigTria[nCurBlockN].size()) ; ++ nBlTr) {
Triangle3d CurrTria = m_BlockBigTria[nCurBlockN][nBlTr] ;
Point3d ptLineTria1, ptLineTria2 ;
// Studio dell'intersezione della retta con il triangolo corrente
int nIntType = IntersLineTria( ptOutP, vtOutD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
// Se non ci sono intersezioni passo al prossimo triangolo
if ( nIntType == ILTT_NO)
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
vInt.emplace_back( ( ptLineTria1 - ptOutP) * vtOutD, vtOutD * CurrTria.GetN()) ;
}
// altrimenti ci sono due intersezioni
else {
double dP1 = ( ptLineTria1 - ptOutP) * vtOutD ;
double dP2 = ( ptLineTria2 - ptOutP) * vtOutD ;
double dD = vtOutD * CurrTria.GetN() ;
vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
}
}
nPrevBlockN = nCurBlockN ;
}
}
}
// Ciclo sui triangoli dei voxel
//for ( auto it = lstTria.begin() ; it != lstTria.end() ; ++it ) {
// // Triangolo corrente e suoi punti di intersezione con la retta
// const Triangle3d& CurrTria = *it ;
// Point3d ptLineTria1, ptLineTria2 ;
// // Studio dell'intersezione della retta con il triangolo corrente
// int nIntType = IntersLineTria( ptP, vtD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
// // Se non ci sono intersezioni passo al prossimo triangolo
// if ( nIntType == ILTT_NO)
// continue ;
// // se altrimenti c'è una sola intersezione
// else if ( nIntType == ILTT_VERT ||
// nIntType == ILTT_EDGE ||
// nIntType == ILTT_IN) {
// vInt.emplace_back( ( ptLineTria1 - ptP) * vtD, vtD * CurrTria.GetN()) ;
// }
// // altrimenti ci sono due intersezioni
// else {
// double dP1 = ( ptLineTria1 - ptP) * vtD ;
// double dP2 = ( ptLineTria2 - ptP) * vtD ;
// double dD = vtD * CurrTria.GetN() ;
// vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
// }
//}
// Ordino le intersezioni in base al parametro distanza con segno da ptP
sort( vInt.begin(), vInt.end(),
@@ -734,7 +875,7 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
}
// Determino le intersezioni con la superficie laterale del cilindro
DBLVECTOR vdCoef( 3) ;
DBLVECTOR vdCoef(3) ;
double dSqRad = dRad * dRad ;
vdCoef[0] = ptP.x * ptP.x + ptP.y * ptP.y - dSqRad ;
vdCoef[1] = 2 * ( ptP.x * vtV.x + ptP.y * vtV.y) ;