//---------------------------------------------------------------------------- // 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 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 ; }