EgtGeomKernel 1.8k3 :

- miglioramenti a Zmap.
This commit is contained in:
Dario Sassi
2017-11-25 18:50:54 +00:00
parent 33d2690ec8
commit 4252497bb3
7 changed files with 702 additions and 711 deletions
+161 -88
View File
@@ -25,6 +25,9 @@
using namespace std ;
//----------------------------------------------------------------------------
// Punti e vettore devono esse espressi nel medesimo sistema di riferimento.
// Il box è allineato con gli assi di tale sistema di riferimento.
// Viene restituito true in caso di intersezione, false altrimenti.
bool
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const
{
@@ -34,6 +37,10 @@ VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d&
}
//----------------------------------------------------------------------------
// Punti e vettore devono esse espressi nel medesimo sistema di riferimento.
// Il box è allineato con gli assi di tale sistema di riferimento.
// In dU1, dU2 vengono restituiti i parametri a cui si trovano le intersezioni.
// Viene restituito true in caso di intersezione, false altrimenti.
bool
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const
@@ -95,17 +102,25 @@ VolZmap::IntersLineZMapLattice( const Point3d& ptP, const Vector3d& vtV, double&
}
//----------------------------------------------------------------------------
// Trova le intersezioni di una retta, definita tramite un suo punto e il vettore della direzione,
// e il bounding box dello Zmap. Punto e vettore devono essere espressi nel sistema di riferimento
// intrinseco dello Zmap. Se vi è intersezione viene restitutito true, false altrimenti.
// Se vi è intersezione in dU1 e dU2 vengono restituiti i parametri a cui avvengono le intersezioni.
bool
VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, double& dU1, double& dU2) const
VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const
{
// Punti estremi del box dello Zmap
Point3d ptMin = ORIG ;
Point3d ptMax = ptMin + Vector3d( m_nNx[nGrid] * m_dStep, m_nNy[nGrid] * m_dStep, m_dMaxZ[nGrid]) ;
Point3d ptMax = ptMin + Vector3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0]) ;
return IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) ;
}
//----------------------------------------------------------------------------
// Trova le intersezioni fra una retta e un dexel parallelepipedale (gli intervalli sono
// parallelepipdi). Punto e vettore devono essere espressi nel sistema grilgia che coincide
// 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,
double& dU1, double& dU2) const
@@ -144,6 +159,10 @@ VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int
}
//----------------------------------------------------------------------------
// Trova le intersezioni fra una semi-retta e un dexel parallelepipedale (gli intervalli sono
// parallelepipdi). Punto e vettore devono essere espressi nel sistema grilgia che coincide
// 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,
double& dU1, double& dU2) const
@@ -196,8 +215,8 @@ VolZmap::GetDepth( const Point3d& ptPLoc, const Vector3d& vtDLoc, double& dInLen
{
Point3d ptP = ptPLoc ;
Vector3d vtD = vtDLoc ;
ptP.ToLoc( m_MapFrame[0]) ;
vtD.ToLoc( m_MapFrame[0]) ;
ptP.ToLoc( m_MapFrame) ;
vtD.ToLoc( m_MapFrame) ;
if ( bExact)
return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ;
@@ -212,12 +231,10 @@ VolZmap::GetDepth( const Point3d& ptPLoc, const Vector3d& vtDLoc, double& dInLen
// OutLength = distanza di uscita
bool
VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dInLength, double& dOutLength) const
{
int nGrid = 0 ;
{
// Intersezione fra semiretta e BBox dello Zmap
double dU1, dU2 ;
bool bTest = IntersLineZMapBBox( ptP, vtV, nGrid, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
bool bTest = IntersLineZMapBBox( ptP, vtV, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
// Semiretta esterna al box dello Zmap quindi esterna anche allo Zmap
if ( ! bTest) {
@@ -226,88 +243,144 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
return true ;
}
Point3d ptI, ptF ;
// Una sola intersezione valida ( punto interno, intersezione valida 2)
if ( dU1 < 0 && dU2 > 0) {
ptI = ptP ;
ptF = ptP + dU2 * vtV ;
}
// due soluzioni valide ( punto esterno)
else {
ptI = ptP + dU1 * vtV ;
ptF = ptP + dU2 * vtV ;
}
// Inizializzo distanze
dInLength = INFINITO ;
dOutLength = - INFINITO ;
double dInLen[3] ;
double dOutLen[3] ;
// Determino asse di spostamento maggiore
bool bOnX = ( abs( ptF.y - ptI.y) <= abs( ptF.x - ptI.x)) ;
// Ciclo sulle griglie
for ( int nGrid = 0 ; nGrid < int( m_nMapNum) ; ++ nGrid) {
// Movimento crescente su asse di movimento principale
if ( ( bOnX && ptF.x < ptI.x) || ( ! bOnX && ptF.y < ptI.y) )
swap( ptI, ptF) ;
Point3d ptP0 = ptP ;
Vector3d vtV0 = vtV ;
// Pendenza
double dDeltaX = ( ptF.x - ptI.x) ;
double dDeltaY = ( ptF.y - ptI.y) ;
double dM = 0 ;
if ( bOnX && abs( dDeltaX) > EPS_SMALL)
dM = dDeltaY / dDeltaX ;
else if ( ! bOnX && abs( dDeltaY) > EPS_SMALL)
dM = dDeltaX / dDeltaY ;
// 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( ptP, vtV, nGrid, i, j, dU1, dU2)) {
dInLength = min( dInLength, dU1) ;
dOutLength = max( dOutLength, dU2) ;
}
// Calcolo spostamento (a destra o sopra)
if ( bOnX) {
double dMoveX = ( ( i + 1) * m_dStep - ptI.x) ;
double dMoveY = dMoveX * dM ;
double dY = ptI.y + dMoveY ;
int nNewJ = Clamp( int( floor( dY / m_dStep)), 0, m_nNy[nGrid] - 1) ;
if ( nNewJ != j)
j = nNewJ ;
else
++ i ;
Point3d ptI, ptF ;
// Una sola intersezione valida ( punto interno, intersezione valida 2)
if ( dU1 < 0 && dU2 > 0) {
ptI = ptP ;
ptF = ptP + dU2 * vtV ;
}
// due soluzioni valide ( punto esterno)
else {
double dMoveY = ( ( j + 1) * m_dStep - ptI.y) ;
double dMoveX = dMoveY * dM ;
double dX = ptI.x + dMoveX ;
int nNewI = Clamp( int( floor( dX / m_dStep)), 0, m_nNx[nGrid] - 1) ;
if ( nNewI != i)
i = nNewI ;
else
++ j ;
ptI = ptP + dU1 * vtV ;
ptF = ptP + dU2 * vtV ;
}
// Passo dal sistema intrinseco alla griglia
if ( nGrid == 1) {
swap( ptP0.y, ptP0.z) ;
swap( ptP0.x, ptP0.z) ;
swap( vtV0.y, vtV0.z) ;
swap( vtV0.x, vtV0.z) ;
swap( ptI.y, ptI.z) ;
swap( ptI.x, ptI.z) ;
swap( ptF.y, ptF.z) ;
swap( ptF.x, ptF.z) ;
}
else if ( nGrid == 2) {
swap( ptP0.x, ptP0.z) ;
swap( ptP0.y, ptP0.z) ;
swap( vtV0.x, vtV0.z) ;
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) ;
}
// 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) ;
double dM = 0 ;
if ( bOnX && abs( dDeltaX) > EPS_SMALL)
dM = dDeltaY / dDeltaX ;
else if ( ! bOnX && abs( dDeltaY) > EPS_SMALL)
dM = dDeltaX / dDeltaY ;
// 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) ;
double dMoveY = dMoveX * dM ;
double dY = ptI.y + dMoveY ;
int nNewJ = Clamp( int( floor( dY / m_dStep)), 0, m_nNy[nGrid] - 1) ;
if ( nNewJ != j)
j = nNewJ ;
else
++ i ;
}
else {
double dMoveY = ( ( j + 1) * m_dStep - ptI.y) ;
double dMoveX = dMoveY * dM ;
double dX = ptI.x + dMoveX ;
int nNewI = Clamp( int( floor( dX / m_dStep)), 0, m_nNx[nGrid] - 1) ;
if ( nNewI != i)
i = nNewI ;
else
++ j ;
}
}
// Se non abbiamo incontrato materiale
if ( dInLen[nGrid] > dOutLen[nGrid] - EPS_SMALL) {
dInLen[nGrid] = - 2 ;
dOutLen[nGrid] = - 2 ;
}
// Se parto dall'interno
else if ( dInLen[nGrid] < - EPS_SMALL)
dInLen[nGrid] = - 1 ;
}
// Se non abbiamo incontrato materiale
if ( dInLength > dOutLength - EPS_SMALL) {
if ( m_nMapNum == 1) {
dInLength = dInLen[0] ;
dOutLength = dOutLen[0] ;
return true ;
}
if ( abs( dInLen[0] + 2) < EPS_SMALL &&
abs( dInLen[1] + 2) < EPS_SMALL &&
abs( dInLen[2] + 2) < EPS_SMALL) {
dInLength = - 2 ;
dOutLength = - 2 ;
return true ;
}
// Se parto dall'interno
if ( dInLength < - EPS_SMALL)
dInLength = - 1 ;
else {
dInLength = INFINITO ;
dOutLength = - INFINITO ;
for ( int nGr = 0 ; nGr < 3 ; ++ nGr) {
if ( dInLen[nGr] > - 2 && dInLen[nGr] < dInLength)
dInLength = dInLen[nGr] ;
if ( dOutLen[nGr] > - 2 && dOutLen[nGr] > dOutLength)
dOutLength = dOutLen[nGr] ;
}
}
return true ;
}
@@ -325,7 +398,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
double dU1, dU2 ;
// Intersezione fra semiretta e BBox dello Zmap
bool bLineBBoxInters = IntersLineZMapBBox( ptP, vtD, 0, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
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 ;
@@ -415,8 +488,8 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT ||
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
nIntType == ILTT_EDGE ||
nIntType == ILTT_IN) {
LineTriaInt NewInt ;
NewInt.dPar = ( ptLineTria1 - ptP) * vtD ;
NewInt.dDot = vtD * CurrTria.GetN() ;
@@ -521,7 +594,7 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
// lo porto nel riferimento intrinseco dello Zmap
b3Box.LocToLoc( frBox, m_MapFrame[0]) ;
b3Box.LocToLoc( frBox, m_MapFrame) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
@@ -538,12 +611,12 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] -1) ;
// Vettore direzione dei dexel nel riferimento del Box
Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame[0], frBox) ;
Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame, frBox) ;
// Riferimento intrinseco dei dexel nel riferimento del box
Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame[0], frBox) ;
Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame[0], frBox) ;
Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame[0], frBox) ;
Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame, frBox) ;
// Ciclo di intersezione dei dexel con il BBox
for ( int i = nStI ; i <= nEnI ; ++ i) {
@@ -1414,7 +1487,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, POCRVVECTOR& vpLoop) cons
return false ;
// Porto il piano nel sistema Zmap
Plane3d plPlaneL = plPlane ;
plPlaneL.ToLoc( m_MapFrame[0]) ;
plPlaneL.ToLoc( m_MapFrame) ;
// Vettore del piano
Vector3d vtNL = plPlaneL.GetVersN() ;
@@ -1466,7 +1539,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, POCRVVECTOR& vpLoop) cons
return false ;
}
pLoop->SetExtrusion( vtNL) ;
pLoop->ToGlob( m_MapFrame[0]) ;
pLoop->ToGlob( m_MapFrame) ;
// Se normali controverse, devo invertire il verso del loop.
if ( nSign < 0)
pLoop->Invert() ;