diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 966bf33..d51fb4e 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -24,14 +24,14 @@ #include "/EgtDev/Include/EGkCalcPocketing.h" #include "/EgtDev/Include/EGkFilletChamfer.h" #include "/EgtDev/Include/EGkDistPointCurve.h" -#include "/EgtDev/Include/EGkDistPointCurve.h" +#include "/EgtDev/Include/EGkDistPointSurfFr.h" #include "/EgtDev/Include/EGkCurveLocal.h" #include "/EgtDev/Include/EGkMedialAxis.h" #include "/EgtDev/Include/EGkLinePntTgCurve.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkIntervals.h" -#include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkChainCurves.h" +#include "/EgtDev/Include/EgtNumUtils.h" #include using namespace std ; @@ -721,42 +721,6 @@ AssignFeedSpiralOpt( const int nOptType, const PocketParams& PockParams, ICurveC return true ; } -//---------------------------------------------------------------------------- -static bool -IsPointInsideSfr( const ISurfFlatRegion* pSfr, const Point3d& pt, bool& bIsInside) -{ - // controllo dei parametri - if ( pSfr == nullptr || ! pSfr->IsValid() || ! pt.IsValid()) - return false ; - bIsInside = false ; - - // ciclo sui chunk della FlatRegion - for ( int i = 0 ; i < pSfr->GetChunkCount() ; i ++) { - // verifico se è contenuto nel loop esterno - PtrOwner pCrv( pSfr->GetLoop( i, 0)) ; - PolyLine PL ; - pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ; - if ( IsPointInsidePolyLine( pt, PL, EPS_SMALL)) { - bool bInsideHole = false ; - // verifico se è contenuto in un loop interno - for ( int j = 1 ; j < pSfr->GetLoopCount( i) ; j ++) { - PtrOwner pCrv( pSfr->GetLoop( i, j)) ; - pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ; - PL.Invert() ; - if ( IsPointInsidePolyLine( pt, PL, EPS_SMALL)) - bInsideHole = true ; - } - // se è contenuto nel loop esterno ma non è contenuto in nessuno dei loop interni allora il punto è interno - if ( ! bInsideHole) { - bIsInside = true ; - return true ; - } - } - } - - return true ; -} - //---------------------------------------------------------------------------- static bool GetCoeffLinArc( const ICurveArc* pArc, double dDiam, double& dSubArc) @@ -6989,15 +6953,16 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con vpCrvs[u]->ToGlob( frPocket) ; // controllo se il punto iniziale e finale sono esterni alla superficie originale + double dMinDist = max( 0., -PockParams.dRadialOffset) ; Point3d ptStart ; vpCrvs[u]->GetStartPoint( ptStart) ; bool bIsInside = false ; - if ( IsPointInsideSfr( pSfrOrig, ptStart, bIsInside) && ! bIsInside) { + if ( IsPointInsideSurfFr( ptStart, pSfrOrig, dMinDist, bIsInside) && ! bIsInside) { Vector3d vtMidOut ; vpCrvs[u]->GetStartDir( vtMidOut) ; vtMidOut.Invert() ; ExtendPathOnOpenEdge( vpCrvs[u], PockParams, pSrfChunk->GetNormVersor(), vtMidOut, false) ; } Point3d ptEnd ; vpCrvs[u]->GetEndPoint( ptEnd) ; - if ( IsPointInsideSfr( pSfrOrig, ptEnd, bIsInside) && ! bIsInside) { + if ( IsPointInsideSurfFr( ptEnd, pSfrOrig, dMinDist, bIsInside) && ! bIsInside) { Vector3d vtMidOut ; vpCrvs[u]->GetEndDir( vtMidOut) ; ExtendPathOnOpenEdge( vpCrvs[u], PockParams, pSrfChunk->GetNormVersor(), vtMidOut, true) ; } diff --git a/DistPointSurfFr.cpp b/DistPointSurfFr.cpp new file mode 100644 index 0000000..ca318ed --- /dev/null +++ b/DistPointSurfFr.cpp @@ -0,0 +1,156 @@ +//---------------------------------------------------------------------------- +// 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 ; +} diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 11258ea..2af9636 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 2a61ee7..825a635 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -310,6 +310,7 @@ copy $(TargetPath) \EgtProg\Dll64 + false false diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 7b4369b..0eff6b3 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -546,6 +546,9 @@ File di origine\GeoCreate + + File di origine\GeoDist + diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index 41b74cb..4c60547 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -922,9 +922,6 @@ SurfFlatRegion::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) bool SurfFlatRegion::GetArea( double& dArea) const { - // controllo parametro di ritorno - if ( &dArea == nullptr) - return false ; // inizio con area nulla dArea = 0 ; // la regione deve essere validata @@ -947,9 +944,6 @@ SurfFlatRegion::GetArea( double& dArea) const bool SurfFlatRegion::GetGrossArea( double& dArea) const { - // controllo parametro di ritorno - if ( &dArea == nullptr) - return false ; // inizio con area nulla dArea = 0 ; // la regione deve essere validata @@ -973,9 +967,6 @@ SurfFlatRegion::GetGrossArea( double& dArea) const bool SurfFlatRegion::GetCentroid( Point3d& ptCen) const { - // controllo parametro di ritorno - if ( &ptCen == nullptr) - return false ; // la regione deve essere validata if ( m_nStatus != OK || m_vpLoop.empty()) return false ; @@ -1001,13 +992,20 @@ SurfFlatRegion::GetCentroid( Point3d& ptCen) const return true ; } +//---------------------------------------------------------------------------- +int +SurfFlatRegion::GetChunkCount( void) const +{ + // la regione deve essere validata + if ( m_nStatus != OK) + return 0 ; + return int( m_vExtInd.size()) ; +} + //---------------------------------------------------------------------------- bool SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const { - // controllo parametro di ritorno - if ( &ptCen == nullptr) - return false ; // la regione deve essere validata if ( m_nStatus != OK || m_vpLoop.empty()) return false ; @@ -1021,13 +1019,53 @@ SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const } //---------------------------------------------------------------------------- -int -SurfFlatRegion::GetChunkCount( void) const +bool +SurfFlatRegion::GetChunkArea( int nChunk, double& dArea) const { + // default, area nulla + dArea = 0 ; // la regione deve essere validata - if ( m_nStatus != OK) - return 0 ; - return int( m_vExtInd.size()) ; + if ( m_nStatus != OK || m_vpLoop.empty()) + return false ; + // il chunk deve esistere + if ( nChunk < 0 || nChunk >= GetChunkCount()) + return false ; + // calcolo l'area + bool bOk = true ; + for ( int nL = 0 ; nL < GetLoopCount( nChunk) ; ++ nL) { + const ICurve* pLoop = GetMyLoop( nChunk, nL) ; + double dLoopArea ; + if ( pLoop != nullptr && pLoop->GetAreaXY( dLoopArea)) + dArea += dLoopArea ; + else + bOk = false ; + } + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +SurfFlatRegion::GetChunkPerimeter( int nChunk, double& dLen) const +{ + // default, perimetro nullo + dLen = 0 ; + // la regione deve essere validata + if ( m_nStatus != OK || m_vpLoop.empty()) + return false ; + // il chunk deve esistere + if ( nChunk < 0 || nChunk >= GetChunkCount()) + return false ; + // calcolo il perimetro + bool bOk = true ; + for ( int nL = 0 ; nL < GetLoopCount( nChunk) ; ++ nL) { + const ICurve* pLoop = GetMyLoop( nChunk, nL) ; + double dLoopLen ; + if ( pLoop != nullptr && pLoop->GetLength( dLoopLen)) + dLen += dLoopLen ; + else + bOk = false ; + } + return bOk ; } //---------------------------------------------------------------------------- @@ -1236,6 +1274,56 @@ SurfFlatRegion::CloneChunk( int nChunk) const return Release( pSfr) ; } +//---------------------------------------------------------------------------- +bool +SurfFlatRegion::EraseChunk(int nChunk) +{ + // la regione deve essere validata + if ( m_nStatus != OK || m_vpLoop.empty()) + return false ; + // il chunk deve esistere + if ( nChunk < 0 || nChunk >= GetChunkCount()) + return false ; + // se un solo chunk, resetto la regione + if ( GetChunkCount() == 1) { + Clear() ; + return true ; + } + // se ultimo chunk + if ( nChunk == m_vExtInd.size() - 1) { + // elimino i loop + for ( int i = m_vExtInd[nChunk] ; i < int( m_vpLoop.size()) ; ++ i) { + delete m_vpLoop[i] ; + m_vpLoop[i] = nullptr ; + } + m_vpLoop.erase( m_vpLoop.begin() + m_vExtInd[nChunk], m_vpLoop.end()) ; + // elimino indice di loop esterno + m_vExtInd.pop_back() ; + } + // altrimenti + else { + // numero di loop da eliminare + int nLoopCnt = m_vExtInd[nChunk+1] - m_vExtInd[nChunk] ; + // elimino i loop + for ( int i = m_vExtInd[nChunk] ; i < m_vExtInd[nChunk+1] ; ++ i) { + delete m_vpLoop[i] ; + m_vpLoop[i] = nullptr ; + } + m_vpLoop.erase( m_vpLoop.begin() + m_vExtInd[nChunk], m_vpLoop.begin() + m_vExtInd[nChunk+1]) ; + // elimino indice di loop esterno + m_vExtInd.erase( m_vExtInd.begin() + nChunk) ; + // aggiorno indice inizio chunk successivi + for ( int i = nChunk ; i < int( m_vExtInd.size()) ; ++i) + m_vExtInd[i] -= nLoopCnt ; + } + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + ResetAuxSurf() ; + // imposto ricalcolo Voronoi + ResetVoronoiObject() ; + return true ; +} + //---------------------------------------------------------------------------- bool SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const @@ -1560,6 +1648,31 @@ SurfFlatRegion::GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, i return GetBasicCurveComposite( pLoop)->GetCurveTempProp( nCrv, nProp, nPropInd) ; } +//---------------------------------------------------------------------------- +bool +SurfFlatRegion::ResetAllCurveTempProps( void) +{ + for ( int nC = 0 ; nC < GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < GetLoopCount( nC) ; ++ nL) { + ICurve* pLoop = GetMyLoop( nC, nL) ; + if ( pLoop != nullptr) { + if ( pLoop->GetType() != CRV_COMPO) { + pLoop->SetTempProp( 0, 0) ; + pLoop->SetTempProp( 0, 1) ; + } + else { + CurveComposite* pCompoLoop = GetBasicCurveComposite( pLoop) ; + for ( int nI = 0 ; nI < pCompoLoop->GetCurveCount() ; ++ nI) { + pCompoLoop->SetCurveTempProp( nI, 0, 0) ; + pCompoLoop->SetCurveTempProp( nI, 0, 1) ; + } + } + } + } + } + return true ; +} + //---------------------------------------------------------------------------- bool SurfFlatRegion::SetCurveTempParam( int nChunk, int nLoop, int nCrv, double dParam, int nParamInd) @@ -1591,3 +1704,28 @@ SurfFlatRegion::GetCurveTempParam( int nChunk, int nLoop, int nCrv, double& dPar } return GetBasicCurveComposite( pLoop)->GetCurveTempParam( nCrv, dParam, nParamInd) ; } + +//---------------------------------------------------------------------------- +bool +SurfFlatRegion::ResetAllCurveTempParams( void) +{ + for ( int nC = 0 ; nC < GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < GetLoopCount( nC) ; ++ nL) { + ICurve* pLoop = GetMyLoop( nC, nL) ; + if ( pLoop != nullptr) { + if ( pLoop->GetType() != CRV_COMPO) { + pLoop->SetTempParam( 0, 0) ; + pLoop->SetTempParam( 0, 1) ; + } + else { + CurveComposite* pCompoLoop = GetBasicCurveComposite( pLoop) ; + for ( int nI = 0 ; nI < pCompoLoop->GetCurveCount() ; ++ nI) { + pCompoLoop->SetCurveTempParam( nI, 0, 0) ; + pCompoLoop->SetCurveTempParam( nI, 0, 1) ; + } + } + } + } + } + return true ; +} diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h index d257fce..be42bea 100644 --- a/SurfFlatRegion.h +++ b/SurfFlatRegion.h @@ -94,24 +94,29 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW { return m_frF.Orig() ; } const Vector3d& GetNormVersor( void) const override { return m_frF.VersZ() ; } + bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ; + void ResetVoronoiObject( void) const override ; + bool GetMaxOffset( double& dOffs) const override ; + bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ; + const SurfTriMesh* GetAuxSurf( void) const override ; + bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ; int GetChunkCount( void) const override ; + SurfFlatRegion* CloneChunk( int nChunk) const override ; + bool EraseChunk(int nChunk) override ; + bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ; + bool GetChunkArea( int nChunk, double& dArea) const override ; + bool GetChunkPerimeter( int nChunk, double& dLen) const override ; + int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides + bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ; int GetLoopCount( int nChunk) const override ; ICurve* GetLoop( int nChunk, int nLoop) const override ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni) bool ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const override ; - const SurfTriMesh* GetAuxSurf( void) const override ; - SurfFlatRegion* CloneChunk( int nChunk) const override ; - bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ; - bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ; - int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides - bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ; - bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ; - bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ; - bool GetMaxOffset( double& dOffs) const override ; - void ResetVoronoiObject( void) const override ; bool SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd = 0) override ; bool GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, int nPropInd = 0) const override ; + bool ResetAllCurveTempProps( void) override ; bool SetCurveTempParam( int nChunk, int nLoop, int nCrv, double dParam, int nParamInd = 0) override ; bool GetCurveTempParam( int nChunk, int nLoop, int nCrv, double& dParam, int nParamInd = 0) const override ; + bool ResetAllCurveTempParams( void) override ; public : // IGeoObjRW int GetNgeId( void) const override ;