6dd3ea5cc2
- aggiustamenti e ricompilazione per passaggio a C++ 20
1607 lines
54 KiB
C++
1607 lines
54 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2019-2019
|
|
//----------------------------------------------------------------------------
|
|
// File : ExtDimension.cpp Data : 27.12.19 Versione : 2.2a1
|
|
// Contenuto : Implementazione della classe Dimension ( quota).
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 27.12.19 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- 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 "IntersLineLine.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 <new>
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
static const string IS_MEASURE = "<>" ;
|
|
static const double STD_EXTLINELEN = 5.0 ;
|
|
static const double MIN_EXTLINELEN = 0.1 ;
|
|
static const double STD_ARROWLEN = 5.0 ;
|
|
static const double MIN_ARROWLEN = 0.1 ;
|
|
static const double STD_TEXTDIST = 2.0 ;
|
|
static const double MIN_TEXTDIST = 0.1 ;
|
|
static const int STD_DECDIGIT = -2 ;
|
|
static const int MAX_DECDIGIT = 6 ;
|
|
static const string STD_FONT = "ModernPropS.Nfe" ;
|
|
static const double STD_TEXTHEIGHT = 10.0 ;
|
|
static const double MIN_TEXTHEIGHT = 1.0 ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
GEOOBJ_REGISTER( EXT_DIMENSION, NGE_E_DIM, ExtDimension) ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
ExtDimension::ExtDimension( void)
|
|
: m_dExtLineLen( STD_EXTLINELEN), m_dArrowLen( STD_ARROWLEN), m_dTextDist( STD_TEXTDIST),
|
|
m_bLenIsMM( true), m_nDecDigit( STD_DECDIGIT), m_sFont( STD_FONT), m_dTextHeight( STD_TEXTHEIGHT),
|
|
m_nTempProp{0,0}, m_dTempParam{0.0,0.0}
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ExtDimension::~ExtDimension( void)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::SetStyle( double dExtLineLen, double dArrowLen, double dTextDist, bool bLenIsMM,
|
|
int nDecDigit, const string& sFont, double dTextHeight)
|
|
{
|
|
m_dExtLineLen = max( dExtLineLen, MIN_EXTLINELEN) ;
|
|
m_dArrowLen = max( dArrowLen, MIN_ARROWLEN) ;
|
|
m_dTextDist = max( dTextDist, MIN_TEXTDIST) ;
|
|
m_bLenIsMM = bLenIsMM ;
|
|
m_nDecDigit = Clamp( nDecDigit, -MAX_DECDIGIT, MAX_DECDIGIT) ;
|
|
m_sFont = sFont ;
|
|
m_dTextHeight = max( dTextHeight, MIN_TEXTHEIGHT) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
|
|
const Vector3d& vtN, const Vector3d& vtDir, const string& sText)
|
|
{
|
|
// 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 P1 e N
|
|
m_ptP1 = ptP1 ;
|
|
m_ptP2 = ptP2 - ( ptP2 - m_ptP1) * m_vtN * m_vtN ;
|
|
m_ptPos = ptPos - ( ptPos - m_ptP1) * m_vtN * m_vtN ;
|
|
// verifico che i punti di misura non siano coincidenti
|
|
if ( AreSamePointApprox( m_ptP1, m_ptP2))
|
|
return false ;
|
|
// direzione di riferimento ( nel piano perpendicolare a vtN)
|
|
m_vtDir = vtDir ;
|
|
if ( m_vtDir.IsSmall())
|
|
m_vtDir = m_ptP2 - m_ptP1 ;
|
|
else {
|
|
m_vtDir -= m_vtDir * m_vtN * m_vtN ;
|
|
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à
|
|
Vector3d vtLine1 = m_vtDir ;
|
|
vtLine1.Rotate( m_vtN, 0, 1) ;
|
|
Vector3d vtLine2 = vtLine1 ;
|
|
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)
|
|
vtLine1 = vtLine2 ;
|
|
if ( abs( dProSca2) < EPS_SMALL)
|
|
vtLine2 = 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 ;
|
|
// assegnazione del testo
|
|
m_sText = sText ;
|
|
// assegno il tipo
|
|
m_nType = DT_LINEAR ;
|
|
// imposto da calcolare
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::SetRadial( const Point3d& ptCen, const Point3d& ptPos,
|
|
const Vector3d& vtN, const string& sText)
|
|
{ // il punto m_ptP6 viene utilizzato per il centro
|
|
// dichiaro quota non ancora determinata
|
|
m_nType = DT_NONE ;
|
|
// verifico la definizione del versore normale e del versore X
|
|
m_vtN = vtN ;
|
|
m_vtDir = ptPos - ptCen ;
|
|
if ( ! m_vtN.Normalize() || ! m_vtDir.Normalize())
|
|
return false ;
|
|
// porto i punti nel piano definito da ptCen e vtN
|
|
m_ptP6 = ptCen ;
|
|
m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ;
|
|
m_ptP1 = ptCen ;
|
|
m_ptP5 = m_ptP1 ;
|
|
m_ptP2 = m_ptPos ;
|
|
// verifico che i punti di misura non siano coincidenti
|
|
if ( AreSamePointApprox( m_ptP6, 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& ptCen, const Point3d& ptPos,
|
|
const Vector3d& vtN, const string& sText)
|
|
{ // il punto m_ptP6 viene utilizzato per il centro
|
|
// dichiaro quota non ancora determinata
|
|
m_nType = DT_NONE ;
|
|
// verifico la definizione del versore normale e del versore X
|
|
m_vtN = vtN ;
|
|
m_vtDir = ptPos - ptCen ;
|
|
if ( ! m_vtN.Normalize() || ! m_vtDir.Normalize())
|
|
return false ;
|
|
// porto i punti nel piano definito da ptP6 e vtN
|
|
m_ptP6 = ptCen ;
|
|
m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ;
|
|
m_ptP2 = m_ptPos ;
|
|
// ottengo il punto diametralmente opposto a ptPos
|
|
m_ptP1 = ptCen - ( m_ptPos - ptCen) ;
|
|
m_ptP5 = m_ptP1 ;
|
|
// verifico che i punti di misura non siano coincidenti
|
|
if ( AreSamePointApprox( m_ptP5, 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;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::SetAngular( const Point3d& ptV, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
|
|
const Vector3d& vtN, const string& sText)
|
|
{
|
|
// 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 e le direzioni nel piano definito da V e N
|
|
m_ptP6 = ptV ;
|
|
m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ;
|
|
m_vtDir = m_ptPos - m_ptP6 ;
|
|
double dLenDir = m_vtDir.Len() ;
|
|
Vector3d vtLine1 = OrthoCompo( ptP1 - m_ptP6, m_vtN) ;
|
|
Vector3d vtLine2 = OrthoCompo( ptP2 - m_ptP6, m_vtN) ;
|
|
// verifico che i punti di misura non siano coincidenti
|
|
if ( ! vtLine1.Normalize() || ! vtLine2.Normalize() || dLenDir < EPS_SMALL)
|
|
return false ;
|
|
|
|
// controllo se è testo o se è la misura
|
|
double dFactor ;
|
|
if ( m_sCalcText.find( IS_MEASURE) != string::npos) {
|
|
m_sCalcText = "300.00" ;
|
|
double dHalfDist = GetTextHalfDist( m_ptPos) ;
|
|
dFactor = 2.5 * dHalfDist ;
|
|
m_sCalcText = "" ;
|
|
}
|
|
else {
|
|
double 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_ptP6 + dFactor * vtDir_n ;
|
|
// ricalcolo m_vtDir
|
|
m_vtDir = m_ptPos - m_ptP6 ;
|
|
dLenDir = m_vtDir.Len() ;
|
|
}
|
|
// assegno gli altri punti notevoli della quotatura
|
|
m_ptP1 = m_ptP6 ;
|
|
m_ptP2 = m_ptP6 ;
|
|
m_ptP5 = m_ptP6 + vtLine1 * dLenDir ;
|
|
m_ptP3 = m_ptP6 + vtLine1 * ( dLenDir + m_dExtLineLen) ;
|
|
m_ptP4 = m_ptP6 + vtLine2 * ( dLenDir + 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::SetAngularEx( const Point3d& ptV1, const Point3d& ptP1,
|
|
const Point3d& ptV2, const Point3d& ptP2, const Point3d& ptPos,
|
|
const Vector3d& vtN, const string& sText)
|
|
{
|
|
// dichiaro quota non ancora determinata
|
|
m_nType = DT_NONE ;
|
|
// verifico la definizione del versore normale
|
|
m_vtN = vtN ;
|
|
if ( ! m_vtN.Normalize())
|
|
return false ;
|
|
// calcolo l'intersezione tra le due linee
|
|
CurveLine Line1 ;
|
|
if ( ! Line1.Set( ptV1, ptP1) || ! Line1.SetExtrusion( m_vtN))
|
|
return false ;
|
|
CurveLine Line2 ;
|
|
if ( ! Line2.Set( ptV2, ptP2) || ! Line2.SetExtrusion( m_vtN))
|
|
return false ;
|
|
IntersLineLine IntLL( Line1, Line2, false) ;
|
|
IntCrvCrvInfo Info ;
|
|
if ( ! IntLL.GetIntCrvCrvInfo( Info) || Info.bOverlap)
|
|
return false ;
|
|
Point3d ptV = Media( Info.IciA[0].ptI, Info.IciB[0].ptI) ;
|
|
// porto i punti e le direzioni nel piano definito da V1 e N
|
|
m_ptP6 = ptV ;
|
|
m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ;
|
|
m_vtDir = m_ptPos - m_ptP6 ;
|
|
double dLenDir = m_vtDir.Len() ;
|
|
Vector3d vtLine1 = OrthoCompo( ptP1 - m_ptP6, m_vtN) ;
|
|
Vector3d vtLine2 = OrthoCompo( ptP2 - m_ptP6, m_vtN) ;
|
|
// verifico che i punti di misura non siano coincidenti
|
|
if ( ! vtLine1.Normalize() || ! vtLine2.Normalize() || dLenDir < EPS_SMALL)
|
|
return false ;
|
|
|
|
// controllo se è testo o se è la misura
|
|
double dFactor ;
|
|
if ( m_sCalcText.find( IS_MEASURE) != string::npos) {
|
|
m_sCalcText = "300.00" ;
|
|
double dHalfDist = GetTextHalfDist( m_ptPos) ;
|
|
dFactor = 2.5 * dHalfDist ;
|
|
m_sCalcText = "" ;
|
|
}
|
|
else {
|
|
double 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_ptP6 + dFactor * vtDir_n ;
|
|
// ricalcolo m_vtDir
|
|
m_vtDir = m_ptPos - m_ptP6 ;
|
|
dLenDir = m_vtDir.Len() ;
|
|
}
|
|
// assegno gli altri punti notevoli della quotatura
|
|
// se i ptV concidono con l'intersezione tra le linee le sposto leggermente verso l'altro punto di quel lato
|
|
Point3d ptV1New = ptV1 ;
|
|
Point3d ptV2New = ptV2 ;
|
|
if ( AreSamePointApprox( ptV1, ptV)) {
|
|
Vector3d vtDir1 ; Line1.GetStartDir( vtDir1) ;
|
|
double dLen ; Line1.GetLength( dLen) ;
|
|
dLen = max( min( 1., dLen/ 10), 0.01) ;
|
|
ptV1New = ptV1 + vtDir1 * dLen ;
|
|
}
|
|
if ( AreSamePointApprox( ptV2, ptV)) {
|
|
Vector3d vtDir2 ; Line2.GetStartDir( vtDir2) ;
|
|
double dLen ; Line2.GetLength( dLen) ;
|
|
dLen = max( min( 1., dLen/ 10), 0.01) ;
|
|
ptV2New = ptV2 + vtDir2 * dLen ;
|
|
}
|
|
m_ptP1 = ptV1New - ( ptV1New - m_ptP6) * m_vtN * m_vtN ;
|
|
m_ptP2 = ptV2New - ( ptV2New - m_ptP6) * m_vtN * m_vtN ;
|
|
m_ptP5 = m_ptP6 + vtLine1 * dLenDir ;
|
|
double dLen1 = Dist( m_ptP6, m_ptP1) ;
|
|
m_ptP3 = m_ptP6 + vtLine1 * ( dLenDir + m_dExtLineLen * ( dLen1 < dLenDir ? 1 : -1)) ;
|
|
double dLen2 = Dist( m_ptP6, m_ptP2) ;
|
|
m_ptP4 = m_ptP6 + vtLine2 * ( dLenDir + m_dExtLineLen * ( dLen2 < dLenDir ? 1 : -1)) ;
|
|
|
|
// assegnazione del testo
|
|
m_sText = sText ;
|
|
// assegno il tipo
|
|
m_nType = DT_ANGULAR ;
|
|
// imposto da calcolare
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ExtDimension*
|
|
ExtDimension::Clone( void) const
|
|
{
|
|
// alloco oggetto
|
|
ExtDimension* pDim = new( nothrow) ExtDimension ;
|
|
if ( pDim != nullptr) {
|
|
if ( ! pDim->CopyFrom( *this)) {
|
|
delete pDim ;
|
|
return nullptr ;
|
|
}
|
|
}
|
|
|
|
return pDim ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::CopyFrom( const IGeoObj* pGObjSrc)
|
|
{
|
|
const ExtDimension* pDim = GetBasicExtDimension( pGObjSrc) ;
|
|
if ( pDim == nullptr)
|
|
return false ;
|
|
return CopyFrom( *pDim) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::CopyFrom( const ExtDimension& clSrc)
|
|
{
|
|
if ( &clSrc == this)
|
|
return true ;
|
|
m_OGrMgr.Reset() ;
|
|
m_nType = clSrc.m_nType ;
|
|
m_vtN = clSrc.m_vtN ;
|
|
m_vtDir = clSrc.m_vtDir ;
|
|
m_ptP1 = clSrc.m_ptP1 ;
|
|
m_ptP2 = clSrc.m_ptP2 ;
|
|
m_ptP3 = clSrc.m_ptP3 ;
|
|
m_ptP4 = clSrc.m_ptP4 ;
|
|
m_ptP5 = clSrc.m_ptP5 ;
|
|
m_ptP6 = clSrc.m_ptP6 ;
|
|
m_ptPos = clSrc.m_ptPos ;
|
|
m_sText = clSrc.m_sText ;
|
|
m_bToCalc = clSrc.m_bToCalc ;
|
|
m_sCalcText = clSrc.m_sCalcText ;
|
|
m_ptCalcPos = clSrc.m_ptCalcPos ;
|
|
m_bCalcArrowIn = clSrc.m_bCalcArrowIn ;
|
|
m_bCalcTextOn = clSrc.m_bCalcTextOn ;
|
|
m_ptCalcP7 = clSrc.m_ptCalcP7 ;
|
|
m_ptCalcP8 = clSrc.m_ptCalcP8 ;
|
|
m_dExtLineLen = clSrc.m_dExtLineLen ;
|
|
m_dArrowLen = clSrc.m_dArrowLen ;
|
|
m_dTextDist = clSrc.m_dTextDist ;
|
|
m_bLenIsMM = clSrc.m_bLenIsMM ;
|
|
m_nDecDigit = clSrc.m_nDecDigit ;
|
|
m_sFont = clSrc.m_sFont ;
|
|
m_dTextHeight = clSrc.m_dTextHeight ;
|
|
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
|
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
|
m_dTempParam[0] = clSrc.m_dTempParam[0] ;
|
|
m_dTempParam[1] = clSrc.m_dTempParam[1] ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeoObjType
|
|
ExtDimension::GetType( void) const
|
|
{
|
|
return static_cast<GeoObjType>( GEOOBJ_GETTYPE( ExtDimension)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
ExtDimension::GetTitle( void) const
|
|
{
|
|
static const string sTitle = "Dimension" ;
|
|
return sTitle ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
ExtDimension::GetSubType( void) const
|
|
{
|
|
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] ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
|
{
|
|
// parametri
|
|
sOut += GetSubType() + szNewLine ;
|
|
sOut += "VN( " + ToString( m_vtN, 3) + ") " + szNewLine ;
|
|
sOut += "VD( " + ToString( m_vtDir, 3) + ") " + szNewLine ;
|
|
sOut += "P1( " + ToString( GetInUiUnits( m_ptP1, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "P2( " + ToString( GetInUiUnits( m_ptP2, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "P3( " + ToString( GetInUiUnits( m_ptP3, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "P4( " + ToString( GetInUiUnits( m_ptP4, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "P5( " + ToString( GetInUiUnits( m_ptP5, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "P6( " + ToString( GetInUiUnits( m_ptP6, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "Pos( " + ToString( GetInUiUnits( m_ptPos, bMM), 3) + ") " + szNewLine ;
|
|
sOut += "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 ;
|
|
sOut += "Mm=" + string( m_bLenIsMM ? "1" : "0") +
|
|
" Dec=" + ToString( m_nDecDigit) + szNewLine ;
|
|
sOut += "Fnt=" + m_sFont +
|
|
" H=" + ToString( GetInUiUnits( m_dTextHeight, bMM), 3) + szNewLine ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExtDimension::GetNgeId( void) const
|
|
{
|
|
return GEOOBJ_GETNGEID( ExtDimension) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Save( NgeWriter& ngeOut) const
|
|
{
|
|
// tipo
|
|
if ( ! ngeOut.WriteInt( m_nType, ";", true))
|
|
return false ;
|
|
// versori normale e direzione
|
|
if ( ! ngeOut.WriteVector( m_vtN, ";"))
|
|
return false ;
|
|
if ( ! ngeOut.WriteVector( m_vtDir, ";", true))
|
|
return false ;
|
|
// punti di quotatura
|
|
if ( ! ngeOut.WritePoint( m_ptP1, ";"))
|
|
return false ;
|
|
if ( ! ngeOut.WritePoint( m_ptP2, ";"))
|
|
return false ;
|
|
if ( ! ngeOut.WritePoint( m_ptP3, ";"))
|
|
return false ;
|
|
if ( ! ngeOut.WritePoint( m_ptP4, ";", true))
|
|
return false ;
|
|
if ( ! ngeOut.WritePoint( m_ptP5, ";"))
|
|
return false ;
|
|
if ( ! ngeOut.WritePoint( m_ptP6, ";"))
|
|
return false ;
|
|
if ( ! ngeOut.WritePoint( m_ptPos, ";", true))
|
|
return false ;
|
|
// testo
|
|
if ( ! ngeOut.WriteString( m_sText, ";", true))
|
|
return false ;
|
|
// attributi
|
|
if ( ! ngeOut.WriteDouble( m_dExtLineLen, ","))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_dArrowLen, ","))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_dTextDist, ","))
|
|
return false ;
|
|
if ( ! ngeOut.WriteBool( m_bLenIsMM, ","))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_nDecDigit, ","))
|
|
return false ;
|
|
if ( ! ngeOut.WriteString( m_sFont, ","))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_dTextHeight, ";", true))
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Load( NgeReader& ngeIn)
|
|
{
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
// leggo la prossima linea : tipo
|
|
if ( ! ngeIn.ReadInt( m_nType, ";", true))
|
|
return false ;
|
|
// leggo la prossima linea : versori normale e direzione
|
|
if ( ! ngeIn.ReadVector( m_vtN, ";"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadVector( m_vtDir, ";", true))
|
|
return false ;
|
|
// leggo la prossima linea : punti di quotatura
|
|
if ( ! ngeIn.ReadPoint( m_ptP1, ";"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadPoint( m_ptP2, ";"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadPoint( m_ptP3, ";"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadPoint( m_ptP4, ";", true))
|
|
return false ;
|
|
if ( ! ngeIn.ReadPoint( m_ptP5, ";"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadPoint( m_ptP6, ";"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadPoint( m_ptPos, ";", true))
|
|
return false ;
|
|
// leggo la prossima linea : testo
|
|
if ( ! ngeIn.ReadString( m_sText, ";", true))
|
|
return false ;
|
|
// leggo la prossima linea : attributi
|
|
if ( ! ngeIn.ReadDouble( m_dExtLineLen, ","))
|
|
return false ;
|
|
if ( ! ngeIn.ReadDouble( m_dArrowLen, ","))
|
|
return false ;
|
|
if ( ! ngeIn.ReadDouble( m_dTextDist, ","))
|
|
return false ;
|
|
if ( ! ngeIn.ReadBool( m_bLenIsMM, ","))
|
|
return false ;
|
|
if ( ! ngeIn.ReadInt( m_nDecDigit, ","))
|
|
return false ;
|
|
if ( ! ngeIn.ReadString( m_sFont, ","))
|
|
return false ;
|
|
if ( ! ngeIn.ReadDouble( m_dTextHeight, ";", true))
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
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 if ( m_nType == DT_RADIAL) {
|
|
b3Loc.Set( m_ptP6) ;
|
|
b3Loc.Add( m_ptPos) ;
|
|
// ingombro del testo
|
|
BBox3d b3Text ;
|
|
if ( GetTextLocalBBox( b3Text))
|
|
b3Loc.Add( b3Text) ;
|
|
return true ;
|
|
}
|
|
else if ( m_nType == DT_DIAMETRAL) {
|
|
b3Loc.Set( m_ptP6) ;
|
|
b3Loc.Add( m_ptPos) ;
|
|
// ingombro del testo
|
|
BBox3d b3Text ;
|
|
if ( GetTextLocalBBox( b3Text))
|
|
b3Loc.Add( b3Text) ;
|
|
return true ;
|
|
}
|
|
else if ( m_nType == DT_ANGULAR) {
|
|
b3Loc.Add( m_ptP1) ;
|
|
b3Loc.Add( m_ptP2) ;
|
|
b3Loc.Add( m_ptP3) ;
|
|
b3Loc.Add( m_ptP4) ;
|
|
b3Loc.Set( m_ptP5) ;
|
|
b3Loc.Set( m_ptP6) ;
|
|
b3Loc.Add( m_ptCalcP7) ;
|
|
b3Loc.Add( m_ptCalcP8) ;
|
|
// ingombro del testo
|
|
BBox3d b3Text ;
|
|
if ( GetTextLocalBBox( b3Text))
|
|
b3Loc.Add( b3Text) ;
|
|
return true ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
|
{
|
|
// verifico validità del frame
|
|
if ( frRef.GetType() == Frame3d::ERR)
|
|
return false ;
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
// se valido
|
|
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 if ( m_nType == DT_RADIAL) {
|
|
// ingombro dei punti ( portati nel riferimento passato)
|
|
Point3d ptFrP5 = m_ptP6 ;
|
|
ptFrP5.ToGlob( frRef) ;
|
|
b3Ref.Set( ptFrP5) ;
|
|
Point3d ptFrPos = m_ptPos ;
|
|
ptFrPos.ToGlob( frRef) ;
|
|
b3Ref.Set( ptFrPos) ;
|
|
// ingombro del testo
|
|
BBox3d b3Text ;
|
|
if ( GetTextBBox( frRef, b3Text))
|
|
b3Ref.Add( b3Text) ;
|
|
return true ;
|
|
}
|
|
else if ( m_nType == DT_DIAMETRAL) {
|
|
// ingombro dei punti ( portati nel riferimento passato)
|
|
Point3d ptFrP5 = m_ptP6 ;
|
|
ptFrP5.ToGlob( frRef) ;
|
|
b3Ref.Set( ptFrP5) ;
|
|
Point3d ptFrPos = m_ptPos ;
|
|
ptFrPos.ToGlob( frRef) ;
|
|
b3Ref.Set( ptFrPos) ;
|
|
// ingombro del testo
|
|
BBox3d b3Text ;
|
|
if ( GetTextBBox( frRef, b3Text))
|
|
b3Ref.Add( b3Text) ;
|
|
return true ;
|
|
}
|
|
else if ( m_nType == DT_ANGULAR) {
|
|
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 ptFrP5 = m_ptP5 ;
|
|
ptFrP5.ToGlob( frRef) ;
|
|
b3Ref.Set( ptFrP5) ;
|
|
Point3d ptFrP6 = m_ptP6 ;
|
|
ptFrP6.ToGlob( frRef) ;
|
|
b3Ref.Set( ptFrP6) ;
|
|
Point3d ptFrP7 = m_ptCalcP7 ;
|
|
ptFrP7.ToGlob( frRef) ;
|
|
b3Ref.Add( ptFrP7) ;
|
|
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 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Translate( const Vector3d& vtMove)
|
|
{
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// se valido
|
|
if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) {
|
|
m_ptP1.Translate( vtMove) ;
|
|
m_ptP2.Translate( vtMove) ;
|
|
m_ptP3.Translate( vtMove) ;
|
|
m_ptP4.Translate( vtMove) ;
|
|
m_ptP5.Translate( vtMove) ;
|
|
m_ptP6.Translate( vtMove) ;
|
|
m_ptPos.Translate( vtMove) ;
|
|
return true ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
// verifico validità dell'asse di rotazione
|
|
if ( vtAx.IsSmall())
|
|
return false ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// se valido
|
|
if ( m_nType >= DT_LINEAR && m_nType <= DT_ANGULAR) {
|
|
return ( m_vtN.Rotate( vtAx, dCosAng, dSinAng) &&
|
|
m_vtDir.Rotate( vtAx, dCosAng, dSinAng) &&
|
|
m_ptP1.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
|
m_ptP2.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
|
m_ptP3.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
|
m_ptP4.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
|
m_ptP5.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
|
m_ptP6.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
|
m_ptPos.Rotate( ptAx, vtAx, dCosAng, dSinAng)) ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
// verifico non sia nulla
|
|
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
|
|
return false ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// 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())
|
|
return false ;
|
|
if ( ! m_vtDir.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) || ! m_vtDir.Normalize())
|
|
return false ;
|
|
m_vtN = m_vtDir ^ vtTmp ;
|
|
if ( ! m_vtN.Normalize())
|
|
return false ;
|
|
// scalo i punti di base
|
|
if ( ! m_ptP1.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
if ( ! m_ptP2.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
if ( ! m_ptP6.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
if ( ! m_ptPos.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
// ricalcolo completamente la quota
|
|
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_ptP6, m_ptPos, m_vtN, m_sText) ;
|
|
case DT_DIAMETRAL :
|
|
return SetDiametral( m_ptP6, m_ptPos, m_vtN, m_sText) ;
|
|
case DT_ANGULAR :
|
|
return SetAngular( m_ptP1, m_ptP6, m_ptP2, m_ptPos, m_vtN, m_sText) ;
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
// verifico validità del piano di specchiatura
|
|
if ( vtNorm.IsSmall())
|
|
return false ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// 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
|
|
if ( ! m_ptP1.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( ! m_ptP2.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( ! m_ptP3.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( ! m_ptP4.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( ! m_ptP5.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( ! m_ptP6.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( ! m_ptPos.Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
|
{
|
|
// verifico validità dei parametri
|
|
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
|
return false ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// 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())
|
|
return false ;
|
|
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_ptP1.Shear( ptOn, vtNorm, vtDir, dCoeff))
|
|
return false ;
|
|
if ( ! m_ptP2.Shear( ptOn, vtNorm, vtDir, dCoeff))
|
|
return false ;
|
|
if ( ! m_ptP6.Shear( ptOn, vtNorm, vtDir, dCoeff))
|
|
return false ;
|
|
if ( ! m_ptPos.Shear( ptOn, vtNorm, vtDir, dCoeff))
|
|
return false ;
|
|
// ricalcolo completamente la quota
|
|
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_ptP6, m_ptPos, m_vtN, m_sText) ;
|
|
case DT_DIAMETRAL :
|
|
return SetDiametral( m_ptP6, m_ptPos, m_vtN, m_sText) ;
|
|
case DT_ANGULAR :
|
|
return SetAngular( m_ptP1, m_ptP6, m_ptP2, m_ptPos, m_vtN, m_sText) ;
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::ToGlob( const Frame3d& frRef)
|
|
{
|
|
// verifico validità del frame
|
|
if ( frRef.GetType() == Frame3d::ERR)
|
|
return false ;
|
|
|
|
// se frame identità, non devo fare alcunché
|
|
if ( IsGlobFrame( frRef))
|
|
return true ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// 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_ptP1.ToGlob( frRef) &&
|
|
m_ptP2.ToGlob( frRef) &&
|
|
m_ptP3.ToGlob( frRef) &&
|
|
m_ptP4.ToGlob( frRef) &&
|
|
m_ptP5.ToGlob( frRef) &&
|
|
m_ptP6.ToGlob( frRef) &&
|
|
m_ptPos.ToGlob( frRef)) ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::ToLoc( const Frame3d& frRef)
|
|
{
|
|
// verifico validità del frame
|
|
if ( frRef.GetType() == Frame3d::ERR)
|
|
return false ;
|
|
|
|
// se frame identità, non devo fare alcunché
|
|
if ( IsGlobFrame( frRef))
|
|
return true ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// 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_ptP1.ToLoc( frRef) &&
|
|
m_ptP2.ToLoc( frRef) &&
|
|
m_ptP3.ToLoc( frRef) &&
|
|
m_ptP4.ToLoc( frRef) &&
|
|
m_ptP5.ToLoc( frRef) &&
|
|
m_ptP6.ToLoc( frRef) &&
|
|
m_ptPos.ToLoc( frRef)) ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|
{
|
|
// verifico validità dei frame
|
|
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
|
return false ;
|
|
|
|
// se i due riferimenti coincidono, non devo fare alcunché
|
|
if ( AreSameFrame( frOri, frDest))
|
|
return true ;
|
|
|
|
// imposto ricalcolo
|
|
m_bToCalc = true ;
|
|
m_OGrMgr.Reset() ;
|
|
|
|
// 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_ptP1.ToGlob( frOri) && m_ptP1.ToLoc( frDest) &&
|
|
m_ptP2.ToGlob( frOri) && m_ptP2.ToLoc( frDest) &&
|
|
m_ptP3.ToGlob( frOri) && m_ptP3.ToLoc( frDest) &&
|
|
m_ptP4.ToGlob( frOri) && m_ptP4.ToLoc( frDest) &&
|
|
m_ptP5.ToGlob( frOri) && m_ptP5.ToLoc( frDest) &&
|
|
m_ptP6.ToGlob( frOri) && m_ptP6.ToLoc( frDest) &&
|
|
m_ptPos.ToGlob( frOri) && m_ptPos.ToLoc( frDest)) ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::Update( void) const
|
|
{
|
|
// se ricalcolo non richiesto, esco
|
|
if ( ! m_bToCalc)
|
|
return true ;
|
|
|
|
// a seconda del tipo, ...
|
|
switch ( m_nType) {
|
|
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 ;
|
|
}
|
|
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 = reinterpret_cast<const char *>( u8"\u00D8") + sVal ;
|
|
ReplaceString( m_sCalcText, IS_MEASURE, sVal) ;
|
|
}
|
|
// punto di inserimento del testo
|
|
m_ptCalcPos = ( m_ptP5 + m_ptP2) / 2 ;
|
|
// alzo il testo dalla linea di misura
|
|
BBox3d b3Text ;
|
|
if ( ! GetTextMyBBox( b3Text) && ! b3Text.IsEmpty())
|
|
return false ;
|
|
double dHeight = b3Text.GetMax().y - b3Text.GetMin().y ;
|
|
double dLength = b3Text.GetMax().x - b3Text.GetMin().x ;
|
|
Vector3d vtPerpDir = m_ptPos - m_ptP6 ;
|
|
if ( ! vtPerpDir.Normalize())
|
|
return false ;
|
|
// calcolo il frame dell'arco per valutare la posizione del testo
|
|
Frame3d frRef ;
|
|
if ( ! frRef.Set( m_ptP6, m_vtN))
|
|
return false ;
|
|
double dAngDeg = 0 ;
|
|
if ( ! m_vtDir.GetAngle( frRef.VersX(), dAngDeg) || ! vtPerpDir.Rotate( m_vtN, ( dAngDeg < 90 ? 90 : -90)))
|
|
return false ;
|
|
m_ptCalcPos = m_ptCalcPos + 0.6 * dHeight * vtPerpDir ;
|
|
// semidistanza di interruzione
|
|
double dHalfDist = GetTextHalfDist( m_ptCalcPos, false) ;
|
|
// lunghezza della linea di misura
|
|
double dLen = Dist( m_ptP1, m_ptP2) ;
|
|
// determino come orientare le frecce e dove mettere il testo
|
|
if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) {
|
|
m_bCalcArrowIn = true ;
|
|
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_ptP2 + 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_ptP5 ;
|
|
if ( ! vtRad.Normalize())
|
|
return false ;
|
|
m_ptCalcPos = m_ptPos + vtRad * ( 2 * m_dArrowLen + m_dTextDist) ;
|
|
const double COMP_LIM = 0.1 ; // circa 5.7deg
|
|
if ( vtRad.x > COMP_LIM)
|
|
m_ptCalcPos += dLength / 2 * X_AX ;
|
|
else if ( vtRad.x < -COMP_LIM)
|
|
m_ptCalcPos -= dLength / 2 * X_AX ;
|
|
if ( vtRad.y > COMP_LIM)
|
|
m_ptCalcPos += dHeight / 2 * Y_AX ;
|
|
else if ( vtRad.y < -COMP_LIM)
|
|
m_ptCalcPos -= dHeight / 2 * Y_AX ;
|
|
}
|
|
// dichiaro ricalcolo eseguito
|
|
m_bToCalc = false ;
|
|
return true ;
|
|
}
|
|
case DT_ANGULAR : {
|
|
// angolo
|
|
double dAngDeg, dAngDeg1, dAngDeg2 = 0 ;
|
|
Vector3d vtLine1 = m_ptP3 - m_ptP6 ;
|
|
Vector3d vtLine2 = m_ptP4 - m_ptP6 ;
|
|
Vector3d vtLine3 = m_ptPos - m_ptP6 ;
|
|
// calcolo gli angoli tra m_ptPos e i due punti che identificano i lati dell'angolo
|
|
// per capire se sto calcolando l'angolo interno o esterno
|
|
if ( ! vtLine1.GetAngle( vtLine2, dAngDeg) || ! vtLine1.GetAngle( vtLine3, dAngDeg1) || ! vtLine2.GetAngle( vtLine3, dAngDeg2))
|
|
return false ;
|
|
if ( dAngDeg < dAngDeg1 + dAngDeg2 - EPS_SMALL || dAngDeg > dAngDeg1 + dAngDeg2 + EPS_SMALL)
|
|
dAngDeg = 360 - dAngDeg ;
|
|
// testo
|
|
m_sCalcText = m_sText ;
|
|
if ( m_sCalcText.find( IS_MEASURE) != string::npos) {
|
|
string sAngDeg = ToString( dAngDeg, m_nDecDigit) ;
|
|
ReplaceString( m_sCalcText, IS_MEASURE, sAngDeg + "°") ;
|
|
}
|
|
// calcolo ptP5_bis
|
|
if ( ! vtLine2.Normalize())
|
|
return false ;
|
|
Point3d ptP5_bis = m_ptP6 + m_vtDir.Len() * vtLine2 ;
|
|
// calcolo l'arco su cui metterò la misura
|
|
PtrOwner<CurveArc> pCrvPos( CreateBasicCurveArc()) ;
|
|
if ( IsNull( pCrvPos) || ! pCrvPos->Set3P( ptP5_bis, 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 dDist = Dist( m_ptCalcPos, m_ptP6) ;
|
|
double dLenPos = dDist * dAngDeg * DEGTORAD ;
|
|
// determino come orientare le frecce e dove mettere il testo
|
|
// frecce e testo dentro
|
|
if ( dLen - 2 * m_dArrowLen >= 2 * dHalfDist) {
|
|
m_bCalcArrowIn = true ;
|
|
m_bCalcTextOn = true ;
|
|
double dU ;
|
|
pCrvPos->GetParamAtLength( dLen / 2. + dHalfDist, dU) ;
|
|
pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP7) ;
|
|
pCrvPos->GetParamAtLength( dLen / 2. - dHalfDist, dU) ;
|
|
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 ;
|
|
double dU ;
|
|
pCrvPos->GetParamAtLength( dLen / 2. + dHalfDist, dU) ;
|
|
pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP7) ;
|
|
pCrvPos->GetParamAtLength( dLen / 2. - dHalfDist, dU) ;
|
|
pCrvPos->GetPointD1D2( dU, ICurve::FROM_MINUS, m_ptCalcP8) ;
|
|
if ( dLen < 2 * dHalfDist) {
|
|
m_ptCalcPos += ( m_ptCalcPos - m_ptP5) ;
|
|
m_bCalcTextOn = false ;
|
|
}
|
|
}
|
|
// stanno fuori sia le frecce sia il testo
|
|
else {
|
|
m_bCalcArrowIn = false ;
|
|
m_bCalcTextOn = false ;
|
|
vtLine1.Normalize() ;
|
|
vtLine2.Normalize() ;
|
|
if ( Dist( m_ptPos, m_ptP5) < Dist( m_ptPos, ptP5_bis)) {
|
|
Vector3d vtDirEnd ;
|
|
pCrvPos->GetEndDir( vtDirEnd) ;
|
|
m_ptCalcPos = m_ptP5 + dHalfDist * ( vtDirEnd + vtLine1) ;
|
|
}
|
|
else {
|
|
Vector3d vtDirStart ;
|
|
pCrvPos->GetStartDir( vtDirStart) ;
|
|
m_ptCalcPos = ptP5_bis + dHalfDist * ( - vtDirStart + vtLine2) ;
|
|
}
|
|
}
|
|
// dichiaro ricalcolo eseguito
|
|
m_bToCalc = false ;
|
|
return true ;
|
|
}
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetMidPoint( Point3d& ptMid) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
switch ( m_nType) {
|
|
case DT_LINEAR :
|
|
case DT_RADIAL :
|
|
case DT_DIAMETRAL:
|
|
ptMid = ( m_ptP1 + m_ptP2) / 2;
|
|
return true ;
|
|
case DT_ANGULAR :
|
|
{ // calcolo ptP5_bis
|
|
Vector3d vtLine2 = m_ptP2 - m_ptP6 ;
|
|
double dLen2 = vtLine2.Len() ;
|
|
if ( ! vtLine2.Normalize())
|
|
return false ;
|
|
Point3d ptP5_bis = m_ptP2 + ( m_vtDir.Len() - dLen2) * vtLine2 ;
|
|
Vector3d vtMid = ( ptP5_bis + m_ptP5) / 2 - m_ptP6 ;
|
|
if ( ! vtMid.Normalize())
|
|
return false ;
|
|
ptMid = m_ptP6 + vtMid * m_vtDir.Len() ;
|
|
return true;
|
|
}
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetCenterPoint( Point3d& ptCen) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
// 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_ptP6 ;
|
|
return true ;
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
// se quota valida
|
|
switch ( m_nType) {
|
|
case DT_LINEAR : {
|
|
// prima linea di riferimento
|
|
lstPL.emplace_back() ;
|
|
lstPL.back().AddUPoint( 0, m_ptP1) ;
|
|
lstPL.back().AddUPoint( 1, m_ptP3) ;
|
|
// seconda linea di riferimento
|
|
lstPL.emplace_back() ;
|
|
lstPL.back().AddUPoint( 0, m_ptP2) ;
|
|
lstPL.back().AddUPoint( 1, m_ptP4) ;
|
|
// se non c'è testo, linea di misura intera
|
|
if ( IsEmptyOrSpaces( m_sCalcText)) {
|
|
lstPL.emplace_back() ;
|
|
lstPL.back().AddUPoint( 0, m_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 ;
|
|
}
|
|
case DT_RADIAL :
|
|
case DT_DIAMETRAL : {
|
|
// prima linea di riferimento
|
|
lstPL.emplace_back() ;
|
|
lstPL.back().AddUPoint( 0, m_ptP1) ;
|
|
lstPL.back().AddUPoint( 1, m_ptP2) ;
|
|
// freccia
|
|
lstPL.emplace_back() ;
|
|
Vector3d vtRad = m_ptPos - m_ptP6 ;
|
|
vtRad.Normalize() ;
|
|
GetArrowHead( m_ptP2, ( m_bCalcArrowIn ? vtRad : - vtRad), lstPL.back()) ;
|
|
if ( ! m_bCalcArrowIn) {
|
|
lstPL.emplace_back() ;
|
|
Point3d ptArrowTail = m_ptP2 + vtRad * m_dArrowLen * 2 ;
|
|
lstPL.back().AddUPoint( 0, m_ptP2) ;
|
|
lstPL.back().AddUPoint( 1, ptArrowTail) ;
|
|
}
|
|
if ( m_nType == DT_DIAMETRAL) {
|
|
lstPL.emplace_back() ;
|
|
GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? - vtRad : vtRad), lstPL.back()) ;
|
|
if ( ! m_bCalcArrowIn) {
|
|
lstPL.emplace_back() ;
|
|
Point3d 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 : {
|
|
// 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<CurveArc> pCrvPos( CreateBasicCurveArc()) ;
|
|
if ( IsNull( pCrvPos))
|
|
return false ;
|
|
// calcolo ptP5_bis
|
|
Vector3d vtLine2 = m_ptP4 - m_ptP6 ;
|
|
if ( ! vtLine2.Normalize())
|
|
return false ;
|
|
Point3d ptP5_bis = m_ptP6 + m_vtDir.Len() * vtLine2 ;
|
|
// approssimerò l'arco con una polyline
|
|
PolyLine plApprox ;
|
|
// se non ho testo
|
|
if ( IsEmptyOrSpaces( m_sCalcText) || ! m_bCalcTextOn) {
|
|
if ( ! pCrvPos->SetC2PN( m_ptP6, ptP5_bis, m_ptP5, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox))
|
|
return false ;
|
|
lstPL.emplace_back( plApprox) ;
|
|
}
|
|
// altrimenti, linea di misura divisa in due parti
|
|
else {
|
|
// prima parte
|
|
if ( ! pCrvPos->SetC2PN( m_ptP6, m_ptP5, m_ptCalcP7, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox))
|
|
return false ;
|
|
lstPL.emplace_back( plApprox) ;
|
|
// seconda parte
|
|
if ( ! pCrvPos->SetC2PN( m_ptP6, ptP5_bis, m_ptCalcP8, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox))
|
|
return false ;
|
|
lstPL.emplace_back( plApprox) ;
|
|
}
|
|
// frecce
|
|
if ( ! pCrvPos->Set3P( ptP5_bis, m_ptPos, m_ptP5, false))
|
|
return false ;
|
|
Vector3d vtStartDir ;
|
|
Vector3d vtEndDir ;
|
|
pCrvPos->GetStartDir( vtStartDir) ;
|
|
pCrvPos->GetEndDir( vtEndDir) ;
|
|
//storto la punta delle frecce su una direzione mediata tra l'arco e la perpendicolare al lato
|
|
double dFactor = 1 / ( 0.6 * m_vtDir.Len()) ;// questo fattore dipende direttamente dalla distanza di m_ptPos dal centro e smorza lo scostamento
|
|
// se però le frecce sono fuori non le storto e faccio le code dritte anziché curvilinee
|
|
if ( ! m_bCalcArrowIn) {
|
|
Point3d ptArrowTail1, ptArrowTail2 ;
|
|
ptArrowTail1 = m_ptP5 + vtEndDir * m_dArrowLen *2 ;
|
|
lstPL.emplace_back() ;
|
|
lstPL.back().AddUPoint( 0, m_ptP5) ;
|
|
lstPL.back().AddUPoint( 1, ptArrowTail1) ;
|
|
ptArrowTail2 = ptP5_bis - vtStartDir * m_dArrowLen *2 ;
|
|
lstPL.emplace_back() ;
|
|
lstPL.back().AddUPoint( 0, ptP5_bis) ;
|
|
lstPL.back().AddUPoint( 1, ptArrowTail2) ;
|
|
dFactor = 0 ;
|
|
}
|
|
lstPL.emplace_back() ;
|
|
Vector3d vtLine1 = m_ptP3 - m_ptP6 ;
|
|
if ( ! vtLine1.Normalize())
|
|
return false ;
|
|
GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? vtEndDir : - vtEndDir) + vtLine1 * dFactor, lstPL.back()) ;
|
|
lstPL.emplace_back() ;
|
|
GetArrowHead( ptP5_bis, ( m_bCalcArrowIn ? - vtStartDir : vtStartDir) + vtLine2 * dFactor, lstPL.back()) ;
|
|
// testo
|
|
POLYLINELIST lstTxt ;
|
|
if ( ApproxTextWithLines( dLinTol, dAngTolDeg, lstTxt))
|
|
lstPL.splice( lstPL.end(), lstTxt) ;
|
|
return true ;
|
|
}
|
|
default:
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
ExtDimension::GetTextHalfDist( const Point3d& ptText, bool bUseRot) const
|
|
{
|
|
// semi distanza di interruzione
|
|
double dHalfDist = m_dTextHeight / 2 + m_dTextDist ;
|
|
// recupero il box di ingombro del testo
|
|
BBox3d b3Text ;
|
|
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 ( bUseRot) {
|
|
Vector3d vtDir = m_vtDir ;
|
|
vtDir.Normalize() ;
|
|
double dCoeff = ( dHalfH > 1 ? dHalfL / dHalfH : 0) ;
|
|
if ( abs( vtDir.x) > dCoeff * abs( vtDir.y))
|
|
dHalfDist = min( dHalfDist, dHalfL / abs( vtDir.x)) ;
|
|
else
|
|
dHalfDist = min( dHalfDist, dHalfH / abs( vtDir.y)) ;
|
|
}
|
|
dHalfDist += m_dTextDist ;
|
|
}
|
|
return dHalfDist ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLine& PL) const
|
|
{
|
|
Vector3d vtPerp = vtDir ^ m_vtN ;
|
|
if ( ! vtPerp.Normalize())
|
|
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( 4, ptTip) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::SetCurrFont( FontManager& fntMgr) const
|
|
{
|
|
static const int FONT_WEIGHT = 400 ;
|
|
static const bool FONT_ITALIC = false ;
|
|
static const double FONT_RATIO = 0.75 ;
|
|
static const double FONT_ADDADVANCE = 0 ;
|
|
|
|
return fntMgr.SetCurrFont( m_sFont, FONT_WEIGHT, FONT_ITALIC, m_dTextHeight, FONT_RATIO, FONT_ADDADVANCE) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
|
|
// se testo vuoto, risultato vuoto
|
|
if ( IsEmptyOrSpaces( m_sCalcText))
|
|
return true ;
|
|
|
|
// imposto il font corrente e i suoi dati
|
|
FontManager& fntMgr = FontManager::GetFontManager() ;
|
|
if ( ! SetCurrFont( fntMgr))
|
|
return false ;
|
|
|
|
// richiedo l'outline
|
|
if ( ! fntMgr.ApproxWithLines( m_sCalcText, ETXT_IPMC, dLinTol, dAngTolDeg, lstPL))
|
|
return false ;
|
|
|
|
// calcolo la trasformazione
|
|
Frame3d frRef ;
|
|
if ( ! frRef.Set( m_ptCalcPos, m_vtN))
|
|
return false ;
|
|
// oriento il testo con il raggio/diametro, ma solo se il testo è dentro la circonferenza
|
|
if ( ( m_nType == DT_RADIAL || m_nType == DT_DIAMETRAL) && m_bCalcTextOn) {
|
|
double dAngDeg = 0 ;
|
|
m_vtDir.GetAngle( frRef.VersX(), dAngDeg) ;
|
|
if ( ! frRef.Set( m_ptCalcPos, m_vtN, ( dAngDeg > 90 ? - m_vtDir : m_vtDir)))
|
|
return false ;
|
|
}
|
|
|
|
// eseguo la trasformazione
|
|
for ( auto& PL : lstPL)
|
|
PL.ToGlob( frRef) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetTextMyBBox( BBox3d& b3Loc) const
|
|
{
|
|
// imposto box vuoto
|
|
b3Loc.Reset() ;
|
|
|
|
// se testo vuoto, box vuoto
|
|
if ( IsEmptyOrSpaces( m_sCalcText))
|
|
return true ;
|
|
|
|
// imposto il font corrente e i suoi dati
|
|
FontManager& fntMgr = FontManager::GetFontManager() ;
|
|
if ( ! SetCurrFont( fntMgr))
|
|
return false ;
|
|
|
|
// richiedo il box
|
|
if ( ! fntMgr.GetBBox( m_sCalcText, ETXT_IPMC, b3Loc))
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetTextMyBBox( const Point3d& ptPos, BBox3d& b3Loc) const
|
|
{
|
|
// determino il box del testo
|
|
if ( ! GetTextMyBBox( b3Loc))
|
|
return false ;
|
|
|
|
// calcolo ed eseguo la trasformazione
|
|
Frame3d frRef ;
|
|
if ( ! frRef.Set( ptPos, m_vtN))
|
|
return false ;
|
|
b3Loc.ToGlob( frRef) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetTextLocalBBox( BBox3d& b3Loc) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
|
|
// calcolo il box
|
|
return GetTextMyBBox( m_ptCalcPos, b3Loc) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExtDimension::GetTextBBox( const Frame3d& frRef, BBox3d& b3Ref) const
|
|
{
|
|
// eventuale ricalcolo
|
|
Update() ;
|
|
|
|
// calcolo il box
|
|
if ( ! GetTextMyBBox( m_ptCalcPos, b3Ref))
|
|
return false ;
|
|
|
|
// porto il box nel riferimento passato
|
|
b3Ref.ToGlob( frRef) ;
|
|
|
|
return true ;
|
|
}
|