Merge remote-tracking branch 'origin/master' into Bezier_trim&mesh
This commit is contained in:
+103
-30
@@ -53,7 +53,8 @@ BBox3d::Set( double dX1, double dY1, double dZ1, double dX2, double dY2, double
|
||||
bool
|
||||
BBox3d::IsValid( void) const
|
||||
{
|
||||
return ( m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
||||
return ( m_ptMin.IsValid() && m_ptMax.IsValid() &&
|
||||
m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
||||
m_ptMin.y < ( m_ptMax.y + EPS_SMALL) &&
|
||||
m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ;
|
||||
}
|
||||
@@ -447,69 +448,141 @@ BBox3d::EnclosesXY( const BBox3d& b3Box) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::Overlaps( const BBox3d& b3B) const
|
||||
BBox3d::Overlaps( const BBox3d& b3Box) const
|
||||
{
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
|
||||
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::OverlapsXY( const BBox3d& b3B) const
|
||||
BBox3d::OverlapsXY( const BBox3d& b3Box) const
|
||||
{
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const
|
||||
inline bool
|
||||
TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
|
||||
const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
|
||||
{
|
||||
if ( ! IsValid() || ! b3B.IsValid())
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
double dLen = ( vtAx.IsNormalized() ? 1 : vtAx.Len()) ;
|
||||
return ( abs( vtDiff * vtAx) >
|
||||
abs( vtHe.x * vtAx.x) + abs( vtHe.y * vtAx.y) + abs( vtHe.z * vtAx.z) +
|
||||
abs( vtHe2X * vtAx) + abs( vtHe2Y * vtAx) + abs( vtHe2Z * vtAx) + EPS_SMALL * dLen) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const
|
||||
{
|
||||
// Verifico validità di entrambi i box
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
|
||||
// Centro e semiampiezza del box
|
||||
Point3d ptCen = ( m_ptMin + m_ptMax) / 2 ;
|
||||
Vector3d vtHe = ( m_ptMax - m_ptMin) / 2 ;
|
||||
// Centro e semiampiezza dell'altro box
|
||||
Point3d ptCen2 = GetToGlob( ( b3Box.m_ptMin + b3Box.m_ptMax) / 2, frBox) ;
|
||||
Vector3d vtHe2X = GetToGlob( Vector3d( ( b3Box.GetDimX()) / 2, 0, 0), frBox) ;
|
||||
Vector3d vtHe2Y = GetToGlob( Vector3d( 0, ( b3Box.GetDimY()) / 2, 0), frBox) ;
|
||||
Vector3d vtHe2Z = GetToGlob( Vector3d( 0, 0, ( b3Box.GetDimZ()) / 2), frBox) ;
|
||||
// Vettore tra i due centri
|
||||
Vector3d vtDiff = ptCen2 - ptCen ;
|
||||
|
||||
// Verifico separazione sulle normali ai piani principali del riferimento globale
|
||||
if ( TestSeparatingAxis( X_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
|
||||
// Verifico separazione sulle normali ai piani principali del secondo riferimento
|
||||
if ( TestSeparatingAxis( frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
|
||||
// Verifico separazione sulle altre normali ottenute come prodotto vettoriali di quelle precedenti
|
||||
if ( TestSeparatingAxis( X_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( X_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( X_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
|
||||
// Si sovrappongono
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersection( const BBox3d& b3Box, BBox3d& b3Int) const
|
||||
{
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
// verifico direttamente la sovrapposizione
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
|
||||
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
// calcolo il box intersezione
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ;
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const
|
||||
BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const
|
||||
{
|
||||
if ( ! IsValid() || ! b3B.IsValid())
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
// verifico direttamente la sovrapposizione
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
// calcolo il box intersezione
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3B.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3B.m_ptMax.z) ;
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -301,11 +301,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
|
||||
b3Tool.Add( ptTL) ;
|
||||
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
|
||||
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
|
||||
if ( vtDirL.IsX())
|
||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
|
||||
else if ( vtDirL.IsY())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
|
||||
else if ( vtDirL.IsZ())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
||||
else {
|
||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
|
||||
|
||||
+11
-8
@@ -23,17 +23,17 @@ using namespace std ;
|
||||
bool
|
||||
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// calcolo il BBox del parallelepipedo
|
||||
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
|
||||
// Calcolo il BBox del parallelepipedo
|
||||
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Box.Expand( dSafeDist) ;
|
||||
b3Box.ToGlob( frBox) ;
|
||||
b3BoxL.Expand( dSafeDist) ;
|
||||
BBox3d b3Box = GetToGlob( b3BoxL, frBox) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Box.Overlaps( b3Poly))
|
||||
if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box
|
||||
// Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Box, vT) ;
|
||||
for ( int nT : vT) {
|
||||
@@ -46,7 +46,10 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il box è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
|
||||
return false ;
|
||||
// Verifico se il box è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptBoxCen = ORIG + vtDiag / 2 ;
|
||||
ptBoxCen.ToGlob( frBox) ;
|
||||
DistPointSurfTm DistBoxCenSurfCalc( ptBoxCen, Stm) ;
|
||||
|
||||
@@ -35,60 +35,60 @@ using namespace std ;
|
||||
bool
|
||||
CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB, double dSafeDist)
|
||||
{
|
||||
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
|
||||
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
|
||||
if ( ! ( SurfA.IsValid() && SurfB.IsValid()) || ! ( SurfA.IsClosed() && SurfB.IsClosed()))
|
||||
return false ;
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
BBox3d b3BoxA, b3BoxB ;
|
||||
SurfA.GetLocalBBox( b3BoxA) ;
|
||||
SurfB.GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxA.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||
return false ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
INTVECTOR vTriaIndex ;
|
||||
SurfA.GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
|
||||
// Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
|
||||
// Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
|
||||
for ( int nTA : vTriaIndex) {
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! ( SurfA.GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
|
||||
continue ;
|
||||
BBox3d b3BoxTriaA ;
|
||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxTriaA.Expand( dSafeDist) ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
INTVECTOR vNearTria ;
|
||||
SurfB.GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TFlags dei triangoli valgono 0.
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TFlags dei triangoli valgono 0.
|
||||
SurfB.ResetTempInt() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
for ( int nTB : vNearTria) {
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
|
||||
continue ;
|
||||
// Se necessario considero l'offset
|
||||
// Se necessario considero l'offset
|
||||
if ( dSafeDist > EPS_SMALL) {
|
||||
int nAdjTriaId[3] ;
|
||||
SurfB.GetTriangleAdjacencies( nTB, nAdjTriaId) ;
|
||||
// Ciclo sui vertici del triangolo.
|
||||
// Ciclo sui vertici del triangolo.
|
||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
int nAdjTriaTempFlag ;
|
||||
if ( ! ( SurfB.GetTriangleTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
continue ;
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||
return true ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( nVB) - trTriaB.GetP( ( nVB + 1) % 3) ;
|
||||
double dEdgeLen = vtEdgeV.Len() ;
|
||||
vtEdgeV /= dEdgeLen ;
|
||||
@@ -97,18 +97,21 @@ CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB,
|
||||
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
|
||||
return true ;
|
||||
}
|
||||
// Traslo il triangolo
|
||||
// Traslo il triangolo
|
||||
trTriaB.Translate( dSafeDist * trTriaB.GetN()) ;
|
||||
}
|
||||
// Processo il triangolo: se i due triangoli collidono ho finito.
|
||||
// Processo il triangolo: se i due triangoli collidono ho finito.
|
||||
if ( CDeTriaTria( trTriaA, trTriaB))
|
||||
return true ;
|
||||
// Segno il triangolo come processato: nTFlag = 1
|
||||
// Segno il triangolo come processato: nTemp = 1
|
||||
SurfB.SetTempInt( nTB, 1) ;
|
||||
}
|
||||
}
|
||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
|
||||
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
||||
return false ;
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
Point3d ptPointA, ptPointB ;
|
||||
SurfA.GetFirstVertex( ptPointA) ;
|
||||
SurfB.GetFirstVertex( ptPointB) ;
|
||||
|
||||
@@ -27,24 +27,25 @@ bool
|
||||
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||
double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// Se il tronco di cono non è ben definito non ha senso proseguire.
|
||||
// Se il tronco di cono non è ben definito non ha senso proseguire
|
||||
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
// Recupero BBox della trimesh
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox del tronco di cono
|
||||
double dMaxRad = max( dBaseRad, dTopRad) ;
|
||||
BBox3d b3Cone( - dMaxRad, - dMaxRad, 0, dMaxRad, dMaxRad, dHeight) ;
|
||||
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0),
|
||||
Point3d( dMaxRad, dMaxRad, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Cone.Expand( dSafeDist) ;
|
||||
b3Cone.ToGlob( frCone) ;
|
||||
b3ConeL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Cone.Overlaps( b3Surf))
|
||||
if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del cono
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
|
||||
// Ciclo sui triangoli che interferiscono col box del cono
|
||||
// Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
@@ -55,6 +56,9 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Se il BBox del tronco di cono non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Cone) && ! b3Cone.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il tronco di cono è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptConeCen( 0, 0, dHeight / 2) ;
|
||||
ptConeCen.ToGlob( frCone) ;
|
||||
|
||||
@@ -23,42 +23,42 @@ using namespace std ;
|
||||
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
|
||||
// La funzione restituisce true in caso di collisione.
|
||||
bool
|
||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorusFrame, double dRad1, double dRad2,
|
||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
||||
double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// I raggi devono essere non nulli e la superficie ben definita.
|
||||
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
|
||||
return false ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3ConvTorusBox ;
|
||||
b3ConvTorusBox.Set( Point3d( - dRad1 - dRad2, - dRad1 - dRad2, - dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
// Aggiungo eventuale distanza di sicurezza
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3ConvTorusBox.Expand( dSafeDist) ;
|
||||
// Porto il box del toro nel riferimento della superficie (inteso some globale)
|
||||
b3ConvTorusBox.ToGlob( frTorusFrame) ;
|
||||
// Box della superficie
|
||||
BBox3d b3SurfBox = Stm.GetAllTriaBox() ;
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3TorusL.Expand( dSafeDist) ;
|
||||
BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3ConvTorusBox.Overlaps( b3SurfBox))
|
||||
if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del toro
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3ConvTorusBox, vT) ;
|
||||
// Ciclo sui triangoli recuperati
|
||||
Stm.GetAllTriaOverlapBox( b3Torus, vT) ;
|
||||
// Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
if ( CDeConvexTorusTria( frTorusFrame, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
||||
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptTorusOrig = frTorusFrame.Orig() ;
|
||||
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptTorusOrig = frTorus.Orig() ;
|
||||
DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ;
|
||||
// Se il toro è interno c'è collisione
|
||||
return ( DistConeOrigSurfCalc.IsPointInside()) ;
|
||||
|
||||
+17
-13
@@ -23,38 +23,42 @@ using namespace std ;
|
||||
bool
|
||||
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// sistemazioni cilindro
|
||||
Frame3d frC = frCyl ;
|
||||
// Sistemazioni cilindro
|
||||
Frame3d frMyCyl = frCyl ;
|
||||
if ( dH < 0) {
|
||||
frC.Translate( dH * frC.VersZ()) ;
|
||||
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
|
||||
dH = - dH ;
|
||||
}
|
||||
// calcolo il BBox del cilindro
|
||||
BBox3d b3Cyl( -dR, -dR, 0, dR, dR, dH) ;
|
||||
// Calcolo il BBox del cilindro
|
||||
BBox3d b3CylL( Point3d( -dR, -dR, 0),
|
||||
Point3d( dR, dR, dH)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Cyl.Expand( dSafeDist) ;
|
||||
b3Cyl.ToGlob( frC) ;
|
||||
b3CylL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Cyl.Overlaps( b3Poly))
|
||||
if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box del Cilindro
|
||||
// Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
|
||||
for ( int nT : vT) {
|
||||
Triangle3d Tria ;
|
||||
if ( Stm.GetTriangle( nT, Tria)) {
|
||||
if ( CDeCylTria( frC, dR, dH, dSafeDist, Tria))
|
||||
if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
|
||||
return false ;
|
||||
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptCylCen( 0, 0, dH / 2) ;
|
||||
ptCylCen.ToGlob( frC) ;
|
||||
ptCylCen.ToGlob( frMyCyl) ;
|
||||
DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ;
|
||||
// Se il cilindro è interno c'è collisione
|
||||
return ( DistCylCenSurfCalc.IsPointInside()) ;
|
||||
|
||||
@@ -37,17 +37,18 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// Calcolo il BBox del tronco di piramide
|
||||
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
|
||||
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
|
||||
BBox3d b3Pyr( -dMaxLenX / 2, -dMaxLenY / 2, 0., dMaxLenX / 2, dMaxLenY / 2, dHeight) ;
|
||||
BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
|
||||
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Pyr.Expand( dSafeDist) ;
|
||||
b3Pyr.ToGlob( frPrismoid) ;
|
||||
b3PyrL.Expand( dSafeDist) ;
|
||||
BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Pyr.Overlaps( b3Surf))
|
||||
if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del tronco di piramide.
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
|
||||
// Ciclo sui triangoli che interferiscono col box del tronco di piramide.
|
||||
// Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
@@ -59,10 +60,13 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptPyrCen( 0, 0, dHeight / 2) ;
|
||||
ptPyrCen.ToGlob( frPrismoid) ;
|
||||
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
|
||||
// C'è collisione se il tronco di piramide è interno.
|
||||
// C'è collisione se il tronco di piramide è interno
|
||||
return ( DistPyrCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
@@ -23,16 +23,16 @@ using namespace std ;
|
||||
bool
|
||||
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// calcolo il BBox della sfera
|
||||
// Calcolo il BBox della sfera
|
||||
BBox3d b3Sphe( ptCen, dR) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Sphe.Expand( dSafeDist) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Sphe.Overlaps( b3Poly))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box della Sfera
|
||||
// Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
|
||||
for ( int nT : vT) {
|
||||
@@ -45,8 +45,11 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
|
||||
return false ;
|
||||
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
DistPointSurfTm DistCenSurfCalc( ptCen, Stm) ;
|
||||
// C'è collisione se la sfera è interna.
|
||||
// C'è collisione se la sfera è interna.
|
||||
return ( DistCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
+4
-4
@@ -824,10 +824,10 @@ CurveArc::Validate( void)
|
||||
m_dAngCenDeg = - ANG_FULL ;
|
||||
}
|
||||
// eseguo il controllo
|
||||
m_nStatus = ( ( m_VtN.IsNormalized() && m_VtS.IsNormalized() &&
|
||||
AreOrthoApprox( m_VtN, m_VtS) &&
|
||||
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
|
||||
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
|
||||
m_nStatus = ( ( m_PtCen.IsValid() &&
|
||||
m_VtN.IsNormalized() && m_VtS.IsNormalized() && AreOrthoApprox( m_VtN, m_VtS) &&
|
||||
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
|
||||
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
|
||||
}
|
||||
|
||||
return ( m_nStatus == OK) ;
|
||||
|
||||
+7
-5
@@ -294,7 +294,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea)
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
|
||||
// calcolo l'area
|
||||
double dAreaXY = 0 ;
|
||||
PL.GetAreaXY( dAreaXY) ;
|
||||
@@ -313,7 +313,7 @@ CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea)
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
|
||||
// calcolo l'area
|
||||
Plane3d plMyPlane ;
|
||||
double dMyArea = 0 ;
|
||||
@@ -364,9 +364,11 @@ CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine)
|
||||
// altri dati per curva chiusa
|
||||
double dAreaXY ;
|
||||
if ( CurveGetAreaXY( crvC, dAreaXY)) {
|
||||
bool bCCW = ( dAreaXY > 0) ;
|
||||
bool bCCW = ( dAreaXY > 0) ;
|
||||
double dAreaUi = GetAreaInUiUnits( abs( dAreaXY), bMM) ;
|
||||
int nDec = ( dAreaUi > 100 ? 1 : ( dAreaUi > 0.1 ? 3 : 6)) ;
|
||||
sOut += string( "Closed") + ( bCCW ? " CCW" : " CW") + " AreaXY=" +
|
||||
ToString( GetAreaInUiUnits( abs( dAreaXY), bMM),1) + szNewLine ;
|
||||
ToString( dAreaUi, nDec) + szNewLine ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -728,7 +730,7 @@ FlattenCurve( const ICurve& crCrv, double dToler, double dAngToler, int nFlag)
|
||||
return nullptr ;
|
||||
// Verifico se curva già piatta
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL))
|
||||
return nullptr ;
|
||||
bool bFlat = true ;
|
||||
Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ;
|
||||
|
||||
@@ -424,6 +424,23 @@ CurveBezier::Load( NgeReader& ngeIn)
|
||||
bool
|
||||
CurveBezier::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
for ( const auto& ptP : m_vPtCtrl) {
|
||||
if ( ! ptP.IsValid()) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
for ( const auto& dWe : m_vWeCtrl) {
|
||||
if ( ! isfinite( dWe)) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_nStatus == TO_VERIFY)
|
||||
m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ;
|
||||
|
||||
|
||||
+16
-4
@@ -849,9 +849,9 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
||||
return false ;
|
||||
// ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali)
|
||||
int nCount = 0 ;
|
||||
for ( const ICurve* pCrv = GetFirstCurve() ;
|
||||
for ( const ICurve* pCrv = GetCurve( nCount) ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = GetNextCurve(), ++ nCount) {
|
||||
pCrv = GetCurve( ++ nCount)) {
|
||||
switch ( pCrv->GetType()) {
|
||||
case CRV_LINE :
|
||||
// punto finale
|
||||
@@ -985,7 +985,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL_INT, PL))
|
||||
return false ;
|
||||
// calcolo il centro mediante PolygonPlane
|
||||
Point3d ptP ;
|
||||
@@ -1313,7 +1313,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
|
||||
|
||||
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
|
||||
if ( nType == APL_SPECIAL) {
|
||||
if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) {
|
||||
// eseguo approssimazione
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
@@ -1324,6 +1324,18 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
PolyLine PLSmpl ;
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl))
|
||||
return false ;
|
||||
// se richiesto almeno un punto interno con curve non rettilinee e ci sono solo gli estremi
|
||||
if ( nType == APL_SPECIAL_INT && pCrv->GetType() != CRV_LINE && PLSmpl.GetPointNbr() == 2) {
|
||||
// aggiungo il punto interno
|
||||
Point3d ptMid ;
|
||||
if ( ! pCrv->GetMidPoint( ptMid))
|
||||
return false ;
|
||||
double dU ;
|
||||
PLSmpl.GetLastU( dU) ;
|
||||
dU /= 2 ;
|
||||
PNTULIST& List = PLSmpl.GetUPointList() ;
|
||||
List.insert( ++ List.begin(), { ptMid, dU}) ;
|
||||
}
|
||||
// ripristino estrusione e spessore della curva semplice (annullandoli)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ bool
|
||||
CurveLine::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY)
|
||||
m_nStatus = ( ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
|
||||
m_nStatus = ( m_PtStart.IsValid() && m_PtEnd.IsValid() && ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
|
||||
|
||||
return ( m_nStatus == OK) ;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -331,6 +331,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="ExtDimension.cpp" />
|
||||
<ClCompile Include="HashGrids1d.cpp" />
|
||||
<ClCompile Include="IntersLineBox.cpp" />
|
||||
<ClCompile Include="IntersLineCone.cpp" />
|
||||
<ClCompile Include="IntersLineCyl.cpp" />
|
||||
<ClCompile Include="IntersLineSphere.cpp" />
|
||||
<ClCompile Include="IntersLineSurfStd.cpp" />
|
||||
<ClCompile Include="IntersPlaneBox.cpp" />
|
||||
@@ -600,6 +602,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="IntersCrvCompoCrvCompo.h" />
|
||||
<ClInclude Include="IntersLineArc.h" />
|
||||
<ClInclude Include="IntersLineBox.h" />
|
||||
<ClInclude Include="IntersLineCone.h" />
|
||||
<ClInclude Include="IntersLineCyl.h" />
|
||||
<ClInclude Include="IntersLineLine.h" />
|
||||
<ClInclude Include="IntersLineSurfStd.h" />
|
||||
<ClInclude Include="IntersLineTria.h" />
|
||||
|
||||
@@ -473,6 +473,11 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="Tree.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
<ClCompile Include="IntersLineCyl.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineCone.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -1107,6 +1112,10 @@
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Tree.h">
|
||||
<ClInclude Include="IntersLineCyl.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineCone.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -456,6 +456,9 @@ Frame3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
bool
|
||||
Frame3d::Verify( void)
|
||||
{
|
||||
// verifica origine
|
||||
if ( ! m_ptOrig.IsValid())
|
||||
return false ;
|
||||
// verifica della ortogonalità dei versori e del senso destrorso
|
||||
double dOrtXY = m_vtVersX * m_vtVersY ;
|
||||
double dOrtYZ = m_vtVersY * m_vtVersZ ;
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCone.cpp Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Implementazione della intersezione linea/tronco di cono.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCone.h"
|
||||
#include "IntersLineCyl.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e tronco di cono sono nel medesimo riferimento.
|
||||
// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRadMin, double dRadMax, double dHeight,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico il tronco di cono
|
||||
if ( ( dRadMin < EPS_SMALL && dRadMax < EPS_SMALL) || dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Se è un cilindro, rimando a questo
|
||||
if ( abs( dRadMax - dRadMin) < EPS_SMALL)
|
||||
return IntersLineCyl( ptL, vtL, ( dRadMin + dRadMax) / 2, dHeight, dU1, dU2) ;
|
||||
|
||||
// Se raggi invertiti, li scambio
|
||||
if ( dRadMin > dRadMax)
|
||||
swap( dRadMin, dRadMax) ;
|
||||
|
||||
// Tangente dell'angolo di semi-apertura del cono
|
||||
double dTanTheta = ( dRadMax - dRadMin) / dHeight ;
|
||||
double dSqTanTheta = dTanTheta * dTanTheta ;
|
||||
double dSqCosTheta = 1 / ( 1 + dSqTanTheta) ;
|
||||
|
||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non giace sul cono)
|
||||
int nBasInt = 0 ;
|
||||
if ( abs( vtL.z) > EPS_ZERO) {
|
||||
// le linee tangenti al cono non sono considerate intersecanti
|
||||
bool bSameHAng = ( abs( abs( vtL.x) - abs( vtL.y)) < EPS_SMALL && abs( dSqCosTheta - vtL.z * vtL.z) < 2 * abs( vtL.z) * EPS_SMALL) ;
|
||||
double EpsRad = ( bSameHAng ? - EPS_SMALL : EPS_SMALL) ;
|
||||
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRadMin * dRadMin + 2 * dRadMin * EpsRad) {
|
||||
dU1 = ( ptInt1 - ptL) * vtL ;
|
||||
nBasInt += 1 ;
|
||||
}
|
||||
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRadMax * dRadMax + 2 * dRadMax * EpsRad) {
|
||||
dU2 = ( ptInt2 - ptL) * vtL ;
|
||||
nBasInt += 2 ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
||||
if ( nBasInt == 3) {
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Posizione del vertice del cono
|
||||
double dDeltaH = ( dRadMin < EPS_SMALL ? 0 : dRadMin / dTanTheta) ;
|
||||
// Sposto il punto di passaggio della linea di conseguenza
|
||||
Point3d ptMyL = ptL + Z_AX * dDeltaH ;
|
||||
|
||||
// Determino le intersezioni con la superficie laterale del cono
|
||||
DBLVECTOR vdCoeff{ ptMyL.x * ptMyL.x + ptMyL.y * ptMyL.y - ptMyL.z * ptMyL.z * dSqTanTheta,
|
||||
2 * ( ptMyL.x * vtL.x + ptMyL.y * vtL.y - ptMyL.z * vtL.z * dSqTanTheta),
|
||||
vtL.x * vtL.x + vtL.y * vtL.y - vtL.z * vtL.z * dSqTanTheta} ;
|
||||
DBLVECTOR vdRoots ;
|
||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||
|
||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del tronco di cono
|
||||
if ( nRoot == 2) {
|
||||
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
|
||||
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
|
||||
-- nRoot ;
|
||||
}
|
||||
if ( nRoot >= 1) {
|
||||
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
|
||||
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
|
||||
if ( nRoot == 2)
|
||||
vdRoots[0] = vdRoots[1] ;
|
||||
-- nRoot ;
|
||||
}
|
||||
}
|
||||
|
||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
||||
if ( nRoot == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
dU2 = vdRoots[1] ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
||||
else if ( nRoot == 1) {
|
||||
// Se piano superiore
|
||||
if ( nBasInt == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti piano inferiore
|
||||
else if ( nBasInt == 1) {
|
||||
dU2 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti niente
|
||||
else
|
||||
return false ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Nessuna soluzione : nessuna intersezione
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCone.h Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Dichiarazione funzioni base per intersezione linea/cono tronco.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e tronco di cono sono nel medesimo riferimento.
|
||||
// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRadMin, double dRadMax, double dHeight,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineCone( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRadMin, double dRadMax, double dHeight)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineCone( ptL, vtL, dRadMin, dRadMax, dHeight, dU1, dU2) ;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCyl.cpp Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Implementazione della intersezione linea/cilindro.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCyl.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRad, double dHeight,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico il cilindro
|
||||
if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
|
||||
int nBasInt = 0 ;
|
||||
if ( abs( vtL.z) > EPS_ZERO) {
|
||||
// le linee tangenti al cilindro non sono considerate intersecanti
|
||||
double EpsRad = ( vtL.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
||||
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * EpsRad) {
|
||||
dU1 = ( ptInt1 - ptL) * vtL ;
|
||||
nBasInt += 1 ;
|
||||
}
|
||||
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * EpsRad) {
|
||||
dU2 = ( ptInt2 - ptL) * vtL ;
|
||||
nBasInt += 2 ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
||||
if ( nBasInt == 3) {
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Determino le intersezioni con la superficie laterale del cilindro
|
||||
DBLVECTOR vdCoeff{ ptL.x * ptL.x + ptL.y * ptL.y - dRad * dRad,
|
||||
2 * ( ptL.x * vtL.x + ptL.y * vtL.y),
|
||||
vtL.x * vtL.x + vtL.y * vtL.y} ;
|
||||
DBLVECTOR vdRoots ;
|
||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||
|
||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
|
||||
if ( nRoot == 2) {
|
||||
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
|
||||
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
|
||||
-- nRoot ;
|
||||
}
|
||||
if ( nRoot >= 1) {
|
||||
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
|
||||
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
|
||||
if ( nRoot == 2)
|
||||
vdRoots[0] = vdRoots[1] ;
|
||||
-- nRoot ;
|
||||
}
|
||||
}
|
||||
|
||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
||||
if ( nRoot == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
dU2 = vdRoots[1] ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
||||
else if ( nRoot == 1) {
|
||||
// Se piano superiore
|
||||
if ( nBasInt == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti piano inferiore
|
||||
else if ( nBasInt == 1) {
|
||||
dU2 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti niente
|
||||
else
|
||||
return false ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Nessuna soluzione : nessuna intersezione
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCyl.h Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Dichiarazione funzioni base per intersezione linea/cilindro.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRad, double dHeight,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRad, double dHeight)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineCyl( ptL, vtL, dRad, dHeight, dU1, dU2) ;
|
||||
}
|
||||
+13
-8
@@ -26,20 +26,25 @@ IntersLineSphere( const Point3d& ptL, const Vector3d& vtL, const Point3d& ptCen,
|
||||
return ILST_NO ;
|
||||
// Proiezione del centro della sfera sulla linea
|
||||
Point3d ptP = ptL + (( ptCen - ptL) * vtL) * vtL ;
|
||||
// Distanza di questo punto di proiezione dal centro della sfera
|
||||
double dDist = Dist( ptCen, ptP) ;
|
||||
// Quadrato della distanza di questo punto di proiezione dal centro della sfera
|
||||
double dSqDist = SqDist( ptCen, ptP) ;
|
||||
// Differenza tra quadrato del raggio e quadrato della distanza
|
||||
double dSqDelta = dRad * dRad - dSqDist ;
|
||||
|
||||
// Se distanza superiore al raggio, nessuna intersezione
|
||||
if ( dSqDelta < - 2 * dRad * EPS_SMALL)
|
||||
return ILST_NO ;
|
||||
|
||||
// Se distanza uguale al raggio, intersezione tangente
|
||||
if ( abs( dDist - dRad) < EPS_SMALL) {
|
||||
if ( dSqDelta < EPS_SMALL * EPS_SMALL) {
|
||||
ptI1 = ptP ;
|
||||
ptI2 = ptP ;
|
||||
return ILST_TG ;
|
||||
}
|
||||
// Se distanza superiore al raggio, nessuna intersezione
|
||||
if ( dDist > dRad)
|
||||
return ILST_NO ;
|
||||
|
||||
// Distanza inferiore al raggio, due intersezioni secanti
|
||||
double dDist2 = sqrt( dRad * dRad - dDist * dDist) ;
|
||||
double dDist2 = sqrt( dSqDelta) ;
|
||||
ptI1 = ptP - dDist2 * vtL ;
|
||||
ptI2 = ptP + dDist2 * vtL ;
|
||||
return ILST_SEC ;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-4
@@ -454,7 +454,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
vLen.pop_back() ;
|
||||
}
|
||||
// eseguo la divisione
|
||||
int nCount = 1 ;
|
||||
double dUPrev = 0 ;
|
||||
double dLenPrev = 0 ;
|
||||
for ( int i = 0 ; i < int( vU.size()) ; ++ i) {
|
||||
@@ -466,7 +465,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( IsNull( pCopy))
|
||||
return false ;
|
||||
m_CrvLst.push_back( Release( pCopy)) ;
|
||||
++ nCount ;
|
||||
// trimmo l'originale
|
||||
pCompo1->TrimStartEndAtParam( dUPrev, vU[i]) ;
|
||||
// la copia diventa il nuovo corrente
|
||||
@@ -474,9 +472,15 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
dUPrev = vU[i] ;
|
||||
dLenPrev = vLen[i] ;
|
||||
}
|
||||
// se fatta almeno una suddivisione, trimmo l'ultima parte
|
||||
if ( dUPrev > EPS_PARAM)
|
||||
// se fatta almeno una suddivisione
|
||||
bool bFirstLastSame = false ;
|
||||
if ( dUPrev > EPS_PARAM) {
|
||||
// trimmo l'ultima parte
|
||||
pCompo1->TrimStartAtParam( dUPrev) ;
|
||||
// rilevo le curve chiuse con due parti di una stessa curva all'inizio e alla fine
|
||||
if ( bClosed && vU[0] > EPS_PARAM && vLen[0] >= 2 * EPS_SMALL)
|
||||
bFirstLastSame = true ;
|
||||
}
|
||||
|
||||
// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
|
||||
if ( ! bClosed) {
|
||||
@@ -581,6 +585,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
}
|
||||
|
||||
// settimo passo : elimino le parti che sono troppo vicine al percorso originale
|
||||
bool bFirstLastDeleted = false ;
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
|
||||
ICurve* pCrv = *iIter ;
|
||||
// distanza minima di alcuni punti interni della curva dalla curva originale
|
||||
@@ -591,8 +596,24 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
GetMinDist( 0.875, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL ||
|
||||
GetMinDist( 0.0625, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL ||
|
||||
GetMinDist( 0.9375, pCrv, &ccCopy) < abs( dDist) - 5 * EPS_SMALL) {
|
||||
// se prima e ultima sono la stessa curva e non ancora cancellate e prima da cancellare
|
||||
if ( bFirstLastSame && ! bFirstLastDeleted && iIter == m_CrvLst.begin()) {
|
||||
bFirstLastDeleted = true ;
|
||||
// cancello ultima
|
||||
delete *prev( m_CrvLst.end()) ;
|
||||
m_CrvLst.pop_back() ;
|
||||
}
|
||||
// se prima e ultima sono la stessa curva e non ancora cancellate e ultima da cancellare
|
||||
if ( bFirstLastSame && ! bFirstLastDeleted && iIter == prev( m_CrvLst.end())) {
|
||||
bFirstLastDeleted = true ;
|
||||
// cancello prima
|
||||
delete *m_CrvLst.begin() ;
|
||||
m_CrvLst.pop_front() ;
|
||||
}
|
||||
// cancello la corrente
|
||||
delete pCrv ;
|
||||
iIter = m_CrvLst.erase( iIter) ;
|
||||
// evito incremento
|
||||
continue ;
|
||||
}
|
||||
// passo alla successiva
|
||||
|
||||
+69
-53
@@ -20,8 +20,11 @@
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -394,15 +397,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
}
|
||||
// se altrimenti guida aperta e tappi arrotondati
|
||||
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
//POLYLINEVECTOR vPL ;
|
||||
//if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
// return nullptr ;
|
||||
//Plane3d plEnds ; double dArea ;
|
||||
//if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
//if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
// step di rotazione per rispettare la tolleranza
|
||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||
// aggiungo il cap sull'inizio
|
||||
@@ -437,8 +431,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
// elimino eventuali fessure
|
||||
//pSTM->Repair() ;
|
||||
}
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
@@ -461,29 +453,37 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
// determino se la guida è chiusa
|
||||
bool bGuideClosed = pGuide->IsClosed() ;
|
||||
// curve di offset
|
||||
OffsetCurve OffsCrvR ;
|
||||
if ( ! OffsCrvR.Make( pGuide, dDimH / 2 - dBevelH, ICurve::OFF_FILLET) || OffsCrvR.GetCurveCount() == 0)
|
||||
const int NUM_OFFS = 4 ;
|
||||
OffsetCurve vOffsCrv[NUM_OFFS] ;
|
||||
double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ;
|
||||
future<bool> vRes[NUM_OFFS] ;
|
||||
for ( int i = 0 ; i < NUM_OFFS ; ++ i)
|
||||
vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
||||
bool bOk = true ;
|
||||
int nFin = 0 ;
|
||||
while ( nFin < NUM_OFFS) {
|
||||
for ( int i = 0 ; i < NUM_OFFS ; ++ i) {
|
||||
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
||||
bOk = vRes[i].get() && bOk ;
|
||||
++ nFin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! bOk ||
|
||||
vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
||||
vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvR( OffsCrvR.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvR( vOffsCrv[0].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvR))
|
||||
return nullptr ;
|
||||
OffsetCurve OffsCrvL ;
|
||||
if ( ! OffsCrvL.Make( pGuide, -dDimH / 2 + dBevelH, ICurve::OFF_FILLET) || OffsCrvL.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvL( OffsCrvL.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvL( vOffsCrv[1].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvL))
|
||||
return nullptr ;
|
||||
OffsetCurve OffsCrvRb ;
|
||||
if ( ! OffsCrvRb.Make( pGuide, dDimH / 2, ICurve::OFF_FILLET) || OffsCrvRb.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvRb( OffsCrvRb.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvRb( vOffsCrv[2].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvRb))
|
||||
return nullptr ;
|
||||
pCrvRb->Translate( - dBevelV * vtNorm) ;
|
||||
OffsetCurve OffsCrvLb ;
|
||||
if ( ! OffsCrvLb.Make( pGuide, -dDimH / 2, ICurve::OFF_FILLET) || OffsCrvLb.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
PtrOwner<ICurve> pCrvLb( OffsCrvLb.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pCrvLb( vOffsCrv[3].GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvLb))
|
||||
return nullptr ;
|
||||
pCrvLb->Translate( - dBevelV * vtNorm) ;
|
||||
@@ -518,19 +518,29 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSrfLft))
|
||||
return nullptr ;
|
||||
// unisco le parti
|
||||
PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
|
||||
pSTM->DoSewing( *pSrfTopR) ;
|
||||
pSTM->DoSewing( *pSrfTopL) ;
|
||||
pSTM->DoSewing( *pSrfRgt) ;
|
||||
pSTM->DoSewing( *pSrfLft) ;
|
||||
pSTM->DoSewing( *pSrfBotR) ;
|
||||
pSTM->DoSewing( *pSrfBotL) ;
|
||||
pSTM->DoSewing( *pSrfBot) ;
|
||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
pSTM->SetSmoothAngle( 20) ;
|
||||
int nBuckets = max( 4 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
|
||||
StmFromTriangleSoup stmSoup ;
|
||||
if ( ! stmSoup.Start( nBuckets))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTop) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTopR) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTopL) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfRgt) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfLft) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBotR) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBotL) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBot) ;
|
||||
PtrOwner<ISurfTriMesh> pSTM ;
|
||||
// se guida aperta e tappi piatti
|
||||
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
// preparo seconda zuppa di triangoli per inserire i tappi
|
||||
StmFromTriangleSoup stmCapSoup ;
|
||||
if ( ! stmCapSoup.Start( nBuckets))
|
||||
return nullptr ;
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
POLYLINEVECTOR vPL ;
|
||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
@@ -545,25 +555,20 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
pSTM->DoSewing( *pSci) ;
|
||||
stmCapSoup.AddSurfTriMesh( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
stmCapSoup.AddSurfTriMesh( *pSce) ;
|
||||
// completo unione con i tappi e recupero la superficie risultante
|
||||
if ( ! stmCapSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmCapSoup.GetSurf()) ;
|
||||
}
|
||||
// se altrimenti guida aperta e tappi arrotondati
|
||||
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
//POLYLINEVECTOR vPL ;
|
||||
//if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
// return nullptr ;
|
||||
//Plane3d plEnds ; double dArea ;
|
||||
//if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
//if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
// return nullptr ;
|
||||
else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// step di rotazione per rispettare il tipo o la tolleranza
|
||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||
// aggiungo il cap sull'inizio
|
||||
@@ -583,7 +588,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
pSTM->DoSewing( *pSci) ;
|
||||
stmSoup.AddSurfTriMesh( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
Point3d ptEnd ;
|
||||
pGuide->GetEndPoint( ptEnd) ;
|
||||
@@ -601,10 +606,21 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
// elimino eventuali fessure
|
||||
//pSTM->Repair() ;
|
||||
stmSoup.AddSurfTriMesh( *pSce) ;
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
}
|
||||
else {
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
}
|
||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
pSTM->SetSmoothAngle( 20) ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
+27
-4
@@ -1,10 +1,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2015
|
||||
// EgalTech 2014-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : StmFromTriangleSoup.cpp Data : 19.05.14 Versione : 1.5e7
|
||||
// File : StmFromTriangleSoup.cpp Data : 07.05.23 Versione : 2.5e2
|
||||
// Contenuto : Implementazione della classe StmFromTriangleSoup, per creare
|
||||
// una superficie trimesh da un insieme disordinato di triangoli(STL).
|
||||
//
|
||||
// una superficie trimesh da un insieme di triangoli
|
||||
// (può essere disordinato come STL o può essere una superficie).
|
||||
//
|
||||
// Modifiche : 19.05.14 DS Creazione modulo.
|
||||
//
|
||||
@@ -112,6 +112,29 @@ StmFromTriangleSoup::AddVertex( const Point3d& ptP)
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::AddSurfTriMesh( const ISurfTriMesh& stmSource)
|
||||
{
|
||||
// verifico inizializzazione
|
||||
if ( m_pSTM == nullptr)
|
||||
return false ;
|
||||
// verifico superficie sorgente
|
||||
if ( &stmSource == nullptr || ! stmSource.IsValid())
|
||||
return false ;
|
||||
// recupero tutti i triangoli della superficie
|
||||
bool bOk ;
|
||||
Triangle3d Tria ;
|
||||
int nT = stmSource.GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// inserisco il triangolo nella zuppa
|
||||
bOk = AddTriangle( Tria) && bOk ;
|
||||
// passo al triangolo successivo
|
||||
nT = stmSource.GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::End( void)
|
||||
|
||||
+1
-1
@@ -3003,7 +3003,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou
|
||||
|
||||
// definisco un Grid per i vertici delle due superfici
|
||||
PointGrid3d VertGrid ;
|
||||
int nBuckets = GetVertexSize() + pOther->GetVertexSize() ;
|
||||
int nBuckets = max( GetVertexSize() + pOther->GetVertexSize(), 1000) ;
|
||||
VertGrid.Init( nBuckets) ;
|
||||
|
||||
// inserisco i vertici della trimesh corrente (li considero tutti diversi tra loro)
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool UpdateOneFace( int nFacet, int nT) ;
|
||||
bool UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) ;
|
||||
bool SetFacet( int nInd, int nT) ;
|
||||
bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ;
|
||||
bool VerifyAdjacTriaFacet( INTVECTOR& vT) const ;
|
||||
bool MarchAlongFacetLoop( int nF, int nT, int nV, int nTimeStamp, PolyLine& PL) const ;
|
||||
bool MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
|
||||
void ResetHashGrids3d( void) const ;
|
||||
|
||||
+7
-14
@@ -394,20 +394,13 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
|
||||
// Fra le catene trovate separo le aperte dalle chiuse
|
||||
int nDegenerateChainNum = 0 ;
|
||||
INTVECTOR vnDegVec ;
|
||||
CHAINVECTOR cvClosedChain ;
|
||||
CHAINVECTOR cvOpenChain ;
|
||||
for ( int nL = 0 ; nL < int( vChain.size()) ; ++ nL) {
|
||||
bool bChainDegenerate = false ;
|
||||
if ( vChain[nL].size() == 1 && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][0].ptEn)) {
|
||||
bChainDegenerate = true ;
|
||||
}
|
||||
|
||||
if ( bChainDegenerate)
|
||||
++ nDegenerateChainNum ;
|
||||
bool bChainDegenerate = ( vChain[nL].size() == 1 && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][0].ptEn)) ;
|
||||
int nCurLoopLast = max( int( vChain[nL].size()) - 1, 0) ;
|
||||
if ( ( ! bChainDegenerate) && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn))
|
||||
if ( ! bChainDegenerate && AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn))
|
||||
cvClosedChain.emplace_back( vChain[nL]) ;
|
||||
else {
|
||||
cvOpenChain.emplace_back( vChain[nL]) ;
|
||||
@@ -446,7 +439,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
|
||||
// Gestione tagli piccoli
|
||||
if ( int( cvOpenChain.size()) == 1 && int( cvOpenChain[0].size()) == 1 && int( cvClosedChain.size()) == 0) {
|
||||
if ( cvOpenChain.size() == 1 && cvOpenChain[0].size() == 1 && cvClosedChain.empty()) {
|
||||
if ( AreSamePointEpsilon( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].ptEn, EPS_SMALL)) {
|
||||
Plane3d plPlane ;
|
||||
plPlane.Set( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].vtOuter) ;
|
||||
@@ -511,7 +504,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop usando le catene
|
||||
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
|
||||
if ( int( cvBoundClosedLoopVec.size()) == 1 && int( cvOpenChain.size()) == 2) {
|
||||
if ( cvBoundClosedLoopVec.size() == 1 && cvOpenChain.size() == 2) {
|
||||
Point3d ptLink0St = cvOpenChain[0][0].ptSt ;
|
||||
Point3d ptLink0En = cvOpenChain[0].back().ptEn ;
|
||||
Point3d ptLink1St = cvOpenChain.back()[0].ptSt ;
|
||||
@@ -571,7 +564,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
POLYLINEVECTOR vplPolyVec ;
|
||||
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
|
||||
for ( int nLoop = 0 ; nLoop < int( vplPolyVec.size()) ; ++ nLoop) {
|
||||
for (int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
|
||||
for ( int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
|
||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][nLine]) ;
|
||||
}
|
||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][0]) ;
|
||||
@@ -1616,7 +1609,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Subtract")
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
@@ -1750,7 +1743,7 @@ SurfTriMesh::Repair( double dMaxEdgeLen)
|
||||
|
||||
// Ritriangolo le facce
|
||||
if ( ! SimplifyFacets( dMaxEdgeLen, true))
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Repair")
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
+21
-12
@@ -17,6 +17,7 @@
|
||||
#include "GeoConst.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <array>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -223,25 +224,33 @@ SurfTriMesh::GetAllTriaInFacet( int nF, INTVECTOR& vT) const
|
||||
vT.reserve( 10) ;
|
||||
vT.push_back( nT) ;
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
return VerifyAdjacTriaFacet( nT, vT) ;
|
||||
return VerifyAdjacTriaFacet( vT) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const
|
||||
SurfTriMesh::VerifyAdjacTriaFacet( INTVECTOR& vT) const
|
||||
{
|
||||
// verifico i triangoli adiacenti
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL &&
|
||||
m_vTria[nAdjT].nTemp != m_nTimeStamp &&
|
||||
m_vTria[nAdjT].nIdFacet == m_vTria[nT].nIdFacet) {
|
||||
vT.push_back( nAdjT) ;
|
||||
m_vTria[nAdjT].nTemp = m_nTimeStamp ;
|
||||
if ( ! VerifyAdjacTriaFacet( nAdjT, vT))
|
||||
return false ;
|
||||
INTVECTOR vStack{ vT.back()} ;
|
||||
while ( ! vStack.empty()) {
|
||||
array<int,3> vNew{ SVT_NULL, SVT_NULL, SVT_NULL} ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[vStack.back()].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL &&
|
||||
m_vTria[nAdjT].nTemp != m_nTimeStamp &&
|
||||
m_vTria[nAdjT].nIdFacet == m_vTria[vStack.back()].nIdFacet) {
|
||||
vT.push_back( nAdjT) ;
|
||||
vNew[j] = nAdjT ;
|
||||
m_vTria[nAdjT].nTemp = m_nTimeStamp ;
|
||||
}
|
||||
}
|
||||
vStack.pop_back() ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
if ( vNew[j] != SVT_NULL)
|
||||
vStack.push_back( vNew[j]) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+385
-531
File diff suppressed because it is too large
Load Diff
+2
-10
@@ -2047,14 +2047,6 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
||||
else {
|
||||
|
||||
if ( nVertComp[nComp] == 5) {
|
||||
double dDotAvarage = 0.;
|
||||
for (int m = 0; m < nVertComp[nComp] - 1; ++m) {
|
||||
for (int l = m + 1 ; l < nVertComp[nComp]; ++l) {
|
||||
dDotAvarage += CompoVert[nComp][m].vtVec * CompoVert[nComp][l].vtVec;
|
||||
}
|
||||
}
|
||||
dDotAvarage /= (( nVertComp[nComp] * ( nVertComp[nComp] - 1)) / 2) ;
|
||||
|
||||
int nNumPar = 0 ;
|
||||
for ( int m = 0 ; m < nVertComp[nComp] - 1 ; ++ m) {
|
||||
for ( int l = m + 1 ; l < nVertComp[nComp] ; ++ l) {
|
||||
@@ -2062,9 +2054,9 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
||||
++ nNumPar ;
|
||||
}
|
||||
}
|
||||
bExtConfirmed = nNumPar == 3 ;
|
||||
bExtConfirmed = ( nNumPar == 3) ;
|
||||
}
|
||||
else if (nVertComp[nComp] < 5) {
|
||||
else if ( nVertComp[nComp] < 5) {
|
||||
bExtConfirmed = false ;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user