From 82195db8cc9cdc7025934004d3a9b33a38e4f9b0 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Sun, 21 Jun 2015 16:56:18 +0000 Subject: [PATCH] =?UTF-8?q?EgtGeomKernel=201.6f3=20:=20-=20ApproxWithLines?= =?UTF-8?q?=20per=20Curve=20con=20possibilit=C3=A0=20di=20forzare=20un=20l?= =?UTF-8?q?ato=20-=20aggiunta=20MergeCurves=20a=20CurveComposite=20-=20a?= =?UTF-8?q?=20PolyLine=20aggiunte=20RemoveAlignedPoints=20e=20ApproxOnSide?= =?UTF-8?q?=20-=20corretta=20ExtendEndByLen=20e=20ExtendStartByLen=20per?= =?UTF-8?q?=20CurveArc=20quando=20=C3=A8=20elica.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CurveArc.cpp | 52 ++++--- CurveArc.h | 2 +- CurveAux.cpp | 4 +- CurveBezier.cpp | 20 ++- CurveBezier.h | 2 +- CurveComposite.cpp | 261 ++++++++++++++++++++++++++-------- CurveComposite.h | 9 +- CurveLine.cpp | 2 +- CurveLine.h | 2 +- DistPointArc.cpp | 2 +- DistPointCrvBezier.cpp | 2 +- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes EgtGeomKernel.vcxproj | 1 + EgtGeomKernel.vcxproj.filters | 3 + FontNfe.cpp | 2 +- FontOs.cpp | 2 +- GdbExecutor.cpp | 2 +- IntersCurveCurve.cpp | 2 +- OutTsc.cpp | 2 +- PolyArc.cpp | 19 +-- PolyLine.cpp | 212 +++++++++++++++++++++++---- StmFromCurves.cpp | 20 +-- 22 files changed, 470 insertions(+), 153 deletions(-) diff --git a/CurveArc.cpp b/CurveArc.cpp index 3ed03ac..f0eafb6 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -755,7 +755,7 @@ CurveArc::GetEndPoint( Point3d& ptEnd) const double dAng = m_dAngCenDeg * DEGTORAD ; Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; ptEnd = m_PtCen + m_dRad * vtDir ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) ptEnd += m_dDeltaN * m_VtN ; return true ; @@ -773,7 +773,7 @@ CurveArc::GetMidPoint( Point3d& ptMid) const double dAng = 0.5 * m_dAngCenDeg * DEGTORAD ; Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; ptMid = m_PtCen + m_dRad * vtDir ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) ptMid += ( 0.5 * m_dDeltaN) * m_VtN ; return true ; @@ -801,7 +801,7 @@ CurveArc::GetCentroid( Point3d& ptCen) const return false ; // approssimo la curva con una polilinea PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, PL)) + if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; // calcolo il centro mediante PolygonPlane Point3d ptP ; @@ -833,7 +833,7 @@ CurveArc::GetDir( double dU, Vector3d& vtDir) const Vector3d vtRad = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; // calcolo della tangente nel punto finale vtDir = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtRad) ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) vtDir += m_dDeltaN * m_VtN ; // normalizzo return vtDir.Normalize() ; @@ -859,13 +859,13 @@ CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, V // calcolo del punto ptPos = m_PtCen + m_dRad * vtDir ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) ptPos += ( dU * m_dDeltaN) * m_VtN ; // calcolo della derivata prima if ( pvtDer1 != nullptr) { *pvtDer1 = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtDir) ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) *pvtDer1 += m_dDeltaN * m_VtN ; } @@ -887,7 +887,7 @@ CurveArc::GetLength( double& dLen) const // lunghezza dell'arco piano dLen = m_dRad * fabs( m_dAngCenDeg) * DEGTORAD ; // aggiunta eventuale parte ortogonale - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) dLen = sqrt( dLen * dLen + m_dDeltaN * m_dDeltaN) ; return ( dLen > EPS_SMALL) ; @@ -1002,7 +1002,7 @@ CurveArc::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) const //---------------------------------------------------------------------------- bool -CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const +CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const { // pulisco la polilinea PL.Clear() ; @@ -1011,8 +1011,15 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) cons if ( m_nStatus != OK) return false ; + // determino se approssimazione interna o esterna + bool bCCW = ( (( m_VtExtr * m_VtN) > - EPS_ZERO) ? ( m_dAngCenDeg > 0) : ( m_dAngCenDeg < 0)) ; + bool bInside = true ; + if ( ( nType == APL_RIGHT && bCCW) || + ( nType == APL_LEFT && ! bCCW)) + bInside = false ; + // eseguo approssimazione - ArcApproxer aAppr( dLinTol, dAngTolDeg, true, *this) ; + ArcApproxer aAppr( dLinTol, dAngTolDeg, bInside, *this) ; double dU ; Point3d ptPos ; while ( aAppr.GetPoint( dU, ptPos)) { @@ -1117,7 +1124,7 @@ CurveArc::Invert( void) return false ; // il centro va spostato di DeltaN - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) m_PtCen += m_dDeltaN * m_VtN ; // il versore normale rimane inalterato // il versore iniziale diventa quello finale @@ -1352,7 +1359,7 @@ CurveArc::TrimStartAtLen( double dLenTrim) dAngRot = m_dAngCenDeg * dLenTrim / dLen ; m_VtS.Rotate( m_VtN, dAngRot) ; m_dAngCenDeg -= dAngRot ; - if ( fabs( m_dDeltaN) > EPS_ZERO) { + if ( fabs( m_dDeltaN) > EPS_SMALL) { dMoveN = m_dDeltaN * dLenTrim / dLen ; m_PtCen.Translate( m_VtN * dMoveN) ; m_dDeltaN -= dMoveN ; @@ -1382,7 +1389,7 @@ CurveArc::TrimEndAtLen( double dLenTrim) // eseguo il trim if ( ( dLen - dLenTrim) > EPS_ZERO) { m_dAngCenDeg *= dLenTrim / dLen ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) m_dDeltaN *= dLenTrim / dLen ; } @@ -1422,8 +1429,11 @@ CurveArc::ExtendEndByLen( double dLenExt) return false ; // eseguo l'estensione - m_dAngCenDeg *= ( dLen + dLenExt) / dLen ; - if ( IsFlat() && fabs( m_dAngCenDeg) > ANG_FULL) + double dCoeff = ( dLen + dLenExt) / dLen ; + m_dAngCenDeg *= dCoeff ; + if ( ! IsFlat()) + m_dDeltaN *= dCoeff ; + else if ( fabs( m_dAngCenDeg) > ANG_FULL) m_dAngCenDeg = _copysign( ANG_FULL, m_dAngCenDeg) ; // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata @@ -1500,7 +1510,7 @@ CurveArc::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dC if ( dCoeffX < 0) m_VtS = - m_VtS ; // scalo vettore estrusione, lo normalizzo e aggiusto spessore - m_VtExtr.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + m_VtExtr.Scale( frRef, dCoeffX, dCoeffX, dCoeffX) ; double dLen = m_VtExtr.Len() ; if ( dLen > EPS_ZERO) { m_VtExtr /= dLen ; @@ -1809,7 +1819,7 @@ CurveArc::Flip( void) if ( ! GetStartPoint( ptStart) || ! GetEndPoint( ptEnd)) return false ; // il punto finale mi interessa nel piano dell'arco - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) ptEnd -= m_dDeltaN * m_VtN ; m_PtCen = ptStart + ( ptEnd - m_PtCen) ; m_VtS = ptStart - m_PtCen ; @@ -1854,7 +1864,11 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const dAngTolDeg = min( dAngTolDeg, ANG_TOL_EXT_MAX_DEG) ; // determinazione dello step angolare - dAngStepDeg = sqrt( 8 * dLinTol / arArc.GetRadius()) * RADTODEG ; + double dLinTolRel = dLinTol / arArc.GetRadius() ; + if ( bInside) + dAngStepDeg = sqrt( 8 * dLinTolRel) * RADTODEG ; + else + dAngStepDeg = sqrt( 8 * dLinTolRel / ( 1 + dLinTolRel)) * RADTODEG ; dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ; // dall'angolo al centro ricavo il numero di passi @@ -1907,7 +1921,7 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP) if ( ! m_bInside && m_nCurrPnt == m_nTotPnt - 1) { dU = 1 ; ptP = m_PtCen + m_vtA1 * m_dRad ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) ptP += ( dU * m_dDeltaN) * m_VtN ; return true ; } @@ -1928,7 +1942,7 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP) ptP = m_PtCen + m_vtA1 * m_dRad ; else ptP = m_PtCen + ( vtA1p + m_vtA1) * ( m_dRad / ( 1 + m_dCosA)) ; - if ( fabs( m_dDeltaN) > EPS_ZERO) + if ( fabs( m_dDeltaN) > EPS_SMALL) ptP += ( dU * m_dDeltaN) * m_VtN ; return true ; diff --git a/CurveArc.h b/CurveArc.h index 9d95cc0..40b268b 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -100,7 +100,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW { return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; } virtual bool GetAreaXY( double& dArea) const { return CurveGetAreaXY( *this, dArea) ; } - virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; virtual bool Invert( void) ; diff --git a/CurveAux.cpp b/CurveAux.cpp index e4e8786..8e7a19c 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -267,7 +267,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea) return false ; // approssimo la curva con una polilinea PolyLine PL ; - crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, PL) ; + crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ; // calcolo l'area double dAreaXY = 0 ; PL.GetAreaXY( dAreaXY) ; @@ -374,7 +374,7 @@ ArcToBezierCurve( const ICurve* pCrv) if ( IsNull( pCrvCompo)) return nullptr ; // inserisco nella CC le curve di Bezier equivalenti alle parti dell'arco - int nParts = (int) ceil( fabs( pArc->GetAngCenter()) / BEZARC_ANG_CEN_MAX) ; + int nParts = (int) ceil( fabs( pArc->GetAngCenter()) / ( BEZARC_ANG_CEN_MAX + EPS_ANG_SMALL)) ; nParts = max( nParts, 2) ; for ( int i = 0 ; i < nParts ; ++ i) { // copio l'arco originale diff --git a/CurveBezier.cpp b/CurveBezier.cpp index fb19b7e..dcf7fb0 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -496,7 +496,7 @@ CurveBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const else { // costruisco una approssimazione lineare PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, PL)) + if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; // ciclo sui punti della approssimazione Point3d ptTemp ; @@ -532,7 +532,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const else { // costruisco una approssimazione lineare PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, PL)) + if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; // ciclo sui punti della approssimazione Point3d ptTemp ; @@ -664,7 +664,7 @@ CurveBezier::GetCentroid( Point3d& ptCen) const return false ; // approssimo la curva con una polilinea PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, PL)) + if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; // calcolo il centro mediante PolygonPlane Point3d ptP ; @@ -1312,7 +1312,7 @@ CurveBezier::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) co //---------------------------------------------------------------------------- bool -CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const +CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const { // pulisco la polilinea PL.Clear() ; @@ -1330,6 +1330,16 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) c dLinTol = max( dLinTol, LIN_TOL_MIN) ; dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; + // se lineare con lato obbligato, gestione speciale + if ( nType == APL_LEFT || nType == APL_RIGHT) { + // prima approssimazione lineare a 10 * Epsilon + if ( ! ApproxWithLines( 10 * EPS_SMALL, dAngTolDeg, APL_STD, PL)) + return false ; + // eliminazione dei punti in tolleranza andando solo dalla parte ammessa + Vector3d vtN = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ; + return PL.ApproxOnSide( vtN, ( nType == APL_LEFT), dLinTol) ; + } + // inserisco il punto iniziale if ( ! PL.AddUPoint( 0, m_aPtCtrl[0])) return false ; @@ -1468,7 +1478,7 @@ CurveBezier::ApproxWithArcsXY( double dLinTol, double dAngTolDeg, PolyArc& PA) c // costruisco una approssimazione lineare PolyLine PL ; - if ( ! ApproxWithLines( dLinTol, dAngTolDeg, PL)) + if ( ! ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, PL)) return false ; // approssimo la curva per approssimazioni successive mediante bisezione diff --git a/CurveBezier.h b/CurveBezier.h index fde05c0..a2a9558 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -101,7 +101,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW { return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; } virtual bool GetAreaXY( double& dArea) const { return CurveGetAreaXY( *this, dArea) ; } - virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; virtual bool Invert( void) ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index efa35e9..7f8ff6d 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -14,6 +14,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveComposite.h" +#include "DistPointLine.h" #include "DistPointCrvComposite.h" #include "CurveLine.h" #include "CurveArc.h" @@ -34,7 +35,7 @@ GEOOBJ_REGISTER( CRV_COMPO, NGE_C_CMP, CurveComposite) ; //---------------------------------------------------------------------------- CurveComposite::CurveComposite( void) - : m_nStatus( TO_VERIFY), m_nCounter(), m_bClosed( false), m_VtExtr(), m_dThick(), m_nTempProp() + : m_nStatus( TO_VERIFY), m_bClosed( false), m_VtExtr(), m_dThick(), m_nTempProp() { } @@ -56,7 +57,6 @@ CurveComposite::Clear( void) m_CrvSmplS.clear() ; m_nStatus = TO_VERIFY ; - m_nCounter = 0 ; m_bClosed = false ; m_VtExtr = V_NULL ; m_dThick = 0 ; @@ -172,7 +172,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT return false ; // verifico lo stato - if ( m_nStatus != OK && ! ( m_nCounter == 0 && m_nStatus == TO_VERIFY)) + if ( m_nStatus != OK && ! ( m_CrvSmplS.empty() && m_nStatus == TO_VERIFY)) return false ; // verifico che il parametro sia una curva semplice @@ -189,7 +189,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT return false ; // se non è la prima - if ( m_nCounter > 0) { + if ( ! m_CrvSmplS.empty()) { // se inserita alla fine if ( bEndOrStart) { // verifico sia in continuità con il finale attuale @@ -219,7 +219,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT } // se prima curva, assegno il punto iniziale o finale - if ( m_nCounter == 0) { + if ( m_CrvSmplS.empty()) { if ( bEndOrStart) m_PtStart = ptStart ; else @@ -231,7 +231,6 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT m_CrvSmplS.push_back( ::Release( pCrv)) ; else m_CrvSmplS.push_front( ::Release( pCrv)) ; - m_nCounter ++ ; // assegno il nuovo punto estremo if ( bEndOrStart) @@ -274,7 +273,7 @@ bool CurveComposite::FromSplit( const ICurve& cCrv, int nParts) { // verifico lo stato - if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + if ( ! m_CrvSmplS.empty() || m_nStatus != TO_VERIFY) return false ; // deve essere valida e semplice @@ -317,7 +316,7 @@ bool CurveComposite::FromPolyLine( const PolyLine& PL) { // verifico lo stato - if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + if ( ! m_CrvSmplS.empty() || m_nStatus != TO_VERIFY) return false ; // deve esserci almeno 1 linea (2 punti) if ( PL.GetLineNbr() < 1) @@ -355,7 +354,7 @@ bool CurveComposite::FromPolyArc( const PolyArc& PA) { // verifico lo stato - if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + if ( ! m_CrvSmplS.empty() || m_nStatus != TO_VERIFY) return false ; // deve esserci almeno 1 arco (2 punti) if ( PA.GetArcNbr() < 1) @@ -408,7 +407,7 @@ bool CurveComposite::PolygonCenterCorner( int nSides, const Point3d& ptCen, const Point3d& ptCorner, const Vector3d& vtN) { // verifico lo stato - if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + if ( ! m_CrvSmplS.empty() || m_nStatus != TO_VERIFY) return false ; // almeno 3 lati e normale ben definita if ( nSides < 3 || vtN.IsSmall()) @@ -456,7 +455,7 @@ bool CurveComposite::PolygonCenterMidSide( int nSides, const Point3d& ptCen, const Point3d& ptMidSide, const Vector3d& vtN) { // verifico lo stato - if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + if ( ! m_CrvSmplS.empty() || m_nStatus != TO_VERIFY) return false ; // almeno 3 lati e normale ben definita if ( nSides < 3 || vtN.IsSmall()) @@ -479,7 +478,7 @@ bool CurveComposite::PolygonSide( int nSides, const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtN) { // verifico lo stato - if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + if ( ! m_CrvSmplS.empty() || m_nStatus != TO_VERIFY) return false ; // almeno 3 lati e normale ben definita if ( nSides < 3 || vtN.IsSmall()) @@ -596,7 +595,7 @@ CurveComposite::Dump( string& sOut, const char* szNewLine) const if ( ! CurveDump( *this, sOut, szNewLine)) return false ; // parametri : numero di curve - sOut += "CrvNbr=" + ToString( m_nCounter) + szNewLine ; + sOut += "CrvNbr=" + ToString( int( m_CrvSmplS.size())) + szNewLine ; // ciclo sulle curve componenti int i = 0 ; const ICurve* pCrvSmpl = GetFirstCurve() ; @@ -625,7 +624,7 @@ bool CurveComposite::Save( NgeWriter& ngeOut) const { // numero di curve - if ( ! ngeOut.WriteInt( m_nCounter, nullptr, true)) + if ( ! ngeOut.WriteInt( int( m_CrvSmplS.size()), nullptr, true)) return false ; // ciclo sulle curve componenti int i = 0 ; @@ -796,7 +795,6 @@ CurveComposite::Validate( void) } // aggiorno m_nStatus = ( nCount > 0 ? OK : TO_VERIFY) ; - m_nCounter = nCount ; if ( m_nStatus == OK) { m_CrvSmplS.front()->GetStartPoint( m_PtStart) ; m_CrvSmplS.back()->GetEndPoint( m_PtEnd) ; @@ -984,7 +982,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const return false ; // approssimo la curva con una polilinea PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, PL)) + if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; // calcolo il centro mediante PolygonPlane Point3d ptP ; @@ -1009,7 +1007,7 @@ CurveComposite::GetMidDir( Vector3d& vtDir) const if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid)) return false ; // calcolo la direzione - return ::GetTang( *this, 0.5 * m_nCounter, FROM_MINUS, vtDir) ; + return ::GetTang( *this, 0.5 * m_CrvSmplS.size(), FROM_MINUS, vtDir) ; } //---------------------------------------------------------------------------- @@ -1021,8 +1019,8 @@ CurveComposite::GetDomain( double& dStart, double& dEnd) const return false ; // assegno gli estremi del dominio - dStart = 0 ; - dEnd = m_nCounter ; + dStart = 0.0 ; + dEnd = double( m_CrvSmplS.size()) ; return true ; } @@ -1031,28 +1029,31 @@ CurveComposite::GetDomain( double& dStart, double& dEnd) const bool CurveComposite::GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const { + // valore massimo del parametro + double dMaxU = double( m_CrvSmplS.size()) ; + // verifico che il parametro non sia troppo fuori dai limiti - if ( dU < - 100 * EPS_PARAM || dU > m_nCounter + 100 * EPS_PARAM) + if ( dU < - 100 * EPS_PARAM || dU > dMaxU + 100 * EPS_PARAM) return false ; // il parametro U deve essere compreso tra 0 e m_nCounter (le curve chiuse sono cicliche) if ( dU < ( 0 + EPS_PARAM)) { // se chiusa e voglio valutare prima dell'inizio devo valutare prima della fine if ( m_bClosed && nS == ICurve::FROM_MINUS) - dU = m_nCounter ; + dU = dMaxU ; // altrimenti posso valutare solo dopo l'inizio else { dU = 0 ; nS = ICurve::FROM_PLUS ; } } - else if ( dU > ( m_nCounter - EPS_PARAM)) { + else if ( dU > ( dMaxU - EPS_PARAM)) { // se chiusa e voglio valutare dopo la fine devo valutare dopo l'inizio if ( m_bClosed && nS == ICurve::FROM_PLUS) dU = 0 ; // altrimenti posso valutare solo prima della fine else { - dU = m_nCounter ; + dU = dMaxU ; nS = ICurve::FROM_MINUS ; } } @@ -1117,7 +1118,7 @@ CurveComposite::GetLengthAtParam( double dU, double& dLen) const return false ; // il parametro U deve essere compreso tra 0 e m_nCounter - if ( dU < - EPS_PARAM || dU > ( m_nCounter + EPS_PARAM)) + if ( dU < - EPS_PARAM || dU > ( double( m_CrvSmplS.size()) + EPS_PARAM)) return false ; // ciclo di calcolo @@ -1238,7 +1239,7 @@ CurveComposite::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) //---------------------------------------------------------------------------- bool -CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const +CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const { // pulisco la polilinea PL.Clear() ; @@ -1249,12 +1250,17 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL // eseguo approssimazione double dStartPar = 0 ; - PolyLine PLSmpl ; - PCSD_CONST_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( auto& pCrv : m_CrvSmplS) { + // assegno estrusione e spessore della curva composita + pCrv->SetExtrusion( m_VtExtr) ; + pCrv->SetThickness( m_dThick) ; // recupero approssimazione per curva semplice - if ( ! (*Iter)->ApproxWithLines( dLinTol, dAngTolDeg, PLSmpl)) + PolyLine PLSmpl ; + if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl)) return false ; + // ripristino estrusione e spessore della curva semplice (annullandoli) + pCrv->SetExtrusion( V_NULL) ; + pCrv->SetThickness( 0) ; // la accodo opportunamente a quella della curva composita if ( ! PL.Join( PLSmpl, dStartPar)) return false ; @@ -1278,14 +1284,12 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) // eseguo approssimazione double dStartPar = 0 ; - PolyArc PASmpl ; - PCSD_CONST_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { - ICurve* pCrv = (*Iter) ; + for ( auto& pCrv : m_CrvSmplS) { // assegno estrusione e spessore della curva composita pCrv->SetExtrusion( m_VtExtr) ; pCrv->SetThickness( m_dThick) ; // recupero approssimazione per curva semplice + PolyArc PASmpl ; if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl)) return false ; // ripristino estrusione e spessore della curva semplice (annullandoli) @@ -1308,9 +1312,11 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) ICurve* CurveComposite::CopyParamRange( double dUStart, double dUEnd) const { + // valore massimo del parametro + double dMaxU = double( m_CrvSmplS.size()) ; // i parametri start ed end devono essere compresi nel dominio parametrico della curva - if ( dUStart < - EPS_PARAM || dUStart > m_nCounter + EPS_PARAM || - dUEnd < - EPS_PARAM || dUEnd > m_nCounter + EPS_PARAM) + if ( dUStart < - EPS_PARAM || dUStart > dMaxU + EPS_PARAM || + dUEnd < - EPS_PARAM || dUEnd > dMaxU + EPS_PARAM) return nullptr ; // se il parametro start supera quello di end if ( dUStart > dUEnd - EPS_PARAM) { @@ -1320,7 +1326,7 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const // se curva chiusa, il trim si avvolge attorno al punto di giunzione else // incremento il parametro finale della dimensione del dominio parametrico originale della curva - dUEnd += m_nCounter ; + dUEnd += dMaxU ; } // determino gli indici della prima e dell'ultima curva da copiare int nIdStart = static_cast( floor( dUStart)) ; @@ -1332,7 +1338,7 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const // eseguo la copia delle sole curve semplici necessarie for ( int i = nIdStart ; i < nIdEnd ; ++ i) { // quando supero il numero di curve nella composita originale riparto dall'inizio - int j = i % m_nCounter ; + int j = i % m_CrvSmplS.size() ; // accodo la curva alla copia if ( ! pCopy->AddCurve( *(m_CrvSmplS[j]))) return nullptr ; @@ -1471,7 +1477,6 @@ CurveComposite::TrimStartAtParam( double dUTrim) delete (*Iter) ; Iter ++ ; m_CrvSmplS.pop_front() ; - m_nCounter -- ; } // se lunghezza ancora da tagliare nulla (entro la tolleranza) else if ( dUToTrim > - EPS_PARAM || @@ -1479,8 +1484,7 @@ CurveComposite::TrimStartAtParam( double dUTrim) delete (*Iter) ; Iter ++ ; m_CrvSmplS.pop_front() ; - m_nCounter -- ; - if ( m_nCounter == 0) + if ( m_CrvSmplS.empty()) return false ; (*Iter)->GetStartPoint( m_PtStart) ; m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ; @@ -1519,8 +1523,6 @@ CurveComposite::TrimEndAtParam( double dUTrim) // cancello l'entità, la tolgo dalla lista e passo alla successiva delete (*Iter) ; Iter = m_CrvSmplS.erase( Iter) ; - // decremento il numero di entità - m_nCounter -- ; } // se lunghezza parametrica ancora da tagliare non nulla else if ( dUToTrim > EPS_PARAM) { @@ -1564,9 +1566,11 @@ CurveComposite::TrimEndAtParam( double dUTrim) bool CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim) { + // valore massimo del parametro + double dMaxU = double( m_CrvSmplS.size()) ; // i parametri start ed end devono essere compresi nel dominio parametrico della curva - if ( dUStartTrim < - EPS_PARAM || dUStartTrim > m_nCounter + EPS_PARAM || - dUEndTrim < - EPS_PARAM || dUEndTrim > m_nCounter + EPS_PARAM) + if ( dUStartTrim < - EPS_PARAM || dUStartTrim > dMaxU + EPS_PARAM || + dUEndTrim < - EPS_PARAM || dUEndTrim > dMaxU + EPS_PARAM) return false ; // se il parametro start supera quello di end if ( dUStartTrim > dUEndTrim - EPS_PARAM) { @@ -1578,7 +1582,7 @@ CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim) // calcolo il minimo numero di curve da accodare per coprire il range esteso int nNumCrv = static_cast( ceil( dUEndTrim)) ; // incremento il parametro finale della dimensione del dominio parametrico originale della curva - dUEndTrim += m_nCounter ; + dUEndTrim += dMaxU ; // eseguo accodamento delle curve for ( int i = 0 ; i < nNumCrv ; ++ i) { if ( ! AddCurve( *(m_CrvSmplS[i]))) @@ -1628,8 +1632,7 @@ CurveComposite::TrimStartAtLen( double dLenTrim) delete (*Iter) ; Iter ++ ; m_CrvSmplS.pop_front() ; - m_nCounter -- ; - if ( m_nCounter == 0) + if ( m_CrvSmplS.empty()) return false ; } // se lunghezza ancora da tagliare nulla (entro la tolleranza) @@ -1637,8 +1640,7 @@ CurveComposite::TrimStartAtLen( double dLenTrim) delete (*Iter) ; Iter ++ ; m_CrvSmplS.pop_front() ; - m_nCounter -- ; - if ( m_nCounter == 0) + if ( m_CrvSmplS.empty()) return false ; (*Iter)->GetStartPoint( m_PtStart) ; m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ; @@ -1685,8 +1687,6 @@ CurveComposite::TrimEndAtLen( double dLenTrim) // cancello l'entità, la tolgo dalla lista e passo alla successiva delete (*Iter) ; Iter = m_CrvSmplS.erase( Iter) ; - // decremento il numero di entità - m_nCounter -- ; } // se lunghezza ancora da tagliare non nulla else if ( dLenToTrim > EPS_SMALL) { @@ -2131,7 +2131,6 @@ CurveComposite::RemoveFirstOrLastCurve( bool bLast) m_CrvSmplS.pop_back() ; // aggiorno la curva composita pCrv->GetStartPoint( m_PtEnd) ; - -- m_nCounter ; } else { // recupero la curva @@ -2140,10 +2139,9 @@ CurveComposite::RemoveFirstOrLastCurve( bool bLast) m_CrvSmplS.pop_front() ; // aggiorno la curva composita pCrv->GetEndPoint( m_PtStart) ; - -- m_nCounter ; } // eseguo mini verifica - m_nStatus = ( m_nCounter > 0 ? OK : TO_VERIFY) ; + m_nStatus = ( m_CrvSmplS.size() > 0 ? OK : TO_VERIFY) ; if ( m_nStatus == OK) m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ; else @@ -2163,7 +2161,7 @@ CurveComposite::IsParamAtJoint( double dU) const { // se aperta e all'inizio o alla fine o lontano dagli interi non è giunzione if ( ( ! m_bClosed && fabs( dU) < EPS_ZERO) || - ( ! m_bClosed && fabs( dU - m_nCounter) < EPS_ZERO) || + ( ! m_bClosed && fabs( dU - double( m_CrvSmplS.size())) < EPS_ZERO) || fabs( dU - (int) ( dU + EPS_ZERO)) > EPS_ZERO) return false ; else @@ -2213,13 +2211,10 @@ CurveComposite::ArcsToBezierCurves( void) ++ nParts ; } pCC->m_CrvSmplS.clear() ; - pCC->m_nCounter = 0 ; // elimino l'arco (e sposto l'iteratore alla curva precedente) delete (*Iter) ; Iter = m_CrvSmplS.erase( Iter) ; -- Iter ; - // aggiorno il numero di curve - m_nCounter += nParts - 1 ; } } } @@ -2235,8 +2230,7 @@ bool CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) { // verifico le singole curve - PCSD_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++ Iter) { // se arco in piano non perpendicolare ad estrusione o curva di Bezier trasformo if ( ( (*Iter)->GetType() == CRV_ARC && ! GetBasicCurveArc((*Iter))->IsInPlanePerpExtr()) || (*Iter)->GetType() == CRV_BEZ) { @@ -2264,13 +2258,10 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe ++ nParts ; } pCC->m_CrvSmplS.clear() ; - pCC->m_nCounter = 0 ; // elimino l'arco (e sposto l'iteratore alla curva precedente) delete (*Iter) ; Iter = m_CrvSmplS.erase( Iter) ; -- Iter ; - // aggiorno il numero di curve - m_nCounter += nParts - 1 ; } } } @@ -2279,4 +2270,148 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe m_OGrMgr.Reset() ; return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg) +{ + // se non ci sono almeno 2 curve, esco subito + if ( m_CrvSmplS.size() < 2) + return true ; + // controllo sui limiti di tolleranza + dLinTol = max( dLinTol, EPS_SMALL) ; + dAngTolDeg = max( dAngTolDeg, EPS_ANG_SMALL) ; + // tolleranza lineare corrente + double dCurrLinTol = dLinTol ; + // devo verificare coppie di curve + auto iterP = m_CrvSmplS.begin() ; + auto iterC = next( iterP) ; + // mentre esiste la coppia + while ( iterC != m_CrvSmplS.end()) { + // se curve unite + if ( MergeTwoCurves( *iterP, *iterC, dCurrLinTol, dAngTolDeg)) { + // cancello l'entità precedente e la tolgo dalla lista + delete (*iterP) ; + iterC = m_CrvSmplS.erase( iterP) ; + } + // altrimenti ripristino la tolleranza + else + dCurrLinTol = dLinTol ; + // avanzo + iterP = iterC ; + iterC = next( iterC) ; + } + // se curva chiusa devo confrontare anche ultima e prima curva + if ( IsClosed()) { + if ( MergeTwoCurves( *iterP, *(m_CrvSmplS.begin()), dCurrLinTol, dAngTolDeg)) { + // cancello l'entità precedente e la tolgo dalla lista + delete (*iterP) ; + iterC = m_CrvSmplS.erase( iterP) ; + } + } + + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dAngTolDeg) +{ + // coefficiente deduzione tolleranza + const double COEFF_TOL = 0.7 ; + // se entrambe rette + if ( pCrvP->GetType() == CRV_LINE && pCrvC->GetType() == CRV_LINE) { + CurveLine* pLineP = GetBasicCurveLine( pCrvP) ; + CurveLine* pLineC = GetBasicCurveLine( pCrvC) ; + // verifico se allineate + Vector3d vtDirP, vtDirC ; + if ( pLineP != nullptr && pLineP->GetStartDir( vtDirP) && + pLineC != nullptr && pLineC->GetStartDir( vtDirC) && + ( vtDirP * vtDirC) >= cos( dAngTolDeg * DEGTORAD)) { + // verifico se il punto di giunzione sia eliminabile + DistPointLine dPL( pLineP->GetEnd(), pLineP->GetStart(), pLineC->GetEnd()) ; + double dSqDist ; + // se da eliminare + if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrLinTol * dCurrLinTol) { + // se calcolo nuova linea ok, procedo con l'unione + CurveLine NewLine ; + if ( NewLine.Set( pLineP->GetStart(), pLineC->GetEnd())) { + // diminuisco la tolleranza corrente dell'errore attuale + dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ; + // aggiorno la linea corrente e torno flag modifica + *pLineC = NewLine ; + return true ; + } + } + } + } + // se entrambi archi + else if ( pCrvP->GetType() == CRV_ARC && pCrvC->GetType() == CRV_ARC) { + CurveArc* pArcP = GetBasicCurveArc( pCrvP) ; + CurveArc* pArcC = GetBasicCurveArc( pCrvC) ; + // centro del primo arco riportato alla quota del punto finale sulla normale dello stesso + Point3d ptC1Fin = pArcP->GetCenter() + pArcP->GetNormVersor() * pArcP->GetDeltaN() ; + // centro del secondo arco alla quota del punto iniziale sulla normale dello stesso + Point3d ptC2Ini = pArcC->GetCenter() ; + // verifico la coincidenza dei centri + if ( ! AreSamePointEpsilon( ptC1Fin, ptC2Ini, dCurrLinTol)) + return false ; + // verifico la coincidenza dei raggi + if ( fabs( pArcP->GetRadius() - pArcC->GetRadius()) > dCurrLinTol) + return false ; + // verifico la collinearità delle normali (tenendo conto del raggio) + if ( ! (( pArcP->GetNormVersor() - pArcC->GetNormVersor()) * pArcP->GetRadius()).IsSmall() && + ! (( pArcP->GetNormVersor() + pArcC->GetNormVersor()) * pArcP->GetRadius()).IsSmall()) + return false ; + // verifico la coincidenza del senso di rotazione (verso delle normali e segno angoli al centro) + if ( pArcP->GetNormVersor() * pArcC->GetNormVersor() * pArcP->GetAngCenter() * pArcC->GetAngCenter() < 0) + return false ; + // se archi piatti + if ( pArcP->IsFlat() && pArcC->IsFlat()) { + // se calcolo nuovo arco ok, procedo con l'unione + Point3d ptP1 ; + pArcP->GetStartPoint( ptP1) ; + Point3d ptP2 ; + pArcP->GetEndPoint( ptP2) ; + Point3d ptP3 ; + pArcC->GetEndPoint( ptP3) ; + CurveArc NewArc ; + if ( NewArc.Set3P( ptP1, ptP2, ptP3)) { + // verifico normale al piano dell'arco + if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0) + NewArc.InvertN() ; + // aggiorno l'arco corrente e torno flag modifica + *pArcC = NewArc ; + return true ; + } + else + return false ; + } + // verifico coincidenza pendenza sulla normale + double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ; + if ( fabs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) / + ( pArcP->GetAngCenter() + pArcC->GetAngCenter())) < dCurrLinTol) { + // se calcolo nuovo arco ok, procedo con l'unione + Point3d ptP1 ; + pArcP->GetStartPoint( ptP1) ; + Vector3d vtDir1 ; + pArcP->GetStartDir( vtDir1) ; + Point3d ptP3 ; + pArcC->GetEndPoint( ptP3) ; + CurveArc NewArc ; + if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) { + // aggiorno l'arco corrente e torno flag modifica + *pArcC = NewArc ; + return true ; + } + else + return false ; + } + } + // nessuna fusione + return false ; } \ No newline at end of file diff --git a/CurveComposite.h b/CurveComposite.h index f4a591b..5982965 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -70,7 +70,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW virtual bool GetStartDir( Vector3d& vtDir) const { return ::GetTang( *this, 0, FROM_PLUS, vtDir) ; } virtual bool GetEndDir( Vector3d& vtDir) const - { return ::GetTang( *this, m_nCounter, FROM_MINUS, vtDir) ; } + { return ::GetTang( *this, double( m_CrvSmplS.size()), FROM_MINUS, vtDir) ; } virtual bool GetMidDir( Vector3d& vtDir) const ; virtual bool GetExtrusion( Vector3d& vtExtr) const { vtExtr = m_VtExtr ; return ( m_nStatus == OK) ; } @@ -100,7 +100,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW { return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; } virtual bool GetAreaXY( double& dArea) const { return CurveGetAreaXY( *this, dArea) ; } - virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; virtual bool Invert( void) ; @@ -132,7 +132,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW virtual bool PolygonCenterMidSide( int nSides, const Point3d& ptCen, const Point3d& ptMidSide, const Vector3d& vtN) ; virtual bool PolygonSide( int nSides, const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtN) ; virtual int GetCurveNumber( void) const - { return m_nCounter ; } + { return int( m_CrvSmplS.size()) ; } virtual const ICurve* GetCurve( int nCrv) const ; virtual const ICurve* GetFirstCurve( void) const ; virtual const ICurve* GetNextCurve( void) const ; @@ -143,6 +143,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW virtual bool ChangeStartPoint( double dU) ; virtual bool ArcsToBezierCurves( void) ; virtual bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) ; + virtual bool MergeCurves( double dLinTol, double dAngTolDeg) ; public : // IGeoObjRW virtual int GetNgeId( void) const ; @@ -169,6 +170,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ; bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ; bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET) ; + bool MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dAngTolDeg) ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; @@ -181,7 +183,6 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto Status m_nStatus ; // stato - int m_nCounter ; // contatore del numero di curve PCRVSMPL_DEQUE m_CrvSmplS ; // deque di curve semplici Point3d m_PtStart ; // punto iniziale Point3d m_PtEnd ; // punto finale diff --git a/CurveLine.cpp b/CurveLine.cpp index 260f2b2..b375eaf 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -477,7 +477,7 @@ CurveLine::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) cons //---------------------------------------------------------------------------- bool -CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const +CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const { // pulisco la polilinea PL.Clear() ; diff --git a/CurveLine.h b/CurveLine.h index bebf4ad..c0e7b1a 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -101,7 +101,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW { return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; } virtual bool GetAreaXY( double& dArea) const { return false ; } - virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; virtual bool Invert( void) ; diff --git a/DistPointArc.cpp b/DistPointArc.cpp index 1f6de07..75c1bb2 100644 --- a/DistPointArc.cpp +++ b/DistPointArc.cpp @@ -117,7 +117,7 @@ DistPointArc::DistPointHelix( const Point3d& ptP, const ICurveArc& arArc) // creo una polilinea di approssimazione PolyLine PL ; - if ( ! arArc.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, PL)) + if ( ! arArc.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL)) return ; // cerco la minima distanza per la polilinea diff --git a/DistPointCrvBezier.cpp b/DistPointCrvBezier.cpp index c1abbb5..3fb2de5 100644 --- a/DistPointCrvBezier.cpp +++ b/DistPointCrvBezier.cpp @@ -39,7 +39,7 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& // creo una polilinea di approssimazione PolyLine PL ; - if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, PL)) + if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL)) return ; // cerco la minima distanza per la polilinea diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index a5b4b53d41a801e46b8b2aa0cf83f38191cb59c5..e5077bf30f6a694fa6132f2f929f524b4775619b 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&Qw&A-_cnHh~ID{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-W11TR delta 94 zcmdlNy)SyhFE&P_&A-_cnHh~HD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-Vf-5U diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index dac07e1..47bbca7 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -393,6 +393,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 4ba659c..5897fbe 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -665,6 +665,9 @@ File di intestazione\Include + + File di intestazione\Include + diff --git a/FontNfe.cpp b/FontNfe.cpp index 4b7ec3c..e7df713 100644 --- a/FontNfe.cpp +++ b/FontNfe.cpp @@ -361,7 +361,7 @@ NfeFont::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, doub pCrvNew->Translate( vtMove) ; // approssimo con linee lstPL.emplace_back() ; - pCrvNew->ApproxWithLines( dLinTol, dAngTolDeg, lstPL.back()) ; + pCrvNew->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, lstPL.back()) ; } bIter = pIter->GoToNext() ; } diff --git a/FontOs.cpp b/FontOs.cpp index 44632d3..d7a90df 100644 --- a/FontOs.cpp +++ b/FontOs.cpp @@ -379,7 +379,7 @@ OsFont::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, doubl (*iIter)->Translate( vtMove) ; // approssimo con rette lstPL.emplace_back() ; - if ( ! (*iIter)->ApproxWithLines( dLinTol, dAngTolDeg, lstPL.back())) + if ( ! (*iIter)->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, lstPL.back())) return false ; } vtMove += Vector3d( dAdvance * dScaX + m_dAddAdvance, 0, 0) ; diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 93f395d..5a86ef8 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -1858,7 +1858,7 @@ GdbExecutor::CurveCompoFromCurveApproximation( const STRVECTOR& vsParams) return false ; if ( nType == 1) { // con linee PolyLine PL ; - if ( ! CrvLoc.Get()->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL) || + if ( ! CrvLoc.Get()->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) || ! pCC->FromPolyLine( PL)) return false ; } diff --git a/IntersCurveCurve.cpp b/IntersCurveCurve.cpp index 2e8a41d..a2881dc 100644 --- a/IntersCurveCurve.cpp +++ b/IntersCurveCurve.cpp @@ -504,7 +504,7 @@ bool IntersCurveCurve::GetCurveOutClass( const ICurve* pCurve, int& nClass) { PolyLine PL ; - if ( ! pCurve->ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, PL)) + if ( ! pCurve->ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL)) return false ; double dArea ; if ( ! PL.GetAreaXY( dArea)) diff --git a/OutTsc.cpp b/OutTsc.cpp index c69fd50..4a5f41e 100644 --- a/OutTsc.cpp +++ b/OutTsc.cpp @@ -478,7 +478,7 @@ OutTsc::PutCurve( const ICurve* pCurve, int nFlag) Point3d ptIni ; Point3d ptFin ; PolyLine PL ; - pCurve->ApproxWithLines( 0.1, 5, PL) ; + pCurve->ApproxWithLines( 0.1, 5, ICurve::APL_STD, PL) ; for ( bool bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) Line2P( ptIni, ptFin) ; diff --git a/PolyArc.cpp b/PolyArc.cpp index b364b92..095e421 100644 --- a/PolyArc.cpp +++ b/PolyArc.cpp @@ -22,7 +22,6 @@ PolyArc::PolyArc( void) { m_vtExtr = Z_AX ; m_nRejected = 0 ; - m_nCount = 0 ; m_iter = m_lUPointBs.end() ; } @@ -37,7 +36,6 @@ PolyArc::Clear( void) { m_vtExtr = Z_AX ; m_nRejected = 0 ; - m_nCount = 0 ; m_lUPointBs.clear() ; m_iter = m_lUPointBs.end() ; return true ; @@ -59,7 +57,7 @@ bool PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge) { // se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok - if ( m_nCount > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) { + if ( m_lUPointBs.size() > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) { ++ m_nRejected ; return true ; } @@ -70,8 +68,6 @@ PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge) return false ; } - m_nCount ++ ; - return true ; } @@ -109,7 +105,6 @@ PolyArc::EraseFirstUPoint( void) return false ; m_lUPointBs.pop_front() ; - m_nCount -- ; return true ; } @@ -122,7 +117,6 @@ PolyArc::EraseLastUPoint( void) return false ; m_lUPointBs.pop_back() ; - m_nCount -- ; return true ; } @@ -280,10 +274,10 @@ bool PolyArc::Join( PolyArc& PA, double dOffsetPar) { // se l'altro poliarco non contiene alcunchè, esco con ok - if ( PA.m_nCount == 0) + if ( PA.m_lUPointBs.size() == 0) return true ; // verifico che l'ultimo punto di questo poliarco coincida con il primo dell'altro - if ( m_nCount > 0 && ! AreSamePointApprox( m_lUPointBs.back().ptP, PA.m_lUPointBs.front().ptP)) + if ( m_lUPointBs.size() > 0 && ! AreSamePointApprox( m_lUPointBs.back().ptP, PA.m_lUPointBs.front().ptP)) return false ; // cancello l'ultimo di questo EraseLastUPoint() ; @@ -292,8 +286,6 @@ PolyArc::Join( PolyArc& PA, double dOffsetPar) PA.AddOffsetToU( dOffsetPar) ; // sposto i punti dall'altra polilinea a questa e aggiorno i contatori m_lUPointBs.splice( m_lUPointBs.end(), PA.m_lUPointBs) ; - m_nCount += PA.GetPointNbr() ; - PA.m_nCount = 0 ; return true ; } @@ -313,11 +305,8 @@ PolyArc::Split( double dU, PolyArc& PA) return false ; // sposto i punti nell'altra polilinea PA.m_lUPointBs.splice( PA.m_lUPointBs.end(), m_lUPointBs, iter, m_lUPointBs.end()) ; - PA.m_nCount = int( PA.m_lUPointBs.size()) ; - m_nCount -= PA.m_nCount ; // prepongo l'ultimo punto rimasto PA.m_lUPointBs.push_front( m_lUPointBs.back()) ; - ++ PA.m_nCount ; // annullo l'iteratore corrente m_iter = m_lUPointBs.end() ; @@ -471,7 +460,7 @@ PolyArc::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) con ptCen += ptP ; } // aggiusto il centro - ptCen /= m_nCount ; + ptCen /= double( m_lUPointBs.size()) ; return ( nRank == 0 || nRank == 2) ; } diff --git a/PolyLine.cpp b/PolyLine.cpp index c2c8035..de5f016 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -13,18 +13,21 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" +#include "CurveLine.h" #include "DistPointLine.h" +#include "IntersLineLine.h" #include "PolygonPlane.h" #include "PointsPCA.h" -#include "\EgtDev\Include\EGkPolyLine.h" -#include "\EgtDev\Include\EGkPlane3d.h" +#include "/EgtDev/Include/EGkPolyLine.h" +#include "/EgtDev/Include/EGkPlane3d.h" +#include "/EgtDev/Include/EGnStringUtils.h" +using namespace std ; //---------------------------------------------------------------------------- PolyLine::PolyLine( void) { m_nRejected = 0 ; - m_nCount = 0 ; m_iter = m_lUPoints.end() ; } @@ -38,7 +41,6 @@ bool PolyLine::Clear( void) { m_nRejected = 0 ; - m_nCount = 0 ; m_lUPoints.clear() ; m_iter = m_lUPoints.end() ; return true ; @@ -49,7 +51,7 @@ bool PolyLine::AddUPoint( double dPar, const Point3d& ptP) { // se il punto è uguale al precedente (ignoro parametro), non lo inserisco ma ok - if ( m_nCount > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) { + if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) { ++ m_nRejected ; return true ; } @@ -61,8 +63,6 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP) return false ; } - ++ m_nCount ; - return true ; } @@ -88,7 +88,6 @@ PolyLine::EraseFirstUPoint( void) return false ; m_lUPoints.pop_front() ; - -- m_nCount ; return true ; } @@ -101,7 +100,6 @@ PolyLine::EraseLastUPoint( void) return false ; m_lUPoints.pop_back() ; - -- m_nCount ; return true ; } @@ -214,20 +212,18 @@ bool PolyLine::Join( PolyLine& PL, double dOffsetPar) { // se l'altra polilinea non contiene alcunchè, esco con ok - if ( PL.m_nCount == 0) + if ( PL.m_lUPoints.size() == 0) return true ; // verifico che l'ultimo punto di questa polilinea coincida con il primo dell'altra - if ( m_nCount > 0 && ! AreSamePointApprox( m_lUPoints.back().first, PL.m_lUPoints.front().first)) + if ( m_lUPoints.size() > 0 && ! AreSamePointApprox( m_lUPoints.back().first, PL.m_lUPoints.front().first)) return false ; // cancello l'ultimo di questa EraseLastUPoint() ; // aggiungo eventuale offset all'altra if ( fabs( dOffsetPar) > EPS_PARAM) PL.AddOffsetToU( dOffsetPar) ; - // sposto i punti dall'altra polilinea a questa e aggiorno i contatori + // sposto i punti dall'altra polilinea a questa m_lUPoints.splice( m_lUPoints.end(), PL.m_lUPoints) ; - m_nCount += PL.GetPointNbr() ; - PL.m_nCount = 0 ; return true ; } @@ -247,11 +243,8 @@ PolyLine::Split( double dU, PolyLine& PL) return false ; // sposto i punti nell'altra polilinea PL.m_lUPoints.splice( PL.m_lUPoints.end(), m_lUPoints, iter, m_lUPoints.end()) ; - PL.m_nCount = int( PL.m_lUPoints.size()) ; - m_nCount -= PL.m_nCount ; // prepongo l'ultimo punto rimasto PL.m_lUPoints.push_front( m_lUPoints.back()) ; - ++ PL.m_nCount ; // annullo l'iteratore corrente m_iter = m_lUPoints.end() ; @@ -606,8 +599,8 @@ PolyLine::GetAreaXY( double& dArea) const //---------------------------------------------------------------------------- bool -PolyLine::GetMaxDistanceFromLine( double& dMaxDist, const Point3d& ptAx, - const Vector3d& vtAx, double dLen, bool bIsSegment) const +PolyLine::GetMaxDistanceFromLine( const Point3d& ptLine, const Vector3d& vtLine, double dLen, + double& dMaxDist, bool bIsSegment) const { // Verifico che la polilinea esista if ( GetPointNbr() < 1) @@ -616,7 +609,7 @@ PolyLine::GetMaxDistanceFromLine( double& dMaxDist, const Point3d& ptAx, dMaxDist = 0 ; Point3d ptP ; for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) { - DistPointLine dstPL( ptP, ptAx, vtAx, dLen, bIsSegment) ; + DistPointLine dstPL( ptP, ptLine, vtLine, dLen, bIsSegment) ; double dDist ; if ( dstPL.GetDist( dDist) && dDist > dMaxDist) dMaxDist = dDist ; @@ -627,7 +620,7 @@ PolyLine::GetMaxDistanceFromLine( double& dMaxDist, const Point3d& ptAx, //---------------------------------------------------------------------------- bool -PolyLine::AdjustForMaxSegmentLen( double& dMaxLen) +PolyLine::AdjustForMaxSegmentLen( double dMaxLen) { PNTULIST::iterator iter = m_lUPoints.begin() ; // se non ci sono punti, esco subito @@ -655,7 +648,6 @@ PolyLine::AdjustForMaxSegmentLen( double& dMaxLen) double dCoeff = double( i) / nStep ; m_lUPoints.insert( iter, POINTU( Media( ptPprec, ptPcurr, dCoeff), (( 1 - dCoeff) * dUprec + dCoeff * dUcurr))) ; - ++ m_nCount ; } } // passo al successivo @@ -671,6 +663,178 @@ PolyLine::AdjustForMaxSegmentLen( double& dMaxLen) return true ; } +//---------------------------------------------------------------------------- +bool +PolyLine::RemoveAlignedPoints( double dToler) +{ + // se non ci sono almeno 3 punti, esco subito + if ( m_lUPoints.size() < 3) + return true ; + // coefficiente deduzione tolleranza + const double COEFF_TOL = 0.7 ; + // si analizza la distanza di un punto dal segmento che unisce precente e successivo + // punto precedente + auto precP = m_lUPoints.begin() ; + // punto corrente + auto currP = next( precP) ; + // punto successivo + auto nextP = next( currP) ; + // assegno la tolleranza corrente + double dCurrToler = dToler ; + // mentre esiste un successivo + while ( nextP != m_lUPoints.end()) { + // distanza del punto corrente dal segmento che unisce gli adiacenti + DistPointLine dPL( currP->first, precP->first, nextP->first) ; + double dSqDist ; + // se da eliminare + if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrToler * dCurrToler) { + // diminuisco la tolleranza corrente dell'errore attuale + dCurrToler -= COEFF_TOL * sqrt( dSqDist) ; + // elimino il punto + m_lUPoints.erase( currP) ; + // avanzo con corrente e successivo + currP = nextP ; + ++ nextP ; + } + // altrimenti da tenere + else { + // ripristino la tolleranza corrente + dCurrToler = dToler ; + // avanzo il terzetto di uno step + precP = currP ; + currP = nextP ; + ++ nextP ; + } + } + // se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura + if ( IsClosed() && m_lUPoints.size() >= 4) { + // precP e currP sono già corretti + // il primo punto ripete l'ultimo (geometricamente coincide con currP) + auto firstP = m_lUPoints.begin() ; + // questo è il vero successivo + nextP = next( firstP) ; + // distanza del punto corrente dal segmento che unisce gli adiacenti + DistPointLine dPL( currP->first, precP->first, nextP->first) ; + double dSqDist ; + // se da eliminare + if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrToler * dCurrToler) { + // faccio coincidere il primo punto con il precedente + firstP->first = precP->first ; + // elimino il punto corrente + m_lUPoints.erase( currP) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyLine::ApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler) +{ + // se non ci sono almeno 3 punti, esco subito + if ( m_lUPoints.size() < 3) + return true ; + // coefficienti deduzione tolleranza + const double COEFF_TOL = 0.7 ; + // punto precedente + auto precP = m_lUPoints.begin() ; + // punto corrente + auto currP = next( precP) ; + // punto successivo + auto nextP = next( currP) ; + // assegno la tolleranza corrente + double dCurrToler = dToler ; + // mentre esiste un successivo + while ( nextP != m_lUPoints.end()) { + // --- si verifica se possibile eliminare il punto corrente rimanendo dal lato voluto e in tolleranza --- + // distanza del punto corrente dal segmento che unisce gli adiacenti + DistPointLine dPL( currP->first, precP->first, nextP->first) ; + double dSqDist = INFINITO * INFINITO ; + dPL.GetSqDist( dSqDist) ; + // se punti allineati + if ( dSqDist < EPS_SMALL * EPS_SMALL) { + // ripristino la tolleranza corrente + dCurrToler = dToler ; + // elimino il corrente + m_lUPoints.erase( currP) ; + // avanzo con corrente e successivo + currP = nextP ; + ++ nextP ; + continue ; + } + // se lato sinistro e gira a sinistra o lato destro e gira a destra + double dCrossXY = ( ( currP->first - precP->first) ^ ( nextP->first - currP->first)) * vtN ; + if ( ( bLeftSide && dCrossXY > 0) || ( ! bLeftSide && dCrossXY < 0)) { + // se eliminabile + if ( dSqDist < dCurrToler * dCurrToler) { + // diminuisco la tolleranza corrente dell'errore attuale + dCurrToler -= COEFF_TOL * sqrt( dSqDist) ; + // elimino il punto corrente + m_lUPoints.erase( currP) ; + // avanzo con corrente e successivo + currP = nextP ; + ++ nextP ; + continue ; + } + } + // --- si verifica se possibile elimare segmento da corrente a successivo rimanendo in tolleranza e dal lato voluto --- + // punto successivo del successivo + auto nex2P = next( nextP) ; + if ( nex2P != m_lUPoints.end()) { + double dCros2XY = ( ( nextP->first - currP->first) ^ ( nex2P->first - nextP->first)) * vtN ; + // se lato sinistro e 2 giri a destra o lato destro e 2 giri a sinistra + if ( ( bLeftSide && dCrossXY < 0 && dCros2XY < 0) || + ( ! bLeftSide && dCrossXY > 0 && dCros2XY > 0)) { + // calcolo del punto di intersezione tra i segmenti precP-currP e nextP-next2P, allungati al centro + CurveLine Line1, Line2 ; + if ( Line1.Set( precP->first, currP->first) && Line1.ExtendEndByLen( 1000) && + Line2.Set( nextP->first, nex2P->first) && Line2.ExtendStartByLen( 1000)) { + // se la normale non coincide con l'asse Z, devo portare le linee nel riferimento OCS di questa + Frame3d frNorm ; + if ( ! vtN.IsZplus() && ! vtN.IsZminus()) + frNorm.Set( ORIG, vtN) ; + Line1.ToLoc( frNorm) ; + Line2.ToLoc( frNorm) ; + IntersLineLine IntLL( Line1, Line2) ; + IntCrvCrvInfo IntInfo ; + if ( IntLL.GetIntCrvCrvInfo( IntInfo) && ! IntInfo.bOverlap) { + Point3d ptInt = 0.5 * ( IntInfo.IciA[0].ptI + IntInfo.IciB[0].ptI) ; + ptInt.ToGlob( frNorm) ; + // verifico che distanza dell'intersezione dal segmento currP-nextP sia inferiore a tolleranza corrente + DistPointLine dIL( ptInt, currP->first, nextP->first) ; + double dSqDist2 = INFINITO * INFINITO ; + dIL.GetSqDist( dSqDist2) ; + // se eliminabile + if ( dSqDist2 < dCurrToler * dCurrToler) { + // diminuisco la tolleranza corrente dell'errore attuale + dCurrToler -= COEFF_TOL * sqrt( dSqDist2) ; + // sposto il successivo sull'intersezione e ne aggiorno il parametro + nextP->first = ptInt ; + nextP->second = 0.5 * ( currP->second + nextP->second) ; + // elimino il punto corrente + m_lUPoints.erase( currP) ; + // avanzo con corrente e successivo + currP = nextP ; + nextP = nex2P ; + continue ; + } + } + } + } + } + // non è stato eliminato alcunché + // ripristino la tolleranza corrente + dCurrToler = dToler ; + // avanzo il terzetto di uno step + precP = currP ; + currP = nextP ; + ++ nextP ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool PolyLine::Invert( bool bInvertU) @@ -685,8 +849,8 @@ PolyLine::Invert( bool bInvertU) // recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione double dUfin = m_lUPoints.front().second ; // ciclo su tutti gli elementi - for ( PNTULIST::iterator iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter) { - iter->second = dUfin - iter->second ; + for ( auto& UPoint : m_lUPoints) { + UPoint.second = dUfin - UPoint.second ; } } return true ; diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index d23243e..ed42d82 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -33,7 +33,7 @@ GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol) return nullptr ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return nullptr ; // creo e setto la superficie trimesh PtrOwner pSTM( CreateSurfTriMesh()) ; @@ -77,7 +77,7 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, return nullptr ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return nullptr ; // se richiesta chiusura agli estremi bool bDoCapEnds = false ; @@ -196,11 +196,11 @@ GetSurfTriMeshByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector dLinTol = max( dLinTol, EPS_SMALL) ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return nullptr ; // calcolo lo step di rotazione double dMaxRad = 0 ; - if ( ! PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) || dMaxRad < EPS_SMALL) + if ( ! PL.GetMaxDistanceFromLine( ptAx, vtAx, 1, dMaxRad, false) || dMaxRad < EPS_SMALL) return nullptr ; double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ; // se richiesta chiusura degli estremi @@ -259,11 +259,11 @@ GetSurfTriMeshByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vecto dLinTol = max( dLinTol, EPS_SMALL) ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return nullptr ; // calcolo lo step di rotazione double dMaxRad = 0 ; - if ( ! PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) || dMaxRad < EPS_SMALL) + if ( ! PL.GetMaxDistanceFromLine( ptAx, vtAx, 1, dMaxRad, false) || dMaxRad < EPS_SMALL) return nullptr ; double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ; // se superficie rototraslata, necessari limiti sulla lunghezza dei segmenti @@ -291,7 +291,7 @@ GetSurfTriMeshRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol) return nullptr ; // calcolo la polilinea che approssima la curva PolyLine PL ; - if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL)) + if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return nullptr ; // creo e setto la superficie trimesh PtrOwner pSTM( CreateSurfTriMesh()) ; @@ -312,11 +312,11 @@ GetSurfTriMeshRuled( const ICurve* pCurve1, const ICurve* pCurve2, double dLinTo return nullptr ; // calcolo la polilinea che approssima la prima curva PolyLine PL1 ; - if ( ! pCurve1->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL1)) + if ( ! pCurve1->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL1)) return nullptr ; // calcolo la polilinea che approssima la seconda curva PolyLine PL2 ; - if ( ! pCurve2->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL2)) + if ( ! pCurve2->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL2)) return nullptr ; // creo e setto la superficie trimesh PtrOwner pSTM( CreateSurfTriMesh()) ; @@ -337,7 +337,7 @@ CalcRegionPolyLines( const ICURVEPVECTOR& vpCurve, double dLinTol, POLYLINEVECTOR vPLtmp ; vPLtmp.resize( vpCurve.size()) ; for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) { - if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, vPLtmp[i])) + if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, vPLtmp[i])) return nullptr ; } // ne calcolo l'area e genero un ordine in senso decrescente