From 4056be90d9b2bbc7ca10004d948b8189dcd8e15e Mon Sep 17 00:00:00 2001 From: DarioS Date: Sun, 9 Jan 2022 15:17:00 +0100 Subject: [PATCH] EgtGeomKernel 2.4a3 : - modifiche a IntersLineBox e IntersPlaneBox - adattamenti conseguenti. --- EgtGeomKernel.rc | Bin 11718 -> 11718 bytes EgtGeomKernel.vcxproj | 1 + EgtGeomKernel.vcxproj.filters | 3 + IntersLineBox.cpp | 235 ++++++++++++++++++---------------- IntersLineBox.h | 34 +++++ IntersLineSurfStd.cpp | 59 +-------- IntersLineSurfStd.h | 5 - IntersLineSurfTm.cpp | 7 +- IntersPlaneBox.cpp | 40 +++++- VolZmap.h | 3 - VolZmapCalculus.cpp | 109 +--------------- VolZmapGraphics.cpp | 1 + 12 files changed, 213 insertions(+), 284 deletions(-) create mode 100644 IntersLineBox.h diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index f90dde081807f4f8b48e64f427b9ac94f72cc9e9..795d3fad3c062ef3fec8fd71bb9e7b0ac4e697cc 100644 GIT binary patch delta 100 zcmX>WeJpyzFE&Qw&G*I5Gfl4J(wY2?Q;pGhvLd(cW-qP@EMOU1W|)YS2jk{G;Q$~X Qr~yeBsu05nEu}f!0J`iS_5c6? delta 100 zcmX>WeJpyzFE&P_&G*I5Gfl4J(wY2?Q;pGRvLd(cW-qP@EMOU1W|)YS2jk{G;Q$~X Qr~yeBsu05nEu}f!0J&5j?f?J) diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index d4f0978..3aa404b 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -588,6 +588,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index e2f9b3d..a6f4b03 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -1085,6 +1085,9 @@ File di intestazione + + File di intestazione + diff --git a/IntersLineBox.cpp b/IntersLineBox.cpp index 64b5b86..e3c30f7 100644 --- a/IntersLineBox.cpp +++ b/IntersLineBox.cpp @@ -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 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 ; } diff --git a/IntersLineBox.h b/IntersLineBox.h new file mode 100644 index 0000000..1d0af21 --- /dev/null +++ b/IntersLineBox.h @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------------- +// EgalTech 2022-2022 +//---------------------------------------------------------------------------- +// File : IntersLineBox.h Data : 08.01.22 Versione : 2.4a3 +// Contenuto : Dichiarazione delle funzioni base per intersezione linea/box. +// +// +// +// Modifiche : 08.01.22 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "/EgtDev/Include/EGkPoint3d.h" + +//---------------------------------------------------------------------------- +// Linea e box allineato agli assi sono nel medesimo riferimento. +// Con 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) ; + +//---------------------------------------------------------------------------- +inline bool +TestIntersLineBox( const Point3d& ptL, const Vector3d& vtL, + const Point3d& ptMin, const Point3d& ptMax) +{ + double dU1, dU2 ; + return IntersLineBox( ptL, vtL, ptMin, ptMax, dU1, dU2) ; +} diff --git a/IntersLineSurfStd.cpp b/IntersLineSurfStd.cpp index 24c8d16..7657f19 100644 --- a/IntersLineSurfStd.cpp +++ b/IntersLineSurfStd.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2017-2018 +// EgalTech 2017-2022 //---------------------------------------------------------------------------- -// File : IntersLineSurfStd.cpp Data : 03.12.18 Versione : 1.9l1 +// File : IntersLineSurfStd.cpp Data : 08.01.22 Versione : 2.4a3 // Contenuto : Implementazione delle funzioni di intersezione // componente lineare e superficie standard. // @@ -13,6 +13,7 @@ #include "stdafx.h" #include "IntersLineSurfStd.h" +#include "IntersLineBox.h" #include "/EgtDev/Include/EGkIntersLinePlane.h" #include "/EgtDev/Include/EGkFrame3d.h" #include "/EgtDev/Include/ENkPolynomialRoots.h" @@ -21,60 +22,6 @@ using namespace std ; -//---------------------------------------------------------------------------- -// Punti e vettore devono essere espressi nel medesimo sistema di riferimento. -// Il box è allineato con gli assi di questo sistema di riferimento. -// In caso di intersezione viene restituito true e i parametri in dU1 e dU2. -//---------------------------------------------------------------------------- -bool -IntersLineBox( const Point3d& ptP, const Vector3d& vtV, - const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) -{ - // Casi di intersezione impossibile - if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL)) - return false ; - if ( abs( vtV.y) < EPS_ZERO && ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL)) - return false ; - if ( abs( vtV.z) < EPS_ZERO && ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL)) - return false ; - - // Inizializzo parametri intersezioni - dU1 = -INFINITO ; - dU2 = INFINITO ; - - // Confronto con piani YZ (perpendicolari ad asse X) - if ( vtV.x > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ; - dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ; - } - else if ( vtV.x < -EPS_ZERO) { - dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ; - dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ; - } - - // Confronto con piani ZX (perpendicolari ad asse Y) - if ( vtV.y > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ; - dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ; - } - else if ( vtV.y < -EPS_ZERO) { - dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ; - dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ; - } - - // Confronto con piani XY (perpendicolari ad asse Z) - if ( vtV.z > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ; - dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ; - } - else if ( vtV.z < -EPS_ZERO) { - dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ; - dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ; - } - - return ( dU2 >= dU1) ; -} - //---------------------------------------------------------------------------- int LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine, diff --git a/IntersLineSurfStd.h b/IntersLineSurfStd.h index 3287d0f..4a0dee0 100644 --- a/IntersLineSurfStd.h +++ b/IntersLineSurfStd.h @@ -34,11 +34,6 @@ // Costanti tipologia di componente lineare enum LinType { Line = 0, Ray = 1, Segment = 2} ; -//---------------------------------------------------------------------------- -bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, - const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ; - - // Costanti tipologia di intersezioni fra un componente lineare e un disco enum LinCompDiscIntersType { D_ERROR_INT = -1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1, D_INNER_INT_LINE_NOT_IN_PLANE = 2, D_ONE_INT_LINE_ON_PLANE = 3, diff --git a/IntersLineSurfTm.cpp b/IntersLineSurfTm.cpp index c479398..1031d5a 100644 --- a/IntersLineSurfTm.cpp +++ b/IntersLineSurfTm.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2019 +// EgalTech 2015-2022 //---------------------------------------------------------------------------- -// File : IntersLineSurfTm.cpp Data : 09.03.15 Versione : 2.1b6 +// File : IntersLineSurfTm.cpp Data : 08.01.22 Versione : 2.4a3 // Contenuto : Implementazione della intersezione linea/superficie trimesh. // // @@ -14,8 +14,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ProjPlane.h" -#include "IntersLineSurfStd.h" -#include "/EgtDev/Include/EGkSurfTriMesh.h" +#include "IntersLineBox.h" #include "/EgtDev/Include/EGkIntersLineTria.h" #include "/EgtDev/Include/EGkIntersLineSurfTm.h" diff --git a/IntersPlaneBox.cpp b/IntersPlaneBox.cpp index 6b0a3cb..51c0912 100644 --- a/IntersPlaneBox.cpp +++ b/IntersPlaneBox.cpp @@ -1,8 +1,8 @@ //---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- -// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1 -// Contenuto : Implementazione della intersezione linea/box. +// File : IntersPlaneBox.cpp Data : 07.05.20 Versione : 2.2e1 +// Contenuto : Implementazione della intersezione piano/box. // // // @@ -20,19 +20,47 @@ using namespace std ; //---------------------------------------------------------------------------- +// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned. bool -IntersPlaneBox( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box, +TestIntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box) +{ + // Verifica del piano + if ( ! plPlane.IsValid()) + return false ; + // Centro e estensione del box + Point3d ptCen ; + Vector3d vtExt ; + if ( ! b3Box.GetCenterExtent( ptCen, vtExt)) + return false ; + // Distanza del centro dal piano + double dDist = DistPointPlane( ptCen, plPlane) ; + // Proiezione dell'estensione sulla normale al piano + Vector3d vtN = plPlane.GetVersN() ; + double dProjExt = vtExt.x * abs( vtN.x) + vtExt.y * abs( vtN.y) + vtExt.z * abs( vtN.z) ; + // Confronto distanza del centro con estensione proiettata + return ( abs( dDist) < dProjExt + EPS_SMALL) ; +} + +//---------------------------------------------------------------------------- +bool +IntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box, PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria) { - // Creo il piano - Plane3d plPlane ; - if ( ! plPlane.Set( ptOn, vtN)) + // Verifico il piano + if ( ! plPlane.IsValid()) return false ; // Recupero i dati del Box Point3d ptMin ; double dDimX, dDimY, dDimZ ; if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ)) return false ; + // Pulisco vettori intersezioni + vPnt.clear() ; + vBpt.clear() ; + vTria.clear() ; + // Verifico se può esistere intersezione + if ( ! TestIntersPlaneBox( plPlane, b3Box)) + return true ; // Contorno di base PolyLine PL ; PL.AddUPoint( 0, ptMin) ; diff --git a/VolZmap.h b/VolZmap.h index 69422b9..500f494 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -304,9 +304,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW double dLenX, double dLenY, double dLenZ, int& nStI, int& nStJ, int& nEnI, int& nEnJ) ; // Intersezioni - bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const ; - bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax, - double& dU1, double& dU2) const ; bool IntersLineZMapLattice( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const ; bool IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const ; bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, int nGrid, int nI, int nJ, diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 5c8d91d..9f4f8cd 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -16,10 +16,12 @@ #include "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" +#include "IntersLineBox.h" #include "IntersLineSurfStd.h" #include "/EgtDev/Include/EGkIntersLineTria.h" #include "/EgtDev/Include/EGkIntersLinePlane.h" #include "/EgtDev/Include/EGkIntersLineSphere.h" +#include "/EgtDev/Include/EGkIntersPlaneBox.h" #include "/EgtDev/Include/EGkIntersPlaneTria.h" #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/ENkPolynomialRoots.h" @@ -30,103 +32,6 @@ using namespace std ; -//---------------------------------------------------------------------------- -// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned. -static bool -TestIntersPlaneBox( const BBox3d& b3Box, const Plane3d& plPlane) -{ - // Calcolo le distanze con segno dei punti dal piano - Point3d ptE0 = b3Box.GetMin() ; - double dDist0 = DistPointPlane( ptE0, plPlane) ; - Point3d ptE1( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMin().z) ; - double dDist1 = DistPointPlane( ptE1, plPlane) ; - Point3d ptE2( b3Box.GetMax().x, b3Box.GetMax().y, b3Box.GetMin().z) ; - double dDist2 = DistPointPlane( ptE2, plPlane) ; - Point3d ptE3( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMin().z) ; - double dDist3 = DistPointPlane( ptE3, plPlane) ; - Point3d ptE4( b3Box.GetMin().x, b3Box.GetMin().y, b3Box.GetMax().z) ; - double dDist4 = DistPointPlane( ptE4, plPlane) ; - Point3d ptE5( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMax().z) ; - double dDist5 = DistPointPlane( ptE5, plPlane) ; - Point3d ptE6 = b3Box.GetMax() ; - double dDist6 = DistPointPlane( ptE6, plPlane) ; - Point3d ptE7( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMax().z) ; - double dDist7 = DistPointPlane( ptE7, plPlane) ; - // Distanze tutte positive - if ( dDist0 > EPS_SMALL && dDist1 > EPS_SMALL && dDist2 > EPS_SMALL && dDist3 > EPS_SMALL && - dDist4 > EPS_SMALL && dDist5 > EPS_SMALL && dDist6 > EPS_SMALL && dDist7 > EPS_SMALL) - return false ; - // Distanze tutte negative - if ( dDist0 < - EPS_SMALL && dDist1 < - EPS_SMALL && dDist2 < - EPS_SMALL && dDist3 < - EPS_SMALL && - dDist4 < - EPS_SMALL && dDist5 < - EPS_SMALL && dDist6 < - EPS_SMALL && dDist7 < - EPS_SMALL) - return false ; - // Il piano interseca il box - return true ; -} - -//---------------------------------------------------------------------------- -// Punti e vettore devono esse espressi nel medesimo sistema di riferimento. -// Il box è allineato con gli assi di tale sistema di riferimento. -// Viene restituito true in caso di intersezione, false altrimenti. -bool -VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const -{ - double dU1, dU2 ; - return IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) ; -} - -//---------------------------------------------------------------------------- -// Punti e vettore devono esse espressi nel medesimo sistema di riferimento. -// Il box è allineato con gli assi di tale sistema di riferimento. -// In dU1, dU2 vengono restituiti i parametri a cui si trovano le intersezioni. -// Viene restituito true in caso di intersezione, false altrimenti. -bool -VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, - const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const -{ - // Il box è allineato agli assi - dU1 = - INFINITO ; - dU2 = INFINITO ; - - // confronto con piani YZ (perpendicolari ad asse X) - if ( vtV.x > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ; - dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ; - } - else if ( vtV.x < - EPS_ZERO) { - dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ; - dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ; - } - else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL) - return false ; - - // confronto con piani ZX (perpendicolari ad asse Y) - if ( vtV.y > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ; - dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ; - } - else if ( vtV.y < - EPS_ZERO) { - dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ; - dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ; - } - else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL) - return false ; - - // confronto con piani XY (perpendicolari ad asse Z) - if ( vtV.z > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ; - dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ; - } - else if ( vtV.z < - EPS_ZERO) { - dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ; - dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ; - } - else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL) - return false ; - - return ( dU2 >= dU1) ; -} - //---------------------------------------------------------------------------- // La retta è rappresentata da un punto e dal versore espressi nel riferimento dello Zmap. // Se non vi è intersezione, viene restituito falso @@ -3188,7 +3093,7 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO if ( ! GetBlockBox( nBlockIJK, b3BlockBox)) return false ; // Se c'è intersezione valuto tutti i voxel interni - if ( IntersLineBox( ptLocP, vtDirL, b3BlockBox.GetMin(), b3BlockBox.GetMax())) { + if ( TestIntersLineBox( ptLocP, vtDirL, b3BlockBox.GetMin(), b3BlockBox.GetMax())) { // Ciclo sui voxel del blocco. // Triangoli smooth for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) { @@ -3199,7 +3104,7 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO m_BlockSmoothTria[nB][nV].k } ; GetVoxelBox( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], b3Vox) ; // Se non c'è intersezione col voxel, passo al successivo. - if ( ! IntersLineBox( ptLocP, vtDirL, b3Vox.GetMin(), b3Vox.GetMax())) + if ( ! TestIntersLineBox( ptLocP, vtDirL, b3Vox.GetMin(), b3Vox.GetMax())) continue ; for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) { Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ; @@ -3374,7 +3279,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c if ( ! GetBlockBox( nBlockIJK, b3BlockBox)) return false ; // Se c'è intersezione valuto tutti i voxel interni - if ( TestIntersPlaneBox( b3BlockBox, plPlaneLoc)) { + if ( TestIntersPlaneBox( plPlaneLoc, b3BlockBox)) { // Ciclo sui voxel del blocco. // Triangoli smooth for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) { @@ -3382,7 +3287,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c BBox3d b3Vox ; GetVoxelBox( m_BlockSmoothTria[nB][nV].i, m_BlockSmoothTria[nB][nV].j, m_BlockSmoothTria[nB][nV].k, b3Vox) ; // Se non c'è intersezione col voxel, passo al successivo. - if ( ! TestIntersPlaneBox(b3Vox, plPlaneLoc)) + if ( ! TestIntersPlaneBox( plPlaneLoc, b3Vox)) continue ; for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) { Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ; @@ -3486,5 +3391,5 @@ bool VolZmap::TestIntersPlaneZmapBBox( const Plane3d& plPlane) const { BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ; - return TestIntersPlaneBox( b3Zmap, plPlane) ; + return TestIntersPlaneBox( plPlane, b3Zmap) ; } diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index b07419c..7a8aeac 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -18,6 +18,7 @@ #include "GeoConst.h" #include "MC_Tables.h" #include "PolygonPlane.h" +#include "IntersLineBox.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkChainCurves.h"