EgtGeomKernel 2.4a3 :
- modifiche a IntersLineBox e IntersPlaneBox - adattamenti conseguenti.
This commit is contained in:
+127
-108
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// File : IntersLineBox.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
//
|
||||
//
|
||||
@@ -13,13 +13,77 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico gli estremi del box
|
||||
if ( ptMin.x > ptMax.x + EPS_SMALL ||
|
||||
ptMin.y > ptMax.y + EPS_SMALL ||
|
||||
ptMin.z > ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtL.x) < EPS_ZERO && ( ptL.x < ptMin.x - EPS_SMALL || ptL.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.y) < EPS_ZERO && ( ptL.y < ptMin.y - EPS_SMALL || ptL.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.z) < EPS_ZERO && ( ptL.z < ptMin.z - EPS_SMALL || ptL.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Parametri degli estremi della retta
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtL.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
else if ( vtL.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtL.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
else if ( vtL.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtL.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
else if ( vtL.z < -EPS_ZERO){
|
||||
dU1 = max( dU1, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
@@ -38,114 +102,69 @@ 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))
|
||||
Point3d ptMin, ptMax ;
|
||||
if ( ! b3Box.GetMinMax( ptMin, ptMax))
|
||||
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 ;
|
||||
|
||||
// Pulisco vettore intersezioni
|
||||
vInters.clear() ;
|
||||
|
||||
// Eseguo intersezione della linea completa
|
||||
double dU1, dU2 ;
|
||||
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
||||
|
||||
// Se non c'è intersezione
|
||||
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
||||
return true ;
|
||||
|
||||
// Se le due intersezioni coincidono
|
||||
if ( ( dU2 - dU1) < EPS_SMALL) {
|
||||
double dU = ( dU1 + dU2) / 2 ;
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TOUCH, 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 ;
|
||||
else {
|
||||
if ( dU > - EPS_SMALL && dU < dLen + EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TOUCH, Clamp( dU, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
// 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 ;
|
||||
}
|
||||
|
||||
// Se sono due intersezioni con la linea giacente su una faccia del box
|
||||
if ( ( abs( vtL.x) < EPS_ZERO && ( abs( ptL.x - ptMin.x) < EPS_SMALL || abs( ptL.x - ptMax.x) < EPS_SMALL)) ||
|
||||
( abs( vtL.y) < EPS_ZERO && ( abs( ptL.y - ptMin.y) < EPS_SMALL || abs( ptL.y - ptMax.y) < EPS_SMALL)) ||
|
||||
( abs( vtL.z) < EPS_ZERO && ( abs( ptL.z - ptMin.z) < EPS_SMALL || abs( ptL.z - ptMax.z) < EPS_SMALL))) {
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TG_INI, dU1) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Altrimenti sono due intersezioni con attraversamento
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_IN, dU1) ;
|
||||
vInters.emplace_back( ILBT_OUT, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user