EgtGeomKernel 1.9b1 :

- in Zmap N_DEXVOXRATIO riportato a 1
- in Zmap migliorie a visualizzazione
- in Zmap migliorate GetDepth e AvoidBox.
This commit is contained in:
Dario Sassi
2018-02-03 18:57:18 +00:00
parent f36c453415
commit fdef0bb7a3
5 changed files with 271 additions and 380 deletions
+79 -104
View File
@@ -218,10 +218,10 @@ VolZmap::GetDepth( const Point3d& ptPLoc, const Vector3d& vtDLoc, double& dInLen
ptP.ToLoc( m_MapFrame) ;
vtD.ToLoc( m_MapFrame) ;
if ( bExact)
return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ;
if ( bExact && m_nMapNum == 3)
return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ;
else
return GetDepthWithDexel( ptP, vtD, dInLength, dOutLength) ;
return GetDepthWithDexel( ptP, vtD, dInLength, dOutLength) ;
}
//----------------------------------------------------------------------------
@@ -272,7 +272,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
swap( ptI.y, ptI.z) ;
swap( ptI.x, ptI.z) ;
swap( ptF.y, ptF.z) ;
swap( ptF.x, ptF.z) ;
swap( ptF.x, ptF.z) ;
}
else if ( nGrid == 2) {
swap( ptP0.x, ptP0.z) ;
@@ -281,21 +281,21 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
swap( vtV0.y, vtV0.z) ;
swap( ptI.x, ptI.z) ;
swap( ptI.y, ptI.z) ;
swap( ptF.x, ptF.z) ;
swap( ptF.y, ptF.z) ;
swap( ptF.x, ptF.z) ;
swap( ptF.y, ptF.z) ;
}
// Inizializzo distanze
dInLen[nGrid] = INFINITO ;
dOutLen[nGrid] = - INFINITO ;
// Determino asse di spostamento maggiore
bool bOnX = ( abs( ptF.y - ptI.y) <= abs( ptF.x - ptI.x)) ;
// Movimento crescente su asse di movimento principale
if ( ( bOnX && ptF.x < ptI.x) || ( ! bOnX && ptF.y < ptI.y) )
swap( ptI, ptF) ;
// Pendenza
double dDeltaX = ( ptF.x - ptI.x) ;
double dDeltaY = ( ptF.y - ptI.y) ;
@@ -304,24 +304,24 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
dM = dDeltaY / dDeltaX ;
else if ( ! bOnX && abs( dDeltaY) > EPS_SMALL)
dM = dDeltaX / dDeltaY ;
// Determinazione degli indici i j dei punti ptI e ptF
// Determinazione degli indici i j dei punti ptI e ptF
int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nNx[nGrid] - 1) ;
int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy[nGrid] - 1) ;
int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx[nGrid] - 1) ;
int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy[nGrid] - 1) ;
// mi muovo
int i = nIi ; int j = nIj ;
while ( ( bOnX && i <= nFi) || ( ! bOnX && j <= nFj)) {
// Eseguo controllo
double dU1, dU2 ;
if ( IntersRayDexel( ptP0, vtV0, nGrid, i, j, dU1, dU2)) {
dInLen[nGrid] = min( dInLen[nGrid], dU1) ;
dOutLen[nGrid] = max( dOutLen[nGrid], dU2) ;
}
// Calcolo spostamento (a destra o sopra)
if ( bOnX) {
double dMoveX = ( ( i + 1) * m_dStep - ptI.x) ;
@@ -344,11 +344,11 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
++ j ;
}
}
// Se non abbiamo incontrato materiale
if ( dInLen[nGrid] > dOutLen[nGrid] - EPS_SMALL) {
dInLen[nGrid] = - 2 ;
dOutLen[nGrid] = - 2 ;
dOutLen[nGrid] = - 2 ;
}
// Se parto dall'interno
else if ( dInLen[nGrid] < - EPS_SMALL)
@@ -361,7 +361,6 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
return true ;
}
if ( abs( dInLen[0] + 2) < EPS_SMALL &&
abs( dInLen[1] + 2) < EPS_SMALL &&
abs( dInLen[2] + 2) < EPS_SMALL) {
@@ -370,7 +369,6 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
return true ;
}
else {
dInLength = INFINITO ;
dOutLength = - INFINITO ;
for ( int nGr = 0 ; nGr < 3 ; ++ nGr) {
@@ -380,8 +378,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
dOutLength = dOutLen[nGr] ;
}
}
return true ;
}
@@ -394,11 +391,10 @@ 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
{
// Parametri di intersezione retta BBox dello Zmap
double dU1, dU2 ;
// Intersezione fra semiretta e BBox dello Zmap
double dU1, dU2 ;
bool bLineBBoxInters = IntersLineZMapBBox( ptP, vtD, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
// Semiretta esterna al box dello Zmap quindi esterna anche allo Zmap
if ( ! bLineBBoxInters) {
dInLength = - 2 ;
@@ -406,28 +402,24 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
return true ;
}
// Indici del voxel corrente
int nVoxI, nVoxJ, nVoxK ;
// Determino il voxel di partenza
int nVoxI, nVoxJ, nVoxK ;
if ( ! GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
if ( ! GetPointVoxel( ptP + dU1 * vtD, nVoxI, nVoxJ, nVoxK))
return false ;
}
// Vettore di voxel
vector<Voxel> vVox ;
// Incrementi degli indici per sguire la retta
int nDeltaI = ( vtD.x > 0 ? 1 : ( vtD.x < 0 ? - 1 : 0)) ;
int nDeltaJ = ( vtD.y > 0 ? 1 : ( vtD.y < 0 ? - 1 : 0)) ;
int nDeltaK = ( vtD.z > 0 ? 1 : ( vtD.z < 0 ? - 1 : 0)) ;
// Scelgo i piani del voxel con cui intersecare la retta,
// per determinare il voxel successivo
// Scelgo i piani del voxel con cui intersecare la retta, per determinare il voxel successivo
int nPlaneI = ( vtD.x >= 0 ? 1 : 0) ;
int nPlaneJ = ( vtD.y >= 0 ? 1 : 0) ;
int nPlaneK = ( vtD.z >= 0 ? 1 : 0) ;
// Ciclo sui voxel
vector<Voxel> vVox ;
while ( IsValidVoxel( nVoxI, nVoxJ, nVoxK)) {
// Estremi della diagonale del voxel corrente
Point3d ptMin( ( nVoxI * N_DEXVOXRATIO + 0.5) * m_dStep,
@@ -451,7 +443,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
abs( ( ( ( nVoxJ + nPlaneJ) * N_DEXVOXRATIO + 0.5) * m_dStep - ptP.y) / vtD.y) : INFINITO) ;
double dMaxTZ = ( abs( vtD.z) > EPS_ZERO ?
abs( ( ( ( nVoxK + nPlaneK) * N_DEXVOXRATIO + 0.5) * m_dStep - ptP.z) / vtD.z) : INFINITO) ;
// Determino gli incrementi
if ( dMaxTX < dMaxTY) {
if ( dMaxTX < dMaxTZ)
nVoxI += nDeltaI ;
@@ -466,76 +458,54 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
}
}
// Triangoli di frontiera dei voxel
TRIA3DEXLIST lstTria ;
ExtMarchingCubes( vVox, lstTria, bEnh) ;
// Struttura studio dell'intersezione
// Dati dell'intersezione
struct LineTriaInt {
double dPar ;
double dDot ;
int nNum ;
double dPar1 ;
double dPar2 ;
double dDot ;
LineTriaInt( void) : nNum( 0) {}
LineTriaInt( double dP, double dD) : nNum( 1), dPar1( dP), dDot( dD) {}
LineTriaInt( double dP1, double dP2, double dD)
: nNum( 2), dPar1( dP1), dPar2( dP2), dDot( dD) {}
} ;
vector<vector<LineTriaInt>> IntMatrix ;
vector<LineTriaInt> vInt ;
// Ciclo sui triangoli del voxel
// Ciclo sui triangoli dei voxel
for ( auto it = lstTria.begin() ; it != lstTria.end() ; ++it ) {
// Triangolo corrente e suoi punti di intersezione con la retta
Triangle3d CurrTria = *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
// 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
// Se non ci sono intersezioni passo al prossimo triangolo
if ( nIntType == ILTT_NO)
continue ;
// se altrimenti c'è una sola intersezione
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
LineTriaInt NewInt ;
NewInt.dPar = ( ptLineTria1 - ptP) * vtD ;
NewInt.dDot = vtD * CurrTria.GetN() ;
vector<LineTriaInt> vSing ;
vSing.emplace_back( NewInt) ;
IntMatrix.emplace_back( vSing) ;
vInt.emplace_back( ( ptLineTria1 - ptP) * vtD, vtD * CurrTria.GetN()) ;
}
// altrimenti ci sono due intersezioni
// altrimenti ci sono due intersezioni
else {
LineTriaInt NewInt1, NewInt2 ;
vector<LineTriaInt> vCouple ;
double dP1 = ( ptLineTria1 - ptP) * vtD ;
double dP2 = ( ptLineTria2 - ptP) * vtD ;
NewInt1.dPar = ( dP1 < dP2 ? dP1 : dP2) ;
NewInt2.dPar = ( dP1 < dP2 ? dP2 : dP1) ;
NewInt1.dDot = vtD * CurrTria.GetN() ;
NewInt2.dDot = NewInt1.dDot ;
vCouple.emplace_back( NewInt1) ;
vCouple.emplace_back( NewInt2) ;
IntMatrix.emplace_back( vCouple) ;
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
for ( int nN = 0 ; nN < int( IntMatrix.size()) - 1 ; ++ nN) {
for ( int nM = nN + 1 ; nM < int( IntMatrix.size()) ; ++ nM) {
double dFP = ( IntMatrix[nN].size() == 2 ? 0.5 * ( IntMatrix[nN][0].dPar + IntMatrix[nN][1].dPar) :
IntMatrix[nN][0].dPar) ;
double dLP = ( IntMatrix[nM].size() == 2 ? 0.5 * ( IntMatrix[nM][0].dPar + IntMatrix[nM][1].dPar) :
IntMatrix[nM][0].dPar) ;
if ( dFP > dLP)
swap( IntMatrix[nN], IntMatrix[nM]) ;
}
}
vector<LineTriaInt> vInt ;
for ( int nN = 0 ; nN < int( IntMatrix.size()) ; ++ nN) {
vInt.emplace_back( IntMatrix[nN][0]) ;
if ( IntMatrix[nN].size() == 2)
vInt.emplace_back( IntMatrix[nN][1]) ;
}
sort( vInt.begin(), vInt.end(),
[]( const LineTriaInt& a, const LineTriaInt& b)
{ double dFP = ( a.nNum == 2 ? 0.5 * ( a.dPar1 + a.dPar2) : a.dPar1) ;
double dLP = ( b.nNum == 2 ? 0.5 * ( b.dPar1 + b.dPar2) : b.dPar1) ;
return ( dLP > dFP) ; }) ;
// Inizializzo le distanze di ingresso e uscita:
// dInLength diminuisce, dOutLength aumenta.
@@ -545,7 +515,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
int nFirstPosN ;
int nN = 0 ;
for ( ; nN < int( vInt.size()) ; ++ nN) {
if ( /*vInt[nN].dPar >= 0*/vInt[nN].dPar > - EPS_SMALL) { // SCEGLIERE FRA LE DUE OPZIONI
if ( vInt[nN].dPar1 > - EPS_SMALL) {
nFirstPosN = nN ;
break ;
}
@@ -562,10 +532,9 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
dInLength = -1 ;
}
else if ( nFirstPosN == 0) {
if ( vInt[nFirstPosN].dDot > EPS_ZERO) //
if ( vInt[nFirstPosN].dDot > EPS_ZERO)
dInLength = -1 ;
else if ( GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
else if ( GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
int nCubeType = CalcIndex( nVoxI, nVoxJ, nVoxK) ;
if ( nCubeType == 255)
dInLength = -1 ;
@@ -573,14 +542,15 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
}
for ( int nN = nFirstPosN ; nN < int( vInt.size()) ; ++ nN) {
if ( vInt[nN].dDot > - EPS_ZERO &&
dOutLength < vInt[nN].dPar)
dOutLength = vInt[nN].dPar ;
if ( vInt[nN].dDot > - EPS_ZERO) {
if ( vInt[nN].nNum == 2 && dOutLength < vInt[nN].dPar2)
dOutLength = vInt[nN].dPar2 ;
else if ( dOutLength < vInt[nN].dPar1)
dOutLength = vInt[nN].dPar1 ;
}
if ( vInt[nN].dDot < EPS_ZERO &&
dInLength > vInt[nN].dPar)
dInLength = vInt[nN].dPar ;
dInLength > vInt[nN].dPar1)
dInLength = vInt[nN].dPar1 ;
}
return true ;
@@ -620,23 +590,28 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
// Ciclo di intersezione dei dexel con il BBox
for ( int i = nStI ; i <= nEnI ; ++ i) {
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
continue ;
Point3d ptC = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
double dZmin, dZmax ;
if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL ||
dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL))
return false ;
for ( int k = 0 ; k < 4 ; ++ k) {
Point3d ptC = ptO + i * m_dStep * vtX + j * m_dStep * vtY ;
if ( k == 0)
ptC += 0.1 * m_dStep * vtX + 0.1 * m_dStep * vtY ;
else if ( k == 1)
ptC += 0.9 * m_dStep * vtX + 0.1 * m_dStep * vtY ;
else if ( k == 2)
ptC += 0.9 * m_dStep * vtX + 0.9 * m_dStep * vtY ;
else if ( k == 3)
ptC += 0.1 * m_dStep * vtX + 0.9 * m_dStep * vtY ;
double dZmin, dZmax ;
if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL ||
dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL))
return false ;
}
}
}
}