5e42cf86c4
- correzione calcolo intersezioni Linea-Box.
152 lines
5.7 KiB
C++
152 lines
5.7 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2020-2020
|
|
//----------------------------------------------------------------------------
|
|
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
|
// Contenuto : Implementazione della intersezione linea/box.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 07.05.20 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "SurfTriMesh.h"
|
|
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
|
{
|
|
Vector3d vtL = ptL2 - ptL1 ;
|
|
double dLen = vtL.Len() ;
|
|
if ( dLen > EPS_SMALL)
|
|
vtL /= dLen ;
|
|
else
|
|
vtL = V_NULL ;
|
|
return IntersLineBox( ptL1, vtL, dLen, b3Box, vInters, bFinite) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
|
{
|
|
// Recupero i dati del Box
|
|
Point3d ptMin ;
|
|
double dDimX, dDimY, dDimZ ;
|
|
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
|
return false ;
|
|
// Contorno di base
|
|
PolyLine PL ;
|
|
PL.AddUPoint( 0, ptMin) ;
|
|
PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0, 0)) ;
|
|
PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY, 0)) ;
|
|
PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY, 0)) ;
|
|
PL.Close() ;
|
|
// Vettore altezza
|
|
Vector3d vtExtr( 0, 0, dDimZ) ;
|
|
// Creo la superficie trimesh equivalente
|
|
SurfTriMesh Stm ;
|
|
if ( ! Stm.CreateByExtrusion( PL, vtExtr))
|
|
return false ;
|
|
SurfTriMesh StmBot ;
|
|
if ( ! StmBot.CreateByFlatContour( PL))
|
|
return false ;
|
|
StmBot.Invert() ;
|
|
SurfTriMesh StmTop ;
|
|
if ( ! StmTop.CreateByFlatContour( PL))
|
|
return false ;
|
|
StmTop.Translate( vtExtr) ;
|
|
if ( ! Stm.DoSewing( StmBot) || ! Stm.DoSewing( StmTop))
|
|
return false ;
|
|
// Calcolo l'intersezione
|
|
ILSIVECTOR vInfo ;
|
|
if ( ! IntersLineSurfTm( ptL, vtL, dLen, Stm, vInfo, bFinite))
|
|
return false ;
|
|
// ciclo sulle intersezioni
|
|
double dUcurr = -INFINITO ;
|
|
for ( const auto& Info : vInfo) {
|
|
// se intersezione puntuale
|
|
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
|
int nFlag = ILBT_TOUCH ;
|
|
if ( Info.dCosDN > EPS_ZERO)
|
|
nFlag = ILBT_OUT ;
|
|
else if ( Info.dCosDN < -EPS_ZERO)
|
|
nFlag = ILBT_IN ;
|
|
vInters.emplace_back( nFlag, Info.dU) ;
|
|
dUcurr = Info.dU ;
|
|
}
|
|
// se altrimenti intersezione con coincidenza
|
|
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
|
if ( Info.dU > dUcurr - EPS_SMALL)
|
|
vInters.emplace_back( ILBT_TG_INI, Info.dU) ;
|
|
vInters.emplace_back( ILBT_TG_FIN, Info.dU2) ;
|
|
dUcurr = Info.dU2 ;
|
|
}
|
|
}
|
|
// elimino intersezioni ripetute
|
|
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
|
// intersezione precedente
|
|
size_t i = j - 1 ;
|
|
// se sono dello stesso tipo, elimino una delle due
|
|
if ( vInters[i].first == vInters[j].first) {
|
|
// se entranti elimino la prima
|
|
if ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_TG_INI)
|
|
vInters.erase( vInters.begin() + i) ;
|
|
// altrimenti la seconda
|
|
else
|
|
vInters.erase( vInters.begin() + j) ;
|
|
if ( i > 0)
|
|
-- j ;
|
|
continue ;
|
|
}
|
|
// se hanno lo stesso parametro
|
|
else if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
|
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
|
if ( ( vInters[i].first == ILBT_IN && vInters[j].first == ILBT_OUT) ||
|
|
( vInters[i].first == ILBT_OUT && vInters[j].first == ILBT_IN)) {
|
|
vInters[i].first = ILBT_TOUCH ;
|
|
vInters.erase( vInters.begin() + j) ;
|
|
if ( i > 0)
|
|
-- j ;
|
|
continue ;
|
|
}
|
|
// se prima puntuale e l'altra inizio o fine di coincidenza, elimino la prima
|
|
else if ( ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TOUCH) &&
|
|
( vInters[j].first == ILBT_TG_INI || vInters[j].first == ILBT_TG_FIN)) {
|
|
vInters.erase( vInters.begin() + i) ;
|
|
if ( i > 0)
|
|
-- j ;
|
|
continue ;
|
|
}
|
|
// se prima inizio o fine di coincidenza e l'altra puntuale, elimino la seconda
|
|
else if ( ( vInters[i].first == ILBT_TG_INI || vInters[i].first == ILBT_TG_FIN) &&
|
|
( vInters[j].first == ILBT_IN || vInters[j].first == ILBT_OUT || vInters[j].first == ILBT_TOUCH)) {
|
|
vInters.erase( vInters.begin() + j) ;
|
|
if ( i > 0)
|
|
-- j ;
|
|
continue ;
|
|
}
|
|
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
|
else if ( ( vInters[i].first == ILBT_TG_FIN && vInters[j].first == ILBT_TG_INI) ||
|
|
( vInters[i].first == ILBT_TG_INI && vInters[j].first == ILBT_TG_FIN)) {
|
|
vInters.erase( vInters.begin() + j) ;
|
|
vInters.erase( vInters.begin() + i) ;
|
|
if ( i > 0)
|
|
-- j ;
|
|
continue ;
|
|
}
|
|
}
|
|
// passo alla successiva
|
|
++ j ;
|
|
}
|
|
|
|
return true ;
|
|
}
|