From bde7ff1e5c72a7b27fe150ba15d4e3e58203075b Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Fri, 31 Mar 2023 14:46:26 +0200 Subject: [PATCH] EgtGeomKernel : - aggiunto alla classe ExtDimension i sottotipi Angular, Radial e Diametral. --- ExtDimension.cpp | 957 +++++++++++++++++++++++++++++++++++++---------- ExtDimension.h | 6 + 2 files changed, 771 insertions(+), 192 deletions(-) diff --git a/ExtDimension.cpp b/ExtDimension.cpp index 010ede8..46653a5 100644 --- a/ExtDimension.cpp +++ b/ExtDimension.cpp @@ -14,15 +14,18 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ExtDimension.h" +#include "GeoConst.h" #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" #include "FontManager.h" #include "FontAux.h" +#include "CurveArc.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkExtText.h" #include "/EgtDev/Include/EGkUiUnits.h" #include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EGkCurve.h" #include using namespace std ; @@ -42,7 +45,7 @@ static const double STD_TEXTHEIGHT = 10.0 ; static const double MIN_TEXTHEIGHT = 1.0 ; //---------------------------------------------------------------------------- -GEOOBJ_REGISTER( EXT_DIMENSION, NGE_E_DIM, ExtDimension) ; +GEOOBJ_REGISTER( EXT_DIMENSION, NGE_E_DIM, ExtDimension ) ; //---------------------------------------------------------------------------- ExtDimension::ExtDimension( void) @@ -97,26 +100,26 @@ ExtDimension::SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d m_vtDir = m_ptP2 - m_ptP1 ; else { m_vtDir -= m_vtDir * m_vtN * m_vtN ; - if ( m_vtDir * ( m_ptP2 - m_ptP1) < 0) + if ( m_vtDir * ( m_ptP2 - m_ptP1) < 0 ) m_vtDir.Invert() ; } if ( ! m_vtDir.Normalize()) return false ; - // punti estremi della linea di misura ed esterni delle linee di estremità + // punti estremi della linea di misura ed esterni delle linee di estremit� Vector3d vtLine1 = m_vtDir ; vtLine1.Rotate( m_vtN, 0, 1) ; Vector3d vtLine2 = vtLine1 ; - double dProSca1 = vtLine1 * ( m_ptPos - m_ptP1) ; + double dProSca1 = vtLine1 * ( m_ptPos - m_ptP1) ; double dProSca2 = vtLine2 * ( m_ptPos - m_ptP2) ; if ( dProSca1 < -EPS_SMALL) vtLine1.Invert() ; if ( dProSca2 < -EPS_SMALL) vtLine2.Invert() ; - if ( abs( dProSca1) < EPS_SMALL) + if ( abs( dProSca1 ) < EPS_SMALL) vtLine1 = vtLine2 ; - if ( abs( dProSca2) < EPS_SMALL) + if ( abs( dProSca2 ) < EPS_SMALL) vtLine2 = vtLine1 ; - m_ptP5 = m_ptP1 + vtLine1 * ( m_ptPos - m_ptP1) * vtLine1 ; + m_ptP5 = m_ptP1 + vtLine1 * ( m_ptPos - m_ptP1) * vtLine1 ; m_ptP6 = m_ptP2 + vtLine2 * ( m_ptPos - m_ptP2) * vtLine2 ; m_ptP3 = m_ptP5 + vtLine1 * m_dExtLineLen ; m_ptP4 = m_ptP6 + vtLine2 * m_dExtLineLen ; @@ -131,6 +134,166 @@ ExtDimension::SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d return true ; } +//---------------------------------------------------------------------------- +bool +ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptP0, const Point3d& ptP2, const Point3d& ptPos, + const Vector3d& vtN, const string& sText) +{ // ptP0 è il vertice dell'angolo e l'ordine di inserimento dei punti nella funzione è: punto1, vertice, punto2 + + // dichiaro quota non ancora determinata + m_nType = DT_NONE ; + // verifico la definizione del versore normale + m_vtN = vtN ; + if ( ! m_vtN.Normalize()) + return false ; + + // porto i punti nel piano definito da ptPos (che è stato proiettato sul piano XY del frLoc) e vtN + m_ptPos = ptPos ; + m_ptP0 = ptP0 - ( ptP0 - m_ptPos) * m_vtN * m_vtN ; + m_ptP1 = ptP1 - ( ptP1 - m_ptPos) * m_vtN * m_vtN ; + m_ptP2 = ptP2 - ( ptP2 - m_ptPos) * m_vtN * m_vtN ; + + // verifico che i punti di misura non siano coincidenti + if ( AreSamePointApprox( m_ptP0, m_ptP1) || AreSamePointApprox( m_ptP0, m_ptP2) || AreSamePointApprox( m_ptP1, m_ptP2)) + return false ; + // calcolo le direzioni su cui giacciono i due lati dell'angolo + Vector3d vtLine1 = m_ptP1 - m_ptP0 ; + Vector3d vtLine2 = m_ptP2 - m_ptP0 ; + double dLen1 = vtLine1.Len() ; + double dLen2 = vtLine2.Len() ; + if ( ! vtLine1.Normalize() || ! vtLine2.Normalize()) + return false ; + // direzione di riferimento (nel piano perpendicolare a vtN) + m_vtDir = m_ptPos - m_ptP0 ; + double dLenDir = m_vtDir.Len() ; + + // controllo se è testo o se è la misura + double dHalfDist ; + double dFactor ; + if ( m_sCalcText.find( IS_MEASURE) != string::npos) { + m_sCalcText = "300.00" ; + dHalfDist = GetTextHalfDist( m_ptPos) ; + dFactor = 2.5 * dHalfDist ; + m_sCalcText = "" ; + } + else { + dHalfDist = GetTextHalfDist( m_ptPos) ; + dFactor = 2.5 * dHalfDist ; + } + //allungo m_vtDir se è troppo vicino al centro + if ( m_vtDir.Len() < dFactor) { + Vector3d vtDir_n = m_vtDir ; + if ( ! vtDir_n.Normalize()) + return false ; + m_ptPos = m_ptP0 + dFactor * vtDir_n ; + // ricalcolo m_vtDir + m_vtDir = m_ptPos - m_ptP0 ; + dLenDir = m_vtDir.Len() ; + } + + // segnalo se i punti che definiscono i lati sono più lontani dal centro di ptPos + bool bPt1Close = false ; + bool bPt2Close = false ; + if ( dLenDir < dLen1 ) + bPt1Close = true ; + if ( dLenDir < dLen2 ) + bPt2Close = true ; + m_ptP5 = m_ptP1 + ( dLenDir - dLen1 ) * vtLine1 ; + m_ptP6 = m_ptP2 + ( dLenDir - dLen2 ) * vtLine2 ; + m_ptP3 = m_ptP5 + ( bPt1Close ? - vtLine1 : vtLine1) * m_dExtLineLen ; + m_ptP4 = m_ptP6 + ( bPt2Close ? - vtLine2 : vtLine2) * m_dExtLineLen ; + + // assegnazione del testo + m_sText = sText ; + // assegno il tipo + m_nType = DT_ANGULAR ; + // imposto da calcolare + m_bToCalc = true ; + m_OGrMgr.Reset() ; + + return true; +} + +//---------------------------------------------------------------------------- +bool +ExtDimension::SetRadial( const Point3d& ptP0, const Point3d& ptPos, const Vector3d& vtX, const Vector3d& vtN, const string& sText) +{ // ptP0 è il vertice del cerchio e ptPos è un punto sulla circonferenza + + // dichiaro quota non ancora determinata + m_nType = DT_NONE ; + // verifico la definizione del versore normale e del versore X + m_vtN = vtN ; + m_vtDir = vtX ; + if ( ! m_vtN.Normalize() || ! m_vtDir.Normalize()) + return false ; + + // porto i punti nel piano definito da ptPos (che è stato proiettato sul piano XY del frLoc) e vtN + m_ptPos = ptPos ; + m_ptP0 = ptP0 - ( ptP0 - m_ptPos) * m_vtN * m_vtN ; + m_ptP1 = m_ptP0 ; + m_ptP5 = m_ptP0 ; + m_ptP3 = m_ptP0 ; + m_ptP2 = m_ptPos ; + m_ptP6 = m_ptPos ; + m_ptP4 = m_ptPos ; + + // verifico che i punti di misura non siano coincidenti + if ( AreSamePointApprox( m_ptP0, m_ptPos)) + return false ; + + // assegnazione del testo + m_sText = sText ; + // assegno il tipo + m_nType = DT_RADIAL ; + // imposto da calcolare + m_bToCalc = true ; + m_OGrMgr.Reset() ; + + return true; +} + +//---------------------------------------------------------------------------- +bool +ExtDimension::SetDiametral( const Point3d& ptP0, const Point3d& ptPos, const Vector3d& vtX, const Vector3d& vtN, const string& sText) +{ // ptP0 è il vertice del cerchio e ptPos è un punto sulla circonferenza + + // dichiaro quota non ancora determinata + m_nType = DT_NONE ; + // verifico la definizione del versore normale e del versore X + m_vtN = vtN ; + m_vtDir = vtX ; + if ( ! m_vtN.Normalize() || ! m_vtDir.Normalize()) + return false ; + + // porto i punti nel piano definito da ptPos (che è stato proiettato sul piano XY del frLoc) e vtN + m_ptPos = ptPos ; + m_ptP0 = ptP0 - ( ptP0 - m_ptPos) * m_vtN * m_vtN ; + m_ptP2 = m_ptPos ; + m_ptP6 = m_ptPos ; + m_ptP4 = m_ptPos ; + + m_ptP1 = m_ptPos; + //ottengo il punto diametralmente opposto a ptPos + m_ptP1.Mirror( m_ptP0, m_ptPos - m_ptP0) ; + m_ptP5 = m_ptP1 ; + m_ptP3 = m_ptP1 ; + + + // verifico che i punti di misura non siano coincidenti + if ( AreSamePointApprox( m_ptP0, m_ptPos)) + return false ; + + // assegnazione del testo + m_sText = sText ; + // assegno il tipo + m_nType = DT_DIAMETRAL ; + // imposto da calcolare + m_bToCalc = true ; + m_OGrMgr.Reset() ; + + return true; +} + //---------------------------------------------------------------------------- ExtDimension* ExtDimension::Clone( void) const @@ -165,8 +328,9 @@ ExtDimension::CopyFrom( const ExtDimension& clSrc) return true ; m_OGrMgr.Reset() ; m_nType = clSrc.m_nType ; - m_vtN = clSrc.m_vtN ; + m_vtN = clSrc.m_vtN ; m_vtDir = clSrc.m_vtDir ; + m_ptP0 = clSrc.m_ptP0 ; m_ptP1 = clSrc.m_ptP1 ; m_ptP2 = clSrc.m_ptP2 ; m_ptP3 = clSrc.m_ptP3 ; @@ -212,8 +376,8 @@ ExtDimension::GetTitle( void) const const string& ExtDimension::GetSubType( void) const { - static const string vsSubType[] = { "None", "Linear", "Radial", "Diametral", "Angular"} ; - if ( m_nType >= DT_NONE && m_nType <= DT_ANGULAR) + static const string vsSubType[] = { "None", "Linear", "Radial", "Diametral", "Angular" } ; + if ( m_nType >= DT_NONE && m_nType <= DT_ANGULAR) return vsSubType[m_nType] ; else return vsSubType[0] ; @@ -227,6 +391,7 @@ ExtDimension::Dump( string& sOut, bool bMM, const char* szNewLine) const sOut += GetSubType() + szNewLine ; sOut += "VN(" + ToString( m_vtN, 3) + ") " + szNewLine ; sOut += "VD(" + ToString( m_vtDir, 3) + ") " + szNewLine ; + sOut += "P0(" + ToString( GetInUiUnits( m_ptP0, bMM), 3) + ") " + szNewLine ; sOut += "P1(" + ToString( GetInUiUnits( m_ptP1, bMM), 3) + ") " + szNewLine ; sOut += "P2(" + ToString( GetInUiUnits( m_ptP2, bMM), 3) + ") " + szNewLine ; sOut += "P3(" + ToString( GetInUiUnits( m_ptP3, bMM), 3) + ") " + szNewLine ; @@ -236,12 +401,12 @@ ExtDimension::Dump( string& sOut, bool bMM, const char* szNewLine) const sOut += "Pos(" + ToString( GetInUiUnits( m_ptPos, bMM), 3) + ") " + szNewLine ; sOut += "Txt=" + m_sText + szNewLine ; sOut += "El=" + ToString( GetInUiUnits( m_dExtLineLen, bMM), 3) + - " Al=" + ToString( GetInUiUnits( m_dArrowLen, bMM), 3) + - " Td=" + ToString( GetInUiUnits( m_dTextDist, bMM), 3) + szNewLine ; + " Al=" + ToString( GetInUiUnits( m_dArrowLen, bMM), 3) + + " Td=" + ToString( GetInUiUnits( m_dTextDist, bMM), 3) + szNewLine ; sOut += "Mm=" + string( m_bLenIsMM ? "1" : "0") + - " Dec=" + ToString( m_nDecDigit) + szNewLine ; - sOut += "Fnt=" + m_sFont + - " H=" + ToString( GetInUiUnits( m_dTextHeight, bMM), 3) + szNewLine ; + " Dec=" + ToString( m_nDecDigit) + szNewLine ; + sOut += "Fnt=" + m_sFont + + " H=" + ToString( GetInUiUnits( m_dTextHeight, bMM), 3) + szNewLine ; return true ; } @@ -266,6 +431,8 @@ ExtDimension::Save( NgeWriter& ngeOut) const if ( ! ngeOut.WriteVector( m_vtDir, ";", true)) return false ; // punti di quotatura + if ( ! ngeOut.WritePoint( m_ptP0, ";")) + return false ; if ( ! ngeOut.WritePoint( m_ptP1, ";")) return false ; if ( ! ngeOut.WritePoint( m_ptP2, ";")) @@ -318,6 +485,8 @@ ExtDimension::Load( NgeReader& ngeIn) if ( ! ngeIn.ReadVector( m_vtDir, ";", true)) return false ; // leggo la prossima linea : punti di quotatura + if ( ! ngeIn.ReadPoint( m_ptP0, ";")) + return false ; if ( ! ngeIn.ReadPoint( m_ptP1, ";")) return false ; if ( ! ngeIn.ReadPoint( m_ptP2, ";")) @@ -360,62 +529,134 @@ ExtDimension::GetLocalBBox( BBox3d& b3Loc, int nFlag) const { // eventuale ricalcolo Update() ; - // se lineare - if ( m_nType == DT_LINEAR) { - b3Loc.Set( m_ptP1) ; - b3Loc.Add( m_ptP2) ; - b3Loc.Add( m_ptP3) ; - b3Loc.Add( m_ptP4) ; - b3Loc.Add( m_ptCalcP7) ; - b3Loc.Add( m_ptCalcP8) ; - // ingombro del testo - BBox3d b3Text ; - if ( GetTextLocalBBox( b3Text)) - b3Loc.Add( b3Text) ; - return true ; - } - else - return false ; + switch ( m_nType) { + + // se lineare + case DT_LINEAR: { + b3Loc.Set( m_ptP1) ; + b3Loc.Add( m_ptP2) ; + b3Loc.Add( m_ptP3) ; + b3Loc.Add( m_ptP4) ; + b3Loc.Add( m_ptCalcP7) ; + b3Loc.Add( m_ptCalcP8) ; + // ingombro del testo + BBox3d b3Text ; + if ( GetTextLocalBBox( b3Text)) + b3Loc.Add( b3Text) ; + return true; + } + // se radiale + case DT_RADIAL: { + b3Loc.Set(m_ptP0) ; + b3Loc.Add(m_ptPos) ; + // ingombro del testo + BBox3d b3Text ; + if ( GetTextLocalBBox(b3Text) ) + b3Loc.Add(b3Text) ; + return true; + } + // se angolare + case DT_ANGULAR: { + b3Loc.Set( m_ptP0) ; + b3Loc.Add( m_ptP1) ; + b3Loc.Add( m_ptP2) ; + b3Loc.Add( m_ptP3) ; + b3Loc.Add( m_ptP4) ; + b3Loc.Add( m_ptCalcP7) ; + b3Loc.Add( m_ptCalcP8) ; + // ingombro del testo + BBox3d b3Text ; + if ( GetTextLocalBBox( b3Text)) + b3Loc.Add( b3Text) ; + return true ; + } + default: + return false ; + } } //---------------------------------------------------------------------------- bool ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const { - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; // eventuale ricalcolo Update() ; - // se lineare - if ( m_nType == DT_LINEAR) { - // ingombro dei punti (portati nel riferimento passato) - Point3d ptFrP1 = m_ptP1 ; - ptFrP1.ToGlob( frRef) ; - b3Ref.Set( ptFrP1) ; - Point3d ptFrP2 = m_ptP2 ; - ptFrP2.ToGlob( frRef) ; - b3Ref.Add( ptFrP2) ; - Point3d ptFrP3 = m_ptP3 ; - ptFrP3.ToGlob( frRef) ; - b3Ref.Add( ptFrP3) ; - Point3d ptFrP4 = m_ptP4 ; - ptFrP4.ToGlob( frRef) ; - b3Ref.Add( ptFrP4) ; - Point3d ptFrP7 = m_ptCalcP7 ; - ptFrP7.ToGlob( frRef) ; - b3Ref.Add( ptFrP7) ; - Point3d ptFrP8 = m_ptCalcP8 ; - ptFrP8.ToGlob( frRef) ; - b3Ref.Add( ptFrP8) ; - // ingombro del testo - BBox3d b3Text ; - if ( GetTextBBox( frRef, b3Text)) - b3Ref.Add( b3Text) ; - return true ; - } - else - return false ; + // se valido + switch ( m_nType) { + case DT_LINEAR: { + // ingombro dei punti (portati nel riferimento passato) + Point3d ptFrP1 = m_ptP1 ; + ptFrP1.ToGlob( frRef) ; + b3Ref.Set( ptFrP1) ; + Point3d ptFrP2 = m_ptP2 ; + ptFrP2.ToGlob( frRef) ; + b3Ref.Add( ptFrP2) ; + Point3d ptFrP3 = m_ptP3 ; + ptFrP3.ToGlob( frRef) ; + b3Ref.Add( ptFrP3) ; + Point3d ptFrP4 = m_ptP4 ; + ptFrP4.ToGlob( frRef) ; + b3Ref.Add( ptFrP4) ; + Point3d ptFrP7 = m_ptCalcP7 ; + ptFrP7.ToGlob( frRef) ; + b3Ref.Add( ptFrP7) ; + Point3d ptFrP8 = m_ptCalcP8 ; + ptFrP8.ToGlob( frRef) ; + b3Ref.Add( ptFrP8) ; + // ingombro del testo + BBox3d b3Text ; + if ( GetTextBBox( frRef, b3Text)) + b3Ref.Add( b3Text) ; + return true ; + } + case DT_RADIAL: { + // ingombro dei punti (portati nel riferimento passato) + Point3d ptFrP0 = m_ptP0 ; + ptFrP0.ToGlob( frRef) ; + b3Ref.Set( ptFrP0) ; + Point3d ptFrPos = m_ptPos ; + ptFrPos.ToGlob( frRef) ; + b3Ref.Set( ptFrPos) ; + // ingombro del testo + BBox3d b3Text ; + if ( GetTextBBox( frRef, b3Text)) + b3Ref.Add( b3Text) ; + return true ; + } + case DT_ANGULAR: { + Point3d ptFrP0 = m_ptP0; + ptFrP0.ToGlob( frRef); + b3Ref.Set( ptFrP0); + Point3d ptFrP1 = m_ptP1 ; + ptFrP1.ToGlob( frRef) ; + b3Ref.Add( ptFrP1) ; + Point3d ptFrP2 = m_ptP2 ; + ptFrP2.ToGlob( frRef) ; + b3Ref.Add( ptFrP2) ; + Point3d ptFrP3 = m_ptP3 ; + ptFrP3.ToGlob( frRef) ; + b3Ref.Add( ptFrP3) ; + Point3d ptFrP4 = m_ptP4 ; + ptFrP4.ToGlob( frRef) ; + b3Ref.Add( ptFrP4) ; + Point3d ptFrP7 = m_ptCalcP7 ; + ptFrP7.ToGlob( frRef) ; + b3Ref.Add( ptFrP7) ; + Point3d ptFrP8 = m_ptCalcP8 ; + ptFrP8.ToGlob( frRef) ; + b3Ref.Add( ptFrP8) ; + // ingombro del testo + BBox3d b3Text ; + if ( GetTextBBox( frRef, b3Text)) + b3Ref.Add( b3Text) ; + return true ; + } + default: + return false ; + } } //---------------------------------------------------------------------------- @@ -425,8 +666,9 @@ ExtDimension::Translate( const Vector3d& vtMove) // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { + m_ptP0.Translate( vtMove) ; m_ptP1.Translate( vtMove) ; m_ptP2.Translate( vtMove) ; m_ptP3.Translate( vtMove) ; @@ -447,10 +689,11 @@ ExtDimension::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { return ( m_vtN.Rotate( vtAx, dCosAng, dSinAng) && m_vtDir.Rotate( vtAx, dCosAng, dSinAng) && + m_ptP0.Rotate( ptAx, vtAx, dCosAng, dSinAng) && m_ptP1.Rotate( ptAx, vtAx, dCosAng, dSinAng) && m_ptP2.Rotate( ptAx, vtAx, dCosAng, dSinAng) && m_ptP3.Rotate( ptAx, vtAx, dCosAng, dSinAng) && @@ -462,7 +705,7 @@ ExtDimension::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, else return false ; } - + //---------------------------------------------------------------------------- bool ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) @@ -473,18 +716,20 @@ ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, doubl // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { // sistemo i vettori Vector3d vtTmp = m_vtN ^ m_vtDir ; - if ( ! vtTmp.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) || ! vtTmp.Normalize()) + if ( ! vtTmp.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) || ! vtTmp.Normalize() ) return false ; - if ( ! m_vtDir.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) || ! m_vtDir.Normalize()) + if ( ! m_vtDir.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) || ! m_vtDir.Normalize() ) return false ; m_vtN = m_vtDir ^ vtTmp ; - if ( ! m_vtN.Normalize()) + if ( ! m_vtN.Normalize() ) return false ; // scalo i punti di base + if ( ! m_ptP0.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) + return false ; if ( ! m_ptP1.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) return false ; if ( ! m_ptP2.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) @@ -492,7 +737,16 @@ ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, doubl if ( ! m_ptPos.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) return false ; // ricalcolo completamente la quota - return SetLinear( m_ptP1, m_ptP2, m_ptPos, m_vtN, m_vtDir, m_sText) ; + switch ( m_nType ) { + case DT_LINEAR: + return SetLinear( m_ptP1, m_ptP2, m_ptPos, m_vtN, m_vtDir, m_sText) ; + case DT_RADIAL: + return SetRadial( m_ptP0, m_ptPos, m_vtDir, m_vtN, m_sText) ; + case DT_ANGULAR: + return SetAngular( m_ptP1, m_ptP0, m_ptP2, m_ptPos, m_vtN, m_sText) ; + default: + return false ; + } } else return false ; @@ -502,20 +756,22 @@ ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, doubl bool ExtDimension::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) { - // verifico validità del piano di specchiatura + // verifico validità del piano di specchiatura if ( vtNorm.IsSmall()) return false ; // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { - // eseguo il mirror dei versori + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { + // eseguo il mirror dei versori if ( ! m_vtN.Mirror( vtNorm)) return false ; if ( ! m_vtDir.Mirror( vtNorm)) return false ; - // eseguo il mirror dei punti + // eseguo il mirror dei punti + if ( ! m_ptP0.Mirror( ptOn, vtNorm)) + return false ; if ( ! m_ptP1.Mirror( ptOn, vtNorm)) return false ; if ( ! m_ptP2.Mirror( ptOn, vtNorm)) @@ -537,27 +793,29 @@ ExtDimension::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) } //---------------------------------------------------------------------------- -bool +bool ExtDimension::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { - // verifico validità dei parametri + // verifico validità dei parametri if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { // sistemo i vettori Vector3d vtTmp = m_vtN ^ m_vtDir ; - if ( ! vtTmp.Shear( vtNorm, vtDir, dCoeff) || ! vtTmp.Normalize()) + if ( ! vtTmp.Shear( vtNorm, vtDir, dCoeff ) || ! vtTmp.Normalize()) return false ; - if ( ! m_vtDir.Shear( vtNorm, vtDir, dCoeff) || ! m_vtDir.Normalize()) + if ( ! m_vtDir.Shear( vtNorm, vtDir, dCoeff ) || ! m_vtDir.Normalize()) return false ; m_vtN = m_vtDir ^ vtTmp ; if ( ! m_vtN.Normalize()) return false ; // eseguo scorrimento dei punti di base + if ( ! m_ptP0.Shear( ptOn, vtNorm, vtDir, dCoeff)) + return false ; if ( ! m_ptP1.Shear( ptOn, vtNorm, vtDir, dCoeff)) return false ; if ( ! m_ptP2.Shear( ptOn, vtNorm, vtDir, dCoeff)) @@ -565,7 +823,16 @@ ExtDimension::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d if ( ! m_ptPos.Shear( ptOn, vtNorm, vtDir, dCoeff)) return false ; // ricalcolo completamente la quota - return SetLinear( m_ptP1, m_ptP2, m_ptPos, m_vtN, m_vtDir, m_sText) ; + switch ( m_nType ) { + case DT_LINEAR: + return SetLinear( m_ptP1, m_ptP2, m_ptPos, m_vtN, m_vtDir, m_sText) ; + case DT_RADIAL: + return SetRadial(m_ptP0, m_ptPos, m_vtDir, m_vtN, m_sText) ; + case DT_ANGULAR: + return SetAngular( m_ptP1, m_ptP0, m_ptP2, m_ptPos, m_vtN, m_sText) ; + default: + return false ; + } } else return false ; @@ -575,20 +842,21 @@ ExtDimension::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d bool ExtDimension::ToGlob( const Frame3d& frRef) { - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se riferimento globale, non devo fare alcunché + // se riferimento globale, non devo fare alcunch� if ( AreSameFrame( frRef, GLOB_FRM)) return true ; // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { - // trasformo punto e versori - return ( m_vtN.ToGlob( frRef) && + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { + // trasformo punto e versori + return ( m_vtN.ToGlob( frRef) && m_vtDir.ToGlob( frRef) && + m_ptP0.ToGlob( frRef) && m_ptP1.ToGlob( frRef) && m_ptP2.ToGlob( frRef) && m_ptP3.ToGlob( frRef) && @@ -605,20 +873,21 @@ ExtDimension::ToGlob( const Frame3d& frRef) bool ExtDimension::ToLoc( const Frame3d& frRef) { - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se riferimento globale, non devo fare alcunché + // se riferimento globale, non devo fare alcunch� if ( AreSameFrame( frRef, GLOB_FRM)) return true ; // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { - // trasformo punto e versori + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { + // trasformo punto e versori return ( m_vtN.ToLoc( frRef) && m_vtDir.ToLoc( frRef) && + m_ptP0.ToLoc( frRef) && m_ptP1.ToLoc( frRef) && m_ptP2.ToLoc( frRef) && m_ptP3.ToLoc( frRef) && @@ -635,20 +904,21 @@ ExtDimension::ToLoc( const Frame3d& frRef) bool ExtDimension::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) { - // verifico validità dei frame + // verifico validit� dei frame if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) return false ; - // se i due riferimenti coincidono, non devo fare alcunché + // se i due riferimenti coincidono, non devo fare alcunch� if ( AreSameFrame( frOri, frDest)) return true ; // imposto ricalcolo m_bToCalc = true ; m_OGrMgr.Reset() ; - // se lineare - if ( m_nType == DT_LINEAR) { + // se valido + if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) { // trasformo punto e versori return ( m_vtN.ToGlob( frOri) && m_vtN.ToLoc( frDest) && m_vtDir.ToGlob( frOri) && m_vtDir.ToLoc( frDest) && + m_ptP0.ToGlob( frOri) && m_ptP0.ToLoc( frDest) && m_ptP1.ToGlob( frOri) && m_ptP1.ToLoc( frDest) && m_ptP2.ToGlob( frOri) && m_ptP2.ToLoc( frDest) && m_ptP3.ToGlob( frOri) && m_ptP3.ToLoc( frDest) && @@ -664,51 +934,213 @@ ExtDimension::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) //---------------------------------------------------------------------------- bool ExtDimension::Update( void) const -{ - // se ricalcolo non richiesto, esco +{// se ricalcolo non richiesto, esco if ( ! m_bToCalc) return true ; - // se quota lineare - if ( m_nType == DT_LINEAR) { - // testo - m_sCalcText = m_sText ; - if ( m_sCalcText.find( IS_MEASURE) != string::npos) { - double dVal = ( m_ptP2 - m_ptP1) * m_vtDir * ( m_bLenIsMM ? 1 : 1. / ONEINCH) ; - string sVal = ToString( dVal, m_nDecDigit) ; - ReplaceString( m_sCalcText, IS_MEASURE, sVal) ; + + switch ( m_nType) { + // se quota lineare, radiale o diametrale + case DT_LINEAR: { + // testo + m_sCalcText = m_sText ; + if ( m_sCalcText.find( IS_MEASURE) != string::npos) { + double dVal = ( m_ptP2 - m_ptP1 ) * m_vtDir * ( m_bLenIsMM ? 1 : 1. / ONEINCH) ; + string sVal = ToString( dVal, m_nDecDigit) ; + ReplaceString( m_sCalcText, IS_MEASURE, sVal) ; + } + // punto di inserimento del testo + m_ptCalcPos = ( m_ptP5 + m_ptP6) / 2 ; + // semidistanza di interruzione + double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; + // lunghezza della linea di misura + double dLen = ( m_ptP6 - m_ptP5 ).Len() ; + // determino come orientare le frecce e dove mettere il testo + if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) { + m_bCalcArrowIn = true ; + m_ptCalcP7 = m_ptCalcPos - m_vtDir * dHalfDist ; + m_ptCalcP8 = m_ptCalcPos + m_vtDir * dHalfDist ; + } + // le frecce stanno fuori ma il testo dentro + else if ( dLen >= 2 * dHalfDist) { + m_bCalcArrowIn = false ; + m_ptCalcP7 = m_ptP5 - m_vtDir * 2 * m_dArrowLen ; + m_ptCalcP8 = m_ptP6 + m_vtDir * 2 * m_dArrowLen ; + } + // stanno fuori sia le frecce sia il testo + else { + m_bCalcArrowIn = false ; + m_ptCalcP7 = m_ptP5 - m_vtDir * 2 * m_dArrowLen ; + m_ptCalcP8 = m_ptP6 + m_vtDir * 2 * m_dArrowLen ; + // metto la quotatura dal lato di ptPos + if ( ( m_ptPos - m_ptCalcP7).SqLen() <= ( m_ptPos - m_ptCalcP8).SqLen() ) + m_ptCalcPos = m_ptCalcP7 - m_vtDir * dHalfDist ; + else + m_ptCalcPos = m_ptCalcP8 + m_vtDir * dHalfDist ; + } + // dichiaro ricalcolo eseguito + m_bToCalc = false ; + return true ; } - // punto di inserimento del testo - m_ptCalcPos = ( m_ptP5 + m_ptP6) / 2 ; - // semidistanza di interruzione - double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; - // lunghezza della linea di misura - double dLen = ( m_ptP6 - m_ptP5).Len() ; - // determino come orientare le frecce e dove mettere il testo - if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) { - m_bCalcArrowIn = true ; - m_ptCalcP7 = m_ptCalcPos - m_vtDir * dHalfDist ; - m_ptCalcP8 = m_ptCalcPos + m_vtDir * dHalfDist ; + case DT_RADIAL: + case DT_DIAMETRAL: { + // testo + m_sCalcText = m_sText ; + if ( m_sCalcText.find( IS_MEASURE) != string::npos) { + double dVal = 0 ; + dVal = Dist( m_ptP1, m_ptP2) * ( m_bLenIsMM ? 1 : 1. / ONEINCH ) ; + string sVal = ToString( dVal, m_nDecDigit) ; + if ( m_nType == DT_RADIAL ) + sVal = 'R' + sVal ; + else if ( m_nType == DT_DIAMETRAL) + sVal = u8"\u00D8" + sVal ; + ReplaceString( m_sCalcText, IS_MEASURE, sVal) ; + } + // punto di inserimento del testo + m_ptCalcPos = ( m_ptP5 + m_ptP6) / 2 ; + // alzo il testo dalla linea di misura + BBox3d b3Text ; + if ( ! GetTextMyBBox( m_ptCalcPos, b3Text) && ! b3Text.IsEmpty()) + return false ; + double dHeight = b3Text.GetMax().y - b3Text.GetMin().y ; + Vector3d vtPerpDir = m_ptPos - m_ptP0 ; + vtPerpDir.Normalize() ; + double dAngDeg = 0 ; + if ( ! vtPerpDir.GetAngle( m_vtDir,dAngDeg) || ! vtPerpDir.Rotate(m_vtN, ( dAngDeg < 90 ? 90 : - 90))) + return false ; + m_ptCalcPos = m_ptCalcPos + 0.6 * dHeight * vtPerpDir ; + // semidistanza di interruzione + double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; + // lunghezza della linea di misura + double dLen = ( m_ptP6 - m_ptP5).Len() ; + // determino come orientare le frecce e dove mettere il testo + if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) { + m_bCalcArrowIn = true ; + m_bCalcTextOn = true ; + m_ptCalcP7 = m_ptCalcPos - m_vtDir * dHalfDist ; + m_ptCalcP8 = m_ptCalcPos + m_vtDir * dHalfDist ; + } + // le frecce stanno fuori ma il testo dentro + else if ( dLen >= 2 * dHalfDist) { + m_bCalcArrowIn = false ; + m_bCalcTextOn = true ; + m_ptCalcP7 = m_ptP5 - m_vtDir * 2 * m_dArrowLen ; + m_ptCalcP8 = m_ptP6 + m_vtDir * 2 * m_dArrowLen ; + } + // stanno fuori sia le frecce sia il testo + else { + m_bCalcArrowIn = false ; + m_bCalcTextOn = false ; + // metto la quotatura dal lato di ptPos + Vector3d vtRad = m_ptPos - m_ptP0 ; + vtRad.Normalize() ; + m_ptCalcPos = m_ptPos + vtRad * ( dHalfDist + 2 * m_dArrowLen) ; + } + // dichiaro ricalcolo eseguito + m_bToCalc = false ; + return true ; } - else if ( dLen >= 2 * dHalfDist) { - m_bCalcArrowIn = false ; - m_ptCalcP7 = m_ptP5 - m_vtDir * 2 * m_dArrowLen ; - m_ptCalcP8 = m_ptP6 + m_vtDir * 2 * m_dArrowLen ; + //se quota angolare + case DT_ANGULAR: { + // testo + m_sCalcText = m_sText ; + if ( m_sCalcText.find( IS_MEASURE ) != string::npos) { + // calcolo gli angoli tra m_ptPos e i due punti che identificano i lati dell'angolo + // per capire se sto calcolando l'angolo interno o esterno + double dAngDeg, dAngDeg1, dAngDeg2 = 0 ; + Vector3d vtLine1 = m_ptP1 - m_ptP0 ; + Vector3d vtLine2 = m_ptP2 - m_ptP0 ; + Vector3d vtLine3 = m_ptPos - m_ptP0 ; + if ( ! vtLine1.GetAngle(vtLine2, dAngDeg) || ! vtLine1.GetAngle(vtLine3, dAngDeg1) || ! vtLine2.GetAngle(vtLine3, dAngDeg2)) + return false ; + if ( dAngDeg < dAngDeg1 + dAngDeg2 - EPS_SMALL || dAngDeg > dAngDeg1 + dAngDeg2 + EPS_SMALL) + dAngDeg = 360 - dAngDeg ; + string sAngDeg = ToString( dAngDeg, m_nDecDigit) ; + ReplaceString( m_sCalcText, IS_MEASURE, sAngDeg + "°") ; + //calcolo l'arco su cui metterò la misura + PtrOwner pCrvPos( CreateBasicCurveArc()) ; + if ( IsNull( pCrvPos) || ! pCrvPos->Set3P(m_ptP6, m_ptPos, m_ptP5, false)) + return false ; + // punto di inserimento del testo + pCrvPos->GetMidPoint( m_ptCalcPos) ; + // semidistanza di interruzione + double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; + // lunghezza della linea di misura + double dLen = 0 ; + if ( ! pCrvPos->GetLength( dLen)) + return false ; + // calcolo anche lo spazio ad una distanza dal centro maggiorata + double dLenPos = 0 ; + double dDist = Dist( m_ptCalcPos, m_ptP0) ; + dLenPos = dDist * dAngDeg * DEGTORAD ; + + // // Creo la curva per trovare le code delle frecce se fuori + // PtrOwner pCrvPosExt(pCrvPos->Clone()) ; + //// controllo che l'arco esplementare sia più lungo della somma delle frecce + // double dLenEsp = dDist * ( 360 - dAngDeg) * DEGTORAD; + // if ( dLenEsp > 4 * m_dArrowLen ) { + // pCrvPosExt->ExtendStartByLen( 2 * m_dArrowLen) ; + // pCrvPosExt->ExtendEndByLen( 2 * m_dArrowLen) ; + // } + //// altrimenti mi allungo solo della lunghezza della punta della freccia + // else { + // pCrvPosExt->ExtendStartByLen( m_dArrowLen) ; + // pCrvPosExt->ExtendEndByLen( m_dArrowLen) ; + // } + + // determino come orientare le frecce e dove mettere il testo + double dU ; + // frecce e testo dentro + if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) { + m_bCalcArrowIn = true ; + m_bCalcTextOn = true ; + pCrvPos->GetParamAtLength( dLen / 2. + dHalfDist, dU) ; + pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP7) ; + pCrvPos->GetParamAtLength( dLen / 2. - dHalfDist, dU) ; + pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP8) ; + } + // le frecce stanno fuori ma il testo dentro + // se allontanadomi dal centro il testo ci sta, allora mi allontano dal centro anziché metter il testo fuori + else if ( dLen > 2 * dHalfDist || ( dLen < 2 * dHalfDist && dLenPos > 2 * dHalfDist)) { + m_bCalcArrowIn = false ; + m_bCalcTextOn = true ; + pCrvPos->GetParamAtLength( dLen / 2. + dHalfDist, dU) ; + pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP7) ; + pCrvPos->GetParamAtLength( dLen / 2. - dHalfDist, dU) ; + pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP8) ; + //pCrvPosExt->GetStartPoint( m_ptCalcP8) ; + //pCrvPosExt->GetEndPoint( m_ptCalcP7) ; + if ( dLen < 2 * dHalfDist) { + m_ptCalcPos += ( m_ptCalcPos - m_ptP0) ; + m_bCalcTextOn = false ; + } + } + // stanno fuori sia le frecce sia il testo + else { + m_bCalcArrowIn = false ; + m_bCalcTextOn = false ; + //pCrvPosExt->GetStartPoint( m_ptCalcP8) ; + //pCrvPosExt->GetEndPoint( m_ptCalcP7) ; + vtLine1.Normalize() ; + vtLine2.Normalize() ; + if ( Dist( m_ptPos, m_ptP5) < Dist( m_ptPos, m_ptP6)) { + Vector3d vtDirEnd ; + pCrvPos->GetEndDir( vtDirEnd) ; + m_ptCalcPos = m_ptP5 + dHalfDist * ( vtDirEnd + vtLine1) ; + } + else { + Vector3d vtDirStart ; + pCrvPos->GetStartDir( vtDirStart) ; + m_ptCalcPos = m_ptP6 + dHalfDist * ( - vtDirStart + vtLine2) ; + } + } + // dichiaro ricalcolo eseguito + m_bToCalc = false ; + return true ; + } } - else { - m_bCalcArrowIn = false ; - m_ptCalcP7 = m_ptP5 - m_vtDir * 2 * m_dArrowLen ; - m_ptCalcP8 = m_ptP6 + m_vtDir * 2 * m_dArrowLen ; - if ( ( m_ptPos - m_ptCalcP7).SqLen() <= ( m_ptPos - m_ptCalcP8).SqLen()) - m_ptCalcPos = m_ptCalcP7 - m_vtDir * dHalfDist ; - else - m_ptCalcPos = m_ptCalcP8 + m_vtDir * dHalfDist ; + default: + return false ; } - // dichiaro ricalcolo eseguito - m_bToCalc = false ; - return true ; - } - else - return false ; } //---------------------------------------------------------------------------- @@ -717,13 +1149,25 @@ ExtDimension::GetMidPoint( Point3d& ptMid) const { // eventuale ricalcolo Update() ; - // se quota lineare - if ( m_nType == DT_LINEAR) { - ptMid = ( m_ptP1 + m_ptP2) / 2 ; - return true ; - } - else - return false ; + switch ( m_nType) { + // se quota lineare o radiale + case DT_LINEAR : + case DT_RADIAL : + case DT_DIAMETRAL: { + ptMid = ( m_ptP1 + m_ptP2) / 2; + return true; + } + // se quota angolare + case DT_ANGULAR : { + PtrOwner pCrvPos( CreateBasicCurveArc()) ; + if ( ! pCrvPos->Set3P( m_ptP6, m_ptPos, m_ptP5, false)) + return false ; + pCrvPos->GetMidPoint( ptMid) ; + return true; + } + default: + return false ; + } } //---------------------------------------------------------------------------- @@ -732,13 +1176,21 @@ ExtDimension::GetCenterPoint( Point3d& ptCen) const { // eventuale ricalcolo Update() ; - // se quota lineare - if ( m_nType == DT_LINEAR) { - ptCen = ( m_ptP5 + m_ptP6) / 2 ; - return true ; + //se valido + switch ( m_nType) { + case DT_LINEAR: { + ptCen = ( m_ptP5 + m_ptP6) / 2 ; + return true ; + } + case DT_RADIAL : + case DT_DIAMETRAL : + case DT_ANGULAR : { + ptCen = m_ptP0 ; + return true ; + } + default: + return false ; } - else - return false ; } //---------------------------------------------------------------------------- @@ -747,45 +1199,155 @@ ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& { // eventuale ricalcolo Update() ; - // se quota lineare - if ( m_nType == DT_LINEAR) { - // prima linea di riferimento - lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP1) ; - lstPL.back().AddUPoint( 1, m_ptP3) ; - // seconda linea di riferimento - lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP2) ; - lstPL.back().AddUPoint( 1, m_ptP4) ; - // se non c'è testo, linea di misura intera - if ( IsEmptyOrSpaces( m_sCalcText)) { + // se quota valida + switch ( m_nType) { + case DT_LINEAR: { + // prima linea di riferimento lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP5) ; - lstPL.back().AddUPoint( 1, m_ptP6) ; + lstPL.back().AddUPoint(0, m_ptP1) ; + lstPL.back().AddUPoint(1, m_ptP3) ; + // seconda linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint(0, m_ptP2) ; + lstPL.back().AddUPoint(1, m_ptP4) ; + // se non c'� testo, linea di misura intera + if ( IsEmptyOrSpaces(m_sCalcText) ) { + lstPL.emplace_back() ; + lstPL.back().AddUPoint(0, m_ptP5) ; + lstPL.back().AddUPoint(1, m_ptP6) ; + } + // altrimenti, linea di misura divisa in due parti + else { + // prima parte + lstPL.emplace_back() ; + lstPL.back().AddUPoint(0, m_ptP5) ; + lstPL.back().AddUPoint(1, m_ptCalcP7) ; + // seconda parte + lstPL.emplace_back() ; + lstPL.back().AddUPoint(0, m_ptP6) ; + lstPL.back().AddUPoint(1, m_ptCalcP8) ; + } + // frecce + lstPL.emplace_back() ; + GetArrowHead(m_ptP5, ( m_bCalcArrowIn ? -m_vtDir : m_vtDir ), lstPL.back()) ; + lstPL.emplace_back() ; + GetArrowHead(m_ptP6, ( m_bCalcArrowIn ? m_vtDir : -m_vtDir ), lstPL.back()) ; + // testo + POLYLINELIST lstTxt; + if ( ApproxTextWithLines(dLinTol, dAngTolDeg, lstTxt)) + lstPL.splice(lstPL.end(), lstTxt) ; + return true ; } - // altrimenti, linea di misura divisa in due parti - else { - // prima parte + case DT_RADIAL: + case DT_DIAMETRAL :{ + Vector3d vtRad = m_ptPos - m_ptP0; + vtRad.Normalize() ; + // prima linea di riferimento lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP5) ; - lstPL.back().AddUPoint( 1, m_ptCalcP7) ; - // seconda parte + lstPL.back().AddUPoint(0, m_ptP1) ; + lstPL.back().AddUPoint(1, m_ptP2) ; + // freccia lstPL.emplace_back() ; - lstPL.back().AddUPoint( 0, m_ptP6) ; - lstPL.back().AddUPoint( 1, m_ptCalcP8) ; + GetArrowHead(m_ptP6, ( m_bCalcArrowIn ? vtRad : - vtRad ), lstPL.back()) ; + Point3d ptArrowTail ; + if ( ! m_bCalcArrowIn) { + lstPL.emplace_back() ; + ptArrowTail = m_ptP6 + vtRad * m_dArrowLen * 2 ; + lstPL.back().AddUPoint(0, m_ptP6) ; + lstPL.back().AddUPoint(1, ptArrowTail) ; + } + if ( m_nType == DT_DIAMETRAL) { + lstPL.emplace_back() ; + GetArrowHead(m_ptP5, ( m_bCalcArrowIn ? - vtRad : vtRad ), lstPL.back()) ; + if ( ! m_bCalcArrowIn) { + lstPL.emplace_back() ; + ptArrowTail = m_ptP5 - vtRad * m_dArrowLen * 2 ; + lstPL.back().AddUPoint(0, m_ptP5) ; + lstPL.back().AddUPoint(1, ptArrowTail) ; + } + } + // testo + POLYLINELIST lstTxt; + if ( ApproxTextWithLines(dLinTol, dAngTolDeg, lstTxt)) + lstPL.splice(lstPL.end(), lstTxt) ; + return true ; + } + case DT_ANGULAR: { + // approssimerò l'arco con una polyline + PolyLine plApprox ; + // cerca nel geom kernel delle tolleranze standard + double dLinTol = 0.01 ; + double dAngTolDeg = 0.01 ; + // prima linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP1) ; + lstPL.back().AddUPoint( 1, m_ptP3) ; + // seconda linea di riferimento + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP2) ; + lstPL.back().AddUPoint( 1, m_ptP4) ; + // curva per l'arco + PtrOwner pCrvPos( CreateBasicCurveArc()) ; + if ( IsNull( pCrvPos)) + return false ; + double dHalfDist = GetTextHalfDist( m_ptCalcPos) ; + + // se non ho testo + if ( IsEmptyOrSpaces( m_sCalcText)) { + if ( ! pCrvPos->SetC2PN( m_ptP0, m_ptP6, m_ptP5, m_vtN) || ! pCrvPos->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) + return false ; + lstPL.emplace_back( plApprox) ; + } + // altrimenti, linea di misura divisa in due parti + else { + // prima parte + if ( ! pCrvPos->SetC2PN( m_ptP0, m_ptP5, m_ptCalcP7, m_vtN) || ! pCrvPos->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) + return false ; + lstPL.emplace_back( plApprox) ; + // seconda parte + if ( ! pCrvPos->SetC2PN( m_ptP0, m_ptP6, m_ptCalcP8, m_vtN) || ! pCrvPos->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox)) + return false ; + lstPL.emplace_back( plApprox) ; + } + // frecce + Vector3d vtStartDir ; + Vector3d vtEndDir ; + if ( ! pCrvPos->Set3P( m_ptP6, m_ptPos, m_ptP5, false)) + return false ; + pCrvPos->GetStartDir( vtStartDir) ; + pCrvPos->GetEndDir( vtEndDir) ; + //storto la punta delle frecce su una direzione mediata tra l'arco e la perpendicolare al lato + double dFactor = 1 / ( 0.6 * m_vtDir.Len()) ; // questo fattore dipende direttamente dalla distanza di m_ptPos dal centro e smorza lo scostamento + Vector3d vtLine1 = m_ptP1 - m_ptP0 ; + Vector3d vtLine2 = m_ptP2 - m_ptP0 ; + vtLine1.Normalize() ; + vtLine2.Normalize() ; + // se però le frecce sono fuori non le storto e faccio le code dritte anziché curvilinee + if ( ! m_bCalcArrowIn) { + Point3d ptArrowTail1, ptArrowTail2 ; + ptArrowTail1 = m_ptP5 + vtEndDir * m_dArrowLen *2 ; + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP5) ; + lstPL.back().AddUPoint( 1, ptArrowTail1) ; + ptArrowTail2 = m_ptP6 - vtStartDir * m_dArrowLen *2 ; + lstPL.emplace_back() ; + lstPL.back().AddUPoint( 0, m_ptP6) ; + lstPL.back().AddUPoint( 1, ptArrowTail2) ; + dFactor = 0 ; + } + lstPL.emplace_back() ; + GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? vtEndDir : - vtEndDir) + vtLine1 * dFactor, lstPL.back()) ; + lstPL.emplace_back() ; + GetArrowHead( m_ptP6, ( m_bCalcArrowIn ? - vtStartDir : vtStartDir) + vtLine2 * dFactor, lstPL.back()) ; + // testo + POLYLINELIST lstTxt ; + if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt)) + lstPL.splice( lstPL.end(), lstTxt) ; + return true ; + } + default: + return false ; } - // frecce - lstPL.emplace_back() ; - GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? -m_vtDir : m_vtDir), lstPL.back()) ; - lstPL.emplace_back() ; - GetArrowHead( m_ptP6, ( m_bCalcArrowIn ? m_vtDir : -m_vtDir), lstPL.back()) ; - // testo - POLYLINELIST lstTxt ; - if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt)) - lstPL.splice( lstPL.end(), lstTxt) ; - } - - return true ; } //---------------------------------------------------------------------------- @@ -796,14 +1358,17 @@ ExtDimension::GetTextHalfDist( const Point3d& ptText) const double dHalfDist = m_dTextHeight / 2 + m_dTextDist ; // recupero il box di ingombro del testo BBox3d b3Text ; - if ( GetTextMyBBox( ptText, b3Text) && ! b3Text.IsEmpty()) { + Vector3d vtDir = m_vtDir ; + if ( m_nType == DT_ANGULAR) + vtDir.Normalize() ; + if ( GetTextMyBBox( ptText, b3Text) && !b3Text.IsEmpty()) { double dHalfL = ( b3Text.GetMax().x - b3Text.GetMin().x) / 2 ; double dHalfH = ( b3Text.GetMax().y - b3Text.GetMin().y) / 2 ; dHalfDist = sqrt( dHalfL * dHalfL + dHalfH * dHalfH) ; - if ( abs( m_vtDir.x) > EPS_ZERO) - dHalfDist = min( dHalfDist, dHalfL / abs( m_vtDir.x)) ; - if ( abs( m_vtDir.y) > EPS_ZERO) - dHalfDist = min( dHalfDist, dHalfH / abs( m_vtDir.y)) ; + if ( abs( vtDir.x) > EPS_ZERO) + dHalfDist = min( dHalfDist, dHalfL / abs( vtDir.x)) ; + if ( abs( vtDir.y) > EPS_ZERO) + dHalfDist = min( dHalfDist, dHalfH / abs( vtDir.y)) ; dHalfDist += m_dTextDist ; } return dHalfDist ; @@ -818,8 +1383,8 @@ ExtDimension::GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLin return false ; const double A_WIDTH_COEFF = 0.1666 ; PL.AddUPoint( 0, ptTip) ; - PL.AddUPoint( 1, ptTip - ( vtDir + vtPerp * A_WIDTH_COEFF) * m_dArrowLen) ; - PL.AddUPoint( 2, ptTip - ( vtDir - vtPerp * A_WIDTH_COEFF) * m_dArrowLen) ; + PL.AddUPoint( 1, ptTip - ( vtDir + vtPerp * A_WIDTH_COEFF ) * m_dArrowLen) ; + PL.AddUPoint( 2, ptTip - ( vtDir - vtPerp * A_WIDTH_COEFF ) * m_dArrowLen) ; PL.AddUPoint( 4, ptTip) ; return true ; } @@ -861,6 +1426,14 @@ ExtDimension::ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELI if ( ! frRef.Set( m_ptCalcPos, m_vtN)) return false ; + if ( ( m_nType == DT_RADIAL || m_nType == DT_DIAMETRAL) && m_bCalcTextOn ) { + double dAngDeg = 0 ; + Vector3d vtRad = m_ptPos - m_ptP0; + m_vtDir.GetAngle( vtRad, dAngDeg); + if ( ! frRef.Set( m_ptCalcPos, m_vtN, ( dAngDeg > 90 ? - vtRad : vtRad ))) + return false ; + } + // eseguo la trasformazione for ( auto& PL : lstPL) PL.ToGlob( frRef) ; diff --git a/ExtDimension.h b/ExtDimension.h index a7e4e95..02a4906 100644 --- a/ExtDimension.h +++ b/ExtDimension.h @@ -62,6 +62,10 @@ class ExtDimension : public IExtDimension, public IGeoObjRW int nDecDigit, const std::string& sFont, double dTextHeight) override ; bool SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos, const Vector3d& vtN, const Vector3d& vtDir, const std::string& sText) override ; + bool SetAngular( const Point3d& ptP1, const Point3d& ptP0, const Point3d& ptP2, const Point3d& ptPos, + const Vector3d& vtN, const std::string& sText ) override ; + bool SetRadial( const Point3d& ptP0, const Point3d& ptPos, const Vector3d& vtX, const Vector3d& vtN, const std::string& sText) override ; + bool SetDiametral( const Point3d& ptP0, const Point3d& ptPos, const Vector3d& vtX, const Vector3d& vtN, const std::string& sText) override ; const Vector3d& GetNormVersor( void) const override { return m_vtN ; } const Vector3d& GetDirVersor( void) const override @@ -128,6 +132,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW int m_nType ; // tipo di quota Vector3d m_vtN ; // versore normale Vector3d m_vtDir ; // versore direzione + Point3d m_ptP0 ; // zeresimo punto Point3d m_ptP1 ; // primo punto Point3d m_ptP2 ; // secondo punto Point3d m_ptP3 ; // terzo punto @@ -140,6 +145,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW mutable std::string m_sCalcText ; // testo effettivo della quota mutable Point3d m_ptCalcPos ; // posizione effettiva della quota mutable bool m_bCalcArrowIn ; // flag posizione effettiva delle frecce + mutable bool m_bCalcTextOn ; // flag posizione del testo sulla linea di misura mutable Point3d m_ptCalcP7 ; // settimo punto effettivo mutable Point3d m_ptCalcP8 ; // ottavo punto effettivo double m_dExtLineLen ; // lunghezza di estensione della linea