Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 104726c5ee | |||
| e2445c0a15 | |||
| 9880fa0173 | |||
| d276809906 | |||
| 4268da4a1f | |||
| 4f485d0e87 | |||
| d48348fa1c | |||
| 003dd0bdef | |||
| ec109908fa | |||
| 3630b85632 | |||
| fdce6e1853 | |||
| 8ffa9d7fb7 | |||
| 360484c9af | |||
| 47606bffcd | |||
| aea99a635f | |||
| ce139c6925 | |||
| 5dcf5f5616 | |||
| 451ef8356b | |||
| 6e810f050e | |||
| 6bfb5c619f | |||
| bd90fc2b59 | |||
| 5800093e53 | |||
| fae6a7cd78 | |||
| 65daddfced | |||
| 95915b16e5 | |||
| ddade325c4 | |||
| 46b91bb49d | |||
| c8ce0a242e | |||
| 8be2246249 | |||
| 47e79756d1 | |||
| 595421bcdd | |||
| 517a66b0fe | |||
| 56cff98cf3 | |||
| 3168bee865 | |||
| 3d2f8c1495 | |||
| 7cd83efd97 | |||
| 751ea085a6 | |||
| 15ed754512 |
+15
-5
@@ -19,10 +19,23 @@
|
|||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Il sistema di riferimento è allineato con il box e ha origine in un suo vertice.
|
||||||
|
// La distanza di sicurezza ha effetto solo se maggiore di EPS_SMALL.
|
||||||
|
// Il sistema di riferimento del box è riferito a quello della superficie.
|
||||||
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
|
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
|
// Se il box non è ben definito non ha senso proseguire
|
||||||
|
if ( vtDiag.IsSmall())
|
||||||
|
return true ;
|
||||||
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
|
return true ;
|
||||||
// Recupero BBox del poliedro
|
// Recupero BBox del poliedro
|
||||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||||
// Calcolo il BBox del parallelepipedo
|
// Calcolo il BBox del parallelepipedo
|
||||||
@@ -39,13 +52,10 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
|
|||||||
for ( int nT : vT) {
|
for ( int nT : vT) {
|
||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
if ( Stm.GetTriangle( nT, Tria)) {
|
if ( Stm.GetTriangle( nT, Tria)) {
|
||||||
if ( CDeBoxTria( frBox, vtDiag, dSafeDist, Tria))
|
if ( CDeBoxTria( frBox, vtDiag, Tria, dSafeDist))
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Se superficie aperta, non c'è collisione
|
|
||||||
if ( ! Stm.IsClosed())
|
|
||||||
return false ;
|
|
||||||
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
|
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||||
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
|
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
+1
-1
@@ -171,7 +171,7 @@ CDeSimpleBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const Triangle3d& trTria)
|
CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Porto il triangolo nel riferimento del box
|
// Porto il triangolo nel riferimento del box
|
||||||
Triangle3d trTriaL = trTria ;
|
Triangle3d trTriaL = trTria ;
|
||||||
|
|||||||
+1
-1
@@ -17,4 +17,4 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool CDeSimpleBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d& trTria) ;
|
bool CDeSimpleBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d& trTria) ;
|
||||||
bool CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const Triangle3d& trTria) ;
|
bool CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
+1
-1
@@ -97,7 +97,7 @@ CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Tr
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria)
|
CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
return CDeSimpleCapsTria( ptP1, ptP2, dR + max( 0., dSafeDist), trTria) ;
|
return CDeSimpleCapsTria( ptP1, ptP2, dR + max( 0., dSafeDist), trTria) ;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,4 +16,4 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria) ;
|
bool CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria) ;
|
||||||
bool CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria) ;
|
bool CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
@@ -22,24 +22,25 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// La funzione restituisce true in caso di collisone, false in caso di assenza
|
|
||||||
// di collisione o inconsistenza dei parametri di input.
|
|
||||||
// Le due superfici devono essere espresse nel medesimo sistema di riferimento.
|
// Le due superfici devono essere espresse nel medesimo sistema di riferimento.
|
||||||
// La distanza di sicurezza ha effetto solo se maggiore di EPS_SMALL.
|
// La distanza di sicurezza ha effetto solo se maggiore di EPS_SMALL.
|
||||||
// Se necessario cerco la collisione con un offset della superficie B costituito
|
// Se necessario cerco la collisione con un offset della superficie B costituito
|
||||||
// da sfere centrate nei vertici, cilindri con i segmenti per asse e il triangolo
|
// da sfere centrate nei vertici, cilindri con gli spigoli per asse e il triangolo
|
||||||
// originale traslato di una costante pari alla distanza di sicurezza lungo la
|
// originale traslato della distanza di sicurezza lungo la sua normale.
|
||||||
// sua normale.
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Recupero le superfici base
|
// Recupero le superfici base
|
||||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||||
const SurfTriMesh* pSrfB = GetBasicSurfTriMesh( &SurfB) ;
|
const SurfTriMesh* pSrfB = GetBasicSurfTriMesh( &SurfB) ;
|
||||||
// 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 ( pSrfA == nullptr || ! pSrfA->IsValid() || ! pSrfA->IsClosed() ||
|
if ( pSrfA == nullptr || ! pSrfA->IsValid() || ! pSrfA->IsClosed() ||
|
||||||
pSrfB == nullptr || ! pSrfB->IsValid() || ! pSrfB->IsClosed())
|
pSrfB == nullptr || ! pSrfB->IsValid() || ! pSrfB->IsClosed())
|
||||||
return false ;
|
return true ;
|
||||||
// Se i box delle superfici non si intersecano, ho finito.
|
// Se i box delle superfici non si intersecano, ho finito.
|
||||||
BBox3d b3BoxA, b3BoxB ;
|
BBox3d b3BoxA, b3BoxB ;
|
||||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||||
|
|||||||
@@ -21,15 +21,22 @@ using namespace std ;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Il sistema di riferimento deve avere l'asse di simmetria del cono come asse Z e origine nel centro della base.
|
// Il sistema di riferimento deve avere l'asse di simmetria del cono come asse Z e origine nel centro della base.
|
||||||
// La distanza di sicurezza ha effetto solo se maggiore di epsilon, altrimenti è ignorata ed è ininfluente.
|
// La distanza di sicurezza ha effetto solo se maggiore di EPS_SMALL, altrimenti è ignorata ed è ininfluente.
|
||||||
// Il sistema di riferimento del cono deve essere immerso in quello della superficie.
|
// Il sistema di riferimento del cono è riferito a quello della superficie.
|
||||||
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||||
double dSafeDist, const ISurfTriMesh& Stm)
|
const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
// 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)
|
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
|
return true ;
|
||||||
// Recupero BBox della trimesh
|
// Recupero BBox della trimesh
|
||||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||||
// Calcolo il BBox del tronco di cono
|
// Calcolo il BBox del tronco di cono
|
||||||
@@ -49,13 +56,10 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
|
|||||||
for ( int nT : vT) {
|
for ( int nT : vT) {
|
||||||
Triangle3d trTria ;
|
Triangle3d trTria ;
|
||||||
if ( Stm.GetTriangle( nT, trTria)) {
|
if ( Stm.GetTriangle( nT, trTria)) {
|
||||||
if ( CDeConeFrustumTria( frCone, dBaseRad, dTopRad, dHeight, dSafeDist, trTria))
|
if ( CDeConeFrustumTria( frCone, dBaseRad, dTopRad, dHeight, trTria, dSafeDist))
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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
|
// 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))
|
if ( ! b3Surf.Encloses( b3Cone) && ! b3Cone.Encloses( b3Surf))
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ CDeSimpleConeFrustumTria( const Frame3d& frCone, double dMinRad, double dMaxRad,
|
|||||||
// La distanza di sicurezza ha effetto solo se maggiore di epsilon, altrimenti è ignorata ed è ininfluente.
|
// La distanza di sicurezza ha effetto solo se maggiore di epsilon, altrimenti è ignorata ed è ininfluente.
|
||||||
bool
|
bool
|
||||||
CDeConeFrustumTria( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
CDeConeFrustumTria( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||||
double dSafeDist, const Triangle3d& trTria)
|
const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Se il tronco di cono o il triangolo non sono ben definiti non procedo
|
// Se il tronco di cono o il triangolo non sono ben definiti non procedo
|
||||||
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL || ! trTria.IsValid())
|
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL || ! trTria.IsValid())
|
||||||
@@ -142,7 +142,7 @@ CDeConeFrustumTria( const Frame3d& frCone, double dBaseRad, double dTopRad, doub
|
|||||||
|
|
||||||
// Se è un cilindro chiamo la routine apposita.
|
// Se è un cilindro chiamo la routine apposita.
|
||||||
if ( abs( dBaseRad - dTopRad) < EPS_SMALL)
|
if ( abs( dBaseRad - dTopRad) < EPS_SMALL)
|
||||||
return CDeCylTria( frCone, max( dBaseRad, dTopRad), dHeight, dSafeDist, trTria) ;
|
return CDeCylTria( frCone, max( dBaseRad, dTopRad), dHeight, trTria, dSafeDist) ;
|
||||||
|
|
||||||
// Se il raggio di base è maggiore del raggio top cambio il sistema di riferimento.
|
// Se il raggio di base è maggiore del raggio top cambio il sistema di riferimento.
|
||||||
double dMinRad = dBaseRad ;
|
double dMinRad = dBaseRad ;
|
||||||
@@ -156,11 +156,11 @@ CDeConeFrustumTria( const Frame3d& frCone, double dBaseRad, double dTopRad, doub
|
|||||||
|
|
||||||
// Se è un cono, chiamo la routine apposita
|
// Se è un cono, chiamo la routine apposita
|
||||||
if ( dMinRad < EPS_SMALL)
|
if ( dMinRad < EPS_SMALL)
|
||||||
return CDeConeTria( frMyCone, dMaxRad, dHeight, dSafeDist, trTria) ;
|
return CDeConeTria( frMyCone, dMaxRad, dHeight, trTria, dSafeDist) ;
|
||||||
|
|
||||||
// Se distanza di sicurezza nulla
|
// Se distanza di sicurezza nulla
|
||||||
if ( dSafeDist < EPS_SMALL)
|
if ( dSafeDist < EPS_SMALL)
|
||||||
return CDeSimpleConeFrustumTria( frMyCone, dBaseRad, dTopRad, dHeight, trTria ) ;
|
return CDeSimpleConeFrustumTria( frMyCone, dBaseRad, dTopRad, dHeight, trTria) ;
|
||||||
|
|
||||||
// Verifica preliminare con tronco di cono esteso
|
// Verifica preliminare con tronco di cono esteso
|
||||||
double dDiffRad = dMaxRad - dMinRad ;
|
double dDiffRad = dMaxRad - dMinRad ;
|
||||||
|
|||||||
@@ -20,6 +20,5 @@
|
|||||||
// Il sistema di riferimento deve avere l'origine nel centro della base minore e l'asse
|
// Il sistema di riferimento deve avere l'origine nel centro della base minore e l'asse
|
||||||
// di simmetria del cono, rivolto verso la direzione di apertura, come asse Z.
|
// di simmetria del cono, rivolto verso la direzione di apertura, come asse Z.
|
||||||
bool CDeSimpleConeFrustumTria( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, const Triangle3d& trTria) ;
|
bool CDeSimpleConeFrustumTria( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, const Triangle3d& trTria) ;
|
||||||
// Il sistema di riferimento ha l'asse Z coincidente con l'asse di simmetria del cono e l'origine nel centro della base.
|
|
||||||
bool CDeConeFrustumTria( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
bool CDeConeFrustumTria( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||||
double dSafeDist, const Triangle3d& trTria) ;
|
const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ CDeSimpleConeTria( const Frame3d& frCone, double dRad, double dHeight, const Tri
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeConeTria( const Frame3d& frCone, double dRad, double dHeight, double dSafeDist, const Triangle3d& trTria)
|
CDeConeTria( const Frame3d& frCone, double dRad, double dHeight, const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Verifico validità del cono
|
// Verifico validità del cono
|
||||||
if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
|
if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
|
||||||
|
|||||||
+1
-1
@@ -19,4 +19,4 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Il sistema di riferimento ha asse Z coincidente con l'asse del cono e origine nel vertice del cono (punto più basso).
|
// Il sistema di riferimento ha asse Z coincidente con l'asse del cono e origine nel vertice del cono (punto più basso).
|
||||||
bool CDeSimpleConeTria( const Frame3d& frCone, double dRad, double dHeight, const Triangle3d& trTria) ;
|
bool CDeSimpleConeTria( const Frame3d& frCone, double dRad, double dHeight, const Triangle3d& trTria) ;
|
||||||
bool CDeConeTria( const Frame3d& frCone, double dRad, double dHeight, double dSafeDist, const Triangle3d& trTria) ;
|
bool CDeConeTria( const Frame3d& frCone, double dRad, double dHeight, const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
@@ -18,17 +18,23 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Il toro convesso è il disco limitato dalla sola parte esterna del toro.
|
// Il toro convesso è il solido a disco limitato dalla sola parte esterna del toro.
|
||||||
// Raggio principale R1, raggio secondario R2.
|
// Raggio principale R1, raggio secondario R2.
|
||||||
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
|
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
|
||||||
// La funzione restituisce true in caso di collisione.
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
||||||
double dSafeDist, const ISurfTriMesh& Stm)
|
const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
// I raggi devono essere non nulli e la superficie ben definita.
|
// I raggi devono essere non nulli
|
||||||
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
|
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
|
return true ;
|
||||||
// Box della superficie
|
// Box della superficie
|
||||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||||
// Box del toro (sempre completo)
|
// Box del toro (sempre completo)
|
||||||
@@ -47,13 +53,10 @@ CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
|||||||
for ( int nT : vT) {
|
for ( int nT : vT) {
|
||||||
Triangle3d trTria ;
|
Triangle3d trTria ;
|
||||||
if ( Stm.GetTriangle( nT, trTria)) {
|
if ( Stm.GetTriangle( nT, trTria)) {
|
||||||
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, trTria, dSafeDist))
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Se superficie aperta, non c'è collisione
|
|
||||||
if ( ! Stm.IsClosed())
|
|
||||||
return false ;
|
|
||||||
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
|
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||||
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
|
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ CDeSimpleConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, in
|
|||||||
bool bContinue = plyApprox.GetFirstPoint( ptSt) && plyApprox.GetNextPoint( ptEn) ;
|
bool bContinue = plyApprox.GetFirstPoint( ptSt) && plyApprox.GetNextPoint( ptEn) ;
|
||||||
while ( bContinue && ! bCollision) {
|
while ( bContinue && ! bCollision) {
|
||||||
frConus.Set( Point3d( 0., 0., ptSt.z), Frame3d::TOP) ;
|
frConus.Set( Point3d( 0., 0., ptSt.z), Frame3d::TOP) ;
|
||||||
bCollision = CDeConeFrustumTria( frConus, ptSt.x, ptEn.x, ptEn.z - ptSt.z, 0., trMyTria) ;
|
bCollision = CDeSimpleConeFrustumTria( frConus, ptSt.x, ptEn.x, ptEn.z - ptSt.z, trMyTria) ;
|
||||||
ptSt = ptEn ;
|
ptSt = ptEn ;
|
||||||
bContinue = plyApprox.GetNextPoint( ptEn) ;
|
bContinue = plyApprox.GetNextPoint( ptEn) ;
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ CDeSimpleConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, in
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType,
|
CDeConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType,
|
||||||
double dSafeDist, const Triangle3d& trTria)
|
const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
// I raggi devono essere non nulli e il triangolo ben definito.
|
// I raggi devono essere non nulli e il triangolo ben definito.
|
||||||
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! trTria.IsValid())
|
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! trTria.IsValid())
|
||||||
|
|||||||
@@ -28,4 +28,4 @@ enum ConvexTorusType { CT_INF = -1, CT_SUP = 1, CT_TOT = 0} ;
|
|||||||
bool CDeSimpleConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType,
|
bool CDeSimpleConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType,
|
||||||
const Triangle3d& trTria) ;
|
const Triangle3d& trTria) ;
|
||||||
bool CDeConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType,
|
bool CDeConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType,
|
||||||
double dSafeDist, const Triangle3d& trTria) ;
|
const Triangle3d& trTria, double dSafeDist) ;
|
||||||
+18
-8
@@ -1,7 +1,7 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2020-2020
|
// EgalTech 2020-2024
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : CDCylSurfTm.cpp Data : 09.01.20 Versione : 2.2a2
|
// File : CDCylSurfTm.cpp Data : 15.02.24 Versione : 2.6b2
|
||||||
// Contenuto : Implementazione della verifica di collisione tra
|
// Contenuto : Implementazione della verifica di collisione tra
|
||||||
// Cylinder e Closed SurftriMesh.
|
// Cylinder e Closed SurftriMesh.
|
||||||
//
|
//
|
||||||
@@ -19,17 +19,30 @@
|
|||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Il sistema di riferimento deve avere l'asse di simmetria del cilindro come asse Z e origine nel centro della base o del top.
|
||||||
|
// La distanza di sicurezza ha effetto solo se maggiore di EPS_SMALL, altrimenti è ignorata ed è ininfluente.
|
||||||
|
// Il sistema di riferimento del cilindro è riferito a quello della superficie.
|
||||||
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm)
|
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
|
// Il cilindro deve essere ben definito
|
||||||
|
if ( dR < EPS_SMALL || dH < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
|
return true ;
|
||||||
// Recupero BBox del poliedro
|
// Recupero BBox del poliedro
|
||||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||||
// Sistemazioni cilindro
|
// Sistemazioni cilindro
|
||||||
Frame3d frMyCyl = frCyl ;
|
Frame3d frMyCyl = frCyl ;
|
||||||
if ( dH < 0) {
|
if ( dH < 0) {
|
||||||
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
|
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
|
||||||
dH = - dH ;
|
dH = -dH ;
|
||||||
}
|
}
|
||||||
// Calcolo il BBox del cilindro
|
// Calcolo il BBox del cilindro
|
||||||
BBox3d b3CylL( Point3d( -dR, -dR, 0),
|
BBox3d b3CylL( Point3d( -dR, -dR, 0),
|
||||||
@@ -46,13 +59,10 @@ CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist
|
|||||||
for ( int nT : vT) {
|
for ( int nT : vT) {
|
||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
if ( Stm.GetTriangle( nT, Tria)) {
|
if ( Stm.GetTriangle( nT, Tria)) {
|
||||||
if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria))
|
if ( CDeCylTria( frMyCyl, dR, dH, Tria, dSafeDist))
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Se superficie aperta, non c'è collisione
|
|
||||||
if ( ! Stm.IsClosed())
|
|
||||||
return false ;
|
|
||||||
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
|
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||||
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
|
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ CDeSimpleCylTria( const Frame3d& frCyl, double dR, double dH, const Triangle3d&
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeCylTria( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const Triangle3d& trTria)
|
CDeCylTria( const Frame3d& frCyl, double dR, double dH, const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Se distanza di sicurezza nulla
|
// Se distanza di sicurezza nulla
|
||||||
if ( dSafeDist < EPS_SMALL)
|
if ( dSafeDist < EPS_SMALL)
|
||||||
|
|||||||
+1
-1
@@ -16,4 +16,4 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool CDeSimpleCylTria( const Frame3d& frCyl, double dR, double dH, const Triangle3d& trTria) ;
|
bool CDeSimpleCylTria( const Frame3d& frCyl, double dR, double dH, const Triangle3d& trTria) ;
|
||||||
bool CDeCylTria( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const Triangle3d& trTria) ;
|
bool CDeCylTria( const Frame3d& frCyl, double dR, double dH, const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
@@ -22,16 +22,23 @@ using namespace std ;
|
|||||||
// Il sistema di riferimento deve avere l'origine nel centro della Base, asse X lungo
|
// Il sistema di riferimento deve avere l'origine nel centro della Base, asse X lungo
|
||||||
// un segmento della stessa e asse Z ortogonale alle basi e diretta verso la base Top.
|
// un segmento della stessa e asse Z ortogonale alle basi e diretta verso la base Top.
|
||||||
// Il sistema di riferimento della piramide deve essere immerso in quello della superficie.
|
// Il sistema di riferimento della piramide deve essere immerso in quello della superficie.
|
||||||
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
||||||
double dSafeDist, const ISurfTriMesh& Stm)
|
const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Se il tronco di piramide non è definito o la superficie non ben definita non ha senso proseguire.
|
// Se il tronco di piramide non è definito non ha senso proseguire.
|
||||||
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
||||||
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
|
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
|
||||||
dHeight < EPS_SMALL || ! Stm.IsValid())
|
dHeight < EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
|
return true ;
|
||||||
// Recupero BBox della trimesh
|
// Recupero BBox della trimesh
|
||||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||||
// Calcolo il BBox del tronco di piramide
|
// Calcolo il BBox del tronco di piramide
|
||||||
@@ -53,13 +60,10 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
|||||||
Triangle3d trTria ;
|
Triangle3d trTria ;
|
||||||
if ( Stm.GetTriangle( nT, trTria)) {
|
if ( Stm.GetTriangle( nT, trTria)) {
|
||||||
if ( CDeRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight,
|
if ( CDeRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight,
|
||||||
dSafeDist, trTria))
|
trTria, dSafeDist))
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Se superficie aperta, non c'è collisione
|
|
||||||
if ( ! Stm.IsClosed())
|
|
||||||
return false ;
|
|
||||||
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
|
// 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))
|
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ CDeSimpleRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, doubl
|
|||||||
bool
|
bool
|
||||||
CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
||||||
double dSafeDist, const Triangle3d& trTria)
|
const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
// Se il tronco di piramide o il triangolo non sono ben definiti non procedo
|
// Se il tronco di piramide o il triangolo non sono ben definiti non procedo
|
||||||
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ bool CDeSimpleRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX,
|
|||||||
// asse X lungo un lato della stessa e asse Z ortogonale alle basi e diretta verso la base Top.
|
// asse X lungo un lato della stessa e asse Z ortogonale alle basi e diretta verso la base Top.
|
||||||
bool CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
bool CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
||||||
double dSafeDist, const Triangle3d& trTria) ;
|
const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
+12
-5
@@ -19,10 +19,20 @@
|
|||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// La funzione restituisce :
|
||||||
|
// - true in caso di collisione o inconsistenza dei parametri di input
|
||||||
|
// - false in caso di assenza di collisione.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
|
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, const ISurfTriMesh& Stm, double dSafeDist)
|
||||||
{
|
{
|
||||||
|
// Il raggio deve essere non nullo
|
||||||
|
if ( dR < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
// Se superficie non valida o aperta, non ha senso proseguire
|
||||||
|
if ( ! Stm.IsValid() || ! Stm.IsClosed())
|
||||||
|
return true ;
|
||||||
// Recupero BBox del poliedro
|
// Recupero BBox del poliedro
|
||||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||||
// Calcolo il BBox della sfera
|
// Calcolo il BBox della sfera
|
||||||
@@ -38,13 +48,10 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
|
|||||||
for ( int nT : vT) {
|
for ( int nT : vT) {
|
||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
if ( Stm.GetTriangle( nT, Tria)) {
|
if ( Stm.GetTriangle( nT, Tria)) {
|
||||||
if ( CDeSpheTria( ptCen, dR, dSafeDist, Tria))
|
if ( CDeSpheTria( ptCen, dR, Tria, dSafeDist))
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Se superficie aperta, non c'è collisione
|
|
||||||
if ( ! Stm.IsClosed())
|
|
||||||
return false ;
|
|
||||||
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
|
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||||
if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
|
if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ CDeSimpleSpheTria( const Point3d& ptCen, double dR, const Triangle3d& trTria)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CDeSpheTria( const Point3d& ptCen, double dR, double dSafeDist, const Triangle3d& trTria)
|
CDeSpheTria( const Point3d& ptCen, double dR, const Triangle3d& trTria, double dSafeDist)
|
||||||
{
|
{
|
||||||
return CDeSimpleSpheTria( ptCen, dR + max( 0., dSafeDist), trTria) ;
|
return CDeSimpleSpheTria( ptCen, dR + max( 0., dSafeDist), trTria) ;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,4 +16,4 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool CDeSimpleSpheTria( const Point3d& ptCen, double dR, const Triangle3d& trTria) ;
|
bool CDeSimpleSpheTria( const Point3d& ptCen, double dR, const Triangle3d& trTria) ;
|
||||||
bool CDeSpheTria( const Point3d& ptCen, double dR, double dSafeDist, const Triangle3d& trTria) ;
|
bool CDeSpheTria( const Point3d& ptCen, double dR, const Triangle3d& trTria, double dSafeDist) ;
|
||||||
|
|||||||
+1
-1
@@ -368,4 +368,4 @@ ClampSegmentOutPlane( const Plane3d& plPlane, Point3d& ptSegP, const Vector3d& v
|
|||||||
dSegLen -= dIntersLen ;
|
dSegLen -= dIntersLen ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -309,14 +309,26 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="CurveByApprox.cpp" />
|
<ClCompile Include="CurveByApprox.cpp" />
|
||||||
<ClCompile Include="CurveByInterp.cpp" />
|
<ClCompile Include="CurveByInterp.cpp" />
|
||||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||||
|
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||||
|
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||||
<ClCompile Include="PolygonElevation.cpp" />
|
<ClCompile Include="PolygonElevation.cpp" />
|
||||||
|
<ClCompile Include="RotationMinimizeFrame.cpp" />
|
||||||
<ClCompile Include="Voronoi.cpp" />
|
<ClCompile Include="Voronoi.cpp" />
|
||||||
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
|
||||||
|
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
||||||
|
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
||||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
||||||
|
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
|
||||||
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
||||||
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
||||||
<ClInclude Include="CDeBoxTria.h" />
|
<ClInclude Include="CDeBoxTria.h" />
|
||||||
@@ -449,6 +461,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="VolZmapGraphics.cpp" />
|
<ClCompile Include="VolZmapGraphics.cpp" />
|
||||||
<ClCompile Include="VolZmapVolume.cpp" />
|
<ClCompile Include="VolZmapVolume.cpp" />
|
||||||
<ClCompile Include="VolZmap.cpp" />
|
<ClCompile Include="VolZmap.cpp" />
|
||||||
|
<ClInclude Include="RotationMinimizeFrame.h" />
|
||||||
<ClInclude Include="Voronoi.h" />
|
<ClInclude Include="Voronoi.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -43,15 +43,18 @@
|
|||||||
<Filter Include="File di origine\GeoOffset">
|
<Filter Include="File di origine\GeoOffset">
|
||||||
<UniqueIdentifier>{f07670fd-9429-4b7e-ac6d-1c0022e756fb}</UniqueIdentifier>
|
<UniqueIdentifier>{f07670fd-9429-4b7e-ac6d-1c0022e756fb}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="File di origine\GeoCollision">
|
|
||||||
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="File di origine\GeoProject">
|
<Filter Include="File di origine\GeoProject">
|
||||||
<UniqueIdentifier>{d96752da-1884-4a73-ba1b-5b20b606e469}</UniqueIdentifier>
|
<UniqueIdentifier>{d96752da-1884-4a73-ba1b-5b20b606e469}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="File di origine\GeoElevation">
|
<Filter Include="File di origine\GeoElevation">
|
||||||
<UniqueIdentifier>{4c6a9dc5-8fac-4ecd-bde6-3e37e056712e}</UniqueIdentifier>
|
<UniqueIdentifier>{4c6a9dc5-8fac-4ecd-bde6-3e37e056712e}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="File di origine\GeoCollisionAvoid">
|
||||||
|
<UniqueIdentifier>{ae52e402-3063-45e3-b9f7-1710035a1f56}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="File di origine\GeoCollisionDetection">
|
||||||
|
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Vector3d.cpp">
|
<ClCompile Include="Vector3d.cpp">
|
||||||
@@ -372,17 +375,8 @@
|
|||||||
<ClCompile Include="IntersLineSurfStd.cpp">
|
<ClCompile Include="IntersLineSurfStd.cpp">
|
||||||
<Filter>File di origine\GeoInters</Filter>
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CAvToolTriangle.cpp">
|
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CAvToolSurfTm.cpp">
|
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CDeBoxTria.cpp">
|
<ClCompile Include="CDeBoxTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp">
|
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="IntersSurfTmSurfTm.cpp">
|
<ClCompile Include="IntersSurfTmSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoInters</Filter>
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
@@ -400,19 +394,19 @@
|
|||||||
<Filter>File di origine\Geo</Filter>
|
<Filter>File di origine\Geo</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeCylTria.cpp">
|
<ClCompile Include="CDeCylTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeBoxClosedSurfTm.cpp">
|
<ClCompile Include="CDeBoxClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeCylClosedSurfTm.cpp">
|
<ClCompile Include="CDeCylClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeSpheTria.cpp">
|
<ClCompile Include="CDeSpheTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeSpheClosedSurfTm.cpp">
|
<ClCompile Include="CDeSpheClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SurfBezier.cpp">
|
<ClCompile Include="SurfBezier.cpp">
|
||||||
<Filter>File di origine\Geo</Filter>
|
<Filter>File di origine\Geo</Filter>
|
||||||
@@ -430,34 +424,34 @@
|
|||||||
<Filter>File di origine\GeoDist</Filter>
|
<Filter>File di origine\GeoDist</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeTriaTria.cpp">
|
<ClCompile Include="CDeTriaTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeConeTria.cpp">
|
<ClCompile Include="CDeConeTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeUtility.cpp">
|
<ClCompile Include="CDeUtility.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp">
|
<ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeConeFrustumClosedSurfTm.cpp">
|
<ClCompile Include="CDeConeFrustumClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeConeFrustumTria.cpp">
|
<ClCompile Include="CDeConeFrustumTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeConvexTorusClosedSurfTm.cpp">
|
<ClCompile Include="CDeConvexTorusClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeConvexTorusTria.cpp">
|
<ClCompile Include="CDeConvexTorusTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeRectPrismoidClosedSurfTm.cpp">
|
<ClCompile Include="CDeRectPrismoidClosedSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SurfTriMeshUtilities.cpp">
|
<ClCompile Include="SurfTriMeshUtilities.cpp">
|
||||||
<Filter>File di origine\Geo</Filter>
|
<Filter>File di origine\Geo</Filter>
|
||||||
@@ -469,7 +463,7 @@
|
|||||||
<Filter>File di origine\Base</Filter>
|
<Filter>File di origine\Base</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CDeCapsTria.cpp">
|
<ClCompile Include="CDeCapsTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Circle2P.cpp">
|
<ClCompile Include="Circle2P.cpp">
|
||||||
<Filter>File di origine\GeoCreate</Filter>
|
<Filter>File di origine\GeoCreate</Filter>
|
||||||
@@ -510,6 +504,27 @@
|
|||||||
<ClCompile Include="PolygonElevation.cpp">
|
<ClCompile Include="PolygonElevation.cpp">
|
||||||
<Filter>File di origine\GeoElevation</Filter>
|
<Filter>File di origine\GeoElevation</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||||
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CAvSimpleSurfFrMove.cpp">
|
||||||
|
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CAvToolSurfTm.cpp">
|
||||||
|
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CAvToolTriangle.cpp">
|
||||||
|
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="IntersLineVolZmap.cpp">
|
||||||
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="IntersPlaneVolZmap.cpp">
|
||||||
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="RotationMinimizeFrame.cpp">
|
||||||
|
<Filter>File di origine\Geo</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h">
|
<ClInclude Include="stdafx.h">
|
||||||
@@ -1169,6 +1184,18 @@
|
|||||||
<ClInclude Include="Voronoi.h">
|
<ClInclude Include="Voronoi.h">
|
||||||
<Filter>File di intestazione</Filter>
|
<Filter>File di intestazione</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h">
|
||||||
|
<Filter>File di intestazione\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h">
|
||||||
|
<Filter>File di intestazione\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h">
|
||||||
|
<Filter>File di intestazione\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RotationMinimizeFrame.h">
|
||||||
|
<Filter>File di intestazione</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||||
|
|||||||
+1
-1
@@ -3073,7 +3073,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
|||||||
return false ;
|
return false ;
|
||||||
bool bInt ;
|
bool bInt ;
|
||||||
|
|
||||||
bInt = ! pZmap->AvoidBox( frBBoxFrame, ptEnd - ORIG) ;
|
bInt = pZmap->CDeBox( frBBoxFrame, ptEnd - ORIG) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}*/
|
}*/
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2024-2024
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : IntersCurveSurfTm.cpp Data : 23.02.24 Versione : 2.6b4
|
||||||
|
// Contenuto : Implementazione della intersezione curva/superficie trimesh.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 23.02.24 DS Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersCurveSurfTm.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static void
|
||||||
|
UpdateInfoIntersCurveSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen, double dUs, double dUe,
|
||||||
|
int nT, const Triangle3d& Tria, ICSIVECTOR& vInfo)
|
||||||
|
{
|
||||||
|
Point3d ptInt, ptInt2 ;
|
||||||
|
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, true) ;
|
||||||
|
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
||||||
|
double dU = dUs + ( ptInt - ptL) * vtDir / dLen * ( dUe - dUs) ;
|
||||||
|
double dCosDN = vtDir * Tria.GetN() ;
|
||||||
|
vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ;
|
||||||
|
}
|
||||||
|
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
|
||||||
|
double dU = dUs + ( ptInt - ptL) * vtDir / dLen * ( dUe - dUs) ;
|
||||||
|
double dU2 = dUs + ( ptInt2 - ptL) * vtDir / dLen * ( dUe - dUs) ;
|
||||||
|
double dCosDN = vtDir * Tria.GetN() ;
|
||||||
|
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static void
|
||||||
|
OrderInfoIntersCurveSurfTm( ICSIVECTOR& vInfo)
|
||||||
|
{
|
||||||
|
// se non trovati, esco
|
||||||
|
if ( vInfo.size() == 0)
|
||||||
|
return ;
|
||||||
|
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||||
|
sort( vInfo.begin(), vInfo.end(),
|
||||||
|
[]( const IntCrvStmInfo& a, const IntCrvStmInfo& b)
|
||||||
|
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
||||||
|
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||||
|
return ( dUa < dUb) ; }) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Intersezione di una curva con una superficie TriMesh
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurveSurfTm( const ICurve& Curve, const ISurfTriMesh& Stm, double dLinTol, ICSIVECTOR& vInfo)
|
||||||
|
{
|
||||||
|
// verifico i parametri ricevuti
|
||||||
|
if ( & Curve == nullptr || &Stm == nullptr || &vInfo == nullptr)
|
||||||
|
return false ;
|
||||||
|
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||||
|
vInfo.clear() ;
|
||||||
|
|
||||||
|
// approssimo la curva con una spezzata
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_SPECIAL, PL))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// per ogni segmento dell'approssimante cerco l'intersezione con la superficie
|
||||||
|
double dParS, dParE ;
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
bool bFound = PL.GetFirstULine( &dParS, &ptStart, &dParE, &ptEnd) ;
|
||||||
|
while ( bFound) {
|
||||||
|
Vector3d vtDir = ptEnd - ptStart ;
|
||||||
|
double dLen = vtDir.Len() ;
|
||||||
|
if ( dLen > EPS_SMALL) {
|
||||||
|
vtDir /= dLen ;
|
||||||
|
// cerco i triangoli intersecati dal segmento
|
||||||
|
const double BOX_STEP = 10 ;
|
||||||
|
int nStep = int( ceil( dLen / BOX_STEP)) ;
|
||||||
|
Vector3d vtStep = dLen / nStep * vtDir ;
|
||||||
|
INTVECTOR vPrevT ;
|
||||||
|
for ( int i = 0 ; i < nStep ; ++ i) {
|
||||||
|
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
|
||||||
|
INTVECTOR vT ;
|
||||||
|
if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) {
|
||||||
|
for ( auto nT : vT) {
|
||||||
|
// se triangolo non ancora intersecato
|
||||||
|
if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) {
|
||||||
|
vPrevT.emplace_back( nT) ;
|
||||||
|
Triangle3d Tria ;
|
||||||
|
Stm.GetTriangle( nT, Tria) ;
|
||||||
|
// aggiorno info con intersezione
|
||||||
|
UpdateInfoIntersCurveSurfTm( ptStart, vtDir, dLen, dParS, dParE, nT, Tria, vInfo) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// passo al segmento successivo
|
||||||
|
bFound = PL.GetNextULine( &dParS, &ptStart, &dParE, &ptEnd) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea
|
||||||
|
OrderInfoIntersCurveSurfTm( vInfo) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurveSurfTmExt( const ICurve& Curve, const ISurfTriMesh& Stm, double dLinTol, INTDBLVECTOR& vInters)
|
||||||
|
{
|
||||||
|
ICSIVECTOR vInfo ;
|
||||||
|
vInters.clear() ;
|
||||||
|
return ( IntersCurveSurfTm( Curve, Stm, dLinTol, vInfo) && FilterCurveSurfTmInters( Curve, vInfo, vInters)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
FilterCurveSurfTmInters( const ICurve& Curve, const ICSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||||
|
{
|
||||||
|
// verifico i parametri ricevuti
|
||||||
|
if ( & Curve == nullptr || &vInfo == nullptr || &vInters == nullptr)
|
||||||
|
return false ;
|
||||||
|
vInters.clear() ;
|
||||||
|
// info sulla curva
|
||||||
|
bool bClosedCrv = Curve.IsClosed() ;
|
||||||
|
double dParSCrv, dParECrv ;
|
||||||
|
Curve.GetDomain( dParSCrv, dParECrv) ;
|
||||||
|
// ciclo sulle intersezioni
|
||||||
|
for ( const auto& Info : vInfo) {
|
||||||
|
// se intersezione puntuale
|
||||||
|
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||||
|
int nFlag = CSIT_NONE ;
|
||||||
|
if ( Info.dCosDN > EPS_ZERO)
|
||||||
|
nFlag = CSIT_IN_OUT ;
|
||||||
|
else if ( Info.dCosDN < -EPS_ZERO)
|
||||||
|
nFlag = CSIT_OUT_IN ;
|
||||||
|
vInters.emplace_back( nFlag, Info.dU) ;
|
||||||
|
}
|
||||||
|
// se altrimenti intersezione con coincidenza
|
||||||
|
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||||
|
vInters.emplace_back( CSIT_IN_ON, Info.dU) ;
|
||||||
|
vInters.emplace_back( CSIT_ON_IN, Info.dU2) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// elimino intersezioni ripetute
|
||||||
|
int nStart = ( bClosedCrv ? 0 : 1) ;
|
||||||
|
for ( int j = nStart ; j < int( vInters.size()) ; ) {
|
||||||
|
// intersezione precedente
|
||||||
|
int i = ( j > 0 ? j - 1 : int( vInters.size()) - 1) ;
|
||||||
|
// se hanno lo stesso parametro
|
||||||
|
if ( abs( vInters[i].second - vInters[j].second) < EPS_PARAM ||
|
||||||
|
( bClosedCrv && abs( vInters[i].second - dParECrv) < EPS_PARAM && abs( vInters[j].second - dParSCrv) < EPS_PARAM)) {
|
||||||
|
// flag per eseguita cancellazione
|
||||||
|
bool bSomeErased = false ;
|
||||||
|
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||||
|
if ( ( vInters[i].first == CSIT_OUT_IN && vInters[j].first == CSIT_OUT_IN) ||
|
||||||
|
( vInters[i].first == CSIT_IN_OUT && vInters[j].first == CSIT_IN_OUT)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una entrante e l'altra uscente, cambio in touch da fuori ed elimino la seconda
|
||||||
|
else if ( vInters[i].first == CSIT_OUT_IN && vInters[j].first == CSIT_IN_OUT) {
|
||||||
|
vInters[i].first = CSIT_OUT_OUT ;
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una uscente e l'altra entrante, cambio in touch da dentro ed elimino la seconda
|
||||||
|
else if ( vInters[i].first == CSIT_IN_OUT && vInters[j].first == CSIT_OUT_IN) {
|
||||||
|
vInters[i].first = CSIT_IN_IN ;
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una touch da fuori o da dentro e l'altra entrante o uscente, elimino la prima
|
||||||
|
else if ( ( vInters[i].first == CSIT_OUT_OUT || vInters[i].first == CSIT_IN_IN) &&
|
||||||
|
( vInters[j].first == CSIT_OUT_IN || vInters[j].first == CSIT_IN_OUT)) {
|
||||||
|
vInters.erase( vInters.begin() + i) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una entrante o uscente e l'altra touch da fuori o da dentro, elimino la seconda
|
||||||
|
else if ( ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT) &&
|
||||||
|
( vInters[j].first == CSIT_OUT_OUT || vInters[j].first == CSIT_IN_IN)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||||
|
else if ( ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT || vInters[i].first == CSIT_NONE) &&
|
||||||
|
( vInters[j].first == CSIT_IN_ON || vInters[j].first == CSIT_OUT_ON)) {
|
||||||
|
vInters[j].first = ( vInters[i].first == CSIT_IN_OUT ? CSIT_IN_ON : CSIT_OUT_ON) ;
|
||||||
|
vInters.erase( vInters.begin() + i) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||||
|
else if ( ( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT) &&
|
||||||
|
( vInters[j].first == CSIT_OUT_IN || vInters[j].first == CSIT_IN_OUT || vInters[j].first == CSIT_NONE)) {
|
||||||
|
vInters[i].first = ( vInters[j].first == CSIT_IN_OUT ? CSIT_ON_OUT : CSIT_ON_IN) ;
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||||
|
else if ( ( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT) &&
|
||||||
|
( vInters[j].first == CSIT_IN_ON || vInters[j].first == CSIT_OUT_ON)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
vInters.erase( vInters.begin() + ( j > 0 ? i : i - 1)) ;
|
||||||
|
bSomeErased = true ;
|
||||||
|
}
|
||||||
|
if ( bSomeErased) {
|
||||||
|
if ( j > 0)
|
||||||
|
-- j ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// passo alla successiva
|
||||||
|
++ j ;
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
+1
-1
@@ -22,7 +22,7 @@ using namespace std ;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Linea e box allineato assi devono essere nel medesimo sistema di riferimento.
|
// Linea e box allineato assi devono essere nel medesimo sistema di riferimento.
|
||||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
// In caso di intersezione viene restituito true e i parametri lunghezza in dU1 e dU2.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Linea e box allineato agli assi sono nel medesimo riferimento.
|
// Linea e box allineato agli assi sono nel medesimo riferimento.
|
||||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
// Con intersezione viene restituito true e i parametri lunghezza in dU1 e dU2.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||||
|
|||||||
+70
-5
@@ -21,7 +21,7 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
static void
|
||||||
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
||||||
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
||||||
{
|
{
|
||||||
@@ -41,7 +41,7 @@ UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dL
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
static void
|
||||||
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
||||||
{
|
{
|
||||||
// se non trovati, esco
|
// se non trovati, esco
|
||||||
@@ -81,7 +81,7 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
// lo ingrandisco per non avere problemi con faccia piana su piani canonici
|
// lo ingrandisco per non avere problemi con faccia piana su piani canonici
|
||||||
b3Stm.Expand( 10 * EPS_SMALL) ;
|
b3Stm.Expand( 10 * EPS_SMALL) ;
|
||||||
double dU1, dU2 ;
|
double dU1, dU2 ;
|
||||||
if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2))
|
if ( ! IntersLineBox( ptL, vtDir, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2))
|
||||||
return true ;
|
return true ;
|
||||||
if ( bFinite) {
|
if ( bFinite) {
|
||||||
dU1 = max( dU1, 0.) ;
|
dU1 = max( dU1, 0.) ;
|
||||||
@@ -89,12 +89,12 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
if ( dU2 - dU1 < EPS_SMALL)
|
if ( dU2 - dU1 < EPS_SMALL)
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
Point3d ptStart = ptL + dU1 * vtL ;
|
Point3d ptStart = ptL + dU1 * vtDir ;
|
||||||
double dLenEff = dU2 - dU1 ;
|
double dLenEff = dU2 - dU1 ;
|
||||||
// cerco i triangoli intersecati dalla linea
|
// cerco i triangoli intersecati dalla linea
|
||||||
const double BOX_STEP = 10 ;
|
const double BOX_STEP = 10 ;
|
||||||
int nStep = int( ceil( dLenEff / BOX_STEP)) ;
|
int nStep = int( ceil( dLenEff / BOX_STEP)) ;
|
||||||
Vector3d vtStep = dLenEff / nStep * vtL ;
|
Vector3d vtStep = dLenEff / nStep * vtDir ;
|
||||||
INTVECTOR vPrevT ;
|
INTVECTOR vPrevT ;
|
||||||
for ( int i = 0 ; i < nStep ; ++ i) {
|
for ( int i = 0 ; i < nStep ; ++ i) {
|
||||||
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
|
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
|
||||||
@@ -189,3 +189,68 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||||
|
{
|
||||||
|
// ciclo sulle intersezioni
|
||||||
|
for ( const auto& Info : vInfo) {
|
||||||
|
// se intersezione puntuale
|
||||||
|
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||||
|
int nFlag = LST_TOUCH ;
|
||||||
|
if ( Info.dCosDN > EPS_ZERO)
|
||||||
|
nFlag = LST_OUT ;
|
||||||
|
else if ( Info.dCosDN < -EPS_ZERO)
|
||||||
|
nFlag = LST_IN ;
|
||||||
|
vInters.emplace_back( nFlag, Info.dU) ;
|
||||||
|
}
|
||||||
|
// se altrimenti intersezione con coincidenza
|
||||||
|
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||||
|
vInters.emplace_back( LST_TG_INI, Info.dU) ;
|
||||||
|
vInters.emplace_back( LST_TG_FIN, Info.dU2) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// elimino intersezioni ripetute
|
||||||
|
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||||
|
// intersezione precedente
|
||||||
|
size_t i = j - 1 ;
|
||||||
|
// se hanno lo stesso parametro
|
||||||
|
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||||
|
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||||
|
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
||||||
|
( vInters[i].first == LST_OUT && vInters[j].first == LST_OUT)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||||
|
else if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_OUT) ||
|
||||||
|
( vInters[i].first == LST_OUT && vInters[j].first == LST_IN)) {
|
||||||
|
vInters[i].first = LST_TOUCH ;
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||||
|
else if ( ( vInters[i].first == LST_IN || vInters[i].first == LST_OUT || vInters[i].first == LST_TOUCH) && vInters[j].first == LST_TG_INI) {
|
||||||
|
vInters.erase( vInters.begin() + i) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||||
|
else if ( vInters[i].first == LST_TG_FIN && ( vInters[j].first == LST_IN || vInters[j].first == LST_OUT || vInters[j].first == LST_TOUCH)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||||
|
else if ( i > 0 && vInters[i].first == LST_TG_FIN && vInters[j].first == LST_TG_INI) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
vInters.erase( vInters.begin() + i) ;
|
||||||
|
-- j ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// passo alla successiva
|
||||||
|
++ j ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2024-2024
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : IntersLineVolZmap.cpp Data : 22.02.24 Versione : 2.6b4
|
||||||
|
// Contenuto : Implementazione della intersezione linea/VolZmap.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 22.02.24 DS Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "VolZmap.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Intersezione di una linea con la superficie di un solido VolZmap
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersLineVolZmap( const Point3d& ptL, const Vector3d& vtL, const IVolZmap& Vzm, ILZIVECTOR& vInfo)
|
||||||
|
{
|
||||||
|
// verifico linea
|
||||||
|
Vector3d vtDir = vtL ;
|
||||||
|
if ( ! vtDir.Normalize( EPS_ZERO))
|
||||||
|
return false ;
|
||||||
|
// verifico volume
|
||||||
|
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
||||||
|
if ( pVzm == nullptr)
|
||||||
|
return false ;
|
||||||
|
// verifico parametro di ritorno
|
||||||
|
if ( &vInfo == nullptr)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// eseguo intersezione
|
||||||
|
return pVzm->GetLineIntersection( ptL, vtL, vInfo) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
FilterLineVolZmapInters( const ILZIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||||
|
{
|
||||||
|
// ciclo sulle intersezioni
|
||||||
|
for ( const auto& Info : vInfo) {
|
||||||
|
// se intersezione puntuale
|
||||||
|
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||||
|
int nFlag = LZT_TOUCH ;
|
||||||
|
if ( Info.dCosDN > EPS_ZERO)
|
||||||
|
nFlag = LZT_OUT ;
|
||||||
|
else if ( Info.dCosDN < -EPS_ZERO)
|
||||||
|
nFlag = LZT_IN ;
|
||||||
|
vInters.emplace_back( nFlag, Info.dU) ;
|
||||||
|
}
|
||||||
|
// se altrimenti intersezione con coincidenza
|
||||||
|
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||||
|
vInters.emplace_back( LZT_TG_INI, Info.dU) ;
|
||||||
|
vInters.emplace_back( LZT_TG_FIN, Info.dU2) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// elimino intersezioni ripetute
|
||||||
|
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||||
|
// intersezione precedente
|
||||||
|
size_t i = j - 1 ;
|
||||||
|
// se hanno lo stesso parametro
|
||||||
|
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||||
|
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||||
|
if ( ( vInters[i].first == LZT_IN && vInters[j].first == LZT_IN) ||
|
||||||
|
( vInters[i].first == LZT_OUT && vInters[j].first == LZT_OUT)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||||
|
else if ( ( vInters[i].first == LZT_IN && vInters[j].first == LZT_OUT) ||
|
||||||
|
( vInters[i].first == LZT_OUT && vInters[j].first == LZT_IN)) {
|
||||||
|
vInters[i].first = LZT_TOUCH ;
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||||
|
else if ( ( vInters[i].first == LZT_IN || vInters[i].first == LZT_OUT || vInters[i].first == LZT_TOUCH) && vInters[j].first == LZT_TG_INI) {
|
||||||
|
vInters.erase( vInters.begin() + i) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||||
|
else if ( vInters[i].first == LZT_TG_FIN && ( vInters[j].first == LZT_IN || vInters[j].first == LZT_OUT || vInters[j].first == LZT_TOUCH)) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||||
|
else if ( i > 0 && vInters[i].first == LZT_TG_FIN && vInters[j].first == LZT_TG_INI) {
|
||||||
|
vInters.erase( vInters.begin() + j) ;
|
||||||
|
vInters.erase( vInters.begin() + i) ;
|
||||||
|
-- j ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// passo alla successiva
|
||||||
|
++ j ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2024-2024
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : IntersPlaneVolZmap.cpp Data : 22.02.24 Versione : 2.6b4
|
||||||
|
// Contenuto : Implementazione della intersezione piano/VolZmap.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 22.02.24 DS Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "VolZmap.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersPlaneVolZmap.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Intersezione di unpiano con la superficie di un solido VolZmap
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR& vpLoop)
|
||||||
|
{
|
||||||
|
// verifico volume
|
||||||
|
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
||||||
|
if ( pVzm == nullptr)
|
||||||
|
return false ;
|
||||||
|
// verifico parametro di ritorno
|
||||||
|
if ( &vpLoop == nullptr)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// eseguo intersezione
|
||||||
|
return pVzm->GetPlaneIntersection( plPlane, vpLoop) ;
|
||||||
|
}
|
||||||
+3
-3
@@ -119,12 +119,12 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
|||||||
Point3d ptSt1, ptEn1 ;
|
Point3d ptSt1, ptEn1 ;
|
||||||
int nRes1 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria1, ptSt1, ptEn1, false) ;
|
int nRes1 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria1, ptSt1, ptEn1, false) ;
|
||||||
|
|
||||||
// limito la liena di intersezione con il secondo triangolo
|
// limito la linea di intersezione con il secondo triangolo
|
||||||
Point3d ptSt2, ptEn2 ;
|
Point3d ptSt2, ptEn2 ;
|
||||||
int nRes2 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria2, ptSt2, ptEn2, false) ;
|
int nRes2 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria2, ptSt2, ptEn2, false) ;
|
||||||
|
|
||||||
// eseguo classificazione
|
// eseguo classificazione
|
||||||
double dIntStU, dIntEnU;
|
double dIntStU, dIntEnU ;
|
||||||
int nIntType = FindTriaTriaIntersType( trTria1, trTria2, ptL, vtL,
|
int nIntType = FindTriaTriaIntersType( trTria1, trTria2, ptL, vtL,
|
||||||
( ptSt1 - ptL) * vtL, ( ptEn1 - ptL) * vtL,
|
( ptSt1 - ptL) * vtL, ( ptEn1 - ptL) * vtL,
|
||||||
( ptSt2 - ptL) * vtL, ( ptEn2 - ptL) * vtL,
|
( ptSt2 - ptL) * vtL, ( ptEn2 - ptL) * vtL,
|
||||||
@@ -234,7 +234,7 @@ int
|
|||||||
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||||
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
|
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
|
||||||
{
|
{
|
||||||
// Controllo su validit� input
|
// Controllo su validità input
|
||||||
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
|
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
|
||||||
return ITTT_NO ;
|
return ITTT_NO ;
|
||||||
// Casi
|
// Casi
|
||||||
|
|||||||
+3
-1
@@ -30,7 +30,9 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
|||||||
if ( IsNull( pCrv))
|
if ( IsNull( pCrv))
|
||||||
return false ;
|
return false ;
|
||||||
if ( IsFillet( pCrv, dDist))
|
if ( IsFillet( pCrv, dDist))
|
||||||
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
||||||
|
else
|
||||||
|
pCrvCo->SetCurveTempParam( i, 0.0) ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
+76
-55
@@ -721,15 +721,42 @@ PolyLine::AdjustForMaxSegmentLen( double dMaxLen)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static bool
|
static bool
|
||||||
PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& ptP2, double dSqTol)
|
DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const int nIndStart,
|
||||||
|
const int nIndEnd, INTVECTOR& vInd)
|
||||||
{
|
{
|
||||||
for ( const auto& ptQ : vRPT) {
|
// se indici uguali, ritorno
|
||||||
double dSqDist ;
|
if ( nIndStart == nIndEnd)
|
||||||
if ( ! DistPointLine( ptQ, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > dSqTol)
|
return true ;
|
||||||
|
|
||||||
|
// distanza massima e indice del punto associato
|
||||||
|
double dMaxSqDist = 0. ;
|
||||||
|
int nMaxInd = 0 ;
|
||||||
|
|
||||||
|
// scorro i punti intermedi tra nIndStart e nIndEnd
|
||||||
|
for ( int i = nIndStart + 1 ; i < nIndEnd ; ++ i) {
|
||||||
|
double dCurrSqDist = 0. ;
|
||||||
|
// distanza tra il punto attuale e la retta tra i punti di indici nIndStart ed nIndEnd
|
||||||
|
DistPointLine DPL( vPtU[i].first, vPtU[nIndStart].first, vPtU[nIndEnd].first) ;
|
||||||
|
if ( DPL.GetSqDist( dCurrSqDist) && dCurrSqDist > dMaxSqDist) {
|
||||||
|
// aggiorno i parametri
|
||||||
|
dMaxSqDist = dCurrSqDist ;
|
||||||
|
nMaxInd = i ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
||||||
|
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
|
||||||
|
if ( dMaxSqDist > dSqTol) {
|
||||||
|
// inserisco il punto
|
||||||
|
vInd.push_back( nMaxInd) ;
|
||||||
|
// split
|
||||||
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nIndStart, nMaxInd, vInd) ||
|
||||||
|
! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, nIndEnd, vInd))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,59 +770,53 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
|||||||
// controllo minimo valore di tolleranza
|
// controllo minimo valore di tolleranza
|
||||||
dToler = max( dToler, LIN_TOL_MIN) ;
|
dToler = max( dToler, LIN_TOL_MIN) ;
|
||||||
double dSqTol = dToler * dToler ;
|
double dSqTol = dToler * dToler ;
|
||||||
// si analizza la distanza di un punto dal segmento che unisce precedente e successivo
|
|
||||||
// punto precedente
|
// vettore contenente i punti della polyline
|
||||||
auto precP = m_lUPoints.begin() ;
|
PNTUVECTOR vPtU ; vPtU.reserve( m_lUPoints.size()) ;
|
||||||
// punto corrente
|
for ( const auto& ptCurr : m_lUPoints)
|
||||||
auto currP = next( precP) ;
|
vPtU.emplace_back( ptCurr) ;
|
||||||
// punto successivo
|
|
||||||
auto nextP = next( currP) ;
|
// vettore indici dei punti rimanenti
|
||||||
// lista dei punti appena rimossi
|
INTVECTOR vInd ; vInd.reserve( vPtU.size()) ;
|
||||||
PNTVECTOR vRPT ; vRPT.reserve( 20) ;
|
|
||||||
// mentre esiste un successivo
|
// se aperta
|
||||||
while ( nextP != m_lUPoints.end()) {
|
if ( ! IsClosed()) {
|
||||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
// considero tutti i punti della PolyLine
|
||||||
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
|
vInd.push_back( 0) ;
|
||||||
double dSqDist ;
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
||||||
// se da eliminare
|
return false ;
|
||||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
|
vInd.push_back( vPtU.size() - 1) ;
|
||||||
// aggiungo il punto nella lista dei rimossi
|
|
||||||
vRPT.emplace_back( currP->first) ;
|
|
||||||
// elimino il punto
|
|
||||||
m_lUPoints.erase( currP) ;
|
|
||||||
// avanzo con corrente e successivo
|
|
||||||
currP = nextP ;
|
|
||||||
++ nextP ;
|
|
||||||
}
|
|
||||||
// altrimenti da tenere
|
|
||||||
else {
|
|
||||||
// cancello la lista dei rimossi
|
|
||||||
vRPT.clear() ;
|
|
||||||
// avanzo il terzetto di uno step
|
|
||||||
precP = currP ;
|
|
||||||
currP = nextP ;
|
|
||||||
++ nextP ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura
|
// altrimenti chiusa
|
||||||
if ( IsClosed() && m_lUPoints.size() >= 4) {
|
else {
|
||||||
// precP e currP sono già corretti
|
// cerco il punto più distante dal primo
|
||||||
// il primo punto ripete l'ultimo (geometricamente coincide con currP)
|
double dMaxDist = 0. ;
|
||||||
auto firstP = m_lUPoints.begin() ;
|
int nMaxInd = 0 ;
|
||||||
// questo è il vero successivo
|
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
|
||||||
nextP = next( firstP) ;
|
double dCurrDist = Dist( vPtU[0].first, vPtU[i].first) ;
|
||||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
if ( dCurrDist > dMaxDist) {
|
||||||
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
|
dMaxDist = dCurrDist ;
|
||||||
double dSqDist ;
|
nMaxInd = i ;
|
||||||
// se da eliminare
|
}
|
||||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
|
|
||||||
// faccio coincidere il primo punto con il precedente
|
|
||||||
firstP->first = precP->first ;
|
|
||||||
// elimino il punto corrente
|
|
||||||
m_lUPoints.erase( currP) ;
|
|
||||||
}
|
}
|
||||||
|
// recupero due PolyLine di approssimazione
|
||||||
|
vInd.push_back( 0) ;
|
||||||
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, nMaxInd, vInd))
|
||||||
|
return false ;
|
||||||
|
vInd.push_back( nMaxInd) ;
|
||||||
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
||||||
|
return false ;
|
||||||
|
vInd.push_back( vPtU.size() - 1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ordino in senso crescente
|
||||||
|
sort( vInd.begin(), vInd.end()) ;
|
||||||
|
|
||||||
|
// rimetto in lista i soli punti rimasti
|
||||||
|
m_lUPoints.clear() ;
|
||||||
|
for ( auto Ind : vInd)
|
||||||
|
m_lUPoints.push_back( vPtU[Ind]) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-13
@@ -18,6 +18,8 @@
|
|||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static bool
|
static bool
|
||||||
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
||||||
@@ -32,14 +34,17 @@ PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext,
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vector3d& vtDir, double dLinTol,
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vector3d& vtDir, double dLinTol, double dMaxSegmLen,
|
||||||
PNT5AXVECTOR& vPt5ax)
|
PNT5AXVECTOR& vPt5ax)
|
||||||
{
|
{
|
||||||
|
// controllo le tolleranze
|
||||||
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||||
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||||
PolyLine PL ;
|
PolyLine PL ;
|
||||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||||
return false ;
|
return false ;
|
||||||
const double MAX_SEG_LEN = 1 ;
|
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -85,23 +90,29 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec
|
|||||||
bFound = PL.GetNextUPoint( &dU, &ptP) ;
|
bFound = PL.GetNextUPoint( &dU, &ptP) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rimuovo i punti allineati entro la tolleranza
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||||
|
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
||||||
double dSqTol = dLinTol * dLinTol ;
|
double dSqTol = dLinTol * dLinTol ;
|
||||||
int nPrec = 0 ;
|
int nPrec = 0 ;
|
||||||
int nCurr = 1 ;
|
int nCurr = 1 ;
|
||||||
int nNext = 2 ;
|
int nNext = 2 ;
|
||||||
while ( nNext < int( vMyPt5ax.size())) {
|
while ( nNext < int( vMyPt5ax.size())) {
|
||||||
bool bRemove = false ;
|
bool bRemove = false ;
|
||||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
// lunghezza del segmento che unisce gli adiacenti
|
||||||
DistPointLine dPL( vMyPt5ax[nCurr].ptP, vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
double dSqLen = SqDist( vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
||||||
double dSqDist ;
|
// se lunghezza inferiore al massimo, passo agli altri controlli
|
||||||
// se distanza inferiore a tolleranza lineare
|
if ( dSqLen <= dSqMaxLen) {
|
||||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vMyPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||||
// verifico se errore angolare inferiore a limite
|
DistPointLine dPL( vMyPt5ax[nCurr].ptP, vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
||||||
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
double dSqDist ;
|
||||||
Vector3d vtNew = Media( vMyPt5ax[nPrec].vtDir, vMyPt5ax[nNext].vtDir, dPar) ;
|
// se distanza inferiore a tolleranza lineare
|
||||||
if ( vtNew.Normalize() && vtNew * vMyPt5ax[nCurr].vtDir > cos( 2 * DEGTORAD))
|
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vMyPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
||||||
bRemove = true ;
|
// verifico se errore angolare inferiore a limite
|
||||||
|
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
||||||
|
Vector3d vtNew = Media( vMyPt5ax[nPrec].vtDir, vMyPt5ax[nNext].vtDir, dPar) ;
|
||||||
|
if ( vtNew.Normalize() && vtNew * vMyPt5ax[nCurr].vtDir > cos( 2 * DEGTORAD))
|
||||||
|
bRemove = true ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// se da eliminare
|
// se da eliminare
|
||||||
if ( bRemove) {
|
if ( bRemove) {
|
||||||
|
|||||||
@@ -0,0 +1,265 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2015-2024
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : RotationMinimizeFrame.cpp Data : 05.03.24 Versione : 2.6c1
|
||||||
|
// Contenuto : Classe per RotationMinimizeFrame
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 05.03.24 RE Creazione modulo.
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "RotationMinimizeFrame.h"
|
||||||
|
#include "GeoConst.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
RotationMinimizeFrame::RotationMinimizeFrame( const ICurve* pCrv, const Frame3d& fr_Start)
|
||||||
|
{
|
||||||
|
// assegno i parametri
|
||||||
|
m_pCrv = pCrv->Clone() ;
|
||||||
|
m_Frame0 = fr_Start ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
RotationMinimizeFrame::~RotationMinimizeFrame( void)
|
||||||
|
{
|
||||||
|
Clear() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
RotationMinimizeFrame::Clear( void)
|
||||||
|
{
|
||||||
|
// pulizia della curva
|
||||||
|
if ( m_pCrv != nullptr)
|
||||||
|
delete m_pCrv ;
|
||||||
|
m_pCrv = nullptr ;
|
||||||
|
|
||||||
|
// reset del frame di partenza
|
||||||
|
m_Frame0.Reset() ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
RotationMinimizeFrame::IsValid()
|
||||||
|
{
|
||||||
|
// controllo validità della curva
|
||||||
|
if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// controllo del frame iniziale
|
||||||
|
if ( ! m_Frame0.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// controllo che l'origine del frame sia sulla curva e che l'asse Z sia tangente alla curva
|
||||||
|
Point3d ptS ;
|
||||||
|
Vector3d vtZ ;
|
||||||
|
if ( ! m_pCrv->GetPointD1D2( 0., ICurve::FROM_MINUS, ptS, &vtZ) ||
|
||||||
|
! vtZ.Normalize() ||
|
||||||
|
! AreSamePointApprox( ptS, m_Frame0.Orig()) ||
|
||||||
|
! AreSameVectorEpsilon( vtZ, m_Frame0.VersZ(), 5 * EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
RotationMinimizeFrame::GetFrameAtLength( const Frame3d& frAct, const double dLenNext, Frame3d& frNext)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Double Reflection
|
||||||
|
Computation of Rotation Minimizing Frame in Computer Graphics
|
||||||
|
Wenping Wang Bert Juttler Dayue Zheng Yang Liu
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ricavo i parametri dal frame
|
||||||
|
if ( ! frAct.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// origine del frame e versori ( ptAct, [ vt_r, vt_s, vt_t])
|
||||||
|
Point3d ptCurr = frAct.Orig() ;
|
||||||
|
Vector3d vt_r = frAct.VersX() ;
|
||||||
|
Vector3d vt_t = frAct.VersZ() ;
|
||||||
|
// ( vt_s è implicito )
|
||||||
|
|
||||||
|
double dUNext ; // parametro sulla curva nello step successivo
|
||||||
|
Point3d ptNext ; // punto sulla curva allo step successivo
|
||||||
|
|
||||||
|
// parametro (i+1)-esimo sulla curva
|
||||||
|
if ( ! m_pCrv->GetParamAtLength( dLenNext, dUNext))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// punto (i+1)-esimo sulla curva e suo vettore tangente
|
||||||
|
Vector3d vt_t_next ;
|
||||||
|
if ( ! m_pCrv->GetPointD1D2( dUNext, ICurve::FROM_MINUS, ptNext, &vt_t_next) ||
|
||||||
|
! vt_t_next.IsValid() || ! vt_t_next.Normalize()) // versore tangente
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// controllo per casi degeneri
|
||||||
|
if ( AreSamePointEpsilon( ptCurr, ptNext, EPS_ZERO) || // non esiste il piano R1
|
||||||
|
abs(( ptNext - ptCurr) * ( vt_t_next + vt_t)) < EPS_ZERO) // non esiste il piano R2
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// ricavo il vettore di riflessione rispetto al piano R1
|
||||||
|
Vector3d vR1_norm = ptNext - ptCurr ;
|
||||||
|
if ( ! vR1_norm.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// parametro di riflessione per R1
|
||||||
|
double dPar1 = vR1_norm * vR1_norm ;
|
||||||
|
|
||||||
|
// riflessione rispetto al piano R1 ( sistema sinistrorso L )
|
||||||
|
Vector3d vt_r_L = vt_r - ( 2 / dPar1) * ( vR1_norm * vt_r) * vR1_norm ;
|
||||||
|
Vector3d vt_t_L = vt_t - ( 2 / dPar1) * ( vR1_norm * vt_t) * vR1_norm ;
|
||||||
|
|
||||||
|
// ricavo il vettore di riflessione rispetto al piano R1
|
||||||
|
Vector3d vR2_norm = vt_t_next - vt_t_L ;
|
||||||
|
if ( ! vR2_norm.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// parametro di riflessione per R2
|
||||||
|
double dPar2 = vR2_norm * vR2_norm ;
|
||||||
|
// versore r del nuovo frame
|
||||||
|
Vector3d vt_r_next = vt_r_L - ( 2 / dPar2) * ( vR2_norm * vt_r_L) * vR2_norm ;
|
||||||
|
// versore t del nuovo frame
|
||||||
|
Vector3d vt_s_next = vt_t_next ^ vt_r_next ;
|
||||||
|
|
||||||
|
// imposto il nuovo frame
|
||||||
|
frNext.Set( ptNext, vt_r_next, vt_s_next, vt_t_next) ;
|
||||||
|
if ( ! frNext.IsValid()) { // il frame potrebbe non essere nelle tolleranze...
|
||||||
|
// ... sistemo ricavando il versore "s" mediante "t" ed "r" ...
|
||||||
|
frNext.Set( ptNext, vt_t_next, vt_r_next) ;
|
||||||
|
if ( ! frNext.IsValid())
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
RotationMinimizeFrame::GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep, bool bUniform)
|
||||||
|
{
|
||||||
|
// controllo sullo step
|
||||||
|
dStep = max( 10 * EPS_SMALL, dStep) ;
|
||||||
|
|
||||||
|
// controllo validità
|
||||||
|
if ( ! IsValid()) {
|
||||||
|
Clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calcolo lunghezza della curva
|
||||||
|
double dLen = 0. ;
|
||||||
|
if ( ! m_pCrv->GetLength( dLen))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// in prima posizione viene inserito il frame iniziale
|
||||||
|
vRMFrames.push_back( m_Frame0) ;
|
||||||
|
|
||||||
|
// ricavo il numero degli step
|
||||||
|
int nStep = int( ceil( dLen / dStep)) ;
|
||||||
|
if ( nStep == 0) // se non ho step allora serve sono il frame iniziale
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
// lunghezza della curva identificata dal punto successivo
|
||||||
|
double dLenNext ;
|
||||||
|
|
||||||
|
// step corrente
|
||||||
|
double dMyStep = dStep ;
|
||||||
|
if ( bUniform)
|
||||||
|
dMyStep = dLen / nStep ;
|
||||||
|
|
||||||
|
// ciclo sugli step in cui la curva è suddivisa
|
||||||
|
for ( int i = 0 ; i < nStep ; ++ i) {
|
||||||
|
// ricavo la lunghezza della curva relativo allo step (i+1)-esimo
|
||||||
|
dLenNext = min( dLen - 10 * EPS_SMALL, ( i + 1) * dMyStep) ;
|
||||||
|
// ricavo il frame alla lunghezza calcolata
|
||||||
|
Frame3d frNext ;
|
||||||
|
if ( ! GetFrameAtLength( vRMFrames[i], dLenNext, frNext))
|
||||||
|
return false ;
|
||||||
|
// aggiornamento vettore dei frame
|
||||||
|
vRMFrames.push_back( frNext) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
RotationMinimizeFrame::GetFramesBySplit( FRAME3DVECTOR& vRMFrames, int nIntervals)
|
||||||
|
{
|
||||||
|
// controllo sul numero di intervalli
|
||||||
|
nIntervals = max( 1, nIntervals) ;
|
||||||
|
|
||||||
|
// ricavo lo step associato
|
||||||
|
double dLen = 0 ;
|
||||||
|
if ( ! m_pCrv->GetLength( dLen))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// ricavo lo step associato
|
||||||
|
double dStep = dLen / nIntervals ;
|
||||||
|
|
||||||
|
return GetFramesByStep( vRMFrames, dStep) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
RotationMinimizeFrame::GetFramesByTollerance( FRAME3DVECTOR& vRMFrames, double dTol)
|
||||||
|
{
|
||||||
|
// controllo sulla tolleranza
|
||||||
|
dTol = max( EPS_SMALL, dTol) ;
|
||||||
|
|
||||||
|
// controllo validità
|
||||||
|
if ( ! IsValid()) {
|
||||||
|
Clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ricavo la PolyLine associata alla curva mediante tale tolleranza
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// ricavo la lunghezza della curva
|
||||||
|
double dCrvLen = 0 ;
|
||||||
|
if ( ! m_pCrv->GetLength( dCrvLen))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// devo calcolare il RMF su ogni punto ricavato dall'approssimazione
|
||||||
|
Point3d ptCurr ;
|
||||||
|
bool bPoint = PL.GetFirstPoint( ptCurr) ;
|
||||||
|
bool bFirst = true ;
|
||||||
|
while ( bPoint) {
|
||||||
|
if ( bFirst) {
|
||||||
|
// in prima posizione viene inserito il frame iniziale
|
||||||
|
vRMFrames.push_back( m_Frame0) ;
|
||||||
|
bFirst = false ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// ricavo la lunghezza della curva al punto corrente
|
||||||
|
double dLen = 0. ;
|
||||||
|
if ( ! m_pCrv->GetLengthAtPoint( ptCurr, dLen))
|
||||||
|
return false ;
|
||||||
|
// per sicurezza controllo che sia minore della lunghezza complessiva
|
||||||
|
dLen = min( dCrvLen - 10 * EPS_SMALL , dLen) ;
|
||||||
|
// ricavo il Frame associato a tale lunghezza
|
||||||
|
Frame3d frNext ;
|
||||||
|
if ( ! GetFrameAtLength( vRMFrames.back(), dLen, frNext))
|
||||||
|
return false ;
|
||||||
|
vRMFrames.emplace_back( frNext) ;
|
||||||
|
}
|
||||||
|
// passo al punto successivo
|
||||||
|
bPoint = PL.GetNextPoint( ptCurr) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2015-2024
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : RotationMinimizeFrame.h Data : 05.03.24 Versione : 2.6c1
|
||||||
|
// Contenuto : Dichiarazione della classe RotationMinimizeFrame
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 05.03.24 RE Creazione modulo.
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkCurve.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
typedef std::vector<Frame3d> FRAME3DVECTOR ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class RotationMinimizeFrame
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
RotationMinimizeFrame( const ICurve* pCrv, const Frame3d& fr_Start) ;
|
||||||
|
~RotationMinimizeFrame( void) ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
bool GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep, bool bUniform = false) ;
|
||||||
|
bool GetFramesBySplit( FRAME3DVECTOR& vRMFrames, int nIntervals) ;
|
||||||
|
bool GetFramesByTollerance( FRAME3DVECTOR& vRMFrames, double dTol) ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
bool Clear( void) ;
|
||||||
|
bool IsValid( void) ;
|
||||||
|
bool GetFrameAtLength( const Frame3d& frAct, const double dLenNext, Frame3d& frNext) ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
ICurve* m_pCrv ; // curva per il calcolo del rotation minimize frame
|
||||||
|
Frame3d m_Frame0 ; // frame iniziale della curva
|
||||||
|
} ;
|
||||||
|
|
||||||
+581
-95
@@ -1,4 +1,4 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2015-2015
|
// EgalTech 2015-2015
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : StmFromCurves.cpp Data : 01.02.15 Versione : 1.6b1
|
// File : StmFromCurves.cpp Data : 01.02.15 Versione : 1.6b1
|
||||||
@@ -19,13 +19,16 @@
|
|||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
#include "SurfTriMesh.h"
|
#include "SurfTriMesh.h"
|
||||||
#include "Voronoi.h"
|
#include "Voronoi.h"
|
||||||
|
#include "RotationMinimizeFrame.h"
|
||||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||||
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <EgtDev/Include/EGkIntersCurves.h>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -109,9 +112,9 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
|||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
|
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// se da fare, metto i tappi sulle estremità
|
// se da fare, metto i tappi sulle estremità
|
||||||
if ( bDoCapEnds) {
|
if ( bDoCapEnds) {
|
||||||
// creo la prima superficie di estremità
|
// creo la prima superficie di estremità
|
||||||
SurfTriMesh STM1 ;
|
SurfTriMesh STM1 ;
|
||||||
if ( ! STM1.CreateByFlatContour( PL))
|
if ( ! STM1.CreateByFlatContour( PL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -155,7 +158,7 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
|
|||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
|
||||||
vPL[i].Invert() ;
|
vPL[i].Invert() ;
|
||||||
}
|
}
|
||||||
// creo la prima superficie di estremità
|
// creo la prima superficie di estremità
|
||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -287,7 +290,7 @@ GetSurfTriMeshByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vecto
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
// se richiesti caps
|
// se richiesti caps
|
||||||
if ( bCapEnds) {
|
if ( bCapEnds) {
|
||||||
// determino se la sezione è chiusa e piatta
|
// determino se la sezione è chiusa e piatta
|
||||||
Plane3d plPlane ; double dArea ;
|
Plane3d plPlane ; double dArea ;
|
||||||
bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
|
bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
|
||||||
// determino non sia una semplice rivoluzione
|
// determino non sia una semplice rivoluzione
|
||||||
@@ -331,7 +334,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
|||||||
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
Vector3d vtNorm = plGuide.GetVersN() ;
|
Vector3d vtNorm = plGuide.GetVersN() ;
|
||||||
// determino se la guida è chiusa
|
// determino se la guida è chiusa
|
||||||
bool bGuideClosed = pGuide->IsClosed() ;
|
bool bGuideClosed = pGuide->IsClosed() ;
|
||||||
// curve di offset
|
// curve di offset
|
||||||
OffsetCurve OffsCrvR ;
|
OffsetCurve OffsCrvR ;
|
||||||
@@ -372,7 +375,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
|||||||
pSTM->SetSmoothAngle( 20) ;
|
pSTM->SetSmoothAngle( 20) ;
|
||||||
// se guida aperta e tappi piatti
|
// se guida aperta e tappi piatti
|
||||||
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
||||||
// verifico che le due estremità siano chiuse e piatte
|
// verifico che le due estremità siano chiuse e piatte
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -451,7 +454,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
Point3d ptCen ;
|
Point3d ptCen ;
|
||||||
pGuide->GetStartPoint( ptCen) ;
|
pGuide->GetStartPoint( ptCen) ;
|
||||||
ptCen -= dDimV / 2 * vtNorm ;
|
ptCen -= dDimV / 2 * vtNorm ;
|
||||||
// determino se la guida è chiusa
|
// determino se la guida è chiusa
|
||||||
bool bGuideClosed = pGuide->IsClosed() ;
|
bool bGuideClosed = pGuide->IsClosed() ;
|
||||||
// curve di offset
|
// curve di offset
|
||||||
const int NUM_OFFS = 4 ;
|
const int NUM_OFFS = 4 ;
|
||||||
@@ -474,7 +477,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
|
// se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
|
||||||
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
||||||
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
||||||
}
|
}
|
||||||
@@ -551,7 +554,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
StmFromTriangleSoup stmCapSoup ;
|
StmFromTriangleSoup stmCapSoup ;
|
||||||
if ( ! stmCapSoup.Start( nBuckets))
|
if ( ! stmCapSoup.Start( nBuckets))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// verifico che le due estremità siano chiuse e piatte
|
// verifico che le due estremità siano chiuse e piatte
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -650,34 +653,450 @@ GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBev
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfTriMesh*
|
ISurfTriMesh*
|
||||||
GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol)
|
GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol, Vector3d* vtStatic)
|
||||||
{
|
{
|
||||||
// verifica parametri
|
// verifica parametri
|
||||||
if ( pSect == nullptr || pGuide == nullptr)
|
if ( pSect == nullptr || pGuide == nullptr)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// calcolo la polilinea che approssima la sezione
|
// calcolo la polilinea che approssima la sezione
|
||||||
PolyLine PL ;
|
PolyLine PL ;
|
||||||
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// determino se la sezione è chiusa
|
|
||||||
|
// determino se la sezione è chiusa
|
||||||
bool bSectClosed = PL.IsClosed() ;
|
bool bSectClosed = PL.IsClosed() ;
|
||||||
|
// determino se la guida è chiusa
|
||||||
|
bool bGuideClosed = pGuide->IsClosed() ;
|
||||||
|
|
||||||
|
// definisco la superficie da restituire ( definendo la sua tolleranza )
|
||||||
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSTM))
|
||||||
|
return nullptr ;
|
||||||
|
pSTM->SetLinearTolerance( dLinTol) ;
|
||||||
|
|
||||||
|
// calcolo punto e versore tangente iniziale
|
||||||
|
Point3d ptStart ; pGuide->GetStartPoint( ptStart) ;
|
||||||
|
Vector3d vtStart ; pGuide->GetStartDir( vtStart) ;
|
||||||
|
// inizializzazione del frame iniziale ( viene definito a seconda dei casi )
|
||||||
|
Frame3d frStart ;
|
||||||
|
|
||||||
|
/* GUIDA PIANA */
|
||||||
|
|
||||||
// verifico che la linea guida sia piana
|
// verifico che la linea guida sia piana
|
||||||
Plane3d plGuide ;
|
Plane3d plGuide ;
|
||||||
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL)) {
|
||||||
return nullptr ;
|
|
||||||
// determino se la guida è chiusa
|
/*
|
||||||
bool bGuideClosed = pGuide->IsClosed() ;
|
La guida non è piana, l'estrusione può essere definita mediante :
|
||||||
// riferimento all'inizio della linea guida
|
( 1) un versore statico
|
||||||
Frame3d frStart ;
|
( 2) mediante l'algoritmo del Rotation Minimize Frame
|
||||||
Point3d ptStart ;
|
*/
|
||||||
pGuide->GetStartPoint( ptStart) ;
|
|
||||||
Vector3d vtStart ;
|
// recupero la sezione dalla PolyLine approssimata come Curva
|
||||||
pGuide->GetStartDir( vtStart) ;
|
PtrOwner<CurveComposite> pSecLocApprox( CreateBasicCurveComposite()) ;
|
||||||
|
if ( IsNull( pSecLocApprox) ||
|
||||||
|
! pSecLocApprox->FromPolyLine( PL) ||
|
||||||
|
! pSecLocApprox->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// recupero il frame iniziale sulla guida ( Origine sul punto iniziale e asse Z tangente )
|
||||||
|
frStart.Set( ptStart, vtStart) ;
|
||||||
|
if ( ! frStart.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// tengo in memoria il frame nel punto iniziale e finale della guida in caso di caps
|
||||||
|
Frame3d frCaps_start ;
|
||||||
|
Frame3d frCaps_end ;
|
||||||
|
|
||||||
|
if ( vtStatic != nullptr) { // (1) versore statico
|
||||||
|
|
||||||
|
// creo il piano di proiezione con normale definita dal vettore
|
||||||
|
Plane3d plProj ;
|
||||||
|
plProj.Set( ORIG, *vtStatic) ;
|
||||||
|
if ( ! plProj.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// porto la sezione nel frame definito dalla guida, tenendo il versore X del frame nel piano
|
||||||
|
// definito da vtStatic
|
||||||
|
Vector3d vtX = vtStart ; // versore tangente alla curva
|
||||||
|
vtX.Rotate( *vtStatic, 90) ; // ruoto di 90 gradi rispetto a vtStatic
|
||||||
|
OrthoCompo( vtX, *vtStatic) ; // tengo la componente nel piano
|
||||||
|
vtX.Normalize() ; // normalizzo
|
||||||
|
Frame3d frInitial ; frInitial.Set( ptStart, vtStart, vtX) ; // creo il frame
|
||||||
|
if ( ! frInitial.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// porto la sezione nel riferimento
|
||||||
|
pSecLocApprox->ToLoc( frInitial) ;
|
||||||
|
PL.ToLoc( frInitial) ; //... porto anche la PolyLine del bordo della sezione
|
||||||
|
|
||||||
|
// approssimo la guida mediante la tolleranza richiesta
|
||||||
|
PolyLine PL_G ;
|
||||||
|
if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL_G))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// punto attuale e punto successivo sulla guida su cui definire il frame
|
||||||
|
Point3d ptCurr, ptSucc ;
|
||||||
|
if ( ! PL_G.GetFirstPoint( ptCurr))
|
||||||
|
return nullptr ;
|
||||||
|
bool bNextPoint = PL_G.GetNextPoint( ptSucc) ;
|
||||||
|
if ( ! bNextPoint)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// parametro attuale e successivo riferito ai punti sulla guida
|
||||||
|
double dParCurr = 0 ;
|
||||||
|
double dParSucc ;
|
||||||
|
|
||||||
|
// versore attuale e successivo riferito ai punti sulla guida
|
||||||
|
Vector3d vtTanCurr, vtTanSucc ;
|
||||||
|
if ( ! pGuide->GetStartDir( vtTanCurr))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// frame iniziale e successivo riferito alla curva
|
||||||
|
Frame3d frCurr, frSucc ;
|
||||||
|
|
||||||
|
bool bFirstIter = true ; // per salvare il frame iniziale nel caso di caps
|
||||||
|
while ( bNextPoint) { // finchè recupero un punto sucessivo...
|
||||||
|
|
||||||
|
// recupero il parametro successivo riferito alla guida
|
||||||
|
if ( ! pGuide->GetParamAtPoint( ptSucc, dParSucc))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// recupero il versore tangente riferito al punto successivo sulla guida
|
||||||
|
if ( ! pGuide->GetPointD1D2( dParSucc, ICurve::FROM_MINUS, ptSucc, &vtTanSucc) ||
|
||||||
|
! vtTanSucc.Normalize())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// creazione del frame nel punto corrente
|
||||||
|
Vector3d vtX_curr = vtTanCurr ;
|
||||||
|
vtX_curr.Rotate( *vtStatic, 90) ;
|
||||||
|
OrthoCompo( vtX_curr, *vtStatic) ;
|
||||||
|
vtX_curr.Normalize() ;
|
||||||
|
frCurr.Set( ptCurr, vtTanCurr, vtX_curr) ;
|
||||||
|
if ( ! frCurr.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// memorizzo il primo frame di caso di caps
|
||||||
|
if ( bFirstIter) {
|
||||||
|
frCaps_start = frCurr ;
|
||||||
|
bFirstIter = false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// creazione del frame nel punto successivo
|
||||||
|
Vector3d vtX_succ = vtTanSucc ;
|
||||||
|
vtX_succ.Rotate( *vtStatic, 90) ;
|
||||||
|
OrthoCompo( vtX_curr, *vtStatic) ;
|
||||||
|
vtX_succ.Normalize() ;
|
||||||
|
frSucc.Set( ptSucc, vtTanSucc, vtX_succ) ;
|
||||||
|
if ( ! frSucc.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
|
||||||
|
frCaps_end = frSucc ; // aggiorno il frame finale ad ogni step
|
||||||
|
|
||||||
|
// definisco la sezione allo step corrente
|
||||||
|
PtrOwner<ICurve> pSecCurr( pSecLocApprox->Clone()) ;
|
||||||
|
if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// considero la sezione ( in locale ) come vista dal globale
|
||||||
|
if ( ! pSecCurr->ToGlob( frCurr))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// definisco la sezione allo step successivo
|
||||||
|
PtrOwner<ICurve> pSecSucc( pSecLocApprox->Clone()) ;
|
||||||
|
if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// considero la sezione ( in locale ) come vista dal globale
|
||||||
|
if ( ! pSecSucc->ToGlob( frSucc))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// creo la rigata tra queste due sezioni
|
||||||
|
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
||||||
|
if ( IsNull( pSr) || ! pSr->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// attacco la rigata alla superficie da restituire
|
||||||
|
pSTM->DoSewing( *pSr) ;
|
||||||
|
|
||||||
|
// aggiornamento dei parametri
|
||||||
|
ptCurr = ptSucc ; // il punto corrente diventa il successivo
|
||||||
|
bNextPoint = PL_G.GetNextPoint( ptSucc) ; // il successivo lo recupero dalla PolyLine
|
||||||
|
vtTanCurr = vtTanSucc ; // il versore tangete corrente diventa il successivo
|
||||||
|
}
|
||||||
|
// la superficie definita dal RMF è invertita, il versore Z è diretto come la tangente della curva
|
||||||
|
pSTM->Invert() ;
|
||||||
|
|
||||||
|
}
|
||||||
|
else { // (2) Rotation Minimize Frame
|
||||||
|
|
||||||
|
// porto la PolyLine e la curva della sezione nel riferimento nel punto iniziale della guida
|
||||||
|
pSecLocApprox->ToLoc( frStart) ;
|
||||||
|
PL.ToLoc( frStart) ;
|
||||||
|
|
||||||
|
// calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
|
||||||
|
RotationMinimizeFrame RMF( pGuide, frStart) ;
|
||||||
|
FRAME3DVECTOR vRMF ;
|
||||||
|
if ( ! RMF.GetFramesByTollerance( vRMF, dLinTol) || vRMF.empty())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// per ogni RMF calcolato, la sezione va roto-traslata lungo la guida
|
||||||
|
for ( int i = 0 ; i < int( vRMF.size()) - 1 ; ++ i) {
|
||||||
|
|
||||||
|
// definisco la sezione allo step corrente
|
||||||
|
PtrOwner<ICurve> pSecCurr( pSecLocApprox->Clone()) ;
|
||||||
|
if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// considero la sezione ( in locale ) come vista dal globale
|
||||||
|
if ( ! pSecCurr->ToGlob( vRMF[i]))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// definisco la sezione allo step successivo
|
||||||
|
PtrOwner<ICurve> pSecSucc( pSecLocApprox->Clone()) ;
|
||||||
|
if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// considero la sezione ( in locale ) come vista dal globale
|
||||||
|
if ( ! pSecSucc->ToGlob( vRMF[i+1]))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// creo la rigata tra queste due sezioni
|
||||||
|
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
||||||
|
if ( IsNull( pSr) || ! pSr->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// attacco la rigata alla superficie da restituire
|
||||||
|
pSTM->DoSewing( *pSr) ;
|
||||||
|
}
|
||||||
|
// la superficie definita dal RMF è invertita, il versore Z è diretto come la tangente della curva
|
||||||
|
pSTM->Invert() ;
|
||||||
|
|
||||||
|
// assegno frame iniziale e finale per caps
|
||||||
|
frCaps_start = vRMF[0] ;
|
||||||
|
frCaps_end = vRMF.back() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se richiesti caps e sezione chiusa e guida aperta
|
||||||
|
// (1) vtStatic, (2) Rotation Minimize Frame
|
||||||
|
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
||||||
|
|
||||||
|
// aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
|
||||||
|
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
||||||
|
return nullptr ;
|
||||||
|
pSci->ToGlob( frCaps_start) ;
|
||||||
|
// unisco
|
||||||
|
pSTM->DoSewing( *pSci) ;
|
||||||
|
|
||||||
|
// aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
|
||||||
|
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
||||||
|
return nullptr ;
|
||||||
|
pSce->ToGlob( frCaps_end) ;
|
||||||
|
|
||||||
|
pSce->Invert() ; // il versore z è definito dalle tangenti alla curva
|
||||||
|
|
||||||
|
// unisco
|
||||||
|
pSTM->DoSewing( *pSce) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||||
|
double dVol ;
|
||||||
|
if ( pSTM->GetVolume( dVol) && dVol < 0)
|
||||||
|
pSTM->Invert() ;
|
||||||
|
|
||||||
|
// restituisco la superficie
|
||||||
|
return Release( pSTM) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GUIDA PIANA
|
||||||
|
La guida è piana, l'estrusione viene definita mediante Offset della guida sulla sezione
|
||||||
|
*/
|
||||||
|
|
||||||
|
// il frame iniziale è definito dal versore tangente e dalla normale al piano
|
||||||
|
// che contiene la guida
|
||||||
Vector3d vtNorm = plGuide.GetVersN() ;
|
Vector3d vtNorm = plGuide.GetVersN() ;
|
||||||
frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
||||||
|
|
||||||
// porto la sezione in questo riferimento e ve la appiattisco
|
// porto la sezione in questo riferimento e ve la appiattisco
|
||||||
if ( ! PL.ToLoc( frStart) || ! PL.Flatten())
|
if ( ! PL.ToLoc( frStart) || ! PL.Flatten())
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
|
// superficie swept
|
||||||
|
PtrOwner<ICurve> pPrevCrv ;
|
||||||
|
Point3d ptP ;
|
||||||
|
bool bPoint = PL.GetFirstPoint( ptP) ;
|
||||||
|
while ( bPoint) {
|
||||||
|
// nuova curva ( definita dall'Offset )
|
||||||
|
OffsetCurve OffsCrv ;
|
||||||
|
if ( ! OffsCrv.Make( pGuide, ptP.x, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0)
|
||||||
|
return nullptr ;
|
||||||
|
PtrOwner<ICurve> pCurrCrv( OffsCrv.GetLongerCurve()) ;
|
||||||
|
if ( IsNull( pCurrCrv))
|
||||||
|
return nullptr ;
|
||||||
|
pCurrCrv->Translate( ptP.y * frStart.VersY()) ;
|
||||||
|
|
||||||
|
// se esiste la curva precedente, costruisco la rigata ( di tipo minima distanza)
|
||||||
|
if ( ! IsNull( pPrevCrv)) {
|
||||||
|
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
||||||
|
if ( IsNull( pSr))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// unisco
|
||||||
|
pSTM->DoSewing( *pSr) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// salvo la curva come prossima precedente
|
||||||
|
pPrevCrv.Set( pCurrCrv) ;
|
||||||
|
|
||||||
|
// prossimo punto
|
||||||
|
bPoint = PL.GetNextPoint( ptP) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se richiesti caps e sezione chiusa e guida aperta
|
||||||
|
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
||||||
|
|
||||||
|
// 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, 100 * EPS_SMALL))
|
||||||
|
return nullptr ;
|
||||||
|
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// aggiungo il cap sull'inizio
|
||||||
|
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
||||||
|
return nullptr ;
|
||||||
|
pSci->ToGlob( frStart) ;
|
||||||
|
|
||||||
|
// unisco
|
||||||
|
pSTM->DoSewing( *pSci) ;
|
||||||
|
|
||||||
|
// riferimento alla fine della linea guida
|
||||||
|
Frame3d frEnd ;
|
||||||
|
Point3d ptEnd ;
|
||||||
|
pGuide->GetEndPoint( ptEnd) ;
|
||||||
|
Vector3d vtEnd ;
|
||||||
|
pGuide->GetEndDir( vtEnd) ;
|
||||||
|
frEnd.Set( ptEnd, -vtEnd, vtEnd ^ vtNorm) ;
|
||||||
|
|
||||||
|
// aggiungo il cap sulla fine
|
||||||
|
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
||||||
|
return nullptr ;
|
||||||
|
pSce->Invert() ;
|
||||||
|
pSce->ToGlob( frEnd) ;
|
||||||
|
|
||||||
|
// unisco
|
||||||
|
pSTM->DoSewing( *pSce) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||||
|
double dVol ;
|
||||||
|
if ( pSTM->GetVolume( dVol) && dVol < 0)
|
||||||
|
pSTM->Invert() ;
|
||||||
|
|
||||||
|
// restituisco la superficie
|
||||||
|
return Release( pSTM) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, bool bCapEnds,
|
||||||
|
double dLinTol, Vector3d* vtStatic)
|
||||||
|
{
|
||||||
|
// verifica dei parametri
|
||||||
|
if ( pSfrSect == nullptr || pGuide == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// creo la Trimesh da restituire
|
||||||
|
PtrOwner<ISurfTriMesh> pStmSwept( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pStmSwept) || ! pStmSwept->AdjustTopology())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
StmFromTriangleSoup StmSoup ;
|
||||||
|
StmSoup.Start() ;
|
||||||
|
// per ogni loop della superficie, creo una Swept
|
||||||
|
for ( int c = 0 ; c < pSfrSect->GetChunkCount() ; ++ c) {
|
||||||
|
for ( int l = 0 ; l < pSfrSect->GetLoopCount( c) ; ++ l) {
|
||||||
|
// recupero il loop
|
||||||
|
PtrOwner<ICurve> pCrvLoop( pSfrSect->GetLoop( c, l)) ;
|
||||||
|
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
// creo la Trimesh Swept
|
||||||
|
PtrOwner<ISurfTriMesh> pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, false, dLinTol, vtStatic)) ;
|
||||||
|
if ( IsNull( pStmLoopSwept) || ! pStmLoopSwept->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
// aggiungo la Swept ricavata al risultato finale ( come triangoli )
|
||||||
|
StmSoup.AddSurfTriMesh( *pStmLoopSwept) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StmSoup.End() ;
|
||||||
|
if ( ! pStmSwept.Set( StmSoup.GetSurf()) || IsNull( pStmSwept) ||
|
||||||
|
! pStmSwept->IsValid() || ! pStmSwept->AdjustTopology())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
|
||||||
|
// se rischista chiusura...
|
||||||
|
// NB. Controllo solo che al guida non sia chiusa, la sezione derivando da una Flatregion è chiusa per
|
||||||
|
// definizione
|
||||||
|
if ( bCapEnds && ! pGuide->IsClosed()) {
|
||||||
|
// creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta )
|
||||||
|
PtrOwner<ISurfTriMesh> pSci( pSfrSect->GetAuxSurf()->Clone()) ;
|
||||||
|
if ( IsNull( pSci) || ! pSci->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
pStmSwept->DoSewing( *pSci) ;
|
||||||
|
// recupero i loops alla fine
|
||||||
|
POLYLINEVECTOR vPL ;
|
||||||
|
if ( ! pStmSwept->GetLoops( vPL))
|
||||||
|
return nullptr ;
|
||||||
|
// creo la superficie alla fine e la attacco
|
||||||
|
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
||||||
|
if ( ! pSce->CreateByRegion( vPL))
|
||||||
|
return nullptr ;
|
||||||
|
// attacco la superficie finale alla swept
|
||||||
|
pSce->Invert() ;
|
||||||
|
pStmSwept->DoSewing( *pSce) ;
|
||||||
|
}
|
||||||
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||||
|
double dVol ;
|
||||||
|
if ( pStmSwept->GetVolume( dVol) && dVol < 0)
|
||||||
|
pStmSwept->Invert() ;
|
||||||
|
|
||||||
|
return Release( pStmSwept) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
GetSurfTriMeshTransSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol)
|
||||||
|
{
|
||||||
|
// verifica parametri
|
||||||
|
if ( pSect == nullptr || pGuide == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
// determino se la sezione è chiusa
|
||||||
|
bool bSectClosed = pSect->IsClosed() ;
|
||||||
|
// punto iniziale della sezione e vettore a inizio guida
|
||||||
|
Point3d ptStart ;
|
||||||
|
if ( ! pSect->GetStartPoint( ptStart))
|
||||||
|
return nullptr ;
|
||||||
|
Point3d ptGuide ;
|
||||||
|
if ( ! pGuide->GetStartPoint( ptGuide))
|
||||||
|
return nullptr ;
|
||||||
|
Vector3d vtDelta = ptStart - ptGuide ;
|
||||||
|
// calcolo la polilinea che approssima la guida
|
||||||
|
PolyLine PLG ;
|
||||||
|
if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLG))
|
||||||
|
return nullptr ;
|
||||||
|
// determino se la guida è chiusa
|
||||||
|
bool bGuideClosed = PLG.IsClosed() ;
|
||||||
// calcolo la superficie
|
// calcolo la superficie
|
||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSTM))
|
if ( IsNull( pSTM))
|
||||||
@@ -687,19 +1106,16 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
|
|||||||
// superficie swept
|
// superficie swept
|
||||||
PtrOwner<ICurve> pPrevCrv ;
|
PtrOwner<ICurve> pPrevCrv ;
|
||||||
Point3d ptP ;
|
Point3d ptP ;
|
||||||
bool bPoint = PL.GetFirstPoint( ptP) ;
|
bool bPoint = PLG.GetFirstPoint( ptP) ;
|
||||||
while ( bPoint) {
|
while ( bPoint) {
|
||||||
// nuova curva
|
// nuova curva
|
||||||
OffsetCurve OffsCrv ;
|
PtrOwner<ICurve> pCurrCrv( pSect->Clone()) ;
|
||||||
if ( ! OffsCrv.Make( pGuide, ptP.x, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0)
|
|
||||||
return nullptr ;
|
|
||||||
PtrOwner<ICurve> pCurrCrv( OffsCrv.GetLongerCurve()) ;
|
|
||||||
if ( IsNull( pCurrCrv))
|
if ( IsNull( pCurrCrv))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pCurrCrv->Translate( ptP.y * frStart.VersY()) ;
|
pCurrCrv->Translate( ptP - ptStart + vtDelta) ;
|
||||||
// se esiste la curva precedente, costruisco la rigata (di tipo minima distanza)
|
// se esiste la curva precedente, costruisco la rigata (di tipo minima distanza)
|
||||||
if ( ! IsNull( pPrevCrv)) {
|
if ( ! IsNull( pPrevCrv)) {
|
||||||
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_ISOPAR, dLinTol)) ;
|
||||||
if ( IsNull( pSr))
|
if ( IsNull( pSr))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSTM->DoSewing( *pSr) ;
|
pSTM->DoSewing( *pSr) ;
|
||||||
@@ -707,39 +1123,33 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
|
|||||||
// salvo la curva come prossima precedente
|
// salvo la curva come prossima precedente
|
||||||
pPrevCrv.Set( pCurrCrv) ;
|
pPrevCrv.Set( pCurrCrv) ;
|
||||||
// prossimo punto
|
// prossimo punto
|
||||||
bPoint = PL.GetNextPoint( ptP) ;
|
bPoint = PLG.GetNextPoint( ptP) ;
|
||||||
}
|
}
|
||||||
// se richiesti caps e sezione chiusa e guida aperta
|
// se richiesti caps e sezione chiusa e guida aperta
|
||||||
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
||||||
// verifico che le due estremità siano chiuse e piatte
|
// calcolo la polilinea che approssima la sezione
|
||||||
POLYLINEVECTOR vPL ;
|
PolyLine PLS ;
|
||||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLS))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
Plane3d plEnds ; double dArea ;
|
// verifico che la sezione sia chiusa e piatta
|
||||||
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
Plane3d plSect ; double dArea ;
|
||||||
return nullptr ;
|
if ( PLS.IsClosedAndFlat( plSect, dArea, 100 * EPS_SMALL)) {
|
||||||
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
// aggiungo il cap sull'inizio
|
||||||
return nullptr ;
|
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||||
// aggiungo il cap sull'inizio
|
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PLS))
|
||||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
return nullptr ;
|
||||||
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
pSci->Invert() ;
|
||||||
return nullptr ;
|
Point3d ptGi ; PLG.GetFirstPoint( ptGi) ;
|
||||||
pSci->ToGlob( frStart) ;
|
pSci->Translate( ptGi - ptStart + vtDelta) ;
|
||||||
pSTM->DoSewing( *pSci) ;
|
pSTM->DoSewing( *pSci) ;
|
||||||
// riferimento alla fine della linea guida
|
// aggiungo il cap sulla fine
|
||||||
Frame3d frEnd ;
|
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||||
Point3d ptEnd ;
|
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PLS))
|
||||||
pGuide->GetEndPoint( ptEnd) ;
|
return nullptr ;
|
||||||
Vector3d vtEnd ;
|
Point3d ptGe ; PLG.GetLastPoint( ptGe) ;
|
||||||
pGuide->GetEndDir( vtEnd) ;
|
pSce->Translate( ptGe - ptStart + vtDelta) ;
|
||||||
frEnd.Set( ptEnd, -vtEnd, vtEnd ^ vtNorm) ;
|
pSTM->DoSewing( *pSce) ;
|
||||||
// aggiungo il cap sulla fine
|
}
|
||||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
|
||||||
return nullptr ;
|
|
||||||
pSce->Invert() ;
|
|
||||||
pSce->ToGlob( frEnd) ;
|
|
||||||
pSTM->DoSewing( *pSce) ;
|
|
||||||
}
|
}
|
||||||
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||||
double dVol ;
|
double dVol ;
|
||||||
@@ -800,56 +1210,132 @@ bool
|
|||||||
CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||||
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
||||||
{
|
{
|
||||||
|
// se non ho curve, non faccio nulla
|
||||||
|
if ( int( vpCurve.size()) == 0)
|
||||||
|
return true ;
|
||||||
|
|
||||||
// calcolo le polilinee che approssimano le curve
|
// calcolo le polilinee che approssimano le curve
|
||||||
POLYLINEVECTOR vPLtmp ;
|
vPL.resize( vpCurve.size()) ;
|
||||||
vPLtmp.resize( vpCurve.size()) ;
|
|
||||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPLtmp[i]))
|
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// ne calcolo l'area e genero un ordine in senso decrescente
|
|
||||||
typedef pair<int,double> INDAREA ; // coppia indice, area
|
// ricavo versore normale
|
||||||
typedef vector<INDAREA> INDAREAVECTOR ; // vettore di coppie indice, area
|
Plane3d plPlane ; double dArea ;
|
||||||
INDAREAVECTOR vArea ;
|
if ( ! vPL[0].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||||
vArea.reserve( vPLtmp.size()) ;
|
return false ;
|
||||||
Vector3d vtN0 ;
|
vtN = plPlane.GetVersN() ;
|
||||||
for ( int i = 0 ; i < int( vPLtmp.size()) ; ++ i) {
|
|
||||||
// verifico chiusura, calcolo piano medio e area
|
typedef std::pair<int,double> INDAREA ;
|
||||||
|
std::vector<INDAREA> m_vArea ;
|
||||||
|
// calcolo piano medio e area delle curve
|
||||||
|
m_vArea.reserve( vPL.size()) ;
|
||||||
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
|
// calcolo piano medio e area
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
double dArea ;
|
double dArea ;
|
||||||
if ( ! vPLtmp[i].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
||||||
return false ;
|
return false ;
|
||||||
// imposto la normale del primo contorno come riferimento
|
|
||||||
if ( i == 0)
|
|
||||||
vtN0 = plPlane.GetVersN() ;
|
|
||||||
// verifico che le normali siano molto vicine
|
// verifico che le normali siano molto vicine
|
||||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN0))
|
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN))
|
||||||
return false ;
|
return false ;
|
||||||
// assegno il segno all'area secondo il verso della normale
|
// assegno il segno all'area secondo il verso della normale
|
||||||
if ( ( plPlane.GetVersN() * vtN0) > 0)
|
if ( ( plPlane.GetVersN() * vtN) > 0)
|
||||||
vArea.emplace_back( i, dArea) ;
|
m_vArea.emplace_back( i, dArea) ;
|
||||||
else
|
else
|
||||||
vArea.emplace_back( i, - dArea) ;
|
m_vArea.emplace_back( i, - dArea) ;
|
||||||
}
|
}
|
||||||
sort( vArea.begin(), vArea.end(),
|
// ordino in senso decrescente sull'area
|
||||||
|
sort( m_vArea.begin(), m_vArea.end(),
|
||||||
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
||||||
// sposto le polilinee nel vettore da restituire secondo l'ordine
|
|
||||||
vPL.clear() ;
|
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
||||||
vPL.resize( vPLtmp.size()) ;
|
Frame3d frRef ; frRef.Set( ORIG, vtN) ;
|
||||||
bool bCCW = true ;
|
if ( ! frRef.IsValid())
|
||||||
for ( int i = 0 ; i < int( vPLtmp.size()) ; ++ i) {
|
return false ;
|
||||||
// scambio
|
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
||||||
swap( vPL[i], vPLtmp[vArea[i].first]) ;
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
// verifico senso di rotazione del contorno esterno
|
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
||||||
if ( i == 0)
|
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
||||||
bCCW = ( vArea[i].second > 0) ;
|
vCrvCompo[i]->ToLoc( frRef) ;
|
||||||
// aggiusto gli altri contorni
|
|
||||||
else {
|
|
||||||
if ( ( bCCW && vArea[i].second > 0) || ( ! bCCW && vArea[i].second < 0))
|
|
||||||
vPL[i].Invert() ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// restituisco la normale positiva alla regione
|
|
||||||
vtN = ( bCCW ? vtN0 : - vtN0) ;
|
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
|
||||||
|
// successive i loop interni
|
||||||
|
INTMATRIX vnPLIndMat ;
|
||||||
|
|
||||||
|
// vettore di indici per ordinare le PolyLine
|
||||||
|
INTVECTOR vPL_IndOrder ; vPL_IndOrder.resize( int( vPL.size())) ;
|
||||||
|
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i)
|
||||||
|
vPL_IndOrder[i] = m_vArea[i].first ;
|
||||||
|
|
||||||
|
// aggiungo le diverse curve
|
||||||
|
bool bFirstCrv ;
|
||||||
|
Plane3d plExtLoop ;
|
||||||
|
double dAreaExtLoop = 0. ;
|
||||||
|
do {
|
||||||
|
bFirstCrv = true ;
|
||||||
|
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||||
|
// recupero indice di percorso e verifico sia valido
|
||||||
|
int j = m_vArea[i].first ;
|
||||||
|
if ( j < 0)
|
||||||
|
continue ;
|
||||||
|
// lo inserisco come esterno...
|
||||||
|
if ( bFirstCrv) {
|
||||||
|
vnPLIndMat.push_back({ j}) ;
|
||||||
|
m_vArea[i].first = -1 ;
|
||||||
|
dAreaExtLoop = m_vArea[i].second ;
|
||||||
|
// inverto se necessario
|
||||||
|
if ( m_vArea[i].second < EPS_SMALL) {
|
||||||
|
vPL[j].Invert() ;
|
||||||
|
vCrvCompo[j]->Invert() ;
|
||||||
|
dAreaExtLoop *= -1 ;
|
||||||
|
}
|
||||||
|
bFirstCrv = false ;
|
||||||
|
}
|
||||||
|
// ... altrimenti verifico se il loop è interno o no
|
||||||
|
else {
|
||||||
|
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
||||||
|
// esterno a tutti i loop già inseriti nella riga attuale.
|
||||||
|
// verifica rispetto loop esterno
|
||||||
|
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
||||||
|
CRVCVECTOR ccClass ;
|
||||||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
|
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
||||||
|
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||||
|
continue ;
|
||||||
|
// verifica rispetto ai loop interni
|
||||||
|
bool bOk = true ;
|
||||||
|
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
||||||
|
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
||||||
|
CRVCVECTOR ccClass2 ;
|
||||||
|
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
|
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
||||||
|
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||||
|
bOk = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bOk) {
|
||||||
|
// inserisco nella matrice
|
||||||
|
vnPLIndMat.back().push_back( j) ;
|
||||||
|
m_vArea[i].first = -1 ;
|
||||||
|
// inverto se necessario
|
||||||
|
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
|
||||||
|
vPL[j].Invert() ;
|
||||||
|
vCrvCompo[j]->Invert() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ( ! bFirstCrv) ;
|
||||||
|
|
||||||
|
// ordino le PolyLine per area
|
||||||
|
POLYLINEVECTOR vPL_tmp ;
|
||||||
|
for ( int i = 0 ; i < int( vPL_IndOrder.size()) ; ++ i)
|
||||||
|
vPL_tmp.push_back( vPL[ vPL_IndOrder[i]]) ;
|
||||||
|
swap( vPL, vPL_tmp) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-47
@@ -16,6 +16,7 @@
|
|||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
#include "SurfFlatRegion.h"
|
#include "SurfFlatRegion.h"
|
||||||
|
#include "AdjustLoops.h"
|
||||||
#include "Voronoi.h"
|
#include "Voronoi.h"
|
||||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||||
@@ -36,7 +37,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
if ( nChunk == 0)
|
if ( nChunk == 0)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// se offset nullo, la nuova regione è la copia di quella attuale
|
// se offset nullo, la nuova regione è la copia di quella attuale
|
||||||
if ( abs( dDist) < 10 * EPS_SMALL)
|
if ( abs( dDist) < 10 * EPS_SMALL)
|
||||||
return this->Clone() ;
|
return this->Clone() ;
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
while ( bOk && ! IsNull( pOffs)) {
|
while ( bOk && ! IsNull( pOffs)) {
|
||||||
if ( pOffs->GetType() == CRV_COMPO) {
|
if ( pOffs->GetType() == CRV_COMPO) {
|
||||||
CurveComposite* pOffsCompo = GetBasicCurveComposite( pOffs) ;
|
CurveComposite* pOffsCompo = GetBasicCurveComposite( pOffs) ;
|
||||||
// assegno proprietà
|
// assegno proprietà
|
||||||
pOffsCompo->SetTempProp( j, 1) ;
|
pOffsCompo->SetTempProp( j, 1) ;
|
||||||
for ( int k = 0 ; k < pOffsCompo->GetCurveCount() ; ++k)
|
for ( int k = 0 ; k < pOffsCompo->GetCurveCount() ; ++k)
|
||||||
pOffsCompo->SetCurveTempProp( k, j, 1) ;
|
pOffsCompo->SetCurveTempProp( k, j, 1) ;
|
||||||
@@ -80,7 +81,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
pOffs->SetTempProp( j, 1) ;
|
pOffs->SetTempProp( j, 1) ;
|
||||||
// se prima curva esterna, è il primo contorno esterno della nuova regione
|
// se prima curva esterna, è il primo contorno esterno della nuova regione
|
||||||
if ( j == 0 && bFirstCurve) {
|
if ( j == 0 && bFirstCurve) {
|
||||||
if ( ! pSfrChk->AddExtLoop( Release( pOffs)))
|
if ( ! pSfrChk->AddExtLoop( Release( pOffs)))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -137,7 +138,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
|
|
||||||
// -------------------- OFFSET CON VORONOI -------------------------------------
|
// -------------------- OFFSET CON VORONOI -------------------------------------
|
||||||
else {
|
else {
|
||||||
// verifico se oggetto Voronoi della superficie è definito
|
// verifico se oggetto Voronoi della superficie è definito
|
||||||
if ( m_pVoronoiObj == nullptr)
|
if ( m_pVoronoiObj == nullptr)
|
||||||
CalcVoronoiObject() ;
|
CalcVoronoiObject() ;
|
||||||
|
|
||||||
@@ -146,51 +147,28 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
if ( ! m_pVoronoiObj->CalcOffset( vOffs, dDist, nType))
|
if ( ! m_pVoronoiObj->CalcOffset( vOffs, dDist, nType))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
|
// costruisco la superficie
|
||||||
if ( vOffs.size() > 0) {
|
if ( vOffs.size() > 0) {
|
||||||
BOOLVECTOR vbAddOrSub( vOffs.size(), true) ;
|
PCRV_DEQUE vLoops ;
|
||||||
int nFirstId = -1 ;
|
for ( int i = 0 ; i < int( vOffs.size()) ; i ++) {
|
||||||
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++) {
|
|
||||||
// porto nel frame della flat region
|
|
||||||
vOffs[i]->ToLoc( m_frF) ;
|
vOffs[i]->ToLoc( m_frF) ;
|
||||||
// calcolo orientamento della curva
|
// rimuovo eventuali sovrapposizioni
|
||||||
double dAreaXY ;
|
ICURVEPLIST CrvLst ;
|
||||||
if ( ! vOffs[i]->GetAreaXY( dAreaXY))
|
AdjustLoops( Release( vOffs[i]), CrvLst, true) ;
|
||||||
return nullptr ;
|
for ( auto pCrv : CrvLst) {
|
||||||
vbAddOrSub[i] = ( dAreaXY > SQ_EPS_SMALL) ;
|
pCrv->SetExtrusion( Z_AX) ;
|
||||||
// verifico se è il primo loop esterno
|
vLoops.emplace_back( pCrv) ;
|
||||||
if ( nFirstId == -1 && vbAddOrSub[i])
|
|
||||||
nFirstId = i ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// inizializzo la superficie
|
|
||||||
if ( nFirstId != -1 && ! pSfr->AddExtLoop( Release( vOffs[nFirstId])))
|
|
||||||
return nullptr ;
|
|
||||||
if ( pSfr->IsValid()) {
|
|
||||||
|
|
||||||
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++) {
|
|
||||||
// verifico non sia il primo loop esterno
|
|
||||||
if ( i == nFirstId)
|
|
||||||
continue ;
|
|
||||||
// costruisco la superficie associata
|
|
||||||
PtrOwner<SurfFlatRegion> pSrfCrv( CreateBasicSurfFlatRegion()) ;
|
|
||||||
if ( IsNull( pSrfCrv) || ! pSrfCrv->AddExtLoop( Release( vOffs[i])))
|
|
||||||
return nullptr ;
|
|
||||||
if ( ! pSrfCrv->IsValid())
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
// aggiungo o sottraggo
|
|
||||||
if ( vbAddOrSub[i]) {
|
|
||||||
if ( ! pSfr->Add( *pSrfCrv))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pSrfCrv->Invert() ;
|
|
||||||
if ( ! pSfr->Subtract( *pSrfCrv))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verifico di avere ancora dei loops
|
||||||
|
if ( vLoops.size() > 0) {
|
||||||
|
pSfr.Set( MyNewSurfFromLoops( vLoops)) ;
|
||||||
|
if ( IsNull( pSfr)) {
|
||||||
|
MyTestAndDelete( vLoops) ;
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,9 +185,9 @@ SurfFlatRegion::Offset( double dDist, int nType)
|
|||||||
if ( nChunk == 0)
|
if ( nChunk == 0)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// se offset nullo, non devo fare alcunchè
|
// se offset nullo, non devo fare alcunchè
|
||||||
if ( abs( dDist) < 10 * EPS_SMALL)
|
if ( abs( dDist) < 10 * EPS_SMALL)
|
||||||
return this->Clone() ;
|
return true ;
|
||||||
|
|
||||||
// calcolo la superficie di offset
|
// calcolo la superficie di offset
|
||||||
PtrOwner<SurfFlatRegion> pSfr( CreateOffsetSurf( dDist, nType)) ;
|
PtrOwner<SurfFlatRegion> pSfr( CreateOffsetSurf( dDist, nType)) ;
|
||||||
|
|||||||
+2
-2
@@ -31,7 +31,7 @@
|
|||||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -1960,7 +1960,7 @@ SurfTriMesh::CreateByRegion( const POLYLINEVECTOR& vPL)
|
|||||||
PNTVECTOR vPnt ;
|
PNTVECTOR vPnt ;
|
||||||
INTVECTOR vTria ;
|
INTVECTOR vTria ;
|
||||||
Triangulate Tri ;
|
Triangulate Tri ;
|
||||||
if ( ! Tri.Make( vPL, vPnt, vTria))
|
if ( ! Tri.MakeAdvanced( vPL, vPnt, vTria))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// inizializzo la superficie
|
// inizializzo la superficie
|
||||||
|
|||||||
+192
-126
@@ -52,9 +52,10 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
|
|||||||
if ( vnDegVec[nC] > 0)
|
if ( vnDegVec[nC] > 0)
|
||||||
++ nExistNotDeg ;
|
++ nExistNotDeg ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divido il loop di partenza in sotto-loop
|
// Divido il loop di partenza in sotto-loop
|
||||||
int nIterationCount = 0 ;
|
int nIterationCount = 0 ;
|
||||||
while ( cvOpenChain.size() > 0) {
|
while ( cvOpenChain.size() > 0) { // per ogni catena aperta...
|
||||||
bool bLoopSplitted = false ;
|
bool bLoopSplitted = false ;
|
||||||
int nLastOpenLoopN = int( cvOpenChain.size()) - 1 ;
|
int nLastOpenLoopN = int( cvOpenChain.size()) - 1 ;
|
||||||
if ( vnDegVec[nLastOpenLoopN] == 1) {
|
if ( vnDegVec[nLastOpenLoopN] == 1) {
|
||||||
@@ -63,13 +64,24 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
|
|||||||
int nLastOpenLoopPoint = max( int( cvOpenChain[nLastOpenLoopN].size()) - 1, 0) ;
|
int nLastOpenLoopPoint = max( int( cvOpenChain[nLastOpenLoopN].size()) - 1, 0) ;
|
||||||
Point3d ptOpenLoopStP = cvOpenChain[nLastOpenLoopN][0].ptSt ;
|
Point3d ptOpenLoopStP = cvOpenChain[nLastOpenLoopN][0].ptSt ;
|
||||||
Point3d ptOpenLoopEnP = cvOpenChain[nLastOpenLoopN][nLastOpenLoopPoint].ptEn ;
|
Point3d ptOpenLoopEnP = cvOpenChain[nLastOpenLoopN][nLastOpenLoopPoint].ptEn ;
|
||||||
|
// costruisco il primo e il secondo loop che si generano
|
||||||
|
// NB. il loop esterno è chiuso, mentre la catena aperta
|
||||||
|
// è la successione dei tratti lineari dovuti ai triangoli dell'altra superficie
|
||||||
PNTVECTOR Loop1, Loop2 ;
|
PNTVECTOR Loop1, Loop2 ;
|
||||||
|
// cambio il punto iniziale del loop di bordo se non coincide già con ptStart della catena aperta
|
||||||
bool bChangedStart = ChangeStart( ptOpenLoopStP, cvBoundClosedLoopVec[nLoop]) ;
|
bool bChangedStart = ChangeStart( ptOpenLoopStP, cvBoundClosedLoopVec[nLoop]) ;
|
||||||
|
// splitto
|
||||||
bool bSplitted = SplitAtPoint( ptOpenLoopEnP, cvBoundClosedLoopVec[nLoop], Loop1, Loop2) ;
|
bool bSplitted = SplitAtPoint( ptOpenLoopEnP, cvBoundClosedLoopVec[nLoop], Loop1, Loop2) ;
|
||||||
if ( ! ( bChangedStart && bSplitted) ||
|
if ( ! ( bChangedStart && bSplitted) ||
|
||||||
( nLastOpenLoopPoint == 0 && ( Loop1.size() == 2 || Loop2.size() == 2)))
|
( nLastOpenLoopPoint == 0 && ( Loop1.size() == 2 || Loop2.size() == 2)))
|
||||||
continue ;
|
continue ; // la catena aperta non è interna al loop chiuso attuale
|
||||||
|
|
||||||
|
// il loop 1 segue sempre la direzione della catena, il loop 2 ha dentro la catena invertita
|
||||||
|
// Ho sempre che il loop 1 è sempre interno ( la direzione della catena è determinata
|
||||||
|
// dalla normale dei triangoli che la formano; avendo chimatao la chian senza ammettere inversioni, sono
|
||||||
|
// curve tutte concordi ) e il loop 2 che è esterno
|
||||||
bLoopSplitted = true ;
|
bLoopSplitted = true ;
|
||||||
|
// ricostrusico i due loop mediante concatenazione
|
||||||
Chain cvCounterChain ;
|
Chain cvCounterChain ;
|
||||||
for ( int nPt = int( cvOpenChain[nLastOpenLoopN].size()) - 1 ; nPt >= 0 ; -- nPt) {
|
for ( int nPt = int( cvOpenChain[nLastOpenLoopN].size()) - 1 ; nPt >= 0 ; -- nPt) {
|
||||||
IntSegment CurSeg ;
|
IntSegment CurSeg ;
|
||||||
@@ -181,7 +193,7 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
|
|||||||
// elimino i punti superflui prima
|
// elimino i punti superflui prima
|
||||||
for ( int i = 0 ; i < nCvFirst ; ++ i)
|
for ( int i = 0 ; i < nCvFirst ; ++ i)
|
||||||
cvBoundClosedLoopVec[nLoop].erase( cvBoundClosedLoopVec[nLoop].begin()) ;
|
cvBoundClosedLoopVec[nLoop].erase( cvBoundClosedLoopVec[nLoop].begin()) ;
|
||||||
// verifico se questo punto � dalla parte valida o no
|
// verifico se questo punto è dalla parte valida o no
|
||||||
bool bC12 = ( ( ptM12 - ptProva) * vtVecProva < 0) ;
|
bool bC12 = ( ( ptM12 - ptProva) * vtVecProva < 0) ;
|
||||||
vbInOut[nLoop] = bC12 ;
|
vbInOut[nLoop] = bC12 ;
|
||||||
}
|
}
|
||||||
@@ -192,7 +204,7 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
|
|||||||
// elimino i punti superflui intermedi
|
// elimino i punti superflui intermedi
|
||||||
for ( int i = nCvFirst + 2 ; i < nCvSecond ; ++ i)
|
for ( int i = nCvFirst + 2 ; i < nCvSecond ; ++ i)
|
||||||
cvBoundClosedLoopVec[nLoop].erase( cvBoundClosedLoopVec[nLoop].begin() + nCvFirst + 2) ;
|
cvBoundClosedLoopVec[nLoop].erase( cvBoundClosedLoopVec[nLoop].begin() + nCvFirst + 2) ;
|
||||||
// verifico se questo punto � dalla parte valida o no
|
// verifico se questo punto è dalla parte valida o no
|
||||||
bool bC21 = ( ( ptM21 - ptProva) * vtVecProva < 0) ;
|
bool bC21 = ( ( ptM21 - ptProva) * vtVecProva < 0) ;
|
||||||
vbInOut[nLoop] = bC21 ;
|
vbInOut[nLoop] = bC21 ;
|
||||||
}
|
}
|
||||||
@@ -234,9 +246,13 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
// La superficie deve essere valida
|
// La superficie deve essere valida
|
||||||
if ( ! Surf.IsValid())
|
if ( ! Surf.IsValid())
|
||||||
return false ;
|
return false ;
|
||||||
// Ritriangolarizzo i triangoli
|
|
||||||
|
// itero sulla unorderd_map
|
||||||
for ( auto it = LoopLines.begin() ; it != LoopLines.end() ; ++ it) {
|
for ( auto it = LoopLines.begin() ; it != LoopLines.end() ; ++ it) {
|
||||||
|
|
||||||
|
// itero sulle catene ( secondo parametro della mappa)
|
||||||
for ( int nS1 = 0 ; nS1 < int( it->second.size()) - 1 ; ++ nS1) {
|
for ( int nS1 = 0 ; nS1 < int( it->second.size()) - 1 ; ++ nS1) {
|
||||||
|
// tolgo i tratti degeneri ad un punto
|
||||||
for ( int nS2 = nS1 + 1 ; nS2 < int( it->second.size()) ; ++ nS2) {
|
for ( int nS2 = nS1 + 1 ; nS2 < int( it->second.size()) ; ++ nS2) {
|
||||||
if ( AreSamePointApprox( it->second[nS1].ptSt, it->second[nS2].ptEn) &&
|
if ( AreSamePointApprox( it->second[nS1].ptSt, it->second[nS2].ptEn) &&
|
||||||
AreSamePointApprox( it->second[nS1].ptEn, it->second[nS2].ptSt) &&
|
AreSamePointApprox( it->second[nS1].ptEn, it->second[nS2].ptSt) &&
|
||||||
@@ -248,22 +264,21 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// se non resta nulla, allora passo alla mappa successiva
|
||||||
if ( int( it->second.size()) == 0)
|
if ( int( it->second.size()) == 0)
|
||||||
continue ;
|
continue ;
|
||||||
|
|
||||||
// Se il triangolo è stato sottoposto a ritriangolazione, le sue componenti sono classificabili come dentro-fuori.
|
// Se il triangolo è stato sottoposto a ritriangolazione, le sue componenti sono classificabili come dentro-fuori.
|
||||||
// Lo tolgo dall'insieme dei triangoli ambigui (intersezione edge-edge)
|
// Lo tolgo dall'insieme dei triangoli ambigui (intersezione edge-edge)
|
||||||
else {
|
auto itS = Ambiguos.find( it->first) ;
|
||||||
auto itS = Ambiguos.find( it->first) ;
|
if ( itS != Ambiguos.end())
|
||||||
if ( itS != Ambiguos.end()) {
|
Ambiguos.erase( itS) ;
|
||||||
Ambiguos.erase( itS) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creo i loop
|
// CREAZIONE DEI LOOP ---------------------------------------------
|
||||||
|
// Chain
|
||||||
ChainCurves LoopCreator ;
|
ChainCurves LoopCreator ;
|
||||||
LoopCreator.Init( false, 2 * EPS_SMALL, int( it->second.size()), 10 * BOOLEAN_SCALE) ;
|
LoopCreator.Init( false, 2 * EPS_SMALL, int( it->second.size()), 10 * BOOLEAN_SCALE) ;
|
||||||
// Carico le curve per concatenarle
|
// Recupero le curve ( gli estremi dei tratti lineari) per concatenarle
|
||||||
for ( int nCv = 0 ; nCv < int( it->second.size()); ++ nCv) {
|
for ( int nCv = 0 ; nCv < int( it->second.size()); ++ nCv) {
|
||||||
Point3d ptSt = it->second[nCv].ptSt ;
|
Point3d ptSt = it->second[nCv].ptSt ;
|
||||||
Point3d ptEn = it->second[nCv].ptEn ;
|
Point3d ptEn = it->second[nCv].ptEn ;
|
||||||
@@ -277,15 +292,14 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
CHAINVECTOR vChain ;
|
CHAINVECTOR vChain ;
|
||||||
while ( LoopCreator.GetChainFromNear( ptNearStart, false, vIds)) {
|
while ( LoopCreator.GetChainFromNear( ptNearStart, false, vIds)) {
|
||||||
Chain chTemp ;
|
Chain chTemp ;
|
||||||
for ( auto i : vIds) {
|
for ( auto i : vIds) // Aggiungo la linea alla curva composta
|
||||||
// Aggiungo la linea alla curva composta.
|
|
||||||
chTemp.emplace_back( it->second[i - 1]) ;
|
chTemp.emplace_back( it->second[i - 1]) ;
|
||||||
}
|
|
||||||
vChain.emplace_back( chTemp) ;
|
vChain.emplace_back( chTemp) ;
|
||||||
}
|
}
|
||||||
// Lavoro su loop e catene per regolarizzarle
|
// Lavoro su loop e catene per regolarizzarle
|
||||||
int nChainCnt = int( vChain.size()) ;
|
int nChainCnt = int( vChain.size()) ;
|
||||||
// unisco eventuali catene estreme che sono parte di una stessa catena
|
// Unisco eventuali catene estreme che sono parte di una stessa catena
|
||||||
if ( nChainCnt > 1) {
|
if ( nChainCnt > 1) {
|
||||||
if ( AreSamePointApprox( vChain[0].front().ptSt, vChain[nChainCnt - 1].back().ptEn)) {
|
if ( AreSamePointApprox( vChain[0].front().ptSt, vChain[nChainCnt - 1].back().ptEn)) {
|
||||||
vChain[0].insert( vChain[0].begin(), vChain[nChainCnt - 1].begin(), vChain[nChainCnt - 1].end()) ;
|
vChain[0].insert( vChain[0].begin(), vChain[nChainCnt - 1].begin(), vChain[nChainCnt - 1].end()) ;
|
||||||
@@ -298,7 +312,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
-- nChainCnt ;
|
-- nChainCnt ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// semplifico catene formate da punti degeneri
|
// Semplifico catene formate da punti degeneri
|
||||||
for ( int nCh = 0 ; nCh < nChainCnt ; ++ nCh) {
|
for ( int nCh = 0 ; nCh < nChainCnt ; ++ nCh) {
|
||||||
if ( vChain[nCh].size() == 2 && ( vChain[nCh][0].bDegenerate || vChain[nCh][1].bDegenerate)) {
|
if ( vChain[nCh].size() == 2 && ( vChain[nCh][0].bDegenerate || vChain[nCh][1].bDegenerate)) {
|
||||||
vChain[nCh][0].ptEn = vChain[nCh][1].ptEn ;
|
vChain[nCh][0].ptEn = vChain[nCh][1].ptEn ;
|
||||||
@@ -377,6 +391,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chiudo i loop costruiti a partire dalle catene
|
// Chiudo i loop costruiti a partire dalle catene
|
||||||
for ( int nC = 0 ; nC < nChainCnt ; ++ nC) {
|
for ( int nC = 0 ; nC < nChainCnt ; ++ nC) {
|
||||||
int nChainLastSegPos = int( vChain[nC].size()) - 1 ;
|
int nChainLastSegPos = int( vChain[nC].size()) - 1 ;
|
||||||
@@ -463,7 +478,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[0] = 0 ;
|
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[0] = 0 ;
|
||||||
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[1] = 0 ;
|
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[1] = 0 ;
|
||||||
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[2] = 0 ;
|
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[2] = 0 ;
|
||||||
Surf.m_vTria[nNewAloneTriaNum].nTempPart = nDist[nAloneVert] ;
|
Surf.m_vTria[nNewAloneTriaNum].nTempPart = nDist[nAloneVert] ;
|
||||||
bModif = true ;
|
bModif = true ;
|
||||||
}
|
}
|
||||||
int nNewCoupleId1[3] = { Surf.AddVertex( ptIntSt), Surf.AddVertex( trTria.GetP( ( nAloneVert + 1) % 3)), Surf.AddVertex( trTria.GetP( ( nAloneVert + 2) % 3)) } ;
|
int nNewCoupleId1[3] = { Surf.AddVertex( ptIntSt), Surf.AddVertex( trTria.GetP( ( nAloneVert + 1) % 3)), Surf.AddVertex( trTria.GetP( ( nAloneVert + 2) % 3)) } ;
|
||||||
@@ -472,7 +487,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[0] = 0 ;
|
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[0] = 0 ;
|
||||||
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[1] = 0 ;
|
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[1] = 0 ;
|
||||||
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[2] = 0 ;
|
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[2] = 0 ;
|
||||||
Surf.m_vTria[nNewCoupleTriaNum1].nTempPart = - nDist[nAloneVert] ;
|
Surf.m_vTria[nNewCoupleTriaNum1].nTempPart = - nDist[nAloneVert] ;
|
||||||
bModif = true ;
|
bModif = true ;
|
||||||
}
|
}
|
||||||
int nNewCoupleId2[3] = { Surf.AddVertex( ptIntSt), Surf.AddVertex( trTria.GetP( ( nAloneVert + 2) % 3)), Surf.AddVertex( ptIntEn) } ;
|
int nNewCoupleId2[3] = { Surf.AddVertex( ptIntSt), Surf.AddVertex( trTria.GetP( ( nAloneVert + 2) % 3)), Surf.AddVertex( ptIntEn) } ;
|
||||||
@@ -481,27 +496,32 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[0] = 0 ;
|
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[0] = 0 ;
|
||||||
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[1] = 0 ;
|
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[1] = 0 ;
|
||||||
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[2] = 0 ;
|
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[2] = 0 ;
|
||||||
Surf.m_vTria[nNewCoupleTriaNum2].nTempPart = - nDist[nAloneVert] ;
|
Surf.m_vTria[nNewCoupleTriaNum2].nTempPart = - nDist[nAloneVert] ;
|
||||||
bModif = true ;
|
bModif = true ;
|
||||||
}
|
}
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Creo il loop chiuso padre di tutti, il perimetro del triangolo.
|
|
||||||
// Questo viene diviso in sotto-loop chiusi mediante quelli aperti.
|
// Creo il loop chiuso padre di tutti, il perimetro del triangolo. Questo viene diviso in sotto-loop
|
||||||
// I loop chiusi trovati precedentemente sono interni a uno dei sotto-loop
|
// chiusi mediante quelli aperti. I loop chiusi trovati precedentemente sono interni a uno dei
|
||||||
// chiusi di cui è formato il perimetro.
|
// sotto-loop chiusi di cui è formato il perimetro.
|
||||||
PNTVECTOR cvFirstLoop ;
|
PNTVECTOR cvFirstLoop ;
|
||||||
cvFirstLoop.emplace_back( trTria.GetP( 0)) ;
|
cvFirstLoop.emplace_back( trTria.GetP( 0)) ;
|
||||||
cvFirstLoop.emplace_back( trTria.GetP( 1)) ;
|
cvFirstLoop.emplace_back( trTria.GetP( 1)) ;
|
||||||
cvFirstLoop.emplace_back( trTria.GetP( 2)) ;
|
cvFirstLoop.emplace_back( trTria.GetP( 2)) ;
|
||||||
|
|
||||||
PNTMATRIX cvBoundClosedLoopVec;
|
// creo una matrice di punti ; ogni riga corrisponde ad una sequenza di punti che indentificano un loop
|
||||||
|
PNTMATRIX cvBoundClosedLoopVec ;
|
||||||
cvBoundClosedLoopVec.emplace_back( cvFirstLoop) ;
|
cvBoundClosedLoopVec.emplace_back( cvFirstLoop) ;
|
||||||
|
|
||||||
|
// vettore per indicare se il loop è interno/esterno all'altra superficie
|
||||||
BOOLVECTOR vbInOut ;
|
BOOLVECTOR vbInOut ;
|
||||||
vbInOut.push_back( true) ;
|
vbInOut.push_back( true) ;
|
||||||
|
|
||||||
// Divido il loop usando le catene
|
// Divido il loop usando le catene
|
||||||
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
|
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
|
||||||
if ( cvBoundClosedLoopVec.size() == 1 && cvOpenChain.size() == 2) {
|
if ( cvBoundClosedLoopVec.size() == 1 && cvOpenChain.size() == 2) {
|
||||||
@@ -556,7 +576,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Surf.m_vTria[it->first].nTempPart = 0 ;
|
Surf.m_vTria[it->first].nTempPart = 0 ;
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Rimuovo il triangolo corrente
|
// Rimuovo il triangolo corrente
|
||||||
int nOldTriaCol = Surf.m_vTria[it->first].nTFlag ;
|
int nOldTriaCol = Surf.m_vTria[it->first].nTFlag ;
|
||||||
Surf.RemoveTriangle( it->first) ;
|
Surf.RemoveTriangle( it->first) ;
|
||||||
@@ -564,14 +584,14 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
POLYLINEVECTOR vplPolyVec ;
|
POLYLINEVECTOR vplPolyVec ;
|
||||||
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
|
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
|
||||||
for ( int nLoop = 0 ; nLoop < int( vplPolyVec.size()) ; ++ nLoop) {
|
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][nLine]) ;
|
||||||
}
|
|
||||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][0]) ;
|
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][0]) ;
|
||||||
|
|
||||||
// Assegno ai loop trovati i rispettivi interni
|
// Assegno ai loop trovati i rispettivi interni
|
||||||
// Assumo che i loop interni a uno dei loop creati fino ad'ora siano tutti sullo stesso livello.
|
// Assumo che i loop interni a uno dei loop creati fino ad'ora siano tutti sullo stesso livello.
|
||||||
// Il caso generale si risolve con una struttura ad albero in cui il nodi corrispondente a un
|
// Il caso generale si risolve con una struttura ad albero in cui il nodi corrispondente a un
|
||||||
// loop è figlio del nodo corrispondente al loop che lo contiene.
|
// loop è figlio del nodo corrispondente al loop che lo contiene.
|
||||||
INTVECTOR vInnerLoop ;
|
INTVECTOR vInnerLoop ;
|
||||||
for ( int nCLI = 0 ; nCLI < int( cvClosedChain.size()) ; ++ nCLI) {
|
for ( int nCLI = 0 ; nCLI < int( cvClosedChain.size()) ; ++ nCLI) {
|
||||||
@@ -692,7 +712,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( vInnerLoop.size() == 0 || bDouble) {
|
if ( vInnerLoop.size() == 0 || bDouble) {
|
||||||
// Eseguo triangolazione
|
// Eseguo triangolazione
|
||||||
PNTVECTOR vPt ;
|
PNTVECTOR vPt ;
|
||||||
@@ -710,7 +730,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
|
||||||
if ( vbInOut[nLoop])
|
if ( vbInOut[nLoop])
|
||||||
Surf.m_vTria[nNewTriaNum].nTempPart = 1 ;
|
Surf.m_vTria[nNewTriaNum].nTempPart = 1 ;
|
||||||
else
|
else
|
||||||
Surf.m_vTria[nNewTriaNum].nTempPart = - 1 ;
|
Surf.m_vTria[nNewTriaNum].nTempPart = - 1 ;
|
||||||
bModif = true ;
|
bModif = true ;
|
||||||
@@ -719,33 +739,32 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// se ho più loop, essi descrivono un poligono di n-lati
|
||||||
POLYLINEVECTOR vPolygons ;
|
POLYLINEVECTOR vPolygons ;
|
||||||
vPolygons.emplace_back( vplPolyVec[nLoop]) ;
|
vPolygons.emplace_back( vplPolyVec[nLoop]) ;
|
||||||
for ( int nL = 0 ; nL < int( vInnerLoop.size()) ; ++ nL) {
|
for ( int nL = 0 ; nL < int( vInnerLoop.size()) ; ++ nL) {
|
||||||
|
// per ognuno di essi, ricavo la PolyLine dai punti
|
||||||
PolyLine CurLoop ;
|
PolyLine CurLoop ;
|
||||||
for ( int nV = 0 ; nV < int( cvClosedChain[vInnerLoop[nL]].size()) ; ++ nV) {
|
for ( int nV = 0 ; nV < int( cvClosedChain[vInnerLoop[nL]].size()) ; ++ nV)
|
||||||
CurLoop.AddUPoint( 0., cvClosedChain[vInnerLoop[nL]][nV].ptSt) ;
|
CurLoop.AddUPoint( 0., cvClosedChain[vInnerLoop[nL]][nV].ptSt) ;
|
||||||
}
|
|
||||||
CurLoop.AddUPoint( 0., cvClosedChain[vInnerLoop[nL]][0].ptSt) ;
|
CurLoop.AddUPoint( 0., cvClosedChain[vInnerLoop[nL]][0].ptSt) ;
|
||||||
vPolygons.emplace_back( CurLoop) ;
|
vPolygons.emplace_back( CurLoop) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// poligono
|
||||||
Polygon3d pgPol ;
|
Polygon3d pgPol ;
|
||||||
pgPol.FromPolyLine(vPolygons[1]) ;
|
pgPol.FromPolyLine( vPolygons[1]) ;
|
||||||
|
|
||||||
|
// controllo direzioni delle normali
|
||||||
bool bCodirectedNormals = trTria.GetN() * pgPol.GetVersN() > 0. ;
|
bool bCodirectedNormals = trTria.GetN() * pgPol.GetVersN() > 0. ;
|
||||||
if ( bCodirectedNormals) {
|
|
||||||
for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
|
||||||
vPolygons[nL].Invert() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aggiungo al loop esterno i punti dei loop interni che si trovano su di esso
|
// Aggiungo al loop esterno i punti dei loop interni che si trovano su di esso
|
||||||
PNTULIST& ExternLoopList = vPolygons[0].GetUPointList() ;
|
PNTULIST& ExternLoopList = vPolygons[0].GetUPointList() ;
|
||||||
// Ciclo sui segmenti del loop esterno
|
// Ciclo sui segmenti del loop esterno
|
||||||
auto itSt = ExternLoopList.begin() ;
|
auto itSt = ExternLoopList.begin() ;
|
||||||
auto itEn = itSt ;
|
auto itEn = itSt ;
|
||||||
++ itEn ;
|
++ itEn ;
|
||||||
for ( ; itSt != ExternLoopList.end() && itEn != ExternLoopList.end() ; ++ itSt, ++ itEn) {
|
for ( ; itSt != ExternLoopList.end() && itEn != ExternLoopList.end() ; ++ itSt, ++ itEn) {
|
||||||
// Estremi del segmento corrente del loop esterno e scorrispondente vettore
|
// Estremi del segmento corrente del loop esterno e scorrispondente vettore
|
||||||
Point3d ptSt = itSt->first ;
|
Point3d ptSt = itSt->first ;
|
||||||
@@ -761,7 +780,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Point3d ptInnPoint ;
|
Point3d ptInnPoint ;
|
||||||
bool bIsFirst = true ;
|
bool bIsFirst = true ;
|
||||||
bool bContinue = vPolygons[nInnPoly].GetFirstPoint( ptInnPoint) ;
|
bool bContinue = vPolygons[nInnPoly].GetFirstPoint( ptInnPoint) ;
|
||||||
while ( bContinue) {
|
while ( bContinue) {
|
||||||
DistPointLine DistCalculator( ptInnPoint, ptSt, ptEn) ;
|
DistPointLine DistCalculator( ptInnPoint, ptSt, ptEn) ;
|
||||||
double dDist ;
|
double dDist ;
|
||||||
DistCalculator.GetDist( dDist) ;
|
DistCalculator.GetDist( dDist) ;
|
||||||
@@ -788,13 +807,14 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
// Aggiungo i punti al loop esterno
|
// Aggiungo i punti al loop esterno
|
||||||
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) ; ++ nPi) {
|
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) ; ++ nPi) {
|
||||||
itSt = ExternLoopList.emplace( itEn, vPointWithOrder[nPi]) ;
|
itSt = ExternLoopList.emplace( itEn, vPointWithOrder[nPi]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PNTVECTOR vPt ;
|
PNTVECTOR vPt ;
|
||||||
INTVECTOR vTr ;
|
INTVECTOR vTr ;
|
||||||
if ( Triangulate().Make( vPolygons, vPt, vTr)) {
|
// classifico i loop e ricavo la triangolazione di essi mediante classificazione
|
||||||
// Inserisco i nuovi triangoli
|
if ( Triangulate().MakeAdvanced( vPolygons, vPt, vTr)) {
|
||||||
|
// Inserisco i nuovi triangoli
|
||||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
|
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
|
||||||
int nNewId[3] = { Surf.AddVertex( vPt[nNewTriaVertId[0]]),
|
int nNewId[3] = { Surf.AddVertex( vPt[nNewTriaVertId[0]]),
|
||||||
@@ -817,7 +837,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
// Divido i loop che si autointercettano
|
// Divido i loop che si autointercettano
|
||||||
int nInitialLoopNum = int( vPolygons.size()) ;
|
int nInitialLoopNum = int( vPolygons.size()) ;
|
||||||
for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) {
|
for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) {
|
||||||
// Lista dei punti della PolyLine Loop corrente
|
// Lista dei punti della PolyLine Loop corrente
|
||||||
PNTULIST& LoopPointList = vPolygons[nL].GetUPointList() ;
|
PNTULIST& LoopPointList = vPolygons[nL].GetUPointList() ;
|
||||||
// Ciclo sui segmenti
|
// Ciclo sui segmenti
|
||||||
auto itSt2 = LoopPointList.begin() ;
|
auto itSt2 = LoopPointList.begin() ;
|
||||||
@@ -928,26 +948,24 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
vPolygons.erase( vPolygons.begin()) ;
|
||||||
vPolygons[nL].Invert() ;
|
if ( Triangulate().MakeAdvanced( vPolygons, vPt, vTr)) {
|
||||||
if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) {
|
// Inserisco i nuovi triangoli
|
||||||
// Inserisco i nuovi triangoli
|
for (int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||||
for (int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
|
||||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
|
int nNewId[3] = { Surf.AddVertex( vPt[nNewTriaVertId[0]]),
|
||||||
int nNewId[3] = { Surf.AddVertex( vPt[nNewTriaVertId[0]]),
|
Surf.AddVertex( vPt[nNewTriaVertId[1]]),
|
||||||
Surf.AddVertex( vPt[nNewTriaVertId[1]]),
|
Surf.AddVertex( vPt[nNewTriaVertId[2]])} ;
|
||||||
Surf.AddVertex( vPt[nNewTriaVertId[2]])} ;
|
int nNewTriaNum = Surf.AddTriangle( nNewId, nOldTriaCol) ;
|
||||||
int nNewTriaNum = Surf.AddTriangle( nNewId, nOldTriaCol) ;
|
if ( IsValidSvt( nNewTriaNum)) {
|
||||||
if ( IsValidSvt( nNewTriaNum)) {
|
Surf.m_vTria[nNewTriaNum].nETempFlag[0] = 0 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[0] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
|
if ( bCodirectedNormals)
|
||||||
if ( bCodirectedNormals)
|
Surf.m_vTria[nNewTriaNum].nTempPart = 1 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nTempPart = 1 ;
|
else
|
||||||
else
|
Surf.m_vTria[nNewTriaNum].nTempPart = -1 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nTempPart = -1 ;
|
bModif = true ;
|
||||||
bModif = true ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1088,18 +1106,23 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
{
|
{
|
||||||
bool bModif = false ;
|
bool bModif = false ;
|
||||||
SurfTriMesh& SurfB = Other ;
|
SurfTriMesh& SurfB = Other ;
|
||||||
|
|
||||||
// Le superfici devono essere valide
|
// Le superfici devono essere valide
|
||||||
if ( m_nStatus != OK || ! SurfB.IsValid())
|
if ( m_nStatus != OK || ! SurfB.IsValid())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// Unordered map dei segmenti di intersezione
|
// Unordered map dei segmenti di intersezione
|
||||||
CHAINMAP LineMapA ;
|
CHAINMAP LineMapA ;
|
||||||
CHAINMAP LineMapB ;
|
CHAINMAP LineMapB ;
|
||||||
|
|
||||||
// Unordered map dei triangoli ambigui (intersezione edge-edge)
|
// Unordered map dei triangoli ambigui (intersezione edge-edge)
|
||||||
TRIA3DVECTORMAP AmbiguosA ;
|
TRIA3DVECTORMAP AmbiguosA ;
|
||||||
TRIA3DVECTORMAP AmbiguosB ;
|
TRIA3DVECTORMAP AmbiguosB ;
|
||||||
|
|
||||||
// Ciclo sui triangoli delle mesh
|
// Ciclo sui triangoli delle mesh
|
||||||
int nTriaNumA = GetTriangleSize() ;
|
int nTriaNumA = GetTriangleSize() ;
|
||||||
int nTriaNumB = SurfB.GetTriangleSize() ;
|
int nTriaNumB = SurfB.GetTriangleSize() ;
|
||||||
|
|
||||||
// Setto il triangolo come né fuori né dentro
|
// Setto il triangolo come né fuori né dentro
|
||||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||||
m_vTria[nTA].nTempPart = 0 ;
|
m_vTria[nTA].nTempPart = 0 ;
|
||||||
@@ -1113,55 +1136,58 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
SurfB.m_vTria[nTB].nETempFlag[1] = 0 ;
|
SurfB.m_vTria[nTB].nETempFlag[1] = 0 ;
|
||||||
SurfB.m_vTria[nTB].nETempFlag[2] = 0 ;
|
SurfB.m_vTria[nTB].nETempFlag[2] = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resetto e ricalcolo la HashGrid della superficie B
|
// Resetto e ricalcolo la HashGrid della superficie B
|
||||||
SurfB.ResetHashGrids3d() ;
|
SurfB.ResetHashGrids3d() ;
|
||||||
|
|
||||||
|
// Scorro i triangoli della superficie A
|
||||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||||
|
|
||||||
// Se il triangolo A non è valido, continuo
|
// Se il triangolo A non è valido, continuo
|
||||||
Triangle3d trTriaA ;
|
Triangle3d trTriaA ;
|
||||||
if ( ! GetTriangle( nTA, trTriaA) || ! trTriaA.Validate( true))
|
if ( ! GetTriangle( nTA, trTriaA) || ! trTriaA.Validate( true))
|
||||||
continue ;
|
continue ;
|
||||||
|
|
||||||
// Box del triangolo A
|
// Box del triangolo A
|
||||||
BBox3d b3dTriaA ;
|
BBox3d b3dTriaA ;
|
||||||
trTriaA.GetLocalBBox( b3dTriaA) ;
|
trTriaA.GetLocalBBox( b3dTriaA) ;
|
||||||
|
|
||||||
// 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 ;
|
INTVECTOR vNearTria ;
|
||||||
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
||||||
|
|
||||||
|
// I scorro tutti i triangoli di B che intersecano il box di A
|
||||||
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
||||||
|
|
||||||
// Se il triangolo B non è valido, continuo
|
// Se il triangolo B non è valido, continuo
|
||||||
Triangle3d trTriaB ;
|
Triangle3d trTriaB ;
|
||||||
if ( ! SurfB.GetTriangle( vNearTria[nTB], trTriaB) || ! trTriaB.Validate( true))
|
if ( ! SurfB.GetTriangle( vNearTria[nTB], trTriaB) || ! trTriaB.Validate( true))
|
||||||
continue ;
|
continue ;
|
||||||
|
|
||||||
// Interseco i triangoli
|
// Interseco i triangoli
|
||||||
Point3d ptSegSt, ptSegEn ;
|
Point3d ptSegSt, ptSegEn ;
|
||||||
TRIA3DVECTOR vTria ;
|
TRIA3DVECTOR vTria ;
|
||||||
int nIntType = IntersTriaTria( trTriaA, trTriaB, ptSegSt, ptSegEn, vTria) ;
|
int nIntType = IntersTriaTria( trTriaA, trTriaB, ptSegSt, ptSegEn, vTria) ;
|
||||||
if ( nIntType == ITTT_EDGE_EDGE_SEG ||
|
|
||||||
nIntType == ITTT_EDGE_INT ||
|
// se l'intersezione è identificabile con un segmento...
|
||||||
nIntType == ITTT_INT_EDGE ||
|
if ( nIntType == ITTT_EDGE_EDGE_SEG || nIntType == ITTT_EDGE_INT ||
|
||||||
nIntType == ITTT_INT_INT_SEG) {
|
nIntType == ITTT_INT_EDGE || nIntType == ITTT_INT_INT_SEG) {
|
||||||
// Assegno i dati di intersezione
|
|
||||||
|
// Assegno i dati di intersezione per la superficie A
|
||||||
IntSegment CurInters ;
|
IntSegment CurInters ;
|
||||||
if ( nIntType == ITTT_EDGE_EDGE_SEG || nIntType == ITTT_EDGE_INT ||
|
CurInters.ptSt = ptSegSt ; // punto iniziale del segmento
|
||||||
nIntType == ITTT_INT_EDGE || nIntType == ITTT_INT_INT_SEG) {
|
CurInters.ptEn = ptSegEn ; // punto finale del segmento
|
||||||
CurInters.ptSt = ptSegSt ;
|
CurInters.bDegenerate = false ; // segmento non degenere
|
||||||
CurInters.ptEn = ptSegEn ;
|
CurInters.vtOuter = trTriaB.GetN() ; // perpendicolare alla tangente ( oritentata )
|
||||||
CurInters.bDegenerate = false ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CurInters.ptSt = ptSegSt ;
|
|
||||||
CurInters.ptEn = ptSegSt ;
|
|
||||||
CurInters.bDegenerate = true ;
|
|
||||||
}
|
|
||||||
CurInters.vtOuter = trTriaB.GetN() ;
|
|
||||||
CurInters.vtOuter -= ( ( CurInters.vtOuter * trTriaA.GetN()) * trTriaA.GetN()) ;
|
CurInters.vtOuter -= ( ( CurInters.vtOuter * trTriaA.GetN()) * trTriaA.GetN()) ;
|
||||||
CurInters.vtOuter.Normalize() ;
|
CurInters.vtOuter.Normalize() ;
|
||||||
// Salvo intersezione per superficie A
|
// Salvo intersezione per superficie A
|
||||||
bool bIntOnEndgeA = false ;
|
bool bIntOnEndgeA = false ;
|
||||||
if ( nIntType != ITTT_EDGE_EDGE_SEG && nIntType != ITTT_EDGE_INT) {
|
if ( nIntType != ITTT_EDGE_EDGE_SEG && nIntType != ITTT_EDGE_INT) {
|
||||||
|
// controllo se tale segmento non è già contenuto
|
||||||
auto itA = LineMapA.find( nTA) ;
|
auto itA = LineMapA.find( nTA) ;
|
||||||
if ( itA != LineMapA.end()) {
|
if ( itA != LineMapA.end())
|
||||||
itA->second.emplace_back( CurInters) ;
|
itA->second.emplace_back( CurInters) ;
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
Chain chTemp ;
|
Chain chTemp ;
|
||||||
chTemp.emplace_back( CurInters) ;
|
chTemp.emplace_back( CurInters) ;
|
||||||
@@ -1171,6 +1197,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
else
|
else
|
||||||
bIntOnEndgeA = true ;
|
bIntOnEndgeA = true ;
|
||||||
|
|
||||||
|
// Inverto i dati del segmento per intersezione con superficie B
|
||||||
swap( CurInters.ptSt, CurInters.ptEn) ;
|
swap( CurInters.ptSt, CurInters.ptEn) ;
|
||||||
CurInters.vtOuter = trTriaA.GetN() ;
|
CurInters.vtOuter = trTriaA.GetN() ;
|
||||||
CurInters.vtOuter -= ( ( CurInters.vtOuter * trTriaB.GetN()) * trTriaB.GetN()) ;
|
CurInters.vtOuter -= ( ( CurInters.vtOuter * trTriaB.GetN()) * trTriaB.GetN()) ;
|
||||||
@@ -1179,10 +1206,10 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
// Salvo intersezione per superficie B
|
// Salvo intersezione per superficie B
|
||||||
bool bIntOnEndgeB = false ;
|
bool bIntOnEndgeB = false ;
|
||||||
if ( nIntType != ITTT_EDGE_EDGE_SEG && nIntType != ITTT_INT_EDGE) {
|
if ( nIntType != ITTT_EDGE_EDGE_SEG && nIntType != ITTT_INT_EDGE) {
|
||||||
|
// controllo se tale segmento non è già contenuto
|
||||||
auto itB = LineMapB.find( vNearTria[nTB]) ;
|
auto itB = LineMapB.find( vNearTria[nTB]) ;
|
||||||
if ( itB != LineMapB.end()) {
|
if ( itB != LineMapB.end())
|
||||||
itB->second.emplace_back( CurInters) ;
|
itB->second.emplace_back( CurInters) ;
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
Chain chTemp ;
|
Chain chTemp ;
|
||||||
chTemp.emplace_back( CurInters) ;
|
chTemp.emplace_back( CurInters) ;
|
||||||
@@ -1191,8 +1218,10 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
bIntOnEndgeB = true ;
|
bIntOnEndgeB = true ;
|
||||||
// Intersezione edge-interno
|
|
||||||
|
// caso di Intersezione edge-interno ( per superificie A con B)
|
||||||
if ( bIntOnEndgeA && ! bIntOnEndgeB) {
|
if ( bIntOnEndgeA && ! bIntOnEndgeB) {
|
||||||
|
// calcolo la massima distanza e il tratto ad essa associato
|
||||||
double dMaxDist = 0. ;
|
double dMaxDist = 0. ;
|
||||||
int nSegMaxDist = - 1 ;
|
int nSegMaxDist = - 1 ;
|
||||||
for ( int nVA = 0 ; nVA < 3 ; ++ nVA) {
|
for ( int nVA = 0 ; nVA < 3 ; ++ nVA) {
|
||||||
@@ -1203,7 +1232,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( nSegMaxDist >= 0) {
|
if ( nSegMaxDist >= 0) {
|
||||||
// Cerco qual'è il segmento di contatto per dichiararlo come invalicabile
|
// Cerco qual è il segmento di contatto per dichiararlo come invalicabile
|
||||||
int nVA ;
|
int nVA ;
|
||||||
for ( nVA = 0 ; nVA < 3 ; ++ nVA) {
|
for ( nVA = 0 ; nVA < 3 ; ++ nVA) {
|
||||||
if ( abs( ( trTriaA.GetP( nVA) - trTriaB.GetP( 0)) * trTriaB.GetN()) < EPS_SMALL &&
|
if ( abs( ( trTriaA.GetP( nVA) - trTriaB.GetP( 0)) * trTriaB.GetN()) < EPS_SMALL &&
|
||||||
@@ -1215,8 +1244,9 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
m_vTria[nTA].nETempFlag[nVA] = m_vTria[nTA].nTempPart ;
|
m_vTria[nTA].nETempFlag[nVA] = m_vTria[nTA].nTempPart ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Intersezione interno-edge
|
// caso di Intersezione interno-edge ( per superficie A con B)
|
||||||
else if ( ! bIntOnEndgeA && bIntOnEndgeB) {
|
else if ( ! bIntOnEndgeA && bIntOnEndgeB) {
|
||||||
|
// calcolo la massima distanza e il tratto ad essa associato
|
||||||
double dMaxDist = 0. ;
|
double dMaxDist = 0. ;
|
||||||
int nSegMaxDist = - 1 ;
|
int nSegMaxDist = - 1 ;
|
||||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||||
@@ -1227,7 +1257,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( nSegMaxDist >= 0) {
|
if ( nSegMaxDist >= 0) {
|
||||||
// Cerco qual'è il segmento di contatto per dichiararlo come invalicabile
|
// Cerco qual è il segmento di contatto per dichiararlo come invalicabile
|
||||||
int nVB ;
|
int nVB ;
|
||||||
for ( nVB = 0 ; nVB < 3 ; ++ nVB) {
|
for ( nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||||
if ( abs( ( trTriaB.GetP( nVB) - trTriaA.GetP(0)) * trTriaA.GetN()) < EPS_SMALL &&
|
if ( abs( ( trTriaB.GetP( nVB) - trTriaA.GetP(0)) * trTriaA.GetN()) < EPS_SMALL &&
|
||||||
@@ -1266,11 +1296,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ritriangolarizzo i triangoli delle superfici
|
// Ritriangolarizzo i triangoli delle superfici
|
||||||
RetriangulationForBooleanOperation( LineMapA, AmbiguosA, *this, bModif) ;
|
RetriangulationForBooleanOperation( LineMapA, AmbiguosA, *this, bModif) ;
|
||||||
RetriangulationForBooleanOperation( LineMapB, AmbiguosB, SurfB, bModif) ;
|
RetriangulationForBooleanOperation( LineMapB, AmbiguosB, SurfB, bModif) ;
|
||||||
|
|
||||||
// Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra.
|
// Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra.
|
||||||
// non mi basta fare un controllo sulle bbox perché non so come sono orientate le superfici e che potrebbero anche non essere chiuse
|
// non mi basta fare un controllo sulle bbox perché non so come sono orientate le superfici e che potrebbero anche non essere chiuse
|
||||||
bool bRetriangulated = true ;
|
bool bRetriangulated = true ;
|
||||||
@@ -1309,7 +1339,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) {
|
if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) {
|
||||||
if ( nInOutNum == 0)
|
if ( nInOutNum == 0)
|
||||||
nInOutNum = 1 ;
|
nInOutNum = 1 ;
|
||||||
else if (nInOutNum == -1) {
|
else if ( nInOutNum == -1) {
|
||||||
bSame = false ;
|
bSame = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -1317,7 +1347,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) {
|
else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) {
|
||||||
if ( nInOutNum == 0)
|
if ( nInOutNum == 0)
|
||||||
nInOutNum = -1 ;
|
nInOutNum = -1 ;
|
||||||
else if (nInOutNum == 1) {
|
else if ( nInOutNum == 1) {
|
||||||
bSame = false ;
|
bSame = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -1325,23 +1355,23 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
// se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino
|
// se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino
|
||||||
// e ricalcolo l'informazione che mi dà la sua normale
|
// e ricalcolo l'informazione che mi dà la sua normale
|
||||||
if ( ! bSame ) {
|
if ( ! bSame) {
|
||||||
Point3d ptBar_tot ;
|
Point3d ptBar_tot ;
|
||||||
for (int nTriaNum : vnTriaNum) {
|
for (int nTriaNum : vnTriaNum) {
|
||||||
SurfB.GetTriangle( nTriaNum, trTriaB) ;
|
SurfB.GetTriangle( nTriaNum, trTriaB) ;
|
||||||
ptBar_tot += trTriaB.GetCentroid();
|
ptBar_tot += trTriaB.GetCentroid();
|
||||||
}
|
}
|
||||||
ptBar_tot /= (int)vnTriaNum.size() ;
|
ptBar_tot /= int( vnTriaNum.size()) ;
|
||||||
for (int nTriaNum : vnTriaNum) {
|
for ( int nTriaNum : vnTriaNum) {
|
||||||
SurfB.GetTriangle( nTriaNum, trTriaB) ;
|
SurfB.GetTriangle( nTriaNum, trTriaB) ;
|
||||||
Point3d ptInters1, ptInters2 ;
|
Point3d ptInters1, ptInters2 ;
|
||||||
int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaB, ptInters1, ptInters2, true) ;
|
int nInters = IntersLineTria( ptFirstV, ptBar_tot, trTriaB, ptInters1, ptInters2, true) ;
|
||||||
if (nInters == ILTT_NO)
|
if ( nInters == ILTT_NO)
|
||||||
continue ;
|
continue ;
|
||||||
else if ( nInters == ILTT_IN ) {
|
else if ( nInters == ILTT_IN) {
|
||||||
if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL)
|
if ( ( ptFirstV - trTriaB.GetP( 0)) * trTriaB.GetN() < - EPS_SMALL)
|
||||||
nInOutNum = 1 ;
|
nInOutNum = 1 ;
|
||||||
else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL)
|
else if ( ( ptFirstV - trTriaB.GetP( 0)) * trTriaB.GetN() > EPS_SMALL)
|
||||||
nInOutNum = -1 ;
|
nInOutNum = -1 ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -1355,9 +1385,10 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
++ nVertNum ;
|
++ nVertNum ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
|
||||||
|
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA)
|
||||||
m_vTria[nTA].nTempPart = nInOutNum ;
|
m_vTria[nTA].nTempPart = nInOutNum ;
|
||||||
}
|
|
||||||
nVertNum = 0 ;
|
nVertNum = 0 ;
|
||||||
nCurVert = SurfB.GetFirstVertex( ptFirstV) ;
|
nCurVert = SurfB.GetFirstVertex( ptFirstV) ;
|
||||||
nInOutNum = 0 ;
|
nInOutNum = 0 ;
|
||||||
@@ -1374,7 +1405,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
DistCalculator.GetDist( dDist) ;
|
DistCalculator.GetDist( dDist) ;
|
||||||
// potrei trovare più triangolo equidistanti, li salvo tutti
|
// potrei trovare più triangolo equidistanti, li salvo tutti
|
||||||
if ( DistPointTriangle( ptFirstV, trTriaA).GetDist( dDist)) {
|
if ( DistPointTriangle( ptFirstV, trTriaA).GetDist( dDist)) {
|
||||||
if ( abs(dDist - dMinDist) < EPS_SMALL)
|
if ( abs( dDist - dMinDist) < EPS_SMALL)
|
||||||
vnTriaNum.push_back( nTA) ;
|
vnTriaNum.push_back( nTA) ;
|
||||||
else if ( dDist < dMinDist){
|
else if ( dDist < dMinDist){
|
||||||
vnTriaNum.clear() ;
|
vnTriaNum.clear() ;
|
||||||
@@ -1392,7 +1423,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) {
|
if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) {
|
||||||
if ( nInOutNum == 0)
|
if ( nInOutNum == 0)
|
||||||
nInOutNum = 1 ;
|
nInOutNum = 1 ;
|
||||||
else if (nInOutNum == -1) {
|
else if ( nInOutNum == -1) {
|
||||||
bSame = false ;
|
bSame = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -1400,7 +1431,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) {
|
else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) {
|
||||||
if ( nInOutNum == 0)
|
if ( nInOutNum == 0)
|
||||||
nInOutNum = -1 ;
|
nInOutNum = -1 ;
|
||||||
else if (nInOutNum == 1) {
|
else if ( nInOutNum == 1) {
|
||||||
bSame = false ;
|
bSame = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -1408,23 +1439,23 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
// se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino
|
// se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino
|
||||||
// e ricalcolo l'informazione che mi dà la sua normale
|
// e ricalcolo l'informazione che mi dà la sua normale
|
||||||
if ( ! bSame ) {
|
if ( ! bSame) {
|
||||||
Point3d ptBar_tot ;
|
Point3d ptBar_tot ;
|
||||||
for (int nTriaNum : vnTriaNum) {
|
for ( int nTriaNum : vnTriaNum) {
|
||||||
GetTriangle( nTriaNum, trTriaA) ;
|
GetTriangle( nTriaNum, trTriaA) ;
|
||||||
ptBar_tot += trTriaA.GetCentroid();
|
ptBar_tot += trTriaA.GetCentroid();
|
||||||
}
|
}
|
||||||
ptBar_tot /= (int)vnTriaNum.size() ;
|
ptBar_tot /= int( vnTriaNum.size()) ;
|
||||||
for (int nTriaNum : vnTriaNum) {
|
for ( int nTriaNum : vnTriaNum) {
|
||||||
GetTriangle( nTriaNum, trTriaA) ;
|
GetTriangle( nTriaNum, trTriaA) ;
|
||||||
Point3d ptInters1, ptInters2 ;
|
Point3d ptInters1, ptInters2 ;
|
||||||
int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaA, ptInters1, ptInters2, true) ;
|
int nInters = IntersLineTria( ptFirstV, ptBar_tot, trTriaA, ptInters1, ptInters2, true) ;
|
||||||
if (nInters == ILTT_NO)
|
if ( nInters == ILTT_NO)
|
||||||
continue ;
|
continue ;
|
||||||
else if ( nInters == ILTT_IN ) {
|
else if ( nInters == ILTT_IN) {
|
||||||
if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL)
|
if ( ( ptFirstV - trTriaA.GetP( 0)) * trTriaA.GetN() < - EPS_SMALL)
|
||||||
nInOutNum = 1 ;
|
nInOutNum = 1 ;
|
||||||
else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL)
|
else if ( ( ptFirstV - trTriaA.GetP( 0)) * trTriaA.GetN() > EPS_SMALL)
|
||||||
nInOutNum = -1 ;
|
nInOutNum = -1 ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -1438,9 +1469,8 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
++ nVertNum ;
|
++ nVertNum ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) {
|
for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB)
|
||||||
SurfB.m_vTria[nTB].nTempPart = nInOutNum ;
|
SurfB.m_vTria[nTB].nTempPart = nInOutNum ;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se c'è stata una ritriangolazione di almeno un triangolo, NON siamo nel caso di tutto dentro o tutto fuori.
|
// Se c'è stata una ritriangolazione di almeno un triangolo, NON siamo nel caso di tutto dentro o tutto fuori.
|
||||||
@@ -1449,11 +1479,12 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
AmbiguosTriangleManager( AmbiguosA, *this) ;
|
AmbiguosTriangleManager( AmbiguosA, *this) ;
|
||||||
AmbiguosTriangleManager( AmbiguosB, SurfB) ;
|
AmbiguosTriangleManager( AmbiguosB, SurfB) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bContinue = true ;
|
bool bContinue = true ;
|
||||||
// Se avvenuta modifica, aggiorno tutto
|
// Se avvenuta modifica, aggiorno tutto
|
||||||
if ( bModif)
|
if ( bModif)
|
||||||
bContinue = ( AdjustVertices() && DoCompacting() && SurfB.AdjustVertices() && SurfB.DoCompacting()) ;
|
bContinue = ( AdjustVertices() && DoCompacting() && SurfB.AdjustVertices() && SurfB.DoCompacting()) ;
|
||||||
|
|
||||||
// Triangoli sovrapposti
|
// Triangoli sovrapposti
|
||||||
if ( bContinue) {
|
if ( bContinue) {
|
||||||
int nTriaNum2A = GetTriangleSize() ;
|
int nTriaNum2A = GetTriangleSize() ;
|
||||||
@@ -1491,7 +1522,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,48 +1651,83 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Surf A è la superficie attuale ( this), SurfB è l'altra
|
||||||
SurfTriMesh SurfB ;
|
SurfTriMesh SurfB ;
|
||||||
SurfB.CopyFrom( &Other) ;
|
SurfB.CopyFrom( &Other) ;
|
||||||
|
|
||||||
|
// scalo la superficie
|
||||||
Frame3d frScalingRef ;
|
Frame3d frScalingRef ;
|
||||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||||
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||||
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||||
|
|
||||||
|
// ritriangolo le due superfici mediante ogni intersezione Triangolo-Triangolo
|
||||||
IntersectTriMeshTriangle( SurfB) ;
|
IntersectTriMeshTriangle( SurfB) ;
|
||||||
|
|
||||||
|
// assegno un medesimo indice ai triangoli che non interferiscono con altri
|
||||||
IdentifyParts() ;
|
IdentifyParts() ;
|
||||||
SurfB.IdentifyParts() ;
|
SurfB.IdentifyParts() ;
|
||||||
|
|
||||||
|
// rimozione dei triangoli di A con proprietà -1 e -2
|
||||||
int nTriaNumA = GetTriangleSize() ;
|
int nTriaNumA = GetTriangleSize() ;
|
||||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||||
if ( m_vTria[nTA].nTempPart == - 1 || m_vTria[nTA].nTempPart == - 2)
|
if ( m_vTria[nTA].nTempPart == - 1 || m_vTria[nTA].nTempPart == - 2)
|
||||||
RemoveTriangle( nTA) ;
|
RemoveTriangle( nTA) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aggiunta dei triangoli di B con proprietà +1
|
||||||
int nPrevMaxTFlag = m_nMaxTFlag ;
|
int nPrevMaxTFlag = m_nMaxTFlag ;
|
||||||
int nTriaNumB = SurfB.GetTriangleSize() ;
|
int nTriaNumB = SurfB.GetTriangleSize() ;
|
||||||
for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) {
|
for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) {
|
||||||
if ( SurfB.m_vTria[nTB].nTempPart == 1) {
|
if ( SurfB.m_vTria[nTB].nTempPart == 1) {
|
||||||
int nNewVert[3] ;
|
int nNewVert[3] ;
|
||||||
for ( int nV = 0 ; nV < 3 ; ++ nV) {
|
for ( int nV = 0 ; nV < 3 ; ++ nV)
|
||||||
nNewVert[nV] = AddVertex( SurfB.m_vVert[SurfB.m_vTria[nTB].nIdVert[nV]].ptP) ;
|
nNewVert[nV] = AddVertex( SurfB.m_vVert[SurfB.m_vTria[nTB].nIdVert[nV]].ptP) ;
|
||||||
}
|
|
||||||
if ( nPrevMaxTFlag == m_nMaxTFlag)
|
if ( nPrevMaxTFlag == m_nMaxTFlag)
|
||||||
++ m_nMaxTFlag ;
|
++ m_nMaxTFlag ;
|
||||||
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sistemazioni varie
|
||||||
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
||||||
|
|
||||||
bool bModified = false ;
|
bool bModified = false ;
|
||||||
bOk = bOk && RemoveDoubleTriangles( bModified) ;
|
bOk = bOk && RemoveDoubleTriangles( bModified) ;
|
||||||
if ( bModified)
|
if ( bModified)
|
||||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||||
|
|
||||||
bOk = bOk && RemoveTJunctions( bModified) ;
|
bOk = bOk && RemoveTJunctions( bModified) ;
|
||||||
if ( bModified)
|
if ( bModified)
|
||||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||||
|
|
||||||
|
// rimuovo tutte le parti esterne all'intersezione
|
||||||
|
int nParts = GetPartCount() ;
|
||||||
|
if ( nParts > 1) {
|
||||||
|
for ( int i = 0 ; i < nParts ; ++ i) {
|
||||||
|
// recupero i triangoli della stessa Part
|
||||||
|
INTVECTOR vTriaPart ;
|
||||||
|
for ( int j = 0 ; j < int( m_vTria.size()) ; ++ j)
|
||||||
|
if ( m_vTria[j].nPart == i)
|
||||||
|
vTriaPart.push_back( j) ;
|
||||||
|
// controllo se il loro box interferisce con il box della superficie B
|
||||||
|
bool bErasePart = true ;
|
||||||
|
for ( int j = 0 ; j < int( vTriaPart.size()) && bErasePart ; ++ j) {
|
||||||
|
// Se il triangolo A non è valido, continuo
|
||||||
|
Triangle3d Tria ;
|
||||||
|
if ( ! GetTriangle( j, Tria) || ! Tria.Validate( true))
|
||||||
|
continue ;
|
||||||
|
// Box del triangolo A
|
||||||
|
BBox3d b3dTriaA ; Tria.GetLocalBBox( b3dTriaA) ;
|
||||||
|
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||||
|
INTVECTOR vNearTria ; SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
||||||
|
bErasePart = int( vNearTria.size() == 0) ;
|
||||||
|
}
|
||||||
|
if ( bErasePart)
|
||||||
|
RemovePart( i) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scalo alle dimensioni originali
|
||||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||||
|
|
||||||
if ( ! SimplifyFacets())
|
if ( ! SimplifyFacets())
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ SurfTriMesh::AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain)
|
|||||||
if ( AreSamePointApprox( OrigChain[nLastOrig], ChainToAdd[0].ptSt)) {
|
if ( AreSamePointApprox( OrigChain[nLastOrig], ChainToAdd[0].ptSt)) {
|
||||||
for ( int nPt = 1 ; nPt <= nLastToAdd ; ++ nPt) {
|
for ( int nPt = 1 ; nPt <= nLastToAdd ; ++ nPt) {
|
||||||
if ( nPt == nLastToAdd) {
|
if ( nPt == nLastToAdd) {
|
||||||
if ( ! AreSamePointApprox(OrigChain[0], ChainToAdd[nPt].ptSt))
|
if ( ! AreSamePointApprox( OrigChain[0], ChainToAdd[nPt].ptSt))
|
||||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||||
}
|
}
|
||||||
else if ( nPt == 1) {
|
else if ( nPt == 1) {
|
||||||
|
|||||||
@@ -1805,8 +1805,9 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
|
|||||||
if ( ! nCells.empty())
|
if ( ! nCells.empty())
|
||||||
nId = nCells.back() ;
|
nId = nCells.back() ;
|
||||||
else
|
else
|
||||||
// il loop è risultato fuori dallo spazio parametrico
|
// il loop è risultato fuori dallo spazio parametrico // può capitare se ho una superficie trimmata con più chunk con bbox separate.
|
||||||
return false ;
|
// ma potrebbe anche essere indicatore di un errore
|
||||||
|
continue ;
|
||||||
int nFirstCell = nId ;
|
int nFirstCell = nId ;
|
||||||
// trovo quali punti della polyline sono nella cella e l'intersezione
|
// trovo quali punti della polyline sono nella cella e l'intersezione
|
||||||
PNTVECTOR vptInters ;
|
PNTVECTOR vptInters ;
|
||||||
@@ -2077,14 +2078,14 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
|
|||||||
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
|
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
|
||||||
// -1 se la curva è sempre dentro la cella
|
// -1 se la curva è sempre dentro la cella
|
||||||
Point3d ptInters ;
|
Point3d ptInters ;
|
||||||
int nEdge2 ;
|
//int nEdge2 ;
|
||||||
if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) {
|
if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) {
|
||||||
nEdge = 0 ;
|
//nEdge = 0 ;
|
||||||
// lato sopra
|
// lato sopra
|
||||||
clEdge.Set( ptTR, ptTl) ;
|
clEdge.Set( ptTR, ptTl) ;
|
||||||
// lato sinistro
|
// lato sinistro
|
||||||
if ( ptEnd.x < ptBL.x) {
|
if ( ptEnd.x < ptBL.x) {
|
||||||
nEdge2 = 1 ;
|
//nEdge2 = 1 ;
|
||||||
clEdge2.Set( ptTl, ptBL) ;
|
clEdge2.Set( ptTl, ptBL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2094,7 +2095,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
|
|||||||
clEdge.Set( ptTl, ptBL) ;
|
clEdge.Set( ptTl, ptBL) ;
|
||||||
// lato sotto
|
// lato sotto
|
||||||
if ( ptEnd.y < ptBL.y) {
|
if ( ptEnd.y < ptBL.y) {
|
||||||
nEdge2 = 2 ;
|
//nEdge2 = 2 ;
|
||||||
clEdge2.Set( ptBL, ptBr) ;
|
clEdge2.Set( ptBL, ptBr) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2104,7 +2105,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
|
|||||||
clEdge.Set( ptBL, ptBr) ;
|
clEdge.Set( ptBL, ptBr) ;
|
||||||
// lato destro
|
// lato destro
|
||||||
if ( ptEnd.x > ptTR.x) {
|
if ( ptEnd.x > ptTR.x) {
|
||||||
nEdge2 = 3 ;
|
//nEdge2 = 3 ;
|
||||||
clEdge2.Set( ptBr, ptTR) ;
|
clEdge2.Set( ptBr, ptTR) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2114,7 +2115,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
|
|||||||
clEdge.Set( ptBr, ptTR) ;
|
clEdge.Set( ptBr, ptTR) ;
|
||||||
// lato sopra
|
// lato sopra
|
||||||
if ( ptEnd.y > ptTR.y) {
|
if ( ptEnd.y > ptTR.y) {
|
||||||
nEdge2 = 0 ;
|
//nEdge2 = 0 ;
|
||||||
clEdge2.Set( ptTR, ptTl) ;
|
clEdge2.Set( ptTR, ptTl) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2917,12 +2918,12 @@ Tree::CheckIfBefore( const PolyLine& pl, int nEdge) const
|
|||||||
bool
|
bool
|
||||||
Tree::CheckIfBefore( const Inters& inA) const
|
Tree::CheckIfBefore( const Inters& inA) const
|
||||||
{
|
{
|
||||||
// questa funzione è pensata in riferimento al lato 3, quindi nessuno dei due punti può stare su Edge = 3
|
// questa funzione è pensata in riferimento al lato 3, quindi nessuno dei due punti può stare su Edge = 3 ( funzione usata per definire RightEdgeIn)
|
||||||
// controllo se l'ingresso è prima dell'uscita
|
// controllo se l'ingresso è prima dell'uscita
|
||||||
int nEdge1 = inA.nIn ;
|
int nEdge1 = inA.nIn ;
|
||||||
int nEdge2 = inA.nOut ;
|
int nEdge2 = inA.nOut ;
|
||||||
if ( nEdge1 == -1)
|
if ( nEdge1 == -1)
|
||||||
return false ;
|
return false ; // questo return è usato in modo improprio perché non fa capire che l'intersezione analizzata non era corretta
|
||||||
PolyLine pl ;
|
PolyLine pl ;
|
||||||
pl.AddUPoint( 0, inA.vpt.back()) ;
|
pl.AddUPoint( 0, inA.vpt.back()) ;
|
||||||
pl.AddUPoint( 1, inA.vpt[0]) ;
|
pl.AddUPoint( 1, inA.vpt[0]) ;
|
||||||
|
|||||||
@@ -173,8 +173,8 @@ class Tree
|
|||||||
bool GetPolygons( POLYLINEMATRIX& vPolygons) ;
|
bool GetPolygons( POLYLINEMATRIX& vPolygons) ;
|
||||||
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
|
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
|
||||||
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
|
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
|
||||||
bool GetLeaves ( std::vector<Cell>& vLeaves) const ;
|
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
|
||||||
void SetTestMode( void) { m_bTestMode = true ;} ;
|
void SetTestMode( void) { m_bTestMode = true ;} ; // attivando la test mode, per la costruzione dell'albero viene usata la funzione BuiltTree_test e viene corretta di conseguenza la FindCell
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
|
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
|
||||||
@@ -193,27 +193,27 @@ class Tree
|
|||||||
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
|
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
|
||||||
bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim
|
bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim
|
||||||
// resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto
|
// resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto
|
||||||
bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) ;
|
bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni.
|
||||||
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ;
|
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella
|
||||||
bool CheckIfBefore( const PolyLine& pl, int nEdge) const ;
|
bool CheckIfBefore( const PolyLine& pl, int nEdge) const ; // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario
|
||||||
bool CheckIfBefore( const Inters& inA) const ;
|
bool CheckIfBefore( const Inters& inA) const ; // controlla se l'ingresso è prima dell'uscita in senso antiorario a partire da ptTR.
|
||||||
bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3
|
bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // verifico quale punto viene prima tra pt1 e pt2 a partire da ptTR girando in senso CCW (punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3)
|
||||||
bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // entrambi i punti sullo stesso lato, nEdge. nEdge2 serve come backup, in caso nEdge sia un vertice.
|
bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // sul lato nEdge controllo se ptP1 viene prima di ptP2.
|
||||||
bool AreSameEdge( int nEdge1, int nEdge2) const ;
|
bool AreSameEdge( int nEdge1, int nEdge2) const ; // indica se i due edge sono lo stesso. Un vertice adiacente ad un edge viene considerato uguale a questo edge
|
||||||
bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const ;
|
bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto
|
||||||
bool SetRightEdgeIn( int nId) ;
|
bool SetRightEdgeIn( int nId) ; // categorizza la cella in base all'edge destro per poter poi definire m_nFlag
|
||||||
bool CategorizeCell( int nId) ;
|
bool CategorizeCell( int nId) ; // categorizza la cella in base al flag m_nFlag (dentro, fuori, intersecata)
|
||||||
bool CheckIfBetween( const Inters& inA, const Inters& inB) const ;
|
bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; // / controllo se inB è compreso tra l'end e lo start di inA (in senso CCW)
|
||||||
bool OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const ;
|
bool OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const ; // indica a quale edge o vertice il punto è vicino entro EPS_SMALL
|
||||||
|
|
||||||
private :
|
private :
|
||||||
const SurfBezier* m_pSrfBz ; // superficie di bezier
|
const SurfBezier* m_pSrfBz ; // superficie di bezier
|
||||||
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00
|
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00
|
||||||
bool m_bTrimmed ; // superficie trimmata
|
bool m_bTrimmed ; // superficie trimmata
|
||||||
INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk
|
INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk
|
||||||
std::map<int,int> m_mChunk ;
|
std::map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
|
||||||
ICURVEPOVECTOR m_vLoop ; // curve di loop
|
ICURVEPOVECTOR m_vLoop ; // curve di loop
|
||||||
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ;
|
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop
|
||||||
bool m_bBilinear ; // superficie bilineare
|
bool m_bBilinear ; // superficie bilineare
|
||||||
bool m_bMulti ; // superficie multi-patch
|
bool m_bMulti ; // superficie multi-patch
|
||||||
bool m_bClosedU ; // superficie chiusa lungo il parametro U
|
bool m_bClosedU ; // superficie chiusa lungo il parametro U
|
||||||
@@ -221,8 +221,8 @@ class Tree
|
|||||||
bool m_bSplitPatches ; // flag che indica se le patches sono state divise prima della creazione dell'albero
|
bool m_bSplitPatches ; // flag che indica se le patches sono state divise prima della creazione dell'albero
|
||||||
int m_nDegU ; // grado della superficie nel parametro U
|
int m_nDegU ; // grado della superficie nel parametro U
|
||||||
int m_nDegV ; // grado della superficie nel parametro V
|
int m_nDegV ; // grado della superficie nel parametro V
|
||||||
int m_nSpanU ;
|
int m_nSpanU ; // numero di span lungo il parametro U
|
||||||
int m_nSpanV ;
|
int m_nSpanV ; // numero di span lungo il parametro V
|
||||||
POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree
|
POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree
|
||||||
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 � puntatore Null e -1 � root
|
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 � puntatore Null e -1 � root
|
||||||
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id � lo stesso che la cella ha in m_mTree
|
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id � lo stesso che la cella ha in m_mTree
|
||||||
|
|||||||
+138
@@ -21,6 +21,8 @@
|
|||||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
|
#include "CurveComposite.h"
|
||||||
|
#include "IntersCrvCompoCrvCompo.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
@@ -218,6 +220,142 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
Triangulate::MakeAdvanced( const POLYLINEVECTOR& vPLORIG, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||||
|
{
|
||||||
|
vPt.clear() ;
|
||||||
|
vTr.clear() ;
|
||||||
|
// se non ho PolyLine, allora non faccio nulla
|
||||||
|
if ( int( vPLORIG.size()) == 0)
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
// copio il vettore di PolyLine
|
||||||
|
POLYLINEVECTOR vPL ;
|
||||||
|
for ( int i = 0 ; i < int( vPLORIG.size()) ; ++ i)
|
||||||
|
vPL.push_back( vPLORIG[i]) ;
|
||||||
|
|
||||||
|
typedef std::pair<int,double> INDAREA ;
|
||||||
|
std::vector<INDAREA> m_vArea ;
|
||||||
|
// calcolo piano medio e area delle curve
|
||||||
|
m_vArea.reserve( vPL.size()) ;
|
||||||
|
Vector3d vtN0 ;
|
||||||
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
|
// calcolo piano medio e area
|
||||||
|
Plane3d plPlane ;
|
||||||
|
double dArea ;
|
||||||
|
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
||||||
|
return false ;
|
||||||
|
// imposto la normale del primo contorno come riferimento
|
||||||
|
if ( i == 0)
|
||||||
|
vtN0 = plPlane.GetVersN() ;
|
||||||
|
// verifico che le normali siano molto vicine
|
||||||
|
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN0))
|
||||||
|
return false ;
|
||||||
|
// assegno il segno all'area secondo il verso della normale
|
||||||
|
if ( ( plPlane.GetVersN() * vtN0) > 0)
|
||||||
|
m_vArea.emplace_back( i, dArea) ;
|
||||||
|
else
|
||||||
|
m_vArea.emplace_back( i, - dArea) ;
|
||||||
|
}
|
||||||
|
// ordino in senso decrescente sull'area
|
||||||
|
sort( m_vArea.begin(), m_vArea.end(),
|
||||||
|
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
||||||
|
|
||||||
|
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
||||||
|
Frame3d frRef ; frRef.Set( ORIG, vtN0) ;
|
||||||
|
if ( ! frRef.IsValid())
|
||||||
|
return false ;
|
||||||
|
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
||||||
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
|
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
||||||
|
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
||||||
|
vCrvCompo[i]->ToLoc( frRef) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
|
||||||
|
// successive i loop interni
|
||||||
|
INTMATRIX vnPLIndMat ;
|
||||||
|
|
||||||
|
// aggiungo le diverse curve
|
||||||
|
bool bFirstCrv ;
|
||||||
|
Plane3d plExtLoop ;
|
||||||
|
double dAreaExtLoop = 0. ;
|
||||||
|
do {
|
||||||
|
bFirstCrv = true ;
|
||||||
|
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||||
|
// recupero indice di percorso e verifico sia valido
|
||||||
|
int j = m_vArea[i].first ;
|
||||||
|
if ( j < 0)
|
||||||
|
continue ;
|
||||||
|
// lo inserisco come esterno...
|
||||||
|
if ( bFirstCrv) {
|
||||||
|
vnPLIndMat.push_back({ j}) ;
|
||||||
|
m_vArea[i].first = -1 ;
|
||||||
|
dAreaExtLoop = m_vArea[i].second ;
|
||||||
|
// inverto se necessario
|
||||||
|
if ( m_vArea[i].second < EPS_SMALL) {
|
||||||
|
vPL[j].Invert() ;
|
||||||
|
vCrvCompo[j]->Invert() ;
|
||||||
|
dAreaExtLoop *= -1 ;
|
||||||
|
}
|
||||||
|
bFirstCrv = false ;
|
||||||
|
}
|
||||||
|
// ... altrimenti verifico se il loop è interno o no
|
||||||
|
else {
|
||||||
|
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
||||||
|
// esterno a tutti i loop già inseriti nella riga attuale.
|
||||||
|
// verifica rispetto loop esterno
|
||||||
|
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
||||||
|
CRVCVECTOR ccClass ;
|
||||||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
|
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
||||||
|
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||||
|
continue ;
|
||||||
|
// verifica rispetto ai loop interni
|
||||||
|
bool bOk = true ;
|
||||||
|
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
||||||
|
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
||||||
|
CRVCVECTOR ccClass2 ;
|
||||||
|
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
|
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
||||||
|
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||||
|
bOk = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bOk) {
|
||||||
|
// inserisco nella matrice
|
||||||
|
vnPLIndMat.back().push_back( j) ;
|
||||||
|
m_vArea[i].first = -1 ;
|
||||||
|
// inverto se necessario
|
||||||
|
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
|
||||||
|
vPL[j].Invert() ;
|
||||||
|
vCrvCompo[j]->Invert() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ( ! bFirstCrv) ;
|
||||||
|
|
||||||
|
// chiamo la Triangolazione per ogni riga della matrice ( quindi su ogni "Chunk")
|
||||||
|
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++ i) {
|
||||||
|
PNTVECTOR vPt_tmp ; INTVECTOR vTr_tmp ;
|
||||||
|
POLYLINEVECTOR vPL_tmp ;
|
||||||
|
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++ j)
|
||||||
|
vPL_tmp.push_back( vPL[vnPLIndMat[i][j]]) ;
|
||||||
|
if ( ! Make( vPL_tmp, vPt_tmp, vTr_tmp))
|
||||||
|
return false ;
|
||||||
|
int nSize = int( vPt.size()) ;
|
||||||
|
for ( int p = 0 ; p < int( vPt_tmp.size()) ; ++ p)
|
||||||
|
vPt.push_back( vPt_tmp[p]) ;
|
||||||
|
for ( int t = 0 ; t < int( vTr_tmp.size()) ; ++ t)
|
||||||
|
vTr.push_back( nSize + vTr_tmp[t]) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Triangulate the CCW n-gon specified by the vertices vPt (Pt[n] != Pt[0])
|
// Triangulate the CCW n-gon specified by the vertices vPt (Pt[n] != Pt[0])
|
||||||
// Ear Clipping algorithm from mapbox
|
// Ear Clipping algorithm from mapbox
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Triangulate
|
|||||||
public :
|
public :
|
||||||
bool Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
bool Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||||
bool Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
bool Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||||
|
bool MakeAdvanced( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool MakeByEC_HPP( const PolyLine& PL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
bool MakeByEC_HPP( const PolyLine& PL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||||
|
|||||||
@@ -17,12 +17,15 @@
|
|||||||
#include "GeoObjRW.h"
|
#include "GeoObjRW.h"
|
||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
#include "/EgtDev/Include/EGkVolZmap.h"
|
#include "/EgtDev/Include/EGkVolZmap.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
// ------------------------- FORWARD -------------------------------------------------------------
|
||||||
|
class IntersParLinesSurfTm ;
|
||||||
|
|
||||||
// ------------------------- STRUTTURE -----------------------------------------------------------
|
// ------------------------- STRUTTURE -----------------------------------------------------------
|
||||||
struct AppliedVector {
|
struct AppliedVector {
|
||||||
Point3d ptPApp ;
|
Point3d ptPApp ;
|
||||||
@@ -112,19 +115,17 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
|
const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
|
||||||
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) override ;
|
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) override ;
|
||||||
bool GetDepth( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bExact) const override ;
|
bool GetDepth( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bExact) const override ;
|
||||||
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const override ;
|
bool CDeBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, bool bPrecise = false) const override ;
|
||||||
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const override ;
|
bool CDeSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bool bPrecise = false) const override ;
|
||||||
bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, bool bPrecise = false) const override ;
|
bool CDeCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise = false) const override ;
|
||||||
bool AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bool bPrecise = false) const override ;
|
bool CDeConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop, double dHeight,
|
||||||
bool AvoidCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise = false) const override ;
|
double dSafeDist, bool bPrecise = false) const override ;
|
||||||
bool AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop, double dHeight,
|
bool CDeRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dSafeDist, bool bPrecise = false) const override ;
|
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
||||||
bool AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
double dSafeDist, bool bPrecise = false) const override ;
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
bool CDeTorus( const Frame3d& frTorus, double dRadMax, double dRadMin,
|
||||||
double dSafeDist, bool bPrecise = false) const override ;
|
double dSafeDist, bool bPrecise = false) const override ;
|
||||||
bool AvoidTorus( const Frame3d& frTorus, double dRadMax, double dRadMin,
|
bool CDeSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecise = false) const override ;
|
||||||
double dSafeDist, bool bPrecise = false) const override ;
|
|
||||||
bool AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecise = false) const override ;
|
|
||||||
bool Cut( const Plane3d& plPlane) override ;
|
bool Cut( const Plane3d& plPlane) override ;
|
||||||
bool Compact( void) override ;
|
bool Compact( void) override ;
|
||||||
int GetPartCount( void) const override ;
|
int GetPartCount( void) const override ;
|
||||||
@@ -149,6 +150,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
{ if ( ! CopyFrom( stSrc))
|
{ if ( ! CopyFrom( stSrc))
|
||||||
LOG_ERROR( GetEGkLogger(), "VolZmap : copy error")
|
LOG_ERROR( GetEGkLogger(), "VolZmap : copy error")
|
||||||
return *this ; }
|
return *this ; }
|
||||||
|
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const ;
|
||||||
|
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
enum CubeType { VOX_EXTERN = 1,
|
enum CubeType { VOX_EXTERN = 1,
|
||||||
@@ -393,14 +396,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
bool ProcessIntervals( IntContainer& IntervalsToProcess) ;
|
bool ProcessIntervals( IntContainer& IntervalsToProcess) ;
|
||||||
bool IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, double& dMinZ, double& dMaxZ) ;
|
bool IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, double& dMinZ, double& dMaxZ) ;
|
||||||
bool IsBox( void) ;
|
bool IsBox( void) ;
|
||||||
// Avoid semplici
|
// Collision Detection semplici
|
||||||
bool AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise = false) const ;
|
bool CDeSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise = false) const ;
|
||||||
bool AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise = false) const ;
|
bool CDeSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise = false) const ;
|
||||||
bool AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise = false) const ;
|
bool CDeSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise = false) const ;
|
||||||
bool AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise = false) const ;
|
bool CDeSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise = false) const ;
|
||||||
bool AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
bool CDeSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise = false) const ;
|
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise = false) const ;
|
||||||
bool AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise = false) const ;
|
bool CDeSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise = false) const ;
|
||||||
// Funzione per crezione solido in parallelo
|
// Funzione per crezione solido in parallelo
|
||||||
bool CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
bool CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||||
|
|||||||
+219
-194
@@ -411,7 +411,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise) const
|
VolZmap::CDeSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// BBox
|
// BBox
|
||||||
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
|
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
|
||||||
@@ -425,10 +425,10 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
|
|||||||
|
|
||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
if ( ! b3Zmap.Overlaps( b3Box) || ! b3Zmap.Overlaps( frBoxInt, b3BoxL))
|
if ( ! b3Zmap.Overlaps( b3Box) || ! b3Zmap.Overlaps( frBoxInt, b3BoxL))
|
||||||
return true ;
|
return false ;
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
|
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Se verifico solo prima mappa
|
// Se verifico solo prima mappa
|
||||||
if ( ! bPrecise || m_nMapNum == 1) {
|
if ( ! bPrecise || m_nMapNum == 1) {
|
||||||
@@ -470,7 +470,7 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
|
|||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
|
|||||||
// 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 &&
|
if ( dMaxU > m_Values[nMap][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,32 +541,36 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, bool bPrecise) const
|
VolZmap::CDeBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
|
// Se il box non è ben definito non ha senso proseguire
|
||||||
|
if ( vtDiag.IsSmall())
|
||||||
|
return true ;
|
||||||
|
|
||||||
// Se distanza di sicurezza nulla
|
// Se distanza di sicurezza nulla
|
||||||
if ( dSafeDist < EPS_SMALL)
|
if ( dSafeDist < EPS_SMALL)
|
||||||
return AvoidSimpleBox( frBox, vtDiag, bPrecise) ;
|
return CDeSimpleBox( frBox, vtDiag, bPrecise) ;
|
||||||
|
|
||||||
// Verifica preliminare con box esteso
|
// Verifica preliminare con box esteso
|
||||||
Frame3d frEst = frBox ; frEst.Translate( -dSafeDist * ( frBox.VersX() + frBox.VersY() + frBox.VersZ())) ;
|
Frame3d frEst = frBox ; frEst.Translate( -dSafeDist * ( frBox.VersX() + frBox.VersY() + frBox.VersZ())) ;
|
||||||
if ( AvoidSimpleBox( frEst, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), bPrecise))
|
if ( ! CDeSimpleBox( frEst, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), bPrecise))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Tre box aumentati con distanza di sicurezza in un sola dimensione
|
// Tre box aumentati con distanza di sicurezza in un sola dimensione
|
||||||
Frame3d frTmp = frBox ; frTmp.Translate( -dSafeDist * frBox.VersX()) ;
|
Frame3d frTmp = frBox ; frTmp.Translate( -dSafeDist * frBox.VersX()) ;
|
||||||
if ( ! AvoidSimpleBox( frTmp, vtDiag + 2 * dSafeDist * X_AX, bPrecise))
|
if ( CDeSimpleBox( frTmp, vtDiag + 2 * dSafeDist * X_AX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp = frBox ; frTmp.Translate( -dSafeDist * frBox.VersY()) ;
|
frTmp = frBox ; frTmp.Translate( -dSafeDist * frBox.VersY()) ;
|
||||||
if ( ! AvoidSimpleBox( frTmp, vtDiag + 2 * dSafeDist * Y_AX, bPrecise))
|
if ( CDeSimpleBox( frTmp, vtDiag + 2 * dSafeDist * Y_AX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp = frBox ; frTmp.Translate( -dSafeDist * frBox.VersZ()) ;
|
frTmp = frBox ; frTmp.Translate( -dSafeDist * frBox.VersZ()) ;
|
||||||
if ( ! AvoidSimpleBox( frTmp, vtDiag + 2 * dSafeDist * Z_AX, bPrecise))
|
if ( CDeSimpleBox( frTmp, vtDiag + 2 * dSafeDist * Z_AX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
// Vertici del box
|
// Vertici del box
|
||||||
Point3d ptVert0 = frBox.Orig() ;
|
Point3d ptVert0 = frBox.Orig() ;
|
||||||
@@ -579,67 +583,67 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDis
|
|||||||
Point3d ptVert7 = ptVert3 + vtDiag.z * frBox.VersZ() ;
|
Point3d ptVert7 = ptVert3 + vtDiag.z * frBox.VersZ() ;
|
||||||
|
|
||||||
// Sfere centrate negli otto vertici
|
// Sfere centrate negli otto vertici
|
||||||
if ( ! AvoidSimpleSphere( ptVert0, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert0, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert1, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert1, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert2, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert2, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert3, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert3, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert4, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert4, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert5, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert5, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert6, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert6, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
if ( ! AvoidSimpleSphere( ptVert7, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptVert7, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
// Cilindri centrati sui dodici spigoli
|
// Cilindri centrati sui dodici spigoli
|
||||||
frTmp.Set( ptVert0, frBox.VersX()) ;
|
frTmp.Set( ptVert0, frBox.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert2, frBox.VersX()) ;
|
frTmp.Set( ptVert2, frBox.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert0, frBox.VersY()) ;
|
frTmp.Set( ptVert0, frBox.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert1, frBox.VersY()) ;
|
frTmp.Set( ptVert1, frBox.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert4, frBox.VersX()) ;
|
frTmp.Set( ptVert4, frBox.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert6, frBox.VersX()) ;
|
frTmp.Set( ptVert6, frBox.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.x, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert4, frBox.VersY()) ;
|
frTmp.Set( ptVert4, frBox.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert5, frBox.VersY()) ;
|
frTmp.Set( ptVert5, frBox.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.y, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert0, frBox.VersZ()) ;
|
frTmp.Set( ptVert0, frBox.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert1, frBox.VersZ()) ;
|
frTmp.Set( ptVert1, frBox.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert2, frBox.VersZ()) ;
|
frTmp.Set( ptVert2, frBox.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frTmp.Set( ptVert3, frBox.VersZ()) ;
|
frTmp.Set( ptVert3, frBox.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dSafeDist, vtDiag.z, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise) const
|
VolZmap::CDeSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// Porto la sfera nel riferimento intrinseco dello Zmap
|
// Porto la sfera nel riferimento intrinseco dello Zmap
|
||||||
Point3d ptC = ptCenter ;
|
Point3d ptC = ptCenter ;
|
||||||
@@ -655,7 +659,7 @@ VolZmap::AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise)
|
|||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
|
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Se verifico solo prima mappa
|
// Se verifico solo prima mappa
|
||||||
if ( ! bPrecise || m_nMapNum == 1) {
|
if ( ! bPrecise || m_nMapNum == 1) {
|
||||||
@@ -693,7 +697,7 @@ VolZmap::AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise)
|
|||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -765,7 +769,7 @@ VolZmap::AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise)
|
|||||||
// 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 &&
|
if ( dMaxU > m_Values[nMap][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -773,19 +777,23 @@ VolZmap::AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bool bPrecise) const
|
VolZmap::CDeSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
return AvoidSimpleSphere( ptCenter, dRad + max( 0., dSafeDist), bPrecise) ;
|
// Il raggio deve essere non nullo
|
||||||
|
if ( dRad < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
return CDeSimpleSphere( ptCenter, dRad + max( 0., dSafeDist), bPrecise) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise) const
|
VolZmap::CDeSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// BBox del cilindro in locale
|
// BBox del cilindro in locale
|
||||||
BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ;
|
BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ;
|
||||||
@@ -799,7 +807,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
|
|||||||
|
|
||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
if ( ! b3Zmap.Overlaps( b3CylI) || ! b3Zmap.Overlaps( frCylInt, b3CylL))
|
if ( ! b3Zmap.Overlaps( b3CylI) || ! b3Zmap.Overlaps( frCylInt, b3CylL))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// BBox del cilindro ottimizzato nel riferimento intrinseco dello Zmap
|
// BBox del cilindro ottimizzato nel riferimento intrinseco dello Zmap
|
||||||
Point3d ptMyCen = frCylInt.Orig() ;
|
Point3d ptMyCen = frCylInt.Orig() ;
|
||||||
@@ -822,7 +830,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
|
|||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Zmap.FindIntersection( b3Cyl, b3Int))
|
if ( ! b3Zmap.FindIntersection( b3Cyl, b3Int))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Se verifico solo prima mappa
|
// Se verifico solo prima mappa
|
||||||
if ( ! bPrecise || m_nMapNum == 1) {
|
if ( ! bPrecise || m_nMapNum == 1) {
|
||||||
@@ -866,7 +874,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
|
|||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -931,7 +939,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
|
|||||||
// 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 &&
|
if ( dMaxU > m_Values[nMap][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -939,13 +947,17 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise) const
|
VolZmap::CDeCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
|
// Il cilindro deve essere ben definito
|
||||||
|
if ( dR < EPS_SMALL || dH < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
|
||||||
// Se altezza negativa, sposto riferimento da faccia sopra a quella sotto
|
// Se altezza negativa, sposto riferimento da faccia sopra a quella sotto
|
||||||
Frame3d frMyCyl = frCyl ;
|
Frame3d frMyCyl = frCyl ;
|
||||||
if ( dH < 0) {
|
if ( dH < 0) {
|
||||||
@@ -955,34 +967,34 @@ VolZmap::AvoidCylinder( const Frame3d& frCyl, double dR, double dH, double dSafe
|
|||||||
|
|
||||||
// Se distanza di sicurezza nulla
|
// Se distanza di sicurezza nulla
|
||||||
if ( dSafeDist < EPS_SMALL)
|
if ( dSafeDist < EPS_SMALL)
|
||||||
return AvoidSimpleCylinder( frMyCyl, dR, dH, bPrecise) ;
|
return CDeSimpleCylinder( frMyCyl, dR, dH, bPrecise) ;
|
||||||
|
|
||||||
// Verifica preliminare con cilindro esteso
|
// Verifica preliminare con cilindro esteso
|
||||||
Frame3d frEst = frMyCyl ; frEst.Translate( -dSafeDist * frMyCyl.VersZ()) ;
|
Frame3d frEst = frMyCyl ; frEst.Translate( -dSafeDist * frMyCyl.VersZ()) ;
|
||||||
if ( AvoidSimpleCylinder( frEst, dR + dSafeDist, dH + 2 * dSafeDist, bPrecise))
|
if ( ! CDeSimpleCylinder( frEst, dR + dSafeDist, dH + 2 * dSafeDist, bPrecise))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Cilindro allargato
|
// Cilindro allargato
|
||||||
if ( ! AvoidSimpleCylinder( frMyCyl, dR + dSafeDist, dH, bPrecise))
|
if ( CDeSimpleCylinder( frMyCyl, dR + dSafeDist, dH, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Cilindro allungato
|
// Cilindro allungato
|
||||||
Frame3d frTmp = frMyCyl ; frTmp.Translate( - dSafeDist * frMyCyl.VersZ()) ;
|
Frame3d frTmp = frMyCyl ; frTmp.Translate( - dSafeDist * frMyCyl.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frTmp, dR, dH + 2 * dSafeDist, bPrecise))
|
if ( CDeSimpleCylinder( frTmp, dR, dH + 2 * dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Toro inferiore
|
// Toro inferiore
|
||||||
if ( ! AvoidSimpleTorus( frMyCyl, dR, dSafeDist, bPrecise))
|
if ( CDeSimpleTorus( frMyCyl, dR, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Toro superiore
|
// Toro superiore
|
||||||
frTmp = frMyCyl ; frTmp.Translate( dH * frMyCyl.VersZ()) ;
|
frTmp = frMyCyl ; frTmp.Translate( dH * frMyCyl.VersZ()) ;
|
||||||
if ( ! AvoidSimpleTorus( frTmp, dR, dSafeDist, bPrecise))
|
if ( CDeSimpleTorus( frTmp, dR, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise) const
|
VolZmap::CDeSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// BBox del tronco di cono in locale
|
// BBox del tronco di cono in locale
|
||||||
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), Point3d( dMaxRad, dMaxRad, dHeight)) ;
|
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), Point3d( dMaxRad, dMaxRad, dHeight)) ;
|
||||||
@@ -996,7 +1008,7 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
|
|||||||
|
|
||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
if ( ! b3Zmap.Overlaps( b3ConeI) || ! b3Zmap.Overlaps( frConeInt, b3ConeL))
|
if ( ! b3Zmap.Overlaps( b3ConeI) || ! b3Zmap.Overlaps( frConeInt, b3ConeL))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// BBox del tronco di cono ottimizzato nel riferimento intrinseco dello Zmap
|
// BBox del tronco di cono ottimizzato nel riferimento intrinseco dello Zmap
|
||||||
Point3d ptRefPoint = frConeInt.Orig() ;
|
Point3d ptRefPoint = frConeInt.Orig() ;
|
||||||
@@ -1025,7 +1037,7 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
|
|||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Zmap.FindIntersection( b3Cone, b3Int))
|
if ( ! b3Zmap.FindIntersection( b3Cone, b3Int))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Uso solo la prima mappa
|
// Uso solo la prima mappa
|
||||||
if ( ! bPrecise || m_nMapNum == 1) {
|
if ( ! bPrecise || m_nMapNum == 1) {
|
||||||
@@ -1068,7 +1080,7 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
|
|||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1133,14 +1145,14 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
|
|||||||
// 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 &&
|
if ( dMaxU > m_Values[nMap][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
dMinU < m_Values[nMap][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1149,12 +1161,16 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
|
|||||||
// Se è un tronco di cono l'origine è nel centro della base Bot e l'asse 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.
|
// la base Top, a prescindere da quale base abbia raggio maggiore.
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop, double dHeight,
|
VolZmap::CDeConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop, double dHeight,
|
||||||
double dSafeDist, bool bPrecise) const
|
double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
|
// Se il tronco di cono non è ben definito non ha senso proseguire
|
||||||
|
if ( max( dRadBot, dRadTop) < EPS_SMALL || dHeight < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
|
||||||
// Se cilindro
|
// Se cilindro
|
||||||
if ( abs( dRadBot - dRadTop) < EPS_SMALL)
|
if ( abs( dRadBot - dRadTop) < EPS_SMALL)
|
||||||
return AvoidCylinder( frCone, max( dRadBot, dRadTop), dHeight, dSafeDist, bPrecise) ;
|
return CDeCylinder( frCone, max( dRadBot, dRadTop), dHeight, dSafeDist, bPrecise) ;
|
||||||
|
|
||||||
// Verifico che la base minore sia in basso nel suo riferimento
|
// Verifico che la base minore sia in basso nel suo riferimento
|
||||||
Frame3d frMyCone = frCone ;
|
Frame3d frMyCone = frCone ;
|
||||||
@@ -1167,7 +1183,7 @@ VolZmap::AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop
|
|||||||
|
|
||||||
// Se distanza di sicurezza nulla
|
// Se distanza di sicurezza nulla
|
||||||
if ( dSafeDist < EPS_SMALL)
|
if ( dSafeDist < EPS_SMALL)
|
||||||
return AvoidSimpleConeFrustum( frMyCone, dMinRad, dMaxRad, dHeight, bPrecise) ;
|
return CDeSimpleConeFrustum( frMyCone, dMinRad, dMaxRad, dHeight, bPrecise) ;
|
||||||
|
|
||||||
// Se vero e proprio cono
|
// Se vero e proprio cono
|
||||||
if ( dMinRad < EPS_SMALL) {
|
if ( dMinRad < EPS_SMALL) {
|
||||||
@@ -1177,28 +1193,28 @@ VolZmap::AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop
|
|||||||
double dRadExt = dMaxRad * dHeightExt / dHeight ;
|
double dRadExt = dMaxRad * dHeightExt / dHeight ;
|
||||||
Frame3d frFrame = frMyCone ;
|
Frame3d frFrame = frMyCone ;
|
||||||
frFrame.Translate( -dDeltaVert * frFrame.VersZ()) ;
|
frFrame.Translate( -dDeltaVert * frFrame.VersZ()) ;
|
||||||
if ( AvoidSimpleConeFrustum( frFrame, 0., dRadExt, dHeightExt, bPrecise))
|
if ( ! CDeSimpleConeFrustum( frFrame, 0., dRadExt, dHeightExt, bPrecise))
|
||||||
return true ;
|
return false ;
|
||||||
// Sfera nel vertice in basso
|
// Sfera nel vertice in basso
|
||||||
frFrame = frMyCone ;
|
frFrame = frMyCone ;
|
||||||
if ( ! AvoidSimpleSphere( frMyCone.Orig(), dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( frMyCone.Orig(), dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Tronco di cono intermedio
|
// Tronco di cono intermedio
|
||||||
double dHypo = sqrt( dMaxRad * dMaxRad + dHeight * dHeight ) ;
|
double dHypo = sqrt( dMaxRad * dMaxRad + dHeight * dHeight ) ;
|
||||||
double dDeltaH = dSafeDist * dMaxRad / dHypo ;
|
double dDeltaH = dSafeDist * dMaxRad / dHypo ;
|
||||||
double dDeltaR = dSafeDist * dHeight / dHypo ;
|
double dDeltaR = dSafeDist * dHeight / dHypo ;
|
||||||
frFrame = frMyCone ; frFrame.Translate( -dDeltaH * frFrame.VersZ()) ;
|
frFrame = frMyCone ; frFrame.Translate( -dDeltaH * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleConeFrustum( frFrame, dDeltaR, dMaxRad + dDeltaR, dHeight, bPrecise))
|
if ( CDeSimpleConeFrustum( frFrame, dDeltaR, dMaxRad + dDeltaR, dHeight, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Cilindro nel toro in alto
|
// Cilindro nel toro in alto
|
||||||
frFrame = frMyCone ; frFrame.Translate( ( dHeight - dSafeDist) * frFrame.VersZ()) ;
|
frFrame = frMyCone ; frFrame.Translate( ( dHeight - dSafeDist) * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dMaxRad, 2 * dSafeDist, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dMaxRad, 2 * dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Toro in alto
|
// Toro in alto
|
||||||
frFrame = frMyCone ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
frFrame = frMyCone ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleTorus( frFrame, dMaxRad, dSafeDist, bPrecise))
|
if ( CDeSimpleTorus( frFrame, dMaxRad, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tronco di cono
|
// Tronco di cono
|
||||||
@@ -1210,33 +1226,33 @@ VolZmap::AvoidConeFrustum( const Frame3d& frCone, double dRadBot, double dRadTop
|
|||||||
double dDeltaMaxRad = ( dDeltaVert + dSafeDist) * dDiffRad / dHeight ;
|
double dDeltaMaxRad = ( dDeltaVert + dSafeDist) * dDiffRad / dHeight ;
|
||||||
double dDeltaMinRad = ( dDeltaVert - dSafeDist) * dDiffRad / dHeight ;
|
double dDeltaMinRad = ( dDeltaVert - dSafeDist) * dDiffRad / dHeight ;
|
||||||
Frame3d frFrame = frMyCone ; frFrame.Translate( -dSafeDist * frFrame.VersZ()) ;
|
Frame3d frFrame = frMyCone ; frFrame.Translate( -dSafeDist * frFrame.VersZ()) ;
|
||||||
if ( AvoidSimpleConeFrustum( frFrame, dMinRad + dDeltaMinRad, dMaxRad + dDeltaMaxRad, dHeight + 2 * dSafeDist, bPrecise))
|
if ( ! CDeSimpleConeFrustum( frFrame, dMinRad + dDeltaMinRad, dMaxRad + dDeltaMaxRad, dHeight + 2 * dSafeDist, bPrecise))
|
||||||
return true ;
|
return false ;
|
||||||
// Tronco di cono intermedio
|
// Tronco di cono intermedio
|
||||||
double dHypo = sqrt( dDiffRad * dDiffRad + dHeight * dHeight ) ;
|
double dHypo = sqrt( dDiffRad * dDiffRad + dHeight * dHeight ) ;
|
||||||
double dDeltaH = dSafeDist * dDiffRad / dHypo ;
|
double dDeltaH = dSafeDist * dDiffRad / dHypo ;
|
||||||
double dDeltaR = dSafeDist * dHeight / dHypo ;
|
double dDeltaR = dSafeDist * dHeight / dHypo ;
|
||||||
frFrame = frMyCone ; frFrame.Translate( -dDeltaH * frFrame.VersZ()) ;
|
frFrame = frMyCone ; frFrame.Translate( -dDeltaH * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleConeFrustum( frFrame, dMinRad + dDeltaR, dMaxRad + dDeltaR, dHeight, bPrecise))
|
if ( CDeSimpleConeFrustum( frFrame, dMinRad + dDeltaR, dMaxRad + dDeltaR, dHeight, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Cilindro sotto
|
// Cilindro sotto
|
||||||
frFrame = frMyCone ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
|
frFrame = frMyCone ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dMinRad, 2 * dSafeDist, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dMinRad, 2 * dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Cilindro sopra
|
// Cilindro sopra
|
||||||
frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dMaxRad, 2 * dSafeDist, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dMaxRad, 2 * dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Toro sotto
|
// Toro sotto
|
||||||
frFrame = frMyCone ;
|
frFrame = frMyCone ;
|
||||||
if ( ! AvoidSimpleTorus( frFrame, dMinRad, dSafeDist, bPrecise))
|
if ( CDeSimpleTorus( frFrame, dMinRad, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Toro sopra
|
// Toro sopra
|
||||||
frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleTorus( frFrame, dMaxRad, dSafeDist, bPrecise))
|
if ( CDeSimpleTorus( frFrame, dMaxRad, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1380,8 +1396,8 @@ RectPrismoidSegmentCollisionPlus( const Frame3d& frPrismoid, double dLenghtBaseX
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
VolZmap::CDeSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise) const
|
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// Box del tronco di prismoide nel suo sistema locale
|
// Box del tronco di prismoide nel suo sistema locale
|
||||||
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
|
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
|
||||||
@@ -1398,7 +1414,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
|
|||||||
|
|
||||||
// Se i box non interferiscono, posso uscire
|
// Se i box non interferiscono, posso uscire
|
||||||
if ( ! b3Zmap.Overlaps( b3PrismI) || ! b3Zmap.Overlaps( frPrismInt, b3PrismL))
|
if ( ! b3Zmap.Overlaps( b3PrismI) || ! b3Zmap.Overlaps( frPrismInt, b3PrismL))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// BBox del tronco di prismoide ottimizzato nel riferimento intrinseco dello Zmap
|
// BBox del tronco di prismoide ottimizzato nel riferimento intrinseco dello Zmap
|
||||||
Point3d ptMyCen = frPrismInt.Orig() ;
|
Point3d ptMyCen = frPrismInt.Orig() ;
|
||||||
@@ -1418,7 +1434,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
|
|||||||
// Se i box non interferiscono, posso uscire
|
// Se i box non interferiscono, posso uscire
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Zmap.FindIntersection( b3Prism, b3Int))
|
if ( ! b3Zmap.FindIntersection( b3Prism, b3Int))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Se verifico solo prima mappa
|
// Se verifico solo prima mappa
|
||||||
if ( ! bPrecise || m_nMapNum == 1) {
|
if ( ! bPrecise || m_nMapNum == 1) {
|
||||||
@@ -1456,7 +1472,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
|
|||||||
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
|
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
|
||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( m_Values[0][nPos][nIndex].dMax >= dStU && m_Values[0][nPos][nIndex].dMin <= dEnU)
|
if ( m_Values[0][nPos][nIndex].dMax >= dStU && m_Values[0][nPos][nIndex].dMin <= dEnU)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1523,30 +1539,30 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
|
|||||||
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
|
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
|
||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( m_Values[nMap][nDex][nIndex].dMax >= dStU && m_Values[nMap][nDex][nIndex].dMin <= dEnU)
|
if ( m_Values[nMap][nDex][nIndex].dMax >= dStU && m_Values[nMap][nDex][nIndex].dMin <= dEnU)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
VolZmap::CDeRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||||
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
||||||
double dSafeDist, bool bPrecise) const
|
double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// Se il tronco di piramide non è ben definito non procedo
|
// Se il tronco di piramide non è ben definito non procedo
|
||||||
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
||||||
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
|
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
|
||||||
dHeight < EPS_SMALL)
|
dHeight < EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
// Se distanza di sicurezza nulla
|
// Se distanza di sicurezza nulla
|
||||||
if ( dSafeDist < EPS_SMALL)
|
if ( dSafeDist < EPS_SMALL)
|
||||||
return AvoidSimpleRectPrismoid( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, bPrecise) ;
|
return CDeSimpleRectPrismoid( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, bPrecise) ;
|
||||||
|
|
||||||
// Verifica preliminare con offset esteso
|
// Verifica preliminare con offset esteso
|
||||||
double dHDiffX = ( dLenghtBaseX - dLenghtTopX) / 2 ;
|
double dHDiffX = ( dLenghtBaseX - dLenghtTopX) / 2 ;
|
||||||
@@ -1560,9 +1576,9 @@ VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, doub
|
|||||||
double dOffsBaseY = dSafeDist * ( dSecAy + dTgAy) ;
|
double dOffsBaseY = dSafeDist * ( dSecAy + dTgAy) ;
|
||||||
double dOffsTopY = dSafeDist * ( dSecAy - dTgAy) ;
|
double dOffsTopY = dSafeDist * ( dSecAy - dTgAy) ;
|
||||||
Frame3d frFrame = frPrismoid ; frFrame.Translate( -dSafeDist * frFrame.VersZ()) ;
|
Frame3d frFrame = frPrismoid ; frFrame.Translate( -dSafeDist * frFrame.VersZ()) ;
|
||||||
if ( AvoidSimpleRectPrismoid( frFrame, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
|
if ( ! CDeSimpleRectPrismoid( frFrame, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
|
||||||
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, bPrecise))
|
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, bPrecise))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Offset fine
|
// Offset fine
|
||||||
// Sfere centrate nei vertici
|
// Sfere centrate nei vertici
|
||||||
@@ -1580,85 +1596,85 @@ VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, doub
|
|||||||
Point3d( -dHalfTopX, dHalfTopY, dHeight)} ;
|
Point3d( -dHalfTopX, dHalfTopY, dHeight)} ;
|
||||||
for ( auto& ptV : vVert) {
|
for ( auto& ptV : vVert) {
|
||||||
ptV.ToGlob( frPrismoid) ;
|
ptV.ToGlob( frPrismoid) ;
|
||||||
if ( ! AvoidSimpleSphere( ptV, dSafeDist, bPrecise))
|
if ( CDeSimpleSphere( ptV, dSafeDist, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
// Cilindri con i segmenti come asse
|
// Cilindri con i segmenti come asse
|
||||||
frFrame.Set( vVert[0], frPrismoid.VersX()) ;
|
frFrame.Set( vVert[0], frPrismoid.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtBaseX, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtBaseX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[1], frPrismoid.VersY()) ;
|
frFrame.Set( vVert[1], frPrismoid.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtBaseY, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtBaseY, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[2], -frPrismoid.VersX()) ;
|
frFrame.Set( vVert[2], -frPrismoid.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtBaseX, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtBaseX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[3], -frPrismoid.VersY()) ;
|
frFrame.Set( vVert[3], -frPrismoid.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtBaseY, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtBaseY, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[4], frPrismoid.VersX()) ;
|
frFrame.Set( vVert[4], frPrismoid.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtTopX, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtTopX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[5], frPrismoid.VersY()) ;
|
frFrame.Set( vVert[5], frPrismoid.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtTopY, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtTopY, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[6], -frPrismoid.VersX()) ;
|
frFrame.Set( vVert[6], -frPrismoid.VersX()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtTopX, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtTopX, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
frFrame.Set( vVert[7], -frPrismoid.VersY()) ;
|
frFrame.Set( vVert[7], -frPrismoid.VersY()) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenghtTopY, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenghtTopY, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
Vector3d vtSeg04 = vVert[4] - vVert[0] ;
|
Vector3d vtSeg04 = vVert[4] - vVert[0] ;
|
||||||
double dLenSeg04 = vtSeg04.Len() ;
|
double dLenSeg04 = vtSeg04.Len() ;
|
||||||
frFrame.Set( vVert[0], vtSeg04) ;
|
frFrame.Set( vVert[0], vtSeg04) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenSeg04, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenSeg04, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
Vector3d vtSeg15 = vVert[5] - vVert[1] ;
|
Vector3d vtSeg15 = vVert[5] - vVert[1] ;
|
||||||
double dLenSeg15 = vtSeg15.Len() ;
|
double dLenSeg15 = vtSeg15.Len() ;
|
||||||
frFrame.Set( vVert[1], vtSeg15) ;
|
frFrame.Set( vVert[1], vtSeg15) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenSeg15, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenSeg15, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
Vector3d vtSeg26 = vVert[6] - vVert[2] ;
|
Vector3d vtSeg26 = vVert[6] - vVert[2] ;
|
||||||
double dLenSeg26 = vtSeg26.Len() ;
|
double dLenSeg26 = vtSeg26.Len() ;
|
||||||
frFrame.Set( vVert[2], vtSeg26) ;
|
frFrame.Set( vVert[2], vtSeg26) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenSeg26, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenSeg26, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
Vector3d vtSeg37 = vVert[7] - vVert[3] ;
|
Vector3d vtSeg37 = vVert[7] - vVert[3] ;
|
||||||
double dLenSeg37 = vtSeg37.Len();
|
double dLenSeg37 = vtSeg37.Len();
|
||||||
frFrame.Set( vVert[3], vtSeg37) ;
|
frFrame.Set( vVert[3], vtSeg37) ;
|
||||||
if ( ! AvoidSimpleCylinder( frFrame, dSafeDist, dLenSeg37, bPrecise))
|
if ( CDeSimpleCylinder( frFrame, dSafeDist, dLenSeg37, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Box sotto
|
// Box sotto
|
||||||
frFrame = frPrismoid ; frFrame.Translate( -dSafeDist * frFrame.VersZ()) ;
|
frFrame = frPrismoid ; frFrame.Translate( -dSafeDist * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleBox( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), bPrecise))
|
if ( CDeSimpleBox( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Box sopra
|
// Box sopra
|
||||||
frFrame = frPrismoid ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
frFrame = frPrismoid ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleBox( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), bPrecise))
|
if ( CDeSimpleBox( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Prismoide allungato in X
|
// Prismoide allungato in X
|
||||||
double dHypoX = sqrt( dHDiffX * dHDiffX + dHeight * dHeight) ;
|
double dHypoX = sqrt( dHDiffX * dHDiffX + dHeight * dHeight) ;
|
||||||
double dOffsX = dSafeDist * dHeight / dHypoX ;
|
double dOffsX = dSafeDist * dHeight / dHypoX ;
|
||||||
double dMoveXZ = dSafeDist * dHDiffX / dHypoX ;
|
double dMoveXZ = dSafeDist * dHDiffX / dHypoX ;
|
||||||
frFrame = frPrismoid ; frFrame.Translate( dMoveXZ * frFrame.VersZ()) ;
|
frFrame = frPrismoid ; frFrame.Translate( dMoveXZ * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleRectPrismoid( frFrame, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
|
if ( CDeSimpleRectPrismoid( frFrame, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
|
||||||
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, bPrecise))
|
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
// Prismoide allungato in Y
|
// Prismoide allungato in Y
|
||||||
double dHypoY = sqrt( dHDiffY * dHDiffY + dHeight * dHeight) ;
|
double dHypoY = sqrt( dHDiffY * dHDiffY + dHeight * dHeight) ;
|
||||||
double dOffsY = dSafeDist * dHeight / dHypoY ;
|
double dOffsY = dSafeDist * dHeight / dHypoY ;
|
||||||
double dMoveYZ = dSafeDist * dHDiffY / dHypoY ;
|
double dMoveYZ = dSafeDist * dHDiffY / dHypoY ;
|
||||||
frFrame = frPrismoid ; frFrame.Translate( dMoveYZ * frFrame.VersZ()) ;
|
frFrame = frPrismoid ; frFrame.Translate( dMoveYZ * frFrame.VersZ()) ;
|
||||||
if ( ! AvoidSimpleRectPrismoid( frFrame, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
|
if ( CDeSimpleRectPrismoid( frFrame, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
|
||||||
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, bPrecise))
|
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, bPrecise))
|
||||||
return false ;
|
return true ;
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise) const
|
VolZmap::CDeSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// BBox del toro in locale
|
// BBox del toro in locale
|
||||||
BBox3d b3TorusL( Point3d( -dMaxRad - dMinRad, -dMaxRad - dMinRad, -dMinRad),
|
BBox3d b3TorusL( Point3d( -dMaxRad - dMinRad, -dMaxRad - dMinRad, -dMinRad),
|
||||||
@@ -1673,7 +1689,7 @@ VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRa
|
|||||||
|
|
||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
if ( ! b3Zmap.Overlaps( b3TorusI) || ! b3Zmap.Overlaps( frTorusInt, b3TorusL))
|
if ( ! b3Zmap.Overlaps( b3TorusI) || ! b3Zmap.Overlaps( frTorusInt, b3TorusL))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// BBox del toro ottimizzato nel riferimento intrinseco dello Zmap
|
// BBox del toro ottimizzato nel riferimento intrinseco dello Zmap
|
||||||
Point3d ptMyCen = frTorusInt.Orig() ;
|
Point3d ptMyCen = frTorusInt.Orig() ;
|
||||||
@@ -1698,7 +1714,7 @@ VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRa
|
|||||||
// Se non interferiscono, posso uscire
|
// Se non interferiscono, posso uscire
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Zmap.FindIntersection( b3Torus, b3Int))
|
if ( ! b3Zmap.FindIntersection( b3Torus, b3Int))
|
||||||
return true ;
|
return false ;
|
||||||
|
|
||||||
// Se verifico solo prima mappa
|
// Se verifico solo prima mappa
|
||||||
if ( ! bPrecise || m_nMapNum == 1) {
|
if ( ! bPrecise || m_nMapNum == 1) {
|
||||||
@@ -1736,13 +1752,13 @@ VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRa
|
|||||||
int nIntType = SegmentTorus( ptSegSt, Z_AX, dParMax - dParMin, ptMyCen, vtMyAx, dMinRad, dMaxRad,
|
int nIntType = SegmentTorus( ptSegSt, Z_AX, dParMax - dParMin, ptMyCen, vtMyAx, dMinRad, dMaxRad,
|
||||||
vbType, vdPar) ;
|
vbType, vdPar) ;
|
||||||
if ( nIntType == LinCompTorusIntersType::T_ERROR)
|
if ( nIntType == LinCompTorusIntersType::T_ERROR)
|
||||||
return false ;
|
return true ;
|
||||||
else if ( nIntType != LinCompTorusIntersType::T_NO_INT) {
|
else if ( nIntType != LinCompTorusIntersType::T_NO_INT) {
|
||||||
double dUmin = vdPar.front() ;
|
double dUmin = vdPar.front() ;
|
||||||
double dUmax = vdPar.back() ;
|
double dUmax = vdPar.back() ;
|
||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( m_Values[0][nPos][nIndex].dMax >= dUmin && m_Values[0][nPos][nIndex].dMin <= dUmax)
|
if ( m_Values[0][nPos][nIndex].dMax >= dUmin && m_Values[0][nPos][nIndex].dMin <= dUmax)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1810,31 +1826,31 @@ VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRa
|
|||||||
int nIntType = SegmentTorus( ptSegSt, vtLineDir, dParMax - dParMin, ptMyCen, vtMyAx, dMinRad, dMaxRad,
|
int nIntType = SegmentTorus( ptSegSt, vtLineDir, dParMax - dParMin, ptMyCen, vtMyAx, dMinRad, dMaxRad,
|
||||||
vbType, vdPar) ;
|
vbType, vdPar) ;
|
||||||
if ( nIntType == LinCompTorusIntersType::T_ERROR)
|
if ( nIntType == LinCompTorusIntersType::T_ERROR)
|
||||||
return false ;
|
return true ;
|
||||||
else if ( nIntType != LinCompTorusIntersType::T_NO_INT) {
|
else if ( nIntType != LinCompTorusIntersType::T_NO_INT) {
|
||||||
double dUmin = vdPar.front() ;
|
double dUmin = vdPar.front() ;
|
||||||
double dUmax = vdPar.back() ;
|
double dUmax = vdPar.back() ;
|
||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( m_Values[nMap][nDex][nIndex].dMax >= dUmin && m_Values[nMap][nDex][nIndex].dMin <= dUmax)
|
if ( m_Values[nMap][nDex][nIndex].dMax >= dUmin && m_Values[nMap][nDex][nIndex].dMin <= dUmax)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad,
|
VolZmap::CDeTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad,
|
||||||
double dSafeDist, bool bPrecise) const
|
double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// I raggi devono essere non nulli
|
// I raggi devono essere non nulli
|
||||||
if ( dMaxRad < EPS_SMALL || dMinRad < EPS_SMALL)
|
if ( dMaxRad < EPS_SMALL || dMinRad < EPS_SMALL)
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
return AvoidSimpleTorus( frTorus, dMaxRad, dMinRad + max( 0., dSafeDist), bPrecise) ;
|
return CDeSimpleTorus( frTorus, dMaxRad, dMinRad + max( 0., dSafeDist), bPrecise) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1844,12 +1860,13 @@ VolZmap::AvoidTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad,
|
|||||||
// quelli di intersezione segmento triangolo vengono eseguiti nel sistema locale. Questo perché
|
// quelli di intersezione segmento triangolo vengono eseguiti nel sistema locale. Questo perché
|
||||||
// è più veloce trasformare le coordinate degli estremi del segmento piuttosto che quelle del
|
// è più veloce trasformare le coordinate degli estremi del segmento piuttosto che quelle del
|
||||||
// triangolo.
|
// triangolo.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecise) const
|
VolZmap::CDeSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecise) const
|
||||||
{
|
{
|
||||||
// Controllo sulla validità della superficie ed eventualmente sulla sua chiusura
|
// Controllo sulla validità della superficie e sulla sua chiusura
|
||||||
if ( ! ( tmSurf.IsValid() && tmSurf.IsClosed()))
|
if ( ! tmSurf.IsValid() || ! tmSurf.IsClosed())
|
||||||
return false ;
|
return true ;
|
||||||
// Bounding box della superficie espresso nel sistema locale
|
// Bounding box della superficie espresso nel sistema locale
|
||||||
BBox3d b3SurfBox ;
|
BBox3d b3SurfBox ;
|
||||||
tmSurf.GetLocalBBox( b3SurfBox) ;
|
tmSurf.GetLocalBBox( b3SurfBox) ;
|
||||||
@@ -1862,7 +1879,7 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
|
|||||||
// Box intersezione: se non c'è intersezione ho finito.
|
// Box intersezione: se non c'è intersezione ho finito.
|
||||||
BBox3d b3IntBox ;
|
BBox3d b3IntBox ;
|
||||||
if ( ! b3ZmapBox.FindIntersection( b3SurfBox, b3IntBox))
|
if ( ! b3ZmapBox.FindIntersection( b3SurfBox, b3IntBox))
|
||||||
return true ;
|
return false ;
|
||||||
// Recupero i triangoli della superficie che cadono nel box intersezione.
|
// Recupero i triangoli della superficie che cadono nel box intersezione.
|
||||||
INTVECTOR vTriaIndex ;
|
INTVECTOR vTriaIndex ;
|
||||||
tmSurf.GetAllTriaOverlapBox( b3IntBox, vTriaIndex) ;
|
tmSurf.GetAllTriaOverlapBox( b3IntBox, vTriaIndex) ;
|
||||||
@@ -1923,7 +1940,7 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
|
|||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1939,7 +1956,7 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
|
|||||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||||
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
|
||||||
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2030,11 +2047,11 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
|
|||||||
double dU1, dU2 ;
|
double dU1, dU2 ;
|
||||||
int nIntersType = SegmentSphere( ptSegSt, vtLineDir, dSegLen, ptVertP, dSafeDist, dU1, dU2) ;
|
int nIntersType = SegmentSphere( ptSegSt, vtLineDir, dSegLen, ptVertP, dSafeDist, dU1, dU2) ;
|
||||||
if ( nIntersType != LinCompSphereIntersType::S_NO_INTERS)
|
if ( nIntersType != LinCompSphereIntersType::S_NO_INTERS)
|
||||||
return false ;
|
return true ;
|
||||||
nIntersType = IntersSegmentCylinder( ptSegSt, vtLineDir, dSegLen, ptVertP, vtEdgeV,
|
nIntersType = IntersSegmentCylinder( ptSegSt, vtLineDir, dSegLen, ptVertP, vtEdgeV,
|
||||||
dSafeDist, dEdgeLen, dU1, dU2) ;
|
dSafeDist, dEdgeLen, dU1, dU2) ;
|
||||||
if ( nIntersType != LinCompCCIntersType::CC_NO_INTERS)
|
if ( nIntersType != LinCompCCIntersType::CC_NO_INTERS)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
// Traslo il triangolo.
|
// Traslo il triangolo.
|
||||||
trNewTria.Translate( dSafeDist * trTria.GetN()) ;
|
trNewTria.Translate( dSafeDist * trTria.GetN()) ;
|
||||||
@@ -2044,14 +2061,14 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
|
|||||||
int nIntersType = IntersLineTria( ptSegSt, vtLineDir, dSegLen, trNewTria, ptInt, ptInt2) ;
|
int nIntersType = IntersLineTria( ptSegSt, vtLineDir, dSegLen, trNewTria, ptInt, ptInt2) ;
|
||||||
// Collisione
|
// Collisione
|
||||||
if ( nIntersType != IntLineTriaType::ILTT_NO)
|
if ( nIntersType != IntLineTriaType::ILTT_NO)
|
||||||
return false ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -2895,8 +2912,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
||||||
int nNumVox ;
|
int nNumVox ;
|
||||||
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
||||||
nNumVox, nB, ptLineTria1, trTria) ;
|
nNumVox, nB, trTria, dCosDN, ptLineTria1) ;
|
||||||
}
|
}
|
||||||
// altrimenti ci sono due intersezioni
|
// altrimenti ci sono due intersezioni
|
||||||
else {
|
else {
|
||||||
@@ -2904,8 +2922,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
||||||
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
||||||
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
||||||
nNumVox, nB, ptLineTria1, ptLineTria2, trTria) ;
|
nNumVox, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2931,8 +2950,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
||||||
int nNumVox ;
|
int nNumVox ;
|
||||||
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
||||||
nNumVox, nB, ptLineTria1, trTria) ;
|
nNumVox, nB, trTria, dCosDN, ptLineTria1) ;
|
||||||
}
|
}
|
||||||
// altrimenti ci sono due intersezioni
|
// altrimenti ci sono due intersezioni
|
||||||
else {
|
else {
|
||||||
@@ -2940,8 +2960,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
||||||
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
||||||
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
||||||
nNumVox, nB, ptLineTria1, ptLineTria2, trTria) ;
|
nNumVox, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2957,15 +2978,17 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
continue ;
|
continue ;
|
||||||
// se altrimenti c'è una sola intersezione
|
// se altrimenti c'è una sola intersezione
|
||||||
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
||||||
-1, nB, ptLineTria1, trTria) ;
|
-1, nB, trTria, dCosDN, ptLineTria1) ;
|
||||||
}
|
}
|
||||||
// altrimenti ci sono due intersezioni
|
// altrimenti ci sono due intersezioni
|
||||||
else {
|
else {
|
||||||
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
||||||
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
||||||
-1, nB, ptLineTria1, ptLineTria2, trTria) ;
|
-1, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2990,8 +3013,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
|
||||||
int nNumVox ;
|
int nNumVox ;
|
||||||
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
|
||||||
nNumVox, nB, ptLineTria1, trTria) ;
|
nNumVox, nB, trTria, dCosDN, ptLineTria1) ;
|
||||||
}
|
}
|
||||||
// altrimenti ci sono due intersezioni
|
// altrimenti ci sono due intersezioni
|
||||||
else {
|
else {
|
||||||
@@ -2999,8 +3023,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
|||||||
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
|
||||||
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
|
||||||
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
|
||||||
|
double dCosDN = vtDir * trTria.GetN() ;
|
||||||
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
|
||||||
nNumVox, nB, ptLineTria1, ptLineTria2, trTria) ;
|
nNumVox, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "VolZmap.h"
|
#include "VolZmap.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
|
|||||||
+199
-131
@@ -79,7 +79,7 @@ Voronoi::AddCurve( const ICurve* pCrv)
|
|||||||
if ( pCrv == nullptr)
|
if ( pCrv == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico se è una linea
|
// verifico se è una linea
|
||||||
int nType = pCrv->GetType() ;
|
int nType = pCrv->GetType() ;
|
||||||
bool bIsLine = ( nType == CRV_LINE) ;
|
bool bIsLine = ( nType == CRV_LINE) ;
|
||||||
if ( nType == CRV_COMPO) {
|
if ( nType == CRV_COMPO) {
|
||||||
@@ -92,7 +92,7 @@ Voronoi::AddCurve( const ICurve* pCrv)
|
|||||||
// verifico sia piana e trovo piano su cui giace
|
// verifico sia piana e trovo piano su cui giace
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
if ( bIsLine) {
|
if ( bIsLine) {
|
||||||
// linea è sicuramente piana. Scelgo piano definito dall'estrusione ( se definita)
|
// linea è sicuramente piana. Scelgo piano definito dall'estrusione ( se definita)
|
||||||
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
|
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
|
||||||
Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ;
|
Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ;
|
||||||
if ( ! vtExtr.IsSmall())
|
if ( ! vtExtr.IsSmall())
|
||||||
@@ -110,30 +110,40 @@ Voronoi::AddCurve( const ICurve* pCrv)
|
|||||||
m_Frame.Set( plPlane.GetPoint(), plPlane.GetVersN()) ;
|
m_Frame.Set( plPlane.GetPoint(), plPlane.GetVersN()) ;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// altrimenti verifico sia complanare ad eventuali curve già presenti
|
// altrimenti verifico sia complanare ad eventuali curve già presenti
|
||||||
if ( ! AreSameOrOppositeVectorApprox( m_Frame.VersZ(), plPlane.GetVersN()) || ! PointInPlaneApprox( m_Frame.Orig(), plPlane))
|
if ( ! AreSameOrOppositeVectorApprox( m_Frame.VersZ(), plPlane.GetVersN()) || ! PointInPlaneApprox( m_Frame.Orig(), plPlane))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico se oggetto vroni è stato inizializzato
|
|
||||||
if ( m_vroni == nullptr) {
|
|
||||||
m_vroni = new( nothrow) vroniObject() ;
|
|
||||||
m_vroni->apiInitializeProgram() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// creo una copia della curva e la porto in locale
|
// creo una copia della curva e la porto in locale
|
||||||
PtrOwner<ICurve> pCrvLoc( pCrv->Clone()) ;
|
PtrOwner<ICurve> pCrvLoc( pCrv->Clone()) ;
|
||||||
|
if ( IsNull( pCrvLoc))
|
||||||
|
return false ;
|
||||||
pCrvLoc->ToLoc( m_Frame) ;
|
pCrvLoc->ToLoc( m_Frame) ;
|
||||||
|
|
||||||
// aggiungo la curva in locale all'oggetto vroni
|
try {
|
||||||
if ( ! AddCurveToVroni( pCrvLoc))
|
// verifico se oggetto vroni è stato inizializzato
|
||||||
|
if ( m_vroni == nullptr) {
|
||||||
|
m_vroni = new( nothrow) vroniObject() ;
|
||||||
|
if ( m_vroni == nullptr)
|
||||||
|
return false ;
|
||||||
|
m_vroni->apiInitializeProgram() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// aggiungo la curva in locale all'oggetto vroni
|
||||||
|
if ( ! AddCurveToVroni( pCrvLoc))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
|
||||||
return false ;
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
// aggiorno il box complessivo
|
// aggiorno il box complessivo
|
||||||
BBox3d bBox ;
|
BBox3d bBox ;
|
||||||
pCrvLoc->GetLocalBBox( bBox) ;
|
pCrvLoc->GetLocalBBox( bBox) ;
|
||||||
m_bBox.Add( bBox) ;
|
m_bBox.Add( bBox) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,28 +165,38 @@ Voronoi::AddSurfFlatRegion( const ISurfFlatRegion* pSfr)
|
|||||||
m_Frame.Set( ptCen, vtN) ;
|
m_Frame.Set( ptCen, vtN) ;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// verifico sia complanare ad eventuali curve già presenti
|
// verifico sia complanare ad eventuali curve già presenti
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
plPlane.Set( ptCen, pSfr->GetNormVersor()) ;
|
plPlane.Set( ptCen, pSfr->GetNormVersor()) ;
|
||||||
if ( ! AreSameOrOppositeVectorApprox( m_Frame.VersZ(), pSfr->GetNormVersor()) || ! PointInPlaneApprox( m_Frame.Orig(), plPlane))
|
if ( ! AreSameOrOppositeVectorApprox( m_Frame.VersZ(), pSfr->GetNormVersor()) || ! PointInPlaneApprox( m_Frame.Orig(), plPlane))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico se oggetto vroni è stato inizializzato
|
try {
|
||||||
if ( m_vroni == nullptr) {
|
// verifico se oggetto vroni è stato inizializzato
|
||||||
m_vroni = new( nothrow) vroniObject() ;
|
if ( m_vroni == nullptr) {
|
||||||
m_vroni->apiInitializeProgram() ;
|
m_vroni = new( nothrow) vroniObject() ;
|
||||||
}
|
if ( m_vroni == nullptr)
|
||||||
|
|
||||||
// aggiungo le curve di loop
|
|
||||||
for ( int i = 0 ; i < pSfr->GetChunkCount() ; i ++) {
|
|
||||||
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; j ++) {
|
|
||||||
PtrOwner<ICurve> pCrvLoc( pSfr->GetLoop( i, j)) ;
|
|
||||||
pCrvLoc->ToLoc( m_Frame) ;
|
|
||||||
if ( ! AddCurveToVroni( pCrvLoc))
|
|
||||||
return false ;
|
return false ;
|
||||||
}
|
m_vroni->apiInitializeProgram() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aggiungo le curve di loop
|
||||||
|
for ( int i = 0 ; i < pSfr->GetChunkCount() ; i ++) {
|
||||||
|
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; j ++) {
|
||||||
|
PtrOwner<ICurve> pCrvLoc( pSfr->GetLoop( i, j)) ;
|
||||||
|
if ( IsNull( pCrvLoc))
|
||||||
|
return false ;
|
||||||
|
pCrvLoc->ToLoc( m_Frame) ;
|
||||||
|
if ( ! AddCurveToVroni( pCrvLoc))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage())
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
// aggiorno il box complessivo
|
// aggiorno il box complessivo
|
||||||
BBox3d bBox ;
|
BBox3d bBox ;
|
||||||
@@ -184,7 +204,7 @@ Voronoi::AddSurfFlatRegion( const ISurfFlatRegion* pSfr)
|
|||||||
frSrf.Invert() ;
|
frSrf.Invert() ;
|
||||||
pSfr->GetBBox( frSrf, bBox) ;
|
pSfr->GetBBox( frSrf, bBox) ;
|
||||||
m_bBox.Add( bBox) ;
|
m_bBox.Add( bBox) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,8 +245,9 @@ Voronoi::AddLineToVroni( const ICurveLine* pLine, int& nVroniCrv, int nLoopId, i
|
|||||||
{
|
{
|
||||||
if ( pLine == nullptr)
|
if ( pLine == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
// verifico se il punto finale viene forzato oppure deve essere ricavato dalla pLine
|
||||||
if ( ! ptEnd.IsValid()) {
|
if ( ! ptEnd.IsValid()) {
|
||||||
// recupero end point
|
|
||||||
if ( ! pLine->GetEndPoint( ptEnd))
|
if ( ! pLine->GetEndPoint( ptEnd))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -260,8 +281,8 @@ Voronoi::AddArcToVroni( const ICurveArc* pArc, int& nVroniCrv, int nLoopId, int
|
|||||||
m_vroni->AddArc( &nVroniCrv, ptStart.x, ptStart.y, ptCen.x, ptCen.y, nArcSiteType, {nLoopId, nCrvId}) ;
|
m_vroni->AddArc( &nVroniCrv, ptStart.x, ptStart.y, ptCen.x, ptCen.y, nArcSiteType, {nLoopId, nCrvId}) ;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// verifico se il punto finale viene forzato oppure deve essere ricavato dal pArc
|
||||||
if ( ! ptEnd.IsValid()) {
|
if ( ! ptEnd.IsValid()) {
|
||||||
// recupero end point dalla curva
|
|
||||||
if ( ! pArc->GetEndPoint( ptEnd))
|
if ( ! pArc->GetEndPoint( ptEnd))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -294,7 +315,7 @@ Voronoi::AddCompoToVroni( const ICurveComposite* pCompo, int& nVroniCrv, int nLo
|
|||||||
for ( int i = 0 ; i < pCopy->GetCurveCount() ; i++) {
|
for ( int i = 0 ; i < pCopy->GetCurveCount() ; i++) {
|
||||||
Point3d ptForcedEnd = P_INVALID ;
|
Point3d ptForcedEnd = P_INVALID ;
|
||||||
|
|
||||||
// se curva è chiusa, forzo l'end point a coincidere con lo start ( per le tolleranze di vroni)
|
// se curva è chiusa, forzo l'end point a coincidere con lo start ( per le tolleranze di vroni)
|
||||||
if ( i == pCopy->GetCurveCount() - 1 && bClosed)
|
if ( i == pCopy->GetCurveCount() - 1 && bClosed)
|
||||||
pCompo->GetStartPoint( ptForcedEnd) ;
|
pCompo->GetStartPoint( ptForcedEnd) ;
|
||||||
|
|
||||||
@@ -338,7 +359,7 @@ Voronoi::AddBezierToVroni( const ICurveBezier* pBezier, int& nVroniCrv, int nLoo
|
|||||||
ICurve*
|
ICurve*
|
||||||
Voronoi::GetCurve( int nId) const
|
Voronoi::GetCurve( int nId) const
|
||||||
{
|
{
|
||||||
// verifico validità indice
|
// verifico validità indice
|
||||||
if ( nId < 0 || nId > ( int)m_vpCrvs.size() - 1)
|
if ( nId < 0 || nId > ( int)m_vpCrvs.size() - 1)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// ne faccio una copia
|
// ne faccio una copia
|
||||||
@@ -354,20 +375,22 @@ Voronoi::GetCurve( int nId) const
|
|||||||
bool
|
bool
|
||||||
Voronoi::CalcVoronoi( int nBound)
|
Voronoi::CalcVoronoi( int nBound)
|
||||||
{
|
{
|
||||||
// se già stato calcolato con lo stesso bound non devo fare nulla
|
// se già stato calcolato con lo stesso bound non devo fare nulla
|
||||||
if ( m_bVDComputed && nBound == m_nBound)
|
if ( m_bVDComputed && nBound == m_nBound)
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
// se già stato calcolato reset dei dati
|
// se già stato calcolato reset dei dati
|
||||||
if ( m_bVDComputed)
|
if ( m_bVDComputed)
|
||||||
m_vroni->ResetVoronoiDiagram() ;
|
m_vroni->ResetVoronoiDiagram() ;
|
||||||
|
|
||||||
|
// come valore minimo per il bound considero quello standard di vroni
|
||||||
|
m_nBound = max( nBound, VORONOI_STD_BOUND) ;
|
||||||
|
|
||||||
// calcolo
|
// calcolo
|
||||||
m_nBound = nBound ;
|
|
||||||
m_bVDComputed = true ;
|
m_bVDComputed = true ;
|
||||||
string sTmp = "" ;
|
string sTmp = "" ;
|
||||||
m_vroni->apiComputeVD( false, true, false, m_nBound, 0, 0, &sTmp[0], false, false, false, &sTmp[0], true) ;
|
m_vroni->apiComputeVD( false, true, false, m_nBound, 0, 0, &sTmp[0], false, false, false, &sTmp[0], true) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,15 +490,24 @@ Voronoi::CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound)
|
|||||||
if ( ! IsValid())
|
if ( ! IsValid())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico se necessario calcolo Voronoi
|
try {
|
||||||
if ( ! m_bVDComputed || nBound != m_nBound)
|
// verifico se necessario calcolo Voronoi
|
||||||
CalcVoronoi( nBound) ;
|
if ( ! m_bVDComputed || nBound != m_nBound)
|
||||||
|
CalcVoronoi( nBound) ;
|
||||||
|
|
||||||
for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) {
|
for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) {
|
||||||
// recupero la curva del bisettore
|
// recupero la curva del bisettore
|
||||||
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
|
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
|
||||||
if ( ! IsNull( pCrv) && pCrv->IsValid())
|
if ( ! IsNull( pCrv) && pCrv->IsValid())
|
||||||
vCrvs.emplace_back( Release( pCrv)) ;
|
vCrvs.emplace_back( Release( pCrv)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// libero la memoria di vroni utilizzata per calcolare bisettore
|
||||||
|
m_vroni->apiFreeBisectorBuffer() ;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -489,10 +521,7 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide)
|
|||||||
|
|
||||||
if ( ! IsValid())
|
if ( ! IsValid())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
if ( ! m_bVDComputed)
|
|
||||||
CalcVoronoi() ;
|
|
||||||
|
|
||||||
// lato per il medial axis
|
// lato per il medial axis
|
||||||
bool bLeft = true ;
|
bool bLeft = true ;
|
||||||
bool bRight = true ;
|
bool bRight = true ;
|
||||||
@@ -501,18 +530,31 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide)
|
|||||||
else if ( nSide == WMAT_RIGHT)
|
else if ( nSide == WMAT_RIGHT)
|
||||||
bLeft = false ;
|
bLeft = false ;
|
||||||
|
|
||||||
// calcolo medial axis
|
try {
|
||||||
m_vroni->apiComputeWMAT( false, 0.0, 0.0, false, bLeft, bRight) ;
|
if ( ! m_bVDComputed)
|
||||||
|
CalcVoronoi() ;
|
||||||
for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) {
|
|
||||||
// verifico se il lato appartiene al medial axis
|
// calcolo medial axis
|
||||||
if ( m_vroni->IsWMATEdge( i)) {
|
m_vroni->apiComputeWMAT( false, 0.0, 0.0, false, bLeft, bRight) ;
|
||||||
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
|
|
||||||
if ( ! IsNull( pCrv) && pCrv->IsValid())
|
for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) {
|
||||||
vCrvs.emplace_back( Release( pCrv)) ;
|
// verifico se il lato appartiene al medial axis
|
||||||
}
|
if ( m_vroni->IsWMATEdge( i)) {
|
||||||
|
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
|
||||||
|
if ( ! IsNull( pCrv) && pCrv->IsValid())
|
||||||
|
vCrvs.emplace_back( Release( pCrv)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// libero la memoria di vroni utilizzata per calcolare bisettore
|
||||||
|
m_vroni->apiFreeBisectorBuffer() ;
|
||||||
}
|
}
|
||||||
return true ;
|
catch (...) {
|
||||||
|
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -559,20 +601,21 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
|
|||||||
if ( pCrv->IsValid()) {
|
if ( pCrv->IsValid()) {
|
||||||
// eventuale inversione
|
// eventuale inversione
|
||||||
if ( dOffs > EPS_SMALL)
|
if ( dOffs > EPS_SMALL)
|
||||||
pCrv->Invert() ;
|
pCrv->Invert() ;
|
||||||
|
|
||||||
|
// sistemo i raccordi
|
||||||
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
||||||
|
IdentifyFillets( pCrv, dOffs) ;
|
||||||
|
AdjustCurveFillets( pCrv, dOffs, nType) ;
|
||||||
|
}
|
||||||
|
|
||||||
if ( bClosed) {
|
if ( bClosed) {
|
||||||
// forzo chiusura della curva per evitare piccole imprecisioni
|
// forzo chiusura della curva per evitare piccole imprecisioni
|
||||||
pCrv->Close() ;
|
pCrv->Close() ;
|
||||||
// sistemo il punto di inizio
|
// sistemo il punto di inizio
|
||||||
AdjustOffsetStart( *pCrv) ;
|
AdjustOffsetStart( *pCrv) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sistemo i raccordi
|
|
||||||
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
|
||||||
IdentifyFillets( pCrv, dOffs) ;
|
|
||||||
AdjustCurveFillets( pCrv, dOffs, nType) ;
|
|
||||||
}
|
|
||||||
// porto nel frame globale
|
// porto nel frame globale
|
||||||
pCrv->ToGlob( m_Frame) ;
|
pCrv->ToGlob( m_Frame) ;
|
||||||
// unisco le parti allineate
|
// unisco le parti allineate
|
||||||
@@ -614,12 +657,12 @@ Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bo
|
|||||||
|
|
||||||
// sistemo i raccordi
|
// sistemo i raccordi
|
||||||
if ( bClosed && bSquareMids) {
|
if ( bClosed && bSquareMids) {
|
||||||
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
|
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
|
||||||
IdentifyFillets( pCrvOffs, dOffs) ;
|
IdentifyFillets( pCrvOffs, dOffs) ;
|
||||||
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
|
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
|
||||||
}
|
}
|
||||||
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
|
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
|
||||||
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
|
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
|
||||||
// modificare solo quelli richiesti
|
// modificare solo quelli richiesti
|
||||||
for ( int j = 0 ; j < pCrvOffs->GetCurveCount() ; j ++) {
|
for ( int j = 0 ; j < pCrvOffs->GetCurveCount() ; j ++) {
|
||||||
int nOrigCrv ; pCrvOffs->GetCurveTempProp( j, nOrigCrv) ;
|
int nOrigCrv ; pCrvOffs->GetCurveTempProp( j, nOrigCrv) ;
|
||||||
@@ -660,75 +703,84 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs, bool bRightOff
|
|||||||
nOrigCrvCnt = pOrigCompo->GetCurveCount() ;
|
nOrigCrvCnt = pOrigCompo->GetCurveCount() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset di eventuali offset precedenti
|
try {
|
||||||
m_vroni->apiResetOffsetData() ;
|
// reset di eventuali offset precedenti
|
||||||
|
|
||||||
// verifico necessario calcolo o ricalcolo di Voronoi
|
|
||||||
UpdateVoronoi( dOffs) ;
|
|
||||||
|
|
||||||
string sTmp = "" ;
|
|
||||||
m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs, 0.0, false, bLeftOffs, bRightOffs) ;
|
|
||||||
int nOffsCnt = m_vroni->GetOffsetCount() ;
|
|
||||||
if ( nOffsCnt == 0) {
|
|
||||||
// se non ho ottenuto offset ritento con valore leggermente diverso per le tolleranze di vroni
|
|
||||||
m_vroni->apiResetOffsetData() ;
|
m_vroni->apiResetOffsetData() ;
|
||||||
m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs - VRONI_OFFS_TOL, 0.0, false, bLeftOffs, bRightOffs) ;
|
|
||||||
nOffsCnt = m_vroni->GetOffsetCount() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// recupero le curve di offset da vroni
|
// verifico necessario calcolo o ricalcolo di Voronoi
|
||||||
for ( int i = 0 ; i < nOffsCnt ; i++) {
|
UpdateVoronoi( dOffs) ;
|
||||||
PtrOwner<CurveComposite> pCrvOffs ( CreateBasicCurveComposite()) ;
|
|
||||||
int nCrvCnt = m_vroni->GetOffsetCurveCount( i) ; // numero di sottocurve
|
|
||||||
|
|
||||||
for ( int j = 0 ; j < nCrvCnt ; j ++) {
|
string sTmp = "" ;
|
||||||
// recupero la sottocurva da vroni
|
m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs, 0.0, false, bLeftOffs, bRightOffs) ;
|
||||||
Point3d ptS, ptE, ptC ;
|
int nOffsCnt = m_vroni->GetOffsetCount() ;
|
||||||
int nType ;
|
if ( nOffsCnt == 0) {
|
||||||
int nOrigCrv, nOrigLoop, nOrigPnt ; // sito
|
// se non ho ottenuto offset ritento con valore leggermente diverso per le tolleranze di vroni
|
||||||
m_vroni->GetOffsetCurve( i, j, nType, ptS.v, ptE.v, ptC.v, nOrigLoop, nOrigCrv, nOrigPnt) ;
|
m_vroni->apiResetOffsetData() ;
|
||||||
|
m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs - VRONI_OFFS_TOL, 0.0, false, bLeftOffs, bRightOffs) ;
|
||||||
if ( j == 0)
|
nOffsCnt = m_vroni->GetOffsetCount() ;
|
||||||
pCrvOffs->AddPoint( ptS) ;
|
|
||||||
|
|
||||||
bool bOk = false ;
|
|
||||||
if ( nType == t_site::SEG)
|
|
||||||
bOk = pCrvOffs->AddLine( ptE) ;
|
|
||||||
else {
|
|
||||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
|
||||||
pArc->Set2PRS( ptS, ptE, Dist( ptC, ptS), nType == CCW) ;
|
|
||||||
bOk = pCrvOffs->AddCurve( Release( pArc)) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// se la curva è stata aggiunta
|
|
||||||
if ( bOk) {
|
|
||||||
// setto come info la sottocurva da cui si è generata
|
|
||||||
int nCurrCrvId = pCrvOffs->GetCurveCount() - 1 ;
|
|
||||||
pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigCrv + 1, 0) ;
|
|
||||||
pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigLoop, 1) ;
|
|
||||||
// verifico se è raccordo relativo agli estremi della curva
|
|
||||||
if ( nOrigCrv == -1 && ( nOrigPnt == 0 || nOrigPnt == nOrigCrvCnt))
|
|
||||||
pCrvOffs->SetCurveTempParam( nCurrCrvId, 1.0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rimuovo tratti di lunghezza inferiore a 5 * EPS_SMALL
|
// recupero le curve di offset da vroni
|
||||||
RemoveCurveSmallParts( pCrvOffs, 5 * EPS_SMALL) ;
|
for ( int i = 0 ; i < nOffsCnt ; i++) {
|
||||||
|
PtrOwner<CurveComposite> pCrvOffs ( CreateBasicCurveComposite()) ;
|
||||||
|
int nCrvCnt = m_vroni->GetOffsetCurveCount( i) ; // numero di sottocurve
|
||||||
|
|
||||||
// aggiungo la curva alla lista degli offset
|
for ( int j = 0 ; j < nCrvCnt ; j ++) {
|
||||||
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid())
|
// recupero la sottocurva da vroni
|
||||||
OffsList.push_back( Release( pCrvOffs)) ;
|
Point3d ptS, ptE, ptC ;
|
||||||
|
int nType ;
|
||||||
|
int nOrigCrv, nOrigLoop, nOrigPnt ; // sito
|
||||||
|
m_vroni->GetOffsetCurve( i, j, nType, ptS.v, ptE.v, ptC.v, nOrigLoop, nOrigCrv, nOrigPnt) ;
|
||||||
|
|
||||||
|
if ( j == 0)
|
||||||
|
pCrvOffs->AddPoint( ptS) ;
|
||||||
|
|
||||||
|
bool bOk = false ;
|
||||||
|
if ( nType == t_site::SEG)
|
||||||
|
bOk = pCrvOffs->AddLine( ptE) ;
|
||||||
|
else {
|
||||||
|
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||||
|
pArc->Set2PRS( ptS, ptE, Dist( ptC, ptS), nType == CCW) ;
|
||||||
|
bOk = pCrvOffs->AddCurve( Release( pArc)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se la curva è stata aggiunta
|
||||||
|
if ( bOk) {
|
||||||
|
// setto come info la sottocurva da cui si è generata
|
||||||
|
int nCurrCrvId = pCrvOffs->GetCurveCount() - 1 ;
|
||||||
|
pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigCrv + 1, 0) ;
|
||||||
|
pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigLoop, 1) ;
|
||||||
|
// verifico se è raccordo relativo agli estremi della curva
|
||||||
|
if ( nOrigCrv == -1 && ( nOrigPnt == 0 || nOrigPnt == nOrigCrvCnt))
|
||||||
|
pCrvOffs->SetCurveTempParam( nCurrCrvId, 1.0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rimuovo tratti di lunghezza inferiore a 5 * EPS_SMALL
|
||||||
|
RemoveCurveSmallParts( pCrvOffs, 5 * EPS_SMALL) ;
|
||||||
|
|
||||||
|
// aggiungo la curva alla lista degli offset
|
||||||
|
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid())
|
||||||
|
OffsList.push_back( Release( pCrvOffs)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// libero la memoria di vroni dedicata agli offset
|
||||||
|
m_vroni->apiFreeOffsetData() ;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
Voronoi::UpdateVoronoi( double dOffs)
|
Voronoi::UpdateVoronoi( double dOffs)
|
||||||
{
|
{
|
||||||
double dNeededBound = abs( dOffs) / 0.49 / sqrt( m_bBox.GetDimX() * m_bBox.GetDimX() + m_bBox.GetDimY() * m_bBox.GetDimY()) ;
|
// calcolo il bound necessario per l'offset desiderato
|
||||||
|
double dNeededBound = abs( dOffs) / 0.49 / sqrt( m_bBox.GetDimX() * m_bBox.GetDimX() + m_bBox.GetDimY() * m_bBox.GetDimY()) ;
|
||||||
if ( ! m_bVDComputed || dNeededBound > m_nBound) {
|
if ( ! m_bVDComputed || dNeededBound > m_nBound) {
|
||||||
// aggiorno il valore del bound
|
// aggiorno il valore del bound
|
||||||
int nBound = ( int)( ceil( dNeededBound) + 0.5) ;
|
int nBound = ( int)( ceil( dNeededBound) + 0.5) ;
|
||||||
@@ -737,7 +789,6 @@ Voronoi::UpdateVoronoi( double dOffs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -747,7 +798,7 @@ Voronoi::VerifyCurvesValidityForOffset()
|
|||||||
if ( m_vpCrvs.size() == 1)
|
if ( m_vpCrvs.size() == 1)
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
// se ho più curve, devono essere tutte chiuse
|
// se ho più curve, devono essere tutte chiuse
|
||||||
for ( auto pCrv : m_vpCrvs) {
|
for ( auto pCrv : m_vpCrvs) {
|
||||||
if ( ! pCrv->IsClosed())
|
if ( ! pCrv->IsClosed())
|
||||||
return false ;
|
return false ;
|
||||||
@@ -767,12 +818,29 @@ Voronoi::VerifyCurvesValidityForOffset()
|
|||||||
|
|
||||||
// se curva con orientamento principale verifico sia esterna a tutte le altre curve con orientamento principale
|
// se curva con orientamento principale verifico sia esterna a tutte le altre curve con orientamento principale
|
||||||
if ( vArea[i] * dRefArea > EPS_SMALL) {
|
if ( vArea[i] * dRefArea > EPS_SMALL) {
|
||||||
for ( int j = i + 1 ; j < ( int)vArea.size() ; j++) {
|
for ( int j = 0 ; j < ( int)vArea.size() ; j++) {
|
||||||
if ( vArea[i] * vArea[j] > EPS_SMALL) {
|
if ( j != i && vArea[i] * vArea[j] > EPS_SMALL) {
|
||||||
IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[j]) ;
|
IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[j]) ;
|
||||||
int nRes = ccInt.GetRegionCurveClassification() ;
|
int nRes = ccInt.GetRegionCurveClassification() ;
|
||||||
if ( ( bRefCCW && nRes != CCREGC_OUT) || ( ! bRefCCW && nRes != CCREGC_IN1))
|
if ( nRes == CCREGC_NULL || nRes == CCREGC_SAME || nRes == CCREGC_INTERS)
|
||||||
return false ;
|
return false ;
|
||||||
|
if ( ( bRefCCW && nRes == CCREGC_IN1) || ( ! bRefCCW && nRes == CCREGC_IN2)) {
|
||||||
|
// se è interna ad una curva con orientamento principale, verifico sia esterna ad almeno una curva con orientamento
|
||||||
|
// diverso dal principale
|
||||||
|
bool bFound = false ;
|
||||||
|
for ( int k = 0 ; k < ( int)vArea.size() ; k++) {
|
||||||
|
if ( k != i && vArea[i] * vArea[k] < EPS_SMALL) {
|
||||||
|
IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[k]) ;
|
||||||
|
int nRes = ccInt.GetRegionCurveClassification() ;
|
||||||
|
if ( ( bRefCCW && nRes == CCREGC_OUT) || ( ! bRefCCW && nRes == CCREGC_IN1)) {
|
||||||
|
bFound = true ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! bFound)
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -842,7 +910,7 @@ Voronoi::AdjustOpenOffsetCurve( ICurveComposite& pCompo, double dOffs)
|
|||||||
// mi posiziono dopo la junction
|
// mi posiziono dopo la junction
|
||||||
pCompo.ChangeStartPoint( vJunctions[0] + 1) ;
|
pCompo.ChangeStartPoint( vJunctions[0] + 1) ;
|
||||||
delete( pCompo.RemoveFirstOrLastCurve()) ;
|
delete( pCompo.RemoveFirstOrLastCurve()) ;
|
||||||
// verifico validità della curva
|
// verifico validità della curva
|
||||||
int nSide = GetOffsetCurveSide( pCompo, 0) ;
|
int nSide = GetOffsetCurveSide( pCompo, 0) ;
|
||||||
if ( nSide == nSideRef) {
|
if ( nSide == nSideRef) {
|
||||||
// scorro fino alla prima curva non valida ed elimino la curva da quel punto fino alla fine
|
// scorro fino alla prima curva non valida ed elimino la curva da quel punto fino alla fine
|
||||||
@@ -853,7 +921,7 @@ Voronoi::AdjustOpenOffsetCurve( ICurveComposite& pCompo, double dOffs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// elimino finchè non trovo una curva valida
|
// elimino finchè non trovo una curva valida
|
||||||
while( nSide != nSideRef && pCompo.IsValid()) {
|
while( nSide != nSideRef && pCompo.IsValid()) {
|
||||||
delete( pCompo.RemoveFirstOrLastCurve( false)) ;
|
delete( pCompo.RemoveFirstOrLastCurve( false)) ;
|
||||||
if ( pCompo.IsValid())
|
if ( pCompo.IsValid())
|
||||||
|
|||||||
Reference in New Issue
Block a user