3b6de06fd9
- a BBox3d aggiunti metodi SqMaxDistFromPoint, SqMaxDistFromPointXY, MaxDistFromPoint e MaxDistFromPointXY - a IntersLineSurfTm e IntersParLine aggiunto parametro bFinite per indicare se linea finita o infinita.
163 lines
5.8 KiB
C++
163 lines
5.8 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : IntersLineSurfTm.cpp Data : 09.03.15 Versione : 1.6b8
|
|
// Contenuto : Implementazione della intersezione linea/superficie trimesh.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 09.03.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "ProjPlane.h"
|
|
#include "IntersLineSurfTm.h"
|
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
|
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
|
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
|
{
|
|
Point3d ptInt, ptInt2 ;
|
|
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, bFinite) ;
|
|
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
|
double dU = ( ptInt - ptL) * vtDir ;
|
|
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 = ( ptInt - ptL) * vtDir ;
|
|
double dU2 = ( ptInt2 - ptL) * vtDir ;
|
|
double dCosDN = vtDir * Tria.GetN() ;
|
|
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
OrderInfoIntersLineSurfTm( ILSIVECTOR& 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 IntLinStmInfo& a, const IntLinStmInfo& 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 linea con una superficie TriMesh
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfTriMesh& Stm,
|
|
ILSIVECTOR& vInfo, bool bFinite)
|
|
{
|
|
// verifico linea
|
|
Vector3d vtDir = vtL ;
|
|
if ( ! vtDir.Normalize( EPS_ZERO))
|
|
return false ;
|
|
// verifico superficie
|
|
if ( &Stm == nullptr)
|
|
return false ;
|
|
// verifico parametro di ritorno
|
|
if ( &vInfo == nullptr)
|
|
return false ;
|
|
vInfo.clear() ;
|
|
|
|
// cerco i triangoli intersecati dalla linea
|
|
Triangle3d Tria ;
|
|
int nT = Stm.GetFirstTriangle( Tria) ;
|
|
while ( nT != SVT_NULL) {
|
|
// aggiorno info con intersezione
|
|
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ;
|
|
// passo al prossimo triangolo
|
|
nT = Stm.GetNextTriangle( nT, Tria) ;
|
|
}
|
|
|
|
// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea
|
|
OrderInfoIntersLineSurfTm( vInfo) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Intersezione di molte linee parallele con una superficie TriMesh
|
|
//----------------------------------------------------------------------------
|
|
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm)
|
|
: m_bOk( false), m_frLines( frLines), m_pSTm( &Stm)
|
|
{
|
|
// verifico esistenza superficie
|
|
if ( m_pSTm == nullptr || ! m_pSTm->IsValid())
|
|
return ;
|
|
|
|
// creo HashGrid 2d
|
|
const int LIM_HG_TRIA = 128 ;
|
|
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
|
|
|
|
// riempio HashGrid
|
|
Triangle3d Tria ;
|
|
int nT = Stm.GetFirstTriangle( Tria) ;
|
|
while ( nT != SVT_NULL) {
|
|
// calcolo il BBox del triangolo nel riferimento scelto
|
|
Tria.ToLoc( m_frLines) ;
|
|
BBox3d b3Tria ;
|
|
b3Tria.Add( Tria.GetP( 0)) ;
|
|
b3Tria.Add( Tria.GetP( 1)) ;
|
|
b3Tria.Add( Tria.GetP( 2)) ;
|
|
// inserisco nella griglia
|
|
if ( ! m_HGrids.Add( nT, b3Tria))
|
|
return ;
|
|
// passo al prossimo triangolo
|
|
nT = Stm.GetNextTriangle( nT, Tria) ;
|
|
}
|
|
// aggiorno
|
|
m_bOk = m_HGrids.Update() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vInfo, bool bFinite)
|
|
{
|
|
// verifico validità
|
|
if ( ! m_bOk)
|
|
return false ;
|
|
// verifico parametro di ritorno
|
|
if ( &vInfo == nullptr)
|
|
return false ;
|
|
vInfo.clear() ;
|
|
|
|
// calcolo box linea (nel riferimento)
|
|
BBox3d b3Line ;
|
|
b3Line.Add( ptL) ;
|
|
|
|
// calcolo punto nel riferimento trimesh
|
|
Point3d ptLL = ptL ;
|
|
ptLL.ToGlob( m_frLines) ;
|
|
|
|
// recupero indici triangoli che intersecano box in 2d
|
|
INTVECTOR vnIds ;
|
|
if ( m_HGrids.Find( b3Line, vnIds)) {
|
|
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
|
int nT = vnIds[i] ;
|
|
Triangle3d Tria ;
|
|
m_pSTm->GetTriangle( nT, Tria) ;
|
|
// aggiorno info con intersezione
|
|
UpdateInfoIntersLineSurfTm( ptLL, m_frLines.VersZ(), dLen, nT, Tria, vInfo, bFinite) ;
|
|
}
|
|
}
|
|
|
|
// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea
|
|
OrderInfoIntersLineSurfTm( vInfo) ;
|
|
|
|
return true ;
|
|
} |