diff --git a/Attribs.cpp b/Attribs.cpp index 06a064b..4aee267 100644 --- a/Attribs.cpp +++ b/Attribs.cpp @@ -81,8 +81,7 @@ Attribs::Dump( const GeomDB& GDB, string& sOut, bool bMM, const char* szNewLine) } sOut += szNewLine ; // eventuali nome e stringhe informative - STRLIST::const_iterator iIter ; - for ( iIter = m_slInfo.begin() ; iIter != m_slInfo.end() ; ++ iIter) + for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter) sOut += *iIter + szNewLine ; return true ; @@ -101,7 +100,7 @@ Attribs::Save( NgeWriter& ngeOut) const // modo if ( ! ngeOut.WriteUchar( m_Data[MODE], ",")) return false ; - // stato (se SEL � convertito in ON) + // stato (se SEL è convertito in ON) int nStat = (( m_Data[STATUS] > GDB_ST_ON) ? GDB_ST_ON : m_Data[STATUS]) ; if ( ! ngeOut.WriteUchar( nStat, ",")) return false ; @@ -118,8 +117,7 @@ Attribs::Save( NgeWriter& ngeOut) const if ( ! ngeOut.WriteInt( int( m_slInfo.size()), ";", true)) return false ; // stringhe di info - STRLIST::const_iterator iIter ; - for ( iIter = m_slInfo.begin() ; iIter != m_slInfo.end() ; ++ iIter) { + for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter) { if ( ! ngeOut.WriteString( *iIter, nullptr, true)) return false ; } @@ -141,7 +139,7 @@ Attribs::Load( NgeReader& ngeIn) if ( ! ngeIn.ReadUchar( ucMode, ",")) return false ; m_Data[MODE] = CLIP( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ; - // stato (se SEL � convertito in ON) + // stato (se SEL è convertito in ON) unsigned char ucStat ; if ( ! ngeIn.ReadUchar( ucStat, ",")) return false ; @@ -177,7 +175,7 @@ Attribs::Load( NgeReader& ngeIn) bool Attribs::DataFromString( const string& sParam) { - // il primo parametro � diviso in 4 parti + // il primo parametro è diviso in 4 parti STRVECTOR vsParams ; Tokenize( sParam, ",", vsParams) ; // 4 parti @@ -215,10 +213,9 @@ Attribs::SetName( const string& sName) if ( sName.empty() || ! IsValidVal( sName)) return false ; - // pu� essere solo la prima stringa - STRLIST::iterator iIter ; - if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() && - FindKey( *iIter, NAME)) { + // può essere solo la prima stringa + auto iIter = m_slInfo.begin() ; + if ( iIter != m_slInfo.end() && FindKey( *iIter, NAME)) { *iIter = NAME + EQUAL + sName ; return true ; } @@ -237,10 +234,9 @@ Attribs::SetName( const string& sName) bool Attribs::GetName( string& sName) const { - // pu� essere solo la prima stringa - STRLIST::const_iterator iIter ; - if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() && - FindKey( *iIter, NAME)) { + // può essere solo la prima stringa + const auto iIter = m_slInfo.cbegin() ; + if ( iIter != m_slInfo.cend() && FindKey( *iIter, NAME)) { sName = iIter->substr( NAME.length() + 1) ; return true ; } @@ -252,23 +248,18 @@ Attribs::GetName( string& sName) const bool Attribs::ExistsName( void) const { - // pu� essere solo la prima stringa - STRLIST::const_iterator iIter ; - if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() && - FindKey( *iIter, NAME)) - return true ; - - return false ; + // può essere solo la prima stringa + const auto iIter = m_slInfo.cbegin() ; + return ( iIter != m_slInfo.cend() && FindKey( *iIter, NAME)) ; } //---------------------------------------------------------------------------- bool Attribs::RemoveName( void) { - // pu� essere solo la prima stringa - STRLIST::const_iterator iIter ; - if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() && - FindKey( *iIter, NAME)) { + // può essere solo la prima stringa + const auto iIter = m_slInfo.cbegin() ; + if ( iIter != m_slInfo.cend() && FindKey( *iIter, NAME)) { m_slInfo.pop_front() ; return true ; } @@ -285,11 +276,11 @@ Attribs::SetInfo( const string& sKey, const string& sVal) if ( ! IsValidKey( sKey) || sVal.empty() || ! IsValidVal( sVal)) return false ; - // se � il nome + // se è il nome if ( sKey == NAME) return SetName( sVal) ; - // se esiste gi� una stringa con quella chiave la sostituisco + // se esiste già una stringa con quella chiave la sostituisco for ( auto iIter = m_slInfo.begin() ; iIter != m_slInfo.end() ; ++ iIter) { if ( FindKey( *iIter, sKey)) { *iIter = sKey + EQUAL + sVal ; diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index ba73ba0..878ea15 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -1,8 +1,8 @@ //---------------------------------------------------------------------------- // EgalTech 2018-2018 //---------------------------------------------------------------------------- -// File : CAToolSurfTm.cpp Data : 08.05.18 Versione : 1.9e2 -// Contenuto : Implementazione della classe CAToolSurfTm. +// File : CAvToolSurfTm.cpp Data : 08.05.18 Versione : 1.9e2 +// Contenuto : Implementazione della classe CAvToolSurfTm. // // // diff --git a/CAvToolTriangle.cpp b/CAvToolTriangle.cpp index b5e1bdb..7c04daf 100644 --- a/CAvToolTriangle.cpp +++ b/CAvToolTriangle.cpp @@ -146,7 +146,7 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d& const Triangle3d& trTria, const Vector3d& vtMove) { // Non ha senso che il movimento sia in direzione "opposta" a quella dell'asse utensile - if ( vtMove * vtToolAx < - EPS_ZERO) + if ( vtMove * vtToolAx < - 10 * EPS_ZERO) return -1. ; // Se avvicinamento non devo fare nulla if ( vtMove * trTria.GetN() < - EPS_ZERO) diff --git a/CDeTriaTria.cpp b/CDeTriaTria.cpp index 1472bfd..c4499f0 100644 --- a/CDeTriaTria.cpp +++ b/CDeTriaTria.cpp @@ -34,7 +34,7 @@ GetTwoGreater( int nVal0, int nVal1, int nVal2, int& nFirstMaxPos, int& nSecondM } else { nFirstMaxPos = 2 ; - nSecondMaxPos = 1 ; + nSecondMaxPos = 0 ; } } else if ( nVal0 > nVal2) { @@ -168,7 +168,7 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB) Vector3d vtSegSecondB = trTriaB.GetP( ( nSecondMaxPosB + 1) % 3) - trTriaB.GetP( nSecondMaxPosB) ; double dSegLenSecondB = vtSegSecondB.Len() ; vtSegSecondB /= dSegLenSecondB ; - DistLineLine LineLineDistCalcSecondB( ptLineP, vtLineV, 100., trTriaB.GetP( nSecondMaxPosA), vtSegSecondB, dSegLenSecondB, false) ; + DistLineLine LineLineDistCalcSecondB( ptLineP, vtLineV, 100., trTriaB.GetP( nSecondMaxPosB), vtSegSecondB, dSegLenSecondB, false) ; double dIntParEnB, dOtherParSecondB ; LineLineDistCalcSecondB.GetPositionsAtMinDistPoints( dIntParEnB, dOtherParSecondB) ; // Ordino i parametri lungo la retta di intersezione fra i piani diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 9c53141..dffed81 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -13,22 +13,21 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "DllMain.h" -#include "GeoConst.h" #include "CurveLine.h" #include "CurveArc.h" #include "CurveComposite.h" #include "BiArcs.h" #include "SurfFlatRegion.h" +#include "GeoConst.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EGkCalcPocketing.h" -#include "EgtDev/Include/EGkFilletChamfer.h" -#include "EgtDev/Include/EGkDistPointCurve.h" -#include "EgtDev/Include/EGkDistPointCurve.h" -#include "EgtDev/Include/EGkCurveLocal.h" -#include "EgtDev/Include/EGkMedialAxis.h" -#include "EgtDev/Include/EGkLinePntTgCurve.h" +#include "/EgtDev/Include/EGkFilletChamfer.h" +#include "/EgtDev/Include/EGkDistPointCurve.h" +#include "/EgtDev/Include/EGkDistPointCurve.h" +#include "/EgtDev/Include/EGkCurveLocal.h" +#include "/EgtDev/Include/EGkMedialAxis.h" +#include "/EgtDev/Include/EGkLinePntTgCurve.h" #include using namespace std ; @@ -1896,7 +1895,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, double dRad, double dStep, bool bSm if ( IsNull( pSrfAct) || pSrfAct->GetChunkCount() == 0) return false ; - double dOffsPrec = dOffs ; + double dOffsPrec = 0. ; while ( nIter < MAX_ITER) { // ricavo la regione piana da VRONI PtrOwner pSfrOffsVR( pSrfAct->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ; @@ -1940,16 +1939,17 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, double dRad, double dStep, bool bSm } // controllo se serve un raggio più piccolo di svuotatura - bool bSmallRad = ( nIter == 0 ? dOffs - dOffsPrec < dRad + EPS_ZERO : dOffs - dOffsPrec < dRad + EPS_ZERO) ; - // memorizzo il valore di Offset per l'iterazione successiva - dOffsPrec = dOffs ; + bool bSmallRad = ( nIter == 0 ? dOffs < dRad + EPS_ZERO : dOffs - dOffsPrec < dRad + EPS_ZERO) ; // se ho trovato dei chunk, allora aggiorno l'Offset per la passata successiva - if ( nChunks > 0) + if ( nChunks > 0) { + // memorizzo il valore di Offset per l'iterazione successiva + dOffsPrec = dOffs ; dOffs += dStep ; + } // se devo usare un Offset più piccolo... else if ( ! bSmallRad) - dOffs += dRad ; + dOffs = dOffsPrec + ( nIter == 0 ? dRad : dRad) ; // superfluo, effettivamente non ho l'offset radiale // altrimenti ho finito la regione da svuotare... else break ; diff --git a/CurveArc.cpp b/CurveArc.cpp index 1b0b5b9..34ec910 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -22,6 +22,7 @@ #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" diff --git a/CurveArc.h b/CurveArc.h index d11bb8c..3879e20 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -18,7 +18,8 @@ #include "DllMain.h" #include "GeoObjRW.h" #include "/EgtDev/Include/EGkCurveArc.h" -#include "/EgtDev/Include/EGkVoronoi.h" + +class Voronoi ; //---------------------------------------------------------------------------- class CurveArc : public ICurveArc, public IGeoObjRW @@ -129,7 +130,6 @@ class CurveArc : public ICurveArc, public IGeoObjRW bool TrimEndAtLen( double dLenTrim) override ; bool ExtendStartByLen( double dLenExt) override ; bool ExtendEndByLen( double dLenExt) override ; - Voronoi* GetVoronoiObject( void) const override ; public : // ICurveArc bool CopyFrom( const IGeoObj* pGObjSrc) override ; @@ -199,6 +199,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW return *this ; } bool MyExtendedOffset( double dDist, bool bAll, int nType = OFF_FILLET) ; bool MyCalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos, double dLinTol) const ; + Voronoi* GetVoronoiObject( void) const ; private : bool CopyFrom( const CurveArc& caSrc) ; diff --git a/CurveAux.cpp b/CurveAux.cpp index f8850b0..ee05bb1 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -19,11 +19,11 @@ #include "CurveArc.h" #include "CurveBezier.h" #include "CurveComposite.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" #include "/EgtDev/Include/EgtPointerOwner.h" -#include "/EgtDev/Include/EGkVoronoi.h" using namespace std ; @@ -1041,11 +1041,24 @@ AdjustCurveSlope( ICurveComposite* pCrv, double dNini, double dNfin) return true ; } +//---------------------------------------------------------------------------- +Voronoi* +GetCurveVoronoi( const ICurve& crvC) +{ + switch ( crvC.GetType()) { + case CRV_LINE : return GetBasicCurveLine( &crvC)->GetVoronoiObject() ; + case CRV_ARC : return GetBasicCurveArc( &crvC)->GetVoronoiObject() ; + case CRV_BEZIER : return GetBasicCurveBezier( &crvC)->GetVoronoiObject() ; + case CRV_COMPO : return GetBasicCurveComposite( &crvC)->GetVoronoiObject() ; + } + return nullptr ; +} + //---------------------------------------------------------------------------- bool CalcCurveVoronoiDiagram( const ICurve& crvC, ICURVEPOVECTOR& vCrvs, int nBound) { - Voronoi* pVoronoiObj = crvC.GetVoronoiObject() ; + Voronoi* pVoronoiObj = GetCurveVoronoi( crvC) ; if ( pVoronoiObj == nullptr) return false ; @@ -1056,7 +1069,7 @@ CalcCurveVoronoiDiagram( const ICurve& crvC, ICURVEPOVECTOR& vCrvs, int nBound) bool CalcCurveMedialAxis( const ICurve& crvC, ICURVEPOVECTOR& vCrvs, int nSide) { - Voronoi* pVoronoiObj = crvC.GetVoronoiObject() ; + Voronoi* pVoronoiObj = GetCurveVoronoi( crvC) ; if ( pVoronoiObj == nullptr) return false ; @@ -1067,7 +1080,7 @@ CalcCurveMedialAxis( const ICurve& crvC, ICURVEPOVECTOR& vCrvs, int nSide) bool CalcCurveFatCurve( const ICurve& crvC, ICURVEPOVECTOR& vCrvs, double dRadius, bool bSquareEnds, bool bSquareMids) { - Voronoi* pVoronoiObj = crvC.GetVoronoiObject() ; + Voronoi* pVoronoiObj = GetCurveVoronoi( crvC) ; if ( pVoronoiObj == nullptr) return false ; diff --git a/CurveAux.h b/CurveAux.h index 18bab55..197cd96 100644 --- a/CurveAux.h +++ b/CurveAux.h @@ -15,6 +15,8 @@ #include "/EgtDev/Include/EGkCurveAux.h" +class Voronoi ; + //---------------------------------------------------------------------------- bool IsClosed( const ICurve& crvC) ; bool IsValidParam( const ICurve& crvC, double dPar, ICurve::Side nSide) ; @@ -31,3 +33,4 @@ bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ; bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ; bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ; bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ; +Voronoi* GetCurveVoronoi( const ICurve& crvC) ; diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 5eabe92..78351a3 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -26,6 +26,7 @@ #include "PolynomialPoint3d.h" #include "Bernstein.h" #include "deCasteljau.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" diff --git a/CurveBezier.h b/CurveBezier.h index b303d9b..f87d649 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -19,8 +19,8 @@ #include "DllMain.h" #include "GeoObjRW.h" #include "/EgtDev/Include/EGkCurveBezier.h" -#include "/EgtDev/Include/EgtNumCollection.h" -#include "/EgtDev/Include/EGkVoronoi.h" + +class Voronoi ; //---------------------------------------------------------------------------- class CurveBezier : public ICurveBezier, public IGeoObjRW @@ -131,7 +131,6 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW bool TrimEndAtLen( double dLenTrim) override ; bool ExtendStartByLen( double dLenExt) override ; bool ExtendEndByLen( double dLenExt) override ; - Voronoi* GetVoronoiObject( void) const override ; public : // ICurveBezier bool CopyFrom( const IGeoObj* pGObjSrc) override ; @@ -165,6 +164,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW return *this ; } bool ApproxWithLines( int nStep, PolyLine& PL) const ; bool GetApproxLength( double& dLen) const ; + Voronoi* GetVoronoiObject( void) const ; private : bool CopyFrom( const CurveBezier& cbSrc) ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 11ca192..a384685 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -26,6 +26,7 @@ #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkCurveByApprox.h" #include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EGkSfrCreate.h" @@ -37,6 +38,9 @@ using namespace std ; +//---------------------------------------------------------------------------- +static const double EPS_CONNECT = 0.01 * EPS_SMALL ; + //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_COMPO, NGE_C_CMP, CurveComposite) ; @@ -214,7 +218,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT // verifico sia in continuità con il finale attuale Point3d ptEnd ; GetEndPoint( ptEnd) ; - if ( ! AreSamePointEpsilon( ptCrvStart, ptEnd, 0.01 * EPS_SMALL)) { + if ( ! AreSamePointEpsilon( ptCrvStart, ptEnd, EPS_CONNECT)) { // se in tolleranza, modifico l'inizio dell'entità if ( SqDist( ptCrvStart, ptEnd) < ( dLinTol * dLinTol)) { // lunghezza della curva originale @@ -236,7 +240,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT // verifico sia in continuità con l'iniziale attuale Point3d ptStart ; GetStartPoint( ptStart) ; - if ( ! AreSamePointEpsilon( ptCrvEnd, ptStart, 0.01 * EPS_SMALL)) { + if ( ! AreSamePointEpsilon( ptCrvEnd, ptStart, EPS_CONNECT)) { // se in tolleranza, modifico la fine dell'entità if ( SqDist( ptCrvEnd, ptStart) < ( dLinTol * dLinTol)) { // lunghezza della curva originale @@ -266,7 +270,8 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT // imposto ricalcolo Voronoi ResetVoronoiObject() ; - return true ; + + return TestClosure() ; } //---------------------------------------------------------------------------- @@ -282,7 +287,7 @@ CurveComposite::Close( void) ! GetEndPoint( ptEnd)) return false ; // se distanza inferiore al limite ridotto, non faccio alcunché - if ( AreSamePointEpsilon( ptStart, ptEnd, EPS_SMALL / 10)) + if ( AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) return true ; // se molto vicini li modifico if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) { @@ -832,8 +837,7 @@ CurveComposite::Validate( void) Point3d ptStart ; // ciclo su tutte le curve int nCount = 0 ; - PCSD_CONST_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( auto Iter = m_CrvSmplS.cbegin() ; Iter != m_CrvSmplS.cend() ; ++Iter) { // verifico validità della curva e sua semplicità if ( ! (*Iter)->IsValid() || (*Iter)->GetType() == CRV_COMPO) { m_nStatus = ERR ; @@ -856,9 +860,32 @@ CurveComposite::Validate( void) m_nStatus = ( nCount > 0 ? OK : TO_VERIFY) ; } + // verifico chiusura + TestClosure() ; + return ( m_nStatus == OK) ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::TestClosure( void) +{ + // se non è chiusa, esco subito + if ( ! IsClosed()) + return true ; + // verifico ed eventualmente aggiusto coincidenza punti estremi + Point3d ptStart ; m_CrvSmplS.front()->GetStartPoint( ptStart) ; + Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ; + // se distanza superiore al limite ridotto forzo i punti a coincidere + if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) { + Point3d ptM = Media( ptStart, ptEnd) ; + if ( ! m_CrvSmplS.front()->ModifyStart( ptM) || + ! m_CrvSmplS.back()->ModifyEnd( ptM)) + return false ; + } + return true ; +} + //---------------------------------------------------------------------------- bool CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) const @@ -1188,8 +1215,7 @@ CurveComposite::GetLength( double& dLen) const // ciclo di calcolo dLen = 0 ; - PCSD_CONST_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( auto Iter = m_CrvSmplS.cbegin() ; Iter != m_CrvSmplS.cend() ; ++Iter) { double dLenCrvSmpl ; if ( (*Iter)->GetLength( dLenCrvSmpl)) dLen += dLenCrvSmpl ; @@ -1215,8 +1241,7 @@ CurveComposite::GetLengthAtParam( double dU, double& dLen) const // ciclo di calcolo dLen = 0 ; double dUToGo = dU ; - PCSD_CONST_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( auto Iter = m_CrvSmplS.cbegin() ; Iter != m_CrvSmplS.cend() ; ++Iter) { // dominio parametrico della curva semplice double dParStart, dParEnd ; (*Iter)->GetDomain( dParStart, dParEnd) ; @@ -1264,8 +1289,7 @@ CurveComposite::GetParamAtLength( double dLen, double& dU) const // ciclo di calcolo dU = 0 ; double dLenToGo = dLen ; - PCSD_CONST_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( auto Iter = m_CrvSmplS.cbegin() ; Iter != m_CrvSmplS.cend() ; ++Iter) { // lunghezza della curva semplice double dCrvLen ; if ( ! (*Iter)->GetLength( dCrvLen)) diff --git a/CurveComposite.h b/CurveComposite.h index 33848ac..ee458fc 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -19,9 +19,10 @@ #include "DllMain.h" #include "GeoObjRW.h" #include "/EgtDev/Include/EGkCurveComposite.h" -#include "/EgtDev/Include/EGkVoronoi.h" #include +class Voronoi ; + //---------------------------------------------------------------------------- class CurveComposite : public ICurveComposite, public IGeoObjRW { @@ -126,7 +127,6 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW bool TrimEndAtLen( double dLenTrim) override ; bool ExtendStartByLen( double dLenExt) override ; bool ExtendEndByLen( double dLenExt) override ; - Voronoi* GetVoronoiObject( void) const override ; public : // ICurveComposite bool CopyFrom( const IGeoObj* pGObjSrc) override ; @@ -194,10 +194,12 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW return *this ; } bool RelocateFrom( CurveComposite& ccSrc) ; bool GetApproxLength( double& dLen) const ; + Voronoi* GetVoronoiObject( void) const ; private : bool CopyFrom( const CurveComposite& ccSrc) ; bool Validate( void) ; + bool TestClosure( void) ; bool AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ; bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ; bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ; @@ -211,7 +213,6 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW private : typedef std::deque PCRVSMPL_DEQUE ; - typedef PCRVSMPL_DEQUE::iterator PCSD_ITER ; typedef PCRVSMPL_DEQUE::const_iterator PCSD_CONST_ITER ; private : diff --git a/CurveLine.cpp b/CurveLine.cpp index 8050e48..92e78a2 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -18,6 +18,7 @@ #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EgtPointerOwner.h" diff --git a/CurveLine.h b/CurveLine.h index 73e5860..e7d5de0 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -18,7 +18,8 @@ #include "DllMain.h" #include "GeoObjRW.h" #include "/EgtDev/Include/EGkCurveLine.h" -#include "/EgtDev/Include/EGkVoronoi.h" + +class Voronoi ; //---------------------------------------------------------------------------- class CurveLine : public ICurveLine, public IGeoObjRW @@ -130,7 +131,6 @@ class CurveLine : public ICurveLine, public IGeoObjRW bool TrimEndAtLen( double dLenTrim) override ; bool ExtendStartByLen( double dLenExt) override ; bool ExtendEndByLen( double dLenExt) override ; - Voronoi* GetVoronoiObject( void) const override ; public : // ICurveLine bool CopyFrom( const IGeoObj* pGObjSrc) override ; @@ -157,6 +157,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW { if ( ! CopyFrom( clSrc)) LOG_ERROR( GetEGkLogger(), "CurveLine : copy error") return *this ; } + Voronoi* GetVoronoiObject( void) const ; private : bool CopyFrom( const CurveLine& clSrc) ; diff --git a/DistLineLine.cpp b/DistLineLine.cpp index f915d9a..a045b45 100644 --- a/DistLineLine.cpp +++ b/DistLineLine.cpp @@ -59,7 +59,7 @@ DistLineLine::DistLineLine( const Point3d& ptSt1, const Vector3d& vtD1, double d //---------------------------------------------------------------------------- bool -DistLineLine::GetSqDist( double& dSqDist) +DistLineLine::GetSqDist( double& dSqDist) const { if ( m_dSqDist < 0) return false ; @@ -70,7 +70,7 @@ DistLineLine::GetSqDist( double& dSqDist) //---------------------------------------------------------------------------- bool -DistLineLine::GetDist( double& dDist) +DistLineLine::GetDist( double& dDist) const { if ( m_dSqDist < 0) return false ; @@ -83,7 +83,7 @@ DistLineLine::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistLineLine::GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) +DistLineLine::GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) const { if ( m_dSqDist < 0) return false ; @@ -94,7 +94,7 @@ DistLineLine::GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) //---------------------------------------------------------------------------- bool -DistLineLine::GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) +DistLineLine::GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) const { if ( m_dSqDist < 0) return false ; diff --git a/DistLineLine.h b/DistLineLine.h index ed817fb..1315c29 100644 --- a/DistLineLine.h +++ b/DistLineLine.h @@ -28,16 +28,16 @@ class DistLineLine bool bIsSegment1 = true, bool bIsSegment2 = true) ; public : - bool GetSqDist( double& dSqDist) ; - bool GetDist( double& dDist) ; - bool IsEpsilon( double dTol) { - double dSqDist ; - return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; - } - bool IsSmall( void) { return IsEpsilon( EPS_SMALL) ; } - bool IsZero( void) { return IsEpsilon( EPS_ZERO) ; } - bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) ; - bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) ; + bool GetSqDist( double& dSqDist) const ; + bool GetDist( double& dDist) const ; + bool IsEpsilon( double dTol) const + { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } + bool IsSmall( void) const + { return IsEpsilon( EPS_SMALL) ; } + bool IsZero( void) const + { return IsEpsilon( EPS_ZERO) ; } + bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) const ; + bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) const ; private : void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1, @@ -45,7 +45,7 @@ class DistLineLine bool bIsSegment1, bool bIsSegment2) ; private: double m_dSqDist ; - double m_dDist ; + mutable double m_dDist ; double m_dPos1 ; double m_dPos2 ; Point3d m_ptMinDist1 ; diff --git a/DistPointArc.cpp b/DistPointArc.cpp index 0b78be8..8d266a8 100644 --- a/DistPointArc.cpp +++ b/DistPointArc.cpp @@ -122,14 +122,13 @@ DistPointArc::DistPointHelix( const Point3d& ptP, const ICurveArc& arArc) // cerco la minima distanza per la polilinea MDCVECTOR vApproxMin ; - MDCVECTOR::iterator Iter ; if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin)) return ; // raffino i punti trovati double dPolishedPar ; Point3d ptPolishedQ ; - for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { + for ( auto Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { // eseguo raffinamento if ( PolishMinDistPointCurve( ptP, arArc, *Iter, dPolishedPar, ptPolishedQ)) { (*Iter).dDist = Dist( ptP, ptPolishedQ) ; @@ -148,7 +147,7 @@ DistPointArc::DistPointHelix( const Point3d& ptP, const ICurveArc& arArc) //---------------------------------------------------------------------------- bool -DistPointArc::GetSqDist( double& dSqDist) +DistPointArc::GetSqDist( double& dSqDist) const { if ( m_dDist < 0) return false ; @@ -159,7 +158,7 @@ DistPointArc::GetSqDist( double& dSqDist) //---------------------------------------------------------------------------- bool -DistPointArc::GetDist( double& dDist) +DistPointArc::GetDist( double& dDist) const { if ( m_dDist < 0) return false ; @@ -170,7 +169,7 @@ DistPointArc::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointArc::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) +DistPointArc::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const { if ( m_dDist < 0) return false ; @@ -185,7 +184,7 @@ DistPointArc::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) //---------------------------------------------------------------------------- bool -DistPointArc::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) +DistPointArc::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const { if ( m_dDist < 0) return false ; diff --git a/DistPointArc.h b/DistPointArc.h index 8998dd6..e1369d1 100644 --- a/DistPointArc.h +++ b/DistPointArc.h @@ -27,17 +27,18 @@ class DistPointArc DistPointArc( const Point3d& ptP, const ICurveArc& arArc) ; public : - bool GetSqDist( double& dSqDist) ; - bool GetDist( double& dDist) ; - bool IsEpsilon( double dTol) + bool GetSqDist( double& dSqDist) const ; + bool GetDist( double& dDist) const ; + bool IsEpsilon( double dTol) const { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } - bool IsSmall( void) + bool IsSmall( void) const { return IsEpsilon( EPS_SMALL) ; } - bool IsZero( void) + bool IsZero( void) const { return IsEpsilon( EPS_ZERO) ; } - int GetNbrMinDist( void) { return (int) m_Info.size() ; } - bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; - bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; + int GetNbrMinDist( void) const + { return (int) m_Info.size() ; } + bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const ; + bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const ; private : DistPointArc( void) ; diff --git a/DistPointCrvAux.cpp b/DistPointCrvAux.cpp index 2839d26..773df96 100644 --- a/DistPointCrvAux.cpp +++ b/DistPointCrvAux.cpp @@ -156,13 +156,10 @@ bool FilterMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve, const MDCVECTOR& vApproxMin, double& dMinDist, MDPCIVECTOR& Info) { - MDCVECTOR::const_iterator Iter ; - - // determino i minimi raffinati da tenere bool bFound = false ; bool bLastOnEnd = false ; // flag per ultimo punto su fine del suo intervallo - for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { + for ( auto Iter = vApproxMin.cbegin() ; Iter != vApproxMin.cend() ; ++Iter) { // altro punto con la stessa minima distanza if ( bFound && abs( (*Iter).dDist - dMinDist) < EPS_SMALL) { // se abbastanza lontano e non su bordi intervallino lo aggiungo diff --git a/DistPointCrvBezier.cpp b/DistPointCrvBezier.cpp index 7fc2f70..693d405 100644 --- a/DistPointCrvBezier.cpp +++ b/DistPointCrvBezier.cpp @@ -44,7 +44,6 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& // cerco la minima distanza per la polilinea MDCVECTOR vApproxMin ; - MDCVECTOR::iterator Iter ; if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin)) return ; @@ -52,7 +51,7 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& double dSingP ; if ( CrvBez.GetSingularParam( dSingP) == 0) dSingP = - 1 ; - for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { + for ( auto Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { // imposto flag per singolarità agli estremi (*Iter).bParMinSing = abs( (*Iter).dParMin - dSingP) < EPS_SMALL ; (*Iter).bParMaxSing = abs( (*Iter).dParMax - dSingP) < EPS_SMALL ; @@ -61,7 +60,7 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& // raffino i punti trovati double dPolishedPar ; Point3d ptPolishedQ ; - for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { + for ( auto Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { // eseguo raffinamento if ( PolishMinDistPointCurve( ptP, CrvBez, *Iter, dPolishedPar, ptPolishedQ)) { (*Iter).dDist = Dist( ptP, ptPolishedQ) ; @@ -80,7 +79,7 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& //---------------------------------------------------------------------------- bool -DistPointCrvBezier::GetSqDist( double& dSqDist) +DistPointCrvBezier::GetSqDist( double& dSqDist) const { if ( m_dDist < 0) return false ; @@ -91,7 +90,7 @@ DistPointCrvBezier::GetSqDist( double& dSqDist) //---------------------------------------------------------------------------- bool -DistPointCrvBezier::GetDist( double& dDist) +DistPointCrvBezier::GetDist( double& dDist) const { if ( m_dDist < 0) return false ; @@ -102,7 +101,7 @@ DistPointCrvBezier::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointCrvBezier::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) +DistPointCrvBezier::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const { if ( m_dDist < 0) return false ; @@ -117,7 +116,7 @@ DistPointCrvBezier::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) //---------------------------------------------------------------------------- bool -DistPointCrvBezier::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) +DistPointCrvBezier::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const { if ( m_dDist < 0) return false ; diff --git a/DistPointCrvBezier.h b/DistPointCrvBezier.h index 1cac563..3033756 100644 --- a/DistPointCrvBezier.h +++ b/DistPointCrvBezier.h @@ -27,17 +27,18 @@ class DistPointCrvBezier DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& CrvBez) ; public : - bool GetSqDist( double& dSqDist) ; - bool GetDist( double& dDist) ; - bool IsEpsilon( double dTol) + bool GetSqDist( double& dSqDist) const ; + bool GetDist( double& dDist) const ; + bool IsEpsilon( double dTol) const { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } - bool IsSmall( void) + bool IsSmall( void) const { return IsEpsilon( EPS_SMALL) ; } - bool IsZero( void) + bool IsZero( void) const { return IsEpsilon( EPS_ZERO) ; } - int GetNbrMinDist( void) { return (int) m_Info.size() ; } - bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; - bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; + int GetNbrMinDist( void) const + { return (int) m_Info.size() ; } + bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const ; + bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const ; private : DistPointCrvBezier( void) ; diff --git a/DistPointCrvComposite.cpp b/DistPointCrvComposite.cpp index 45f57fb..42a634c 100644 --- a/DistPointCrvComposite.cpp +++ b/DistPointCrvComposite.cpp @@ -129,7 +129,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo //---------------------------------------------------------------------------- bool -DistPointCrvComposite::GetSqDist( double& dSqDist) +DistPointCrvComposite::GetSqDist( double& dSqDist) const { if ( m_dDist < 0) return false ; @@ -140,7 +140,7 @@ DistPointCrvComposite::GetSqDist( double& dSqDist) //---------------------------------------------------------------------------- bool -DistPointCrvComposite::GetDist( double& dDist) +DistPointCrvComposite::GetDist( double& dDist) const { if ( m_dDist < 0) return false ; @@ -151,7 +151,7 @@ DistPointCrvComposite::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointCrvComposite::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) +DistPointCrvComposite::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const { if ( m_dDist < 0) return false ; @@ -166,7 +166,7 @@ DistPointCrvComposite::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag //---------------------------------------------------------------------------- bool -DistPointCrvComposite::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) +DistPointCrvComposite::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const { if ( m_dDist < 0) return false ; diff --git a/DistPointCrvComposite.h b/DistPointCrvComposite.h index c35f489..f7d20bc 100644 --- a/DistPointCrvComposite.h +++ b/DistPointCrvComposite.h @@ -26,17 +26,18 @@ class DistPointCrvComposite DistPointCrvComposite( const Point3d& ptP, const ICurveComposite& CrvCompo) ; public : - bool GetSqDist( double& dSqDist) ; - bool GetDist( double& dDist) ; - bool IsEpsilon( double dTol) + bool GetSqDist( double& dSqDist) const ; + bool GetDist( double& dDist) const ; + bool IsEpsilon( double dTol) const { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } - bool IsSmall( void) + bool IsSmall( void) const { return IsEpsilon( EPS_SMALL) ; } - bool IsZero( void) + bool IsZero( void) const { return IsEpsilon( EPS_ZERO) ; } - int GetNbrMinDist( void) { return (int) m_Info.size() ; } - bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; - bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; + int GetNbrMinDist( void) const + { return (int) m_Info.size() ; } + bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const ; + bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const ; private : DistPointCrvComposite( void) ; diff --git a/DistPointCurve.cpp b/DistPointCurve.cpp index 5485307..01a37f9 100644 --- a/DistPointCurve.cpp +++ b/DistPointCurve.cpp @@ -98,7 +98,7 @@ DistPointCurve::CrvCompositeCalculate( const Point3d& ptP, const ICurve& Curve) //---------------------------------------------------------------------------- bool -DistPointCurve::GetSqDist( double& dSqDist) +DistPointCurve::GetSqDist( double& dSqDist) const { if ( m_dDist < 0) return false ; @@ -109,7 +109,7 @@ DistPointCurve::GetSqDist( double& dSqDist) //---------------------------------------------------------------------------- bool -DistPointCurve::GetDist( double& dDist) +DistPointCurve::GetDist( double& dDist) const { if ( m_dDist < 0) return false ; @@ -120,7 +120,7 @@ DistPointCurve::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) +DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const { if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size()) return false ; @@ -132,7 +132,7 @@ DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) //---------------------------------------------------------------------------- bool -DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFlag) +DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFlag) const { if ( m_dDist < 0 || m_Info.empty()) return false ; @@ -166,7 +166,7 @@ DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFl //---------------------------------------------------------------------------- bool -DistPointCurve::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) +DistPointCurve::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const { if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size()) return false ; @@ -178,7 +178,7 @@ DistPointCurve::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) //---------------------------------------------------------------------------- bool -DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int& nFlag) +DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int& nFlag) const { if ( m_dDist < 0 || m_Info.empty()) return false ; @@ -209,7 +209,7 @@ DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int& //---------------------------------------------------------------------------- bool -DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide) +DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide) const { if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size()) return false ; @@ -257,7 +257,7 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide //---------------------------------------------------------------------------- bool -DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide) +DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide) const { if ( m_dDist < 0 || m_Info.empty()) return false ; @@ -278,7 +278,7 @@ DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, i //---------------------------------------------------------------------------- bool -DistPointCurve::GetMinDistInfo( int nInd, MinDistPCInfo& aInfo) +DistPointCurve::GetMinDistInfo( int nInd, MinDistPCInfo& aInfo) const { if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size()) return false ; diff --git a/DistPointLine.cpp b/DistPointLine.cpp index f7bea33..ad97230 100644 --- a/DistPointLine.cpp +++ b/DistPointLine.cpp @@ -95,7 +95,7 @@ DistPointLine::Calculate( const Point3d& ptP, //---------------------------------------------------------------------------- bool -DistPointLine::GetSqDist( double& dSqDist) +DistPointLine::GetSqDist( double& dSqDist) const { if ( m_dSqDist < 0) return false ; @@ -106,7 +106,7 @@ DistPointLine::GetSqDist( double& dSqDist) //---------------------------------------------------------------------------- bool -DistPointLine::GetDist( double& dDist) +DistPointLine::GetDist( double& dDist) const { if ( m_dSqDist < 0) return false ; @@ -119,7 +119,7 @@ DistPointLine::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointLine::GetMinDistPoint( Point3d& ptMinDist) +DistPointLine::GetMinDistPoint( Point3d& ptMinDist) const { if ( m_dSqDist < 0) return false ; @@ -130,7 +130,7 @@ DistPointLine::GetMinDistPoint( Point3d& ptMinDist) //---------------------------------------------------------------------------- bool -DistPointLine::GetParamAtMinDistPoint( double& dParam) +DistPointLine::GetParamAtMinDistPoint( double& dParam) const { if ( m_dSqDist < 0) return false ; diff --git a/DistPointLine.h b/DistPointLine.h index e6b92be..08a3bdc 100644 --- a/DistPointLine.h +++ b/DistPointLine.h @@ -31,18 +31,18 @@ class DistPointLine const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment = true) ; public : - bool GetSqDist( double& dSqDist) ; - bool GetDist( double& dDist) ; - bool IsEpsilon( double dTol) + bool GetSqDist( double& dSqDist) const ; + bool GetDist( double& dDist) const ; + bool IsEpsilon( double dTol) const { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } - bool IsSmall( void) + bool IsSmall( void) const { return IsEpsilon( EPS_SMALL) ; } - bool IsZero( void) + bool IsZero( void) const { return IsEpsilon( EPS_ZERO) ; } - int GetNbrMinDist( void) + int GetNbrMinDist( void) const { return (( m_dSqDist < 0) ? 0 : 1) ; } - bool GetMinDistPoint( Point3d& ptMinDist) ; - bool GetParamAtMinDistPoint( double& dParam) ; + bool GetMinDistPoint( Point3d& ptMinDist) const ; + bool GetParamAtMinDistPoint( double& dParam) const ; private : DistPointLine( void) ; @@ -51,7 +51,7 @@ class DistPointLine private : double m_dSqDist ; - double m_dDist ; + mutable double m_dDist ; double m_dParam ; Point3d m_ptMinDist ; } ; diff --git a/DistPointSurfTm.cpp b/DistPointSurfTm.cpp index 44b340f..6ba054d 100644 --- a/DistPointSurfTm.cpp +++ b/DistPointSurfTm.cpp @@ -176,7 +176,7 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf) //---------------------------------------------------------------------------- bool -DistPointSurfTm::GetDist( double& dDist) +DistPointSurfTm::GetDist( double& dDist) const { // Distanza non valida if ( m_dDist < -EPS_ZERO) @@ -188,7 +188,7 @@ DistPointSurfTm::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointSurfTm::GetMinDistPoint( Point3d& ptMinDistPoint) +DistPointSurfTm::GetMinDistPoint( Point3d& ptMinDistPoint) const { // Distanza non valida if ( m_dDist < -EPS_ZERO) @@ -200,7 +200,7 @@ DistPointSurfTm::GetMinDistPoint( Point3d& ptMinDistPoint) //---------------------------------------------------------------------------- bool -DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex) +DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex) const { // Distanza non valida if ( m_dDist < -EPS_ZERO) diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 693c79c..6e8fa5b 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 48dc5a0..8c884bb 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -109,7 +109,7 @@ Use Level3 Disabled - WIN32;_WINDOWS;I_AM_EGK;NVRONI;_DEBUG;%(PreprocessorDefinitions) + WIN32;_WINDOWS;I_AM_EGK;_DEBUG;%(PreprocessorDefinitions) false CompileAsCpp false @@ -145,7 +145,7 @@ copy $(TargetPath) \EgtProg\DllD32 Use Level3 Disabled - WIN32;_WINDOWS;I_AM_EGK;NVRONI;_DEBUG;%(PreprocessorDefinitions) + WIN32;_WINDOWS;I_AM_EGK;_DEBUG;%(PreprocessorDefinitions) false CompileAsCpp false @@ -183,7 +183,7 @@ copy $(TargetPath) \EgtProg\DllD64 MaxSpeed true true - WIN32;_WINDOWS;I_AM_EGK;NVRONI;NDEBUG;%(PreprocessorDefinitions) + WIN32;_WINDOWS;I_AM_EGK;NDEBUG;%(PreprocessorDefinitions) false CompileAsCpp Speed @@ -232,7 +232,7 @@ copy $(TargetPath) \EgtProg\Dll32 MaxSpeed true true - WIN32;_WINDOWS;I_AM_EGK;NVRONI;NDEBUG;%(PreprocessorDefinitions) + WIN32;_WINDOWS;I_AM_EGK;NDEBUG;%(PreprocessorDefinitions) false CompileAsCpp Speed @@ -449,6 +449,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 1f8e8f8..c24cae1 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -1166,6 +1166,9 @@ File di intestazione\Include + + File di intestazione + diff --git a/ExtDimension.cpp b/ExtDimension.cpp index 7e6b156..43d40f6 100644 --- a/ExtDimension.cpp +++ b/ExtDimension.cpp @@ -2,7 +2,7 @@ // EgalTech 2019-2019 //---------------------------------------------------------------------------- // File : ExtDimension.cpp Data : 27.12.19 Versione : 2.2a1 -// Contenuto : Implementazione della classe Dimension (quota). +// Contenuto : Implementazione della classe Dimension ( quota). // // // @@ -63,7 +63,7 @@ ExtDimension::~ExtDimension( void) //---------------------------------------------------------------------------- bool ExtDimension::SetStyle( double dExtLineLen, double dArrowLen, double dTextDist, bool bLenIsMM, - int nDecDigit, const string& sFont, double dTextHeight) + int nDecDigit, const string& sFont, double dTextHeight) { m_dExtLineLen = max( dExtLineLen, MIN_EXTLINELEN) ; m_dArrowLen = max( dArrowLen, MIN_ARROWLEN) ; @@ -93,7 +93,7 @@ ExtDimension::SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d // verifico che i punti di misura non siano coincidenti if ( AreSamePointApprox( m_ptP1, m_ptP2)) return false ; - // direzione di riferimento (nel piano perpendicolare a vtN) + // direzione di riferimento ( nel piano perpendicolare a vtN) m_vtDir = vtDir ; if ( m_vtDir.IsSmall()) m_vtDir = m_ptP2 - m_ptP1 ; @@ -137,7 +137,7 @@ ExtDimension::SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d bool ExtDimension::SetRadial( const Point3d& ptCen, const Point3d& ptPos, const Vector3d& vtN, const string& sText) -{ +{ // il punto m_ptP6 viene utilizzato per il centro // dichiaro quota non ancora determinata m_nType = DT_NONE ; // verifico la definizione del versore normale e del versore X @@ -145,25 +145,20 @@ ExtDimension::SetRadial( const Point3d& ptCen, const Point3d& ptPos, m_vtDir = ptPos - ptCen ; if ( ! m_vtN.Normalize() || ! m_vtDir.Normalize()) return false ; - // porto i punti nel piano definito da ptCen e vtN + m_ptP6 = ptCen ; + m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ; m_ptP1 = ptCen ; - m_ptPos = ptPos - ( ptPos - m_ptP5) * m_vtN * m_vtN ; - m_ptP3 = m_ptP1 ; m_ptP5 = m_ptP1 ; m_ptP2 = m_ptPos ; - m_ptP4 = m_ptPos ; - m_ptP6 = m_ptPos ; - // verifico che i punti di misura non siano coincidenti - if ( AreSamePointApprox( m_ptP5, m_ptPos)) + if ( AreSamePointApprox( m_ptP6, m_ptPos)) return false ; - - // assegnazione del testo + // assegnazione del testo m_sText = sText ; - // assegno il tipo + // assegno il tipo m_nType = DT_RADIAL ; - // imposto da calcolare + // imposto da calcolare m_bToCalc = true ; m_OGrMgr.Reset() ; @@ -174,7 +169,7 @@ ExtDimension::SetRadial( const Point3d& ptCen, const Point3d& ptPos, bool ExtDimension::SetDiametral( const Point3d& ptCen, const Point3d& ptPos, const Vector3d& vtN, const string& sText) -{ +{ // il punto m_ptP6 viene utilizzato per il centro // dichiaro quota non ancora determinata m_nType = DT_NONE ; // verifico la definizione del versore normale e del versore X @@ -182,26 +177,21 @@ ExtDimension::SetDiametral( const Point3d& ptCen, const Point3d& ptPos, m_vtDir = ptPos - ptCen ; if ( ! m_vtN.Normalize() || ! m_vtDir.Normalize()) return false ; - - // porto i punti nel piano definito da ptP1 e vtN - m_ptPos = ptPos - ( ptPos - ptCen) * m_vtN * m_vtN ; + // porto i punti nel piano definito da ptP6 e vtN + m_ptP6 = ptCen ; + m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ; m_ptP2 = m_ptPos ; - m_ptP6 = m_ptPos ; - m_ptP4 = m_ptPos ; // ottengo il punto diametralmente opposto a ptPos m_ptP1 = ptCen - ( m_ptPos - ptCen) ; m_ptP5 = m_ptP1 ; - m_ptP3 = m_ptP1 ; - // verifico che i punti di misura non siano coincidenti if ( AreSamePointApprox( m_ptP5, m_ptPos)) return false ; - - // assegnazione del testo + // assegnazione del testo m_sText = sText ; - // assegno il tipo + // assegno il tipo m_nType = DT_DIAMETRAL ; - // imposto da calcolare + // imposto da calcolare m_bToCalc = true ; m_OGrMgr.Reset() ; @@ -210,7 +200,7 @@ ExtDimension::SetDiametral( const Point3d& ptCen, const Point3d& ptPos, //---------------------------------------------------------------------------- bool -ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptV, const Point3d& ptPos, +ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d& ptP2, const Point3d& ptPos, const Vector3d& vtN, const string& sText) { // dichiaro quota non ancora determinata @@ -222,32 +212,25 @@ ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptP2, const Point3 // porto i punti nel piano definito da P1 e N m_ptP1 = ptP1 ; m_ptP2 = ptP2 - ( ptP2 - m_ptP1) * m_vtN * m_vtN ; - m_ptP5 = ptV - ( ptV - m_ptP1) * m_vtN * m_vtN ; + m_ptP6 = ptV - ( ptV - m_ptP1) * m_vtN * m_vtN ; m_ptPos = ptPos - ( ptPos - m_ptP1) * m_vtN * m_vtN ; // verifico che i punti di misura non siano coincidenti - if ( AreSamePointApprox( m_ptP1, m_ptP2) || AreSamePointApprox( m_ptP1, m_ptP5) || AreSamePointApprox( m_ptP2, m_ptP5)) + if ( AreSamePointApprox( m_ptP1, m_ptP2) || AreSamePointApprox( m_ptP1, m_ptP6) || AreSamePointApprox( m_ptP2, m_ptP5)) return false ; - // calcolo le direzioni su cui giacciono i due lati dell'angolo - Vector3d vtLine1 = m_ptP1 - m_ptP5 ; - Vector3d vtLine2 = m_ptP2 - m_ptP5 ; - double dLen1 = vtLine1.Len() ; - double dLen2 = vtLine2.Len() ; - if ( ! vtLine1.Normalize() || ! vtLine2.Normalize()) - return false ; - // direzione di riferimento (nel piano perpendicolare a vtN) - m_vtDir = m_ptPos - m_ptP5 ; + // direzione di riferimento ( nel piano perpendicolare a vtN) + m_vtDir = m_ptPos - m_ptP6 ; double dLenDir = m_vtDir.Len() ; - + // controllo se è testo o se è la misura - double dHalfDist ; double dFactor ; if ( m_sCalcText.find( IS_MEASURE) != string::npos) { - dHalfDist = GetTextHalfDist( m_ptPos) ; + m_sCalcText = "300.00" ; + double dHalfDist = GetTextHalfDist( m_ptPos) ; dFactor = 2.5 * dHalfDist ; m_sCalcText = "" ; } else { - dHalfDist = GetTextHalfDist( m_ptPos) ; + double dHalfDist = GetTextHalfDist( m_ptPos) ; dFactor = 2.5 * dHalfDist ; } // allungo m_vtDir se è troppo vicino al centro @@ -255,24 +238,26 @@ ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptP2, const Point3 Vector3d vtDir_n = m_vtDir ; if ( ! vtDir_n.Normalize()) return false ; - m_ptPos = m_ptP5 + dFactor * vtDir_n ; + m_ptPos = m_ptP6 + dFactor * vtDir_n ; // ricalcolo m_vtDir - m_vtDir = m_ptPos - m_ptP5 ; + m_vtDir = m_ptPos - m_ptP6 ; dLenDir = m_vtDir.Len() ; } - + // calcolo le direzioni su cui giacciono i due lati dell'angolo + Vector3d vtLine1 = m_ptP1 - m_ptP6 ; + Vector3d vtLine2 = m_ptP2 - m_ptP6 ; + double dLen1 = vtLine1.Len() ; + double dLen2 = vtLine2.Len() ; + if ( ! vtLine1.Normalize() || ! vtLine2.Normalize()) + return false ; // segnalo se i punti che definiscono i lati sono più lontani dal centro di ptPos - bool bPt1Close = false ; - bool bPt2Close = false ; - if ( dLenDir < dLen1) - bPt1Close = true ; - if ( dLenDir < dLen2) - bPt2Close = true ; + bool bPt1Close = ( dLenDir < dLen1 ? true : false) ; + bool bPt2Close = ( dLenDir < dLen2 ? true : false) ; m_ptP5 = m_ptP1 + ( dLenDir - dLen1) * vtLine1 ; - m_ptP6 = m_ptP2 + ( dLenDir - dLen2) * vtLine2 ; + Point3d ptP5_bis = m_ptP2 + ( dLenDir - dLen2) * vtLine2 ; m_ptP3 = m_ptP5 + ( bPt1Close ? - vtLine1 : vtLine1) * m_dExtLineLen ; - m_ptP4 = m_ptP6 + ( bPt2Close ? - vtLine2 : vtLine2) * m_dExtLineLen ; - + m_ptP4 = ptP5_bis + ( bPt2Close ? - vtLine2 : vtLine2) * m_dExtLineLen ; + // assegnazione del testo m_sText = sText ; // assegno il tipo @@ -332,6 +317,7 @@ ExtDimension::CopyFrom( const ExtDimension& clSrc) m_sCalcText = clSrc.m_sCalcText ; m_ptCalcPos = clSrc.m_ptCalcPos ; m_bCalcArrowIn = clSrc.m_bCalcArrowIn ; + m_bCalcTextOn = clSrc.m_bCalcTextOn ; m_ptCalcP7 = clSrc.m_ptCalcP7 ; m_ptCalcP8 = clSrc.m_ptCalcP8 ; m_dExtLineLen = clSrc.m_dExtLineLen ; @@ -380,15 +366,15 @@ ExtDimension::Dump( string& sOut, bool bMM, const char* szNewLine) const { // parametri sOut += GetSubType() + szNewLine ; - sOut += "VN(" + ToString( m_vtN, 3) + ") " + szNewLine ; - sOut += "VD(" + ToString( m_vtDir, 3) + ") " + szNewLine ; - sOut += "P1(" + ToString( GetInUiUnits( m_ptP1, bMM), 3) + ") " + szNewLine ; - sOut += "P2(" + ToString( GetInUiUnits( m_ptP2, bMM), 3) + ") " + szNewLine ; - sOut += "P3(" + ToString( GetInUiUnits( m_ptP3, bMM), 3) + ") " + szNewLine ; - sOut += "P4(" + ToString( GetInUiUnits( m_ptP4, bMM), 3) + ") " + szNewLine ; - sOut += "P5(" + ToString( GetInUiUnits( m_ptP5, bMM), 3) + ") " + szNewLine ; - sOut += "P6(" + ToString( GetInUiUnits( m_ptP6, bMM), 3) + ") " + szNewLine ; - sOut += "Pos(" + ToString( GetInUiUnits( m_ptPos, bMM), 3) + ") " + szNewLine ; + sOut += "VN( " + ToString( m_vtN, 3) + ") " + szNewLine ; + sOut += "VD( " + ToString( m_vtDir, 3) + ") " + szNewLine ; + sOut += "P1( " + ToString( GetInUiUnits( m_ptP1, bMM), 3) + ") " + szNewLine ; + sOut += "P2( " + ToString( GetInUiUnits( m_ptP2, bMM), 3) + ") " + szNewLine ; + sOut += "P3( " + ToString( GetInUiUnits( m_ptP3, bMM), 3) + ") " + szNewLine ; + sOut += "P4( " + ToString( GetInUiUnits( m_ptP4, bMM), 3) + ") " + szNewLine ; + sOut += "P5( " + ToString( GetInUiUnits( m_ptP5, bMM), 3) + ") " + szNewLine ; + sOut += "P6( " + ToString( GetInUiUnits( m_ptP6, bMM), 3) + ") " + szNewLine ; + sOut += "Pos( " + ToString( GetInUiUnits( m_ptPos, bMM), 3) + ") " + szNewLine ; sOut += "Txt=" + m_sText + szNewLine ; sOut += "El=" + ToString( GetInUiUnits( m_dExtLineLen, bMM), 3) + " Al=" + ToString( GetInUiUnits( m_dArrowLen, bMM), 3) + @@ -529,7 +515,7 @@ ExtDimension::GetLocalBBox( BBox3d& b3Loc, int nFlag) const return true ; } else if ( m_nType == DT_RADIAL) { - b3Loc.Set( m_ptP5) ; + b3Loc.Set( m_ptP6) ; b3Loc.Add( m_ptPos) ; // ingombro del testo BBox3d b3Text ; @@ -538,7 +524,7 @@ ExtDimension::GetLocalBBox( BBox3d& b3Loc, int nFlag) const return true ; } else if ( m_nType == DT_DIAMETRAL) { - b3Loc.Set( m_ptP5) ; + b3Loc.Set( m_ptP6) ; b3Loc.Add( m_ptPos) ; // ingombro del testo BBox3d b3Text ; @@ -552,6 +538,7 @@ ExtDimension::GetLocalBBox( BBox3d& b3Loc, int nFlag) const b3Loc.Add( m_ptP3) ; b3Loc.Add( m_ptP4) ; b3Loc.Set( m_ptP5) ; + b3Loc.Set( m_ptP6) ; b3Loc.Add( m_ptCalcP7) ; b3Loc.Add( m_ptCalcP8) ; // ingombro del testo @@ -575,7 +562,7 @@ ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const Update() ; // se valido if ( m_nType == DT_LINEAR) { - // ingombro dei punti (portati nel riferimento passato) + // ingombro dei punti ( portati nel riferimento passato) Point3d ptFrP1 = m_ptP1 ; ptFrP1.ToGlob( frRef) ; b3Ref.Set( ptFrP1) ; @@ -601,8 +588,8 @@ ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const return true ; } else if ( m_nType == DT_RADIAL) { - // ingombro dei punti (portati nel riferimento passato) - Point3d ptFrP5 = m_ptP5 ; + // ingombro dei punti ( portati nel riferimento passato) + Point3d ptFrP5 = m_ptP6 ; ptFrP5.ToGlob( frRef) ; b3Ref.Set( ptFrP5) ; Point3d ptFrPos = m_ptPos ; @@ -615,8 +602,8 @@ ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const return true ; } else if ( m_nType == DT_DIAMETRAL) { - // ingombro dei punti (portati nel riferimento passato) - Point3d ptFrP5 = m_ptP5 ; + // ingombro dei punti ( portati nel riferimento passato) + Point3d ptFrP5 = m_ptP6 ; ptFrP5.ToGlob( frRef) ; b3Ref.Set( ptFrP5) ; Point3d ptFrPos = m_ptPos ; @@ -629,9 +616,6 @@ ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const return true ; } else if ( m_nType == DT_ANGULAR) { - Point3d ptFrP5 = m_ptP5 ; - ptFrP5.ToGlob( frRef) ; - b3Ref.Set( ptFrP5) ; Point3d ptFrP1 = m_ptP1 ; ptFrP1.ToGlob( frRef) ; b3Ref.Add( ptFrP1) ; @@ -644,6 +628,12 @@ ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const Point3d ptFrP4 = m_ptP4 ; ptFrP4.ToGlob( frRef) ; b3Ref.Add( ptFrP4) ; + Point3d ptFrP5 = m_ptP5 ; + ptFrP5.ToGlob( frRef) ; + b3Ref.Set( ptFrP5) ; + Point3d ptFrP6 = m_ptP6 ; + ptFrP6.ToGlob( frRef) ; + b3Ref.Set( ptFrP6) ; Point3d ptFrP7 = m_ptCalcP7 ; ptFrP7.ToGlob( frRef) ; b3Ref.Add( ptFrP7) ; @@ -698,14 +688,14 @@ ExtDimension::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, // se valido if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { return ( m_vtN.Rotate( vtAx, dCosAng, dSinAng) && - m_vtDir.Rotate( vtAx, dCosAng, dSinAng) && - m_ptP1.Rotate( ptAx, vtAx, dCosAng, dSinAng) && - m_ptP2.Rotate( ptAx, vtAx, dCosAng, dSinAng) && - m_ptP3.Rotate( ptAx, vtAx, dCosAng, dSinAng) && - m_ptP4.Rotate( ptAx, vtAx, dCosAng, dSinAng) && - m_ptP5.Rotate( ptAx, vtAx, dCosAng, dSinAng) && - m_ptP6.Rotate( ptAx, vtAx, dCosAng, dSinAng) && - m_ptPos.Rotate( ptAx, vtAx, dCosAng, dSinAng)) ; + m_vtDir.Rotate( vtAx, dCosAng, dSinAng) && + m_ptP1.Rotate( ptAx, vtAx, dCosAng, dSinAng) && + m_ptP2.Rotate( ptAx, vtAx, dCosAng, dSinAng) && + m_ptP3.Rotate( ptAx, vtAx, dCosAng, dSinAng) && + m_ptP4.Rotate( ptAx, vtAx, dCosAng, dSinAng) && + m_ptP5.Rotate( ptAx, vtAx, dCosAng, dSinAng) && + m_ptP6.Rotate( ptAx, vtAx, dCosAng, dSinAng) && + m_ptPos.Rotate( ptAx, vtAx, dCosAng, dSinAng)) ; } else return false ; @@ -739,6 +729,8 @@ ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, doubl return false ; if ( ! m_ptP2.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) return false ; + if ( ! m_ptP6.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) + return false ; if ( ! m_ptPos.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) return false ; // ricalcolo completamente la quota @@ -746,11 +738,11 @@ ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, doubl case DT_LINEAR : return SetLinear( m_ptP1, m_ptP2, m_ptPos, m_vtN, m_vtDir, m_sText) ; case DT_RADIAL : - return SetRadial( m_ptP5, m_ptPos, m_vtN, m_sText) ; + return SetRadial( m_ptP6, m_ptPos, m_vtN, m_sText) ; case DT_DIAMETRAL : - return SetDiametral( m_ptP5, m_ptPos, m_vtN, m_sText) ; + return SetDiametral( m_ptP6, m_ptPos, m_vtN, m_sText) ; case DT_ANGULAR : - return SetAngular( m_ptP5, m_ptP1, m_ptP2, m_ptPos, m_vtN, m_sText) ; + return SetAngular( m_ptP1, m_ptP6, m_ptP2, m_ptPos, m_vtN, m_sText) ; default : return false ; } @@ -773,12 +765,12 @@ ExtDimension::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) // se valido if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { - // eseguo il mirror dei versori + // eseguo il mirror dei versori if ( ! m_vtN.Mirror( vtNorm)) return false ; if ( ! m_vtDir.Mirror( vtNorm)) return false ; - // eseguo il mirror dei punti + // eseguo il mirror dei punti if ( ! m_ptP1.Mirror( ptOn, vtNorm)) return false ; if ( ! m_ptP2.Mirror( ptOn, vtNorm)) @@ -827,6 +819,8 @@ ExtDimension::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d return false ; if ( ! m_ptP2.Shear( ptOn, vtNorm, vtDir, dCoeff)) return false ; + if ( ! m_ptP6.Shear( ptOn, vtNorm, vtDir, dCoeff)) + return false ; if ( ! m_ptPos.Shear( ptOn, vtNorm, vtDir, dCoeff)) return false ; // ricalcolo completamente la quota @@ -834,11 +828,11 @@ ExtDimension::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d case DT_LINEAR : return SetLinear( m_ptP1, m_ptP2, m_ptPos, m_vtN, m_vtDir, m_sText) ; case DT_RADIAL : - return SetRadial( m_ptP5, m_ptPos, m_vtN, m_sText) ; + return SetRadial( m_ptP6, m_ptPos, m_vtN, m_sText) ; case DT_DIAMETRAL : - return SetDiametral( m_ptP5, m_ptPos, m_vtN, m_sText) ; + return SetDiametral( m_ptP6, m_ptPos, m_vtN, m_sText) ; case DT_ANGULAR : - return SetAngular( m_ptP5, m_ptP1, m_ptP2, m_ptPos, m_vtN, m_sText) ; + return SetAngular( m_ptP1, m_ptP6, m_ptP2, m_ptPos, m_vtN, m_sText) ; default : return false ; } @@ -865,16 +859,16 @@ ExtDimension::ToGlob( const Frame3d& frRef) // se valido if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { - // trasformo punto e versori + // trasformo punto e versori return ( m_vtN.ToGlob( frRef) && - m_vtDir.ToGlob( frRef) && - m_ptP1.ToGlob( frRef) && - m_ptP2.ToGlob( frRef) && - m_ptP3.ToGlob( frRef) && - m_ptP4.ToGlob( frRef) && - m_ptP5.ToGlob( frRef) && - m_ptP6.ToGlob( frRef) && - m_ptPos.ToGlob( frRef)) ; + m_vtDir.ToGlob( frRef) && + m_ptP1.ToGlob( frRef) && + m_ptP2.ToGlob( frRef) && + m_ptP3.ToGlob( frRef) && + m_ptP4.ToGlob( frRef) && + m_ptP5.ToGlob( frRef) && + m_ptP6.ToGlob( frRef) && + m_ptPos.ToGlob( frRef)) ; } else return false ; @@ -898,16 +892,16 @@ ExtDimension::ToLoc( const Frame3d& frRef) // se valido if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { - // trasformo punto e versori + // trasformo punto e versori return ( m_vtN.ToLoc( frRef) && - m_vtDir.ToLoc( frRef) && - m_ptP1.ToLoc( frRef) && - m_ptP2.ToLoc( frRef) && - m_ptP3.ToLoc( frRef) && - m_ptP4.ToLoc( frRef) && - m_ptP5.ToLoc( frRef) && - m_ptP6.ToLoc( frRef) && - m_ptPos.ToLoc( frRef)) ; + m_vtDir.ToLoc( frRef) && + m_ptP1.ToLoc( frRef) && + m_ptP2.ToLoc( frRef) && + m_ptP3.ToLoc( frRef) && + m_ptP4.ToLoc( frRef) && + m_ptP5.ToLoc( frRef) && + m_ptP6.ToLoc( frRef) && + m_ptPos.ToLoc( frRef)) ; } else return false ; @@ -933,14 +927,14 @@ ExtDimension::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { // trasformo punto e versori return ( m_vtN.ToGlob( frOri) && m_vtN.ToLoc( frDest) && - m_vtDir.ToGlob( frOri) && m_vtDir.ToLoc( frDest) && - m_ptP1.ToGlob( frOri) && m_ptP1.ToLoc( frDest) && - m_ptP2.ToGlob( frOri) && m_ptP2.ToLoc( frDest) && - m_ptP3.ToGlob( frOri) && m_ptP3.ToLoc( frDest) && - m_ptP4.ToGlob( frOri) && m_ptP4.ToLoc( frDest) && - m_ptP5.ToGlob( frOri) && m_ptP5.ToLoc( frDest) && - m_ptP6.ToGlob( frOri) && m_ptP6.ToLoc( frDest) && - m_ptPos.ToGlob( frOri) && m_ptPos.ToLoc( frDest)) ; + m_vtDir.ToGlob( frOri) && m_vtDir.ToLoc( frDest) && + m_ptP1.ToGlob( frOri) && m_ptP1.ToLoc( frDest) && + m_ptP2.ToGlob( frOri) && m_ptP2.ToLoc( frDest) && + m_ptP3.ToGlob( frOri) && m_ptP3.ToLoc( frDest) && + m_ptP4.ToGlob( frOri) && m_ptP4.ToLoc( frDest) && + m_ptP5.ToGlob( frOri) && m_ptP5.ToLoc( frDest) && + m_ptP6.ToGlob( frOri) && m_ptP6.ToLoc( frDest) && + m_ptPos.ToGlob( frOri) && m_ptPos.ToLoc( frDest)) ; } else return false ; @@ -993,7 +987,7 @@ ExtDimension::Update( void) const else m_ptCalcPos = m_ptCalcP8 + m_vtDir * dHalfDist ; } - // dichiaro ricalcolo eseguito + // dichiaro ricalcolo eseguito m_bToCalc = false ; return true ; } @@ -1012,21 +1006,27 @@ ExtDimension::Update( void) const ReplaceString( m_sCalcText, IS_MEASURE, sVal) ; } // punto di inserimento del testo - m_ptCalcPos = ( m_ptP5 + m_ptP6) / 2 ; + m_ptCalcPos = ( m_ptP5 + m_ptP2) / 2 ; // alzo il testo dalla linea di misura BBox3d b3Text ; if ( ! GetTextMyBBox( b3Text) && ! b3Text.IsEmpty()) return false ; double dHeight = b3Text.GetMax().y - b3Text.GetMin().y ; - Vector3d vtPerpDir = m_ptPos - m_ptP5 ; - vtPerpDir.Normalize() ; - if ( ! vtPerpDir.Rotate( m_vtN, 90)) + Vector3d vtPerpDir = m_ptPos - m_ptP6 ; + if ( ! vtPerpDir.Normalize()) + return false ; + // calcolo il frame dell'arco per valutare la posizione del testo + Frame3d frRef ; + if ( ! frRef.Set( m_ptP6, m_vtN)) + return false ; + double dAngDeg = 0 ; + if ( ! m_vtDir.GetAngle( frRef.VersX(), dAngDeg) || ! vtPerpDir.Rotate( m_vtN, ( dAngDeg < 90 ? 90 : -90))) return false ; m_ptCalcPos = m_ptCalcPos + 0.6 * dHeight * vtPerpDir ; // semidistanza di interruzione double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; // lunghezza della linea di misura - double dLen = ( m_ptP6 - m_ptP5).Len() ; + double dLen = Dist( m_ptP1, m_ptP2) ; // determino come orientare le frecce e dove mettere il testo if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) { m_bCalcArrowIn = true ; @@ -1039,7 +1039,7 @@ ExtDimension::Update( void) const m_bCalcArrowIn = false ; m_bCalcTextOn = true ; m_ptCalcP7 = m_ptP5 - m_vtDir * 2 * m_dArrowLen ; - m_ptCalcP8 = m_ptP6 + m_vtDir * 2 * m_dArrowLen ; + m_ptCalcP8 = m_ptP2 + m_vtDir * 2 * m_dArrowLen ; } // stanno fuori sia le frecce sia il testo else { @@ -1047,7 +1047,8 @@ ExtDimension::Update( void) const m_bCalcTextOn = false ; // metto la quotatura dal lato di ptPos Vector3d vtRad = m_ptPos - m_ptP5 ; - vtRad.Normalize() ; + if ( ! vtRad.Normalize()) + return false ; m_ptCalcPos = m_ptPos + vtRad * ( dHalfDist + 2 * m_dArrowLen) ; } // dichiaro ricalcolo eseguito @@ -1057,9 +1058,11 @@ ExtDimension::Update( void) const case DT_ANGULAR : { // angolo double dAngDeg, dAngDeg1, dAngDeg2 = 0 ; - Vector3d vtLine1 = m_ptP1 - m_ptP5 ; - Vector3d vtLine2 = m_ptP2 - m_ptP5 ; - Vector3d vtLine3 = m_ptPos - m_ptP5 ; + Vector3d vtLine1 = m_ptP1 - m_ptP6 ; + Vector3d vtLine2 = m_ptP2 - m_ptP6 ; + Vector3d vtLine3 = m_ptPos - m_ptP6 ; + // calcolo gli angoli tra m_ptPos e i due punti che identificano i lati dell'angolo + // per capire se sto calcolando l'angolo interno o esterno if ( ! vtLine1.GetAngle( vtLine2, dAngDeg) || ! vtLine1.GetAngle( vtLine3, dAngDeg1) || ! vtLine2.GetAngle( vtLine3, dAngDeg2)) return false ; if ( dAngDeg < dAngDeg1 + dAngDeg2 - EPS_SMALL || dAngDeg > dAngDeg1 + dAngDeg2 + EPS_SMALL) @@ -1067,14 +1070,17 @@ ExtDimension::Update( void) const // testo m_sCalcText = m_sText ; if ( m_sCalcText.find( IS_MEASURE) != string::npos) { - // calcolo gli angoli tra m_ptPos e i due punti che identificano i lati dell'angolo - // per capire se sto calcolando l'angolo interno o esterno string sAngDeg = ToString( dAngDeg, m_nDecDigit) ; ReplaceString( m_sCalcText, IS_MEASURE, sAngDeg + "°") ; } + // calcolo ptP5_bis + double dLen2 = vtLine2.Len() ; + if ( ! vtLine2.Normalize()) + return false ; + Point3d ptP5_bis = m_ptP2 + ( m_vtDir.Len() - dLen2) * vtLine2 ; // calcolo l'arco su cui metterò la misura PtrOwner pCrvPos( CreateBasicCurveArc()) ; - if ( IsNull( pCrvPos) || ! pCrvPos->Set3P( m_ptP6, m_ptPos, m_ptP5, false)) + if ( IsNull( pCrvPos) || ! pCrvPos->Set3P( ptP5_bis, m_ptPos, m_ptP5, false)) return false ; // punto di inserimento del testo pCrvPos->GetMidPoint( m_ptCalcPos) ; @@ -1085,15 +1091,14 @@ ExtDimension::Update( void) const if ( ! pCrvPos->GetLength( dLen)) return false ; // calcolo anche lo spazio ad una distanza dal centro maggiorata - double dLenPos = 0 ; - double dDist = Dist( m_ptCalcPos, m_ptP5) ; - dLenPos = dDist * dAngDeg * DEGTORAD ; - // determino come orientare le frecce e dove mettere il testo - double dU ; + double dDist = Dist( m_ptCalcPos, m_ptP6) ; + double dLenPos = dDist * dAngDeg * DEGTORAD ; + // determino come orientare le frecce e dove mettere il testo // frecce e testo dentro if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) { m_bCalcArrowIn = true ; m_bCalcTextOn = true ; + double dU ; pCrvPos->GetParamAtLength( dLen / 2. + dHalfDist, dU) ; pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP7) ; pCrvPos->GetParamAtLength( dLen / 2. - dHalfDist, dU) ; @@ -1104,12 +1109,11 @@ ExtDimension::Update( void) const else if ( dLen > 2 * dHalfDist || ( dLen < 2 * dHalfDist && dLenPos > 2 * dHalfDist)) { m_bCalcArrowIn = false ; m_bCalcTextOn = true ; + double dU ; pCrvPos->GetParamAtLength( dLen / 2. + dHalfDist, dU) ; pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP7) ; pCrvPos->GetParamAtLength( dLen / 2. - dHalfDist, dU) ; pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP8) ; - //pCrvPosExt->GetStartPoint( m_ptCalcP8) ; - //pCrvPosExt->GetEndPoint( m_ptCalcP7) ; if ( dLen < 2 * dHalfDist) { m_ptCalcPos += ( m_ptCalcPos - m_ptP5) ; m_bCalcTextOn = false ; @@ -1119,11 +1123,9 @@ ExtDimension::Update( void) const else { m_bCalcArrowIn = false ; m_bCalcTextOn = false ; - //pCrvPosExt->GetStartPoint( m_ptCalcP8) ; - //pCrvPosExt->GetEndPoint( m_ptCalcP7) ; vtLine1.Normalize() ; vtLine2.Normalize() ; - if ( Dist( m_ptPos, m_ptP5) < Dist( m_ptPos, m_ptP6)) { + if ( Dist( m_ptPos, m_ptP5) < Dist( m_ptPos, ptP5_bis)) { Vector3d vtDirEnd ; pCrvPos->GetEndDir( vtDirEnd) ; m_ptCalcPos = m_ptP5 + dHalfDist * ( vtDirEnd + vtLine1) ; @@ -1131,7 +1133,7 @@ ExtDimension::Update( void) const else { Vector3d vtDirStart ; pCrvPos->GetStartDir( vtDirStart) ; - m_ptCalcPos = m_ptP6 + dHalfDist * ( - vtDirStart + vtLine2) ; + m_ptCalcPos = ptP5_bis + dHalfDist * ( - vtDirStart + vtLine2) ; } } // dichiaro ricalcolo eseguito @@ -1156,12 +1158,18 @@ ExtDimension::GetMidPoint( Point3d& ptMid) const ptMid = ( m_ptP1 + m_ptP2) / 2; return true ; case DT_ANGULAR : - { PtrOwner pCrvPos( CreateBasicCurveArc()) ; - if ( ! pCrvPos->Set3P( m_ptP6, m_ptPos, m_ptP5, false)) - return false ; - pCrvPos->GetMidPoint( ptMid) ; - return true ; - } + { // calcolo ptP5_bis + Vector3d vtLine2 = m_ptP2 - m_ptP6 ; + double dLen2 = vtLine2.Len() ; + if ( ! vtLine2.Normalize()) + return false ; + Point3d ptP5_bis = m_ptP2 + ( m_vtDir.Len() - dLen2) * vtLine2 ; + Vector3d vtMid = ( ptP5_bis + m_ptP5) / 2 - m_ptP6 ; + if ( ! vtMid.Normalize()) + return false ; + ptMid = m_ptP6 + vtMid * m_vtDir.Len() ; + return true; + } default : return false ; } @@ -1181,7 +1189,7 @@ ExtDimension::GetCenterPoint( Point3d& ptCen) const case DT_RADIAL : case DT_DIAMETRAL : case DT_ANGULAR : - ptCen = m_ptP5 ; + ptCen = m_ptP6 ; return true ; default : return false ; @@ -1196,153 +1204,154 @@ ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& Update() ; // se quota valida switch ( m_nType) { - case DT_LINEAR : { - // prima linea di riferimento + case DT_LINEAR : { + // prima linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP1) ; + lstPL.back().AddUPoint( 1, m_ptP3) ; + // seconda linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP2) ; + lstPL.back().AddUPoint( 1, m_ptP4) ; + // se non c'è testo, linea di misura intera + if ( IsEmptyOrSpaces( m_sCalcText)) { lstPL.emplace_back() ; - lstPL.back().AddUPoint(0, m_ptP1) ; - lstPL.back().AddUPoint(1, m_ptP3) ; - // seconda linea di riferimento - lstPL.emplace_back() ; - lstPL.back().AddUPoint(0, m_ptP2) ; - lstPL.back().AddUPoint(1, m_ptP4) ; - // se non c'è testo, linea di misura intera - if ( IsEmptyOrSpaces(m_sCalcText)) { - lstPL.emplace_back() ; - lstPL.back().AddUPoint(0, m_ptP5) ; - lstPL.back().AddUPoint(1, m_ptP6) ; - } - // altrimenti, linea di misura divisa in due parti - else { - // prima parte - lstPL.emplace_back() ; - lstPL.back().AddUPoint(0, m_ptP5) ; - lstPL.back().AddUPoint(1, m_ptCalcP7) ; - // seconda parte - lstPL.emplace_back() ; - lstPL.back().AddUPoint(0, m_ptP6) ; - lstPL.back().AddUPoint(1, m_ptCalcP8) ; - } - // frecce - lstPL.emplace_back() ; - GetArrowHead(m_ptP5, ( m_bCalcArrowIn ? -m_vtDir : m_vtDir), lstPL.back()) ; - lstPL.emplace_back() ; - GetArrowHead(m_ptP6, ( m_bCalcArrowIn ? m_vtDir : -m_vtDir), lstPL.back()) ; - // testo - POLYLINELIST lstTxt; - if ( ApproxTextWithLines(dLinTol, dAngTolDeg, lstTxt)) - lstPL.splice(lstPL.end(), lstTxt) ; - return true ; + lstPL.back().AddUPoint( 0, m_ptP5) ; + lstPL.back().AddUPoint( 1, m_ptP6) ; } - case DT_RADIAL : - case DT_DIAMETRAL : { - Vector3d vtRad = m_ptPos - m_ptP5 ; - vtRad.Normalize() ; - // prima linea di riferimento + // altrimenti, linea di misura divisa in due parti + else { + // prima parte lstPL.emplace_back() ; - lstPL.back().AddUPoint(0, m_ptP1) ; - lstPL.back().AddUPoint(1, m_ptP2) ; - // freccia + lstPL.back().AddUPoint( 0, m_ptP5) ; + lstPL.back().AddUPoint( 1, m_ptCalcP7) ; + // seconda parte lstPL.emplace_back() ; - GetArrowHead(m_ptP6, ( m_bCalcArrowIn ? vtRad : - vtRad), lstPL.back()) ; - Point3d ptArrowTail ; - if ( ! m_bCalcArrowIn) { - lstPL.emplace_back() ; - ptArrowTail = m_ptP6 + vtRad * m_dArrowLen * 2 ; - lstPL.back().AddUPoint(0, m_ptP6) ; - lstPL.back().AddUPoint(1, ptArrowTail) ; - } - if ( m_nType == DT_DIAMETRAL) { - lstPL.emplace_back() ; - GetArrowHead(m_ptP5, ( m_bCalcArrowIn ? - vtRad : vtRad), lstPL.back()) ; - if ( ! m_bCalcArrowIn) { - lstPL.emplace_back() ; - ptArrowTail = m_ptP5 - vtRad * m_dArrowLen * 2 ; - lstPL.back().AddUPoint(0, m_ptP5) ; - lstPL.back().AddUPoint(1, ptArrowTail) ; - } - } - // testo - POLYLINELIST lstTxt; - if ( ApproxTextWithLines(dLinTol, dAngTolDeg, lstTxt)) - lstPL.splice(lstPL.end(), lstTxt) ; - return true ; + lstPL.back().AddUPoint( 0, m_ptP6) ; + lstPL.back().AddUPoint( 1, m_ptCalcP8) ; } - case DT_ANGULAR : { - // approssimerò l'arco con una polyline - PolyLine plApprox ; - // cerca nel geom kernel delle tolleranze standard - double dLinTol = 0.01 ; - double dAngTolDeg = 0.01 ; - // prima linea di riferimento - lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP1) ; - lstPL.back().AddUPoint( 1, m_ptP3) ; - // seconda linea di riferimento + // frecce + lstPL.emplace_back() ; + GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? -m_vtDir : m_vtDir), lstPL.back()) ; + lstPL.emplace_back() ; + GetArrowHead( m_ptP6, ( m_bCalcArrowIn ? m_vtDir : -m_vtDir), lstPL.back()) ; + // testo + POLYLINELIST lstTxt; + if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt)) + lstPL.splice( lstPL.end(), lstTxt) ; + return true ; + } + case DT_RADIAL : + case DT_DIAMETRAL : { + // prima linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP1) ; + lstPL.back().AddUPoint( 1, m_ptP2) ; + // freccia + lstPL.emplace_back() ; + Vector3d vtRad = m_ptPos - m_ptP6 ; + vtRad.Normalize() ; + GetArrowHead( m_ptP2, ( m_bCalcArrowIn ? vtRad : - vtRad), lstPL.back()) ; + if ( ! m_bCalcArrowIn) { lstPL.emplace_back() ; + Point3d ptArrowTail = m_ptP2 + vtRad * m_dArrowLen * 2 ; lstPL.back().AddUPoint( 0, m_ptP2) ; - lstPL.back().AddUPoint( 1, m_ptP4) ; - // curva per l'arco - PtrOwner pCrvPos( CreateBasicCurveArc()) ; - if ( IsNull( pCrvPos)) - return false ; - //double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; - - // se non ho testo - if ( IsEmptyOrSpaces( m_sCalcText)) { - if ( ! pCrvPos->SetC2PN( m_ptP5, m_ptP6, m_ptP5, m_vtN) || ! pCrvPos->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) - return false ; - lstPL.emplace_back( plApprox) ; - } - // altrimenti, linea di misura divisa in due parti - else { - // prima parte - if ( ! pCrvPos->SetC2PN( m_ptP5, m_ptP5, m_ptCalcP7, m_vtN) || ! pCrvPos->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) - return false ; - lstPL.emplace_back( plApprox) ; - // seconda parte - if ( ! pCrvPos->SetC2PN( m_ptP5, m_ptP6, m_ptCalcP8, m_vtN) || ! pCrvPos->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) - return false ; - lstPL.emplace_back( plApprox) ; - } - // frecce - Vector3d vtStartDir ; - Vector3d vtEndDir ; - if ( ! pCrvPos->Set3P( m_ptP6, m_ptPos, m_ptP5, false)) - return false ; - pCrvPos->GetStartDir( vtStartDir) ; - pCrvPos->GetEndDir( vtEndDir) ; - //storto la punta delle frecce su una direzione mediata tra l'arco e la perpendicolare al lato - double dFactor = 1 / ( 0.6 * m_vtDir.Len()) ; // questo fattore dipende direttamente dalla distanza di m_ptPos dal centro e smorza lo scostamento - Vector3d vtLine1 = m_ptP1 - m_ptP5 ; - Vector3d vtLine2 = m_ptP2 - m_ptP5 ; - vtLine1.Normalize() ; - vtLine2.Normalize() ; - // se però le frecce sono fuori non le storto e faccio le code dritte anziché curvilinee + lstPL.back().AddUPoint( 1, ptArrowTail) ; + } + if ( m_nType == DT_DIAMETRAL) { + lstPL.emplace_back() ; + GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? - vtRad : vtRad), lstPL.back()) ; if ( ! m_bCalcArrowIn) { - Point3d ptArrowTail1, ptArrowTail2 ; - ptArrowTail1 = m_ptP5 + vtEndDir * m_dArrowLen *2 ; lstPL.emplace_back() ; + Point3d ptArrowTail = m_ptP5 - vtRad * m_dArrowLen * 2 ; lstPL.back().AddUPoint( 0, m_ptP5) ; - lstPL.back().AddUPoint( 1, ptArrowTail1) ; - ptArrowTail2 = m_ptP6 - vtStartDir * m_dArrowLen *2 ; - lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP6) ; - lstPL.back().AddUPoint( 1, ptArrowTail2) ; - dFactor = 0 ; + lstPL.back().AddUPoint( 1, ptArrowTail) ; } - lstPL.emplace_back() ; - GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? vtEndDir : - vtEndDir) + vtLine1 * dFactor, lstPL.back()) ; - lstPL.emplace_back() ; - GetArrowHead( m_ptP6, ( m_bCalcArrowIn ? - vtStartDir : vtStartDir) + vtLine2 * dFactor, lstPL.back()) ; - // testo - POLYLINELIST lstTxt ; - if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt)) - lstPL.splice( lstPL.end(), lstTxt) ; - return true ; } - default: + // testo + POLYLINELIST lstTxt; + if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt)) + lstPL.splice( lstPL.end(), lstTxt) ; + return true ; + } + case DT_ANGULAR : { + // prima linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP1) ; + lstPL.back().AddUPoint( 1, m_ptP3) ; + // seconda linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP2) ; + lstPL.back().AddUPoint( 1, m_ptP4) ; + // curva per l'arco + PtrOwner pCrvPos( CreateBasicCurveArc()) ; + if ( IsNull( pCrvPos)) return false ; + // calcolo ptP5_bis + Vector3d vtLine2 = m_ptP2 - m_ptP6 ; + double dLen2 = vtLine2.Len() ; + if ( ! vtLine2.Normalize()) + return false ; + Point3d ptP5_bis = m_ptP2 + ( m_vtDir.Len() - dLen2) * vtLine2 ; + // approssimerò l'arco con una polyline + PolyLine plApprox ; + double dLinTol = 0.01 ; + double dAngTolDeg = 0.01 ; + // se non ho testo + if ( IsEmptyOrSpaces( m_sCalcText) || ! m_bCalcTextOn) { + if ( ! pCrvPos->SetC2PN( m_ptP6, ptP5_bis, m_ptP5, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) + return false ; + lstPL.emplace_back( plApprox) ; } + // altrimenti, linea di misura divisa in due parti + else { + // prima parte + if ( ! pCrvPos->SetC2PN( m_ptP6, m_ptP5, m_ptCalcP7, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) + return false ; + lstPL.emplace_back( plApprox) ; + // seconda parte + if ( ! pCrvPos->SetC2PN( m_ptP6, ptP5_bis, m_ptCalcP8, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) + return false ; + lstPL.emplace_back( plApprox) ; + } + // frecce + if ( ! pCrvPos->Set3P( ptP5_bis, m_ptPos, m_ptP5, false)) + return false ; + Vector3d vtStartDir ; + Vector3d vtEndDir ; + pCrvPos->GetStartDir( vtStartDir) ; + pCrvPos->GetEndDir( vtEndDir) ; + //storto la punta delle frecce su una direzione mediata tra l'arco e la perpendicolare al lato + double dFactor = 1 / ( 0.6 * m_vtDir.Len()) ;// questo fattore dipende direttamente dalla distanza di m_ptPos dal centro e smorza lo scostamento + // se però le frecce sono fuori non le storto e faccio le code dritte anziché curvilinee + if ( ! m_bCalcArrowIn) { + Point3d ptArrowTail1, ptArrowTail2 ; + ptArrowTail1 = m_ptP5 + vtEndDir * m_dArrowLen *2 ; + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP5) ; + lstPL.back().AddUPoint( 1, ptArrowTail1) ; + ptArrowTail2 = ptP5_bis - vtStartDir * m_dArrowLen *2 ; + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, ptP5_bis) ; + lstPL.back().AddUPoint( 1, ptArrowTail2) ; + dFactor = 0 ; + } + lstPL.emplace_back() ; + Vector3d vtLine1 = m_ptP1 - m_ptP6 ; + if ( ! vtLine1.Normalize()) + return false ; + GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? vtEndDir : - vtEndDir) + vtLine1 * dFactor, lstPL.back()) ; + lstPL.emplace_back() ; + GetArrowHead( ptP5_bis, ( m_bCalcArrowIn ? - vtStartDir : vtStartDir) + vtLine2 * dFactor, lstPL.back()) ; + // testo + POLYLINELIST lstTxt ; + if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt)) + lstPL.splice( lstPL.end(), lstTxt) ; + return true ; + } + default: + return false ; + } } //---------------------------------------------------------------------------- @@ -1420,12 +1429,11 @@ ExtDimension::ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELI Frame3d frRef ; if ( ! frRef.Set( m_ptCalcPos, m_vtN)) return false ; - + // oriento il testo con il raggio/diametro, ma solo se il testo è dentro la circonferenza if ( ( m_nType == DT_RADIAL || m_nType == DT_DIAMETRAL) && m_bCalcTextOn) { double dAngDeg = 0 ; - Vector3d vtRad = m_ptPos - m_ptP5 ; - m_vtDir.GetAngle( vtRad, dAngDeg) ; - if ( ! frRef.Set( m_ptCalcPos, m_vtN, ( dAngDeg > 90 ? - vtRad : vtRad))) + m_vtDir.GetAngle( frRef.VersX(), dAngDeg) ; + if ( ! frRef.Set( m_ptCalcPos, m_vtN, ( dAngDeg > 90 ? - m_vtDir : m_vtDir))) return false ; } diff --git a/ExtDimension.h b/ExtDimension.h index f896fcc..4e6e043 100644 --- a/ExtDimension.h +++ b/ExtDimension.h @@ -71,7 +71,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW const Vector3d& vtN, const std::string& sText) override ; bool SetDiametral( const Point3d& ptCen, const Point3d& ptPos, const Vector3d& vtN, const std::string& sText) override ; - bool SetAngular( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptV, const Point3d& ptPos, + bool SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d& ptP2, const Point3d& ptPos, const Vector3d& vtN, const std::string& sText) override ; const Vector3d& GetNormVersor( void) const override { return m_vtN ; } @@ -145,7 +145,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW Point3d m_ptP3 ; // terzo punto Point3d m_ptP4 ; // quarto punto Point3d m_ptP5 ; // quinto punto - Point3d m_ptP6 ; // sesto punto + Point3d m_ptP6 ; // sesto punto; nel caso delle quotature angolari � il centro Point3d m_ptPos ; // posizione ricevuta della quota std::string m_sText ; // testo della quota mutable bool m_bToCalc ; // flag dati effettivi da ricalcolare @@ -162,7 +162,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW int m_nDecDigit ; // numero di cifre decimali std::string m_sFont ; // font del testo double m_dTextHeight ; // altezza del testo - int m_nTempProp[2] ; // vettore proprietà temporanee + int m_nTempProp[2] ; // vettore propriet� temporanee double m_dTempParam[2] ; // vettore parametri temporanei } ; diff --git a/FontOs.cpp b/FontOs.cpp index 1006509..08ae540 100644 --- a/FontOs.cpp +++ b/FontOs.cpp @@ -298,8 +298,7 @@ OsFont::GetOutline( const string& sText, int nInsPos, ICURVEPLIST& lstPC) const if ( ! GetCharOutline( vCode[i], dAdvance, lstTmpPC)) return false ; // lo trasformo opportunamente - ICURVEPLIST::iterator iIter ; - for ( iIter = lstTmpPC.begin() ; iIter != lstTmpPC.end() ; ++ iIter) { + for ( auto iIter = lstTmpPC.begin() ; iIter != lstTmpPC.end() ; ++ iIter) { // trasformazioni (*iIter)->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ; (*iIter)->Translate( vtMove) ; @@ -464,8 +463,7 @@ OsFont::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, doubl if ( ! GetCharOutline( vCode[i], dAdvance, lstPC)) return false ; // lo approssimo con segmenti di retta - ICURVEPLIST::iterator iIter ; - for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) { + for ( auto iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) { // trasformazioni (*iIter)->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ; (*iIter)->Translate( vtMove) ; @@ -478,7 +476,7 @@ OsFont::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, doubl if ( vtMove.x > dMaxW) dMaxW = vtMove.x ; // ciclo di pulizia - for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) + for ( auto iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) delete (*iIter) ; lstPC.clear() ; } @@ -549,8 +547,7 @@ OsFont::ApproxWithArcs( const string& sText, int nInsPos, double dLinTol, double if ( ! GetCharOutline( vCode[i], dAdvance, lstPC)) return false ; // lo approssimo con segmenti di arco e retta - ICURVEPLIST::iterator iIter ; - for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) { + for ( auto iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) { // trasformazioni (*iIter)->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ; (*iIter)->Translate( vtMove) ; @@ -563,7 +560,7 @@ OsFont::ApproxWithArcs( const string& sText, int nInsPos, double dLinTol, double if ( vtMove.x > dMaxW) dMaxW = vtMove.x ; // ciclo di pulizia - for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) + for ( auto iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) delete (*iIter) ; lstPC.clear() ; } diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index e73c658..43fadf4 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -1423,8 +1423,7 @@ GdbExecutor::CurveArcChangeRadius( const STRVECTOR& vsParams) if ( ! GetLengthParam( vsParams[1], dNewRad)) return false ; // esecuzione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero l'arco ICurveArc* pCrvArc = GetCurveArc( m_pGDB->GetGeoObj( *Iter)) ; if ( pCrvArc == nullptr) @@ -1452,8 +1451,7 @@ GdbExecutor::CurveArcChangeDeltaN( const STRVECTOR& vsParams) if ( ! GetLengthParam( vsParams[1], dNewDeltaN)) return false ; // esecuzione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero l'arco ICurveArc* pCrvArc = GetCurveArc( m_pGDB->GetGeoObj( *Iter)) ; if ( pCrvArc == nullptr) @@ -1686,8 +1684,7 @@ GdbExecutor::CurveCompoMake( const STRVECTOR& vsParams) if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest)) return false ; // esecuzione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero la curva int nIdCrv = *Iter ; const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ; @@ -1722,7 +1719,7 @@ GdbExecutor::CurveCompoMake( const STRVECTOR& vsParams) if ( AddGeoObj( vsParams[0], vsParams[1], Release( pCrvCompo))) { // se richiesto, cancello le curve originali if ( bErase) { - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->Erase( *Iter)) return false ; } @@ -2309,8 +2306,7 @@ GdbExecutor::SurfTriMeshByTriangleSoup( const STRVECTOR& vsParams) if ( ! StmFts.Start()) return false ; // Recupero tutti i triangoli delle superfici sorgenti e li inserisco nella nuova - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero la superficie sorgente const ISurfTriMesh* pStmS = GetSurfTriMesh( m_pGDB->GetGeoObj( *Iter)) ; if ( pStmS == nullptr) @@ -2340,7 +2336,7 @@ GdbExecutor::SurfTriMeshByTriangleSoup( const STRVECTOR& vsParams) if ( AddGeoObj( vsParams[0], vsParams[1], pSTM)) { // se richiesto, cancello le curve originali if ( bErase) { - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->Erase( *Iter)) return false ; } @@ -2534,8 +2530,7 @@ GdbExecutor::SurfTriMeshDoCompacting( const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // opero sui diversi oggetti - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero la superficie ISurfTriMesh* pStm = GetSurfTriMesh( m_pGDB->GetGeoObj( *Iter)) ; if ( pStm == nullptr) @@ -2572,8 +2567,7 @@ GdbExecutor::SurfTriMeshDoSewing( const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[1], vnNames)) return false ; // esecuzione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero la superficie da cucire const ISurfTriMesh* pStmS = GetSurfTriMesh( m_pGDB->GetGeoObj( *Iter)) ; if ( pStmS == nullptr) @@ -2590,7 +2584,7 @@ GdbExecutor::SurfTriMeshDoSewing( const STRVECTOR& vsParams) } // se richiesto, cancello le superfici cucite alla prima if ( bErase) { - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) m_pGDB->Erase( *Iter) ; } return true ; @@ -5432,8 +5426,7 @@ GdbExecutor::TextOutline( const STRVECTOR& vsParams) pTXT->GetOutline( lstPCRV) ; // inserisco le curve nel gruppo destinazione dopo aver sistemato il cambio di riferimento bool bOk = true ; - ICURVEPLIST::iterator iIter ; - for ( iIter = lstPCRV.begin() ; iIter != lstPCRV.end() ; ++ iIter) { + for ( auto iIter = lstPCRV.begin() ; iIter != lstPCRV.end() ; ++ iIter) { (*iIter)->LocToLoc( frTXT, frDest) ; if ( m_pGDB->AddGeoObj( GDB_ID_NULL, nIdDest, (*iIter)) == GDB_ID_NULL) { delete (*iIter) ; @@ -5510,8 +5503,7 @@ GdbExecutor::GetNamesParam( const string& sParam, INTVECTOR& vnNames) // converto in interi vnNames.clear() ; vnNames.reserve( vsNames.size()) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsNames.begin() ; Iter != vsNames.end() ; ++Iter) { + for ( auto Iter = vsNames.begin() ; Iter != vsNames.end() ; ++Iter) { Trim( (*Iter), " \t\r\n()") ; int nId = GetIdParam( *Iter) ; if ( nId != GDB_ID_SEL) { @@ -5538,8 +5530,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector // divido in parti STRVECTOR vsParams ; Tokenize( sParam, ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // se 2 parti, allora Z = 0 if ( vsParams.size() == 2) { @@ -5594,8 +5585,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 3, sParam.length()-4), ",", "(", ")", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n") ; // ci deve essere almeno un parametro if ( vsParams.size() < 1) @@ -5747,8 +5737,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d& // divido in parti STRVECTOR vsParams ; Tokenize( sParam, ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // se 2 parti, allora Z = 0 if ( vsParams.size() == 2) { @@ -5778,8 +5767,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d& // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 3, sParam.length()-4), ",", "(", ")", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n") ; // ci deve essere almeno un parametro if ( vsParams.size() < 1) @@ -5962,8 +5950,7 @@ GdbExecutor::GetPointsParam( const string& sParam, const Frame3d& frPnt, PolyLin Tokenize( sParam.substr( 1, sParam.length()-2), ",", "(", ")", vsPoints) ; // converto in punti PL.Clear() ; - STRVECTOR::iterator Iter ; - for ( Iter = vsPoints.begin() ; Iter != vsPoints.end() ; ++Iter) { + for ( auto Iter = vsPoints.begin() ; Iter != vsPoints.end() ; ++Iter) { Trim( (*Iter), " \t\r\n") ; if ( GetIdParam( *Iter) == GDB_ID_SEL) { int nId = m_pGDB->GetFirstSelectedObj() ; @@ -5997,8 +5984,7 @@ GdbExecutor::GetPointWParam( const string& sParam, const Frame3d& frPnt, Point3d // divido in parti STRVECTOR vsParams ; Tokenize( sParam.substr( 1, sParam.length()-2), ",", "(", ")", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n") ; // se 4 parti, sono 3 coordinate e un peso @@ -6037,8 +6023,7 @@ GdbExecutor::GetPointWsParam( const string& sParam, const Frame3d& frPnt, PolyAr Tokenize( sParam.substr( 1, sParam.length()-2), ",", "(", ")", vsPointWs) ; // converto in punti PA.Clear() ; - STRVECTOR::iterator Iter ; - for ( Iter = vsPointWs.begin() ; Iter != vsPointWs.end() ; ++Iter) { + for ( auto Iter = vsPointWs.begin() ; Iter != vsPointWs.end() ; ++Iter) { Trim( (*Iter), " \t\r\n") ; Point3d ptP ; double dBulge ; @@ -6059,8 +6044,7 @@ GdbExecutor::GetLengthParam( const string& sParam, double& dLen) // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 1), ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // ci deve essere almeno un parametro if ( vsParams.size() < 1) @@ -6082,8 +6066,7 @@ GdbExecutor::GetLengthParam( const string& sParam, double& dLen) // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 1), ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // ci deve essere almeno un parametro if ( vsParams.size() < 1) @@ -6118,8 +6101,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 3, sParam.length()-4), ",", "(", ")", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n") ; // ci deve essere almeno un parametro if ( vsParams.size() < 1) @@ -6263,8 +6245,7 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d& // divido in parti ed elimino spazi iniziali/finali STRVECTOR vsParams ; Tokenize( sTmp, ",", "(", ")", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n") ; // verifico siano 4 parti e le converto if ( vsParams.size() != 4) @@ -6291,8 +6272,7 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d& // divido in parti ed elimino spazi iniziali/finali STRVECTOR vsParams ; Tokenize( sTmp, ",", "(", ")", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n") ; // se c'è un parametro è l'origine Point3d ptOrig ; @@ -6358,8 +6338,7 @@ GdbExecutor::GetColorParam( const string& sParam, bool& bByParent, Color& cCol) // divido in parti STRVECTOR vsParams ; Tokenize( sParam, ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // devono essere 3 o 4 parametri ( Red, Green, Blue [, Alpha]) if ( vsParams.size() != 3 && vsParams.size() != 4) @@ -6387,8 +6366,7 @@ GdbExecutor::GetColorParam( const string& sParam, bool& bByParent, Color& cCol) // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 1), ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // ci deve essere un parametro if ( vsParams.size() != 1) @@ -6421,8 +6399,7 @@ GdbExecutor::GetMaterialParam( const string& sParam, bool& bByParent, int& nMat) // recupero i parametri associati STRVECTOR vsParams ; Tokenize( sParam.substr( 1), ",", vsParams) ; - STRVECTOR::iterator Iter ; - for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + for ( auto Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) Trim( (*Iter), " \t\r\n()") ; // ci deve essere un parametro if ( vsParams.size() != 1) @@ -6479,8 +6456,7 @@ GdbExecutor::ExecuteLevel( const string& sCmd2, const STRVECTOR& vsParams) else return false ; // esecuzione impostazione livello - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SetLevel( *Iter, nLevel)) return false ; } @@ -6511,8 +6487,7 @@ GdbExecutor::ExecuteMode( const string& sCmd2, const STRVECTOR& vsParams) else return false ; // esecuzione impostazione modo - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SetMode( *Iter, nMode)) return false ; } @@ -6543,8 +6518,7 @@ GdbExecutor::ExecuteStatus( const string& sCmd2, const STRVECTOR& vsParams) else return false ; // esecuzione impostazione stato - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SetStatus( *Iter, nStat)) return false ; } @@ -6565,8 +6539,7 @@ GdbExecutor::ExecuteSelect( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione selezione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SelectObj( *Iter)) return false ; } @@ -6610,8 +6583,7 @@ GdbExecutor::ExecuteSelect( const string& sCmd2, const STRVECTOR& vsParams) nFilter = EXT_TEXT ; } // esecuzione selezione di tutti gli oggetti di ogni gruppo - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SelectGroupObjs( *Iter, nFilter)) return false ; } @@ -6635,8 +6607,7 @@ GdbExecutor::ExecuteDeselect( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione deselezione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->DeselectObj( *Iter)) return false ; } @@ -6652,8 +6623,7 @@ GdbExecutor::ExecuteDeselect( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione deselezione di tutti gli oggetti di ogni gruppo - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->DeselectGroupObjs( *Iter)) return false ; } @@ -6710,8 +6680,7 @@ GdbExecutor::MaterialColor( const STRVECTOR& vsParams) if ( ! GetColorParam( vsParams[1], bByParent, cCol)) return false ; // esecuzione impostazione colore - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( bByParent) { if ( ! m_pGDB->SetMaterial( *Iter, GDB_MT_PARENT)) return false ; @@ -6741,8 +6710,7 @@ GdbExecutor::MaterialMaterial( const STRVECTOR& vsParams) if ( ! GetMaterialParam( vsParams[1], bByParent, nMat)) return false ; // esecuzione impostazione colore - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( bByParent) { if ( ! m_pGDB->SetMaterial( *Iter, GDB_MT_PARENT)) return false ; @@ -6789,8 +6757,7 @@ GdbExecutor::ExecuteName( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetStringParam( vsParams[1], sName)) return false ; // eseguo assegnazione nome - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SetName( *Iter, sName)) return false ; } @@ -6806,8 +6773,7 @@ GdbExecutor::ExecuteName( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // eseguo rimozione nome - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->RemoveName( *Iter)) return false ; } @@ -6839,8 +6805,7 @@ GdbExecutor::ExecuteInfo( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetStringParam( vsParams[2], sInfo)) return false ; // eseguo assegnazione Info di data Key - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->SetInfo( *Iter, sKey, sInfo)) return false ; } @@ -6860,8 +6825,7 @@ GdbExecutor::ExecuteInfo( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetStringParam( vsParams[1], sKey)) return false ; // eseguo rimozione nome Info di data Key - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->RemoveInfo( *Iter, sKey)) return false ; } @@ -7010,8 +6974,7 @@ GdbExecutor::ExecuteRelocate( const string& sCmd2, const STRVECTOR& vsParams) // recupero flag per globale bool bGlob = ( sCmd2 == "GLOB" || sCmd2 == "G") ; // esecuzione rilocazioni - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( bGlob) { if ( ! m_pGDB->RelocateGlob( *Iter, GetIdParam( vsParams[1]), nSonBeforeAfter)) return false ; @@ -7036,8 +6999,7 @@ GdbExecutor::ExecuteErase( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione cancellazioni - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { if ( ! m_pGDB->Erase( *Iter)) return false ; } @@ -7079,8 +7041,7 @@ GdbExecutor::ExecuteTranslate( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetVectorParam( vsParams[1], frRef, vtVN)) return false ; // esecuzione traslazioni - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { switch ( nTraType) { case TRA_LOC : if ( ! m_pGDB->Translate( *Iter, vtVN)) @@ -7144,8 +7105,7 @@ GdbExecutor::ExecuteRotate( const string& sCmd2, const STRVECTOR& vsParams) if ( ! FromString( vsParams[3], dAngDeg)) return false ; // esecuzione rotazioni - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { switch ( nRotType) { case ROT_LOC : if ( ! m_pGDB->Rotate( *Iter, ptPC, vtVN, dAngDeg)) @@ -7214,8 +7174,7 @@ GdbExecutor::ExecuteScale( const string& sCmd2, const STRVECTOR& vsParams) ! FromString( vsParams[4], dCoeffZ)) return false ; // esecuzione scalature - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { switch ( nScaType) { case SCA_LOC : if ( ! m_pGDB->Scale( *Iter, frFrame, dCoeffX, dCoeffY, dCoeffZ)) @@ -7273,8 +7232,7 @@ GdbExecutor::ExecuteMirror( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetVectorParam( vsParams[2], frRef, vtVN)) return false ; // esecuzione specchiature - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { switch ( nMirType) { case MIR_LOC : if ( ! m_pGDB->Mirror( *Iter, ptPC, vtVN)) @@ -7340,8 +7298,7 @@ GdbExecutor::ExecuteShear( const string& sCmd2, const STRVECTOR& vsParams) if ( ! FromString( vsParams[4], dCoeff)) return false ; // esecuzione scorrimenti - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { switch ( nMirType) { case MIR_LOC : if ( ! m_pGDB->Shear( *Iter, ptPC, vtNorm, vtDir, dCoeff)) @@ -7400,8 +7357,7 @@ GdbExecutor::CurveModifyInvert( const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione inversione curve - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { ICurve* pCurve = GetCurve( m_pGDB->GetGeoObj( *Iter)) ; if ( pCurve == nullptr || ! pCurve->Invert()) return false ; @@ -7518,8 +7474,7 @@ GdbExecutor::CurveModifyTrim( const STRVECTOR& vsParams, int nTrimType) if ( ! FromString( vsParams[1], dPar)) return false ; // esecuzione trim - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { ICurve* pCurve ; if ( ( pCurve = GetCurve( m_pGDB->GetGeoObj( *Iter))) != nullptr) { switch ( nTrimType) { @@ -7718,8 +7673,7 @@ GdbExecutor::CurveCopyByChain( const STRVECTOR& vsParams) // preparo i dati per il concatenamento ChainCurves chainC ; chainC.Init( bAllowInvert, dToler, int( vnNames.size())) ; - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero la curva e il suo riferimento ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( *Iter)) ; if ( pCrv == nullptr) @@ -7748,10 +7702,9 @@ GdbExecutor::CurveCopyByChain( const STRVECTOR& vsParams) if ( IsNull( pCrvCompo)) return false ; // recupero le curve semplici e le inserisco nella curva composita - INTVECTOR::iterator Iter2 ; - for ( Iter2 = vIds.begin() ; Iter2 != vIds.end() ; ++Iter2) { - int nId = abs( *Iter2) ; - bool bInvert = ( *Iter2 < 0) ; + for ( auto Iter = vIds.cbegin() ; Iter != vIds.cend() ; ++Iter) { + int nId = abs( *Iter) ; + bool bInvert = ( *Iter < 0) ; // recupero la curva e il suo riferimento ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nId)) ; if ( pCrv == nullptr) @@ -7806,8 +7759,7 @@ GdbExecutor::SurfModifyInvert( const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione inversione normale superficie - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { ISurf* pSurf = GetSurf( m_pGDB->GetGeoObj( *Iter)) ; if ( pSurf == nullptr || ! pSurf->Invert()) return false ; @@ -8049,8 +8001,7 @@ GdbExecutor::ExecuteOutTsc( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero l'oggetto ed eseguo l'output if ( ! OutGroupTsc( *Iter, nFlag)) return false ; @@ -8073,8 +8024,7 @@ GdbExecutor::ExecuteOutTsc( const string& sCmd2, const STRVECTOR& vsParams) if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; // esecuzione - INTVECTOR::iterator Iter ; - for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { + for ( auto Iter = vnNames.cbegin() ; Iter != vnNames.cend() ; ++Iter) { // recupero l'oggetto ed eseguo l'output if ( ! m_OutTsc.PutGeoObj( m_pGDB->GetGeoObj( *Iter), nFlag)) return false ; diff --git a/GdbGroup.cpp b/GdbGroup.cpp index df1a7fd..173490f 100644 --- a/GdbGroup.cpp +++ b/GdbGroup.cpp @@ -44,7 +44,7 @@ GdbGroup::~GdbGroup( void) // nel sorgente aggiorno lista dei riferimenti INTVECTOR vnList ; pGdbObj->GetInfo( GDB_SI_LIST, vnList) ; - INTVECTOR::const_iterator iFind = find( vnList.begin(), vnList.end(), m_nId) ; + const auto iFind = find( vnList.begin(), vnList.end(), m_nId) ; if ( iFind != vnList.end()) vnList.erase( iFind) ; if ( vnList.empty()) diff --git a/GdbIterator.cpp b/GdbIterator.cpp index f5f7d26..21dfb1a 100644 --- a/GdbIterator.cpp +++ b/GdbIterator.cpp @@ -1468,7 +1468,8 @@ GdbIterator::SetInfo( const string& sKey, int nInfo) bool GdbIterator::SetInfo( const string& sKey, double dInfo) { - return SetInfo( sKey, ToString( dInfo)) ; + int nErr ; + return ( SetInfo( sKey, ToString( dInfo, 6, &nErr)) && nErr == 0) ; } //---------------------------------------------------------------------------- diff --git a/GdbObj.cpp b/GdbObj.cpp index 0bdda80..bf8f258 100644 --- a/GdbObj.cpp +++ b/GdbObj.cpp @@ -862,7 +862,8 @@ GdbObj::SetInfo( const string& sKey, int nInfo) bool GdbObj::SetInfo( const string& sKey, double dInfo) { - return SetInfo( sKey, ToString( dInfo)) ; + int nErr ; + return ( SetInfo( sKey, ToString( dInfo, 6, &nErr)) && nErr == 0) ; } //---------------------------------------------------------------------------- diff --git a/GeomDB.cpp b/GeomDB.cpp index 80a13bc..e8a6374 100644 --- a/GeomDB.cpp +++ b/GeomDB.cpp @@ -2785,7 +2785,8 @@ GeomDB::SetInfo( int nId, const string& sKey, int nInfo) bool GeomDB::SetInfo( int nId, const string& sKey, double dInfo) { - return SetInfo( nId, sKey, ToString( dInfo)) ; + int nErr ; + return ( SetInfo( nId, sKey, ToString( dInfo, 6, &nErr)) && nErr == 0) ; } //---------------------------------------------------------------------------- diff --git a/IterManager.h b/IterManager.h index 2b86401..18bd1c7 100644 --- a/IterManager.h +++ b/IterManager.h @@ -26,8 +26,7 @@ class IterManager { public : bool IsGdbIteratorInList( GdbIterator* pIter) - { PGDBI_LIST::const_iterator Iter ; - for ( Iter = m_IterList.begin() ; Iter != m_IterList.end() ; ++ Iter) { + { for ( auto Iter = m_IterList.cbegin() ; Iter != m_IterList.cend() ; ++ Iter) { if ( *Iter == pIter) return true ; } @@ -41,8 +40,7 @@ class IterManager catch (...) { return false ;} return true ; } bool RemoveGdbIterator( GdbIterator* pIter) - { PGDBI_LIST::iterator Iter ; - for ( Iter = m_IterList.begin() ; Iter != m_IterList.end() ; ++ Iter) { + { for ( auto Iter = m_IterList.cbegin() ; Iter != m_IterList.cend() ; ++ Iter) { if ( *Iter == pIter) { m_IterList.erase( Iter) ; return true ; diff --git a/OffsetAux.cpp b/OffsetAux.cpp index b84bfd8..ad683bb 100644 --- a/OffsetAux.cpp +++ b/OffsetAux.cpp @@ -30,7 +30,9 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist) if ( IsNull( pCrv)) return false ; if ( IsFillet( pCrv, dDist)) - pCrvCo->SetCurveTempParam( i, 1.0) ; + pCrvCo->SetCurveTempParam( i, 1.0) ; + else + pCrvCo->SetCurveTempParam( i, 0.0) ; } return true ; } diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp index f12841a..859e066 100644 --- a/OffsetCurve.cpp +++ b/OffsetCurve.cpp @@ -21,6 +21,7 @@ #include "CurveComposite.h" #include "RemoveCurveDefects.h" #include "OffsetAux.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkDistPointCurve.h" @@ -66,11 +67,7 @@ OffsetCurve::Reset( void) bool OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) { - // imposto metodo di calcolo - bool bUseVoronoi = false ; - #ifdef _VRONI - bUseVoronoi = true ; - #endif // _VRONI + // metodo di calcolo impostato da USE_VORONOI // pulisco tutto Reset() ; @@ -85,7 +82,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) else { const CurveComposite* pCompo = GetBasicCurveComposite( pCrv) ; Point3d ptStart, ptEnd ; - if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd)) + if ( pCompo != nullptr && pCompo->IsALine( m_dLinTol, ptStart, ptEnd)) bIsLine = true ; } // verifico che la curva sia piana (per le linee è comunque sempre vero) @@ -126,8 +123,8 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) return true ; } - // determino se necessario cambiare riferimento ( dal vettore estrusione) - bool bNeedRef = ( ! vtExtr.IsZplus()) ; + // determino se necessario cambiare riferimento ( dal vettore estrusione) e mai con Voronoi + bool bNeedRef = ( ! vtExtr.IsZplus() && ! USE_VORONOI) ; // determino se necessario effettuare scalatura bool bNeedScale = ( abs( dExtrOnN) < cos( 0.1 * DEGTORAD)) ; @@ -168,18 +165,18 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) bool bChangeStart = true ; // -------------------- OFFSET STANDARD --------------------------------- - if ( ! bUseVoronoi) { + if ( ! USE_VORONOI) { // verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+) - if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG)) + if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, ANG_TOL_STD_DEG)) return false ; // elimino eventuali piccole Z - if ( ! RemoveCurveSmallZs( &ccCopy, 10 * EPS_SMALL)) + if ( ! RemoveCurveSmallZs( &ccCopy, m_dLinTol)) return false ; // elimino tratti molto corti - if ( ! RemoveCurveSmallParts( &ccCopy, 10 * EPS_SMALL)) + if ( ! RemoveCurveSmallParts( &ccCopy, m_dLinTol)) return false ; // converto archi diritti in segmenti di retta @@ -187,7 +184,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) if ( ! ccCopy.StraightArcsToLines( 2 * EPS_SMALL, ANG_CEN_MAX)) return false ; // unisco parti allineate - if ( ! ccCopy.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG, bClosed)) + if ( ! ccCopy.MergeCurves( m_dLinTol, ANG_TOL_STD_DEG, bClosed, true)) return false ; // verifico se il punto iniziale è stato modificato @@ -437,7 +434,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) // se non rimasto nulla, esco double dLen ; - if ( ! pCrvCompo->IsValid() || ! pCrvCompo->GetLength( dLen) || dLen < 10 * EPS_SMALL) + if ( ! pCrvCompo->IsValid() || ! pCrvCompo->GetLength( dLen) || dLen < m_dLinTol) return true ; // inserisco la curva nella lista m_CrvLst.push_back( Release( pCrvCompo)) ; @@ -656,14 +653,14 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) pCrvCo2->GetStartPoint( ptStart2) ; pCrvCo2->GetEndPoint( ptEnd2) ; // verifiche di concatenamento - if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) { - if ( pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL)) + if ( AreSamePointEpsilon( ptEnd, ptStart2, m_dLinTol)) { + if ( pCrvCo->AddCurve( pCrvCo2, true, m_dLinTol)) ptEnd = ptEnd2 ; m_CrvLst.erase( iIter2) ; iIter2 = next( iIter) ; } - else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) { - if ( pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL)) + else if ( AreSamePointEpsilon( ptEnd2, ptStart, m_dLinTol)) { + if ( pCrvCo->AddCurve( pCrvCo2, false, m_dLinTol)) ptStart = ptStart2 ; m_CrvLst.erase( iIter2) ; iIter2 = next( iIter) ; @@ -692,7 +689,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) if ( bNeedRef || bNeedScale) voronoiObj = ccCopy.GetVoronoiObject() ; else - voronoiObj = pCrv->GetVoronoiObject() ; + voronoiObj = GetCurveVoronoi( *pCrv) ; if ( voronoiObj == nullptr) return false ; @@ -733,10 +730,13 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) pCrv->ToGlob( frCopy) ; } - // assegno estrusione e spessore come curva originale + // assegno estrusione e spessore come curva originale e unisco parti allineate for ( auto pCrv : m_CrvLst) { pCrv->SetExtrusion( vtExtr) ; pCrv->SetThickness( dThick) ; + // unisco eventuali parti allineate (tranne gli estremi) + if ( pCrv->GetType() == CRV_COMPO) + GetBasicCurveComposite( pCrv)->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG, false) ; } // ordino le curve in ordine decrescente di lunghezza diff --git a/PolyArc.cpp b/PolyArc.cpp index 7d0eeca..e2e549a 100644 --- a/PolyArc.cpp +++ b/PolyArc.cpp @@ -147,8 +147,7 @@ PolyArc::EraseLastUPoint( void) bool PolyArc::AddOffsetToU( double dOffset) { - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->dU += dOffset ; return true ; @@ -173,8 +172,7 @@ PolyArc::ParamLinearTransform( double dStartU, double dEndU) else return false ; // eseguo la riparametrizzazione - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->dU = dStartU + dCoeff * ( iter->dU - dOriStartU) ; return true ; } @@ -183,8 +181,7 @@ PolyArc::ParamLinearTransform( double dStartU, double dEndU) bool PolyArc::SetElevation( double dZ) { - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.z = dZ ; return true ; @@ -194,8 +191,7 @@ PolyArc::SetElevation( double dZ) bool PolyArc::AddElevation( double dZ) { - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.z += dZ ; return true ; @@ -206,8 +202,7 @@ bool PolyArc::Translate( const Vector3d& vtMove) { // il vettore estrusione non subisce modifiche - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.Translate( vtMove) ; return true ; @@ -218,8 +213,7 @@ bool PolyArc::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { m_vtExtr.Rotate( vtAx, dCosAng, dSinAng) ; - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; return true ; @@ -230,8 +224,7 @@ bool PolyArc::Scale( const Frame3d& frRef, double dCoeff) { m_vtExtr.Scale( frRef, dCoeff, dCoeff, dCoeff) ; - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.Scale( frRef, dCoeff, dCoeff, dCoeff) ; return true ; @@ -242,8 +235,7 @@ bool PolyArc::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) { m_vtExtr.Mirror( vtNorm) ; - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { iter->ptP.Mirror( ptOn, vtNorm) ; iter->dB *= - 1 ; } @@ -256,8 +248,7 @@ bool PolyArc::ToGlob( const Frame3d& frRef) { m_vtExtr.ToGlob( frRef) ; - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.ToGlob( frRef) ; return true ; @@ -268,8 +259,7 @@ bool PolyArc::ToLoc( const Frame3d& frRef) { m_vtExtr.ToLoc( frRef) ; - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.ToLoc( frRef) ; return true ; @@ -284,8 +274,7 @@ PolyArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) return true ; // ciclo sui punti m_vtExtr.LocToLoc( frOri, frDest) ; - UPNTBLIST::iterator iter ; - for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) iter->ptP.LocToLoc( frOri, frDest) ; return true ; @@ -319,8 +308,7 @@ PolyArc::Split( double dU, PolyArc& PA) // pulisco la polilinea destinazione PA.Clear() ; // ricerca del punto in cui dividere - UPNTBLIST::const_iterator iter ; - iter = m_lUPointBs.begin() ; + auto iter = m_lUPointBs.begin() ; while ( iter != m_lUPointBs.end() && iter->dU < ( dU + EPS_PARAM)) ++ iter ; if ( iter == m_lUPointBs.end()) @@ -585,7 +573,7 @@ PolyArc::Invert( bool bInvertU) // inverto la lista m_lUPointBs.reverse() ; // sposto il bulge all'estremo iniziale di ogni tratto (l'ultimo non conta) e lo inverto - for ( UPNTBLIST::iterator iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { if ( next( iter) != m_lUPointBs.end()) iter->dB = - next( iter)->dB ; else @@ -596,7 +584,7 @@ PolyArc::Invert( bool bInvertU) // recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione double dUfin = m_lUPointBs.front().dU ; // ciclo su tutti gli elementi - for ( UPNTBLIST::iterator iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { + for ( auto iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter) { iter->dU = dUfin - iter->dU ; } } diff --git a/PolyLine.cpp b/PolyLine.cpp index 85242fc..8a18072 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -139,8 +139,7 @@ PolyLine::EraseLastUPoint( void) bool PolyLine::AddOffsetToU( double dOffset) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->second += dOffset ; return true ; @@ -150,8 +149,7 @@ PolyLine::AddOffsetToU( double dOffset) bool PolyLine::Translate( const Vector3d& vtMove) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.Translate( vtMove) ; return true ; @@ -161,8 +159,7 @@ PolyLine::Translate( const Vector3d& vtMove) bool PolyLine::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; return true ; @@ -172,8 +169,7 @@ PolyLine::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, dou bool PolyLine::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; return true ; @@ -183,8 +179,7 @@ PolyLine::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dC bool PolyLine::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.Mirror( ptOn, vtNorm) ; return true ; @@ -194,8 +189,7 @@ PolyLine::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) bool PolyLine::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.Shear( ptOn, vtNorm, vtDir, dCoeff) ; return true ; @@ -205,8 +199,7 @@ PolyLine::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vt bool PolyLine::ToGlob( const Frame3d& frRef) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.ToGlob( frRef) ; return true ; @@ -216,8 +209,7 @@ PolyLine::ToGlob( const Frame3d& frRef) bool PolyLine::ToLoc( const Frame3d& frRef) { - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.ToLoc( frRef) ; return true ; @@ -231,8 +223,7 @@ PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) if ( AreSameFrame( frOri, frDest)) return true ; // ciclo sui punti - PNTULIST::iterator iter ; - for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) + for ( auto iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) iter->first.LocToLoc( frOri, frDest) ; return true ; @@ -654,6 +645,12 @@ PolyLine::GetAreaXY( double& dArea) const for ( bool bFound = GetFirstLine( ptIni, ptFin) ; bFound ; bFound = GetNextLine( ptIni, ptFin)) { dArea += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy } + // considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area + // significativa anche se sono coincidenti per le nostre tolleranze + ptIni = ptFin ; + GetFirstPoint( ptFin) ; + if ( ! AreSamePointExact( ptIni, ptFin)) + dArea += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; dArea = 0.5 * dArea ; return true ; } @@ -683,7 +680,7 @@ PolyLine::GetMaxDistanceFromLine( const Point3d& ptLine, const Vector3d& vtLine, bool PolyLine::AdjustForMaxSegmentLen( double dMaxLen) { - PNTULIST::iterator iter = m_lUPoints.begin() ; + auto iter = m_lUPoints.begin() ; // se non ci sono punti, esco subito if ( iter == m_lUPoints.end()) return false ; diff --git a/RemoveCurveDefects.cpp b/RemoveCurveDefects.cpp index f3b0a42..fcdd695 100644 --- a/RemoveCurveDefects.cpp +++ b/RemoveCurveDefects.cpp @@ -149,6 +149,7 @@ RemoveCurveSmallParts( ICurveComposite* pCurve, double dLinTol) int nCrvCount = pCurve->GetCurveCount() ; if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed())) return true ; + // se aperta, verifico le due curve agli estremi if ( ! pCurve->IsClosed()) { // curva iniziale @@ -170,6 +171,7 @@ RemoveCurveSmallParts( ICurveComposite* pCurve, double dLinTol) -- nCrvCount ; } } + // ciclo sulle curve elementari della composita int nStart = pCurve->IsClosed() ? 0 : 1 ; int nEnd = pCurve->IsClosed() ? nCrvCount : nCrvCount - 1 ; @@ -183,22 +185,23 @@ RemoveCurveSmallParts( ICurveComposite* pCurve, double dLinTol) Point3d ptMid ; pCurrCrv->GetMidPoint( ptMid) ; // rimuovo il segmento if ( pCurve->RemoveJoint( i)) { - -- nCrvCount ; - -- nEnd ; - -- i ; // porto il nuovo estremo sul punto medio - pCurve->ModifyJoint( i + 1, ptMid) ; + pCurve->ModifyJoint( i, ptMid) ; + // aggiorno valore di i tenendo conto che ModifyJoint potrebbe modificare la curva precedente + // che quindi va ricontrollata + i = max( i - 2, nStart - 1) ; + // aggiorno valore di nEnd ( ModifyJoint potrebbe aver rimosso la curva precedente e la successiva) + nEnd = pCurve->GetCurveCount() - ( pCurve->IsClosed() ? 0 : 1) ; } - // altrimenti devo rimuovere anche il successivo - else if ( pCurve->RemoveJoint( i + 1) && pCurve->RemoveJoint( i)) { - nCrvCount -= 2 ; - nEnd -= 2 ; - -- i ; - // porto il nuovo estremo sul punto medio - pCurve->ModifyJoint( i + 1, ptMid) ; + // altrimenti rimuovo anche il successivo + else if ( pCurve->RemoveJoint( i + 1)) { + pCurve->RemoveJoint( i) ; + pCurve->ModifyJoint( i, ptMid) ; + i = max( i - 2, nStart - 1) ; + nEnd = pCurve->GetCurveCount() - ( pCurve->IsClosed() ? 0 : 1) ; } } } return true ; -} +} \ No newline at end of file diff --git a/SfrCreate.cpp b/SfrCreate.cpp index 96f6671..e84ece2 100644 --- a/SfrCreate.cpp +++ b/SfrCreate.cpp @@ -19,6 +19,7 @@ #include "SurfFlatRegion.h" #include "AdjustLoops.h" #include "GeoConst.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkBiArcs.h" #include "/EgtDev/Include/EGkOffsetCurve.h" @@ -114,13 +115,9 @@ GetSurfFlatRegionDisk( double dRadius) //------------------------------------------------------------------------------- ISurfFlatRegion* -GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids) +GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids, double dOffsLinTol) { - // imposto metodo di calcolo - bool bUseVoronoi = false ; - #ifdef _VRONI - bUseVoronoi = true ; - #endif // _VRONI + // metodo di calcolo impostato da USE_VORONOI // mi impossesso della curva PtrOwner pCurve( pCrv) ; @@ -132,7 +129,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b vtExtr = Z_AX ; // ----------------- CALCOLO STANDARD -------------------------------- - if ( ! bUseVoronoi) { + if ( ! USE_VORONOI) { PtrOwner pCompo1 ; if ( ! pCompo1.Set( ConvertCurveToBasicComposite( Release( pCurve)))) return nullptr ; @@ -187,7 +184,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b // per creare la regione SurfFlatRegionByContours SfrCntr( false, false) ; // offset della prima curva a destra del raggio - OffsetCurve OffsCrv1 ; + OffsetCurve OffsCrv1( dOffsLinTol) ; if ( ! OffsCrv1.Make( pCompo1, dRadius, nOffsType)) return nullptr ; ICurve* pOffs1 = OffsCrv1.GetLongerCurve() ; @@ -197,7 +194,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b } // offset della seconda curva a destra del raggio (è invertita rispetto alla precedente) - OffsetCurve OffsCrv2 ; + OffsetCurve OffsCrv2( dOffsLinTol) ; if ( ! OffsCrv2.Make( pCompo2, dRadius, nOffsType)) return nullptr ; ICurve* pOffs2 = OffsCrv2.GetLongerCurve() ; @@ -227,7 +224,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b SurfFlatRegionByContours SfrCntr( false, false) ; // offset della prima curva a destra del raggio - OffsetCurve OffsCrv1 ; + OffsetCurve OffsCrv1( dOffsLinTol) ; if ( ! OffsCrv1.Make( pCompo1, dRadius, nOffsType)) return nullptr ; ICurve* pOffs1 = OffsCrv1.GetLongerCurve() ; @@ -243,7 +240,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b } // offset della seconda curva a destra del raggio - OffsetCurve OffsCrv2 ; + OffsetCurve OffsCrv2( dOffsLinTol) ; if ( ! OffsCrv2.Make( pCompo2, dRadius, nOffsType)) return nullptr ; ICurve* pOffs2 = OffsCrv2.GetLongerCurve() ; diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index cf74ab9..cb52072 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -18,6 +18,7 @@ #include "CurveArc.h" #include "CurveComposite.h" #include "SurfTriMesh.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" @@ -345,8 +346,6 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, PtrOwner pCrvL( OffsCrvL.GetLongerCurve()) ; if ( IsNull( pCrvL)) return nullptr ; - PtrOwner pCrvRb ; - PtrOwner pCrvLb ; // costruisco le parti di superficie PtrOwner pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ; if ( IsNull( pSrfTop)) @@ -440,6 +439,8 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, static ISurfTriMesh* GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) { + // metodo di calcolo impostato da USE_VORONOI + // verifico che la linea guida sia piana Plane3d plGuide ; if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL)) @@ -456,19 +457,28 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub const int NUM_OFFS = 4 ; OffsetCurve vOffsCrv[NUM_OFFS] ; double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ; - future vRes[NUM_OFFS] ; - for ( int i = 0 ; i < NUM_OFFS ; ++ i) - vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ; bool bOk = true ; - int nFin = 0 ; - while ( nFin < NUM_OFFS) { - for ( int i = 0 ; i < NUM_OFFS ; ++ i) { - if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { - bOk = vRes[i].get() && bOk ; - ++ nFin ; + if ( ! USE_VORONOI) { + future vRes[NUM_OFFS] ; + for ( int i = 0 ; i < NUM_OFFS ; ++ i) + vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ; + bool bOk = true ; + int nFin = 0 ; + while ( nFin < NUM_OFFS) { + for ( int i = 0 ; i < NUM_OFFS ; ++ i) { + if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { + bOk = vRes[i].get() && bOk ; + ++ nFin ; + } } - } + } } + else { + // se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo + for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i) + bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ; + } + if ( ! bOk || vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 || vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0) diff --git a/StmFromTriangleSoup.cpp b/StmFromTriangleSoup.cpp index e83191b..0e3a7e6 100644 --- a/StmFromTriangleSoup.cpp +++ b/StmFromTriangleSoup.cpp @@ -4,7 +4,7 @@ // File : StmFromTriangleSoup.cpp Data : 07.05.23 Versione : 2.5e2 // Contenuto : Implementazione della classe StmFromTriangleSoup, per creare // una superficie trimesh da un insieme di triangoli -// (pu� essere disordinato come STL o pu� essere una superficie). +// (può essere disordinato come STL o può essere una superficie). // // Modifiche : 19.05.14 DS Creazione modulo. // @@ -53,7 +53,7 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria) // ciclo sui tre vertici int nIdV[3] ; for ( int i = 0 ; i < 3 ; ++ i) { - // verifico se vertice gi� presente + // verifico se vertice già presente int nId ; if ( ! m_VertGrid.Find( Tria.GetP( i), 2 * EPS_SMALL, nId)) { // aggiungo il vertice @@ -77,7 +77,7 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria) //---------------------------------------------------------------------------- bool StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2, - const double dU0, const double dV0,const double dU1, const double dV1,const double dU2, const double dV2) + double dU0, double dV0, double dU1, double dV1, double dU2, double dV2) { // verifico inizializzazione if ( m_pSTM == nullptr) @@ -100,9 +100,9 @@ StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, cons //---------------------------------------------------------------------------- int -StmFromTriangleSoup::AddVertex( const Point3d& ptP, const double dU, const double dV) +StmFromTriangleSoup::AddVertex( const Point3d& ptP, double dU, double dV) { - // verifico se gi� presente + // verifico se già presente int nId ; if ( m_VertGrid.Find( ptP, 2 * EPS_SMALL, nId)) return nId ; diff --git a/StmStandard.cpp b/StmStandard.cpp index 3bf1bc2..e32198a 100644 --- a/StmStandard.cpp +++ b/StmStandard.cpp @@ -26,34 +26,36 @@ using namespace std ; static SurfTriMesh* GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight) { - // creo la polilinea del contorno della base - PolyLine PL ; - int nU = 0 ; - PL.AddUPoint( nU, Point3d( 0, 0, 0)) ; - PL.AddUPoint( ++ nU, Point3d( dDimX, 0, 0)) ; - PL.AddUPoint( ++ nU, Point3d( dDimX, dDimY, 0)) ; - PL.AddUPoint( ++ nU, Point3d( 0, dDimY, 0)) ; - PL.AddUPoint( ++ nU, Point3d( 0, 0, 0)) ; - if ( dHeight < 0) - PL.Invert() ; - // vettore altezza (estrusione) - Vector3d vtExtr( 0, 0, dHeight) ; - // creo e setto la superficie trimesh laterale + // creo oggetto vuoto PtrOwner pSTM( CreateBasicSurfTriMesh()) ; - if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr)) + if ( IsNull( pSTM)) return nullptr ; - // creo la prima superficie di estremità - SurfTriMesh STM1 ; - if ( ! STM1.CreateByFlatContour( PL)) + // assegno i vertici + double dBotZ = 0, dTopZ = dHeight ; + if ( dBotZ > dTopZ) + swap( dBotZ, dTopZ) ; + if ( pSTM->AddVertex( Point3d( 0, 0, dBotZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( 0, 0, dTopZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( dDimX, 0, dBotZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( dDimX, 0, dTopZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( dDimX, dDimY, dBotZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( dDimX, dDimY, dTopZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( 0, dDimY, dBotZ)) == SVT_NULL || + pSTM->AddVertex( Point3d( 0, dDimY, dTopZ)) == SVT_NULL) return nullptr ; - // la copio - SurfTriMesh STM2 = STM1 ; - // inverto la prima superficie - STM1.Invert() ; - // traslo la seconda - STM2.Translate( Vector3d( 0, 0, dHeight)) ; - // le unisco alla superficie del fianco - if ( ! pSTM->DoSewing( STM1) || ! pSTM->DoSewing( STM2)) + // definisco i triangoli + int aVertId[12][3]{{ 1, 0, 2}, { 1, 2, 3}, + { 3, 2, 4}, { 3, 4, 5}, + { 5, 4, 6}, { 5, 6, 7}, + { 7, 6, 0}, { 7, 0, 1}, + { 0, 4, 2}, { 6, 4, 0}, + { 1, 3, 5}, { 7, 1, 5}} ; + for ( int i = 0 ; i < 12 ; ++ i) { + if ( pSTM->AddTriangle( aVertId[i]) == SVT_NULL) + return nullptr ; + } + // sistemo la topologia + if ( ! pSTM->AdjustTopology()) return nullptr ; // restituisco la superficie return Release( pSTM) ; diff --git a/SurfBezier.cpp b/SurfBezier.cpp index b005b74..265236c 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -54,7 +54,7 @@ SurfBezier::~SurfBezier( void) bool SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational) { - // verifico validità grado + // verifico validit� grado if ( nDegU < 1 || nDegU > MAXDEG || nDegV < 1 || nDegV > MAXDEG || nSpanU < 1 || nSpanV < 1) return false ; @@ -86,7 +86,7 @@ SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational bool SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) { - // verifico validità indice + // verifico validit� indice if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd >= GetDim()) return false ; @@ -108,7 +108,7 @@ SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) bool SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) { - // verifico validità, razionalità e indice + // verifico validit�, razionalit� e indice if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) return false ; @@ -158,7 +158,7 @@ SurfBezier::GetTrimRegion( void) const bool SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const { - // verifico validità superficie + // verifico validit� superficie if ( m_nStatus != OK) return false ; // restituisco gradi e flag di razionale @@ -175,7 +175,7 @@ SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIs const Point3d& SurfBezier::GetControlPoint( int nInd, bool* pbOk) const { - // verifico validità e indice + // verifico validit� e indice if ( m_nStatus != OK || nInd < 0 || nInd >= GetDim()) { if ( pbOk != NULL) *pbOk = false ; @@ -191,7 +191,7 @@ SurfBezier::GetControlPoint( int nInd, bool* pbOk) const double SurfBezier::GetControlWeight( int nInd, bool* pbOk) const { - // verifico validità, razionalità e indice + // verifico validit�, razionalit� e indice if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) { if ( pbOk != NULL) *pbOk = false ; @@ -503,7 +503,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Side nUs, Side nVs, if ( vtN.Normalize()) return true ; - // se solo una delle due derivate è piccola, mi sposto lungo il relativo parametro e uso le tangenti + // se solo una delle due derivate � piccola, mi sposto lungo il relativo parametro e uso le tangenti if ( pvtDerU->Len() < EPS_SMALL && pvtDerV->Len() > 10 * EPS_SMALL) { double dCoeff = ( dU - 1000 * EPS_PARAM < 0. ? 1 : -1) ; double dUm = dU + 1000 * EPS_PARAM * dCoeff ; @@ -582,7 +582,7 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc) m_vWeCtrl = sbSrc.m_vWeCtrl ; if ( sbSrc.m_bTrimmed) { m_bTrimmed = true ; - m_pTrimReg = sbSrc.m_pTrimReg ; + m_pTrimReg = sbSrc.m_pTrimReg->Clone() ; } m_nTempProp[0] = sbSrc.m_nTempProp[0] ; m_nTempProp[1] = sbSrc.m_nTempProp[1] ; @@ -610,7 +610,7 @@ SurfBezier::GetTitle( void) const bool SurfBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const { - // verifico validità superficie + // verifico validit� superficie if ( m_nStatus != OK) sOut += string( "Status=Invalid") + szNewLine ; // area @@ -843,7 +843,7 @@ SurfBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, d // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità dell'asse di rotazione + // verifico validit� dell'asse di rotazione if ( vtAx.IsSmall()) return false ; @@ -899,7 +899,7 @@ SurfBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità del piano di specchiatura + // verifico validit� del piano di specchiatura if ( vtNorm.IsSmall()) return false ; @@ -922,7 +922,7 @@ SurfBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità dei parametri + // verifico validit� dei parametri if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; @@ -944,11 +944,11 @@ SurfBezier::ToGlob( const Frame3d& frRef) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se frame identità, non devo fare alcunché + // se frame identit�, non devo fare alcunch� if ( IsGlobFrame( frRef)) return true ; @@ -970,11 +970,11 @@ SurfBezier::ToLoc( const Frame3d& frRef) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se frame identità, non devo fare alcunché + // se frame identit�, non devo fare alcunch� if ( IsGlobFrame( frRef)) return true ; @@ -996,11 +996,11 @@ SurfBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità dei frame + // verifico validit� dei frame if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) return false ; - // se i due riferimenti coincidono, non devo fare alcunché + // se i due riferimenti coincidono, non devo fare alcunch� if ( AreSameFrame( frOri, frDest)) return true ; @@ -1263,7 +1263,7 @@ SurfBezier::GetLoop( int nLoop) const // se loop chiuso lo restituisco, altrimenti errore return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ; } - // la superficie è trimmata, quindi devo cercare nei vari chunck il loop corrispondente + // la superficie � trimmata, quindi devo cercare nei vari chunck il loop corrispondente else { if ( nLoop > m_pTrimReg->GetChunkCount()) return nullptr ; @@ -1421,7 +1421,7 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const // ResetAuxSurf() ; // return nullptr ; // } -// // se già calcolata, la restituisco +// // se gi� calcolata, la restituisco // if ( m_pSTM != nullptr) // return m_pSTM ; // // costruttore della superficie @@ -1497,34 +1497,44 @@ SurfBezier::GetAuxSurf( void) const ResetAuxSurf() ; return nullptr ; } - // se già calcolata, la restituisco + // se gi� calcolata, la restituisco if ( m_pSTM != nullptr) return m_pSTM ; - // costruttore della superficie - vector vvPL ; + // costruttore della superficie + POLYLINEMATRIX vvPL ; //POLYLINEVECTOR vPL ; // per usare i polygon basic Tree Tree( this, true) ; - std::vector> vTrees ; + BIPNTVECTOR vTrees ; Tree.GetIndependentTrees( vTrees) ; + bool bTest = false ; // per debug for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) { Point3d ptMin = std::get<0>( vTrees[i]) ; Point3d ptMax = std::get<1>( vTrees[i]) ; Tree.SetSurf( this, true, ptMin, ptMax) ; - //Tree.BuildTree_test() ; // per debug - //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; - Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + if ( bTest) { + Tree.BuildTree_test() ; // per debug + //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug + Tree.SetTestMode() ; + } + else { + Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + } Tree.GetPolygons( vvPL) ; + //Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic } - //// per usare i polygon basic////////////////////// + //// per usare i polygon basic////////////////////// //for (int k = 0 ; k < (int)vPL.size(); ++k) { // vvPL.emplace_back() ; // vvPL.back().push_back(vPL[k]) ; //} - //// per usare i polygon basic/////////////////// + //// per usare i polygon basic/////////////////// + + // qui non sarebbe male stampare un messaggio di errore nel log se avevo un'area da disegnare ma non sono usciti dei poligoni + if ( int(vvPL.size()) == 0) + LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface couldn't be triangulated, hence wasn't drawn") ; - PtrOwner pSrfTm( CreateBasicSurfTriMesh()) ; StmFromTriangleSoup stmSoup ; if ( ! stmSoup.Start()) return nullptr ; @@ -1565,24 +1575,27 @@ SurfBezier::GetAuxSurf( void) const //---------------------------------------------------------------------------- bool -SurfBezier::GetLeaves( std::vector>& vLeaves) const +SurfBezier::GetLeaves( vector>& vLeaves) const { - std::vector vCells ; Tree Tree( this, true) ; - std::vector> vTrees ; + BIPNTVECTOR vTrees ; Tree.GetIndependentTrees( vTrees) ; - for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) { - Point3d ptMin = std::get<0>( vTrees[i]) ; - Point3d ptMax = std::get<1>( vTrees[i]) ; + for ( int i = 0 ; i < int( vTrees.size()) ; ++ i) { + Point3d ptMin = get<0>( vTrees[i]) ; + Point3d ptMax = get<1>( vTrees[i]) ; Tree.SetSurf( this, true, ptMin, ptMax) ; - //Tree.BuildTree_test() ; - //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; - Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + bool bTest = false ; // per debug + if ( bTest) { + Tree.BuildTree_test() ; // per debug + //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug + } + else { + Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + } + vector vCells ; Tree.GetLeaves( vCells) ; - for (int k = 0 ; k < (int)vCells.size(); ++ k ) { - std::tuple tCell ; - tCell = make_tuple( vCells[k].m_nId, vCells[k].GetBottomLeft(), vCells[k].GetTopRight()) ; - vLeaves.push_back( tCell) ; + for ( int k = 0 ; k < int( vCells.size()) ; ++ k) { + vLeaves.emplace_back( vCells[k].m_nId, vCells[k].GetBottomLeft(), vCells[k].GetTopRight()) ; } } return true ; diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index a250754..7c0095d 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -22,6 +22,7 @@ #include "CurveLine.h" #include "AdjustLoops.h" #include "GeoConst.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" #include "/EgtDev/Include/EGkIntervals.h" @@ -1439,21 +1440,6 @@ SurfFlatRegion::CalcVoronoiObject() const return true ; } -//---------------------------------------------------------------------------- -Voronoi* -SurfFlatRegion::GetVoronoiObject() const -{ - if ( m_nStatus != OK) - return nullptr ; - - // se non è stato calcolato, lo calcolo - if ( m_pVoronoiObj == nullptr) - CalcVoronoiObject() ; - - // restituisco Voronoi - return m_pVoronoiObj ; -} - //---------------------------------------------------------------------------- void SurfFlatRegion::ResetVoronoiObject() const diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h index 794e755..dcfb642 100644 --- a/SurfFlatRegion.h +++ b/SurfFlatRegion.h @@ -22,6 +22,8 @@ #include "/EgtDev/Include/EGkSurfFlatRegion.h" #include +class Voronoi ; + //---------------------------------------------------------------------------- class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW { @@ -101,8 +103,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW 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 - Voronoi* GetVoronoiObject( void) const override ; - bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = VORONOI_STD_BOUND) const override ; + bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ; bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ; public : // IGeoObjRW diff --git a/SurfFlatRegionOffset.cpp b/SurfFlatRegionOffset.cpp index c1e47cb..cda1912 100644 --- a/SurfFlatRegionOffset.cpp +++ b/SurfFlatRegionOffset.cpp @@ -16,6 +16,7 @@ #include "GeoConst.h" #include "CurveComposite.h" #include "SurfFlatRegion.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -28,11 +29,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const { // restituisce la superficie offsettata senza modificare la superficie corrente. In caso di errore restituisce nullptr - // imposto metodo di calcolo - bool bUseVoronoi = false ; - #ifdef _VRONI - bUseVoronoi = true ; - #endif // _VRONI + // metodo di calcolo impostato da USE_VORONOI // recupero il numero dei chunk int nChunk = GetChunkCount() ; @@ -49,7 +46,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const return nullptr ; // -------------------- OFFSET STANDARD ------------------------------------- - if ( ! bUseVoronoi) { + if ( ! USE_VORONOI) { bool bFirstRegion = true ; // ciclo sui chunk for ( int i = 0 ; i < nChunk ; ++ i) { diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 03cc80e..3ff41d3 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -106,7 +106,7 @@ SurfTriMesh::Clear( void) //---------------------------------------------------------------------------- int -SurfTriMesh::AddVertex( const Point3d& ptVert, const double dU, const double dV) +SurfTriMesh::AddVertex( const Point3d& ptVert, double dU, double dV) { // imposto ricalcolo m_nStatus = TO_VERIFY ; diff --git a/SurfTriMesh.h b/SurfTriMesh.h index fd35597..e78f3f5 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -226,7 +226,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW { m_dSmoothAng = std::max( dSmoothAngDeg, EPS_ANG_SMALL) ; m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ; m_OGrMgr.Reset() ; } - int AddVertex( const Point3d& ptVert, const double dU = -1 , const double dV = -1) override ; + int AddVertex( const Point3d& ptVert, double dU = -1, double dV = -1) override ; bool MoveVertex( int nInd, const Point3d& ptNewVert) override ; int AddTriangle( const int nIdVert[3], int nTFlag = 0) override ; bool RemoveTriangle( int nId) override ; diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index a2a44d9..8303cdb 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -1275,6 +1275,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) RetriangulationForBooleanOperation( LineMapB, AmbiguosB, SurfB, bModif) ; // Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra. + // non mi basta fare un controllo sulle bbox perché non so come sono orientate le superfici e che potrebbero anche non essere chiuse bool bRetriangulated = true ; if ( ! bModif && ( int( AmbiguosA.size()) == 0 || int( AmbiguosB.size()) == 0)) { bRetriangulated = false ; @@ -1283,7 +1284,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) int nCurVert = GetFirstVertex( ptFirstV) ; int nInOutNum = 0 ; while ( nInOutNum == 0 && nCurVert != SVT_NULL) { - int nTriaNum = - 1 ; + INTVECTOR vnTriaNum ; double dMinDist = DBL_MAX ; for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) { // Se il triangolo B non è valido, continuo @@ -1291,18 +1292,66 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) if ( ! SurfB.GetTriangle( nTB, trTriaB) || ! trTriaB.Validate( true)) continue ; double dDist ; - if ( DistPointTriangle( ptFirstV, trTriaB).GetDist( dDist) && dDist < dMinDist) { - nTriaNum = nTB ; - dMinDist = dDist ; + // potrei trovare più triangolo equidistanti, li salvo tutti + if ( DistPointTriangle( ptFirstV, trTriaB).GetDist( dDist)) { + if ( abs(dDist - dMinDist) < EPS_SMALL) + vnTriaNum.push_back( nTB) ; + else if ( dDist < dMinDist){ + vnTriaNum.clear() ; + vnTriaNum.push_back( nTB) ; + dMinDist = dDist ; + } } } - if ( nTriaNum >= 0) { + if ( ! vnTriaNum.empty()) { Triangle3d trTriaB ; - SurfB.GetTriangle( nTriaNum, trTriaB) ; - if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) - nInOutNum = 1 ; - else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) - nInOutNum = - 1 ; + bool bSame = true ; + // controllo se rispetto a questi triangoli il punto risulta sempre fuori o sempre dentro + for ( int nTriaNum : vnTriaNum) { + SurfB.GetTriangle( nTriaNum, trTriaB) ; + if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = 1 ; + else if (nInOutNum == -1) { + bSame = false ; + break ; + } + } + else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = -1 ; + else if (nInOutNum == 1) { + bSame = false ; + break ; + } + } + } + // se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino + // e ricalcolo l'informazione che mi dà la sua normale + if ( ! bSame ) { + Point3d ptBar_tot ; + for (int nTriaNum : vnTriaNum) { + SurfB.GetTriangle( nTriaNum, trTriaB) ; + ptBar_tot += trTriaB.GetCentroid(); + } + ptBar_tot /= (int)vnTriaNum.size() ; + for (int nTriaNum : vnTriaNum) { + SurfB.GetTriangle( nTriaNum, trTriaB) ; + Point3d ptInters1, ptInters2 ; + int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaB, ptInters1, ptInters2, true) ; + if (nInters == ILTT_NO) + continue ; + else if ( nInters == ILTT_IN ) { + if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) + nInOutNum = 1 ; + else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) + nInOutNum = -1 ; + break ; + } + else + nInOutNum = 0 ; + } + } } if ( nInOutNum == 0) { nCurVert = GetNextVertex( nVertNum, ptFirstV) ; @@ -1316,7 +1365,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) nCurVert = SurfB.GetFirstVertex( ptFirstV) ; nInOutNum = 0 ; while ( nInOutNum == 0 && nCurVert != SVT_NULL) { - int nTriaNum = - 1 ; + INTVECTOR vnTriaNum ; double dMinDist = DBL_MAX ; for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) { // Se il triangolo A non è valido, continuo @@ -1326,19 +1375,65 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) DistPointTriangle DistCalculator( ptFirstV, trTriaA) ; double dDist ; DistCalculator.GetDist( dDist) ; - if ( dDist < dMinDist) { - nTriaNum = nTA ; - dMinDist = dDist ; + // potrei trovare più triangolo equidistanti, li salvo tutti + if ( DistPointTriangle( ptFirstV, trTriaA).GetDist( dDist)) { + if ( abs(dDist - dMinDist) < EPS_SMALL) + vnTriaNum.push_back( nTA) ; + else if ( dDist < dMinDist){ + vnTriaNum.clear() ; + vnTriaNum.push_back( nTA) ; + dMinDist = dDist ; + } } } - if ( nTriaNum >= 0) { + if ( ! vnTriaNum.empty()) { Triangle3d trTriaA ; - GetTriangle( nTriaNum, trTriaA) ; - if ( ( ptFirstV - trTriaA.GetP( 0)) * trTriaA.GetN() < - EPS_SMALL) { - nInOutNum = 1 ; + bool bSame = true ; + // controllo se rispetto a questi triangoli il punto risulta sempre fuori o sempre dentro + for ( int nTriaNum : vnTriaNum) { + GetTriangle( nTriaNum, trTriaA) ; + if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = 1 ; + else if (nInOutNum == -1) { + bSame = false ; + break ; + } + } + else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = -1 ; + else if (nInOutNum == 1) { + bSame = false ; + break ; + } + } } - else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) { - nInOutNum = - 1 ; + // se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino + // e ricalcolo l'informazione che mi dà la sua normale + if ( ! bSame ) { + Point3d ptBar_tot ; + for (int nTriaNum : vnTriaNum) { + GetTriangle( nTriaNum, trTriaA) ; + ptBar_tot += trTriaA.GetCentroid(); + } + ptBar_tot /= (int)vnTriaNum.size() ; + for (int nTriaNum : vnTriaNum) { + GetTriangle( nTriaNum, trTriaA) ; + Point3d ptInters1, ptInters2 ; + int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaA, ptInters1, ptInters2, true) ; + if (nInters == ILTT_NO) + continue ; + else if ( nInters == ILTT_IN ) { + if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) + nInOutNum = 1 ; + else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) + nInOutNum = -1 ; + break ; + } + else + nInOutNum = 0 ; + } } } if ( nInOutNum == 0) { diff --git a/SurfTriMeshFaceting.cpp b/SurfTriMeshFaceting.cpp index 66422c1..2b9df41 100644 --- a/SurfTriMeshFaceting.cpp +++ b/SurfTriMeshFaceting.cpp @@ -731,7 +731,7 @@ SurfTriMesh::CloneFacet( int nF) const int nIdV[3] ; for ( int j = 0 ; j < 3 ; ++ j) { // verifico se vertice già presente - VVMAP::iterator it = PntMap.find( m_vTria[nT].nIdVert[j]) ; + const auto it = PntMap.find( m_vTria[nT].nIdVert[j]) ; if ( it == PntMap.end()) { // aggiungo il vertice if ( ( nIdV[j] = pSTM->AddVertex( m_vVert[m_vTria[nT].nIdVert[j]].ptP)) == SVT_NULL) diff --git a/SurfTriMeshUtilities.cpp b/SurfTriMeshUtilities.cpp index 42467a3..c09cf0a 100644 --- a/SurfTriMeshUtilities.cpp +++ b/SurfTriMeshUtilities.cpp @@ -254,16 +254,19 @@ SurfTriMesh::RemoveTJunctions( bool& bModified) static bool IsVertex( PNTULIST& PointList, PNTULIST::const_iterator itCurr) { + // se la lista contiene meno di tre punti, test inutili + if ( PointList.size() < 3) + return false ; // recupero il punto precedente PNTULIST::const_iterator itPrev ; - if ( itCurr == PointList.begin()) - itPrev = prev( PointList.end(), 2) ; + if ( itCurr == PointList.cbegin()) + itPrev = prev( PointList.cend(), 2) ; else itPrev = prev( itCurr) ; // recupero il punto successivo auto itNext = next( itCurr) ; - if ( itNext == PointList.end()) - itNext = next( PointList.begin()) ; + if ( itNext == PointList.cend()) + itNext = next( PointList.cbegin()) ; // se cambia faccia adiacente tra prima e dopo, va bene if ( itPrev->second != itCurr->second) return true ; diff --git a/Tree.cpp b/Tree.cpp index a6ffae9..9bdfaca 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -13,7 +13,6 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include #include "Tree.h" #include "SurfBezier.h" #include "GeoConst.h" @@ -25,63 +24,22 @@ #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkCurve.h" #include "DistPointCrvComposite.h" +#include -//---------------------------------------------------------------------------- -Cell::Cell( void) - : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), - m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), - m_ptPbl( ORIG), m_ptPtr(), m_bProcessed( false), m_bSplitVert( true) -{ - Point3d ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ; - m_ptPtr = ptTr ; -} - - -//---------------------------------------------------------------------------- -Cell::Cell( const Point3d& ptBL, const Point3d& ptTR) - : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), - m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), - m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) -{} - - -//---------------------------------------------------------------------------- -Cell::~Cell( void) -{ -} - -//---------------------------------------------------------------------------- -inline bool -Cell::IsSame( const Cell& cOtherCell) const -{ - if ( m_nId == cOtherCell.m_nId) - return true ; - else - return false ; -} - -//---------------------------------------------------------------------------- -bool -Cell::IsLeaf ( void) const -{ - if( m_nChild1 == -2 && m_nChild2 == -2) - return true ; - else - return false ; -} +using namespace std ; //---------------------------------------------------------------------------- Tree::Tree( void) - : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true) + : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false) { Point3d ptBl( 0, 0), ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ; Cell cRoot( ptBl, ptTr) ; - m_mTree.insert( std::pair< int, Cell>( -1, cRoot)) ; + m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; } //---------------------------------------------------------------------------- -Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d ptMin, const Point3d ptMax) - : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true) +Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) + : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false) { SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ; } @@ -93,9 +51,9 @@ Tree::~Tree( void) //---------------------------------------------------------------------------- void -Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d ptMin, const Point3d ptMax) +Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) { - // pulisco i vettori membri + // pulisco i vettori membri m_vnLeaves.clear() ; m_vnParents.clear() ; m_mVert.clear() ; @@ -105,8 +63,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d m_vChunk.clear() ; m_vPolygons.clear() ; - - m_pSrfBz = pSrfBz ; m_bSplitPatches = bSplitPatches ; // le coordinate delle celle sono nello spazio parametrico @@ -127,7 +83,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d int nLoop = 0 ; INTVECTOR vChunk ; - // recupero la superficie di trim per avere accesso diretto ai loop e mantenendo le informazioni sui chunk + // recupero la superficie di trim per avere accesso diretto ai loop e mantenendo le informazioni sui chunk PtrOwner pTrimReg( m_pSrfBz->GetTrimRegion()->Clone()) ; double dLinTol = 0.01 ; // questo è riferito allo spazio parametrico double dAngTolDeg = 5 ; @@ -135,17 +91,22 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d PtrOwner pChunk( pTrimReg->CloneChunk( i)) ; for ( int j = 0 ; j < pChunk->GetLoopCount( 0) ; ++ j) { vChunk.push_back( nLoop) ; - // i chunk della falt region sono ancora flat region composte da 1 chunk + // i chunk della falt region sono ancora flat region composte da 1 chunk PtrOwner pLoop ( pChunk->GetLoop( 0, j)) ; - PtrOwner pCrv( pLoop->Clone()) ; + // rimuovo i difetti dei loop prima di salvarli + PtrOwner pCrvCompo( GetBasicCurveComposite(pLoop->Clone())) ; + pCrvCompo->MergeCurves( dLinTol, dAngTolDeg) ; + pCrvCompo->RemoveSmallDefects( dLinTol, dAngTolDeg, true) ; + pCrvCompo->RemoveSmallParts( dLinTol, dAngTolDeg) ; + PtrOwner pCrv( pCrvCompo->Clone()) ; m_vLoop.emplace_back( Release( pLoop)) ; m_mChunk[nLoop] = i ; ++ nLoop ; - // approssimo i loop di trim con delle spezzate + // approssimo i loop di trim con delle spezzate PolyLine plApprox ; int nType = 0 ; pCrv->ApproxWithLines( dLinTol,dAngTolDeg, nType, plApprox) ; - // calcolo se il loop è CCW o CW + // calcolo se il loop è CCW o CW double dArea ; Plane3d plExtPlane ; bool bCCW ; @@ -154,21 +115,21 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d bCCW = true ; else bCCW = false ; - m_vPlApprox.push_back( std::tuple(plApprox,bCCW)) ; + m_vPlApprox.push_back( tuple(plApprox,bCCW)) ; } - // li riordino dal più grande al più piccolo - std::sort(vChunk.begin(), vChunk.end(), [this]( const int& a, const int& b) { double dArea1, dArea2 ; - m_vLoop[a]->GetAreaXY( dArea1) ; - m_vLoop[b]->GetAreaXY( dArea2) ; - return dArea1 > dArea2 ;}) ; + // li riordino dal più grande al più piccolo + sort(vChunk.begin(), vChunk.end(), [this]( const int& a, const int& b) { double dArea1, dArea2 ; + m_vLoop[a]->GetAreaXY( dArea1) ; + m_vLoop[b]->GetAreaXY( dArea2) ; + return dArea1 > dArea2 ; }) ; m_vChunk.push_back( vChunk) ; vChunk.clear() ; } - // li riordino dal più grande al più piccolo - std::sort(m_vChunk.begin(), m_vChunk.end(), [this]( const INTVECTOR& a, const INTVECTOR& b) { double dArea1, dArea2 ; - m_vLoop[a[0]]->GetAreaXY( dArea1) ; - m_vLoop[b[0]]->GetAreaXY( dArea2) ; - return dArea1 > dArea2 ;}) ; + // li riordino dal più grande al più piccolo + sort(m_vChunk.begin(), m_vChunk.end(), [this]( const INTVECTOR& a, const INTVECTOR& b) { double dArea1, dArea2 ; + m_vLoop[a[0]]->GetAreaXY( dArea1) ; + m_vLoop[b[0]]->GetAreaXY( dArea2) ; + return dArea1 > dArea2 ;}) ; } // salvo i vertici 3d della cella root Point3d ptTop( nSpanU * SBZ_TREG_COEFF, nSpanV * SBZ_TREG_COEFF) ; @@ -179,7 +140,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } m_mTree.clear() ; Cell cRoot( ptMin, ptTop) ; - m_mTree.insert( std::pair< int, Cell>( -1, cRoot)) ; + m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; Point3d ptP00, ptP10, ptP11, ptP01 ; bool bOk = false ; if ( ! bLimited) { @@ -199,18 +160,18 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d vVert.push_back( ptP10) ; vVert.push_back( ptP11) ; vVert.push_back( ptP01) ; - m_mVert.insert( std::pair( -1, vVert)) ; + m_mVert.insert( pair( -1, vVert)) ; // se richiesto divido preliminarmente le patches m_vnParents.clear() ; if ( m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) { int nId = -1 ; - // se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo + // se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo if ( AreSamePointApprox(ptP00, ptP10) && AreSamePointApprox(ptP01, ptP11) ) { m_mTree[-1].m_nLeft = -1 ; m_mTree[-1].m_nRight = -1 ; m_bClosedU = true ; } - // se la superficie è chiusa lungo il parametro V, sistemo le adiacenze al bordo + // se la superficie è chiusa lungo il parametro V, sistemo le adiacenze al bordo if ( ( AreSamePointApprox(ptP00, ptP01) && AreSamePointApprox(ptP10, ptP11) ) ) { m_mTree[-1].m_nTop = -1 ; m_mTree[-1].m_nBottom = -1 ; @@ -239,15 +200,13 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } } vLeaves.clear() ; - GetHeightLeaves( -1, vLeaves) ; - m_vnParents = vLeaves ; } - // controllo se la superficie è chiusa. - // se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa - // e sistemo le adiacenze + // controllo se la superficie è chiusa. + // se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa + // e sistemo le adiacenze if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) || ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11))) { - //m_bClosed = true ; + // m_bClosed = true ; if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) && (int) m_mTree.size() == 1) { if ( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11)) { m_mTree[-1].m_nTop = -1 ; @@ -256,13 +215,13 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } m_mTree[-1].SetSplitDirVert( false) ; Split( -1) ; - // qui devo fare il controllo capped ( chiusura a semisfera) - // devo controllare se i punti ai parametri U=0 e U=1 sono tutti coincidenti - // in caso devo fare uno split nell'altra direzione + // qui devo fare il controllo capped ( chiusura a semisfera) + // devo controllare se i punti ai parametri U=0 e U=1 sono tutti coincidenti + // in caso devo fare uno split nell'altra direzione bool bOk = false ; bool bCapped0 = true, bCapped1 = true ; Point3d ptV0, ptV1 ; - // controllo se tutti i punti sull'isoparametrica sono uguali + // controllo se tutti i punti sull'isoparametrica sono uguali for ( int i = 1 ; i < nDegV * nSpanV + 1 ; ++ i) { ptV0 = m_pSrfBz->GetControlPoint( i * ( nDegU * nSpanU + 1), &bOk) ; bCapped0 = bCapped0 && AreSamePointApprox( ptP00, ptV0) ; @@ -276,9 +235,9 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d Split( 1) ; } } - // nella condizione di questo if non controllo eventuali divisioni preliminari, perché ne tengo conto dopo + // nella condizione di questo if non controllo eventuali divisioni preliminari, perché ne tengo conto dopo if ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11)) { - if( (int) m_mTree.size() == 1) { + if ( m_mTree.size() == 1) { if ( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11)) { m_mTree[-1].m_nLeft = -1 ; m_mTree[-1].m_nRight = -1 ; @@ -286,12 +245,12 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } m_mTree[-1].SetSplitDirVert( true) ; Split( -1) ; - // devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti - // in caso devo fare uno split nell'altra direzione + // devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti + // in caso devo fare uno split nell'altra direzione bool bOk = false ; bool bCapped0 = true, bCapped1 = true ; Point3d ptU0, ptU1 ; - // controllo se tutti i punti sull'isoparametrica sono uguali + // controllo se tutti i punti sull'isoparametrica sono uguali for ( int i = 1 ; i < nDegU * nSpanU + 1 ; ++ i) { ptU0 = m_pSrfBz->GetControlPoint( i, &bOk) ; bCapped0 = bCapped0 && AreSamePointApprox( ptP00, ptU0) ; @@ -305,7 +264,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d Split( 1) ; } } - // se ho fatto solo 1 split orizzontale e ho due celle foglie nId = 0 e nId = 1 + // se ho fatto solo 1 split orizzontale e ho due celle foglie nId = 0 e nId = 1 else if ( (int) m_mTree.size() > 1 && (int) m_mTree.size() < 4 && ! m_mTree.at(-1).IsSplitVert()) { // si può mettere anche < 5 m_mTree[0].m_nLeft = -1 ; m_mTree[0].m_nRight = -1 ; @@ -318,8 +277,12 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } } } + // calcolo i parent che ho creato con le eventuali divisioni preliminari + INTVECTOR vLeaves ; + GetHeightLeaves( -1, vLeaves) ; + m_vnParents = vLeaves ; - // calcolo e salvo la lunghezza reale delle curve di bezier di bordo + // calcolo e salvo la lunghezza reale delle curve di bezier di bordo PtrOwner pCrvV0( m_pSrfBz->GetCurveOnU( 0)) ; PtrOwner pCrvV1( m_pSrfBz->GetCurveOnU( double(nSpanV))) ; PtrOwner pCrvU0( m_pSrfBz->GetCurveOnV( 0)) ; @@ -353,10 +316,11 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d //---------------------------------------------------------------------------- bool -AddOrMergeBBox ( const BBox3d& bBox3dA , std::vector& vBBox, const bool& bAdd = true, const int& nInd = 0) { +AddOrMergeBBox( const BBox3d& bBox3dA, vector& vBBox, bool bAdd = true, int nInd = 0) +{ Point3d ptMin = bBox3dA.GetMin() ; Point3d ptMax = bBox3dA.GetMax() ; - if ( (int)vBBox.size() == 0) { + if ( vBBox.empty()) { vBBox.push_back( bBox3dA) ; return true ; } @@ -364,7 +328,7 @@ AddOrMergeBBox ( const BBox3d& bBox3dA , std::vector& vBBox, const bool& for ( int b = 0 ; b < (int)vBBox.size() ; ++b) { BBox3d bBox3dB = vBBox[b] ; BBox3d b3Int ; - // se sono celle diverse e ho un'intersezione faccio il merge + // se sono celle diverse e ho un'intersezione faccio il merge if ( ! ( AreSamePointExact( ptMin, bBox3dB.GetMin()) && AreSamePointExact( ptMax, bBox3dB.GetMax())) && bBox3dA.FindIntersectionXY( bBox3dB, b3Int)) { vBBox[b].Add( bBox3dA) ; @@ -372,7 +336,7 @@ AddOrMergeBBox ( const BBox3d& bBox3dA , std::vector& vBBox, const bool& vBBox.erase( vBBox.begin() + nInd) ; -- b ; } - // se ho fatto un merge devo controllare se ora la nuova bbox ha delle intersezioni + // se ho fatto un merge devo controllare se ora la nuova bbox ha delle intersezioni AddOrMergeBBox( vBBox[b], vBBox, false, b) ; bAdded = true ; break ; @@ -385,59 +349,60 @@ AddOrMergeBBox ( const BBox3d& bBox3dA , std::vector& vBBox, const bool& //---------------------------------------------------------------------------- bool -Tree::GetIndependentTrees( std::vector>& vTrees) +Tree::GetIndependentTrees( BIPNTVECTOR& vTrees) { - if ( ! m_bTrimmed ) { - vTrees.push_back( std::tuple( ORIG, ORIG)); + if ( ! m_bTrimmed) { + vTrees.emplace_back( ORIG, ORIG) ; } else { - // se ho dei loop di trim trovo le loro BBox3d per costruire l'albero solo all'interno di queste BBox - bool bIsRoot = false ; - std::vector vBBox ; - for ( int a = 0 ; a < (int)m_vPlApprox.size(); ++a ) { - PolyLine plLoop = std::get<0>( m_vPlApprox[a]) ; - // calcolo la BBox3d - BBox3d bBox3dA ; - Point3d pt ; - plLoop.GetFirstPoint( pt) ; - bBox3dA.Add( pt) ; - while ( plLoop.GetNextPoint( pt)) - bBox3dA.Add( pt) ; - // controllo se ho intersezioni con altre bbox - // se ho intersezioni unisco le bbox, altrimenti le lascio indipendenti + // se ho dei loop di trim trovo le loro BBox3d per costruire l'albero solo all'interno di queste BBox + BOXVECTOR vBBox ; + for ( int i = 0 ; i < int( m_vPlApprox.size()) ; ++ i) { + PolyLine plLoop = get<0>( m_vPlApprox[i]) ; + // calcolo la BBox3d + Point3d ptP ; + plLoop.GetFirstPoint( ptP) ; + BBox3d bBox3dA( ptP) ; + while ( plLoop.GetNextPoint( ptP)) + bBox3dA.Add( ptP) ; + // controllo se ho intersezioni con altre bbox + // se ho intersezioni unisco le bbox, altrimenti le lascio indipendenti AddOrMergeBBox( bBox3dA, vBBox) ; } - // controllo se dopo aver unito le bbox ho ottenuto Root + // controllo se dopo aver unito le bbox ho ottenuto Root + bool bIsRoot = false ; Point3d ptTR( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF) ; - for (int c = 0 ; c < (int)vBBox.size(); ++ c) { - BBox3d bBox3d = vBBox[c] ; - if ( AreSamePointEpsilon( bBox3d.GetMin(), ORIG, 10) && AreSamePointEpsilon( bBox3d.GetMax(), ptTR, 10)){ + for ( int i = 0 ; i < int( vBBox.size()) ; ++ i) { + BBox3d bBox3d = vBBox[i] ; + if ( AreSamePointEpsilon( bBox3d.GetMin(), ORIG, 10) && AreSamePointEpsilon( bBox3d.GetMax(), ptTR, 10)) { bIsRoot = true ; break ; } } - // restituisco le celle parent di partenza a partire dalle bbox che ho ottenuto - if ( ! bIsRoot ) { - for (int i = 0 ; i < (int)vBBox.size() ; ++ i) { + // restituisco le celle parent di partenza a partire dalle bbox che ho ottenuto + if ( ! bIsRoot) { + for ( int i = 0 ; i < int( vBBox.size()) ; ++ i) { Point3d ptMin = vBBox[i].GetMin() ; Point3d ptMax = vBBox[i].GetMax() ; - vTrees.push_back( std::tuple( ptMin, ptMax)) ; + vTrees.emplace_back( ptMin, ptMax) ; } } else - vTrees.push_back( std::tuple( ORIG, ORIG)); + vTrees.emplace_back( ORIG, ORIG); } return true ; } //---------------------------------------------------------------------------- bool -Tree::Split( const int& nId, const double& dSplitValue) +Tree::Split( int nId, double dSplitValue) { // controllo che lo split non venga fatto sul lato della cella - if ( ( m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().x + EPS_SMALL && dSplitValue < m_mTree[nId].GetTopRight().x - EPS_SMALL) || - ( ! m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().y + EPS_SMALL && dSplitValue < m_mTree[nId].GetTopRight().y - EPS_SMALL)) { - // quando si implementerà lo split a parametro libero bisognerà impedire che si facciano split troppo vicini al bordo della cella!!!!!!!!!!!!!!!!!!! + if ( ( m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().x + EPS_SMALL && + dSplitValue < m_mTree[nId].GetTopRight().x - EPS_SMALL) || + ( ! m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().y + EPS_SMALL && + dSplitValue < m_mTree[nId].GetTopRight().y - EPS_SMALL)) { + // quando si implementerà lo split a parametro libero bisognerà impedire che si facciano split troppo vicini al bordo della cella!!!!!!!!!!!!!!!!!!! m_mTree[nId].m_dSplit = dSplitValue ; Cell cChild1, cChild2 ; cChild1.m_nDepth = m_mTree[nId].m_nDepth + 1 ; @@ -447,14 +412,13 @@ Tree::Split( const int& nId, const double& dSplitValue) m_mTree[nId].m_nChild1 = nNodes - 1 ; cChild2.m_nId = nNodes ; m_mTree[nId].m_nChild2 = nNodes ; - m_mTree.insert( std::pair( nNodes - 1, cChild1)) ; - m_mTree.insert( std::pair( nNodes, cChild2)) ; + m_mTree.insert( pair( nNodes - 1, cChild1)) ; + m_mTree.insert( pair( nNodes, cChild2)) ; Point3d ptVert1, ptVert2 ; PNTVECTOR vVert ; - m_mVert.insert( std::pair( nNodes - 1, vVert)) ; - m_mVert.insert( std::pair( nNodes, vVert)) ; - if ( ! m_mTree[nId].IsSplitVert()) - { + m_mVert.insert( pair( nNodes - 1, vVert)) ; + m_mVert.insert( pair( nNodes, vVert)) ; + if ( ! m_mTree[nId].IsSplitVert()) { // la cella figlio 1 è quella sopra Point3d ptBL( m_mTree[nId].GetBottomLeft().x, dSplitValue) ; m_mTree[m_mTree[nId].m_nChild1].SetBottomLeft( ptBL) ; @@ -521,7 +485,7 @@ Tree::Split( const int& nId, const double& dSplitValue) //---------------------------------------------------------------------------- bool -Tree::Split( const int& nId) +Tree::Split( int nId) { double dValue ; if ( m_mTree[nId].IsSplitVert()) @@ -533,14 +497,12 @@ Tree::Split( const int& nId) //---------------------------------------------------------------------------- bool -Tree::BuildTree_test( const double& dLinTol, const double& dSideMin, const double& dSideMax) +Tree::BuildTree_test( double dLinTol, double dSideMin, double dSideMax) { // per poter usare questa funzione, anziché quella normale, bisogna: // - commentare la parte di funzione di SetSurf dove si fanno gli split preliminare // - se si usa anche la funzione GetLeaves, bisogna anche lì usare BuildTree_test al posto di BuildTree - - //int nCToSplit = -1 ; //celle 0,1 m_mTree[-1].SetSplitDirVert( true) ; Split( -1) ; @@ -592,13 +554,15 @@ Tree::BuildTree_test( const double& dLinTol, const double& dSideMin, const doubl Split( 10) ; m_vnLeaves.push_back( 20) ; m_vnLeaves.push_back( 21) ; + // riempio anche la lista dei parent delle celle + m_vnParents = m_vnLeaves ; return true ; } //---------------------------------------------------------------------------- bool -Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dSideMax) +Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) { // suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri int nCToSplit = -1 ; @@ -645,7 +609,7 @@ Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dS DistPointCurve dpc( ptPSrf, clV) ; double dDist ; dpc.GetDist( dDist) ; - dCurvV = std::max( dCurvV, dDist) ; + dCurvV = max( dCurvV, dDist) ; } dStep = 1. / ( m_nDegV * 2) ; for ( double k = dStep ; k < 1 + EPS_SMALL ; k = k + dStep) { @@ -662,7 +626,7 @@ Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dS DistPointCurve dpc( ptPSrf, clU) ; double dDist ; dpc.GetDist( dDist) ; - dCurvU = std::max( dCurvU, dDist) ; + dCurvU = max( dCurvU, dDist) ; } } @@ -708,18 +672,18 @@ Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dS double dSideMinVal = 0, dSideMaxVal = 0 ; if ( bVert) { if ( dLen0 > EPS_ZERO && dLen2 > EPS_ZERO) - dSideMinVal = std::min( dLen0, dLen2) ; + dSideMinVal = min( dLen0, dLen2) ; else - dSideMinVal = std::max( dLen0, dLen2) ; + dSideMinVal = max( dLen0, dLen2) ; } else { if ( dLen1 > EPS_ZERO && dLen3 > EPS_ZERO) - dSideMinVal = std::min( dLen1, dLen3) ; + dSideMinVal = min( dLen1, dLen3) ; else - dSideMinVal = std::max( dLen1, dLen3) ; + dSideMinVal = max( dLen1, dLen3) ; } // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella - dSideMaxVal = std::max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; + dSideMaxVal = max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; // se la cella è abbastanza grande da poter essere divisa ancora, calcolo l'errore di approssimazione bool bSplit = false ; @@ -854,12 +818,7 @@ Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dS double dDistU = 0, dDistV = 0 ; PNTVECTOR vPtU, vPtV ; if ( ! m_bMulti) { - if ( std::max( dLen0, dLen2) > std::max( dLen1, dLen3)) { - bVert = true ; - } - else { - bVert = false ; - } + bVert = ( max( dLen0, dLen2) > max( dLen1, dLen3)) ; } else { for ( double i = 0.25 ; i < 1 ; i = i + 0.25) { @@ -888,23 +847,10 @@ Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dS } } - // verifico che la cella sia abbastanza grande da poter essere splittata - double dSideMinVal = 0, dSideMaxVal = 0 ; - if ( bVert) { - if ( dLen0 != 0 && dLen2 != 0) - dSideMinVal = std::max( dLen0, dLen2) ; - else - dSideMinVal = std::max( dLen0, dLen2) ; - } - else { - if ( dLen1 != 0 && dLen3 != 0) - dSideMinVal = std::max( dLen1, dLen3) ; - else - dSideMinVal = std::max( dLen1, dLen3) ; - } - // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella - dSideMaxVal = std::max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; - + // verifico che la cella sia abbastanza grande da poter essere splittata + double dSideMinVal = ( bVert ? max( dLen0, dLen2) : max( dLen1, dLen3)) ; + // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella + double dSideMaxVal = max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; double dErr = 0 ; if ( m_bMulti) { @@ -923,7 +869,7 @@ Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dS double dU = ( ( 1 - i) * m_mTree[nCToSplit].GetTopRight().x + i * m_mTree[nCToSplit].GetBottomLeft().x) / SBZ_TREG_COEFF ; double dV = ( ( 1 - j) * m_mTree[nCToSplit].GetTopRight().y + j * m_mTree[nCToSplit].GetBottomLeft().y) / SBZ_TREG_COEFF ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - dErr = std::max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; + dErr = max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; } } } @@ -983,9 +929,9 @@ Tree::Balance() //---------------------------------------------------------------------------- void -Tree::GetTopNeigh( const int& nId, INTVECTOR& vTopNeighs) const +Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const { - if ( (int) vTopNeighs.size() == 0) { + if ( vTopNeighs.empty()) { if ( m_mTree.at( nId).m_nTop == -2) return ; if ( m_mTree.at( m_mTree.at( nId).m_nTop).IsLeaf()) @@ -999,9 +945,9 @@ Tree::GetTopNeigh( const int& nId, INTVECTOR& vTopNeighs) const vTopNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà - else{ - if ( m_mTree.at( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild1).GetTopRight().x <= m_mTree.at( nId).GetBottomLeft().x || - m_mTree.at( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild1).GetBottomLeft().x >= m_mTree.at( nId).GetTopRight().x ) + else { + if ( m_mTree.at( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild1).GetTopRight().x <= m_mTree.at( nId).GetBottomLeft().x || + m_mTree.at( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild1).GetBottomLeft().x >= m_mTree.at( nId).GetTopRight().x ) vTopNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild2) ; else vTopNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild1) ; @@ -1051,10 +997,10 @@ Tree::GetTopNeigh( const int& nId, INTVECTOR& vTopNeighs) const } } } - std::vector vCells ; + vector vCells ; for ( int k : vTopNeighs) vCells.push_back( m_mTree.at( k)) ; - std::sort( vCells.begin(), vCells.end(), Cell::minorX) ; + sort( vCells.begin(), vCells.end(), Cell::minorX) ; vTopNeighs.clear() ; for ( Cell c : vCells) vTopNeighs.push_back( c.m_nId) ; @@ -1063,9 +1009,9 @@ Tree::GetTopNeigh( const int& nId, INTVECTOR& vTopNeighs) const //---------------------------------------------------------------------------- void -Tree::GetBottomNeigh( const int& nId, INTVECTOR& vBottomNeighs) const +Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const { - if ( (int) vBottomNeighs.size() == 0) { + if ( vBottomNeighs.empty()) { if ( m_mTree.at( nId).m_nBottom == -2) return ; if ( m_mTree.at( m_mTree.at( nId).m_nBottom).IsLeaf()) @@ -1101,7 +1047,7 @@ Tree::GetBottomNeigh( const int& nId, INTVECTOR& vBottomNeighs) const GetBottomNeigh( nId, vBottomNeighs) ; } else { - for ( int j = 0 ; j != (int) vBottomNeighs.size() ; ++ j) { + for ( int j = 0 ; j < int( vBottomNeighs.size()) ; ++ j) { int i = vBottomNeighs.at( j) ; if ( m_mTree.at( i).IsLeaf()) continue ; @@ -1131,21 +1077,20 @@ Tree::GetBottomNeigh( const int& nId, INTVECTOR& vBottomNeighs) const } } } - std::vector vCells ; + vector vCells ; for ( int k : vBottomNeighs) vCells.push_back( m_mTree.at( k)) ; - std::sort( vCells.begin(), vCells.end(), Cell::minorX) ; + sort( vCells.begin(), vCells.end(), Cell::minorX) ; vBottomNeighs.clear() ; for ( Cell c : vCells) vBottomNeighs.push_back( c.m_nId) ; } - //---------------------------------------------------------------------------- void -Tree::GetLeftNeigh( const int& nId, INTVECTOR& vLeftNeighs) const +Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const { - if ( (int) vLeftNeighs.size() == 0) { + if ( vLeftNeighs.empty()) { if ( m_mTree.at( nId).m_nLeft == -2) return ; if ( m_mTree.at( m_mTree.at( nId).m_nLeft).IsLeaf()) @@ -1181,7 +1126,7 @@ Tree::GetLeftNeigh( const int& nId, INTVECTOR& vLeftNeighs) const GetLeftNeigh( nId, vLeftNeighs) ; } else { - for ( int j = 0 ; j != (int) vLeftNeighs.size() ; ++ j) { + for (int j = 0 ; j < int( vLeftNeighs.size()) ; ++ j) { int i = vLeftNeighs.at( j) ; if ( m_mTree.at( i).IsLeaf()) continue ; @@ -1211,10 +1156,10 @@ Tree::GetLeftNeigh( const int& nId, INTVECTOR& vLeftNeighs) const } } } - std::vector vCells ; + vector vCells ; for ( int k : vLeftNeighs) vCells.push_back( m_mTree.at( k)) ; - std::sort( vCells.begin(), vCells.end(), Cell::minorY) ; + sort( vCells.begin(), vCells.end(), Cell::minorY) ; vLeftNeighs.clear() ; for ( Cell c : vCells) vLeftNeighs.push_back( c.m_nId) ; @@ -1222,9 +1167,9 @@ Tree::GetLeftNeigh( const int& nId, INTVECTOR& vLeftNeighs) const //---------------------------------------------------------------------------- void -Tree::GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const +Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const { - if ( (int) vRightNeighs.size() == 0) { + if ( vRightNeighs.empty()) { if ( m_mTree.at( nId).m_nRight == -2) return ; if ( m_mTree.at( m_mTree.at( nId).m_nRight).IsLeaf()) @@ -1260,7 +1205,7 @@ Tree::GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const GetRightNeigh( nId, vRightNeighs) ; } else { - for ( int j = 0 ; j != (int) vRightNeighs.size() ; ++ j) { + for (int j = 0 ; j < int( vRightNeighs.size()) ; ++ j) { int i = vRightNeighs.at( j) ; if ( m_mTree.at( i).IsLeaf()) continue ; @@ -1290,10 +1235,10 @@ Tree::GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const } } } - std::vector vCells ; + vector vCells ; for ( int k : vRightNeighs) vCells.push_back( m_mTree.at( k)) ; - std::sort( vCells.begin(), vCells.end(), Cell::minorY) ; + sort( vCells.begin(), vCells.end(), Cell::minorY) ; vRightNeighs.clear() ; for ( Cell c : vCells) vRightNeighs.push_back( c.m_nId) ; @@ -1301,7 +1246,7 @@ Tree::GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const //---------------------------------------------------------------------------- void -Tree::GetRootNeigh( const int& nEdge, INTVECTOR& vNeigh) +Tree::GetRootNeigh( int nEdge, INTVECTOR& vNeigh) { int nId = -1 ; bool bMod = false ; @@ -1345,14 +1290,14 @@ Tree::GetRootNeigh( const int& nEdge, INTVECTOR& vNeigh) //---------------------------------------------------------------------------- int -Tree::GetHeightLeaves( const int& nId, INTVECTOR& vnLeaves, int d) const +Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d) const { if ( nId == -1 && m_mTree.at( -1).IsLeaf()) { vnLeaves.push_back( -1) ; return 0 ; } else { - if ( (int) vnLeaves.size() == 0) { + if ( vnLeaves.empty()) { if ( m_mTree.at( nId).IsLeaf()) return d ; else { @@ -1364,7 +1309,7 @@ Tree::GetHeightLeaves( const int& nId, INTVECTOR& vnLeaves, int d) const } } else { - for ( int j = 0 ; j != (int) vnLeaves.size() ; ++ j) { + for ( int j = 0 ; j < int( vnLeaves.size()) ; ++ j) { int i = vnLeaves.at( j) ; if ( m_mTree.at( i).IsLeaf()) { continue ; @@ -1375,38 +1320,42 @@ Tree::GetHeightLeaves( const int& nId, INTVECTOR& vnLeaves, int d) const -- j ; vnLeaves.push_back( m_mTree.at( i).m_nChild1) ; vnLeaves.push_back( m_mTree.at( i).m_nChild2) ; - d = std::max ( d, m_mTree.at( m_mTree.at( i).m_nChild1).m_nDepth) ; + d = max( d, m_mTree.at( m_mTree.at( i).m_nChild1).m_nDepth) ; } } return d ; } - return d - m_mTree.at( nId).m_nDepth ; + return ( d - m_mTree.at( nId).m_nDepth) ; } } //---------------------------------------------------------------------------- int -Tree::GetDepth( const int& nId, const int& nRef = -2) const +Tree::GetDepth( int nId, int nRef = -2) const { - int c = 0 ; + int i = 0 ; int nCell = nId ; while ( m_mTree.at( nCell).m_nParent != nRef) { nCell = m_mTree.at( nCell).m_nParent ; - ++ c ; + ++ i ; } - return c ; + return i ; } +//---------------------------------------------------------------------------- struct generator { int value ; - generator() { value = -1 ;} - int operator() () { return ++value ; } + generator( void) + { value = -1 ; } + int operator() () + { return ++value ; } } ; //---------------------------------------------------------------------------- bool -Tree::GetPolygons( std::vector& vPolygons) { +Tree::GetPolygons( POLYLINEMATRIX& vPolygons) +{ if ( (int) m_vPolygons.size() == 0) { if ( ! m_bTrimmed) { vPolygons.clear() ; @@ -1419,16 +1368,15 @@ Tree::GetPolygons( std::vector& vPolygons) { } return true ; } - // trimmata + // trimmata else { POLYLINEVECTOR vPolygonsBasic ; GetPolygonsBasic( vPolygonsBasic) ; if ( ! TraceLoopLabelCell( vPolygonsBasic)) return false ; // scorro sulle celle e costruisco i poligoni - int nCells = (int)vPolygonsBasic.size() ; - for ( int i = 0 ; i < nCells ; ++i) { - + int nCells = int( vPolygonsBasic.size()) ; + for ( int i = 0 ; i < nCells ; ++ i) { // costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps int nId = m_vnLeaves[i] ; if ( m_mTree[nId].m_nFlag == 4) { @@ -1444,7 +1392,7 @@ Tree::GetPolygons( std::vector& vPolygons) { INTVECTOR vnParentChunk ; // vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ; - std::generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ; + generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ; // numero di poligoni aggiunti int nPoly = 0 ; // scorro sui vettori intersezione della cella nId e sui suoi vertici @@ -1541,12 +1489,12 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons) vNeigh.clear() ; vVertices.push_back( m_mTree.at( nId).GetTopRight()) ; GetTopNeigh ( nId, vNeigh) ; - std::reverse( vNeigh.begin(), vNeigh.end()) ; + reverse( vNeigh.begin(), vNeigh.end()) ; // aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top - if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { - // se la superficie è chiusa lungo il parametro U e la cella è sul lato top + if ( ! vNeigh.empty() && vNeigh.size() != 1) { + // se la superficie è chiusa lungo il parametro V e la cella è sul lato top // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. - if ( m_bClosedU && m_mTree.at( nId).m_bOnTopEdge) { + if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; vVertices.push_back( pt) ; @@ -1562,7 +1510,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons) bTopLeft = false ; vNeigh.clear() ; GetLeftNeigh ( nId, vNeigh) ; - std::reverse( vNeigh.begin(), vNeigh.end()) ; + reverse( vNeigh.begin(), vNeigh.end()) ; // aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { // se la superficie è chiusa lungo il parametro U e la cella è sul lato left @@ -1638,12 +1586,13 @@ Tree::ResetTree( void) //---------------------------------------------------------------------------- INTVECTOR -Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const +Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs) const { INTVECTOR nCells ; int nId = -1 ; // se fallisce ritorna un vettore vuoto // verifico che il punto sia all'interno dello spazio parametrico + // allargo i bordi in modo da tenere anche i punti sul bordo dello spazio parametrico if ( ptToAssign.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptToAssign.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL|| ptToAssign.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptToAssign.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) { //nCells.push_back( - 2) ; @@ -1652,15 +1601,21 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const // se ho diviso preliminarmente le patches e in uno dei due parametri ho un numero dispari di patches devo individuare a mano la cella parent // in cui individuare la foglia giusta - if ( m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) { + if ( (m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) || m_bTestMode) { INTVECTOR nParents = FindCell( ptToAssign, clTrim, m_vnParents) ; + if ( nParents.empty()) + return nCells ; nId = nParents.back() ; + if ( m_bTestMode ) { + nCells.push_back(nId) ; + return nCells ; + } } // individuo la foglia in cui ho lo start del loop while ( ! m_mTree.at( nId).IsLeaf()) { if ( m_mTree.at( nId).IsSplitVert()) { double dMid = ( m_mTree.at( nId).GetBottomLeft().x + m_mTree.at( nId).GetTopRight().x) / 2 ; - if ( ptToAssign.x < dMid + EPS_SMALL) { + if ( ptToAssign.x < dMid) { nId = m_mTree.at( nId).m_nChild1 ; } else { @@ -1669,7 +1624,7 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const } else { double dMid = ( m_mTree.at( nId).GetBottomLeft().y + m_mTree.at( nId).GetTopRight().y) / 2 ; - if ( ptToAssign.y < dMid + EPS_SMALL) { + if ( ptToAssign.y < dMid) { nId = m_mTree.at( nId).m_nChild2 ; } else { @@ -1679,26 +1634,37 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const } nCells.push_back( nId) ; - - // se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta - Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; - Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ; - if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL || - abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) - { - Point3d ptToAssignPlus ; - double dParam ; - Vector3d vDir ; - clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; - clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vDir) ; - if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) { - vDir.Rotate( Z_AX, -90) ; - ptToAssignPlus = ptToAssignPlus + vDir * 2 * EPS_SMALL ; - } - nCells = FindCell( ptToAssignPlus, clTrim) ; - if ( nCells.empty()) { - ptToAssignPlus = ptToAssignPlus - 4 * vDir * EPS_SMALL ; - nCells = FindCell( ptToAssignPlus, clTrim) ; + if ( ! bRecurs) { + // se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta + Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; + Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ; + if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL || + abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) + { + Vector3d vtDir ; + clTrim.GetStartDir( vtDir) ; + // proseguo lungo la curva di trim di EPS_SMALL + Point3d ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ; + // se la curva di trim è praticamente parallela ad un lato allora giro a destra, perché voglio considerare intersecate le celle esterne ( sul bordo) al loop + if ( abs( vtDir.x) > 1 - EPS_SMALL || abs( vtDir.y) > 1 - EPS_SMALL) { + Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, 90) ; + ptToAssignPlus = ptToAssignPlus + vtDir * EPS_SMALL ; + // controllo di non essere uscito dallo spazio parametrico ed eventualmente giro a sinistra + if ( ptToAssignPlus.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptToAssignPlus.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL|| + ptToAssignPlus.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptToAssignPlus.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) { + // rispetto al punto di partenza avanzo lungo la curva di trim + ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ; + Vector3d vtDirSX = vtDir ; vtDirSX.Rotate( Z_AX, -90) ; + // e poi giro a sinistra + ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ; + } + } + INTVECTOR nCellsSave = nCells ; + nCells = FindCell( ptToAssignPlus, clTrim, true) ; + if ( nCells.empty()) { + // se nonostante tutto non trovo nulla allora tengo il risultato ottenuto scorrendo l'albero + nCells = nCellsSave ; + } } } return nCells ; @@ -1706,27 +1672,107 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const //---------------------------------------------------------------------------- INTVECTOR -Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const +Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs) const { // se non trova nulla restituisce un vettore vuoto // restituisce sempre solo una cella - // la CurveLine è il segmento di trim su cui giace ptToAssign - Point3d ptIntersPlus ; - double dParam ; - Vector3d vDir ; - cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; - // mi sposto appena più avanti di ptToAssign - cl.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptIntersPlus, vDir) ; + // questo punto va trovato con precisione, perché se seleziono la cella sbagliata si incasina tutto INTVECTOR nCells ; int nId = -1 ; for ( int nCell : vCells) { - if ( ptIntersPlus.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptIntersPlus.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO && - ptIntersPlus.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptIntersPlus.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) { + if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x && + ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y) { nId = nCell ; nCells.push_back( nId) ; } } + // se non ho trovato nulla vuol dire che sono su un vertice o su un lato + if ( (int)nCells.size() == 0 && ! bRecurs) { + int nEdge = -1 ; + for ( int nCell : vCells) { + OnWhichEdge( nCell,ptToAssign, nEdge) ; + if ( nEdge != -1) + break ; + } + Vector3d vtDir ; + cl.GetStartDir( vtDir) ; + Point3d ptIntersPlus = ptToAssign ; + // N.B. DESTRA e SINISTRA SONO SEMPRE RIFERITE al guardare nella direzione del vettore di partenza della curva di trim + // potrei essere su un lato + if ( nEdge == 0 || nEdge == 1 || nEdge == 2 || nEdge == 3) { + // se è orientato con il lato mi sposto a destra + if ( ( nEdge == 0 || nEdge == 2 ) && abs(vtDir.x) > 1 - EPS_SMALL ) { + Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ; + ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ; + } + else if ( (nEdge == 0 || nEdge == 2) && abs(vtDir.y) > EPS_SMALL) + ptIntersPlus.y += (vtDir.y > 0 ? 1 : -1) * EPS_SMALL ; + else if ( ( nEdge == 1 || nEdge == 3 ) && abs(vtDir.y) > 1 - EPS_SMALL ) { + Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ; + ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ; + } + else if ( (nEdge == 1 || nEdge == 3) && abs(vtDir.x) > EPS_SMALL) + ptIntersPlus.x += (vtDir.x > 0 ? 1 : -1) * EPS_SMALL ; + } + // o in un vertice + else if ( nEdge == 4 || nEdge == 5 || nEdge == 6 || nEdge == 7) { + // se non è orientato con gli assi procedo con la direzione del trim + if ( abs(vtDir.x) < 1 - EPS_SMALL && abs(vtDir.y) < 1 - EPS_SMALL ) + ptIntersPlus = ptIntersPlus + vtDir * EPS_SMALL ; + // altrimenti ruoto a destra + else { + Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -45) ; + ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ; + } + } + // + else + return nCells ; + // controllo di non essere uscito dallo spazio parametrico (in tal caso riparto da ptToAssign e mi muovo a sinistra) + if ( ptIntersPlus.x < m_mTree.at( -1).GetBottomLeft().x || ptIntersPlus.x > m_mTree.at( -1).GetTopRight().x || + ptIntersPlus.y < m_mTree.at( -1).GetBottomLeft().y || ptIntersPlus.y > m_mTree.at( -1).GetTopRight().y) { + Vector3d vtDirSX = vtDir ; vtDirSX.Rotate(Z_AX, 45) ; + ptIntersPlus = ptToAssign + vtDirSX * EPS_SMALL ; + } + // rilancio la rigida ricerca + nCells = FindCell( ptIntersPlus, cl, vCells, true) ; + + /////////////////////////// questa versione funziona, ma forse potrebbe fallire in alcuni casi/// + // for ( int nCell : vCells) { + // if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_SMALL && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_SMALL && + // ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_SMALL && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_SMALL) { + // nId = nCell ; + // nCells.push_back( nId) ; + // } + // } + // if ( (int)nCells.size() == 1) + // return nCells ; + // // sono su vertice o un lato, quindi avanzo con il parametro lungo la curva + // else if ( (int)nCells.size() > 1 ) { + // // la CurveLine è il segmento di trim su cui giace ptToAssign + // Point3d ptIntersPlus ; + // Vector3d vtDir ; + // cl.GetStartDir( vtDir) ; + // // mi sposto appena più avanti di ptToAssign + // // se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore a destra prima di spostarmi + // if ( abs( vtDir.x) >= 1 - EPS_SMALL || abs( vtDir.y) >= 1 - EPS_SMALL) + // vtDir.Rotate( Z_AX, -45) ; + // ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ; + // // se sono finito fuori dallo spazio parametrico giro invece a sinistra + // if ( ptIntersPlus.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptIntersPlus.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL|| + // ptIntersPlus.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptIntersPlus.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) { + // vtDir.Rotate( Z_AX, 90) ; + // ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ; + // } + // nCells = FindCell( ptIntersPlus, cl, vCells) ; + // } + //// se vuoto allora il punto non è in nessuna delle celle passate in input + // else + // return nCells ; + ////////////////////////////////////////////////////////////////////////// + } + return nCells ; } @@ -1741,16 +1787,16 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) double dLinTol = - EPS_SMALL ; // percorro i loop trovando le interezioni con le celle e riempiendo i vettori m_vInters delle varie celle for ( int i = 0 ; i < (int) m_vPlApprox.size() ; ++ i) { - PolyLine plLoop = std::get<0>(m_vPlApprox[i]) ; + PolyLine plLoop = get<0>( m_vPlApprox[i]) ; // controllo se il loop è CCW o CW - bool bCCW = std::get<1>(m_vPlApprox[i]) ; + bool bCCW = get<1>( m_vPlApprox[i]) ; // trovo in quale cella è il ptStart Point3d ptStart ; plLoop.GetFirstPoint( ptStart) ; PNTULIST lPt = plLoop.GetUPointList() ; PNTULIST:: iterator ptFirst = lPt.begin() ; PNTULIST:: iterator ptSecond = ptFirst ; - std::advance( ptSecond, 1) ; + advance( ptSecond, 1) ; CurveLine clFirst ; clFirst.Set( ptFirst->first, ptSecond->first) ; // individuo la cella da cui parte il loop @@ -1759,8 +1805,9 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) if ( ! nCells.empty()) nId = nCells.back() ; else - // il loop è fuori dalla cella root che sto analizzando - continue ; + // il loop è risultato fuori dallo spazio parametrico // può capitare se ho una superficie trimmata con più chunk con bbox separate. + // ma potrebbe anche essere indicatore di un errore + continue ; int nFirstCell = nId ; // trovo quali punti della polyline sono nella cella e l'intersezione PNTVECTOR vptInters ; @@ -1776,8 +1823,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) m_mTree[nId].m_vInters.back().nChunk = m_mChunk[i] ; bool bLoopInside = true ; Point3d ptCurr ; - INTVECTOR :: iterator iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; - int nIdPolygon = std::distance( m_vnLeaves.begin(), iter) ; + auto iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; + int nIdPolygon = distance( m_vnLeaves.begin(), iter) ; bool bEraseNextPoint = false ; while ( plLoop.GetNextPoint( ptCurr)) { Point3d ptTStart, ptTEnd ; @@ -1786,7 +1833,7 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) CurveLine clTrim ; clTrim.Set( ptTStart, ptTEnd) ; // qui devo mettere una tolleranza negativa per poter tener conto anche dei punti che sono SULLA curva - while( ! IsPointInsidePolyLine( ptCurr, vplPolygons[nIdPolygon], dLinTol)) { + while ( ! IsPointInsidePolyLine( ptCurr, vplPolygons[nIdPolygon], dLinTol)) { // sto uscendo dalla cella, quindi cerco l'intersezione if ( bEraseNextPoint) { vptInters.pop_back() ; @@ -1811,7 +1858,7 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) } // ricalcolo la posizione di nId nel vettore delle foglie iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; - nIdPolygon = std::distance( m_vnLeaves.begin(), iter) ; + nIdPolygon = distance( m_vnLeaves.begin(), iter) ; // salvo il verso del loop m_mTree[nId].m_vInters.back().bCCW = bCCW ; // salvo il chunk del loop @@ -1842,10 +1889,12 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ; //sistemo l'ingresso della prima cella int nEdge ; - OnWhichEdge( nFirstCell, ptFirst, nEdge) ; + if ( ! OnWhichEdge( nFirstCell, ptFirst, nEdge)) + return false ; m_mTree[nFirstCell].m_vInters[nPass].nIn = nEdge ; // sistemo l'uscita dell'ultima cella - OnWhichEdge( nId, ptLast, nEdge) ; + if ( ! OnWhichEdge( nId, ptLast, nEdge)) + return false ; m_mTree[nId].m_vInters.back().nOut = nEdge ; // sistemo il flag dell'ultima cella if ( m_mTree[nId].m_nFlag == -1) @@ -1869,7 +1918,7 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) // riordino i vettori di intersezione per ogni cella e setto il flag RightEdgeIn for ( int nId : m_vnLeaves) { - std::sort( m_mTree[nId].m_vInters.begin(), m_mTree[nId].m_vInters.end()) ; + sort( m_mTree[nId].m_vInters.begin(), m_mTree[nId].m_vInters.end()) ; SetRightEdgeIn( nId) ; } @@ -2028,28 +2077,17 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool int nEdge ; // flag che indica il lato su cui ho l'intersezione a partire dal lato top in senso antiorario // oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario // -1 se la curva è sempre dentro la cella - bool bIntersFound = false ; Point3d ptInters ; - int nEdge2 ; + //int nEdge2 ; if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) { - nEdge = 0 ; + //nEdge = 0 ; // lato sopra clEdge.Set( ptTR, ptTl) ; // lato sinistro if ( ptEnd.x < ptBL.x) { - nEdge2 = 1 ; + //nEdge2 = 1 ; clEdge2.Set( ptTl, ptBL) ; } - //else if ( AreSamePointExact( ptEnd, ptTl) && bFirstInters) { - // nEdge = 4 ; - // ptInters = ptTl ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptTR) && bFirstInters) { - // nEdge = 7 ; - // ptInters = ptTR ; - // bIntersFound = true ; - //} } else if ( ptEnd.x <= ptBL.x && ptEnd.y <= ptTR.y) { nEdge = 1 ; @@ -2057,19 +2095,9 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool clEdge.Set( ptTl, ptBL) ; // lato sotto if ( ptEnd.y < ptBL.y) { - nEdge2 = 2 ; + //nEdge2 = 2 ; clEdge2.Set( ptBL, ptBr) ; } - //else if ( AreSamePointExact( ptEnd, ptBL) && bFirstInters) { - // nEdge = 5 ; - // ptInters = ptBL ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptTl) && bFirstInters) { - // nEdge = 4 ; - // ptInters = ptTl ; - // bIntersFound = true ; - //} } else if ( ptEnd.y <= ptBL.y && ptEnd.x >= ptBL.x) { nEdge = 2 ; @@ -2077,19 +2105,9 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool clEdge.Set( ptBL, ptBr) ; // lato destro if ( ptEnd.x > ptTR.x) { - nEdge2 = 3 ; + //nEdge2 = 3 ; clEdge2.Set( ptBr, ptTR) ; } - //else if ( AreSamePointExact( ptEnd, ptBr) && bFirstInters) { - // nEdge = 6 ; - // ptInters = ptBr ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptBL) && bFirstInters) { - // nEdge = 5 ; - // ptInters = ptBL ; - // bIntersFound = true ; - //} } else if ( ptEnd.x >= ptTR.x && ptEnd.y >= ptBL.y) { nEdge = 3 ; @@ -2097,71 +2115,75 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool clEdge.Set( ptBr, ptTR) ; // lato sopra if ( ptEnd.y > ptTR.y) { - nEdge2 = 0 ; + //nEdge2 = 0 ; clEdge2.Set( ptTR, ptTl) ; } - //else if ( AreSamePointExact( ptEnd, ptTR) && bFirstInters) { - // nEdge = 7 ; - // ptInters = ptTR ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptBr) && bFirstInters) { - // nEdge = 6 ; - // ptInters = ptBr ; - // bIntersFound = true ; - //} } else return false ; - bool bIntersOn2Found = false ; - if ( ! bIntersFound) { - // intersezione e controlli - IntersLineLine illExit( clTrim, clEdge, true) ; - IntCrvCrvInfo aInfo, aInfo2 ; - bool bIntersOn1Found = true ; - if ( ! illExit.GetIntCrvCrvInfo( aInfo)) { - bIntersOn1Found = false ; - if ( ! clEdge2.IsValid()) - return false ; - } - else if ( aInfo.bOverlap && ! bFirstInters) { - ptInters = aInfo.IciA[1].ptI ; - bIntersFound = true ; - } - if ( clEdge2.IsValid() && ! bIntersFound){ - IntersLineLine illExit2( clTrim, clEdge2, true) ; - // verifico su quale dei due lati ho l'intersezione - if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)){ - if ( bIntersOn1Found) { - // se ho intersezione su Edge1 con sovrapposizione, seleziono o il primo punto o il secondo. - if ( aInfo.bOverlap && ! bFirstInters) - ptInters = aInfo.IciA[1].ptI ; - else - ptInters = aInfo.IciA[0].ptI ; - } - else - return false ; - } - else { - //// solo intersezione sul lato 2 - bIntersOn2Found = true ; - if ( aInfo2.bOverlap && ! bFirstInters) - ptInters = aInfo2.IciA[1].ptI ; - else - ptInters = aInfo2.IciA[0].ptI ; - } - } - else - ptInters = aInfo.IciA[0].ptI ; // qui devo mettere il controllo su prima o seconda intersezione? + bool bIntersFound = false ; + // intersezione e controlli + IntersLineLine illExit( clTrim, clEdge, true) ; + IntCrvCrvInfo aInfo, aInfo2 ; + if ( ! illExit.GetIntCrvCrvInfo( aInfo)) { + bIntersFound = false ; + if ( ! clEdge2.IsValid()) + return false ; } - if ( ! bIntersOn2Found) - OnWhichEdge( nId, ptInters, nEdge) ; - else - nEdge = nEdge2 ; + else { + bIntersFound = true ; + if ( aInfo.bOverlap) + ptInters = aInfo.IciA[1].ptI ; + else + ptInters = aInfo.IciA[0].ptI ; + } + if ( clEdge2.IsValid() && ! bIntersFound){ + IntersLineLine illExit2( clTrim, clEdge2, true) ; + // verifico su quale dei due lati ho l'intersezione + if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)) + bIntersFound = false ; + else { + bIntersFound = true ; + //// solo intersezione sul lato 2 + if ( aInfo2.bOverlap) + ptInters = aInfo2.IciA[1].ptI ; + else + ptInters = aInfo2.IciA[0].ptI ; + } + } + if ( ! bIntersFound) + return false ; + // determino il lato/vertice di uscita + OnWhichEdge( nId, ptInters, nEdge) ; m_mTree[nId].m_vInters.back().nOut = nEdge ; - if ( (int)vptInters.size() == 0 || ! AreSamePointExact( ptInters , vptInters.back())) + // se è risultato che sono abbastanza vicino( di EPS_SMALL) ad un vertice allora il punto aggiunto sarà il vertice vero e proprio + // se è abbastanza vicino ad un lato allora modifico le sue coordinate in modo che sia esattamente sul lato + if ( nEdge == 0) + ptInters.y = ptTl.y ; + else if ( nEdge == 1) + ptInters.x = ptTl.x ; + else if ( nEdge == 2) + ptInters.y = ptBL.y ; + else if ( nEdge == 3) + ptInters.x = ptTR.x ; + else if ( nEdge == 4) + ptInters = ptTl ; + else if ( nEdge == 5) + ptInters = ptBL ; + else if ( nEdge == 6) + ptInters = ptBr ; + else if ( nEdge == 7) + ptInters = ptTR ; + // aggiungo il nuovo punto al vettore delle intersezioni + if ( (int)vptInters.size() == 0 || ! AreSamePointApprox( ptInters , vptInters.back())) vptInters.push_back( ptInters) ; + else { + // se l'ultimo punto del vettore delle intersezioni è quasi uguale al punto che devo aggiungere allora lo sostituisco con quest'ultimo + vptInters.pop_back() ; + vptInters.push_back( ptInters) ; + } + // salvo il vettore intersezione per la cella e capisco in quale altra cella passare if ( (int)vptInters.size() == 1) m_mTree[nId].m_vInters.back().vpt.push_back( vptInters[0]) ; @@ -2181,7 +2203,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool INTVECTOR vNeigh, vNeigh1 ; if ( nEdge == 0) { GetTopNeigh( nId, vNeigh) ; - std::reverse( vNeigh.begin(), vNeigh.end()) ; + reverse( vNeigh.begin(), vNeigh.end()) ; for ( int j : vNeigh) { if ( ptInters.x >= m_mTree[j].GetBottomLeft().x) { nId = j ; @@ -2201,7 +2223,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool } else if ( nEdge == 1) { GetLeftNeigh( nId, vNeigh) ; - std::reverse( vNeigh.begin(), vNeigh.end()) ; + reverse( vNeigh.begin(), vNeigh.end()) ; for ( int j : vNeigh) { if ( ptInters.y >= m_mTree[j].GetBottomLeft().y) { nId = j ; @@ -2300,11 +2322,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 6 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1.back() ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 7 ; } + else + return false ; } } else if ( nEdge == 5) { @@ -2349,11 +2373,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 7 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1[0] ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 4 ; } + else + return false ; } } else if ( nEdge == 6) { @@ -2398,11 +2424,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 4 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1[0] ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 5 ; } + else + return false ; } } else if ( nEdge == 7) { @@ -2447,11 +2475,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 5 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1.back() ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 6 ; } + else + return false ; } } // aggiungo l'intersezione al vettore delle intersezioni della prossima cella @@ -2461,11 +2491,11 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool //---------------------------------------------------------------------------- bool -Tree::CreateCellPolygons( const int& nLeafId, std::vector& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) +Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) { // conto quanti vertici in più ho per lato e creo un vettore dei vertici per lato int nId = m_vnLeaves[nLeafId] ; - std::vector vEdgeVertex ; + PNTMATRIX vEdgeVertex ; Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; vEdgeVertex.emplace_back() ; @@ -2532,40 +2562,74 @@ Tree::CreateCellPolygons( const int& nLeafId, std::vector& vPoly Vector3d vLast = ptLast - ptSecondToLast ; vLast.Normalize() ; Vector3d vEdge ; - if ( AreSameEdge( nEdge, 0)) { - if ( AreSamePointExact( ptLast, ptTl)) { - vEdge = m_mTree[nId].GetBottomLeft() - ptTl ; - vEdge.Normalize() ; - if ( AreOppositeVectorApprox( vLast, vEdge)) { + //if ( AreSameEdge( nEdge, 0)) { + // if ( AreSamePointExact( ptLast, ptTl)) { + // vEdge = m_mTree[nId].GetBottomLeft() - ptTl ; + // vEdge.Normalize() ; + // if ( AreOppositeVectorApprox( vLast, vEdge)) { + // plTrimmedPoly.EraseLastUPoint() ; + // nEdge = 1 ; + // } + // } + //} + //else if ( AreSameEdge( nEdge, 1) && AreSamePointExact( ptLast, m_mTree[nId].GetBottomLeft())) { + // vEdge = ptBr - m_mTree[nId].GetBottomLeft() ; + // vEdge.Normalize() ; + // if ( AreOppositeVectorApprox( vLast, vEdge)) { + // plTrimmedPoly.EraseLastUPoint() ; + // nEdge = 2 ; + // } + //} + //else if ( AreSameEdge( nEdge, 2)) { + // if ( AreSamePointExact( ptLast, ptBr)) { + // vEdge = m_mTree[nId].GetTopRight() - ptBr ; + // vEdge.Normalize() ; + // if ( AreOppositeVectorApprox( vLast, vEdge)) { + // plTrimmedPoly.EraseLastUPoint() ; + // nEdge = 3 ; + // } + // } + //} + //else if ( AreSameEdge( nEdge, 3) && AreSamePointExact( ptLast, m_mTree[nId].GetTopRight())) { + // vEdge = ptTl - m_mTree[nId].GetTopRight() ; + // vEdge.Normalize() ; + // if ( AreOppositeVectorApprox( vLast, vEdge)) { + // plTrimmedPoly.EraseLastUPoint() ; + // nEdge = 0 ; + // } + //} + + // estendo: se l'ultimo tratto è sovrapposto e controverso allora elimino l'ultimo punto + if ( nEdge == 0 || nEdge == 7 ) { + //vEdge = ptTl - m_mTree[nId].GetTopRight() ; + vEdge.Set( 1,0,0) ; + if ( AreOppositeVectorApprox( vLast, vEdge)) { + plTrimmedPoly.EraseLastUPoint() ; + nEdge = 0 ; + } + } + else if ( nEdge == 1 || nEdge == 4 ) { + //vEdge = ptBr - m_mTree[nId].GetBottomLeft() ; + vEdge.Set( 0,-1,0) ; + if ( AreOppositeVectorApprox( vLast, vEdge)) { plTrimmedPoly.EraseLastUPoint() ; nEdge = 1 ; - } } } - else if ( AreSameEdge( nEdge, 1) && AreSamePointExact( ptLast, m_mTree[nId].GetBottomLeft())) { - vEdge = ptBr - m_mTree[nId].GetBottomLeft() ; - vEdge.Normalize() ; + else if ( nEdge == 2 || nEdge == 5 ) { + //vEdge = ptTl - m_mTree[nId].GetTopRight() ; + vEdge.Set( -1,0,0) ; if ( AreOppositeVectorApprox( vLast, vEdge)) { - plTrimmedPoly.EraseLastUPoint() ; - nEdge = 2 ; + plTrimmedPoly.EraseLastUPoint() ; + nEdge = 2 ; } } - else if ( AreSameEdge( nEdge, 2)) { - if ( AreSamePointExact( ptLast, ptBr)) { - vEdge = m_mTree[nId].GetTopRight() - ptBr ; - vEdge.Normalize() ; - if ( AreOppositeVectorApprox( vLast, vEdge)) { + else if ( nEdge == 3 || nEdge == 6 ) { + //vEdge = m_mTree[nId].GetTopRight() - ptBr ; + vEdge.Set( 0,1,0) ; + if ( AreOppositeVectorApprox( vLast, vEdge)) { plTrimmedPoly.EraseLastUPoint() ; nEdge = 3 ; - } - } - } - else if ( AreSameEdge( nEdge, 3) && AreSamePointExact( ptLast, m_mTree[nId].GetTopRight())) { - vEdge = ptTl - m_mTree[nId].GetTopRight() ; - vEdge.Normalize() ; - if ( AreOppositeVectorApprox( vLast, vEdge)) { - plTrimmedPoly.EraseLastUPoint() ; - nEdge = 0 ; } } @@ -2720,7 +2784,7 @@ Tree::CreateCellPolygons( const int& nLeafId, std::vector& vPoly //---------------------------------------------------------------------------- bool -Tree::CreateIslandAndHoles( const int& nLeafId, std::vector& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) +Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) { // vettore dei poligoni ( loop) della cella nId POLYLINEVECTOR vCellPolygons ; @@ -2829,7 +2893,7 @@ Tree::CreateIslandAndHoles( const int& nLeafId, std::vector& vPo //---------------------------------------------------------------------------- bool -Tree::CheckIfBefore( const PolyLine& pl, const int& nEdge) const +Tree::CheckIfBefore( const PolyLine& pl, int nEdge) const { // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario ( quindi se è dopo in senso orario) Point3d ptStart, ptEnd ; @@ -2854,22 +2918,22 @@ Tree::CheckIfBefore( const PolyLine& pl, const int& nEdge) const bool Tree::CheckIfBefore( const Inters& inA) const { - // questa funzione è pensata in riferimento al lato 3, quindi nessuno dei due punti può stare su Edge = 3 + // questa funzione è pensata in riferimento al lato 3, quindi nessuno dei due punti può stare su Edge = 3 ( funzione usata per definire RightEdgeIn) // controllo se l'ingresso è prima dell'uscita int nEdge1 = inA.nIn ; int nEdge2 = inA.nOut ; if ( nEdge1 == -1) - return false ; + return false ; // questo return è usato in modo improprio perché non fa capire che l'intersezione analizzata non era corretta PolyLine pl ; pl.AddUPoint( 0, inA.vpt.back()) ; pl.AddUPoint( 1, inA.vpt[0]) ; INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6} ; // controllo se nEdge1 viene prima di nEdge2. la partenza è da ptTR e l'arrivo è ptBr - INTVECTOR :: iterator iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ; - int nPos1 = std::distance( vEdges.begin(), iter1) ; - INTVECTOR :: iterator iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ; - int nPos2 = std::distance( vEdges.begin(), iter2) ; + auto iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ; + int nPos1 = distance( vEdges.begin(), iter1) ; + auto iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ; + int nPos2 = distance( vEdges.begin(), iter2) ; if ( nPos1 < nPos2) return true ; else if ( nPos1 > nPos2) @@ -2886,17 +2950,17 @@ Tree::CheckIfBefore( const Inters& inA) const //---------------------------------------------------------------------------- bool -Tree::CheckIfBefore( const int& nEdge1, const Point3d& ptP1, const int& nEdge2, const Point3d& ptP2) const +Tree::CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const { if ( nEdge1 == -1 || nEdge2 == -1) return false ; // questa funzione è pensata in riferimento al lato 3, quindi nessuno dei due punti può stare su Edge = 3 INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6} ; // controllo se ptP1, che è su nEdge1, viene prima di ptP2, che è su nEdge2. la partenza è da ptTR e l'arrivo è ptBr - INTVECTOR :: iterator iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ; - int nPos1 = std::distance( vEdges.begin(), iter1) ; - INTVECTOR :: iterator iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ; - int nPos2 = std::distance( vEdges.begin(), iter2) ; + auto iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ; + int nPos1 = distance( vEdges.begin(), iter1) ; + auto iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ; + int nPos2 = distance( vEdges.begin(), iter2) ; if ( nPos1 < nPos2) return true ; else if ( nPos1 > nPos2) @@ -2915,14 +2979,14 @@ Tree::CheckIfBefore( const int& nEdge1, const Point3d& ptP1, const int& nEdge2, //---------------------------------------------------------------------------- bool -Tree::CheckIfBefore( const int& nEdge, const Point3d& ptP1, const Point3d& ptP2, const int& nEdge2) const +Tree::CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2) const { - // i punti devono essere sullo stesso lato nEdge - // nEdge2 è di backup, in caso nEdge sia un vertice, per capire di quale lato si tratta - int nEdgeRef ; + // i punti devono essere sullo stesso lato nEdge + // nEdge2 è di backup, in caso nEdge sia un vertice, per capire di quale lato si tratta + int nEdgeRef = -1 ; if ( nEdge != nEdge2 && nEdge2 != -1) { - if ( std::min(nEdge, nEdge2) < 4) - nEdgeRef = std::min(nEdge, nEdge2) ; + if ( min( nEdge, nEdge2) < 4) + nEdgeRef = min( nEdge, nEdge2) ; else if ( AreSameEdge( nEdge, 0) && AreSameEdge( nEdge2, 0)) nEdgeRef = 0 ; else if ( AreSameEdge( nEdge, 1) && AreSameEdge( nEdge2, 1)) @@ -2934,84 +2998,52 @@ Tree::CheckIfBefore( const int& nEdge, const Point3d& ptP1, const Point3d& ptP2, } else nEdgeRef = nEdge ; - // sul lato nEdge controllo se ptP1 viene prima di ptP2. - // i lati vengono percorsi in senso antiorario + // sul lato nEdge controllo se ptP1 viene prima di ptP2. + // i lati vengono percorsi in senso antiorario if ( AreSameEdge( nEdgeRef, 0)) { - return ptP1.x > ptP2.x ; + return ( ptP1.x > ptP2.x) ; } else if ( AreSameEdge( nEdgeRef, 1)) { - return ptP1.y > ptP2.y ; + return ( ptP1.y > ptP2.y) ; } else if ( AreSameEdge( nEdgeRef, 2)) { - return ptP1.x < ptP2.x ; + return ( ptP1.x < ptP2.x) ; } else if ( AreSameEdge( nEdgeRef, 3)) { - return ptP1.y < ptP2.y ; + return ( ptP1.y < ptP2.y) ; } return false ; } //---------------------------------------------------------------------------- bool -Tree::AreSameEdge( const int& nEdge1, const int nEdge2) const +Tree::AreSameEdge( int nEdge1, int nEdge2) const { - if ( nEdge1 == 0) { - if ( nEdge2 == 4 || nEdge2 == 0 || nEdge2 == 7) - return true ; - else - return false ; - } - else if ( nEdge1 == 1) { - if ( nEdge2 == 4 || nEdge2 == 1 || nEdge2 == 5) - return true ; - else - return false ; - } - else if ( nEdge1 == 2) { - if ( nEdge2 == 6 || nEdge2 == 2 || nEdge2 == 5) - return true ; - else - return false ; - } - else if ( nEdge1 == 3) { - if ( nEdge2 == 6 || nEdge2 == 3 || nEdge2 == 7) - return true ; - else - return false ; - } - else if ( nEdge1 == 4) { - if ( nEdge2 == 0 || nEdge2 == 1 || nEdge2 == 7 || nEdge2 == 5) - return true ; - else - return false ; - } - else if ( nEdge1 == 5) { - if ( nEdge2 == 2 || nEdge2 == 1 || nEdge2 == 4 || nEdge2 == 6) - return true ; - else - return false ; - } - else if ( nEdge1 == 6) { - if ( nEdge2 == 2 || nEdge2 == 3 || nEdge2 == 5 || nEdge2 == 7) - return true ; - else - return false ; - } - else if ( nEdge1 == 7) { - if ( nEdge2 == 0 || nEdge2 == 3 || nEdge2 == 4 || nEdge2 == 6) - return true ; - else - return false ; - } + if ( nEdge1 == 0) + return ( nEdge2 == 4 || nEdge2 == 0 || nEdge2 == 7) ; + else if ( nEdge1 == 1) + return ( nEdge2 == 4 || nEdge2 == 1 || nEdge2 == 5) ; + else if ( nEdge1 == 2) + return ( nEdge2 == 6 || nEdge2 == 2 || nEdge2 == 5) ; + else if ( nEdge1 == 3) + return ( nEdge2 == 6 || nEdge2 == 3 || nEdge2 == 7) ; + else if ( nEdge1 == 4) + return ( nEdge2 == 0 || nEdge2 == 1 || nEdge2 == 7 || nEdge2 == 5) ; + else if ( nEdge1 == 5) + return ( nEdge2 == 2 || nEdge2 == 1 || nEdge2 == 4 || nEdge2 == 6) ; + else if ( nEdge1 == 6) + return ( nEdge2 == 2 || nEdge2 == 3 || nEdge2 == 5 || nEdge2 == 7) ; + else if ( nEdge1 == 7) + return ( nEdge2 == 0 || nEdge2 == 3 || nEdge2 == 4 || nEdge2 == 6) ; else return false ; } //---------------------------------------------------------------------------- bool -Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const +Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const { - // se è il primo punto della PolyLine lo aggiungo + // se è il primo punto della PolyLine lo aggiungo if ( plTrimmedPoly.GetPointNbr() == 0) { plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; @@ -3023,13 +3055,13 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly Point3d ptBL = vEdgeVertex[2][0] ; Point3d ptLast ; plTrimmedPoly.GetLastPoint( ptLast) ; - // verifico di essere allineato con un lato, sennò aggiungo e basta + // verifico di essere allineato con un lato, sennò aggiungo e basta Vector3d vDir ; if ( ! AreSamePointApprox( ptToAdd, ptLast)) vDir = ptToAdd - ptLast ; else return true ; - // se non riesco a normalizzare perché sono troppo vicino ad un vertice allora aggiungo direttamente il vertice + // se non riesco a normalizzare perché sono troppo vicino ad un vertice allora aggiungo direttamente il vertice if ( ! vDir.Normalize()) { plTrimmedPoly.EraseLastUPoint() ; if ( AreSamePointApprox( ptToAdd, ptBr)) @@ -3046,8 +3078,8 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly return true ; } if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) { - // se su un edge devo fare dei controlli - // edge 0 + // se su un edge devo fare dei controlli + // edge 0 if ( ptToAdd.x >= ptBL.x && ptToAdd.x <= ptTR.x && ptToAdd.y == ptTR.y && abs( vDir.x) > 1 - EPS_SMALL) { for ( int t = 0 ; t < (int)vEdgeVertex[0].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[0][t] ; @@ -3059,7 +3091,7 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; } - // edge 1 + // edge 1 else if ( ptToAdd.y >= ptBL.y && ptToAdd.y <= ptTR.y && ptToAdd.x == ptBL.x && abs( vDir.y) > 1 - EPS_SMALL) { for ( int t = 0 ; t < (int)vEdgeVertex[1].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[1][t] ; @@ -3071,7 +3103,7 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; } - // edge 2 + // edge 2 else if ( ptToAdd.x >= ptBL.x && ptToAdd.x <= ptTR.x && ptToAdd.y == ptBL.y && abs( vDir.x) > 1 - EPS_SMALL) { for ( int t = 0 ; t < (int)vEdgeVertex[2].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[2][t] ; @@ -3083,7 +3115,7 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; } - // edge 3 + // edge 3 else if ( ptToAdd.y >= ptBL.y && ptToAdd.y <= ptTR.y && ptToAdd.x == ptTR.x && abs( vDir.y) > 1 - EPS_SMALL) { for ( int t = 0 ; t < (int)vEdgeVertex[3].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[3][t] ; @@ -3095,14 +3127,14 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; } - // sono allineato con un lato, ma NON sono su un lato - // aggiungo e basta + // sono allineato con un lato, ma NON sono su un lato + // aggiungo e basta else { plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; } } - // non su un edge, quindi aggiungo e basta + // non su un edge, quindi aggiungo e basta else { plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; @@ -3110,84 +3142,20 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly return true ; } -//usando i poligoni // deprecato e non funzionante -////---------------------------------------------------------------------------- -//bool -//Tree::SetRightEdgeIn( int nId, std::vector& vEdgeVertex, PolyLine& plTrimmedPoly) -//{ -// Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; -// Point3d ptTR = m_mTree.at( nId).GetTopRight() ; -// int nPos0 = -1 , nPos1 = -1 ; -// bool bSave = false ; -// PNTLIST lPtInt ; -// for ( int k = 0 ; k < plTrimmedPoly.GetPointNbr() ; ++ k) { -// Point3d ptIter ; -// plTrimmedPoly. GetNextPoint( ptIter) ; -// if ( AreSamePointExact( ptIter, ptBr)) { -// nPos0 = k ; -// bSave = bSave ^ true ; -// } -// if ( AreSamePointExact( ptIter, ptTR)) { -// nPos1 = k ; -// bSave = bSave ^ true ; -// } -// if ( bSave) { -// lPtInt.push_back( ptIter) ; -// } -// } -// lPtInt.pop_front() ; -// // verifico se ci sono tutti e due i punti -// if ( nPos0 != -1 && nPos1 != -1) { -// // se sono di seguito tutto il lato destro è dentro -// if ( nPos1 == nPos0 + 1 || nPos0 == nPos1 + 1) { -// m_mTree[nId].m_nRightEdgeIn = 1 ; -// } -// // ci sono dei punti in mezzo, devo capire se sono allineati o no -// else { -// // verifico se tutti i punti intermedi sono allineati o no -// CurveLine clRightEdge ; -// clRightEdge.Set( ptBr, ptTR) ; -// bool bAllOn = true ; -// -// PNTLIST::iterator lIter = lPtInt.begin() ; -// std::advance( lIter, 0) ; -// for ( int p = 0 ; p < (int)lPtInt.size() ; ++ p) { -// if ( ! clRightEdge.IsPointOn( *lIter)) { -// bAllOn = false ; -// break ; -// } -// } -// // divisi da punti allineati e quindi lato dentro -// if ( bAllOn) { -// m_mTree[nId].m_nRightEdgeIn = 1 ; -// } -// // se sono dentro, ma non allineati, allora solo in parte -// else { -// m_mTree[nId].m_nRightEdgeIn = 2 ; -// } -// } -// } -// // il lato destro è sicuramente esterno -// else { -// m_mTree[nId].m_nRightEdgeIn = 0 ; -// } -// return true ; -//} - //usando le intersezioni con le celle //---------------------------------------------------------------------------- bool -Tree::SetRightEdgeIn( const int& nId) +Tree::SetRightEdgeIn( int nId) { - // categorizzo la cella in base a quanta parte del lato destro è conenuta all'interno delle curve di trim - // RightEdgeIn -> 0 non contenuto ; 1 contenuto ; 2 in parte contenuto + // categorizzo la cella in base a quanta parte del lato destro è conenuta all'interno delle curve di trim + // RightEdgeIn -> 0 non contenuto ; 1 contenuto ; 2 in parte contenuto int nPass = (int) m_mTree[nId].m_vInters.size() ; - if ( nPass == 0 ) { + if ( nPass == 0) { m_mTree[nId].m_nRightEdgeIn = 0 ; return true ; } bool bDone = false ; - // se ho solo loop interni devo controllare se il più esterno è CCW ( lato destro esterno) o CW ( lato destro interno) + // se ho solo loop interni devo controllare se il più esterno è CCW ( lato destro esterno) o CW ( lato destro interno) if ( m_mTree[nId].m_nFlag == 2) { bool bAllContained = true ; bool bContained = false ; @@ -3199,7 +3167,7 @@ Tree::SetRightEdgeIn( const int& nId) if ( ! inA.bCCW) { bContained = false ; Inters inB = m_mTree[nId].m_vInters[0] ; - for( int c = 0 ; c < nInters ; ++ c){ + for ( int c = 0 ; c < nInters ; ++ c) { inB = m_mTree[nId].m_vInters[c] ; if ( inB.nIn == -1) { if ( inB != inA && inB.nChunk == inA.nChunk && inB.bCCW) { @@ -3288,15 +3256,12 @@ Tree::SetRightEdgeIn( const int& nId) m_mTree[nId].m_nRightEdgeIn = 0 ; } - if ( m_mTree[nId].m_nRightEdgeIn != -1) - return true ; - else - return false ; + return ( m_mTree[nId].m_nRightEdgeIn != -1) ; } //---------------------------------------------------------------------------- bool -Tree::CategorizeCell( const int& nId) +Tree::CategorizeCell( int nId) { if ( m_mTree[nId].m_nFlag != -1) { return true ; @@ -3306,10 +3271,10 @@ Tree::CategorizeCell( const int& nId) // mi servono i vicini di sinistra per capire se sono dentro il loop o fuori // nRightEdgeIn // 0 right edge fuori, 1 right edge dentro, 2 metà e metà // nFlag // 0 fuori, 1 intersecata, 2 contiene loop, 3 = 1 & 2, 4 dentro - if ( (int)vNeigh.size() == 0) { + if ( vNeigh.empty()) { m_mTree[nId].m_nFlag = 0 ; } - else if ( (int)vNeigh.size() == 1) { + else if ( vNeigh.size() == 1) { if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 1) m_mTree[nId].m_nFlag = 4 ; else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 0) @@ -3317,18 +3282,16 @@ Tree::CategorizeCell( const int& nId) if ( m_mTree[vNeigh[0]].m_nFlag == 1 || m_mTree[vNeigh[0]].m_nFlag == 3) m_mTree[nId].m_nFlag = 0 ; else { - if ( m_mTree[vNeigh[0]].m_nFlag == 4) { + if ( m_mTree[vNeigh[0]].m_nFlag == 4) m_mTree[nId].m_nFlag = 4 ; - } - else if ( m_mTree[vNeigh[0]].m_nFlag == 0) { + else if ( m_mTree[vNeigh[0]].m_nFlag == 0) m_mTree[nId].m_nFlag = 0 ; - } } // se solo parte del right edge del vicino è compreso, allora devo verificare se la cella è contenuta o no // guardando nFlag del vicino bottom, che è già categorizzato! else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 2) { GetBottomNeigh( nId, vNeigh1) ; - if ( (int) vNeigh1.size() > 0) { + if ( ! vNeigh1.empty()) { int nNeigh = vNeigh1[0] ; if ( m_mTree[nNeigh].m_nFlag == 0 || m_mTree[nNeigh].m_nFlag == 2) { m_mTree[nId].m_nFlag = 0 ; @@ -3401,7 +3364,7 @@ Tree::CategorizeCell( const int& nId) } } } - // se non ho vicini bottom devo per forza guardare il vicino a sinistra + // se non ho vicini bottom devo per forza guardare il vicino a sinistra else { Point3d ptInters = m_mTree[vNeigh[0]].GetTopRight() ; int nEdge = 3 ; @@ -3518,7 +3481,7 @@ Tree::CheckIfBetween( const Inters& inA, const Inters& inB) const //---------------------------------------------------------------------------- bool -Tree::GetLeaves( std::vector& vLeaves) const +Tree::GetLeaves( vector& vLeaves) const { vLeaves.clear() ; for ( int k : m_vnLeaves) { @@ -3531,21 +3494,13 @@ Tree::GetLeaves( std::vector& vLeaves) const //---------------------------------------------------------------------------- bool -Tree::OnWhichEdge( const int& nId, const Point3d& ptToAssign, int& nEdge) const +Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const { Point3d ptTR = m_mTree.at( nId).GetTopRight() ; Point3d ptBL = m_mTree.at( nId).GetBottomLeft() ; Point3d ptTl ( ptBL.x, ptTR.y) ; Point3d ptBr ( ptTR.x, ptBL.y) ; - if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptTR.y) < EPS_SMALL) - nEdge = 0 ; - else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptBL.x) < EPS_SMALL) - nEdge = 1 ; - else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptBL.y) < EPS_SMALL) - nEdge = 2 ; - else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL) - nEdge = 3 ; if ( AreSamePointApprox( ptToAssign, ptTR)) nEdge = 7 ; else if ( AreSamePointApprox( ptToAssign, ptTl)) @@ -3554,6 +3509,14 @@ Tree::OnWhichEdge( const int& nId, const Point3d& ptToAssign, int& nEdge) const nEdge = 5 ; else if ( AreSamePointApprox( ptToAssign, ptBr)) nEdge = 6 ; + else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptTR.y) < EPS_SMALL) + nEdge = 0 ; + else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptBL.x) < EPS_SMALL) + nEdge = 1 ; + else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptBL.y) < EPS_SMALL) + nEdge = 2 ; + else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL) + nEdge = 3 ; else return false ; return true ; diff --git a/Tree.h b/Tree.h index 541101f..ea60bb6 100644 --- a/Tree.h +++ b/Tree.h @@ -14,27 +14,28 @@ #pragma once //--------------------------- Include ---------------------------------------- -#include #include "SurfBezier.h" #include "GeoConst.h" #include "CurveLine.h" #include "/EgtDev/Include/EGkPolyLine.h" +#include +//---------------------------------------------------------------------------- struct Inters { int nIn ; PNTVECTOR vpt ; int nOut ; bool bCCW ; - bool bVertex ; int nChunk ; // riordino le intersezioni per lato in senso antiorario dal top - // se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR - bool operator < ( Inters& b) { - // trovo in che ordine stanno i due strat, tenendo conto anche della possibilità che siano vertici + // se ho pi� intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR + bool operator < ( Inters& b) + { + // trovo in che ordine stanno i due strat, tenendo conto anche della possibilit� che siano vertici INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ; - INTVECTOR::iterator iter1 = find( vEdges.begin(), vEdges.end(), nIn) ; + const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ; int nPos1 = std::distance( vEdges.begin(), iter1) ; - INTVECTOR::iterator iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ; + const auto iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ; int nPos2 = std::distance( vEdges.begin(), iter2) ; // se sono loop interni li ordino in modo decrescente rispetto all'area bool bEqIn = ( nIn == b.nIn) ; @@ -51,27 +52,29 @@ struct Inters { pl.Close() ; pl.GetAreaXY( dAreaB) ; } - // se nIn è un vertice sistemo il valore + // se nIn � un vertice sistemo il valore int nEdgeIn = nIn ; if ( nIn > 3) nEdgeIn = nIn - 4 ; - return nPos1 < nPos2 || - ( bEqIn && nEdgeIn == -1 && abs(dAreaA) > abs(dAreaB)) || - ( bEqIn && nEdgeIn == 0 && vpt[0].x > b.vpt[0].x) || - ( bEqIn && nEdgeIn == 1 && vpt[0].y > b.vpt[0].y) || - ( bEqIn && nEdgeIn == 2 && vpt[0].x < b.vpt[0].x) || - ( bEqIn && nEdgeIn == 3 && vpt[0].y < b.vpt[0].y) - ; } - bool operator == ( Inters& b) { + return ( nPos1 < nPos2 || + ( bEqIn && nEdgeIn == -1 && abs( dAreaA) > abs( dAreaB)) || + ( bEqIn && nEdgeIn == 0 && vpt[0].x > b.vpt[0].x) || + ( bEqIn && nEdgeIn == 1 && vpt[0].y > b.vpt[0].y) || + ( bEqIn && nEdgeIn == 2 && vpt[0].x < b.vpt[0].x) || + ( bEqIn && nEdgeIn == 3 && vpt[0].y < b.vpt[0].y)) ; + } + bool operator == ( Inters& b) + { return AreSamePointExact( vpt[0], b.vpt[0]) ; } - bool operator != ( Inters& b){ + bool operator != ( Inters& b) + { return ! AreSamePointExact( vpt[0], b.vpt[0]) ; } } ; // nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario -// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario -// -1 se la curva è sempre dentro la cella +// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da l� in senso antiorario +// -1 se la curva � sempre dentro la cella //---------------------------------------------------------------------------- class Cell @@ -86,23 +89,47 @@ class Cell // |_________________| // Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE) public : - ~Cell( void) ; - Cell( void) ; - Cell( const Point3d& ptBL, const Point3d& ptTR) ; - inline bool IsSame( const Cell& cOtherCell) const ; - void SetBottomLeft( const Point3d ptBL) { m_ptPbl = ptBL ; } - void SetTopRight( const Point3d ptTR) { m_ptPtr = ptTR ; } - void SetSplitDirVert( const bool bVert) { m_bSplitVert = bVert ; } - void SetParent( const int& nParent) { m_nParent = nParent ; } - Point3d GetBottomLeft( void) const { return m_ptPbl ; } - Point3d GetTopRight( void) const { return m_ptPtr ; } - double GetSplitValue( void) const { return m_dSplit ; } - bool IsSplitVert( void) const { return m_bSplitVert ; } // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente - bool IsLeaf( void) const ; // flag che indica se la cella ha figli o se è una foglia - bool IsProcessed( void) const { return m_bProcessed ; } // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati - void SetProcessed( const bool bProcessed = true) { m_bProcessed = bProcessed ; } - static bool minorX ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.x < c2.m_ptPbl.x ; } - static bool minorY ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.y < c2.m_ptPbl.y ; } + ~Cell( void) {} + Cell( void) + : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), + m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), + m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true) + { + Point3d ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ; + m_ptPtr = ptTr ; + } + Cell( const Point3d& ptBL, const Point3d& ptTR) + : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), + m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), + m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {} + bool IsSame( const Cell& cOtherCell) const + { return ( m_nId == cOtherCell.m_nId) ; } + void SetBottomLeft( const Point3d& ptBL) + { m_ptPbl = ptBL ; } + void SetTopRight( const Point3d& ptTR) + { m_ptPtr = ptTR ; } + void SetSplitDirVert( bool bVert) + { m_bSplitVert = bVert ; } + void SetParent( int nParent) + { m_nParent = nParent ; } + Point3d GetBottomLeft( void) const + { return m_ptPbl ; } + Point3d GetTopRight( void) const + { return m_ptPtr ; } + double GetSplitValue( void) const + { return m_dSplit ; } + bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, senn� orizzontalmente + { return m_bSplitVert ; } + bool IsLeaf( void) const // flag che indica se la cella ha figli o se � una foglia + { return ( m_nChild1 == -2 && m_nChild2 == -2) ; } + bool IsProcessed( void) const // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati + { return m_bProcessed ; } + void SetProcessed( bool bProcessed = true) + { m_bProcessed = bProcessed ; } + static bool minorX( const Cell& c1, const Cell& c2) + { return c1.m_ptPbl.x < c2.m_ptPbl.x ; } + static bool minorY( const Cell& c1, const Cell& c2) + { return c1.m_ptPbl.y < c2.m_ptPbl.y ; } public : int m_nId ; // Id della cella @@ -111,94 +138,95 @@ class Cell int m_nLeft ; // cella adiacente al lato left int m_nRight ; // cella adiacente al lato right int m_nParent ; // cella genitore - int m_nDepth ; // profondità della cella rispetto a root - double m_dSplit ; // parametro a cui è stata splittata la cella + int m_nDepth ; // profondit� della cella rispetto a root + double m_dSplit ; // parametro a cui � stata splittata la cella int m_nChild1 ; // prima cella figlio int m_nChild2 ; // seconda cella figlio int m_nFlag ; // falg che indica la caratterizzazione della cella rispetto ai loop di trim // 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop - int m_nFlag2 ; // falg che indica se la cella è stata attraversata durante l'ultima fase del labelling - int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà - bool m_bOnLeftEdge ; // flag che indica se la cella è sul lato sinistro ( per superfici chiuse sul parametro U) - bool m_bOnTopEdge ; // flag che indica se la cella è sul lato top ( per superfici chiuse sul parametro V) - std::vector m_vInters ; // vettore delle intersezioni della cella con i loop di trim - // ogni elemento del vettore è l'insieme dei punti che caratterizza un atrtaversamento della cella + int m_nFlag2 ; // falg che indica se la cella � stata attraversata durante l'ultima fase del labelling + int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 met� e met� + bool m_bOnLeftEdge ; // flag che indica se la cella � sul lato sinistro ( per superfici chiuse sul parametro U) + bool m_bOnTopEdge ; // flag che indica se la cella � sul lato top ( per superfici chiuse sul parametro V) + std::vector m_vInters ; // vettore delle intersezioni della cella con i loop di trim + // ogni elemento del vettore � l'insieme dei punti che caratterizza un atrtaversamento della cella private : Point3d m_ptPbl ; // punto bottom left Point3d m_ptPtr ; // punto top right - bool m_bProcessed ; // flag che indica se la cella è stata processata - bool m_bSplitVert ; // flag che indica in quale direzione è stata divisa la cella + bool m_bProcessed ; // flag che indica se la cella � stata processata + bool m_bSplitVert ; // flag che indica in quale direzione � stata divisa la cella } ; //---------------------------------------------------------------------------- class Tree { -public : - ~Tree( void) ; - Tree( void) ; - Tree ( const SurfBezier* pSrfBz, const bool bSplitPatches = true, const Point3d ptMin = ORIG, const Point3d ptMax = ORIG) ; - void SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches = true, const Point3d ptMin = ORIG, const Point3d ptMax = ORIG) ; - bool GetIndependentTrees( std::vector>& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini) - bool BuildTree( const double& dLinTol = LIN_TOL_STD, const double& dSideMin = 1, const double& dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh - // dSideMin è lunghezza minima del lato di una cella nello spazio reale - bool BuildTree_test( const double& dLinTol = LIN_TOL_STD, const double& dSideMin = 1, const double& dSideMax = INFINITO) ; - bool GetPolygons( std::vector& vPolygons) ; - bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero - // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati - bool GetLeaves ( std::vector& vLeaves) const ; + public : + ~Tree( void) ; + Tree( void) ; + Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; + void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; + bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini) + bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax � il massimo per la dimensione maggiore di un triangolo della trimesh + // dSideMin � lunghezza minima del lato di una cella nello spazio reale + bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; + bool GetPolygons( POLYLINEMATRIX& vPolygons) ; + bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero + // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati + bool GetLeaves ( std::vector& vLeaves) const ; // restituisce gli indici delle foglie nell'albero + void SetTestMode( void) { m_bTestMode = true ;} ; // attivando la test mode, per la costruzione dell'albero viene usata la funzione BuiltTree_test e viene corretta di conseguenza la FindCell -private : - bool Split( const int& nId, const double& dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert - bool Split( const int& nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert - void Balance () ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profonditù di +- 1 - int GetHeightLeaves ( const int& nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId - int GetDepth ( const int& nId, const int& nRef) const ; // livello del nodo nId - void GetTopNeigh( const int& nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top - void GetBottomNeigh( const int& nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom - void GetLeftNeigh( const int& nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left - void GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right - void GetRootNeigh( const int& nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario - void ResetTree ( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero - INTVECTOR FindCell ( const Point3d& ptToAssign, const CurveLine& cl) const ; // dato un punto, trova la cella foglia a cui appartiene - INTVECTOR FindCell ( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const ; // dato un punto, trova la cella foglia a cui appartiene - bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle - bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim - // resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto - bool CreateCellPolygons ( const int& nLeafId, std::vector& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) ; - bool CreateIslandAndHoles ( const int& nLeafId, std::vector& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ; - bool CheckIfBefore( const PolyLine& pl, const int& nEdge) const ; - bool CheckIfBefore( const Inters& inA) const ; - bool CheckIfBefore( const int& nEdge1, const Point3d& ptP1, const int& nEdge2, const Point3d& ptP2) const ; // punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3 - bool CheckIfBefore( const int& nEdge, const Point3d& ptP1, const Point3d& ptP2, const int& nEdge2 = -1) const ; // entrambi i punti sullo stesso lato, nEdge. nEdge2 serve come backup, in caso nEdge sia un vertice. - bool AreSameEdge( const int& nEdge1, const int nEdge2) const ; - bool AddVertex( const int& nId, const std::vector& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const ; - //bool SetRightEdgeIn( int nId, std::vector& vEdgeVertex, PolyLine& plTrimmedPoly) ; - bool SetRightEdgeIn( const int& nId) ; - bool CategorizeCell( const int& nId) ; - bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; - bool OnWhichEdge( const int& nId, const Point3d& ptToAssign, int& nEdge) const ; + private : + bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert + bool Split( int nId) ; // funzione di split di una cella dell'albero a met� nella direzione data da bVert + void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondit� di +- 1 + int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId + int GetDepth( int nId, int nRef) const ; // livello del nodo nId + void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top + void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom + void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left + void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right + void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario + void ResetTree( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero + INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene + INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene + bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle + bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim + // resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto + bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni. + bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella + bool CheckIfBefore( const PolyLine& pl, int nEdge) const ; // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario + bool CheckIfBefore( const Inters& inA) const ; // controlla se l'ingresso è prima dell'uscita in senso antiorario a partire da ptTR. + bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // verifico quale punto viene prima tra pt1 e pt2 a partire da ptTR girando in senso CCW (punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3) + bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // sul lato nEdge controllo se ptP1 viene prima di ptP2. + bool AreSameEdge( int nEdge1, int nEdge2) const ; // indica se i due edge sono lo stesso. Un vertice adiacente ad un edge viene considerato uguale a questo edge + bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto + bool SetRightEdgeIn( int nId) ; // categorizza la cella in base all'edge destro per poter poi definire m_nFlag + bool CategorizeCell( int nId) ; // categorizza la cella in base al flag m_nFlag (dentro, fuori, intersecata) + bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; // / controllo se inB è compreso tra l'end e lo start di inA (in senso CCW) + bool OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const ; // indica a quale edge o vertice il punto è vicino entro EPS_SMALL -private : - const SurfBezier* m_pSrfBz ; // superficie di bezier - DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00 - bool m_bTrimmed ; // superficie trimmata - std::vector m_vChunk ; // elenco dei loop divisi per chunk - std::map m_mChunk ; - ICURVEPOVECTOR m_vLoop ; // curve di loop - std::vector> m_vPlApprox ; - bool m_bBilinear ; // superficie bilineare - bool m_bMulti ; // superficie multi-patch - bool m_bClosedU ; // superficie chiusa lungo il parametro U - bool m_bClosedV ; // superficie chiusa lungo il parametro V - bool m_bSplitPatches ; // flag che indica se le patches sono state divise prima della creazione dell'albero - int m_nDegU ; // grado della superficie nel parametro U - int m_nDegV ; // grado della superficie nel parametro V - int m_nSpanU ; - int m_nSpanV ; - std::vector m_vPolygons ; // vettore dei poligoni del tree - std::map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root - std::map m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id è lo stesso che la cella ha in m_mTree - INTVECTOR m_vnLeaves ; // vettore delle foglie - INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch + private : + const SurfBezier* m_pSrfBz ; // superficie di bezier + DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00 + bool m_bTrimmed ; // superficie trimmata + INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk + std::map m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim + ICURVEPOVECTOR m_vLoop ; // curve di loop + std::vector> m_vPlApprox ; // vettore contenente le approssimazioni dei loop + bool m_bBilinear ; // superficie bilineare + bool m_bMulti ; // superficie multi-patch + bool m_bClosedU ; // superficie chiusa lungo il parametro U + bool m_bClosedV ; // superficie chiusa lungo il parametro V + bool m_bSplitPatches ; // flag che indica se le patches sono state divise prima della creazione dell'albero + int m_nDegU ; // grado della superficie nel parametro U + int m_nDegV ; // grado della superficie nel parametro V + int m_nSpanU ; // numero di span lungo il parametro U + int m_nSpanV ; // numero di span lungo il parametro V + POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree + std::map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 � puntatore Null e -1 � root + std::map m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id � lo stesso che la cella ha in m_mTree + INTVECTOR m_vnLeaves ; // vettore delle foglie + INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch + bool m_bTestMode ; // bool che indica se la test mode è attiva } ; \ No newline at end of file diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 9e7e8f6..cadc688 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -1930,9 +1930,12 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis } // Intersezione della linea con triangolo eventualmente offsettato Point3d ptInt, ptInt2 ; - if ( IntersLineTria( ptT, vtK, 1, trNewTria, ptInt, ptInt2, false) != IntLineTriaType::ILTT_NO) { + int nIntLnTr = IntersLineTria( ptT, vtK, 1, trNewTria, ptInt, ptInt2, false) ; + if ( nIntLnTr != ILTT_NO) { double dZmin = ( ptInt - ptT) * vtK ; - double dZmax = ( ptInt2 - ptT) * vtK ; + double dZmax = dZmin ; + if ( nIntLnTr == ILTT_SEGM || nIntLnTr == ILTT_SEGM_ON_EDGE) + dZmax = ( ptInt2 - ptT) * vtK ; for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) { if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL && dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL) diff --git a/Voronoi.cpp b/Voronoi.cpp index 641494d..e863f8e 100644 --- a/Voronoi.cpp +++ b/Voronoi.cpp @@ -18,7 +18,7 @@ #include "SurfFlatRegion.h" #include "OffsetAux.h" #include "RemoveCurveDefects.h" -#include "/EgtDev/Include/EGkVoronoi.h" +#include "Voronoi.h" #include "/EgtDev/Include/EGkDistPointCurve.h" using namespace std ; @@ -115,25 +115,35 @@ Voronoi::AddCurve( const ICurve* pCrv) return false ; } - // verifico se oggetto vroni è stato inizializzato - if ( m_vroni == nullptr) { - m_vroni = new( nothrow) vroniObject() ; - m_vroni->apiInitializeProgram() ; - } - // creo una copia della curva e la porto in locale PtrOwner pCrvLoc( pCrv->Clone()) ; + if ( IsNull( pCrvLoc)) + return false ; pCrvLoc->ToLoc( m_Frame) ; - // aggiungo la curva in locale all'oggetto vroni - if ( ! AddCurveToVroni( pCrvLoc)) + try { + // verifico se oggetto vroni è stato inizializzato + if ( m_vroni == nullptr) { + m_vroni = new( nothrow) vroniObject() ; + if ( m_vroni == nullptr) + return false ; + m_vroni->apiInitializeProgram() ; + } + + // aggiungo la curva in locale all'oggetto vroni + if ( ! AddCurveToVroni( pCrvLoc)) + return false ; + } + catch (...) { + LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ; return false ; + } // aggiorno il box complessivo BBox3d bBox ; pCrvLoc->GetLocalBBox( bBox) ; m_bBox.Add( bBox) ; - + return true ; } @@ -162,21 +172,31 @@ Voronoi::AddSurfFlatRegion( const ISurfFlatRegion* pSfr) return false ; } - // verifico se oggetto vroni è stato inizializzato - if ( m_vroni == nullptr) { - m_vroni = new( nothrow) vroniObject() ; - m_vroni->apiInitializeProgram() ; - } - - // aggiungo le curve di loop - for ( int i = 0 ; i < pSfr->GetChunkCount() ; i ++) { - for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; j ++) { - PtrOwner pCrvLoc( pSfr->GetLoop( i, j)) ; - pCrvLoc->ToLoc( m_Frame) ; - if ( ! AddCurveToVroni( pCrvLoc)) + try { + // verifico se oggetto vroni è stato inizializzato + if ( m_vroni == nullptr) { + m_vroni = new( nothrow) vroniObject() ; + if ( m_vroni == nullptr) return false ; - } - } + m_vroni->apiInitializeProgram() ; + } + + // aggiungo le curve di loop + for ( int i = 0 ; i < pSfr->GetChunkCount() ; i ++) { + for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; j ++) { + PtrOwner pCrvLoc( pSfr->GetLoop( i, j)) ; + if ( IsNull( pCrvLoc)) + return false ; + pCrvLoc->ToLoc( m_Frame) ; + if ( ! AddCurveToVroni( pCrvLoc)) + return false ; + } + } + } + catch (...) { + LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) + return false ; + } // aggiorno il box complessivo BBox3d bBox ; @@ -184,7 +204,7 @@ Voronoi::AddSurfFlatRegion( const ISurfFlatRegion* pSfr) frSrf.Invert() ; pSfr->GetBBox( frSrf, bBox) ; m_bBox.Add( bBox) ; - + return true ; } @@ -225,8 +245,9 @@ Voronoi::AddLineToVroni( const ICurveLine* pLine, int& nVroniCrv, int nLoopId, i { if ( pLine == nullptr) return false ; + + // verifico se il punto finale viene forzato oppure deve essere ricavato dalla pLine if ( ! ptEnd.IsValid()) { - // recupero end point if ( ! pLine->GetEndPoint( ptEnd)) return false ; } @@ -244,7 +265,7 @@ Voronoi::AddArcToVroni( const ICurveArc* pArc, int& nVroniCrv, int nLoopId, int Point3d ptCen = pArc->GetCenter() ; double dAngCen = pArc->GetAngCenter() ; - int nArcSiteType = ( dAngCen > EPS_SMALL ? ARC : -ARC ) ; + int nArcSiteType = ( dAngCen > 0 ? ARC : -ARC ) ; Vector3d vtN = pArc->GetNormVersor() ; if ( AreOppositeVectorApprox( vtN, Z_AX)) nArcSiteType *= -1 ; @@ -260,8 +281,8 @@ Voronoi::AddArcToVroni( const ICurveArc* pArc, int& nVroniCrv, int nLoopId, int m_vroni->AddArc( &nVroniCrv, ptStart.x, ptStart.y, ptCen.x, ptCen.y, nArcSiteType, {nLoopId, nCrvId}) ; } else { + // verifico se il punto finale viene forzato oppure deve essere ricavato dal pArc if ( ! ptEnd.IsValid()) { - // recupero end point dalla curva if ( ! pArc->GetEndPoint( ptEnd)) return false ; } @@ -362,8 +383,10 @@ Voronoi::CalcVoronoi( int nBound) if ( m_bVDComputed) m_vroni->ResetVoronoiDiagram() ; + // come valore minimo per il bound considero quello standard di vroni + m_nBound = max( nBound, VORONOI_STD_BOUND) ; + // calcolo - m_nBound = nBound ; m_bVDComputed = true ; string sTmp = "" ; m_vroni->apiComputeVD( false, true, false, m_nBound, 0, 0, &sTmp[0], false, false, false, &sTmp[0], true) ; @@ -377,65 +400,85 @@ Voronoi::GetBisectorCurve( int i) { if ( i >= m_vroni->GetNumberOfEdges()) return nullptr ; - - // recupero estremi del bisettore - Point3d ptS, ptE ; - m_vroni->GetVDBisectorPoints( i, ptS.v, ptE.v) ; - if ( AreSamePointApprox( ptS, ptE)) - return nullptr ; - - // recupero parametri del bisettore - double dParS, dParE ; - m_vroni->GetVDBisectorParams( i, dParS, dParE) ; - - // eventuale inversione - if ( dParS > dParE + EPS_SMALL) { - swap( dParS, dParE) ; - swap( ptS, ptE) ; - } - - // costruisco la curva - int nType = m_vroni->GetVDBisectorType( i) ; - if ( nType == LINE) { + + // identifico il tipo di bisettore + int nType = m_vroni->GetBisectorType( i) ; + + // linea + if ( nType == BisectorType::LINE) { + // recupero i dati del bisettore da vroni + Point3d ptS, ptE ; + double dParS, dParE ; + m_vroni->GetLinearBisectorData( i, ptS.v, ptE.v, dParS, dParE) ; + // creo la linea CurveLine* pLine = CreateBasicCurveLine() ; if ( pLine == nullptr) return nullptr ; pLine->Set( ptS, ptE) ; - pLine->ToGlob( m_Frame) ; - // salvo le distanze nei suoi estremi come TempParam pLine->SetTempParam( dParS, 0) ; pLine->SetTempParam( dParE, 1) ; + pLine->ToGlob( m_Frame) ; return pLine ; } - else if ( nType != NONE) { - // creo una composita campionando il bisettore + + // degenerate hyperellipse ( arco) + else if ( nType == BisectorType::DEGENERATE_HYPERELL) { + // recupero i dati del bisettore da vroni + Point3d ptS, ptE, ptC ; + double dParS, dParE ; + m_vroni->GetDegenerateHyperEllipticBisectorData( i, ptS.v, ptE.v, ptC.v, dParS, dParE) ; + // creo arco + CurveArc* pArc = CreateBasicCurveArc() ; + if ( pArc == nullptr) + return nullptr ; + pArc->SetC2P( ptC, ptS, ptE) ; + pArc->SetTempParam( dParS, 0) ; + pArc->SetTempParam( dParS, 1) ; + pArc->ToGlob( m_Frame) ; + return pArc ; + } + + // bisettore generico + else if ( nType != BisectorType::NONE) { + // approssimo linearmente il bisettore + int nPoints = m_vroni->GetApproxedBisectorPointsNbr( i) ; + if ( nPoints < 2) + return nullptr ; + CurveComposite* pCompo = CreateBasicCurveComposite() ; if ( pCompo == nullptr) - return nullptr ; - int nMaxPnts = 100 ; - double dDelta = ( dParE - dParS) / nMaxPnts ; - pCompo->AddPoint( ptS) ; - for ( int j = 1 ; j < nMaxPnts ; j ++) { - Point3d ptP ; - m_vroni->GetVDBisectorPointAtParam( i, dParS + j * dDelta, ptP.v) ; - if ( pCompo->AddLine( ptP)) { - // salvo le distanze dalla curva nei suoi estremi come temp param - pCompo->SetCurveTempParam( pCompo->GetCurveCount() - 1, dParS + ( j - 1) * dDelta, 0) ; - pCompo->SetCurveTempParam( pCompo->GetCurveCount() - 1, dParS + j * dDelta, 1) ; - } - } - // ultimo punto - if ( pCompo->AddLine( ptE)) { - pCompo->SetCurveTempParam( pCompo->GetCurveCount() - 1, dParS + ( nMaxPnts - 1) * dDelta, 0) ; - pCompo->SetCurveTempParam( pCompo->GetCurveCount() - 1, dParE, 1) ; + return nullptr ; + + // punto iniziale + Point3d pt ; + double dParS ; + m_vroni->GetApproxedBisectorPoint( i, 0, pt.v, dParS) ; + pCompo->AddPoint( pt) ; + int nCrvCount = 0 ; + + double dParPrev = dParS ; + for ( int j = 1 ; j < nPoints ; j ++) { + double dPar ; + m_vroni->GetApproxedBisectorPoint( i, j, pt.v, dPar) ; + if ( pCompo->AddLine( pt)) { + // setto i parametri sulla sottocurva + pCompo->SetCurveTempParam( nCrvCount, dParPrev, 0) ; + pCompo->SetCurveTempParam( nCrvCount, dPar, 1) ; + // aggiorno parametro precedente + dParPrev = dPar ; + nCrvCount ++ ; + } } + + // setto parametri sulla curva pCompo->SetTempParam( dParS, 0) ; - pCompo->SetTempParam( dParE, 1) ; - pCompo->ToGlob( m_Frame) ; - return pCompo ; + pCompo->SetTempParam( dParPrev, 1) ; + + pCompo->ToGlob( m_Frame) ; + return pCompo ; } - else - return nullptr ; + + return nullptr ; } //---------------------------------------------------------------------------- @@ -447,15 +490,21 @@ Voronoi::CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound) if ( ! IsValid()) return false ; - // verifico se necessario calcolo Voronoi - if ( ! m_bVDComputed || nBound != m_nBound) - CalcVoronoi( nBound) ; + try { + // verifico se necessario calcolo Voronoi + if ( ! m_bVDComputed || nBound != m_nBound) + CalcVoronoi( nBound) ; - for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) { - // recupero la curva del bisettore - PtrOwner pCrv( GetBisectorCurve( i)) ; - if ( ! IsNull( pCrv)) - vCrvs.emplace_back( Release( pCrv)) ; + for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) { + // recupero la curva del bisettore + PtrOwner pCrv( GetBisectorCurve( i)) ; + if ( ! IsNull( pCrv) && pCrv->IsValid()) + vCrvs.emplace_back( Release( pCrv)) ; + } + } + catch (...) { + LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ; + return false ; } return true ; @@ -469,10 +518,7 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) if ( ! IsValid()) return false ; - - if ( ! m_bVDComputed) - CalcVoronoi() ; - + // lato per il medial axis bool bLeft = true ; bool bRight = true ; @@ -481,18 +527,28 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) else if ( nSide == WMAT_RIGHT) bLeft = false ; - // calcolo medial axis - m_vroni->apiComputeWMAT( false, 0.0, 0.0, false, bLeft, bRight) ; - - for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) { - // verifico se il lato appartiene al medial axis - if ( m_vroni->IsWMATEdge( i)) { - PtrOwner pCrv( GetBisectorCurve( i)) ; - if ( ! IsNull( pCrv)) - vCrvs.emplace_back( Release( pCrv)) ; - } + try { + if ( ! m_bVDComputed) + CalcVoronoi() ; + + // calcolo medial axis + m_vroni->apiComputeWMAT( false, 0.0, 0.0, false, bLeft, bRight) ; + + for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) { + // verifico se il lato appartiene al medial axis + if ( m_vroni->IsWMATEdge( i)) { + PtrOwner pCrv( GetBisectorCurve( i)) ; + if ( ! IsNull( pCrv) && pCrv->IsValid()) + vCrvs.emplace_back( Release( pCrv)) ; + } + } } - return true ; + catch (...) { + LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ; + return false ; + } + + return true ; } //---------------------------------------------------------------------------- @@ -539,20 +595,21 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType) if ( pCrv->IsValid()) { // eventuale inversione if ( dOffs > EPS_SMALL) - pCrv->Invert() ; - + pCrv->Invert() ; + + // sistemo i raccordi + if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) { + IdentifyFillets( pCrv, dOffs) ; + AdjustCurveFillets( pCrv, dOffs, nType) ; + } + if ( bClosed) { // forzo chiusura della curva per evitare piccole imprecisioni pCrv->Close() ; // sistemo il punto di inizio AdjustOffsetStart( *pCrv) ; } - - // sistemo i raccordi - if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) { - IdentifyFillets( pCrv, dOffs) ; - AdjustCurveFillets( pCrv, dOffs, nType) ; - } + // porto nel frame globale pCrv->ToGlob( m_Frame) ; // unisco le parti allineate @@ -640,75 +697,81 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs, bool bRightOff nOrigCrvCnt = pOrigCompo->GetCurveCount() ; } - // reset di eventuali offset precedenti - m_vroni->apiResetOffsetData() ; - - // verifico necessario calcolo o ricalcolo di Voronoi - UpdateVoronoi( dOffs) ; - - string sTmp = "" ; - m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs, 0.0, false, bLeftOffs, bRightOffs) ; - int nOffsCnt = m_vroni->GetOffsetCount() ; - if ( nOffsCnt == 0) { - // se non ho ottenuto offset ritento con valore leggermente diverso per le tolleranze di vroni + try { + // reset di eventuali offset precedenti m_vroni->apiResetOffsetData() ; - m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs - VRONI_OFFS_TOL, 0.0, false, bLeftOffs, bRightOffs) ; - nOffsCnt = m_vroni->GetOffsetCount() ; - } - // recupero le curve di offset da vroni - for ( int i = 0 ; i < nOffsCnt ; i++) { - PtrOwner pCrvOffs ( CreateBasicCurveComposite()) ; - int nCrvCnt = m_vroni->GetOffsetCurveCount( i) ; // numero di sottocurve + // verifico necessario calcolo o ricalcolo di Voronoi + UpdateVoronoi( dOffs) ; - for ( int j = 0 ; j < nCrvCnt ; j ++) { - // recupero la sottocurva da vroni - Point3d ptS, ptE, ptC ; - int nType ; - int nOrigCrv, nOrigLoop, nOrigPnt ; // sito - m_vroni->GetOffsetCurve( i, j, nType, ptS.v, ptE.v, ptC.v, nOrigLoop, nOrigCrv, nOrigPnt) ; - - if ( j == 0) - pCrvOffs->AddPoint( ptS) ; - - bool bOk = false ; - if ( nType == t_site::SEG) - bOk = pCrvOffs->AddLine( ptE) ; - else { - PtrOwner pArc( CreateBasicCurveArc()) ; - pArc->Set2PRS( ptS, ptE, Dist( ptC, ptS), nType == CCW) ; - bOk = pCrvOffs->AddCurve( Release( pArc)) ; - } - - // se la curva è stata aggiunta - if ( bOk) { - // setto come info la sottocurva da cui si è generata - int nCurrCrvId = pCrvOffs->GetCurveCount() - 1 ; - pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigCrv + 1, 0) ; - pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigLoop, 1) ; - // verifico se è raccordo relativo agli estremi della curva - if ( nOrigCrv == -1 && ( nOrigPnt == 0 || nOrigPnt == nOrigCrvCnt)) - pCrvOffs->SetCurveTempParam( nCurrCrvId, 1.0, 0) ; - } + string sTmp = "" ; + m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs, 0.0, false, bLeftOffs, bRightOffs) ; + int nOffsCnt = m_vroni->GetOffsetCount() ; + if ( nOffsCnt == 0) { + // se non ho ottenuto offset ritento con valore leggermente diverso per le tolleranze di vroni + m_vroni->apiResetOffsetData() ; + m_vroni->apiComputeOff( false, &sTmp[0], false, false, dOffs - VRONI_OFFS_TOL, 0.0, false, bLeftOffs, bRightOffs) ; + nOffsCnt = m_vroni->GetOffsetCount() ; } - // rimuovo tratti di lunghezza inferiore a 5 * EPS_SMALL - RemoveCurveSmallParts( pCrvOffs, 5 * EPS_SMALL) ; + // recupero le curve di offset da vroni + for ( int i = 0 ; i < nOffsCnt ; i++) { + PtrOwner pCrvOffs ( CreateBasicCurveComposite()) ; + int nCrvCnt = m_vroni->GetOffsetCurveCount( i) ; // numero di sottocurve - // aggiungo la curva alla lista degli offset - if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid()) - OffsList.push_back( Release( pCrvOffs)) ; + for ( int j = 0 ; j < nCrvCnt ; j ++) { + // recupero la sottocurva da vroni + Point3d ptS, ptE, ptC ; + int nType ; + int nOrigCrv, nOrigLoop, nOrigPnt ; // sito + m_vroni->GetOffsetCurve( i, j, nType, ptS.v, ptE.v, ptC.v, nOrigLoop, nOrigCrv, nOrigPnt) ; + + if ( j == 0) + pCrvOffs->AddPoint( ptS) ; + + bool bOk = false ; + if ( nType == t_site::SEG) + bOk = pCrvOffs->AddLine( ptE) ; + else { + PtrOwner pArc( CreateBasicCurveArc()) ; + pArc->Set2PRS( ptS, ptE, Dist( ptC, ptS), nType == CCW) ; + bOk = pCrvOffs->AddCurve( Release( pArc)) ; + } + + // se la curva è stata aggiunta + if ( bOk) { + // setto come info la sottocurva da cui si è generata + int nCurrCrvId = pCrvOffs->GetCurveCount() - 1 ; + pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigCrv + 1, 0) ; + pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigLoop, 1) ; + // verifico se è raccordo relativo agli estremi della curva + if ( nOrigCrv == -1 && ( nOrigPnt == 0 || nOrigPnt == nOrigCrvCnt)) + pCrvOffs->SetCurveTempParam( nCurrCrvId, 1.0, 0) ; + } + } + + // rimuovo tratti di lunghezza inferiore a 5 * EPS_SMALL + RemoveCurveSmallParts( pCrvOffs, 5 * EPS_SMALL) ; + + // aggiungo la curva alla lista degli offset + if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid()) + OffsList.push_back( Release( pCrvOffs)) ; + } + } + catch (...) { + LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ; + return false ; } return true ; } - //---------------------------------------------------------------------------- bool Voronoi::UpdateVoronoi( double dOffs) { - double dNeededBound = abs( dOffs) / 0.49 / sqrt( m_bBox.GetDimX() * m_bBox.GetDimX() + m_bBox.GetDimY() * m_bBox.GetDimY()) ; + // calcolo il bound necessario per l'offset desiderato + double dNeededBound = abs( dOffs) / 0.49 / sqrt( m_bBox.GetDimX() * m_bBox.GetDimX() + m_bBox.GetDimY() * m_bBox.GetDimY()) ; if ( ! m_bVDComputed || dNeededBound > m_nBound) { // aggiorno il valore del bound int nBound = ( int)( ceil( dNeededBound) + 0.5) ; @@ -717,7 +780,6 @@ Voronoi::UpdateVoronoi( double dOffs) } return true ; - } //---------------------------------------------------------------------------- diff --git a/Voronoi.h b/Voronoi.h new file mode 100644 index 0000000..5b0e57e --- /dev/null +++ b/Voronoi.h @@ -0,0 +1,85 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2023 +//---------------------------------------------------------------------------- +// File : Voronoi.h Data : 23.11.23 Versione : 2.5k5 +// Contenuto : Dichiarazione della classe Voronoi con libreria VRONI +// +// +// +// Modifiche : 23.11.23 SP Creazione modulo. + +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "/EgtDev/Include/EGkFrame3d.h" +#include "/EgtDev/Include/EGkCurve.h" +#include "/EgtDev/Include/EGkCurveArc.h" +#include "/EgtDev/Include/EGkCurveBezier.h" +#include "/EgtDev/Include/EGkCurveComposite.h" +#include "/EgtDev/Include/EGkCurveLine.h" +#include "/EgtDev/Extern/vroni/Include/vroni_object.h" + +//---------------------------------------------------------------------------- +static const bool USE_VORONOI = true ; +static const int VORONOI_STD_BOUND = 3 ; +static const double VRONI_OFFS_TOL = 1e-9 ; + +//-------------------------- Forward Definitions ------------------------------- +class ISurfFlatRegion ; + +//---------------------------------------------------------------------------- +class Voronoi +{ + public : + // costanti per il lato del medial axis + enum WMATSide { WMAT_BOTHSIDES = 0, + WMAT_LEFT = 1, + WMAT_RIGHT = 2} ; + public : + Voronoi( void) + : m_vroni( nullptr), m_nBound( VORONOI_STD_BOUND), m_bVDComputed( false), m_bAllowAdd( true) {} ; + Voronoi( const ICurve* pCrv, bool bAllowAdd) ; + Voronoi( const ISurfFlatRegion* pSfr, bool bAllowAdd) ; + ~Voronoi( void) ; + + public : + bool AddCurve( const ICurve* pCrv) ; + bool AddSurfFlatRegion( const ISurfFlatRegion* pSfr) ; + ICurve* GetCurve( int nId) const ; + int GetCurveCount( void) const + { return m_vpCrvs.size() ; } ; + bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = VORONOI_STD_BOUND) ; + bool CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType) ; + bool CalcFatCurve( ICURVEPOVECTOR& vOffs, double dOffs, bool bSquareEnds, bool bSquareMids) ; + bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) ; + + private : + bool Clear( void) ; + bool IsValid( void) const + { return m_vroni != nullptr ; } ; + bool AddCurveToVroni( const ICurve * pCrv) ; + bool AddLineToVroni( const ICurveLine* pLine, int& nVroniCrv, int nLoopId, int nCrvId = 0, Point3d ptForcedEnd = P_INVALID) ; + bool AddArcToVroni( const ICurveArc* pArc, int& nVroniCrv, int nLoopId, int nCrvId = 0, Point3d ptForcedEnd = P_INVALID) ; + bool AddCompoToVroni( const ICurveComposite* pCompo, int& nCrv, int nLoopId) ; + bool AddBezierToVroni( const ICurveBezier* pBezier, int& nVroniCrv, int nLoopId) ; + + bool CalcVoronoi( int nBound = VORONOI_STD_BOUND) ; + bool CalcVroniOffset( ICRVCOMPOPLIST& vOffs, double dOffs, bool bRightOffs, bool bLeftOffs) ; + bool UpdateVoronoi( double dOffs) ; + bool VerifyCurvesValidityForOffset( void) ; + bool AdjustOpenOffsetCurve( ICurveComposite& pCompo, double dOffs) ; + bool AdjustOffsetStart( ICurveComposite& pCompo) ; + int GetOffsetCurveSide( const ICurveComposite& pOffs, int nCrv) ; + ICurve* GetBisectorCurve( int i) ; + + private : + vroniObject* m_vroni ; // oggetto base della libreria vroni + Frame3d m_Frame ; // frame in cui è espresso l'oggetto vroni + int m_nBound ; // bound associato al diagramma di Voronoi corrente + CICURVEPVECTOR m_vpCrvs ; // curve associate al Voronoi ( espresse rispetto a m_Frame) + BBox3d m_bBox ; // box degli oggetti associati al Voronoi + bool m_bVDComputed ; // indica se il diagramma di Voronoi è stato calcolato + bool m_bAllowAdd ; // indica se possibile aggiungere altre curve/superifici dopo aver creato l'oggetto Voronoi +} ; diff --git a/earcut.hpp b/earcut.hpp index a73ae87..b98508f 100644 --- a/earcut.hpp +++ b/earcut.hpp @@ -263,11 +263,8 @@ void Earcut::earcutLinked(Node* ear, int pass) { Node* prev; Node* next; - int iterations = 0; - // iterate through ears, slicing them one by one while (ear->prev != ear->next) { - iterations++; prev = ear->prev; next = ear->next;