//---------------------------------------------------------------------------- // EgalTech 2018-2020 //---------------------------------------------------------------------------- // File : DistPointSurfTm.cpp Data : 19.12.20 Versione : 2.2l3 // Contenuto : Implementazione della classe distanza Punto da Trimesh. // // // // Modifiche : 07.12.18 LM Creazione modulo. // // //---------------------------------------------------------------------------- #include "stdafx.h" #include "SurfFlatRegion.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkDistPointSurfFr.h" using namespace std ; //---------------------------------------------------------------------------- DistPointSurfFr::DistPointSurfFr( const Point3d& ptP, const ISurfFlatRegion& frSurf) : m_dDist( -1) { // FlatRegion non valida if ( &frSurf == nullptr || ! frSurf.IsValid()) return ; // Calcolo la distanza Calculate( ptP, frSurf) ; } //---------------------------------------------------------------------------- void DistPointSurfFr::Calculate( const Point3d& ptP, const ISurfFlatRegion& frSurf) { // Inizializzo distanza non calcolata m_dDist = -1 ; // Converto regione in classe base const SurfFlatRegion* pSfr = GetBasicSurfFlatRegion( &frSurf) ; if ( pSfr == nullptr) return ; // ciclo sulle parti della regione for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; nC ++) { // ciclo sui loop della parte di regione for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; nL ++) { PtrOwner pLoop( pSfr->GetLoop( nC, nL)) ; if ( IsNull( pLoop)) { m_dDist = -1 ; return ; } DistPointCurve DPL( ptP, *pLoop) ; double dDist ; if ( DPL.GetDist( dDist) && ( m_dDist < -EPS_SMALL || dDist < m_dDist)) { m_dDist = dDist ; int nFlag ; m_nMinChunk = nC ; m_nMinLoop = nL ; DPL.GetParamAtMinDistPoint( 0, m_dMinPar, nFlag) ; DPL.GetMinDistPoint( 0, m_ptMinDistPoint, nFlag) ; DPL.GetSideAtMinDistPoint( 0, pSfr->GetNormVersor(), m_nSide) ; } } } // se trovata, aggiorno minima distanza sul piano if ( m_dDist > - EPS_SMALL) { Point3d ptOn = ptP - ( ptP - pSfr->GetPlanePoint()) * pSfr->GetNormVersor() * pSfr->GetNormVersor() ; m_dDistOnPlane = min( Dist( ptOn, m_ptMinDistPoint), m_dDist) ; } } //---------------------------------------------------------------------------- bool DistPointSurfFr::GetDist( double& dDist) const { if ( m_dDist < 0) return false ; dDist = m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointSurfFr::GetDistOnRegionPlane( double& dDist) const { if ( m_dDist < 0) return false ; dDist = m_dDistOnPlane ; return true ; } //---------------------------------------------------------------------------- bool DistPointSurfFr::GetPointAtMinDist( Point3d& ptMinDist) const { if ( m_dDist < 0) return false ; ptMinDist = m_ptMinDistPoint ; return true ; } //---------------------------------------------------------------------------- bool DistPointSurfFr::GetParamAtMinDist( int& nMinChunk, int& nMinLoop, double& dMinPar) const { if ( m_dDist < 0) return false ; nMinChunk = m_nMinChunk ; nMinLoop = m_nMinLoop ; dMinPar = m_dMinPar ; return true ; } //---------------------------------------------------------------------------- bool DistPointSurfFr::GetSideAtMinDist( int& nSide) const { if ( m_dDist < 0) return false ; nSide = m_nSide ; return true ; } //---------------------------------------------------------------------------- bool IsPointInsideSurfFr( const Point3d& ptP, const ISurfFlatRegion* pSfr, double dMinDist, bool& bInside, int& nChunk) { // default non include bInside = false ; nChunk = -1 ; // verifica regione if ( pSfr == nullptr || ! pSfr->IsValid()) return false ; // verifico se la proiezione del punto sul piano della regione sta nel suo box Point3d ptOn = ptP - ( ptP - pSfr->GetPlanePoint()) * pSfr->GetNormVersor() * pSfr->GetNormVersor() ; BBox3d b3Box ; pSfr->GetLocalBBox( b3Box) ; b3Box.Expand( dMinDist) ; if ( ! b3Box.Encloses( ptOn)) return true ; // determino dove sta il punto DistPointSurfFr DPR( ptP, *pSfr) ; double dDist ; int nMinCh, nMinL; double dMinPar ; int nSide ; if ( DPR.GetDistOnRegionPlane( dDist) && DPR.GetParamAtMinDist( nMinCh, nMinL, dMinPar) && DPR.GetSideAtMinDist( nSide)) { if ( abs( dMinDist) < EPS_SMALL) bInside = ( nSide != PRS_OUT) ; else if ( dMinDist < 0) bInside = ( nSide == PRS_IN && dDist > abs( dMinDist) - EPS_SMALL) ; else bInside = ( nSide != PRS_OUT || dDist < dMinDist + EPS_SMALL) ; if ( bInside) nChunk = nMinCh ; } return true ; }