EgtGeomKernel :

- altra correzione a MC_Table per Zmap
- in Zmap ad AvoidBox, AvoidCylinder e AvoidSphere aggiunto parametro dSafeDist e migliorate queste funzioni.
This commit is contained in:
Dario Sassi
2019-04-08 09:58:57 +00:00
parent 541de9ac58
commit 59a2cfbfed
4 changed files with 123 additions and 33 deletions
+112 -19
View File
@@ -672,13 +672,23 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
//----------------------------------------------------------------------------
bool
VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist) const
{
// BBox
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
// lo porto nel riferimento intrinseco dello Zmap
b3Box.LocToLoc( frBox, m_MapFrame) ;
// Sistemazioni per distanza di sicurezza
if ( dSafeDist > EPS_SMALL)
b3Box.Expand( dSafeDist) ;
// Riferimento nell'angolo con coordinate minime
Point3d ptMin = b3Box.GetMin() ; ptMin.ToGlob( frBox) ;
Frame3d frB = frBox ; frB.ChangeOrig( ptMin) ;
Vector3d vtDg = b3Box.GetMax() - b3Box.GetMin() ;
b3Box.Set( ORIG, ORIG + vtDg) ;
// Lo porto nel riferimento intrinseco dello Zmap
b3Box.LocToLoc( frB, 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])) ;
@@ -695,12 +705,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, frBox) ;
Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame, frB) ;
// Riferimento intrinseco dei dexel nel riferimento del box
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) ;
Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame, frB) ;
Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame, frB) ;
Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame, frB) ;
// Ciclo di intersezione dei dexel con il BBox
for ( int i = nStI ; i <= nEnI ; ++ i) {
@@ -722,7 +732,7 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
else if ( k == 4)
ptT += - 0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ;
double dZmin, dZmax ;
if ( IntersLineBox( ptT, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) {
if ( IntersLineBox( ptT, vtK, ORIG, ORIG + vtDg, 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))
@@ -738,12 +748,16 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
//----------------------------------------------------------------------------
bool
VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad) const
VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist) const
{
// Porto la sfera nel riferimento intrinseco dello Zmap
Point3d ptC = ptCenter ;
ptC.ToLoc( m_MapFrame) ;
// Aumento il raggio della distanza di sicurezza
if ( dSafeDist > EPS_SMALL)
dRad += dSafeDist ;
// BBox della sfera
BBox3d b3Box( ptC) ;
b3Box.Expand( dRad) ;
@@ -782,9 +796,9 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad) const
else if ( k == 4)
ptT += - 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ;
Point3d ptI1, ptI2 ;
if ( IntersLineSphere( ptT, Z_AX, ptC, dRad, ptI1, ptI2) != ILST_NO) {
double dZmin = ptI1.z ;
double dZmax = ptI2.z ;
if ( ::IntersLineSphere( ptT, Z_AX, ptC, dRad, ptI1, ptI2) != ILST_NO) {
double dZmin = min( ptI1.z, ptI2.z) ;
double dZmax = max( ptI1.z, ptI2.z) ;
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))
@@ -800,8 +814,89 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad) const
//----------------------------------------------------------------------------
bool
VolZmap::AvoidCylinder( const Frame3d& frCyl, double dL, double dR) const
VolZmap::AvoidCylinder( const Frame3d& frCyl, double dH, double dR, double dSafeDist) const
{
// Porto il cilindro nel riferimento intrinseco dello Zmap
Frame3d frC = frCyl ;
frC.ToLoc( m_MapFrame) ;
// Se altezza negativa, sposto riferimento da faccia sopra a quella sotto
if ( dH < 0) {
frC.Translate( dH * frC.VersZ()) ;
dH = - dH ;
}
// Sistemazioni per distanza di sicurezza
if ( dSafeDist > EPS_SMALL) {
frC.Translate( - dSafeDist * frC.VersZ()) ;
dH += 2 * dSafeDist ;
dR += dSafeDist ;
}
// BBox del cilindro
Vector3d vtDirL = frC.VersZ() ;
BBox3d b3Box( frC.Orig()) ;
b3Box.Add( frC.Orig() + frC.VersZ() * dH) ;
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
b3Box.Expand( 0, dR, dR) ;
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
b3Box.Expand( dR, 0, dR) ;
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
b3Box.Expand( dR, dR, 0) ;
else {
double dExpandX = dR * sqrt( 1 - vtDirL.x * vtDirL.x) ;
double dExpandY = dR * sqrt( 1 - vtDirL.y * vtDirL.y) ;
double dExpandZ = dR * sqrt( 1 - vtDirL.z * vtDirL.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
return true ;
// Limiti su indici
int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nNx[0] -1) ;
int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nNx[0] -1) ;
int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nNy[0] -1) ;
int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] -1) ;
// Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
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 ;
for ( int k = 0 ; k < 5 ; ++ k) {
Point3d ptT = ORIG + ( i + 0.5) * m_dStep * X_AX + ( j + 0.5) * m_dStep * Y_AX ;
if ( k == 0)
;
else if ( k == 1)
ptT += - 0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ;
else if ( k == 2)
ptT += + 0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ;
else if ( k == 3)
ptT += + 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ;
else if ( k == 4)
ptT += - 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ;
Point3d ptI1, ptI2 ;
Vector3d vtN1, vtN2 ;
if ( IntersLineCylinder( ptT, Z_AX, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
double dZmin = min( ptI1.z, ptI2.z) ;
double dZmax = max( ptI1.z, ptI2.z) ;
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 ;
}
}
}
}
}
return true ;
}
@@ -813,7 +908,7 @@ VolZmap::AvoidCylinder( const Frame3d& frCyl, double dL, double dR) const
bool
VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2)
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
{
// Porto la linea nel riferimento del cilindro
Point3d ptP = ptLineSt ; ptP.ToLoc( CylFrame) ;
@@ -880,8 +975,6 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
// Punti di intersezione con la superficie del cilindro
ptInt1 = ptP + vdRoots[0] * vtV ;
ptInt2 = ptP + vdRoots[1] * vtV ;
if ( ptInt1.z > ptInt2.z)
swap( ptInt1, ptInt2) ;
// Determino le normali
vtN1.Set( -ptInt1.x, -ptInt1.y, 0) ;
vtN1.Normalize() ;
@@ -938,7 +1031,7 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
bool
VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir,
const Frame3d& ConusFrame, double dTan, double dMinH, double dMaxH, bool bTapLow, bool bTapUp,
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2)
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
{
// Porto la linea nel riferimento del cono
Point3d ptP = ptLineSt ; ptP.ToLoc( ConusFrame) ;
@@ -1072,7 +1165,7 @@ bool
VolZmap::IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen,
bool bTapLow, bool bTapUp,
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2)
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
{
// Se il cilindrico ellittico degenera in un piano, non bisogna tagliare
if ( abs( dLongMvLen) < EPS_SMALL)
@@ -1210,7 +1303,7 @@ VolZmap::IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d&
bool
VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir,
const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaZ,
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2)
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
{
// Controllo sulle dimensioni lineari affinché sia valido il poliedro
if ( dLenX <= EPS_SMALL || dLenY <= EPS_SMALL || dLenZ <= EPS_SMALL)