From 30f8c71894cd93a5c802f59bf66724d78f8c5ae7 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Sat, 21 Dec 2013 16:18:29 +0000 Subject: [PATCH] EgtGeomKernel 1.4l2 : Aggiunte ApproxWithLines su Curve Semplici. --- CurveArc.cpp | 73 ++++++++++++++++- CurveArc.h | 1 + CurveAux.cpp | 6 +- CurveBezier.cpp | 145 +++++++++++++++++++++++++++++++++- CurveBezier.h | 4 + CurveComposite.cpp | 23 ++++-- CurveLine.cpp | 18 ++++- CurveLine.h | 1 + DistPointLine.cpp | 136 +++++++++++++++++++++++++++++++ DllMain.h | 20 +++++ EGkDllMain.cpp | 19 ++++- EgtGeomKernel.rc | Bin 7634 -> 7634 bytes EgtGeomKernel.vcxproj | 6 +- EgtGeomKernel.vcxproj.filters | 18 ++++- GdbExecutor.cpp | 9 +-- GdbExecutor.h | 3 +- GeomDB.cpp | 21 ++--- GeomDB.h | 8 +- OutScl.cpp | 104 ++++++++++++------------ OutScl.h | 7 +- Vector3d.cpp | 31 +++++++- 21 files changed, 548 insertions(+), 105 deletions(-) create mode 100644 DistPointLine.cpp create mode 100644 DllMain.h diff --git a/CurveArc.cpp b/CurveArc.cpp index d7fbb52..1d5a55e 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -233,8 +233,8 @@ CurveArc::GetDomain( double& dStart, double& dEnd) const return false ; // assegno gli estremi del dominio - dStart = 0 ; - dEnd = 1 ; + dStart = PAR_START ; + dEnd = PAR_END ; return true ; } @@ -286,6 +286,75 @@ CurveArc::GetLength( double& dLen) const return ( dLen > EPS_SMALL) ; } +//---------------------------------------------------------------------------- +bool +CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const +{ + int i ; + int nStep ; + double dAngStepDeg ; + double dCosA ; + double dSinA ; + double dU ; + Point3d ptPos ; + Vector3d vtA1 ; + Vector3d vtA2 ; + Vector3d vtA1p ; + Vector3d vtA2p ; + + + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // limiti minimi su tolleranza e deviazione angolare + dLinTol = max( dLinTol, LIN_TOL_MIN) ; + dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; + + // determinazione dello step angolare + dAngStepDeg = sqrt( 8 * dLinTol / m_dRad) * RADTODEG ; + dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ; + + // dall'angolo al centro ricavo il numero di passi + nStep = (int) ( fabs( m_dAngCenDeg) / dAngStepDeg + 0.999) ; + + // sistemo lo step (per il numero intero di passi) + dAngStepDeg = m_dAngCenDeg / nStep ; + + // riservo lo spazio necessario nel vettore di punti + vUPoints.reserve( nStep + 1) ; + + // versori di riferimento nel piano dell'arco + vtA1 = m_VtS ; + vtA2 = m_VtN ^ m_VtS ; + + // seno e coseno dell'angolo di step + dCosA = cos( dAngStepDeg * DEGTORAD) ; + dSinA = sin( dAngStepDeg * DEGTORAD) ; + + // primo punto + ptPos = m_PtCen + vtA1 * m_dRad ; + vUPoints.push_back( UPOINT( 0, ptPos)) ; + + // ciclo per i punti successivi + for ( i = 1 ; i <= nStep ; ++ i) { + // parametro del punto + dU = i / (double) nStep ; + // nuovo valore versori + vtA1p = vtA1 ; + vtA2p = vtA2 ; + vtA1 = dCosA * vtA1p + dSinA * vtA2p ; + vtA2 = - dSinA * vtA1p + dCosA * vtA2p ; + // calcolo del punto + ptPos = m_PtCen + vtA1 * m_dRad ; + if ( fabs( m_dDeltaN) > EPS_ZERO) + ptPos = ptPos + ( dU * m_dDeltaN) * m_VtN ; + vUPoints.push_back( UPOINT( dU, ptPos)) ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool CurveArc::Reverse( void) diff --git a/CurveArc.h b/CurveArc.h index cca98f2..8717981 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -76,6 +76,7 @@ class CurveArc : public ICurveArc { return m_dAngCenDeg ; } virtual double GetDeltaN( void) const { return m_dDeltaN ; } + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ; public : CurveArc( void) ; diff --git a/CurveAux.cpp b/CurveAux.cpp index 238f948..62e5d66 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -54,19 +54,19 @@ GetPointTang( const ICurve& crvC, double dU, Point3d& ptPos, Vector3d& vtTang) bool GetPointTangNormCurv( const ICurve& crvC, double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) { - double dLenSqD1 ; + double dSqLenD1 ; Vector3d vtDer2 ; if ( ! crvC.GetPointD1D2( dU, ptPos, vtT, vtDer2)) return false ; // se esiste la derivata prima non nulla - dLenSqD1 = vtT.LenSq() ; + dSqLenD1 = vtT.SqLen() ; if ( vtT.Normalize()) { // del vettore deriv2^ tengo la sola componente perpendicolare al vettore tangente vtN = vtDer2 - ( vtDer2 * vtT) * vtT ; if ( vtN.Normalize()) - dCurv = ( vtT ^ vtDer2).Len() / dLenSqD1 ; + dCurv = ( vtT ^ vtDer2).Len() / dSqLenD1 ; else dCurv = 0 ; } diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 8c9c4e8..04b5b02 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -13,10 +13,12 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" +#include "DllMain.h" #include "CurveBezier.h" #include "GeoObjFactory.h" #include "\EgtDev\Include\EGnStringUtils.h" #include "\EgtDev\Include\EGkCurveArc.h" +#include "\EgtDev\Include\EGkDistPointLine.h" #include using namespace std ; @@ -359,8 +361,8 @@ CurveBezier::GetDomain( double& dStart, double& dEnd) const return false ; // assegno gli estremi del dominio - dStart = 0 ; - dEnd = 1 ; + dStart = PAR_START ; + dEnd = PAR_END ; return true ; } @@ -500,6 +502,25 @@ CurveBezier::IncreaseBernsteinOneDegree( double dU, int nDeg, double dBern[]) co } +//---------------------------------------------------------------------------- +bool +CurveBezier::GetControlPolygonLength( double& dLen) const +{ + int i ; + + + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // ciclo sui punti di controllo + dLen = 0 ; + for ( i = 1 ; i <= m_nDeg ; ++ i) + dLen += Dist( m_aPtCtrl[i], m_aPtCtrl[i-1]) ; + + return true ; +} + //---------------------------------------------------------------------------- bool CurveBezier::GetLength( double& dLen) const @@ -512,7 +533,7 @@ double CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2, const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2) const { - const int MAX_LEV = 5 ; + const int MAX_LEV = 10 ; const double MAX_ARC = 1.05 ; const double LEN_RATIO = 1.2 ; double dD1 ; @@ -523,6 +544,10 @@ CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2, // algoritmo dell'approssimazione con arco per tre punti di S. Vincent e D. Forsey + // verifica superamento del massimo livello di recursione per debug + if ( nLev >= MAX_LEV) + LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions") + // calcolo delle distanze dD1 = Dist( ptP0, ptP2) ; dDa = Dist( ptP0, ptP1) ; @@ -530,7 +555,7 @@ CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2, dD2 = dDa + dDb ; // distanza piccola o massimo livello di recursione, approx arco ok - if ( dD2 < EPS_SMALL || nLev == MAX_LEV) + if ( dD2 < EPS_SMALL || nLev >= MAX_LEV) return ( dD2 + ( dD2 - dD1) / 3) ; // se ci sono anomalie si suddivide @@ -697,6 +722,118 @@ CurveBezier::GetParamAtLength( double dLen, double& dU) const return bOk ; } +//---------------------------------------------------------------------------- +bool +CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, double dParEnd, + double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const +{ + const int MAX_LEV = 10 ; + int i ; + double dMaxSqDist ; + double dSqDist ; + double dAngDeg ; + double dPolLen ; + Vector3d vtDirI ; + Vector3d vtDirF ; + DistPointLine dstPL ; + + + // se raggiunto il massimo livello di recursione ... + if ( nLev >= MAX_LEV) { + // segnalo situazione per debug + LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions") + // considero la curva piatta (inserisco il punto se abbastanza lontano dal precedente) ed esco + if ( SqDist( vUPoints.back().second, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol)) + vUPoints.push_back( UPOINT( dParEnd, crvBez.m_aPtCtrl[m_nDeg])) ; + return true ; + } + + // massima distanza al quadrato dei punti di controllo intermedi dalla linea tra primo e ultimo + dMaxSqDist = 0 ; + dstPL.SetLine( crvBez.m_aPtCtrl[0], crvBez.m_aPtCtrl[m_nDeg], true) ; + for ( i = 1 ; i < m_nDeg ; i ++) { + dstPL.SetPoint( crvBez.m_aPtCtrl[i]) ; + dSqDist = dstPL.GetSqDist() ; + if ( dSqDist > dMaxSqDist) + dMaxSqDist = dSqDist ; + } + + // se distanza entro tolleranza + if ( dMaxSqDist <= ( dLinTol * dLinTol)) { + // deviazione angolare tra primo e ultimo tratto del poligono di controllo (grado >= 1) + vtDirI = crvBez.m_aPtCtrl[1] - crvBez.m_aPtCtrl[0] ; + vtDirF = crvBez.m_aPtCtrl[m_nDeg] - crvBez.m_aPtCtrl[m_nDeg-1] ; + vtDirI.GetAngle( vtDirF, dAngDeg) ; + // se deviazione angolare entro tolleranza oppure lunghezza poligono controllo entro tolleranza + if ( fabs( dAngDeg) <= dAngTolDeg || + ( crvBez.GetControlPolygonLength( dPolLen) && dPolLen <= dLinTol)) { + // considero la curva piatta (inserisco il punto se abbastanza lontano dal precedente) ed esco + if ( SqDist( vUPoints.back().second, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol)) + vUPoints.push_back( UPOINT( dParEnd, crvBez.m_aPtCtrl[m_nDeg])) ; + return true ; + } + } + + // curva da dividere + { + double dParMid ; + CurveBezier crvBez1 ; + // parametro a metà + dParMid = 0.5 * ( dParStart + dParEnd) ; + // prima metà + crvBez1 = crvBez ; + crvBez1.TrimEndAtParam( 0.5) ; + if ( ! FlatOrSplit( nLev + 1, crvBez1, dParStart, dParMid, dLinTol, dAngTolDeg, vUPoints)) + return false ; + // seconda metà + crvBez1 = crvBez ; + crvBez1.TrimStartAtParam( 0.5) ; + if ( ! FlatOrSplit( nLev + 1, crvBez1, dParMid, dParEnd, dLinTol, dAngTolDeg, vUPoints)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const +{ + const int VP_DIM = 64 ; + + + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // se di primo grado, basta inserire gli estremi + if ( m_nDeg == 1) { + vUPoints.reserve( 2) ; + vUPoints.push_back( UPOINT( 0, m_aPtCtrl[0])) ; + vUPoints.push_back( UPOINT( 1, m_aPtCtrl[m_nDeg])) ; + return true ; + } + + // limiti minimi su tolleranza e deviazione angolare + dLinTol = max( dLinTol, LIN_TOL_MIN) ; + dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; + + // riservo uno spazio standard nel vettore di punti + vUPoints.reserve( VP_DIM) ; + + // inserisco il punto iniziale + vUPoints.push_back( UPOINT( 0, m_aPtCtrl[0])) ; + + // verifico se va divisa + FlatOrSplit( 0, *this, PAR_START, PAR_END, dLinTol, dAngTolDeg, vUPoints) ; + + // se è stato inserito un solo punto, aggiungo il finale + if ( vUPoints.size() == 1) + vUPoints.push_back( UPOINT( 1, m_aPtCtrl[m_nDeg])) ; + + return true ; +} + //---------------------------------------------------------------------------- bool CurveBezier::Reverse( void) diff --git a/CurveBezier.h b/CurveBezier.h index ffae48a..bf2e5b3 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -70,6 +70,8 @@ class CurveBezier : public ICurveBezier { return m_bRat ; } virtual const Point3d& GetControlPoint( int nInd, bool* pbOk = NULL) const ; virtual double GetControlWeight( int nInd, bool* pbOk = NULL) const ; + virtual bool GetControlPolygonLength( double& dLen) const ; + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ; public : CurveBezier( void) ; @@ -90,6 +92,8 @@ class CurveBezier : public ICurveBezier const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2) const ; bool GetSegmentParam( double dLen, double& dCurrLen, double& dSegLen, double& dUIni, double& dUFin) const ; + bool FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, double dParEnd, + double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index d382b47..d8f4f40 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -340,6 +340,8 @@ CurveComposite::GetDomain( double& dStart, double& dEnd) const bool CurveComposite::GetPointD1D2( double dU, Point3d& ptPos, Vector3d& vtDer1, Vector3d& vtDer2) const { + double dParStart ; + double dParEnd ; PCRVSMPL_LIST::const_iterator Iter ; @@ -351,10 +353,11 @@ CurveComposite::GetPointD1D2( double dU, Point3d& ptPos, Vector3d& vtDer1, Vecto // determino la curva di appartenenza e faccio eseguire il calcolo for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { - if ( dU <= 1) - return (*Iter)->GetPointD1D2( dU, ptPos, vtDer1, vtDer2) ; + (*Iter)->GetDomain( dParStart, dParEnd) ; + if ( dU <= ( dParEnd - dParStart)) + return (*Iter)->GetPointD1D2( dParStart + dU, ptPos, vtDer1, vtDer2) ; else - dU -= 1 ; + dU -= ( dParEnd - dParStart) ; } return false ; @@ -404,6 +407,8 @@ CurveComposite::Reverse( void) bool CurveComposite::TrimStartAtParam( double dUTrim) { + double dParStart ; + double dParEnd ; double dUToTrim ; PCRVSMPL_LIST::iterator Iter ; @@ -411,9 +416,10 @@ CurveComposite::TrimStartAtParam( double dUTrim) // ciclo sulle diverse curve dall'inizio dUToTrim = dUTrim ; for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { - // dominio parametrico della curva sempre 1 + // dominio parametrico della curva semplice + (*Iter)->GetDomain( dParStart, dParEnd) ; // lunghezza parametrica progressiva - dUToTrim -= 1 ; + dUToTrim -= ( dParEnd - dParStart) ; // se lunghezza ancora da tagliare non nulla if ( dUToTrim > EPS_ZERO) { delete (*Iter) ; @@ -453,6 +459,8 @@ bool CurveComposite::TrimEndAtParam( double dUTrim) { bool bToErase ; + double dParStart ; + double dParEnd ; double dUToTrim ; PCRVSMPL_LIST::iterator Iter ; @@ -461,9 +469,10 @@ CurveComposite::TrimEndAtParam( double dUTrim) bToErase = false ; dUToTrim = dUTrim ; for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { - // dominio parametrico delle curve semplici sempre 1 + // dominio parametrico della curva semplice + (*Iter)->GetDomain( dParStart, dParEnd) ; // lunghezza parametrica progressiva - dUToTrim -= 1 ; + dUToTrim -= ( dParEnd - dParStart) ; // se da cancellare if ( bToErase) { // cancello l'entità, la tolgo dalla lista e passo alla successiva diff --git a/CurveLine.cpp b/CurveLine.cpp index a53f425..e71010a 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -114,7 +114,7 @@ bool CurveLine::Validate( void) { if ( m_nStatus == TO_VERIFY) - m_nStatus = ( ( DistSq( m_PtStart, m_PtEnd) > EPS_SMALL * EPS_SMALL) ? OK : ERR) ; + m_nStatus = ( ( SqDist( m_PtStart, m_PtEnd) > EPS_SMALL * EPS_SMALL) ? OK : ERR) ; return ( m_nStatus == OK) ; } @@ -202,6 +202,22 @@ CurveLine::GetLength( double& dLen) const return ( dLen > EPS_SMALL) ; } +//---------------------------------------------------------------------------- +bool +CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const +{ + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // inserisco gli estremi + vUPoints.reserve( 2) ; + vUPoints.push_back( UPOINT( 0, m_PtStart)) ; + vUPoints.push_back( UPOINT( 1, m_PtEnd)) ; + + return true ; +} + //---------------------------------------------------------------------------- bool CurveLine::Reverse( void) diff --git a/CurveLine.h b/CurveLine.h index 2831d10..298ae74 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -63,6 +63,7 @@ class CurveLine : public ICurveLine { return m_PtStart ; } virtual const Point3d& GetEnd( void) const { return m_PtEnd ; } + virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ; public : CurveLine( void) ; diff --git a/DistPointLine.cpp b/DistPointLine.cpp new file mode 100644 index 0000000..f9756d0 --- /dev/null +++ b/DistPointLine.cpp @@ -0,0 +1,136 @@ +//---------------------------------------------------------------------------- +// EgalTech 2013-2013 +//---------------------------------------------------------------------------- +// File : DistPointLine.cpp Data : 17.12.13 Versione : 1.4l1 +// Contenuto : Implementazione dell'oggetto distanza punto da linea/segmento. +// +// !!! ToDo : Gestire i sistemi di riferimento. +// +// Modifiche : 17.12.13 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "\EgtDev\Include\EGkDistPointLine.h" + + +//---------------------------------------------------------------------------- +DistPointLine::DistPointLine( void) +{ + m_dLen = 0 ; + m_bIsSegment = false ; + m_dSqDist = - 1 ; + m_dDist = - 1 ; +} + +//---------------------------------------------------------------------------- +bool +DistPointLine::Set( const Point3d& ptP, const Point3d& ptIni, const Point3d& ptFin, bool bIsSegment) +{ + m_ptP = ptP ; + m_ptIni = ptIni ; + m_dLen = Dist( ptIni, ptFin) ; + if ( m_dLen > EPS_SMALL) + m_vtDir = ( ptFin - ptIni) / m_dLen ; + else + m_vtDir.Set( 0, 0, 0) ; + m_bIsSegment = bIsSegment ; + m_dSqDist = - 1 ; + m_dDist = - 1 ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +DistPointLine::SetPoint( const Point3d& ptP) +{ + m_ptP = ptP ; + m_dSqDist = - 1 ; + m_dDist = - 1 ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +DistPointLine::SetLine( const Point3d& ptIni, const Point3d& ptFin, bool bIsSegment) +{ + m_ptIni = ptIni ; + m_dLen = Dist( ptIni, ptFin) ; + if ( m_dLen > EPS_SMALL) + m_vtDir = ( ptFin - ptIni) / m_dLen ; + else + m_vtDir.Set( 0, 0, 0) ; + m_bIsSegment = bIsSegment ; + m_dSqDist = - 1 ; + m_dDist = - 1 ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +DistPointLine::Calculate( void) +{ + // se la linea è un punto + if ( m_dLen < EPS_SMALL) + m_ptMinDist = m_ptIni ; + + // se la linea è illimitata + else if ( ! m_bIsSegment) + m_ptMinDist = m_ptIni + m_vtDir * ( m_vtDir * ( m_ptP - m_ptIni)) ; + + // altrimenti la linea è un segmento + else { + double dProiez = m_vtDir * ( m_ptP - m_ptIni) ; + if ( dProiez <= 0) + m_ptMinDist = m_ptIni ; + else if ( dProiez >= m_dLen) + m_ptMinDist = m_ptIni + m_vtDir * m_dLen ; + else + m_ptMinDist = m_ptIni + m_vtDir * dProiez ; + } + + // calcolo il quadrato della distanza + m_dSqDist = SqDist( m_ptP, m_ptMinDist) ; + + return true ; +} + +//---------------------------------------------------------------------------- +double +DistPointLine::GetSqDist( void) +{ + // se necessario, faccio eseguire i conti + if ( m_dSqDist < 0) + Calculate() ; + + return m_dSqDist ; +} + +//---------------------------------------------------------------------------- +double +DistPointLine::GetDist( void) +{ + // se necessario, faccio eseguire i conti + if ( m_dSqDist < 0) + Calculate() ; + if ( m_dDist < 0) + m_dDist = sqrt( m_dSqDist) ; + + return m_dDist ; +} + +//---------------------------------------------------------------------------- +const Point3d& +DistPointLine::GetPointMinDist( void) +{ + // se necessario, faccio eseguire i conti + if ( m_dSqDist < 0) + Calculate() ; + + return m_ptMinDist ; +} diff --git a/DllMain.h b/DllMain.h new file mode 100644 index 0000000..a694cb1 --- /dev/null +++ b/DllMain.h @@ -0,0 +1,20 @@ +//---------------------------------------------------------------------------- +// EgalTech 2013-2013 +//---------------------------------------------------------------------------- +// File : DllMain.h Data : 18.12.13 Versione : 1.4l2 +// Contenuto : Prototipi funzioni per uso locale della DLL. +// +// +// +// Modifiche : 18.12.13 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + + +#include "/EgtDev/Include/EgtILogger.h" + +//----------------------------------------------------------------------------- +ILogger* GetEGkLogger( void) ; diff --git a/EGkDllMain.cpp b/EGkDllMain.cpp index c4bf4f1..e7919df 100644 --- a/EGkDllMain.cpp +++ b/EGkDllMain.cpp @@ -13,7 +13,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include <\EgtDev\Include\EGkVersion.h> +#include <\EgtDev\Include\EGkDllMain.h> #include <\EgtDev\Include\EgnGetModuleVer.h> #include <\EgtDev\Include\EgtTrace.h> @@ -57,3 +57,20 @@ GetEGkVersion( void) return s_szEGkNameVer ; } + +//----------------------------------------------------------------------------- +static ILogger* s_pLogger = nullptr ; + +//----------------------------------------------------------------------------- +void +SetEGkLogger( ILogger* pLogger) +{ + s_pLogger = pLogger ; +} + +//----------------------------------------------------------------------------- +ILogger* +GetEGkLogger( void) +{ + return s_pLogger ; +} diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 68c9bdf26b1eda855bc02d88285c405d7159d327..a4aaac6cb861c0e1c3eb93d1e3a78739d1ee8142 100644 GIT binary patch delta 56 zcmca)eaU*m4>m@l%@_I3Gfn2>(V6^0P>s=O@m@_%@_I3Gfn2>(V6^0P>s=W@ + @@ -149,6 +150,8 @@ copy $(TargetPath) \EgtProg\Dll + + @@ -158,14 +161,15 @@ copy $(TargetPath) \EgtProg\Dll + - + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index d836bf1..c0d1ade 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -93,6 +93,9 @@ File di origine\Gdb + + File di origine\Base + @@ -134,9 +137,6 @@ File di intestazione - - File di intestazione - File di intestazione @@ -218,6 +218,18 @@ File di intestazione + + File di intestazione + + + File di intestazione + + + File di intestazione + + + File di intestazione + diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 6765d27..184c541 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -15,6 +15,7 @@ #include "stdafx.h" #include "GdbExecutor.h" #include "GdbIterator.h" +#include "DllMain.h" #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EgnStringConverter.h" #include "/EgtDev/Include/EgkGeoPoint3d.h" @@ -39,7 +40,6 @@ CreateGdbExecutor( void) GdbExecutor::GdbExecutor( void) { m_pGDB = nullptr ; - m_pLogger = nullptr ; } //---------------------------------------------------------------------------- @@ -49,10 +49,9 @@ GdbExecutor::~GdbExecutor( void) //---------------------------------------------------------------------------- bool -GdbExecutor::Init( IGeomDB* pGdb, ILogger* pLogger) +GdbExecutor::Init( IGeomDB* pGdb) { m_pGDB = pGdb ; - m_pLogger = pLogger ; return ( m_pGDB != nullptr) ; } @@ -73,7 +72,7 @@ GdbExecutor::Execute( const string& sCmd1, const string& sCmd2, const STRVECTOR& sOut += *theConstIter ; } sOut += "]" ; - LOG_DEBUG( m_pLogger, sOut.c_str()) ; + LOG_DBG_INFO( GetEGkLogger(), sOut.c_str()) ; // esecuzione comando if ( sCmd1 == "ALIAS") @@ -909,7 +908,7 @@ GdbExecutor::ExecuteLoad( const STRVECTOR& vsParams) return false ; // pulizia e reinizializzazione del DB geometrico m_pGDB->Clear() ; - m_pGDB->ReInit() ; + m_pGDB->Init() ; // esecuzione caricamento return m_pGDB->Load( vsParams[0]) ; } diff --git a/GdbExecutor.h b/GdbExecutor.h index 979e261..87720dd 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -22,7 +22,7 @@ class GdbExecutor : public IGdbExecutor { public : virtual bool Execute( const std::string& sCmd1, const std::string& sCmd2, const STRVECTOR& vsParams) ; - virtual bool Init( IGeomDB* pGdb, ILogger* pLogger) ; + virtual bool Init( IGeomDB* pGdb) ; public : GdbExecutor( void) ; @@ -58,7 +58,6 @@ class GdbExecutor : public IGdbExecutor private : IGeomDB* m_pGDB ; - ILogger* m_pLogger ; OutScl m_OutScl ; typedef std::unordered_map AliasMap ; AliasMap m_AliasMap ; diff --git a/GeomDB.cpp b/GeomDB.cpp index 14bc900..870c736 100644 --- a/GeomDB.cpp +++ b/GeomDB.cpp @@ -15,6 +15,7 @@ #include "stdafx.h" #include "GeomDB.h" #include "GdbObj.h" +#include "DllMain.h" #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EgnStringConverter.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -45,19 +46,7 @@ GeomDB::~GeomDB( void) //---------------------------------------------------------------------------- bool -GeomDB::Init( ILogger* pLogger) -{ - m_pLogger = pLogger ; - - // imposto numero minimo buckets del map degli Id - m_IdManager.Init( 1024) ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -GeomDB::ReInit( void) +GeomDB::Init( void) { // imposto numero minimo buckets del map degli Id @@ -90,14 +79,14 @@ GeomDB::Load( const std::string& sFileIn) // inizializzo lo scanner if ( ! TheScanner.Init( sFileIn)) { - LOG_ERROR( m_pLogger, "GeomDbLoad : Error on Init ") ; + LOG_ERROR( GetEGkLogger(), "GeomDbLoad : Error on Init ") ; return false ; } // leggo l'intestazione if ( ! LoadStart( TheScanner)) { string sOut = "GeomDbLoad : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; - LOG_ERROR( m_pLogger, sOut.c_str()) ; + LOG_ERROR( GetEGkLogger(), sOut.c_str()) ; return false ; } @@ -107,7 +96,7 @@ GeomDB::Load( const std::string& sFileIn) if ( ! LoadOneNode( TheScanner, bEnd)) { bOk = false ; string sOut = "GeomDbLoad : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; - LOG_ERROR( m_pLogger, sOut.c_str()) ; + LOG_ERROR( GetEGkLogger(), sOut.c_str()) ; } } while ( ! bEnd) ; diff --git a/GeomDB.h b/GeomDB.h index f7de089..a7dd733 100644 --- a/GeomDB.h +++ b/GeomDB.h @@ -30,8 +30,7 @@ class GeomDB : public IGeomDB public : virtual ~GeomDB( void) ; - virtual bool Init( ILogger* pLogger) ; - virtual bool ReInit( void) ; + virtual bool Init( void) ; virtual bool Clear( void) ; virtual bool Load( const std::string& sFileIn) ; virtual bool Save( const std::string& sFileOut) const ; @@ -65,9 +64,8 @@ class GeomDB : public IGeomDB bool LoadOneNode( Scanner& TheScanner, bool& bEnd) ; private : - GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB - IdManager m_IdManager ; // gestore del nuovo Id - ILogger* m_pLogger ; + GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB + IdManager m_IdManager ; // gestore del nuovo Id } ; //---------------------------------------------------------------------------- diff --git a/OutScl.cpp b/OutScl.cpp index 292c772..4ec4f7b 100644 --- a/OutScl.cpp +++ b/OutScl.cpp @@ -200,12 +200,16 @@ OutScl::SetPartLayRef( string sPart, string sLay, const Frame3d& frFrame) //---------------------------------------------------------------------------- bool -OutScl::Line2P( Point3d ptP1, Point3d ptP2) +OutScl::Line2P( const Point3d& ptP1, const Point3d& ptP2) { // verifico sia aperto if ( ! m_ofFile.is_open()) return false ; + // verifico non sia praticamente nulla + if ( AreSamePointNear( ptP1, ptP2)) + return true ; + // emetto linea m_ofFile << "Line3D( \"" << m_sPartLay << "\", \"" << m_sMaterial << "\", " ; m_ofFile << ToString( ptP1) << ", " << ToString( ptP2) ; @@ -216,7 +220,7 @@ OutScl::Line2P( Point3d ptP1, Point3d ptP2) //---------------------------------------------------------------------------- bool -OutScl::Arc3P( Point3d ptP1, Point3d ptP2, Point3d ptP3) +OutScl::Arc3P( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3) { // verifico sia aperto if ( ! m_ofFile.is_open()) @@ -232,7 +236,7 @@ OutScl::Arc3P( Point3d ptP1, Point3d ptP2, Point3d ptP3) //---------------------------------------------------------------------------- bool -OutScl::ArcCPA( Point3d ptCen, Point3d ptMed, double dAngCenDeg) +OutScl::ArcCPA( const Point3d& ptCen, const Point3d& ptMed, double dAngCenDeg) { Point3d ptP1 ; Point3d ptP3 ; @@ -256,6 +260,22 @@ OutScl::ArcCPA( Point3d ptCen, Point3d ptMed, double dAngCenDeg) return true ; } +//---------------------------------------------------------------------------- +bool +OutScl::CircleCR( const Point3d& ptCen, double dRad) +{ + // verifico sia aperto + if ( ! m_ofFile.is_open()) + return false ; + + // emetto arco + m_ofFile << "CircCR( \"" << m_sPartLay << "\", \"" << m_sMaterial << "\", " ; + m_ofFile << ToString( ptCen.x) << "," << ToString( ptCen.y) << ", " << ToString( dRad) ; + m_ofFile << ") ;" << endl ; + + return true ; +} + //---------------------------------------------------------------------------- bool OutScl::PutCurve( const IGeoObj* pCurve, int nFlag) @@ -292,44 +312,34 @@ OutScl::PutCurveLine( const ICurveLine& CrvLine) bool OutScl::PutCurveArc( const ICurveArc& CrvArc, int nFlag) { - const double DELTA_ANG = 15 ; - int nNumSeg ; - int i ; - double dU ; - double dCurv ; - Point3d ptIni ; - Point3d ptFin ; - Vector3d vtT ; - Vector3d vtN ; + int i ; + double dU ; + double dCurv ; + Point3d ptFin ; + Vector3d vtT ; + Vector3d vtN ; + UPNTVECTOR vUPoints ; - // numero segmenti con cui approssimare - nNumSeg = (int) ( fabs( CrvArc.GetAngCenter()) / DELTA_ANG) + 1 ; // ciclo sui segmenti Remark( "CurveArc") ; - for ( i = 0 ; i <= nNumSeg ; ++ i) { - // ricavo il punto - dU = i / (double) nNumSeg ; - CrvArc.GetPoint( dU, ptFin) ; - // dopo il primo, disegno - if ( i > 0) - Line2P( ptIni, ptFin) ; - // nuovo iniziale prende i valori del finale - ptIni = ptFin ; + CrvArc.ApproxWithLines( 0.1, 5, vUPoints) ; + for ( i = 1 ; i < (int) vUPoints.size() ; ++ i) { + Line2P( vUPoints[i-1].second, vUPoints[i].second) ; } // se richieste derivate e curvature if ( ( nFlag & 1) != 0) { // ciclo per disegnare le derivate Remark( "ArcTangents+Der2") ; - for ( i = 0 ; i <= nNumSeg ; ++ i) { + for ( i = 0 ; i < (int) vUPoints.size() ; ++ i) { // ricavo il punto - dU = i / (double) nNumSeg ; + dU = vUPoints[i].first ; CrvArc.GetPointTangNormCurv( dU, ptFin, vtT, vtN, dCurv) ; // tangente Line2P( ptFin - vtT, ptFin + vtT) ; // curvatura if ( fabs( dCurv) > EPS_ZERO) - Line2P( ptFin, ptFin + vtN * ( 1 / dCurv)) ; + Line2P( ptFin, ptFin + vtN / dCurv) ; } } @@ -340,17 +350,16 @@ OutScl::PutCurveArc( const ICurveArc& CrvArc, int nFlag) bool OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag) { - const int NUM_SEG = 20 ; - bool bCCW ; - int i ; - double dU ; - double dCurv ; - double dAngCenDeg ; - Point3d ptIni ; - Point3d ptFin ; - Point3d ptCen ; - Vector3d vtT ; - Vector3d vtN ; + bool bCCW ; + int i ; + double dU ; + double dCurv ; + double dAngCenDeg ; + Point3d ptFin ; + Point3d ptCen ; + Vector3d vtT ; + Vector3d vtN ; + UPNTVECTOR vUPoints ; // se richiesto anche il poligono di controllo @@ -359,28 +368,22 @@ OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag) // ciclo per disegnare i segmenti Remark( "BezierCurve") ; - for ( i = 0 ; i <= NUM_SEG ; ++ i) { - // ricavo il punto - dU = i / (double) NUM_SEG ; - CrvBez.GetPoint( dU, ptFin) ; - // dopo il primo, disegno - if ( i > 0) - Line2P( ptIni, ptFin) ; - // nuovo iniziale prende i valori del finale - ptIni = ptFin ; + CrvBez.ApproxWithLines( 0.1, 5, vUPoints) ; + for ( i = 1 ; i < (int) vUPoints.size() ; ++ i) { + Line2P( vUPoints[i-1].second, vUPoints[i].second) ; } // se richieste derivate e curvature if ( ( nFlag & 1) != 0) { // ciclo per disegnare le derivate e le curvature Remark( "BezierTangents+Der2") ; - for ( i = 0 ; i <= NUM_SEG ; ++ i) { + for ( i = 0 ; i < (int) vUPoints.size() ; ++ i) { // ricavo il punto - dU = i / (double) NUM_SEG ; + dU = vUPoints[i].first ; CrvBez.GetPointTangNormCurv( dU, ptFin, vtT, vtN, dCurv) ; // curvatura if ( fabs( dCurv) > EPS_ZERO) { // tratto di arco - ptCen = ptFin + vtN * ( 1 / dCurv) ; + ptCen = ptFin + vtN / dCurv ; bCCW = ( vtT ^ vtN).z > 0 ; dAngCenDeg = ( bCCW ? 1 : -1) * 4 * dCurv * RADTODEG ; ArcCPA( ptCen, ptFin, dAngCenDeg) ; @@ -390,6 +393,9 @@ OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag) // altrimenti, tangente else if ( ! vtT.IsSmall()) Line2P( ptFin - vtT, ptFin + vtT) ; + // altrimenti cerchietto + else + CircleCR( ptFin, 1) ; } } diff --git a/OutScl.h b/OutScl.h index 5aa29ef..b218bbb 100644 --- a/OutScl.h +++ b/OutScl.h @@ -46,9 +46,10 @@ class OutScl bool End( void) ; bool New( void) ; bool SetMaterial( std::string sMaterial, double dRed, double dGreen, double dBlue) ; - bool Line2P( Point3d ptP1, Point3d ptP2) ; - bool Arc3P( Point3d ptP1, Point3d ptP2, Point3d ptP3) ; - bool ArcCPA( Point3d ptCen, Point3d ptMed, double dAngCenDeg) ; + bool Line2P( const Point3d& ptP1, const Point3d& ptP2) ; + bool Arc3P( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3) ; + bool ArcCPA( const Point3d& ptCen, const Point3d& ptMed, double dAngCenDeg) ; + bool CircleCR( const Point3d& ptCen, double dRad) ; private : std::ofstream m_ofFile ; diff --git a/Vector3d.cpp b/Vector3d.cpp index 6fd5661..1d9f58c 100644 --- a/Vector3d.cpp +++ b/Vector3d.cpp @@ -56,7 +56,7 @@ Vector3d::FromPolar( double dLen, double dAngDeg) // Quadrato della lunghezza di un vettore //---------------------------------------------------------------------------- double -Vector3d::LenSq( void) const +Vector3d::SqLen( void) const { return ( x * x + y * y + z * z) ; } @@ -268,8 +268,33 @@ Vector3d::ToLoc( const Frame3d& frRef) } //---------------------------------------------------------------------------- -// Calcolo angolo di rotazione per portare la componente perpendicolare del -// vettore sulla stessa direzione della componente perpendicolare di vtEnd +// Calcolo dell'angolo tra il vettore e un altro +//---------------------------------------------------------------------------- +bool +Vector3d::GetAngle( const Vector3d& vtEnd, double& dAngDeg) +{ + double dProSca ; + double dProVett ; + + + // quantità ugualmente proporzionali a coseno e seno + dProSca = *this * vtEnd ; + dProVett = ( *this ^ vtEnd).Len() ; + + // se entrambe nulle + if ( fabs( dProSca) < EPS_ZERO && fabs( dProVett) < EPS_ZERO) { + dAngDeg = 0 ; + return false ; + } + + dAngDeg = atan2( dProVett, dProSca) * RADTODEG ; + + return true ; +} + +//---------------------------------------------------------------------------- +// Calcolo angolo di rotazione per portare la componente del vettore perpendicolare +// all'asse di rotazione sulla stessa direzione della componente perpendicolare di vtEnd //---------------------------------------------------------------------------- bool Vector3d::GetRotation( const Vector3d& vtEnd, const Vector3d& vtAx, double& dAngDeg, bool& bDet)