Files
EgtGeomKernel/ExtDimension.cpp
T
2021-07-21 12:50:58 +02:00

927 lines
30 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 "GeoObjFactory.h"
#include "NgeWriter.h"
#include "NgeReader.h"
#include "FontManager.h"
#include "FontAux.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkUiUnits.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include <new>
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_nTempProp[1] = 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 ;
}
//----------------------------------------------------------------------------
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 = dynamic_cast<const ExtDimension*>( 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_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] ;
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() ;
// 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 ;
}
//----------------------------------------------------------------------------
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 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 ;
}
//----------------------------------------------------------------------------
bool
ExtDimension::Translate( const Vector3d& vtMove)
{
// imposto ricalcolo
m_bToCalc = true ;
m_OGrMgr.Reset() ;
// se lineare
if ( m_nType == DT_LINEAR) {
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)
{
// imposto ricalcolo
m_bToCalc = true ;
m_OGrMgr.Reset() ;
// se lineare
if ( m_nType == DT_LINEAR) {
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 lineare
if ( m_nType == DT_LINEAR) {
// 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_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) ;
}
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 lineare
if ( m_nType == DT_LINEAR) {
// 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 lineare
if ( m_nType == DT_LINEAR) {
// 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_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) ;
}
else
return false ;
}
//----------------------------------------------------------------------------
bool
ExtDimension::ToGlob( const Frame3d& frRef)
{
// verifico validità del frame
if ( frRef.GetType() == Frame3d::ERR)
return false ;
// 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) &&
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 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.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 lineare
if ( m_nType == DT_LINEAR) {
// 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 ;
// 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) ;
}
// 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 ;
}
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 ;
}
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 ;
}
// dichiaro ricalcolo eseguito
m_bToCalc = false ;
return true ;
}
else
return false ;
}
//----------------------------------------------------------------------------
bool
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 ;
}
//----------------------------------------------------------------------------
bool
ExtDimension::GetCenterPoint( Point3d& ptCen) const
{
// eventuale ricalcolo
Update() ;
// se quota lineare
if ( m_nType == DT_LINEAR) {
ptCen = ( m_ptP5 + m_ptP6) / 2 ;
return true ;
}
else
return false ;
}
//----------------------------------------------------------------------------
bool
ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const
{
// 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)) {
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 ;
}
//----------------------------------------------------------------------------
double
ExtDimension::GetTextHalfDist( const Point3d& ptText) 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)) {
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)) ;
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 ;
// eseguo la trasformazione
for ( auto& PL : lstPL)
PL.ToGlob( frRef) ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExtDimension::GetTextMyBBox( const Point3d& ptPos, 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 ;
// 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 ;
}