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
+201 -1
View File
@@ -18,16 +18,25 @@
#include "GeoConst.h"
#include "IntersLineSurfTm.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
using namespace std ;
//----------------------------------------------------------------------------
bool
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const
{
// Il box è allineato agli assi
double dU1, dU2 ;
return IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const
{
// Il box è allineato agli assi
dU1 = - INFINITO ;
dU2 = INFINITO ;
@@ -168,6 +177,11 @@ VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int n
bool
VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) const
{
#if 1
GetDepthWithVoxel( ptPGlob, vtDir, dInLength, dOutLength) ;
return true ;
#else
int nGrid = 0 ;
// Porto il raggio nel riferimento intrinseco
@@ -271,6 +285,190 @@ VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLen
if ( dInLength < - EPS_SMALL)
dInLength = - 1 ;
return true ;
#endif
}
//----------------------------------------------------------------------------
// Punti e vettori devono essere espressi nel sistema locale (quello in cui è immerso lo Zmap)
// InLength = distanza di ingresso (se -1 il punto è interno, se -2 il punto è esterno e il raggio non interseca lo Zmap)
// OutLength = distanza di uscita
bool
VolZmap::GetDepthWithVoxel( const Point3d& ptPLoc, const Vector3d& vtDir, double& dInLength, double& dOutLength) const
{
// Porto punto e vettore della retta nel sistema Zmap
Point3d ptP = ptPLoc ;
ptP.ToLoc( m_MapFrame[0]) ;
Vector3d vtD = vtDir ;
vtD.ToLoc( m_MapFrame[0]) ;
vtD.Normalize() ;
// Parametri di intersezione retta BBox dello Zmap
double dU1, dU2 ;
// Intersezione fra semiretta e BBox dello Zmap
bool bLineBBoxInters = IntersLineZMapBBox( ptP, vtD, 0, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
// Semiretta esterna al box dello Zmap quindi esterna anche allo Zmap
if ( ! bLineBBoxInters) {
dInLength = - 2 ;
dOutLength = - 2 ;
return true ;
}
// Indici del voxel corrente
int nVoxI, nVoxJ, nVoxK ;
// Determino il voxel di partenza
if ( ! GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
if ( ! GetPointVoxel( ptP + dU1 * vtD, nVoxI, nVoxJ, nVoxK))
return false ;
}
// Indici dell'ultimo voxel
int nVxEndI, nVxEndJ, nVxEndK ;
// Determino il voxel finale
if ( ! GetPointVoxel( ptP + dU2 * vtD, nVxEndI, nVxEndJ, nVxEndK))
return false ;
// Struttura studio dell'intersezione
struct LineTriaInt {
double dPar ;
double dDot ;
} ;
std::vector<std::vector<LineTriaInt>> IntMatrix ;
int nStI = min( nVoxI, nVxEndI) ;
int nStJ = min( nVoxJ, nVxEndJ) ;
int nStK = min( nVoxK, nVxEndK) ;
int nEnI = max( nVoxI, nVxEndI) ;
int nEnJ = max( nVoxJ, nVxEndJ) ;
int nEnK = max( nVoxK, nVxEndK) ;
for ( int nI = nStI ; nI <= nEnI ; ++ nI) {
for ( int nJ = nStJ ; nJ <= nEnJ ; ++ nJ) {
for ( int nK = nStK ; nK <= nEnK ; ++ nK) {
Point3d ptMin( ( nI + 0.5) * m_dStep,
( nJ + 0.5) * m_dStep,
( nK + 0.5) * m_dStep) ;
Point3d ptMax( ( nI + 1.5) * m_dStep,
( nJ + 1.5) * m_dStep,
( nK + 1.5) * m_dStep) ;
if ( IsValidVoxel( nI, nJ, nK) &&
IntersLineBox( ptP, vtD, ptMin, ptMax)) {
// Analisi del voxel
int nCbType ;
TRIA3DLIST lstTria ;
ProcessCube( nI, nJ, nK, nCbType, lstTria) ;
// Se il voxel contiene triangoli
if ( nCbType == VOX_ON_BOUNDARY) {
// Ciclo sui triangoli del voxel
for ( auto it = lstTria.begin() ; it != lstTria.end() ; ++it ) {
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) {
LineTriaInt NewInt ;
NewInt.dPar = ( ptLineTria1 - ptP) * vtD ;
NewInt.dDot = vtD * CurrTria.GetN() ;
std::vector<LineTriaInt> vSing ;
vSing.emplace_back( NewInt) ;
IntMatrix.emplace_back( vSing) ;
}
// altrimenti ci sono due intersezioni
else {
LineTriaInt NewInt1, NewInt2 ;
std::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) ;
}
}
}
}
}
}
}
// Ordino le intersezioni in base al parametro distanza con segno da ptP
for ( int nN = 0 ; nN < int( IntMatrix.size()) - 1 ; ++ nN) {
double dFP = ( IntMatrix[nN].size() == 2 ? 0.5 * ( IntMatrix[nN][0].dPar + IntMatrix[nN][1].dPar) :
IntMatrix[nN][0].dPar) ;
double dLP = ( IntMatrix[nN+1].size() == 2 ? 0.5 * ( IntMatrix[nN+1][0].dPar + IntMatrix[nN+1][1].dPar) :
IntMatrix[nN+1][0].dPar) ;
if ( dFP > dLP)
swap( IntMatrix[nN], IntMatrix[nN+1]) ;
}
std::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]) ;
}
// Inizializzo le distanze di ingresso e uscita:
// dInLength diminuisce, dOutLength aumenta.
dInLength = INFINITO ;
dOutLength = - INFINITO ;
int nFirstPosN ;
int nN = 0 ;
for ( ; nN < int( vInt.size()) ; ++ nN) {
if ( vInt[nN].dPar >= 0) {
nFirstPosN = nN ;
break ;
}
}
if ( nN == int( vInt.size())) {
dInLength = - 2 ;
dOutLength = - 2 ;
return true ;
}
if ( nFirstPosN > 0) {
if ( vInt[nFirstPosN - 1].dDot < EPS_ZERO)
dInLength = -1 ;
}
else if ( nFirstPosN == 0) {
if ( vInt[nFirstPosN].dDot > - EPS_ZERO)
dInLength = -1 ;
}
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 &&
dInLength > vInt[nN].dPar)
dInLength = vInt[nN].dPar ;
}
return true ;
}
@@ -1161,3 +1359,5 @@ VolZmap::GetPartVolume( int nPart, double& dVol) const
return true ;
}