diff --git a/BBox3d.cpp b/BBox3d.cpp
index 12b14fe..da639aa 100644
--- a/BBox3d.cpp
+++ b/BBox3d.cpp
@@ -53,7 +53,8 @@ BBox3d::Set( double dX1, double dY1, double dZ1, double dX2, double dY2, double
bool
BBox3d::IsValid( void) const
{
- return ( m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
+ return ( m_ptMin.IsValid() && m_ptMax.IsValid() &&
+ m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
m_ptMin.y < ( m_ptMax.y + EPS_SMALL) &&
m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ;
}
@@ -447,69 +448,141 @@ BBox3d::EnclosesXY( const BBox3d& b3Box) const
//----------------------------------------------------------------------------
bool
-BBox3d::Overlaps( const BBox3d& b3B) const
+BBox3d::Overlaps( const BBox3d& b3Box) const
{
- if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
+ if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
- if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
+ if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
- if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
+ if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
-BBox3d::OverlapsXY( const BBox3d& b3B) const
+BBox3d::OverlapsXY( const BBox3d& b3Box) const
{
- if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
+ if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
- if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
+ if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
return true ;
}
//----------------------------------------------------------------------------
-bool
-BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const
+inline bool
+TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
+ const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
{
- if ( ! IsValid() || ! b3B.IsValid())
+ if ( vtAx.IsSmall())
+ return false ;
+ double dLen = ( vtAx.IsNormalized() ? 1 : vtAx.Len()) ;
+ return ( abs( vtDiff * vtAx) >
+ abs( vtHe.x * vtAx.x) + abs( vtHe.y * vtAx.y) + abs( vtHe.z * vtAx.z) +
+ abs( vtHe2X * vtAx) + abs( vtHe2Y * vtAx) + abs( vtHe2Z * vtAx) + EPS_SMALL * dLen) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const
+{
+ // Verifico validità di entrambi i box
+ if ( ! IsValid() || ! b3Box.IsValid())
+ return false ;
+
+ // Centro e semiampiezza del box
+ Point3d ptCen = ( m_ptMin + m_ptMax) / 2 ;
+ Vector3d vtHe = ( m_ptMax - m_ptMin) / 2 ;
+ // Centro e semiampiezza dell'altro box
+ Point3d ptCen2 = GetToGlob( ( b3Box.m_ptMin + b3Box.m_ptMax) / 2, frBox) ;
+ Vector3d vtHe2X = GetToGlob( Vector3d( ( b3Box.GetDimX()) / 2, 0, 0), frBox) ;
+ Vector3d vtHe2Y = GetToGlob( Vector3d( 0, ( b3Box.GetDimY()) / 2, 0), frBox) ;
+ Vector3d vtHe2Z = GetToGlob( Vector3d( 0, 0, ( b3Box.GetDimZ()) / 2), frBox) ;
+ // Vettore tra i due centri
+ Vector3d vtDiff = ptCen2 - ptCen ;
+
+ // Verifico separazione sulle normali ai piani principali del riferimento globale
+ if ( TestSeparatingAxis( X_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Y_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Z_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+
+ // Verifico separazione sulle normali ai piani principali del secondo riferimento
+ if ( TestSeparatingAxis( frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+
+ // Verifico separazione sulle altre normali ottenute come prodotto vettoriali di quelle precedenti
+ if ( TestSeparatingAxis( X_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( X_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( X_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Y_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Y_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Y_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Z_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Z_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+ if ( TestSeparatingAxis( Z_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
+ return false ;
+
+ // Si sovrappongono
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+BBox3d::FindIntersection( const BBox3d& b3Box, BBox3d& b3Int) const
+{
+ if ( ! IsValid() || ! b3Box.IsValid())
return false ;
// verifico direttamente la sovrapposizione
- if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
+ if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
- if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
+ if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
- if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
+ if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
return false ;
// calcolo il box intersezione
- b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
- b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
- b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ;
- b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
- b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
- b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ;
+ b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
+ b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
+ b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ;
+ b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
+ b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
+ b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ;
return true ;
}
//----------------------------------------------------------------------------
bool
-BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const
+BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const
{
- if ( ! IsValid() || ! b3B.IsValid())
+ if ( ! IsValid() || ! b3Box.IsValid())
return false ;
// verifico direttamente la sovrapposizione
- if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
+ if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
- if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
+ if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
// calcolo il box intersezione
- b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
- b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
- b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3B.m_ptMin.z) ;
- b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
- b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
- b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3B.m_ptMax.z) ;
+ b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
+ b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
+ b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ;
+ b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
+ b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
+ b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ;
return true ;
}
diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp
index d03bc8a..ba73ba0 100644
--- a/CAvToolSurfTm.cpp
+++ b/CAvToolSurfTm.cpp
@@ -301,11 +301,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
b3Tool.Add( ptTL) ;
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
- if ( vtDirL.IsXplus() || vtDirL.IsXminus())
+ if ( vtDirL.IsX())
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
- else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
+ else if ( vtDirL.IsY())
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
- else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
+ else if ( vtDirL.IsZ())
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
else {
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
diff --git a/CDeBoxClosedSurfTm.cpp b/CDeBoxClosedSurfTm.cpp
index ca39b66..6b29905 100644
--- a/CDeBoxClosedSurfTm.cpp
+++ b/CDeBoxClosedSurfTm.cpp
@@ -23,17 +23,17 @@ using namespace std ;
bool
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
{
- // recupero BBox del poliedro
+ // Recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ;
- // calcolo il BBox del parallelepipedo
- BBox3d b3Box( ORIG, ORIG + vtDiag) ;
+ // Calcolo il BBox del parallelepipedo
+ BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
if ( dSafeDist > EPS_SMALL)
- b3Box.Expand( dSafeDist) ;
- b3Box.ToGlob( frBox) ;
+ b3BoxL.Expand( dSafeDist) ;
+ BBox3d b3Box = GetToGlob( b3BoxL, frBox) ;
// Se i BBox non interferiscono, non c'è collisione
- if ( ! b3Box.Overlaps( b3Poly))
+ if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
return false ;
- // recupero i triangoli che interferiscono con il box
+ // Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Box, vT) ;
for ( int nT : vT) {
@@ -46,7 +46,10 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
- // Verifico se il box è dentro la superficie tramite calcolo distanza minima.
+ // Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
+ if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
+ return false ;
+ // Verifico se il box è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptBoxCen = ORIG + vtDiag / 2 ;
ptBoxCen.ToGlob( frBox) ;
DistPointSurfTm DistBoxCenSurfCalc( ptBoxCen, Stm) ;
diff --git a/CDeClosedSurfTmClosedSurfTm.cpp b/CDeClosedSurfTmClosedSurfTm.cpp
index d625dc6..50c7158 100644
--- a/CDeClosedSurfTmClosedSurfTm.cpp
+++ b/CDeClosedSurfTmClosedSurfTm.cpp
@@ -35,60 +35,60 @@ using namespace std ;
bool
CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB, double dSafeDist)
{
- // Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
+ // Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
if ( ! ( SurfA.IsValid() && SurfB.IsValid()) || ! ( SurfA.IsClosed() && SurfB.IsClosed()))
return false ;
- // Se i box delle superfici non si intersecano, ho finito.
+ // Se i box delle superfici non si intersecano, ho finito.
BBox3d b3BoxA, b3BoxB ;
SurfA.GetLocalBBox( b3BoxA) ;
SurfB.GetLocalBBox( b3BoxB) ;
- // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
+ // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxA.Expand( dSafeDist) ;
- // Se i box non si sovrappongono, non c'è collisione. Ho finito.
+ // Se i box non si sovrappongono, non c'è collisione. Ho finito.
if ( ! b3BoxA.Overlaps( b3BoxB))
return false ;
- // Recupero i triangoli di B che interferiscono col box del triangolo di A
+ // Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vTriaIndex ;
SurfA.GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
- // Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
+ // Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
for ( int nTA : vTriaIndex) {
Triangle3d trTriaA ;
if ( ! ( SurfA.GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
continue ;
BBox3d b3BoxTriaA ;
trTriaA.GetLocalBBox( b3BoxTriaA) ;
- // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
+ // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxTriaA.Expand( dSafeDist) ;
- // Recupero i triangoli di B che interferiscono col box del triangolo di A
+ // Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vNearTria ;
SurfB.GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
- // Settare tutti i triangoli come già processati.
- // Al termine della chiamata i TFlags dei triangoli valgono 0.
+ // Settare tutti i triangoli come già processati.
+ // Al termine della chiamata i TFlags dei triangoli valgono 0.
SurfB.ResetTempInt() ;
- // Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
+ // Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
for ( int nTB : vNearTria) {
- // Recupero il triangolo corrente della superficie B.
- // Se triangolo non valido salto al successivo.
+ // Recupero il triangolo corrente della superficie B.
+ // Se triangolo non valido salto al successivo.
Triangle3d trTriaB ;
if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
continue ;
- // Se necessario considero l'offset
+ // Se necessario considero l'offset
if ( dSafeDist > EPS_SMALL) {
int nAdjTriaId[3] ;
SurfB.GetTriangleAdjacencies( nTB, nAdjTriaId) ;
- // Ciclo sui vertici del triangolo.
+ // Ciclo sui vertici del triangolo.
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
- // Se il triangolo adiacente al triangolo corrente su questo edge
- // non è stato processato, processo il vertice e l'edge.
+ // Se il triangolo adiacente al triangolo corrente su questo edge
+ // non è stato processato, processo il vertice e l'edge.
int nAdjTriaTempFlag ;
if ( ! ( SurfB.GetTriangleTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
continue ;
- // Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
+ // Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
return true ;
- // Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
+ // Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
Vector3d vtEdgeV = trTriaB.GetP( nVB) - trTriaB.GetP( ( nVB + 1) % 3) ;
double dEdgeLen = vtEdgeV.Len() ;
vtEdgeV /= dEdgeLen ;
@@ -97,18 +97,21 @@ CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB,
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
return true ;
}
- // Traslo il triangolo
+ // Traslo il triangolo
trTriaB.Translate( dSafeDist * trTriaB.GetN()) ;
}
- // Processo il triangolo: se i due triangoli collidono ho finito.
+ // Processo il triangolo: se i due triangoli collidono ho finito.
if ( CDeTriaTria( trTriaA, trTriaB))
return true ;
- // Segno il triangolo come processato: nTFlag = 1
+ // Segno il triangolo come processato: nTemp = 1
SurfB.SetTempInt( nTB, 1) ;
}
}
- // Non ho trovato collisioni fra triangoli delle superfici.
- // La collisione c'è se una superficie è dentro l'altra.
+ // Non ho trovato collisioni fra triangoli delle superfici.
+ // Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
+ if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
+ return false ;
+ // La collisione c'è se una superficie è dentro l'altra.
Point3d ptPointA, ptPointB ;
SurfA.GetFirstVertex( ptPointA) ;
SurfB.GetFirstVertex( ptPointB) ;
diff --git a/CDeConeFrustumClosedSurfTm.cpp b/CDeConeFrustumClosedSurfTm.cpp
index b01fcb3..f425e18 100644
--- a/CDeConeFrustumClosedSurfTm.cpp
+++ b/CDeConeFrustumClosedSurfTm.cpp
@@ -27,24 +27,25 @@ bool
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
double dSafeDist, const ISurfTriMesh& Stm)
{
- // Se il tronco di cono non è ben definito non ha senso proseguire.
+ // Se il tronco di cono non è ben definito non ha senso proseguire
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
return false ;
// Recupero BBox della trimesh
BBox3d b3Surf = Stm.GetAllTriaBox() ;
// Calcolo il BBox del tronco di cono
double dMaxRad = max( dBaseRad, dTopRad) ;
- BBox3d b3Cone( - dMaxRad, - dMaxRad, 0, dMaxRad, dMaxRad, dHeight) ;
+ BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0),
+ Point3d( dMaxRad, dMaxRad, dHeight)) ;
if ( dSafeDist > EPS_SMALL)
- b3Cone.Expand( dSafeDist) ;
- b3Cone.ToGlob( frCone) ;
+ b3ConeL.Expand( dSafeDist) ;
+ BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ;
// Se i BBox non interferiscono, non c'è collisione
- if ( ! b3Cone.Overlaps( b3Surf))
+ if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
return false ;
// Recupero i triangoli che interferiscono con il box del cono
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
- // Ciclo sui triangoli che interferiscono col box del cono
+ // Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox
for ( int nT : vT) {
Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) {
@@ -55,6 +56,9 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
+ // Se il BBox del tronco di cono non è interno a quello del poliedro e viceversa, non c'è collisione
+ if ( ! b3Surf.Encloses( b3Cone) && ! b3Cone.Encloses( b3Surf))
+ return false ;
// Verifico se il tronco di cono è dentro la superficie tramite calcolo distanza minima.
Point3d ptConeCen( 0, 0, dHeight / 2) ;
ptConeCen.ToGlob( frCone) ;
diff --git a/CDeConvexTorusClosedSurfTm.cpp b/CDeConvexTorusClosedSurfTm.cpp
index c8ef0b0..280cd13 100644
--- a/CDeConvexTorusClosedSurfTm.cpp
+++ b/CDeConvexTorusClosedSurfTm.cpp
@@ -23,42 +23,42 @@ using namespace std ;
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
// La funzione restituisce true in caso di collisione.
bool
-CDeConvexTorusClosedSurfTm( const Frame3d& frTorusFrame, double dRad1, double dRad2,
+CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
double dSafeDist, const ISurfTriMesh& Stm)
{
// I raggi devono essere non nulli e la superficie ben definita.
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
return false ;
- // Box del toro (sempre completo)
- BBox3d b3ConvTorusBox ;
- b3ConvTorusBox.Set( Point3d( - dRad1 - dRad2, - dRad1 - dRad2, - dRad2),
- Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
- // Aggiungo eventuale distanza di sicurezza
- if ( dSafeDist > EPS_SMALL)
- b3ConvTorusBox.Expand( dSafeDist) ;
- // Porto il box del toro nel riferimento della superficie (inteso some globale)
- b3ConvTorusBox.ToGlob( frTorusFrame) ;
// Box della superficie
- BBox3d b3SurfBox = Stm.GetAllTriaBox() ;
+ BBox3d b3Surf = Stm.GetAllTriaBox() ;
+ // Box del toro (sempre completo)
+ BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2),
+ Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
+ if ( dSafeDist > EPS_SMALL)
+ b3TorusL.Expand( dSafeDist) ;
+ BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ;
// Se i BBox non interferiscono, non c'è collisione
- if ( ! b3ConvTorusBox.Overlaps( b3SurfBox))
+ if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL))
return false ;
// Recupero i triangoli che interferiscono con il box del toro
INTVECTOR vT ;
- Stm.GetAllTriaOverlapBox( b3ConvTorusBox, vT) ;
- // Ciclo sui triangoli recuperati
+ Stm.GetAllTriaOverlapBox( b3Torus, vT) ;
+ // Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox
for ( int nT : vT) {
Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) {
- if ( CDeConvexTorusTria( frTorusFrame, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
+ if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
return true ;
}
}
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
- // Verifico se il toro è dentro la superficie tramite calcolo distanza minima.
- Point3d ptTorusOrig = frTorusFrame.Orig() ;
+ // Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
+ if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
+ return false ;
+ // Verifico se il toro è dentro la superficie tramite calcolo distanza minima del suo centro
+ Point3d ptTorusOrig = frTorus.Orig() ;
DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ;
// Se il toro è interno c'è collisione
return ( DistConeOrigSurfCalc.IsPointInside()) ;
diff --git a/CDeCylClosedSurfTm.cpp b/CDeCylClosedSurfTm.cpp
index 6bbe5d2..f8feab3 100644
--- a/CDeCylClosedSurfTm.cpp
+++ b/CDeCylClosedSurfTm.cpp
@@ -23,38 +23,42 @@ using namespace std ;
bool
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm)
{
- // recupero BBox del poliedro
+ // Recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ;
- // sistemazioni cilindro
- Frame3d frC = frCyl ;
+ // Sistemazioni cilindro
+ Frame3d frMyCyl = frCyl ;
if ( dH < 0) {
- frC.Translate( dH * frC.VersZ()) ;
+ frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
dH = - dH ;
}
- // calcolo il BBox del cilindro
- BBox3d b3Cyl( -dR, -dR, 0, dR, dR, dH) ;
+ // Calcolo il BBox del cilindro
+ BBox3d b3CylL( Point3d( -dR, -dR, 0),
+ Point3d( dR, dR, dH)) ;
if ( dSafeDist > EPS_SMALL)
- b3Cyl.Expand( dSafeDist) ;
- b3Cyl.ToGlob( frC) ;
+ b3CylL.Expand( dSafeDist) ;
+ BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ;
// Se i BBox non interferiscono, non c'è collisione
- if ( ! b3Cyl.Overlaps( b3Poly))
+ if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
return false ;
- // recupero i triangoli che interferiscono con il box del Cilindro
+ // Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
for ( int nT : vT) {
Triangle3d Tria ;
if ( Stm.GetTriangle( nT, Tria)) {
- if ( CDeCylTria( frC, dR, dH, dSafeDist, Tria))
+ if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria))
return true ;
}
}
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
- // Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima.
+ // Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
+ if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
+ return false ;
+ // Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptCylCen( 0, 0, dH / 2) ;
- ptCylCen.ToGlob( frC) ;
+ ptCylCen.ToGlob( frMyCyl) ;
DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ;
// Se il cilindro è interno c'è collisione
return ( DistCylCenSurfCalc.IsPointInside()) ;
diff --git a/CDeRectPrismoidClosedSurfTm.cpp b/CDeRectPrismoidClosedSurfTm.cpp
index 62e9da8..0c1d1e0 100644
--- a/CDeRectPrismoidClosedSurfTm.cpp
+++ b/CDeRectPrismoidClosedSurfTm.cpp
@@ -37,17 +37,18 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
// Calcolo il BBox del tronco di piramide
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
- BBox3d b3Pyr( -dMaxLenX / 2, -dMaxLenY / 2, 0., dMaxLenX / 2, dMaxLenY / 2, dHeight) ;
+ BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
+ Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
if ( dSafeDist > EPS_SMALL)
- b3Pyr.Expand( dSafeDist) ;
- b3Pyr.ToGlob( frPrismoid) ;
+ b3PyrL.Expand( dSafeDist) ;
+ BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ;
// Se i BBox non interferiscono, non c'è collisione
- if ( ! b3Pyr.Overlaps( b3Surf))
+ if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL))
return false ;
// Recupero i triangoli che interferiscono con il box del tronco di piramide.
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
- // Ciclo sui triangoli che interferiscono col box del tronco di piramide.
+ // Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox
for ( int nT : vT) {
Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) {
@@ -59,10 +60,13 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
- // Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima.
+ // Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
+ if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
+ return false ;
+ // Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptPyrCen( 0, 0, dHeight / 2) ;
ptPyrCen.ToGlob( frPrismoid) ;
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
- // C'è collisione se il tronco di piramide è interno.
+ // C'è collisione se il tronco di piramide è interno
return ( DistPyrCenSurfCalc.IsPointInside()) ;
}
diff --git a/CDeSpheClosedSurfTm.cpp b/CDeSpheClosedSurfTm.cpp
index cfbdec9..e6ab0c8 100644
--- a/CDeSpheClosedSurfTm.cpp
+++ b/CDeSpheClosedSurfTm.cpp
@@ -23,16 +23,16 @@ using namespace std ;
bool
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
{
- // recupero BBox del poliedro
+ // Recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ;
- // calcolo il BBox della sfera
+ // Calcolo il BBox della sfera
BBox3d b3Sphe( ptCen, dR) ;
if ( dSafeDist > EPS_SMALL)
b3Sphe.Expand( dSafeDist) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Sphe.Overlaps( b3Poly))
return false ;
- // recupero i triangoli che interferiscono con il box della Sfera
+ // Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
for ( int nT : vT) {
@@ -45,8 +45,11 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
- // Verifico se la sfera è dentro la superficie tramite calcolo distanza minima.
+ // Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
+ if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
+ return false ;
+ // Verifico se la sfera è dentro la superficie tramite calcolo distanza minima del suo centro
DistPointSurfTm DistCenSurfCalc( ptCen, Stm) ;
- // C'è collisione se la sfera è interna.
+ // C'è collisione se la sfera è interna.
return ( DistCenSurfCalc.IsPointInside()) ;
}
diff --git a/CurveArc.cpp b/CurveArc.cpp
index f78f842..b9f8fb9 100644
--- a/CurveArc.cpp
+++ b/CurveArc.cpp
@@ -824,10 +824,10 @@ CurveArc::Validate( void)
m_dAngCenDeg = - ANG_FULL ;
}
// eseguo il controllo
- m_nStatus = ( ( m_VtN.IsNormalized() && m_VtS.IsNormalized() &&
- AreOrthoApprox( m_VtN, m_VtS) &&
- m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
- abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
+ m_nStatus = ( ( m_PtCen.IsValid() &&
+ m_VtN.IsNormalized() && m_VtS.IsNormalized() && AreOrthoApprox( m_VtN, m_VtS) &&
+ m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
+ abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
}
return ( m_nStatus == OK) ;
diff --git a/CurveAux.cpp b/CurveAux.cpp
index 239b8df..4e0ba4d 100644
--- a/CurveAux.cpp
+++ b/CurveAux.cpp
@@ -294,7 +294,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea)
return false ;
// approssimo la curva con una polilinea
PolyLine PL ;
- crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
+ crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
// calcolo l'area
double dAreaXY = 0 ;
PL.GetAreaXY( dAreaXY) ;
@@ -313,7 +313,7 @@ CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea)
return false ;
// approssimo la curva con una polilinea
PolyLine PL ;
- crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
+ crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
// calcolo l'area
Plane3d plMyPlane ;
double dMyArea = 0 ;
@@ -364,9 +364,11 @@ CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine)
// altri dati per curva chiusa
double dAreaXY ;
if ( CurveGetAreaXY( crvC, dAreaXY)) {
- bool bCCW = ( dAreaXY > 0) ;
+ bool bCCW = ( dAreaXY > 0) ;
+ double dAreaUi = GetAreaInUiUnits( abs( dAreaXY), bMM) ;
+ int nDec = ( dAreaUi > 100 ? 1 : ( dAreaUi > 0.1 ? 3 : 6)) ;
sOut += string( "Closed") + ( bCCW ? " CCW" : " CW") + " AreaXY=" +
- ToString( GetAreaInUiUnits( abs( dAreaXY), bMM),1) + szNewLine ;
+ ToString( dAreaUi, nDec) + szNewLine ;
}
return true ;
@@ -728,7 +730,7 @@ FlattenCurve( const ICurve& crCrv, double dToler, double dAngToler, int nFlag)
return nullptr ;
// Verifico se curva già piatta
PolyLine PL ;
- if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
+ if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL))
return nullptr ;
bool bFlat = true ;
Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ;
diff --git a/CurveBezier.cpp b/CurveBezier.cpp
index ac0e967..3514473 100644
--- a/CurveBezier.cpp
+++ b/CurveBezier.cpp
@@ -424,6 +424,23 @@ CurveBezier::Load( NgeReader& ngeIn)
bool
CurveBezier::Validate( void)
{
+ if ( m_nStatus == TO_VERIFY) {
+ for ( const auto& ptP : m_vPtCtrl) {
+ if ( ! ptP.IsValid()) {
+ m_nStatus = ERR ;
+ break ;
+ }
+ }
+ }
+ if ( m_nStatus == TO_VERIFY) {
+ for ( const auto& dWe : m_vWeCtrl) {
+ if ( ! isfinite( dWe)) {
+ m_nStatus = ERR ;
+ break ;
+ }
+ }
+ }
+
if ( m_nStatus == TO_VERIFY)
m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ;
diff --git a/CurveComposite.cpp b/CurveComposite.cpp
index a642003..46d3ce8 100644
--- a/CurveComposite.cpp
+++ b/CurveComposite.cpp
@@ -849,9 +849,9 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
return false ;
// ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali)
int nCount = 0 ;
- for ( const ICurve* pCrv = GetFirstCurve() ;
+ for ( const ICurve* pCrv = GetCurve( nCount) ;
pCrv != nullptr ;
- pCrv = GetNextCurve(), ++ nCount) {
+ pCrv = GetCurve( ++ nCount)) {
switch ( pCrv->GetType()) {
case CRV_LINE :
// punto finale
@@ -985,7 +985,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const
return false ;
// approssimo la curva con una polilinea
PolyLine PL ;
- if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL, PL))
+ if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL_INT, PL))
return false ;
// calcolo il centro mediante PolygonPlane
Point3d ptP ;
@@ -1313,7 +1313,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
- if ( nType == APL_SPECIAL) {
+ if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) {
// eseguo approssimazione
double dStartPar = 0 ;
for ( auto& pCrv : m_CrvSmplS) {
@@ -1324,6 +1324,18 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
PolyLine PLSmpl ;
if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl))
return false ;
+ // se richiesto almeno un punto interno con curve non rettilinee e ci sono solo gli estremi
+ if ( nType == APL_SPECIAL_INT && pCrv->GetType() != CRV_LINE && PLSmpl.GetPointNbr() == 2) {
+ // aggiungo il punto interno
+ Point3d ptMid ;
+ if ( ! pCrv->GetMidPoint( ptMid))
+ return false ;
+ double dU ;
+ PLSmpl.GetLastU( dU) ;
+ dU /= 2 ;
+ PNTULIST& List = PLSmpl.GetUPointList() ;
+ List.insert( ++ List.begin(), { ptMid, dU}) ;
+ }
// ripristino estrusione e spessore della curva semplice (annullandoli)
pCrv->SetExtrusion( V_NULL) ;
pCrv->SetThickness( 0) ;
diff --git a/CurveLine.cpp b/CurveLine.cpp
index 79ee00a..dbdc8c1 100644
--- a/CurveLine.cpp
+++ b/CurveLine.cpp
@@ -259,7 +259,7 @@ bool
CurveLine::Validate( void)
{
if ( m_nStatus == TO_VERIFY)
- m_nStatus = ( ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
+ m_nStatus = ( m_PtStart.IsValid() && m_PtEnd.IsValid() && ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
return ( m_nStatus == OK) ;
}
diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index 40c1ad1..f04937a 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index ef86681..73e0726 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -331,6 +331,8 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
@@ -600,6 +602,8 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index ce84aa1..13b53ad 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -473,6 +473,11 @@
File di origine\Base
+
+ File di origine\GeoInters
+
+
+ File di origine\GeoInters
@@ -1107,6 +1112,10 @@
File di intestazione
+
+ File di intestazione
+
+
File di intestazione
diff --git a/Frame3d.cpp b/Frame3d.cpp
index 0338468..0216924 100644
--- a/Frame3d.cpp
+++ b/Frame3d.cpp
@@ -456,6 +456,9 @@ Frame3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
bool
Frame3d::Verify( void)
{
+ // verifica origine
+ if ( ! m_ptOrig.IsValid())
+ return false ;
// verifica della ortogonalità dei versori e del senso destrorso
double dOrtXY = m_vtVersX * m_vtVersY ;
double dOrtYZ = m_vtVersY * m_vtVersZ ;
diff --git a/IntersLineCone.cpp b/IntersLineCone.cpp
new file mode 100644
index 0000000..97f5d61
--- /dev/null
+++ b/IntersLineCone.cpp
@@ -0,0 +1,138 @@
+//----------------------------------------------------------------------------
+// EgalTech 2023-2023
+//----------------------------------------------------------------------------
+// File : IntersLineCone.cpp Data : 16.05.23 Versione : 2.5e3
+// Contenuto : Implementazione della intersezione linea/tronco di cono.
+//
+//
+//
+// Modifiche : 16.05.23 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "IntersLineCone.h"
+#include "IntersLineCyl.h"
+#include "/EgtDev/Include/ENkPolynomialRoots.h"
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+// Linea e tronco di cono sono nel medesimo riferimento.
+// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
+// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
+//----------------------------------------------------------------------------
+bool
+IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
+ double dRadMin, double dRadMax, double dHeight,
+ double& dU1, double& dU2)
+{
+ // Verifico il versore
+ if ( vtL.IsSmall())
+ return false ;
+
+ // Verifico il tronco di cono
+ if ( ( dRadMin < EPS_SMALL && dRadMax < EPS_SMALL) || dHeight < EPS_SMALL)
+ return false ;
+
+ // Se è un cilindro, rimando a questo
+ if ( abs( dRadMax - dRadMin) < EPS_SMALL)
+ return IntersLineCyl( ptL, vtL, ( dRadMin + dRadMax) / 2, dHeight, dU1, dU2) ;
+
+ // Se raggi invertiti, li scambio
+ if ( dRadMin > dRadMax)
+ swap( dRadMin, dRadMax) ;
+
+ // Tangente dell'angolo di semi-apertura del cono
+ double dTanTheta = ( dRadMax - dRadMin) / dHeight ;
+ double dSqTanTheta = dTanTheta * dTanTheta ;
+ double dSqCosTheta = 1 / ( 1 + dSqTanTheta) ;
+
+ // Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non giace sul cono)
+ int nBasInt = 0 ;
+ if ( abs( vtL.z) > EPS_ZERO) {
+ // le linee tangenti al cono non sono considerate intersecanti
+ bool bSameHAng = ( abs( abs( vtL.x) - abs( vtL.y)) < EPS_SMALL && abs( dSqCosTheta - vtL.z * vtL.z) < 2 * abs( vtL.z) * EPS_SMALL) ;
+ double EpsRad = ( bSameHAng ? - EPS_SMALL : EPS_SMALL) ;
+ Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
+ if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRadMin * dRadMin + 2 * dRadMin * EpsRad) {
+ dU1 = ( ptInt1 - ptL) * vtL ;
+ nBasInt += 1 ;
+ }
+ Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
+ if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRadMax * dRadMax + 2 * dRadMax * EpsRad) {
+ dU2 = ( ptInt2 - ptL) * vtL ;
+ nBasInt += 2 ;
+ }
+ }
+
+ // Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
+ if ( nBasInt == 3) {
+ if ( dU1 > dU2)
+ swap( dU1, dU2) ;
+ // Trovate intersezioni
+ return true ;
+ }
+
+ // Posizione del vertice del cono
+ double dDeltaH = ( dRadMin < EPS_SMALL ? 0 : dRadMin / dTanTheta) ;
+ // Sposto il punto di passaggio della linea di conseguenza
+ Point3d ptMyL = ptL + Z_AX * dDeltaH ;
+
+ // Determino le intersezioni con la superficie laterale del cono
+ DBLVECTOR vdCoeff{ ptMyL.x * ptMyL.x + ptMyL.y * ptMyL.y - ptMyL.z * ptMyL.z * dSqTanTheta,
+ 2 * ( ptMyL.x * vtL.x + ptMyL.y * vtL.y - ptMyL.z * vtL.z * dSqTanTheta),
+ vtL.x * vtL.x + vtL.y * vtL.y - vtL.z * vtL.z * dSqTanTheta} ;
+ DBLVECTOR vdRoots ;
+ int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
+
+ // Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del tronco di cono
+ if ( nRoot == 2) {
+ double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
+ if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
+ -- nRoot ;
+ }
+ if ( nRoot >= 1) {
+ double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
+ if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
+ if ( nRoot == 2)
+ vdRoots[0] = vdRoots[1] ;
+ -- nRoot ;
+ }
+ }
+
+ // Due soluzioni: la retta interseca due volte la superficie laterale
+ if ( nRoot == 2) {
+ dU1 = vdRoots[0] ;
+ dU2 = vdRoots[1] ;
+ if ( dU1 > dU2)
+ swap( dU1, dU2) ;
+ // Trovate intersezioni
+ return true ;
+ }
+
+ // Una soluzione : la retta interseca la superficie laterale e un piano
+ else if ( nRoot == 1) {
+ // Se piano superiore
+ if ( nBasInt == 2) {
+ dU1 = vdRoots[0] ;
+ }
+ // altrimenti piano inferiore
+ else if ( nBasInt == 1) {
+ dU2 = vdRoots[0] ;
+ }
+ // altrimenti niente
+ else
+ return false ;
+ if ( dU1 > dU2)
+ swap( dU1, dU2) ;
+ // Trovate intersezioni
+ return true ;
+ }
+
+ // Nessuna soluzione : nessuna intersezione
+ else
+ return false ;
+}
diff --git a/IntersLineCone.h b/IntersLineCone.h
new file mode 100644
index 0000000..8ffa732
--- /dev/null
+++ b/IntersLineCone.h
@@ -0,0 +1,35 @@
+//----------------------------------------------------------------------------
+// EgalTech 2023-2023
+//----------------------------------------------------------------------------
+// File : IntersLineCone.h Data : 16.05.23 Versione : 2.5e3
+// Contenuto : Dichiarazione funzioni base per intersezione linea/cono tronco.
+//
+//
+//
+// Modifiche : 16.05.23 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "/EgtDev/Include/EGkPoint3d.h"
+
+//----------------------------------------------------------------------------
+// Linea e tronco di cono sono nel medesimo riferimento.
+// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
+// Con intersezione viene restituito true e i parametri in dU1 e dU2.
+//----------------------------------------------------------------------------
+bool
+IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
+ double dRadMin, double dRadMax, double dHeight,
+ double& dU1, double& dU2) ;
+
+//----------------------------------------------------------------------------
+inline bool
+TestIntersLineCone( const Point3d& ptL, const Vector3d& vtL,
+ double dRadMin, double dRadMax, double dHeight)
+{
+ double dU1, dU2 ;
+ return IntersLineCone( ptL, vtL, dRadMin, dRadMax, dHeight, dU1, dU2) ;
+}
diff --git a/IntersLineCyl.cpp b/IntersLineCyl.cpp
new file mode 100644
index 0000000..c78b3b7
--- /dev/null
+++ b/IntersLineCyl.cpp
@@ -0,0 +1,118 @@
+//----------------------------------------------------------------------------
+// EgalTech 2023-2023
+//----------------------------------------------------------------------------
+// File : IntersLineCyl.cpp Data : 16.05.23 Versione : 2.5e3
+// Contenuto : Implementazione della intersezione linea/cilindro.
+//
+//
+//
+// Modifiche : 16.05.23 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "IntersLineCyl.h"
+#include "/EgtDev/Include/ENkPolynomialRoots.h"
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+// Linea e cilindro sono nel medesimo riferimento.
+// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
+// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
+//----------------------------------------------------------------------------
+bool
+IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
+ double dRad, double dHeight,
+ double& dU1, double& dU2)
+{
+ // Verifico il versore
+ if ( vtL.IsSmall())
+ return false ;
+
+ // Verifico il cilindro
+ if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
+ return false ;
+
+ // Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
+ int nBasInt = 0 ;
+ if ( abs( vtL.z) > EPS_ZERO) {
+ // le linee tangenti al cilindro non sono considerate intersecanti
+ double EpsRad = ( vtL.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
+ Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
+ if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * EpsRad) {
+ dU1 = ( ptInt1 - ptL) * vtL ;
+ nBasInt += 1 ;
+ }
+ Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
+ if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * EpsRad) {
+ dU2 = ( ptInt2 - ptL) * vtL ;
+ nBasInt += 2 ;
+ }
+ }
+
+ // Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
+ if ( nBasInt == 3) {
+ if ( dU1 > dU2)
+ swap( dU1, dU2) ;
+ // Trovate intersezioni
+ return true ;
+ }
+
+ // Determino le intersezioni con la superficie laterale del cilindro
+ DBLVECTOR vdCoeff{ ptL.x * ptL.x + ptL.y * ptL.y - dRad * dRad,
+ 2 * ( ptL.x * vtL.x + ptL.y * vtL.y),
+ vtL.x * vtL.x + vtL.y * vtL.y} ;
+ DBLVECTOR vdRoots ;
+ int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
+
+ // Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
+ if ( nRoot == 2) {
+ double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
+ if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
+ -- nRoot ;
+ }
+ if ( nRoot >= 1) {
+ double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
+ if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
+ if ( nRoot == 2)
+ vdRoots[0] = vdRoots[1] ;
+ -- nRoot ;
+ }
+ }
+
+ // Due soluzioni: la retta interseca due volte la superficie laterale
+ if ( nRoot == 2) {
+ dU1 = vdRoots[0] ;
+ dU2 = vdRoots[1] ;
+ if ( dU1 > dU2)
+ swap( dU1, dU2) ;
+ // Trovate intersezioni
+ return true ;
+ }
+
+ // Una soluzione : la retta interseca la superficie laterale e un piano
+ else if ( nRoot == 1) {
+ // Se piano superiore
+ if ( nBasInt == 2) {
+ dU1 = vdRoots[0] ;
+ }
+ // altrimenti piano inferiore
+ else if ( nBasInt == 1) {
+ dU2 = vdRoots[0] ;
+ }
+ // altrimenti niente
+ else
+ return false ;
+ if ( dU1 > dU2)
+ swap( dU1, dU2) ;
+ // Trovate intersezioni
+ return true ;
+ }
+
+ // Nessuna soluzione : nessuna intersezione
+ else
+ return false ;
+}
diff --git a/IntersLineCyl.h b/IntersLineCyl.h
new file mode 100644
index 0000000..4448739
--- /dev/null
+++ b/IntersLineCyl.h
@@ -0,0 +1,35 @@
+//----------------------------------------------------------------------------
+// EgalTech 2023-2023
+//----------------------------------------------------------------------------
+// File : IntersLineCyl.h Data : 16.05.23 Versione : 2.5e3
+// Contenuto : Dichiarazione funzioni base per intersezione linea/cilindro.
+//
+//
+//
+// Modifiche : 16.05.23 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "/EgtDev/Include/EGkPoint3d.h"
+
+//----------------------------------------------------------------------------
+// Linea e cilindro sono nel medesimo riferimento.
+// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
+// Con intersezione viene restituito true e i parametri in dU1 e dU2.
+//----------------------------------------------------------------------------
+bool
+IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
+ double dRad, double dHeight,
+ double& dU1, double& dU2) ;
+
+//----------------------------------------------------------------------------
+inline bool
+TestIntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
+ double dRad, double dHeight)
+{
+ double dU1, dU2 ;
+ return IntersLineCyl( ptL, vtL, dRad, dHeight, dU1, dU2) ;
+}
diff --git a/IntersLineSphere.cpp b/IntersLineSphere.cpp
index befeab1..6d2629b 100644
--- a/IntersLineSphere.cpp
+++ b/IntersLineSphere.cpp
@@ -26,20 +26,25 @@ IntersLineSphere( const Point3d& ptL, const Vector3d& vtL, const Point3d& ptCen,
return ILST_NO ;
// Proiezione del centro della sfera sulla linea
Point3d ptP = ptL + (( ptCen - ptL) * vtL) * vtL ;
- // Distanza di questo punto di proiezione dal centro della sfera
- double dDist = Dist( ptCen, ptP) ;
+ // Quadrato della distanza di questo punto di proiezione dal centro della sfera
+ double dSqDist = SqDist( ptCen, ptP) ;
+ // Differenza tra quadrato del raggio e quadrato della distanza
+ double dSqDelta = dRad * dRad - dSqDist ;
+
+ // Se distanza superiore al raggio, nessuna intersezione
+ if ( dSqDelta < - 2 * dRad * EPS_SMALL)
+ return ILST_NO ;
+
// Se distanza uguale al raggio, intersezione tangente
- if ( abs( dDist - dRad) < EPS_SMALL) {
+ if ( dSqDelta < EPS_SMALL * EPS_SMALL) {
ptI1 = ptP ;
ptI2 = ptP ;
return ILST_TG ;
}
- // Se distanza superiore al raggio, nessuna intersezione
- if ( dDist > dRad)
- return ILST_NO ;
+
// Distanza inferiore al raggio, due intersezioni secanti
- double dDist2 = sqrt( dRad * dRad - dDist * dDist) ;
+ double dDist2 = sqrt( dSqDelta) ;
ptI1 = ptP - dDist2 * vtL ;
ptI2 = ptP + dDist2 * vtL ;
return ILST_SEC ;
-}
\ No newline at end of file
+}
diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp
index d3e5adc..ed433dc 100644
--- a/OffsetCurve.cpp
+++ b/OffsetCurve.cpp
@@ -454,7 +454,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
vLen.pop_back() ;
}
// eseguo la divisione
- int nCount = 1 ;
double dUPrev = 0 ;
double dLenPrev = 0 ;
for ( int i = 0 ; i < int( vU.size()) ; ++ i) {
@@ -466,7 +465,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
if ( IsNull( pCopy))
return false ;
m_CrvLst.push_back( Release( pCopy)) ;
- ++ nCount ;
// trimmo l'originale
pCompo1->TrimStartEndAtParam( dUPrev, vU[i]) ;
// la copia diventa il nuovo corrente
@@ -474,9 +472,15 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
dUPrev = vU[i] ;
dLenPrev = vLen[i] ;
}
- // se fatta almeno una suddivisione, trimmo l'ultima parte
- if ( dUPrev > EPS_PARAM)
+ // se fatta almeno una suddivisione
+ bool bFirstLastSame = false ;
+ if ( dUPrev > EPS_PARAM) {
+ // trimmo l'ultima parte
pCompo1->TrimStartAtParam( dUPrev) ;
+ // rilevo le curve chiuse con due parti di una stessa curva all'inizio e alla fine
+ if ( bClosed && vU[0] > EPS_PARAM && vLen[0] >= 2 * EPS_SMALL)
+ bFirstLastSame = true ;
+ }
// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
if ( ! bClosed) {
@@ -581,6 +585,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
}
// settimo passo : elimino le parti che sono troppo vicine al percorso originale
+ bool bFirstLastDeleted = false ;
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
ICurve* pCrv = *iIter ;
// distanza minima di alcuni punti interni della curva dalla curva originale
@@ -591,8 +596,24 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
GetMinDist( 0.875, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL ||
GetMinDist( 0.0625, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL ||
GetMinDist( 0.9375, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL) {
+ // se prima e ultima sono la stessa curva e non ancora cancellate e prima da cancellare
+ if ( bFirstLastSame && ! bFirstLastDeleted && iIter == m_CrvLst.begin()) {
+ bFirstLastDeleted = true ;
+ // cancello ultima
+ delete *prev( m_CrvLst.end()) ;
+ m_CrvLst.pop_back() ;
+ }
+ // se prima e ultima sono la stessa curva e non ancora cancellate e ultima da cancellare
+ if ( bFirstLastSame && ! bFirstLastDeleted && iIter == prev( m_CrvLst.end())) {
+ bFirstLastDeleted = true ;
+ // cancello prima
+ delete *m_CrvLst.begin() ;
+ m_CrvLst.pop_front() ;
+ }
+ // cancello la corrente
delete pCrv ;
iIter = m_CrvLst.erase( iIter) ;
+ // evito incremento
continue ;
}
// passo alla successiva
diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp
index 65d1bf7..168422e 100644
--- a/StmFromCurves.cpp
+++ b/StmFromCurves.cpp
@@ -20,8 +20,11 @@
#include "SurfTriMesh.h"
#include "/EgtDev/Include/EGkOffsetCurve.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
+#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include
+#include
+#include
using namespace std ;
@@ -394,15 +397,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
}
// se altrimenti guida aperta e tappi arrotondati
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
- // verifico che le due estremità siano chiuse e piatte
- //POLYLINEVECTOR vPL ;
- //if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
- // return nullptr ;
- //Plane3d plEnds ; double dArea ;
- //if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
- // return nullptr ;
- //if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
- // return nullptr ;
// step di rotazione per rispettare la tolleranza
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
// aggiungo il cap sull'inizio
@@ -437,8 +431,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
return nullptr ;
pSce->Invert() ;
pSTM->DoSewing( *pSce) ;
- // elimino eventuali fessure
- //pSTM->Repair() ;
}
// restituisco la superficie
return Release( pSTM) ;
@@ -461,29 +453,37 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// curve di offset
- OffsetCurve OffsCrvR ;
- if ( ! OffsCrvR.Make( pGuide, dDimH / 2 - dBevelH, ICurve::OFF_FILLET) || OffsCrvR.GetCurveCount() == 0)
+ const int NUM_OFFS = 4 ;
+ OffsetCurve vOffsCrv[NUM_OFFS] ;
+ double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ;
+ future vRes[NUM_OFFS] ;
+ for ( int i = 0 ; i < NUM_OFFS ; ++ i)
+ vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ;
+ bool bOk = true ;
+ int nFin = 0 ;
+ while ( nFin < NUM_OFFS) {
+ for ( int i = 0 ; i < NUM_OFFS ; ++ i) {
+ if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
+ bOk = vRes[i].get() && bOk ;
+ ++ nFin ;
+ }
+ }
+ }
+ if ( ! bOk ||
+ vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
+ vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
return nullptr ;
- PtrOwner pCrvR( OffsCrvR.GetLongerCurve()) ;
+ PtrOwner pCrvR( vOffsCrv[0].GetLongerCurve()) ;
if ( IsNull( pCrvR))
return nullptr ;
- OffsetCurve OffsCrvL ;
- if ( ! OffsCrvL.Make( pGuide, -dDimH / 2 + dBevelH, ICurve::OFF_FILLET) || OffsCrvL.GetCurveCount() == 0)
- return nullptr ;
- PtrOwner pCrvL( OffsCrvL.GetLongerCurve()) ;
+ PtrOwner pCrvL( vOffsCrv[1].GetLongerCurve()) ;
if ( IsNull( pCrvL))
return nullptr ;
- OffsetCurve OffsCrvRb ;
- if ( ! OffsCrvRb.Make( pGuide, dDimH / 2, ICurve::OFF_FILLET) || OffsCrvRb.GetCurveCount() == 0)
- return nullptr ;
- PtrOwner pCrvRb( OffsCrvRb.GetLongerCurve()) ;
+ PtrOwner pCrvRb( vOffsCrv[2].GetLongerCurve()) ;
if ( IsNull( pCrvRb))
return nullptr ;
pCrvRb->Translate( - dBevelV * vtNorm) ;
- OffsetCurve OffsCrvLb ;
- if ( ! OffsCrvLb.Make( pGuide, -dDimH / 2, ICurve::OFF_FILLET) || OffsCrvLb.GetCurveCount() == 0)
- return nullptr ;
- PtrOwner pCrvLb( OffsCrvLb.GetLongerCurve()) ;
+ PtrOwner pCrvLb( vOffsCrv[3].GetLongerCurve()) ;
if ( IsNull( pCrvLb))
return nullptr ;
pCrvLb->Translate( - dBevelV * vtNorm) ;
@@ -518,19 +518,29 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
if ( IsNull( pSrfLft))
return nullptr ;
// unisco le parti
- PtrOwner pSTM( Release( pSrfTop)) ;
- pSTM->DoSewing( *pSrfTopR) ;
- pSTM->DoSewing( *pSrfTopL) ;
- pSTM->DoSewing( *pSrfRgt) ;
- pSTM->DoSewing( *pSrfLft) ;
- pSTM->DoSewing( *pSrfBotR) ;
- pSTM->DoSewing( *pSrfBotL) ;
- pSTM->DoSewing( *pSrfBot) ;
- // salvo tolleranza lineare usata e imposto angolo per smooth
- pSTM->SetLinearTolerance( dLinTol) ;
- pSTM->SetSmoothAngle( 20) ;
+ int nBuckets = max( 4 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
+ StmFromTriangleSoup stmSoup ;
+ if ( ! stmSoup.Start( nBuckets))
+ return nullptr ;
+ stmSoup.AddSurfTriMesh( *pSrfTop) ;
+ stmSoup.AddSurfTriMesh( *pSrfTopR) ;
+ stmSoup.AddSurfTriMesh( *pSrfTopL) ;
+ stmSoup.AddSurfTriMesh( *pSrfRgt) ;
+ stmSoup.AddSurfTriMesh( *pSrfLft) ;
+ stmSoup.AddSurfTriMesh( *pSrfBotR) ;
+ stmSoup.AddSurfTriMesh( *pSrfBotL) ;
+ stmSoup.AddSurfTriMesh( *pSrfBot) ;
+ PtrOwner pSTM ;
// se guida aperta e tappi piatti
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
+ // completo unione e recupero la superficie risultante
+ if ( ! stmSoup.End())
+ return nullptr ;
+ pSTM.Set( stmSoup.GetSurf()) ;
+ // preparo seconda zuppa di triangoli per inserire i tappi
+ StmFromTriangleSoup stmCapSoup ;
+ if ( ! stmCapSoup.Start( nBuckets))
+ return nullptr ;
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
@@ -545,25 +555,20 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
return nullptr ;
pSci->Invert() ;
- pSTM->DoSewing( *pSci) ;
+ stmCapSoup.AddSurfTriMesh( *pSci) ;
// aggiungo il cap sulla fine
PtrOwner pSce( CreateSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
return nullptr ;
pSce->Invert() ;
- pSTM->DoSewing( *pSce) ;
+ stmCapSoup.AddSurfTriMesh( *pSce) ;
+ // completo unione con i tappi e recupero la superficie risultante
+ if ( ! stmCapSoup.End())
+ return nullptr ;
+ pSTM.Set( stmCapSoup.GetSurf()) ;
}
// se altrimenti guida aperta e tappi arrotondati
- if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
- // verifico che le due estremità siano chiuse e piatte
- //POLYLINEVECTOR vPL ;
- //if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
- // return nullptr ;
- //Plane3d plEnds ; double dArea ;
- //if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
- // return nullptr ;
- //if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
- // return nullptr ;
+ else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
// step di rotazione per rispettare il tipo o la tolleranza
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
// aggiungo il cap sull'inizio
@@ -583,7 +588,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
return nullptr ;
pSci->Invert() ;
- pSTM->DoSewing( *pSci) ;
+ stmSoup.AddSurfTriMesh( *pSci) ;
// aggiungo il cap sulla fine
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
@@ -601,10 +606,21 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
return nullptr ;
pSce->Invert() ;
- pSTM->DoSewing( *pSce) ;
- // elimino eventuali fessure
- //pSTM->Repair() ;
+ stmSoup.AddSurfTriMesh( *pSce) ;
+ // completo unione e recupero la superficie risultante
+ if ( ! stmSoup.End())
+ return nullptr ;
+ pSTM.Set( stmSoup.GetSurf()) ;
}
+ else {
+ // completo unione e recupero la superficie risultante
+ if ( ! stmSoup.End())
+ return nullptr ;
+ pSTM.Set( stmSoup.GetSurf()) ;
+ }
+ // salvo tolleranza lineare usata e imposto angolo per smooth
+ pSTM->SetLinearTolerance( dLinTol) ;
+ pSTM->SetSmoothAngle( 20) ;
// restituisco la superficie
return Release( pSTM) ;
}
diff --git a/StmFromTriangleSoup.cpp b/StmFromTriangleSoup.cpp
index 23838da..fb72490 100644
--- a/StmFromTriangleSoup.cpp
+++ b/StmFromTriangleSoup.cpp
@@ -1,10 +1,10 @@
//----------------------------------------------------------------------------
-// EgalTech 2014-2015
+// EgalTech 2014-2023
//----------------------------------------------------------------------------
-// File : StmFromTriangleSoup.cpp Data : 19.05.14 Versione : 1.5e7
+// File : StmFromTriangleSoup.cpp Data : 07.05.23 Versione : 2.5e2
// Contenuto : Implementazione della classe StmFromTriangleSoup, per creare
-// una superficie trimesh da un insieme disordinato di triangoli(STL).
-//
+// una superficie trimesh da un insieme di triangoli
+// (può essere disordinato come STL o può essere una superficie).
//
// Modifiche : 19.05.14 DS Creazione modulo.
//
@@ -112,6 +112,29 @@ StmFromTriangleSoup::AddVertex( const Point3d& ptP)
return nId ;
}
+//----------------------------------------------------------------------------
+bool
+StmFromTriangleSoup::AddSurfTriMesh( const ISurfTriMesh& stmSource)
+{
+ // verifico inizializzazione
+ if ( m_pSTM == nullptr)
+ return false ;
+ // verifico superficie sorgente
+ if ( &stmSource == nullptr || ! stmSource.IsValid())
+ return false ;
+ // recupero tutti i triangoli della superficie
+ bool bOk ;
+ Triangle3d Tria ;
+ int nT = stmSource.GetFirstTriangle( Tria) ;
+ while ( nT != SVT_NULL) {
+ // inserisco il triangolo nella zuppa
+ bOk = AddTriangle( Tria) && bOk ;
+ // passo al triangolo successivo
+ nT = stmSource.GetNextTriangle( nT, Tria) ;
+ }
+ return bOk ;
+}
+
//----------------------------------------------------------------------------
bool
StmFromTriangleSoup::End( void)
diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp
index 75de929..dbf19d5 100644
--- a/SurfTriMesh.cpp
+++ b/SurfTriMesh.cpp
@@ -3003,7 +3003,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou
// definisco un Grid per i vertici delle due superfici
PointGrid3d VertGrid ;
- int nBuckets = GetVertexSize() + pOther->GetVertexSize() ;
+ int nBuckets = max( GetVertexSize() + pOther->GetVertexSize(), 1000) ;
VertGrid.Init( nBuckets) ;
// inserisco i vertici della trimesh corrente (li considero tutti diversi tra loro)
diff --git a/SurfTriMesh.h b/SurfTriMesh.h
index f5fa0d2..2082811 100644
--- a/SurfTriMesh.h
+++ b/SurfTriMesh.h
@@ -360,7 +360,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool UpdateOneFace( int nFacet, int nT) ;
bool UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) ;
bool SetFacet( int nInd, int nT) ;
- bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ;
+ bool VerifyAdjacTriaFacet( INTVECTOR& vT) const ;
bool MarchAlongFacetLoop( int nF, int nT, int nV, int nTimeStamp, PolyLine& PL) const ;
bool MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
void ResetHashGrids3d( void) const ;
diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp
index b8a27ad..71620a5 100644
--- a/SurfTriMeshBooleans.cpp
+++ b/SurfTriMeshBooleans.cpp
@@ -394,20 +394,13 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
}
// Fra le catene trovate separo le aperte dalle chiuse
- int nDegenerateChainNum = 0 ;
INTVECTOR vnDegVec ;
CHAINVECTOR cvClosedChain ;
CHAINVECTOR cvOpenChain ;
for ( int nL = 0 ; nL < int( vChain.size()) ; ++ nL) {
- bool bChainDegenerate = false ;
- if ( vChain[nL].size() == 1 && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][0].ptEn)) {
- bChainDegenerate = true ;
- }
-
- if ( bChainDegenerate)
- ++ nDegenerateChainNum ;
+ bool bChainDegenerate = ( vChain[nL].size() == 1 && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][0].ptEn)) ;
int nCurLoopLast = max( int( vChain[nL].size()) - 1, 0) ;
- if ( ( ! bChainDegenerate) && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn))
+ if ( ! bChainDegenerate && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn))
cvClosedChain.emplace_back( vChain[nL]) ;
else {
cvOpenChain.emplace_back( vChain[nL]) ;
@@ -446,7 +439,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
}
// Gestione tagli piccoli
- if ( int( cvOpenChain.size()) == 1 && int( cvOpenChain[0].size()) == 1 && int( cvClosedChain.size()) == 0) {
+ if ( cvOpenChain.size() == 1 && cvOpenChain[0].size() == 1 && cvClosedChain.empty()) {
if ( AreSamePointEpsilon( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].ptEn, EPS_SMALL)) {
Plane3d plPlane ;
plPlane.Set( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].vtOuter) ;
@@ -511,7 +504,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
vbInOut.push_back( true) ;
// Divido il loop usando le catene
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
- if ( int( cvBoundClosedLoopVec.size()) == 1 && int( cvOpenChain.size()) == 2) {
+ if ( cvBoundClosedLoopVec.size() == 1 && cvOpenChain.size() == 2) {
Point3d ptLink0St = cvOpenChain[0][0].ptSt ;
Point3d ptLink0En = cvOpenChain[0].back().ptEn ;
Point3d ptLink1St = cvOpenChain.back()[0].ptSt ;
@@ -571,7 +564,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
POLYLINEVECTOR vplPolyVec ;
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
for ( int nLoop = 0 ; nLoop < int( vplPolyVec.size()) ; ++ nLoop) {
- for (int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
+ for ( int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][nLine]) ;
}
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][0]) ;
@@ -1616,7 +1609,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
if ( ! SimplifyFacets())
- LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
+ LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Subtract")
return bOk ;
}
@@ -1750,7 +1743,7 @@ SurfTriMesh::Repair( double dMaxEdgeLen)
// Ritriangolo le facce
if ( ! SimplifyFacets( dMaxEdgeLen, true))
- LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
+ LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Repair")
return true ;
}
diff --git a/SurfTriMeshFaceting.cpp b/SurfTriMeshFaceting.cpp
index 363325b..0188cc4 100644
--- a/SurfTriMeshFaceting.cpp
+++ b/SurfTriMeshFaceting.cpp
@@ -17,6 +17,7 @@
#include "GeoConst.h"
#include "PolygonPlane.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
+#include
#include
#include
@@ -223,25 +224,33 @@ SurfTriMesh::GetAllTriaInFacet( int nF, INTVECTOR& vT) const
vT.reserve( 10) ;
vT.push_back( nT) ;
m_vTria[nT].nTemp = m_nTimeStamp ;
- return VerifyAdjacTriaFacet( nT, vT) ;
+ return VerifyAdjacTriaFacet( vT) ;
}
//----------------------------------------------------------------------------
bool
-SurfTriMesh::VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const
+SurfTriMesh::VerifyAdjacTriaFacet( INTVECTOR& vT) const
{
- // verifico i triangoli adiacenti
- for ( int j = 0 ; j < 3 ; ++ j) {
- int nAdjT = m_vTria[nT].nIdAdjac[j] ;
- if ( nAdjT != SVT_NULL &&
- m_vTria[nAdjT].nTemp != m_nTimeStamp &&
- m_vTria[nAdjT].nIdFacet == m_vTria[nT].nIdFacet) {
- vT.push_back( nAdjT) ;
- m_vTria[nAdjT].nTemp = m_nTimeStamp ;
- if ( ! VerifyAdjacTriaFacet( nAdjT, vT))
- return false ;
+ INTVECTOR vStack{ vT.back()} ;
+ while ( ! vStack.empty()) {
+ array vNew{ SVT_NULL, SVT_NULL, SVT_NULL} ;
+ for ( int j = 0 ; j < 3 ; ++ j) {
+ int nAdjT = m_vTria[vStack.back()].nIdAdjac[j] ;
+ if ( nAdjT != SVT_NULL &&
+ m_vTria[nAdjT].nTemp != m_nTimeStamp &&
+ m_vTria[nAdjT].nIdFacet == m_vTria[vStack.back()].nIdFacet) {
+ vT.push_back( nAdjT) ;
+ vNew[j] = nAdjT ;
+ m_vTria[nAdjT].nTemp = m_nTimeStamp ;
+ }
+ }
+ vStack.pop_back() ;
+ for ( int j = 0 ; j < 3 ; ++ j) {
+ if ( vNew[j] != SVT_NULL)
+ vStack.push_back( vNew[j]) ;
}
}
+
return true ;
}
diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp
index 9f4f8cd..1443894 100644
--- a/VolZmapCalculus.cpp
+++ b/VolZmapCalculus.cpp
@@ -17,6 +17,8 @@
#include "VolZmap.h"
#include "GeoConst.h"
#include "IntersLineBox.h"
+#include "IntersLineCyl.h"
+#include "IntersLineCone.h"
#include "IntersLineSurfStd.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
@@ -411,15 +413,18 @@ bool
VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise) const
{
// BBox
- BBox3d b3Box( ORIG, ORIG + vtDiag) ;
+ BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
// Porto il box nel riferimento intrinseco dello Zmap
- b3Box.LocToLoc( frBox, m_MapFrame) ;
+ Frame3d frBoxInt = GetToLoc( frBox, m_MapFrame) ;
+ BBox3d b3Box = GetToGlob( b3BoxL, frBoxInt) ;
// 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
+ if ( ! b3Zmap.Overlaps( b3Box) || ! b3Zmap.Overlaps( frBoxInt, b3BoxL))
+ return true ;
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
return true ;
@@ -434,12 +439,12 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
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.ToLoc( frBoxInt) ;
// 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.ToLoc( frBoxInt) ;
+ Vector3d vtX = X_AX ; vtX.ToLoc( frBoxInt) ;
+ Vector3d vtY = Y_AX ; vtY.ToLoc( frBoxInt) ;
// Ciclo di intersezione dei dexel con il BBox
for ( int i = nStI ; i <= nEnI ; ++ i) {
@@ -450,16 +455,13 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
continue ;
for ( int k = 0 ; k < 5 ; ++ k) {
Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
- if ( k == 0)
- ;
- else if ( k == 1)
- ptT += - 0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ;
- else if ( k == 2)
- ptT += + 0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ;
- else if ( k == 3)
- ptT += + 0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ;
- else if ( k == 4)
- ptT += - 0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ;
+ switch ( k) {
+ case 0 : break ;
+ case 1 : ptT += -0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
+ case 2 : ptT += +0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
+ case 3 : ptT += +0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
+ case 4 : ptT += -0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
+ }
double dZmin, dZmax ;
if ( IntersLineBox( ptT, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
@@ -503,10 +505,10 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
vtK = Y_AX ;
}
// Passo da sistema griglia a sistema BBox
- ptO.ToLoc( frBox) ;
- vtX.ToLoc( frBox) ;
- vtY.ToLoc( frBox) ;
- vtK.ToLoc( frBox) ;
+ ptO.ToLoc( frBoxInt) ;
+ vtX.ToLoc( frBoxInt) ;
+ vtY.ToLoc( frBoxInt) ;
+ vtK.ToLoc( frBoxInt) ;
// Limiti su indici
int nStI = Clamp( int( ptBoxInf.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptBoxSup.x / m_dStep), 0, m_nNx[nMap] - 1) ;
@@ -780,33 +782,41 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bo
bool
VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise) const
{
- // Porto il cilindro nel riferimento intrinseco dello Zmap
- Frame3d frC = frCyl ;
- frC.ToLoc( m_MapFrame) ;
+ // BBox del cilindro in locale
+ BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ;
- // 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 del cilindro nel riferimento intrinseco dello Zmap
+ Frame3d frCylInt = GetToLoc( frCyl, m_MapFrame) ;
+ BBox3d b3CylI = GetToGlob( b3CylL, frCylInt) ;
// 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
+ if ( ! b3Zmap.Overlaps( b3CylI) || ! b3Zmap.Overlaps( frCylInt, b3CylL))
+ return true ;
+
+ // BBox del cilindro ottimizzato nel riferimento intrinseco dello Zmap
+ Point3d ptMyCen = frCylInt.Orig() ;
+ Vector3d vtMyAx = frCylInt.VersZ() ;
+ BBox3d b3Cyl( ptMyCen) ;
+ b3Cyl.Add( ptMyCen + vtMyAx * dH) ;
+ if ( vtMyAx.IsX())
+ b3Cyl.Expand( 0, dR, dR) ;
+ else if ( vtMyAx.IsY())
+ b3Cyl.Expand( dR, 0, dR) ;
+ else if ( vtMyAx.IsZ())
+ b3Cyl.Expand( dR, dR, 0) ;
+ else {
+ double dExpandX = dR * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
+ double dExpandY = dR * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
+ double dExpandZ = dR * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
+ b3Cyl.Expand( dExpandX, dExpandY, dExpandZ) ;
+ }
+
// Se non interferiscono, posso uscire
BBox3d b3Int ;
- if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
+ if ( ! b3Zmap.FindIntersection( b3Cyl, b3Int))
return true ;
// Se verifico solo prima mappa
@@ -818,6 +828,14 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
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) ;
+ // Vettore direzione dei dexel nel riferimento del Box
+ Vector3d vtK = GetToLoc( Z_AX, frCylInt) ;
+
+ // Riferimento intrinseco dei dexel nel riferimento del box
+ Point3d ptO = GetToLoc( ORIG, frCylInt) ;
+ Vector3d vtX = GetToLoc( X_AX, frCylInt) ;
+ Vector3d vtY = GetToLoc( Y_AX, frCylInt) ;
+
// 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) {
@@ -828,19 +846,16 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
if ( m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[0][nPos][0].dMin > b3Int.GetMax().z)
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 ;
+ Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
switch ( k) {
case 0 : break ;
- case 1 : ptT += -0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ; break ;
- case 2 : ptT += +0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ; break ;
- case 3 : ptT += +0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ; break ;
- case 4 : ptT += -0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ; break ;
+ case 1 : ptT += -0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
+ case 2 : ptT += +0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
+ case 3 : ptT += +0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
+ case 4 : ptT += -0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
}
- 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) ;
+ double dZmin, dZmax ;
+ if ( IntersLineCyl( ptT, vtK, dR, dH, 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)
@@ -856,6 +871,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
else {
// Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
+ Point3d ptO = ORIG ;
Vector3d vtX = X_AX ;
Vector3d vtY = Y_AX ;
Vector3d vtK = Z_AX ;
@@ -880,6 +896,11 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
vtY = X_AX ;
vtK = Y_AX ;
}
+ // Passo da riferimento intrinseco griglia a riferimento cilindro
+ ptO.ToLoc( frCylInt) ;
+ vtX.ToLoc( frCylInt) ;
+ vtY.ToLoc( frCylInt) ;
+ vtK.ToLoc( frCylInt) ;
// Limiti su indici
int nStI = Clamp( int( ptBoxInf.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptBoxSup.x / m_dStep), 0, m_nNx[nMap] - 1) ;
@@ -894,27 +915,13 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
continue ;
if ( m_Values[nMap][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[nMap][nPos][0].dMin > b3Int.GetMax().z)
continue ;
- Point3d ptT = ORIG + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
- Point3d ptI1, ptI2 ;
- Vector3d vtN1, vtN2 ;
- // La linea del dexel interseca il cilindro.
- if ( IntersLineCylinder( ptT, vtK, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
- double dMinU, dMaxU ;
- if ( nMap == 0) {
- dMinU = min( ptI1.z, ptI2.z) ;
- dMaxU = max( ptI1.z, ptI2.z) ;
- }
- else if ( nMap == 1) {
- dMinU = min( ptI1.x, ptI2.x) ;
- dMaxU = max( ptI1.x, ptI2.x) ;
- }
- else {
- dMinU = min( ptI1.y, ptI2.y) ;
- dMaxU = max( ptI1.y, ptI2.y) ;
- }
- // Ciclo sui segmenti del dexel.
+ Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
+ double dMinU, dMaxU ;
+ // La retta associata al dexel interseca il cilindro.
+ if ( IntersLineCyl( ptT, vtK, dR, dH, dMinU, dMaxU)) {
+ // Ciclo sui segmenti del dexel
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
- // Se il segmento è interno all'intervallo d'intersezione, ho finito.
+ // Se il segmento è interno all'intervallo d'intersezione, ho finito.
if ( dMaxU > m_Values[nMap][nPos][nIndex].dMin - EPS_SMALL &&
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
return false ;
@@ -933,33 +940,33 @@ bool
VolZmap::AvoidCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise) const
{
// Se altezza negativa, sposto riferimento da faccia sopra a quella sotto
- Frame3d frC = frCyl ;
+ Frame3d frMyCyl = frCyl ;
if ( dH < 0) {
- frC.Translate( dH * frC.VersZ()) ;
+ frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
dH = - dH ;
}
// Se distanza di sicurezza nulla
if ( dSafeDist < EPS_SMALL)
- return AvoidSimpleCylinder( frC, dR, dH, bPrecise) ;
+ return AvoidSimpleCylinder( frMyCyl, dR, dH, bPrecise) ;
// Verifica preliminare con cilindro esteso
- Frame3d frEst = frC ; frEst.Translate( -dSafeDist * frC.VersZ()) ;
+ Frame3d frEst = frMyCyl ; frEst.Translate( -dSafeDist * frMyCyl.VersZ()) ;
if ( AvoidSimpleCylinder( frEst, dR + dSafeDist, dH + 2 * dSafeDist, bPrecise))
return true ;
// Cilindro allargato
- if ( ! AvoidSimpleCylinder( frC, dR + dSafeDist, dH, bPrecise))
+ if ( ! AvoidSimpleCylinder( frMyCyl, dR + dSafeDist, dH, bPrecise))
return false ;
// Cilindro allungato
- Frame3d frTmp = frC ; frTmp.Translate( - dSafeDist * frC.VersZ()) ;
+ Frame3d frTmp = frMyCyl ; frTmp.Translate( - dSafeDist * frMyCyl.VersZ()) ;
if ( ! AvoidSimpleCylinder( frTmp, dR, dH + 2 * dSafeDist, bPrecise))
return false ;
// Toro inferiore
- if ( ! AvoidSimpleTorus( frC, dR, dSafeDist, bPrecise))
+ if ( ! AvoidSimpleTorus( frMyCyl, dR, dSafeDist, bPrecise))
return false ;
// Toro superiore
- frTmp = frC ; frTmp.Translate( dH * frC.VersZ()) ;
+ frTmp = frMyCyl ; frTmp.Translate( dH * frMyCyl.VersZ()) ;
if ( ! AvoidSimpleTorus( frTmp, dR, dSafeDist, bPrecise))
return false ;
@@ -1065,34 +1072,47 @@ VolZmap::SingleMapDexelConeCollision( int nStI, int nEnI, int nStJ, int nEnJ, co
bool
VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise) const
{
- // Porto il tronco di cono nel sistema intrinseco e normalizzo il vettore.
- Point3d ptRefPoint = frCone.Orig() ;
- Vector3d vtRefAx = frCone.VersZ() ;
- ptRefPoint.ToLoc( m_MapFrame) ;
- vtRefAx.ToLoc( m_MapFrame) ;
+ // BBox del tronco di cono in locale
+ BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), Point3d( dMaxRad, dMaxRad, dHeight)) ;
- // BBox del tronco di cono
- BBox3d b3Box( ptRefPoint) ;
- b3Box.Add( ptRefPoint + vtRefAx * dHeight) ;
- if ( vtRefAx.IsXplus() || vtRefAx.IsXminus())
- b3Box.Expand( 0, dMaxRad, dMaxRad) ;
- else if ( vtRefAx.IsYplus() || vtRefAx.IsYminus())
- b3Box.Expand( dMaxRad, 0, dMaxRad) ;
- else if ( vtRefAx.IsZplus() || vtRefAx.IsZminus())
- b3Box.Expand( dMaxRad, dMaxRad, 0) ;
- else {
- double dExpandX = dMaxRad * sqrt( 1 - vtRefAx.x * vtRefAx.x) ;
- double dExpandY = dMaxRad * sqrt( 1 - vtRefAx.y * vtRefAx.y) ;
- double dExpandZ = dMaxRad * sqrt( 1 - vtRefAx.z * vtRefAx.z) ;
- b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
- }
+ // BBox del tronco di cono nel riferimento intrinseco dello Zmap
+ Frame3d frConeInt = GetToLoc( frCone, m_MapFrame) ;
+ BBox3d b3ConeI = GetToGlob( b3ConeL, frConeInt) ;
// 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
+ if ( ! b3Zmap.Overlaps( b3ConeI) || ! b3Zmap.Overlaps( frConeInt, b3ConeL))
+ return true ;
+
+ // BBox del tronco di cono ottimizzato nel riferimento intrinseco dello Zmap
+ Point3d ptRefPoint = frConeInt.Orig() ;
+ Vector3d vtRefAx = frConeInt.VersZ() ;
+ BBox3d b3Cone( ptRefPoint) ;
+ b3Cone.Add( ptRefPoint + vtRefAx * dHeight) ;
+ if ( vtRefAx.IsX())
+ b3Cone.Expand( 0, dMaxRad, dMaxRad) ;
+ else if ( vtRefAx.IsY())
+ b3Cone.Expand( dMaxRad, 0, dMaxRad) ;
+ else if ( vtRefAx.IsZ())
+ b3Cone.Expand( dMaxRad, dMaxRad, 0) ;
+ else {
+ double dCoeffX = sqrt( 1 - vtRefAx.x * vtRefAx.x) ;
+ double dCoeffY = sqrt( 1 - vtRefAx.y * vtRefAx.y) ;
+ double dCoeffZ = sqrt( 1 - vtRefAx.z * vtRefAx.z) ;
+ BBox3d b3Base( ptRefPoint) ;
+ b3Base.Expand( dMinRad * dCoeffX, dMinRad * dCoeffY, dMinRad * dCoeffZ) ;
+ BBox3d b3Top( ptRefPoint + vtRefAx * dHeight) ;
+ b3Top.Expand( dMaxRad * dCoeffX, dMaxRad * dCoeffY, dMaxRad * dCoeffZ) ;
+ b3Cone.Reset() ;
+ b3Cone.Add( b3Base) ;
+ b3Cone.Add( b3Top) ;
+ }
+
// Se non interferiscono, posso uscire
BBox3d b3Int ;
- if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
+ if ( ! b3Zmap.FindIntersection( b3Cone, b3Int))
return true ;
// Uso solo la prima mappa
@@ -1102,177 +1122,103 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
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) ;
- // Limiti su Z
- double dZmin = b3Int.GetMin().z ;
- double dZmax = b3Int.GetMax().z ;
- // Numero massimo di thread
- int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
- // se un solo thread
- if ( nThreadMax == 1) {
- m_bBreak = false ;
- bool bCollision = SingleMapDexelConeCollision( nStI, nEnI, nStJ, nEnJ, ptRefPoint, vtRefAx,
- dMinRad, dMaxRad, dHeight, dZmin, dZmax) ;
- return ( ! bCollision) ;
- }
- // altrimenti esecuzione in parallelo dei calcoli
- else {
- //string sOut = "I=" + ToString( nStI) + "," + ToString( nEnI) + " J=" + ToString( nStJ) + "," + ToString( nEnJ) ;
- //LOG_INFO( GetEGkLogger(), sOut.c_str())
- m_bBreak = false ;
- // lancio dei thread
- int nSpanI = ( nEnI - nStI + 1) / nThreadMax + 1 ;
- int nSpanJ = ( nEnJ - nStJ + 1) / nThreadMax + 1 ;
- bool bOnI = ( nSpanI >= nSpanJ) ;
- int nThreadTot = 0 ;
- vector< future> vRes( nThreadMax) ;
- for ( int nT = 0 ; nT < nThreadMax ; ++ nT) {
- int nMyStI = ( bOnI ? nStI + nT * nSpanI : nStI) ;
- int nMyEnI = ( bOnI ? min( nMyStI + nSpanI - 1, nEnI) : nEnI) ;
- int nMyStJ = ( bOnI ? nStJ : nStJ + nT * nSpanJ) ;
- int nMyEnJ = ( bOnI ? nEnJ : min( nMyStJ + nSpanJ - 1, nEnJ)) ;
- if ( nMyStI > nEnI || nMyStJ > nEnJ)
- break ;
- //string sOut = "MyI=" + ToString( nMyStI) + "," + ToString( nMyEnI) + " MyJ=" + ToString( nMyStJ) + "," + ToString( nMyEnJ) ;
- //LOG_INFO( GetEGkLogger(), sOut.c_str())
- vRes[nT] = async( launch::async, &VolZmap::SingleMapDexelConeCollision, this,
- nMyStI, nMyEnI, nMyStJ, nMyEnJ, cref( ptRefPoint), cref( vtRefAx),
- dMinRad, dMaxRad, dHeight, dZmin, dZmax) ;
- ++ nThreadTot ;
- }
- // recupero i risultati dei thread alla loro terminazione
- bool bCollision = false ;
- int nTerminated = 0 ;
- while ( nTerminated < nThreadTot) {
- for ( int nT = 0 ; nT < nThreadTot ; ++ nT) {
- // Async terminato
- if ( vRes[nT].valid() && vRes[nT].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
- ++ nTerminated ;
- // Se c'è collisione ...
- if ( vRes[nT].get()) {
- bCollision = true ;
- m_bBreak = true ;
+
+ // Vettore direzione dei dexel nel riferimento del tronco di cono
+ Vector3d vtK = GetToLoc( Z_AX, frConeInt) ;
+
+ // Riferimento intrinseco dei dexel nel riferimento del tronco di cono
+ Point3d ptO = GetToLoc( ORIG, frConeInt) ;
+ Vector3d vtX = GetToLoc( X_AX, frConeInt) ;
+ Vector3d vtY = GetToLoc( Y_AX, frConeInt) ;
+
+ // Ciclo di intersezione dei dexel con il tronco di cono (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 ;
+ if ( m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[0][nPos][0].dMin > b3Int.GetMax().z)
+ continue ;
+ for ( int k = 0 ; k < 5 ; ++ k) {
+ Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
+ switch ( k) {
+ case 0 : break ;
+ case 1 : ptT += -0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
+ case 2 : ptT += +0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
+ case 3 : ptT += +0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
+ case 4 : ptT += -0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
+ }
+ double dZmin, dZmax ;
+ if ( IntersLineCone( ptT, vtK, dMinRad, dMaxRad, dHeight, 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 ;
}
}
}
}
- return ( ! bCollision) ;
}
}
// Uso tutte le mappe
else {
- // Ciclo sulle mappe.
+ // Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
- Point3d ptInfIntBox = b3Int.GetMin() ;
- Point3d ptSupIntBox = b3Int.GetMax() ;
- // Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
+ Point3d ptO = ORIG ;
+ Vector3d vtX = X_AX ;
+ Vector3d vtY = Y_AX ;
+ Vector3d vtK = Z_AX ;
+ // Estremi del box
+ Point3d ptBoxInf = b3Int.GetMin() ;
+ Point3d ptBoxSup = b3Int.GetMax() ;
if ( nMap == 1) {
- swap( ptInfIntBox.x, ptInfIntBox.z) ;
- swap( ptInfIntBox.x, ptInfIntBox.y) ;
- swap( ptSupIntBox.x, ptSupIntBox.z) ;
- swap( ptSupIntBox.x, ptSupIntBox.y) ;
+ swap( ptBoxInf.x, ptBoxInf.z) ;
+ swap( ptBoxInf.x, ptBoxInf.y) ;
+ swap( ptBoxSup.x, ptBoxSup.z) ;
+ swap( ptBoxSup.x, ptBoxSup.y) ;
+ vtX = Y_AX ;
+ vtY = Z_AX ;
+ vtK = X_AX ;
}
else if ( nMap == 2) {
- swap( ptInfIntBox.y, ptInfIntBox.z) ;
- swap( ptInfIntBox.x, ptInfIntBox.y) ;
- swap( ptSupIntBox.y, ptSupIntBox.z) ;
- swap( ptSupIntBox.x, ptSupIntBox.y) ;
+ swap( ptBoxInf.y, ptBoxInf.z) ;
+ swap( ptBoxInf.x, ptBoxInf.y) ;
+ swap( ptBoxSup.y, ptBoxSup.z) ;
+ swap( ptBoxSup.x, ptBoxSup.y) ;
+ vtX = Z_AX ;
+ vtY = X_AX ;
+ vtK = Y_AX ;
}
+ // Passo da riferimento intrinseco griglia a riferimento cilindro
+ ptO.ToLoc( frConeInt) ;
+ vtX.ToLoc( frConeInt) ;
+ vtY.ToLoc( frConeInt) ;
+ vtK.ToLoc( frConeInt) ;
// Limiti su indici
- int nStI = Clamp( int( ptInfIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
- int nEnI = Clamp( int( ptSupIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
- int nStJ = Clamp( int( ptInfIntBox.y / m_dStep), 0, m_nNy[nMap] - 1) ;
- int nEnJ = Clamp( int( ptSupIntBox.y / m_dStep), 0, m_nNy[nMap] - 1) ;
- // Ciclo sui dexel.
- for ( int nDex = 0 ; nDex < int( m_Values[nMap].size()) ; ++ nDex) {
- int nDexSize = (int)m_Values[nMap][nDex].size() ;
- if ( nDexSize == 0 ||
- m_Values[nMap][nDex][ nDexSize- 1].dMax < ptInfIntBox.z ||
- m_Values[nMap][nDex][0].dMin > ptSupIntBox.z)
- continue ;
- // Indici del dexel.
- int nI = nDex % m_nNx[nMap] ;
- int nJ = nDex / m_nNx[nMap] ;
- // Se fuori dalla regione ammissibile salto l'iterazione
- if ( nI < nStI || nI > nEnI || nJ < nStJ || nJ > nEnJ)
- continue ;
- // Posizione del dexel.
- double dX = ( nI + 0.5) * m_dStep ;
- double dY = ( nJ + 0.5) * m_dStep ;
- Point3d ptLineSt( dX, dY, 0.) ;
- Vector3d vtLineDir( 0., 0., 1.) ;
- // Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
- if ( nMap == 1) {
- swap( ptLineSt.x, ptLineSt.y) ;
- swap( ptLineSt.x, ptLineSt.z) ;
- swap( vtLineDir.x, vtLineDir.y) ;
- swap( vtLineDir.x, vtLineDir.z) ;
- }
- else if ( nMap == 2) {
- swap( ptLineSt.x, ptLineSt.y) ;
- swap( ptLineSt.y, ptLineSt.z) ;
- swap( vtLineDir.x, vtLineDir.y) ;
- swap( vtLineDir.y, vtLineDir.z) ;
- }
- // Cono proprio
- if ( dMinRad < EPS_SMALL) {
- double dMinPar = m_Values[nMap][nDex][0].dMin ;
- double dMaxPar = m_Values[nMap][nDex][nDexSize - 1].dMax ;
- Point3d ptSegSt = ptLineSt + dMinPar * vtLineDir ;
- double dU1, dU2 ;
- int nIntType = SegmentCone( ptSegSt, vtLineDir, dMaxPar - dMinPar, ptRefPoint, vtRefAx,
- dMaxRad, dHeight, dU1, dU2) ;
- if ( nIntType == LinCompCCIntersType::CC_ERROR_INT)
- return false ;
- else if ( nIntType != LinCompCCIntersType::CC_NO_INTERS) {
- for ( int nIndex = 0 ; nIndex < nDexSize ; nIndex += 1) {
- if ( m_Values[nMap][nDex][nIndex].dMax >= dU1 && m_Values[nMap][nDex][nIndex].dMin <= dU2)
- return false ;
- }
- }
- nIntType = SegmentDisc( ptSegSt, vtLineDir, dMaxPar - dMinPar, ptRefPoint + dHeight * vtRefAx,
- vtRefAx, dMaxRad, dU1, dU2) ;
- if ( nIntType == LinCompDiscIntersType::D_ERROR_INT)
- return false ;
- else if ( nIntType != LinCompDiscIntersType::D_NO_INTERS) {
- for ( int nIndex = 0 ; nIndex < nDexSize ; nIndex += 1) {
- if ( m_Values[nMap][nDex][nIndex].dMax >= dU1 && m_Values[nMap][nDex][nIndex].dMin <= dU2)
- return false ;
- }
- }
- }
- // Tronco di cono
- else {
- double dMinPar = m_Values[nMap][nDex][0].dMin ;
- double dMaxPar = m_Values[nMap][nDex][nDexSize - 1].dMax ;
- Point3d ptSegSt = ptLineSt + dMinPar * vtLineDir ;
- double dU1, dU2 ;
- int nIntType = SegmentConeFrustum( ptSegSt, vtLineDir, dMaxPar - dMinPar, ptRefPoint, vtRefAx,
- dMinRad, dMaxRad, dHeight, dU1, dU2) ;
- if ( nIntType == LinCompCCIntersType::CC_ERROR_INT)
- return false ;
- else if ( nIntType != LinCompCCIntersType::CC_NO_INTERS) {
- for ( int nIndex = 0 ; nIndex < nDexSize ; nIndex += 1) {
- if ( m_Values[nMap][nDex][nIndex].dMax >= dU1 && m_Values[nMap][nDex][nIndex].dMin <= dU2)
- return false ;
- }
- }
- nIntType = SegmentDisc( ptSegSt, vtLineDir, dMaxPar - dMinPar, ptRefPoint + dHeight * vtRefAx,
- vtRefAx, dMaxRad, dU1, dU2) ;
- if ( nIntType == LinCompDiscIntersType::D_ERROR_INT)
- return false ;
- else if ( nIntType != LinCompDiscIntersType::D_NO_INTERS) {
- for ( int nIndex = 0 ; nIndex < nDexSize ; nIndex += 1) {
- if ( m_Values[nMap][nDex][nIndex].dMax >= dU1 && m_Values[nMap][nDex][nIndex].dMin <= dU2)
- return false ;
- }
- }
- nIntType = SegmentDisc( ptSegSt, vtLineDir, dMaxPar - dMinPar, ptRefPoint, vtRefAx, dMinRad, dU1, dU2) ;
- if ( nIntType == LinCompDiscIntersType::D_ERROR_INT)
- return false ;
- else if ( nIntType != LinCompDiscIntersType::D_NO_INTERS) {
- for ( int nIndex = 0 ; nIndex < nDexSize ; nIndex += 1) {
- if ( m_Values[nMap][nDex][nIndex].dMax >= dU1 && m_Values[nMap][nDex][nIndex].dMin <= dU2)
+ int nStI = Clamp( int( ptBoxInf.x / m_dStep), 0, m_nNx[nMap] - 1) ;
+ int nEnI = Clamp( int( ptBoxSup.x / m_dStep), 0, m_nNx[nMap] - 1) ;
+ int nStJ = Clamp( int( ptBoxInf.y / m_dStep), 0, m_nNy[nMap] - 1) ;
+ int nEnJ = Clamp( int( ptBoxSup.y / m_dStep), 0, m_nNy[nMap] - 1) ;
+ // Ciclo sui dexel.
+ for ( int i = nStI ; i <= nEnI ; ++ i) {
+ for ( int j = nStJ ; j <= nEnJ ; ++ j) {
+ int nPos = j * m_nNx[nMap] + i ;
+ int nSize = int( m_Values[nMap][nPos].size()) ;
+ if ( nSize == 0)
+ continue ;
+ if ( m_Values[nMap][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[nMap][nPos][0].dMin > b3Int.GetMax().z)
+ continue ;
+ Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
+ double dMinU, dMaxU ;
+ // La retta associata al dexel interseca il tronco di cono
+ if ( IntersLineCone( ptT, vtK, dMinRad, dMaxRad, dHeight, dMinU, dMaxU)) {
+ // Ciclo sui segmenti del dexel
+ for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
+ // Se il segmento è interno all'intervallo d'intersezione, ho finito.
+ if ( dMaxU > m_Values[nMap][nPos][nIndex].dMin - EPS_SMALL &&
+ dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
return false ;
}
}
@@ -1286,7 +1232,7 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
//----------------------------------------------------------------------------
// Ha come asse Z l'asse del cono/tronco di cono. Se è un cono proprio l'origine
// è nel vertice del cono e l'asse Z è diretto verso l'apertura.
-// Se è un tronco di cono l'origine è nel centro della base Bot e l'azze Z è diretto verso
+// Se è un tronco di cono l'origine è nel centro della base Bot e l'asse Z è diretto verso
// la base Top, a prescindere da quale base abbia raggio maggiore.
bool
VolZmap::AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop, double dHeight,
@@ -1381,150 +1327,28 @@ VolZmap::AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop
//----------------------------------------------------------------------------
static bool
-RectPrismoidSegmentCollision( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
- double dLenghtTopX, double dLenghtTopY, double dHeight,
- const Point3d& ptSt, const Point3d& ptEn)
+IntersSegmentPlanePlus( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3,
+ const Point3d& ptLnSt, const Vector3d& vtLnDir, double dLnLen,
+ double& dStU, double& dEnU)
{
- // Se il solido non è ben definito, non ha senso continuare.
- if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
- max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
- dHeight < EPS_SMALL)
+ Plane3d plPlane ;
+ if ( ! plPlane.Set( ptP1, ptP2, ptP3))
return false ;
-
- // Porto il segmento nel sistema del tronco.
- Point3d ptMySt = ptSt ;
- ptMySt.ToLoc( frPrismoid) ;
- Point3d ptMyEn = ptEn ;
- ptMyEn.ToLoc( frPrismoid) ;
-
- // Se il segmento non è ben definito, non ha senso continuare.
- Vector3d vtMySeg = ptMyEn - ptMySt ;
- if ( ! vtMySeg.Normalize())
- return false ;
-
- double dHalfBaseX = 0.5 * dLenghtBaseX ;
- double dHalfBaseY = 0.5 * dLenghtBaseY ;
- double dHalfTopX = 0.5 * dLenghtTopX ;
- double dHalfTopY = 0.5 * dLenghtTopY ;
-
- // Se almeno un vertice collide ho finito
- if ( ( ptMySt.z > - EPS_SMALL && ptMySt.z < dHeight + EPS_SMALL &&
- ( ptMySt.x + dHalfBaseX + EPS_SMALL) * dHeight > ( dHalfBaseX - dHalfTopX) * ptMySt.z &&
- ( ptMySt.x - dHalfBaseX - EPS_SMALL) * dHeight < ( dHalfTopX - dHalfBaseX) * ptMySt.z &&
- ( ptMySt.y + dHalfBaseY + EPS_SMALL) * dHeight > ( dHalfBaseY - dHalfTopY) * ptMySt.z &&
- ( ptMySt.y - dHalfBaseY - EPS_SMALL) * dHeight < ( dHalfTopY - dHalfBaseY) * ptMySt.z) ||
- ( ptMyEn.z > - EPS_SMALL && ptMySt.z < dHeight + EPS_SMALL &&
- ( ptMyEn.x + dHalfBaseX + EPS_SMALL) * dHeight > ( dHalfBaseX - dHalfTopX) * ptMyEn.z &&
- ( ptMyEn.x - dHalfBaseX - EPS_SMALL) * dHeight < ( dHalfTopX - dHalfBaseX) * ptMyEn.z &&
- ( ptMyEn.y + dHalfBaseY + EPS_SMALL) * dHeight > ( dHalfBaseY - dHalfTopY) * ptMyEn.z &&
- ( ptMyEn.y - dHalfBaseY - EPS_SMALL) * dHeight < ( dHalfTopY - dHalfBaseY) * ptMyEn.z))
+ Point3d ptInt ;
+ int nIntType = IntersLinePlane( ptLnSt, vtLnDir, dLnLen, plPlane, ptInt) ;
+ if ( nIntType == ILPT_INPLANE)
return true ;
-
- // Se c'è collisione con almeno un triangolo delle facce ho finito
- Triangle3d trFaceTria1, trFaceTria2 ;
- Point3d ptInt, ptInt2 ;
- // Faccia base
- trFaceTria1.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( - dHalfBaseX, dHalfBaseY, 0.),
- Point3d( dHalfBaseX, dHalfBaseY, 0.)) ;
- if ( trFaceTria1.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria1, ptInt, ptInt2) != ILTT_NO)
- return true ;
- trFaceTria2.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( dHalfBaseX, - dHalfBaseY, 0.)) ;
- if ( trFaceTria2.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria2, ptInt, ptInt2) != ILTT_NO)
- return true ;
- // Faccia top
- trFaceTria1.Set( Point3d( - dHalfTopX, - dHalfTopY, dHeight),
- Point3d( dHalfTopX, dHalfTopY, dHeight),
- Point3d( - dHalfTopX, dHalfTopY, dHeight)) ;
- if ( trFaceTria1.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria1, ptInt, ptInt2) != ILTT_NO)
- return true ;
- trFaceTria2.Set( Point3d( - dHalfTopX, - dHalfTopY, dHeight),
- Point3d( dHalfTopX, - dHalfTopY, dHeight),
- Point3d( dHalfTopX, dHalfTopY, dHeight)) ;
- if ( trFaceTria2.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria2, ptInt, ptInt2) != ILTT_NO)
- return true ;
- // Faccia laterale 1
- trFaceTria1.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( dHalfTopX , - dHalfTopY , dHeight),
- Point3d( - dHalfTopX , - dHalfTopY , dHeight)) ;
- if ( trFaceTria1.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria1, ptInt, ptInt2) != ILTT_NO)
- return true ;
- trFaceTria2.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( dHalfTopX, - dHalfTopY , dHeight)) ;
- if ( trFaceTria2.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria2, ptInt, ptInt2) != ILTT_NO)
- return true ;
- // Faccia laterale 2
- trFaceTria1.Set( Point3d( dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( dHalfTopX , dHalfTopY , dHeight),
- Point3d( dHalfTopX , - dHalfTopY , dHeight)) ;
- if ( trFaceTria1.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria1, ptInt, ptInt2) != ILTT_NO)
- return true ;
- trFaceTria2.Set( Point3d( dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( dHalfTopX , dHalfTopY , dHeight)) ;
- if ( trFaceTria2.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria2, ptInt, ptInt2) != ILTT_NO)
- return true ;
- // Faccia laterale 3
- trFaceTria1.Set( Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( - dHalfTopX , dHalfTopY , dHeight),
- Point3d( dHalfTopX , dHalfTopY , dHeight)) ;
- if ( trFaceTria1.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria1, ptInt, ptInt2) != ILTT_NO)
- return true ;
- trFaceTria2.Set( Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( - dHalfBaseX, dHalfBaseY, 0.),
- Point3d( - dHalfTopX , dHalfTopY , dHeight)) ;
- if ( trFaceTria2.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria2, ptInt, ptInt2) != ILTT_NO)
- return true ;
- // Faccia laterale 4
- trFaceTria1.Set( Point3d( - dHalfBaseX, dHalfBaseY, 0.),
- Point3d( - dHalfTopX , - dHalfTopY , dHeight),
- Point3d( - dHalfTopX , dHalfTopY , dHeight)) ;
- if ( trFaceTria1.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria1, ptInt, ptInt2) != ILTT_NO)
- return true ;
- trFaceTria2.Set( Point3d( - dHalfBaseX, dHalfBaseY, 0.),
- Point3d( - dHalfBaseX, - dHalfBaseY, 0.),
- Point3d( - dHalfTopX , - dHalfTopY , dHeight)) ;
- if ( trFaceTria2.Validate() && IntersLineTria( ptMySt, ptMyEn, trFaceTria2, ptInt, ptInt2) != ILTT_NO)
- return true ;
-
- return false ;
-}
-
-//----------------------------------------------------------------------------
-static bool
-IntersSegmentTrianglePlus( const Point3d& ptTr1, const Point3d& ptTr2, const Point3d& ptTr3,
- const Point3d& ptLnSt, const Vector3d& vtLnDir, double dLnLen,
- double& dStU, double& dEnU)
-{
- Triangle3d trFaceTria ;
- trFaceTria.Set( ptTr1, ptTr2, ptTr3) ;
- if ( trFaceTria.Validate()) {
- Point3d ptMyIntSt, ptMyIntEn ;
- int nIntType = IntersLineTria( ptLnSt, vtLnDir, dLnLen, trFaceTria, ptMyIntSt, ptMyIntEn, true) ;
- if ( nIntType != ILTT_NO) {
- if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
- double dCurU = ( ptMyIntSt - ptLnSt) * vtLnDir ;
- if ( dCurU < dStU)
- dStU = dCurU ;
- if ( dCurU > dEnU)
- dEnU = dCurU ;
- }
- else {
- double dCurStU = ( ptMyIntSt - ptLnSt) * vtLnDir ;
- double dCurEnU = ( ptMyIntEn - ptLnSt) * vtLnDir ;
- if ( dCurStU < dStU)
- dStU = dCurStU ;
- if ( dCurEnU > dEnU)
- dEnU = dCurEnU ;
- }
- }
+ if ( nIntType == ILPT_NO) {
+ if ( DistPointPlane( ptLnSt, plPlane) > 0)
+ dEnU = -1 ;
return true ;
}
-
- return false ;
+ double dIntU = ( ptInt - ptLnSt) * vtLnDir ;
+ if ( vtLnDir * plPlane.GetVersN() > 0)
+ dEnU = min( dEnU, dIntU) ;
+ else
+ dStU = max( dStU, dIntU) ;
+ return true ;
}
//----------------------------------------------------------------------------
@@ -1534,19 +1358,17 @@ RectPrismoidSegmentCollisionPlus( const Frame3d& frPrismoid, double dLenghtBaseX
const Point3d& ptSt, const Point3d& ptEn,
double& dStU, double& dEnU)
{
- // Se il solido non è ben definito, non ha senso continuare.
+ // Se il solido non è ben definito, non ha senso continuare
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
dHeight < EPS_SMALL)
return false ;
// Porto il segmento nel sistema del prismoide a base rettangolare
- Point3d ptMySt = ptSt ;
- ptMySt.ToLoc( frPrismoid) ;
- Point3d ptMyEn = ptEn ;
- ptMyEn.ToLoc( frPrismoid) ;
+ Point3d ptMySt = GetToLoc( ptSt, frPrismoid) ;
+ Point3d ptMyEn = GetToLoc( ptEn, frPrismoid) ;
- // Se il segmento non è ben definito, non ha senso continuare.
+ // Se il segmento non è ben definito, non ha senso continuare
Vector3d vtMySeg = ptMyEn - ptMySt ;
double dSegLen = vtMySeg.Len() ;
if ( dSegLen < EPS_SMALL)
@@ -1559,78 +1381,87 @@ RectPrismoidSegmentCollisionPlus( const Frame3d& frPrismoid, double dLenghtBaseX
double dHalfTopX = 0.5 * dLenghtTopX ;
double dHalfTopY = 0.5 * dLenghtTopY ;
- // Inizializzo gli estremi della parte di retta che interseca il prismoide
- dStU = INFINITO ;
- dEnU = -INFINITO ;
- // Interseco la retta con le facce e salvo i punti d'intersezione
- // Faccia base
- IntersSegmentTrianglePlus( Point3d( -dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( -dHalfBaseX, dHalfBaseY, 0.),
- Point3d( dHalfBaseX, dHalfBaseY, 0.),
+ // Parametri estremi linea
+ dStU = 0 ;
+ dEnU = dSegLen ;
+ // Verifico con faccia base
+ IntersSegmentPlanePlus( Point3d( -dHalfBaseX, -dHalfBaseY, 0),
+ Point3d( -dHalfBaseX, dHalfBaseY, 0),
+ Point3d( dHalfBaseX, 0, 0),
+ ptMySt, vtMySeg, dSegLen,
+ dStU, dEnU) ;
+ if ( dEnU < dStU - EPS_ZERO)
+ return false ;
+ // Verifico con faccia top
+ IntersSegmentPlanePlus( Point3d( -dHalfTopX, dHalfTopY, dHeight),
+ Point3d( -dHalfTopX, -dHalfTopY, dHeight),
+ Point3d( dHalfTopX, 0, dHeight),
+ ptMySt, vtMySeg, dSegLen,
+ dStU, dEnU) ;
+ if ( dEnU < dStU - EPS_ZERO)
+ return false ;
+ // Verifico con faccia laterale 1
+ if ( dHalfTopX > dHalfBaseX)
+ IntersSegmentPlanePlus( Point3d( 0, -dHalfBaseY, 0),
+ Point3d( dHalfTopX, -dHalfTopY, dHeight),
+ Point3d( -dHalfTopX, -dHalfTopY, dHeight),
ptMySt, vtMySeg, dSegLen,
dStU, dEnU) ;
- IntersSegmentTrianglePlus( Point3d( -dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( dHalfBaseX, -dHalfBaseY, 0.),
+ else
+ IntersSegmentPlanePlus( Point3d( -dHalfBaseX, -dHalfBaseY, 0),
+ Point3d( dHalfBaseX, -dHalfBaseY, 0),
+ Point3d( 0, -dHalfTopY, dHeight),
ptMySt, vtMySeg, dSegLen,
dStU, dEnU) ;
- // Faccia top
- IntersSegmentTrianglePlus( Point3d( -dHalfTopX, -dHalfTopY, dHeight),
+ if ( dEnU < dStU - EPS_ZERO)
+ return false ;
+ // Verifico con faccia laterale 2
+ if ( dHalfTopY > dHalfBaseY)
+ IntersSegmentPlanePlus( Point3d( dHalfBaseX, 0, 0),
Point3d( dHalfTopX, dHalfTopY, dHeight),
- Point3d( -dHalfTopX, dHalfTopY, dHeight),
- ptMySt, vtMySeg, dSegLen,
- dStU, dEnU) ;
- IntersSegmentTrianglePlus( Point3d( -dHalfTopX, -dHalfTopY, dHeight),
Point3d( dHalfTopX, -dHalfTopY, dHeight),
+ ptMySt, vtMySeg, dSegLen,
+ dStU, dEnU) ;
+ else
+ IntersSegmentPlanePlus( Point3d( dHalfBaseX, -dHalfBaseY, 0),
+ Point3d( dHalfBaseX, dHalfBaseY, 0),
+ Point3d( dHalfTopX, 0, dHeight),
+ ptMySt, vtMySeg, dSegLen,
+ dStU, dEnU) ;
+ if ( dEnU < dStU - EPS_ZERO)
+ return false ;
+ // Verifico con faccia laterale 3
+ if ( dHalfTopX > dHalfBaseX)
+ IntersSegmentPlanePlus( Point3d( 0, dHalfBaseY, 0),
+ Point3d( -dHalfTopX, dHalfTopY, dHeight),
Point3d( dHalfTopX, dHalfTopY, dHeight),
ptMySt, vtMySeg, dSegLen,
dStU, dEnU) ;
- // Faccia laterale 1
- IntersSegmentTrianglePlus( Point3d( -dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( dHalfTopX , -dHalfTopY , dHeight),
- Point3d( -dHalfTopX , -dHalfTopY , dHeight),
+ else
+ IntersSegmentPlanePlus( Point3d( dHalfBaseX, dHalfBaseY, 0),
+ Point3d( -dHalfBaseX, dHalfBaseY, 0),
+ Point3d( 0, dHalfTopY, dHeight),
ptMySt, vtMySeg, dSegLen,
dStU, dEnU) ;
- IntersSegmentTrianglePlus( Point3d( -dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( dHalfTopX, -dHalfTopY , dHeight),
+ if ( dEnU < dStU - EPS_ZERO)
+ return false ;
+ // Verifico con faccia laterale 4
+ if ( dHalfTopY > dHalfBaseY)
+ IntersSegmentPlanePlus( Point3d( -dHalfBaseX, 0, 0),
+ Point3d( -dHalfTopX, -dHalfTopY, dHeight),
+ Point3d( -dHalfTopX, dHalfTopY, dHeight),
ptMySt, vtMySeg, dSegLen,
dStU, dEnU) ;
- // Faccia laterale 2
- IntersSegmentTrianglePlus( Point3d( dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( dHalfTopX , dHalfTopY , dHeight),
- Point3d( dHalfTopX , -dHalfTopY , dHeight),
- ptMySt, vtMySeg, dSegLen,
- dStU, dEnU) ;
- IntersSegmentTrianglePlus( Point3d( dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( dHalfTopX , dHalfTopY , dHeight),
- ptMySt, vtMySeg, dSegLen,
- dStU, dEnU) ;
- // Faccia laterale 3
- IntersSegmentTrianglePlus( Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( -dHalfTopX , dHalfTopY , dHeight),
- Point3d( dHalfTopX , dHalfTopY , dHeight),
- ptMySt, vtMySeg, dSegLen,
- dStU, dEnU) ;
- IntersSegmentTrianglePlus( Point3d( dHalfBaseX, dHalfBaseY, 0.),
- Point3d( -dHalfBaseX, dHalfBaseY, 0.),
- Point3d( -dHalfTopX , dHalfTopY , dHeight),
- ptMySt, vtMySeg, dSegLen,
- dStU, dEnU) ;
- // Faccia laterale 4
- IntersSegmentTrianglePlus( Point3d( -dHalfBaseX, dHalfBaseY, 0.),
- Point3d( -dHalfTopX , -dHalfTopY , dHeight),
- Point3d( -dHalfTopX , dHalfTopY , dHeight),
- ptMySt, vtMySeg, dSegLen,
- dStU, dEnU) ;
- IntersSegmentTrianglePlus( Point3d( -dHalfBaseX, dHalfBaseY, 0.),
- Point3d( -dHalfBaseX, -dHalfBaseY, 0.),
- Point3d( -dHalfTopX , -dHalfTopY , dHeight),
+ else
+ IntersSegmentPlanePlus( Point3d( -dHalfBaseX, dHalfBaseY, 0),
+ Point3d( -dHalfBaseX, -dHalfBaseY, 0),
+ Point3d( -dHalfTopX, 0, dHeight),
ptMySt, vtMySeg, dSegLen,
dStU, dEnU) ;
+ if ( dEnU < dStU - EPS_ZERO)
+ return false ;
- return ( dEnU > dStU - EPS_ZERO && dStU < dSegLen + EPS_SMALL && dEnU > -EPS_SMALL) ;
+ return true ;
}
//----------------------------------------------------------------------------
@@ -1638,34 +1469,51 @@ bool
VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise) const
{
- // IL sistema del tronco di piramide generalizzato è definito nel sistema locale.
- // Lo porto nel sistema intrinseco.
- Frame3d frMyFrame = frPrismoid ;
- frMyFrame.ToLoc( m_MapFrame) ;
-
- // Box del tronco nel suo sistema
+ // Box del tronco di prismoide nel suo sistema locale
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
- BBox3d b3GenPyrBox( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
- Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
- // Porto il box nel sistema intrinseco dello Zmap
- b3GenPyrBox.ToGlob( frMyFrame) ;
+ BBox3d b3PrismL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
+ Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
- // Box del solido
+ // BBox del tronco di prismoide nel riferimento intrinseco dello Zmap
+ Frame3d frPrismInt = GetToLoc( frPrismoid, m_MapFrame) ;
+ BBox3d b3PrismI = GetToGlob( b3PrismL, frPrismInt) ;
+
+ // BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
- BBox3d b3Int ;
- // Se i box non si si sovrappongono, ho finito.
- if ( ! b3Zmap.FindIntersection( b3GenPyrBox, b3Int))
+ // Se i box non interferiscono, posso uscire
+ if ( ! b3Zmap.Overlaps( b3PrismI) || ! b3Zmap.Overlaps( frPrismInt, b3PrismL))
return true ;
+ // BBox del tronco di prismoide ottimizzato nel riferimento intrinseco dello Zmap
+ Point3d ptMyCen = frPrismInt.Orig() ;
+ Vector3d vtMyAxX = frPrismInt.VersX() ;
+ Vector3d vtMyAxY = frPrismInt.VersY() ;
+ Vector3d vtMyAxZ = frPrismInt.VersZ() ;
+ BBox3d b3Prism ;
+ b3Prism.Add( ptMyCen - dLenghtBaseX / 2 * vtMyAxX - dLenghtBaseY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen + dLenghtBaseX / 2 * vtMyAxX - dLenghtBaseY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen + dLenghtBaseX / 2 * vtMyAxX + dLenghtBaseY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen - dLenghtBaseX / 2 * vtMyAxX + dLenghtBaseY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen + dHeight * vtMyAxZ - dLenghtTopX / 2 * vtMyAxX - dLenghtTopY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen + dHeight * vtMyAxZ + dLenghtTopX / 2 * vtMyAxX - dLenghtTopY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen + dHeight * vtMyAxZ + dLenghtTopX / 2 * vtMyAxX + dLenghtTopY / 2 * vtMyAxY) ;
+ b3Prism.Add( ptMyCen + dHeight * vtMyAxZ - dLenghtTopX / 2 * vtMyAxX + dLenghtTopY / 2 * vtMyAxY) ;
+
+ // Se i box non interferiscono, posso uscire
+ BBox3d b3Int ;
+ if ( ! b3Zmap.FindIntersection( b3Prism, b3Int))
+ return true ;
+
+ // Se verifico solo prima mappa
if ( ! bPrecise) {
- // Limiti su indici
+ // 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)
+ // 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 ;
@@ -1688,7 +1536,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
double dStU, dEnU ;
Point3d ptSegSt = ptLineSt + m_Values[0][nPos][0].dMin * Z_AX ;
Point3d ptSegEn = ptLineSt + m_Values[0][nPos][nSize-1].dMax * Z_AX ;
- if ( RectPrismoidSegmentCollisionPlus( frMyFrame, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
+ if ( RectPrismoidSegmentCollisionPlus( frPrismInt, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( m_Values[0][nPos][nIndex].dMax >= dStU && m_Values[0][nPos][nIndex].dMin <= dEnU)
@@ -1699,12 +1547,14 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
}
}
}
+
+ // altrimenti verifico con tutte e tre le mappe
else {
- // Ciclo sulle mappe
+ // Ciclo sulle mappe
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
Point3d ptInfIntBox = b3Int.GetMin();
Point3d ptSupIntBox = b3Int.GetMax();
- // Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
+ // Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
if ( nMap == 1) {
swap( ptInfIntBox.x, ptInfIntBox.z) ;
swap( ptInfIntBox.x, ptInfIntBox.y) ;
@@ -1717,7 +1567,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
swap( ptSupIntBox.y, ptSupIntBox.z) ;
swap( ptSupIntBox.x, ptSupIntBox.y) ;
}
- // Limiti su indici
+ // Limiti su indici
int nStI = Clamp( int( ptInfIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptSupIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nStJ = Clamp( int( ptInfIntBox.y / m_dStep), 0, m_nNy[nMap] - 1) ;
@@ -1726,18 +1576,18 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
int nSize = int( m_Values[nMap][nDex].size()) ;
if ( nSize == 0)
continue ;
- // Indici del dexel
+ // Indici del dexel
int nI = nDex % m_nNx[nMap] ;
int nJ = nDex / m_nNx[nMap] ;
- // Se fuori dalla regione ammissibile salto l'iterazione
+ // Se fuori dalla regione ammissibile salto l'iterazione
if ( nI < nStI || nI > nEnI || nJ < nStJ || nJ > nEnJ)
continue ;
- // Posizione del dexel
+ // Posizione del dexel
double dX = ( nI + 0.5) * m_dStep ;
double dY = ( nJ + 0.5) * m_dStep ;
Point3d ptLineSt( dX, dY, 0.) ;
Vector3d vtLineDir( 0., 0., 1.) ;
- // Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
+ // Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
if ( nMap == 1) {
swap( ptLineSt.x, ptLineSt.y) ;
swap( ptLineSt.x, ptLineSt.z) ;
@@ -1753,7 +1603,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
double dStU, dEnU ;
Point3d ptSegSt = ptLineSt + m_Values[nMap][nDex][0].dMin * vtLineDir ;
Point3d ptSegEn = ptLineSt + m_Values[nMap][nDex][nSize-1].dMax * vtLineDir ;
- if ( RectPrismoidSegmentCollisionPlus( frMyFrame, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
+ if ( RectPrismoidSegmentCollisionPlus( frPrismInt, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( m_Values[nMap][nDex][nIndex].dMax >= dStU && m_Values[nMap][nDex][nIndex].dMin <= dEnU)
@@ -1798,6 +1648,7 @@ VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, doub
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, bPrecise))
return true ;
+ // Offset fine
// Sfere centrate nei vertici
double dHalfBaseX = dLenghtBaseX / 2 ;
double dHalfBaseY = dLenghtBaseY / 2 ;
@@ -1893,36 +1744,44 @@ VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, doub
bool
VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise) const
{
- // Porto il toro nel sistema intrinseco dello Zmap.
- Point3d ptMyCen = frTorus.Orig() ;
- Vector3d vtMyAx = frTorus.VersZ() ;
- ptMyCen.ToLoc( m_MapFrame) ;
- vtMyAx.ToLoc( m_MapFrame) ;
+ // BBox del toro in locale
+ BBox3d b3TorusL( Point3d( -dMaxRad - dMinRad, -dMaxRad - dMinRad, -dMinRad),
+ Point3d( dMaxRad + dMinRad, dMaxRad + dMinRad, dMinRad)) ;
- // BBox del toro
- BBox3d b3Box( ptMyCen) ;
- b3Box.Add( ptMyCen + vtMyAx * dMinRad) ;
- b3Box.Add( ptMyCen - vtMyAx * dMinRad) ;
- double dTotRad = dMaxRad + dMinRad ;
- if ( vtMyAx.IsXplus() || vtMyAx.IsXminus())
- b3Box.Expand( 0, dTotRad, dTotRad) ;
- else if ( vtMyAx.IsYplus() || vtMyAx.IsYminus())
- b3Box.Expand( dTotRad, 0, dTotRad) ;
- else if ( vtMyAx.IsZplus() || vtMyAx.IsZminus())
- b3Box.Expand( dTotRad, dTotRad, 0) ;
- else {
- double dExpandX = dTotRad * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
- double dExpandY = dTotRad * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
- double dExpandZ = dTotRad * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
- b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
- }
+ // BBox del toro nel riferimento intrinseco dello Zmap
+ Frame3d frTorusInt = GetToLoc( frTorus, m_MapFrame) ;
+ BBox3d b3TorusI = GetToGlob( b3TorusL, frTorusInt) ;
// 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
+ if ( ! b3Zmap.Overlaps( b3TorusI) || ! b3Zmap.Overlaps( frTorusInt, b3TorusL))
+ return true ;
+
+ // BBox del toro ottimizzato nel riferimento intrinseco dello Zmap
+ Point3d ptMyCen = frTorusInt.Orig() ;
+ Vector3d vtMyAx = frTorusInt.VersZ() ;
+ BBox3d b3Torus( ptMyCen) ;
+ b3Torus.Add( ptMyCen + vtMyAx * dMinRad) ;
+ b3Torus.Add( ptMyCen - vtMyAx * dMinRad) ;
+ double dTotRad = dMaxRad + dMinRad ;
+ if ( vtMyAx.IsX())
+ b3Torus.Expand( 0, dTotRad, dTotRad) ;
+ else if ( vtMyAx.IsY())
+ b3Torus.Expand( dTotRad, 0, dTotRad) ;
+ else if ( vtMyAx.IsZ())
+ b3Torus.Expand( dTotRad, dTotRad, 0) ;
+ else {
+ double dExpandX = dTotRad * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
+ double dExpandY = dTotRad * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
+ double dExpandZ = dTotRad * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
+ b3Torus.Expand( dExpandX, dExpandY, dExpandZ) ;
+ }
+
// Se non interferiscono, posso uscire
BBox3d b3Int ;
- if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
+ if ( ! b3Zmap.FindIntersection( b3Torus, b3Int))
return true ;
// Se verifico solo prima mappa
@@ -2282,10 +2141,10 @@ 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) const
-{
+{
// Porto la linea nel riferimento del cilindro
- Point3d ptP = ptLineSt ; ptP.ToLoc( CylFrame) ;
- Vector3d vtV = vtLineDir ; vtV.ToLoc( CylFrame) ;
+ Point3d ptP = GetToLoc( ptLineSt, CylFrame) ;
+ Vector3d vtV = GetToLoc( vtLineDir, CylFrame) ;
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
int nBasInt = 0 ;
@@ -2316,13 +2175,11 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
}
// Determino le intersezioni con la superficie laterale del cilindro
- 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) ;
- vdCoef[2] = vtV.x * vtV.x + vtV.y * vtV.y ;
+ DBLVECTOR vdCoeff{ ptP.x * ptP.x + ptP.y * ptP.y - dRad * dRad,
+ 2 * ( ptP.x * vtV.x + ptP.y * vtV.y),
+ vtV.x * vtV.x + vtV.y * vtV.y} ;
DBLVECTOR vdRoots ;
- int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
+ int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
// Epsilon per piani di tappo
double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ;
@@ -2332,7 +2189,7 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
if ( nRoot == 2) {
double dIntZ2 = ptP.z + vdRoots[1] * vtV.z ;
if ( dIntZ2 < 0 + dEpsLow || dIntZ2 > dH + dEpsUp)
- nRoot = 1 ;
+ -- nRoot ;
}
if ( nRoot >= 1) {
double dIntZ1 = ptP.z + vdRoots[0] * vtV.z ;
@@ -2407,8 +2264,8 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir,
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
{
// Porto la linea nel riferimento del cono
- Point3d ptP = ptLineSt ; ptP.ToLoc( ConusFrame) ;
- Vector3d vtV = vtLineDir ; vtV.ToLoc( ConusFrame) ;
+ Point3d ptP = GetToLoc( ptLineSt, ConusFrame) ;
+ Vector3d vtV = GetToLoc( vtLineDir, ConusFrame) ;
// Raggi delle due basi
double dMinRad = dTan * dMinH ;
@@ -2445,19 +2302,18 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir,
}
// Determino le intersezioni con la superficie laterale del cono
- DBLVECTOR vdCoef( 3) ;
double dSqTan = dTan * dTan ;
- vdCoef[0] = dSqTan * ptP.z * ptP.z - ptP.x * ptP.x - ptP.y * ptP.y ;
- vdCoef[1] = 2 * ( dSqTan * ptP.z * vtV.z - ptP.x * vtV.x - ptP.y * vtV.y) ;
- vdCoef[2] = dSqTan * vtV.z * vtV.z - vtV.x * vtV.x - vtV.y * vtV.y ;
+ DBLVECTOR vdCoeff{ dSqTan * ptP.z * ptP.z - ptP.x * ptP.x - ptP.y * ptP.y,
+ 2 * ( dSqTan * ptP.z * vtV.z - ptP.x * vtV.x - ptP.y * vtV.y),
+ dSqTan * vtV.z * vtV.z - vtV.x * vtV.x - vtV.y * vtV.y} ;
DBLVECTOR vdRoots ;
- int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
+ int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del tronco
if ( nRoot == 2) {
double dIntZ2 = ptP.z + vdRoots[1] * vtV.z ;
if ( dIntZ2 < dMinH + dEpsLow || dIntZ2 > dMaxH + dEpsUp)
- nRoot = 1 ;
+ -- nRoot ;
}
if ( nRoot >= 1) {
double dIntZ1 = ptP.z + vdRoots[0] * vtV.z ;
@@ -2545,8 +2401,8 @@ VolZmap::IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d&
return false ;
// Porto la linea nel riferimento del cilindro
- Point3d ptP = ptLineSt ; ptP.ToLoc( CircFrame) ;
- Vector3d vtV = vtLineDir ; vtV.ToLoc( CircFrame) ;
+ Point3d ptP = GetToLoc( ptLineSt, CircFrame) ;
+ Vector3d vtV = GetToLoc( vtLineDir, CircFrame) ;
// Quadrato del raggio
double dSqRad = dRad * dRad ;
@@ -2688,8 +2544,8 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine
return false ;
// Porto la linea nel riferimento del poliedro
- Point3d ptP = ptLineSt ; ptP.ToLoc( PolyFrame) ;
- Vector3d vtV = vtLineDir ; vtV.ToLoc( PolyFrame) ;
+ Point3d ptP = GetToLoc( ptLineSt, PolyFrame) ;
+ Vector3d vtV = GetToLoc( vtLineDir, PolyFrame) ;
// Facce 1 e 2 parallele a XY
// Facce 3 e 4 parallele a XZ
@@ -2837,10 +2693,8 @@ VolZmap::IntersLineTruncatedPyramid( const Point3d& ptLineSt, const Vector3d& vt
return false ;
// Porto la linea nel riferimento del solido
- Point3d ptP = ptLineSt ;
- Vector3d vtV = vtLineDir ;
- ptP.ToLoc( frTruncPyramFrame) ;
- vtV.ToLoc( frTruncPyramFrame) ;
+ Point3d ptP = GetToLoc( ptLineSt, frTruncPyramFrame) ;
+ Vector3d vtV = GetToLoc( vtLineDir, frTruncPyramFrame) ;
// Se la retta sta sopra o sotto il solido non vi può essere intersezione
if ( abs( vtV.z) < EPS_ZERO && ( ptP.z < EPS_SMALL || ptP.z > dHeight + EPS_SMALL))
diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp
index 077f084..fb5b8eb 100644
--- a/VolZmapGraphics.cpp
+++ b/VolZmapGraphics.cpp
@@ -2047,14 +2047,6 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
else {
if ( nVertComp[nComp] == 5) {
- double dDotAvarage = 0.;
- for (int m = 0; m < nVertComp[nComp] - 1; ++m) {
- for (int l = m + 1 ; l < nVertComp[nComp]; ++l) {
- dDotAvarage += CompoVert[nComp][m].vtVec * CompoVert[nComp][l].vtVec;
- }
- }
- dDotAvarage /= (( nVertComp[nComp] * ( nVertComp[nComp] - 1)) / 2) ;
-
int nNumPar = 0 ;
for ( int m = 0 ; m < nVertComp[nComp] - 1 ; ++ m) {
for ( int l = m + 1 ; l < nVertComp[nComp] ; ++ l) {
@@ -2062,9 +2054,9 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
++ nNumPar ;
}
}
- bExtConfirmed = nNumPar == 3 ;
+ bExtConfirmed = ( nNumPar == 3) ;
}
- else if (nVertComp[nComp] < 5) {
+ else if ( nVertComp[nComp] < 5) {
bExtConfirmed = false ;
}
}