EgtGeomKernel :

- a ExtText aggiunta GetAuxSurf (solo per font di sistema)
- molto migliorata gestione anelli e spikes nella creazione di regioni.
This commit is contained in:
Dario Sassi
2020-06-02 10:12:47 +00:00
parent e8796dac88
commit e6d64e2c60
9 changed files with 239 additions and 27 deletions
+28 -16
View File
@@ -57,11 +57,8 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
// Calcolo le auto intersezioni
SelfIntersCurve sintC( *pMyCrv) ;
// se ci sono auto-intersezioni che si attraversano (anche con sovrapposizione), errore
if ( sintC.GetCrossIntersCount() > 0)
return false ;
// se non ci sono auto-intersezioni che si toccano (anche con sovrapposizione), non devo fare alcunché
if ( sintC.GetTouchIntersCount() == 0) {
// se non ci sono auto-intersezioni che si attraversano o che si toccano (anche con sovrapposizione), non devo fare alcunché
if ( sintC.GetCrossIntersCount() == 0 && sintC.GetTouchIntersCount() == 0) {
// riporto la curva nel riferimento originale
if ( bNeedRef)
pMyCrv->ToGlob( frExtr) ;
@@ -77,25 +74,40 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
Intervals inOk( EPS_PARAM) ;
inOk.Set( dStart, dEnd) ;
// Tolgo le parti in sovrapposizione da eliminare
// Tolgo le parti da eliminare
IntCrvCrvInfo iccInfo ;
for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) {
// se sovrapposti
// se con sovrapposizione
if ( iccInfo.bOverlap) {
// se equiversi, elimino solo uno dei due tratti
if ( iccInfo.bCBOverEq) {
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
}
// se altrimenti controversi, elimino entrambi i tratti
else if ( ! iccInfo.bCBOverEq) {
// se solo touch
if ( ( iccInfo.IciA[0].nPrevTy == iccInfo.IciA[1].nNextTy ||
iccInfo.IciA[0].nPrevTy == ICCT_SPK || iccInfo.IciA[1].nNextTy == ICCT_SPK) &&
iccInfo.IciA[0].nPrevTy != ICCT_NULL && iccInfo.IciA[1].nNextTy != ICCT_NULL) {
// obbligatoriamente controversi, elimino entrambi i tratti
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ;
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
}
// altrimenti attraversamento
else {
// elimino la parte interna
if ( iccInfo.bCBOverEq)
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciB[0].dU) ;
else
inOk.Subtract( min( iccInfo.IciA[0].dU, iccInfo.IciB[1].dU), max( iccInfo.IciB[0].dU, iccInfo.IciA[1].dU)) ;
}
}
// altrimenti sono touch
// altrimenti
else {
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[0].dU) ;
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[0].dU) ;
// se solo touch
if ( iccInfo.IciA[0].nPrevTy == iccInfo.IciA[0].nNextTy &&
iccInfo.IciA[0].nPrevTy != ICCT_NULL && iccInfo.IciA[0].nNextTy != ICCT_NULL) {
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[0].dU) ;
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[0].dU) ;
}
// altrimenti attraversamento
else {
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciB[0].dU) ;
}
}
}
+89 -1
View File
@@ -19,7 +19,11 @@
#include "NgeReader.h"
#include "FontManager.h"
#include "FontAux.h"
#include "SurfFlatRegion.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
#include "/EgtDev/Include/EGkUiUnits.h"
#include <new>
@@ -30,7 +34,7 @@ GEOOBJ_REGISTER( EXT_TEXT, NGE_E_TXT, ExtText) ;
//----------------------------------------------------------------------------
ExtText::ExtText( void)
: m_ptP(), m_vtN( 0, 0, 1), m_vtD( 1, 0, 0), m_sFont(),
: m_pSTM( nullptr), m_ptP(), m_vtN( 0, 0, 1), m_vtD( 1, 0, 0), m_sFont(),
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0), m_nTempProp()
{
}
@@ -38,6 +42,7 @@ ExtText::ExtText( void)
//----------------------------------------------------------------------------
ExtText::~ExtText( void)
{
ResetAuxSurf() ;
}
//----------------------------------------------------------------------------
@@ -61,6 +66,7 @@ ExtText::Set( const Point3d& ptP, double dAngDeg, const string& sText, double dH
m_nInsPos = ETXT_IPBL ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return true ;
@@ -91,6 +97,7 @@ ExtText::Set( const Point3d& ptP, const Vector3d& vtN, const Vector3d& vtD,
m_nInsPos = ETXT_IPBL ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return true ;
@@ -126,6 +133,7 @@ ExtText::Set( const Point3d& ptP, const Vector3d& vtN, const Vector3d& vtD,
m_nInsPos = (( nInsPos >= ETXT_IPTL && nInsPos <= ETXT_IPBR) ? nInsPos : ETXT_IPBL) ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return true ;
@@ -163,6 +171,7 @@ ExtText::CopyFrom( const ExtText& clSrc)
{
if ( &clSrc == this)
return true ;
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
m_ptP = clSrc.m_ptP ;
m_vtN = clSrc.m_vtN ;
@@ -282,6 +291,7 @@ bool
ExtText::Load( NgeReader& ngeIn)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// leggo la prossima linea : punto, posiz. inserimento, normale, direzione
if ( ! ngeIn.ReadPoint( m_ptP, ";"))
@@ -386,6 +396,7 @@ ExtText::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
bool
ExtText::Translate( const Vector3d& vtMove)
{
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
m_ptP.Translate( vtMove) ;
return true ;
@@ -395,6 +406,7 @@ ExtText::Translate( const Vector3d& vtMove)
bool
ExtText::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
{
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return ( m_ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
m_vtN.Rotate( vtAx, dCosAng, dSinAng) &&
@@ -410,6 +422,7 @@ ExtText::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCo
return false ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// scalo il punto di inserimento
@@ -449,6 +462,7 @@ ExtText::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
return false ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// eseguo il mirror del punto di inserimento
@@ -480,6 +494,7 @@ ExtText::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD
return false ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// eseguo scorrimento del punto di inserimento
@@ -515,6 +530,7 @@ bool
ExtText::ToGlob( const Frame3d& frRef)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// trasformo punto e versori
return ( m_ptP.ToGlob( frRef) &&
@@ -527,6 +543,7 @@ bool
ExtText::ToLoc( const Frame3d& frRef)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// trasformo punto e versori
return ( m_ptP.ToLoc( frRef) &&
@@ -545,6 +562,7 @@ ExtText::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
if ( AreSameFrame( frOri, frDest))
return true ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// trasformo punto e versori
return ( m_ptP.ToGlob( frOri) && m_ptP.ToLoc( frDest) &&
@@ -791,11 +809,76 @@ ExtText::ApproxWithArcs( double dLinTol, double dAngTolDeg, POLYARCLIST& lstPA)
return true ;
}
//----------------------------------------------------------------------------
const ISurfTriMesh*
ExtText::GetAuxSurf( void) const
{
// imposto il font corrente e i suoi dati
FontManager& fntMgr = FontManager::GetFontManager() ;
if ( ! fntMgr.SetCurrFont( m_sFont, m_nWeight, m_bItalic, m_dHeight, m_dRatio, m_dAddAdvance))
return nullptr ;
// se già calcolata, la restituisco
if ( m_pSTM != nullptr)
return m_pSTM ;
// calcolo la trasformazione
Frame3d frRef ;
if ( ! frRef.Set( m_ptP, m_vtN, m_vtD))
return nullptr ;
// preparo il generatore della superficie
StmFromTriangleSoup StmFts ;
if ( ! StmFts.Start())
return nullptr ;
// richiedo la lista delle regioni
ISURFFRPLIST lstSfr ;
if ( ! fntMgr.GetRegion( m_sText, m_nInsPos, lstSfr))
return nullptr ;
// per ogni regione richiedo la superficie ausiliaria e la aggiungo a quella generale
for ( const auto& pSfr : lstSfr) {
// recupero la superficie trimesh
const ISurfTriMesh* pStm = pSfr->GetAuxSurf() ;
if ( pStm != nullptr) {
Triangle3d Tria ;
int nT = pStm->GetFirstTriangle( Tria) ;
while ( nT != SVT_NULL) {
StmFts.AddTriangle( Tria) ;
nT = pStm->GetNextTriangle( nT, Tria) ;
}
}
// cancello la regione
delete pSfr ;
}
// valido e assegno la superficie complessiva
if ( ! StmFts.End())
return nullptr ;
m_pSTM = GetBasicSurfTriMesh( StmFts.GetSurf()) ;
// eseguo la trasformazione
m_pSTM->ToGlob( frRef) ;
return m_pSTM ;
}
//----------------------------------------------------------------------------
void
ExtText::ResetAuxSurf( void) const
{
if ( m_pSTM != nullptr)
delete( m_pSTM) ;
m_pSTM = nullptr ;
}
//----------------------------------------------------------------------------
bool
ExtText::Flip( void)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// recupero il centro
Point3d ptCen ;
@@ -813,6 +896,7 @@ bool
ExtText::Mir( bool bOnLen)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// se auto-mirror sulla lunghezza del testo
@@ -857,6 +941,7 @@ ExtText::ModifyText( const string& sText)
return false ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// assegno nuovo test
m_sText = sText ;
@@ -869,6 +954,7 @@ bool
ExtText::ChangeFont( const string& sFont)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// assegno nuovo font
m_sFont = sFont ;
@@ -881,6 +967,7 @@ bool
ExtText::ChangeHeight( double dH)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// assegno nuova altezza
m_dHeight = dH ;
@@ -893,6 +980,7 @@ bool
ExtText::ChangeItalic( bool bItl)
{
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
// assegno nuovo flag di talico
m_bItalic = bItl ;
+4
View File
@@ -16,6 +16,7 @@
#include "ObjGraphicsMgr.h"
#include "DllMain.h"
#include "GeoObjRW.h"
#include "SurfTriMesh.h"
#include "/EgtDev/Include/EGkExtText.h"
@@ -95,6 +96,7 @@ class ExtText : public IExtText, public IGeoObjRW
bool SplitOnLineBreak( IEXTTEXTPVECTOR& vText) const override ;
bool ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const override ;
bool ApproxWithArcs( double dLinTol, double dAngTolDeg, POLYARCLIST& lstPA) const override ;
const ISurfTriMesh* GetAuxSurf( void) const override ;
bool Flip( void) override ;
bool Mir( bool bOnLen) override ;
bool ModifyText( const std::string& sText) override ;
@@ -119,6 +121,7 @@ class ExtText : public IExtText, public IGeoObjRW
private :
bool CopyFrom( const ExtText& gpSrc) ;
void ResetAuxSurf( void) const ;
private :
static const int MAX_FONT_LEN = 125 ;
@@ -127,6 +130,7 @@ class ExtText : public IExtText, public IGeoObjRW
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria
Point3d m_ptP ; // punto di inserimento
Vector3d m_vtN ; // versore normale
Vector3d m_vtD ; // versore di direzione
+10
View File
@@ -131,6 +131,16 @@ FontManager::GetOutline( const string& sText, int nInsPos, ICURVEPLIST& lstPC) c
return m_OsFont.GetOutline( sText, nInsPos, lstPC) ;
}
//----------------------------------------------------------------------------
bool
FontManager::GetRegion( const string& sText, int nInsPos, ISURFFRPLIST& lstSFR) const
{
if ( m_bCurrNfeFont)
return false ;
else
return m_OsFont.GetRegion( sText, nInsPos, lstSFR) ;
}
//----------------------------------------------------------------------------
bool
FontManager::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const
+1 -2
View File
@@ -35,14 +35,13 @@ class FontManager
{ return m_sNfeFontDir ; }
const std::string& GetDefaultFont( void) const
{ return m_sDefaultFont ; }
bool IsNfeFont( void) const
{ return m_bCurrNfeFont ; }
bool GetCapHeight( double& dCapH) const ;
bool GetAscent( double& dAsc) const ;
bool GetDescent( double& dDesc) const ;
bool GetCapBox( const std::string& sText, int nInsPos, BBox3d& b3Box) const ;
bool GetBBox( const std::string& sText, int nInsPos, BBox3d& b3Box) const ;
bool GetOutline( const std::string& sText, int nInsPos, ICURVEPLIST& lstPC) const ;
bool GetRegion( const std::string& sText, int nInsPos, ISURFFRPLIST& lstSFR) const ;
bool ApproxWithLines( const std::string& sText, int nInsPos, double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const ;
bool ApproxWithArcs( const std::string& sText, int nInsPos, double dLinTol, double dAngTolDeg, POLYARCLIST& lstPA) const ;
bool GetTextLines( const std::string& sText, int nInsPos, PNTVECTOR& vPt, STRVECTOR& vLine) const ;
+85
View File
@@ -16,6 +16,8 @@
#include "FontOs.h"
#include "FontAux.h"
#include "FontConst.h"
#include "SurfFlatRegion.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EGkCurve.h"
@@ -23,6 +25,7 @@
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveBezier.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/EgtStringConverter.h"
@@ -329,6 +332,88 @@ OsFont::GetOutline( const string& sText, int nInsPos, ICURVEPLIST& lstPC) const
return true ;
}
//----------------------------------------------------------------------------
bool
OsFont::GetRegion( const string& sText, int nInsPos, ISURFFRPLIST& lstSFR) const
{
// verifico esistenza font corrente
if ( m_hDC == nullptr || m_hFont == nullptr || m_sFont.empty())
return false ;
// rendo corrente il font
HFONT hPrevFont = (HFONT) SelectObject( m_hDC, m_hFont) ;
if ( hPrevFont == nullptr)
return false ;
// calcolo i fattori di scala
double dScaY = m_dHeight / m_dHCap ;
double dScaX = dScaY * m_dRatio ;
double dScaZ = 1 ;
// recupero altezza maiuscole e interlinea
double dHCap = m_dHeight ;
double dH = m_dH * m_dHeight / m_dHCap ;
// converto i byte della stringa in codici carattere
UINTVECTOR vCode ;
GetCodePoints( sText, vCode) ;
// ciclo sui codici
double dMaxW = 0 ;
double dMinH = 0 ;
Vector3d vtMove ;
for ( unsigned int i = 0 ; i < vCode.size() ; ++ i) {
// verifico se comando di a capo
int nLbLen ;
if ( IsLineBreak( vCode, i, nLbLen)) {
vtMove.Set( 0, vtMove.y - dH, 0) ;
if ( vtMove.y < dMinH)
dMinH = vtMove.y ;
i += nLbLen ;
continue ;
}
// recupero l'outline
double dAdvance ;
ICURVEPLIST lstPC ;
if ( ! GetCharOutline( vCode[i], dAdvance, lstPC))
return false ;
// lo trasformo opportunamente
ICURVEPLIST::iterator iIter ;
for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) {
// inverto i percorsi per avere gli esterni CCW
(*iIter)->Invert() ;
// la trasformo per avere solo archi e rette
GetCurveComposite( *iIter)->ArcsBezierCurvesToArcsPerpExtr( LIN_TOL_FINE, ANG_STRAIGHT) ;
}
// creo la regione
SurfFlatRegionByContours SfrCntr( false, true) ;
for ( auto& PC : lstPC)
SfrCntr.AddCurve( PC) ;
PtrOwner<SurfFlatRegion> pSfr( GetBasicSurfFlatRegion( SfrCntr.GetSurf())) ;
if ( ! IsNull( pSfr)) {
// trasformazioni
pSfr->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ;
pSfr->Translate( vtMove) ;
// inserimento in lista
lstSFR.push_back( Release( pSfr)) ;
}
// aggiorno per larghezza
vtMove += Vector3d( dAdvance * dScaX + m_dAddAdvance, 0, 0) ;
if ( vtMove.x > dMaxW)
dMaxW = vtMove.x ;
}
// sistemazioni per la posizione del punto di inserimento
Vector3d vtIpMove = GetTextInsertPointMove( dMaxW, dHCap, dMinH, nInsPos) ;
for ( const auto& pSfr : lstSFR)
pSfr->Translate( vtIpMove) ;
// ripristino il font originale
SelectObject( m_hDC, hPrevFont) ;
return true ;
}
//----------------------------------------------------------------------------
bool
OsFont::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, double dAngTolDeg,
+2
View File
@@ -14,6 +14,7 @@
#pragma once
#include "/EgtDev/Include/EGkCurve.h"
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
#include "/EgtDev/Include/EgtStringBase.h"
#define NOMINMAX
#include <Windows.h>
@@ -34,6 +35,7 @@ class OsFont
bool GetDescent( double& dDesc) const ;
bool GetXBox( const std::string& sText, int nInsPos, bool bCapOrBound, BBox3d& b3Box) const ;
bool GetOutline( const std::string& sText, int nInsPos, ICURVEPLIST& lstPC) const ;
bool GetRegion( const std::string& sText, int nInsPos, ISURFFRPLIST& lstSFR) const ;
bool ApproxWithLines( const std::string& sText, int nInsPos, double dLinTol, double dAngTolDeg,
POLYLINELIST& lstPL) const ;
bool ApproxWithArcs( const std::string& sText, int nInsPos, double dLinTol, double dAngTolDeg,
+19 -8
View File
@@ -1051,15 +1051,12 @@ SurfFlatRegion::ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, doub
}
//----------------------------------------------------------------------------
const ISurfTriMesh*
SurfFlatRegion::GetAuxSurf( void) const
SurfTriMesh*
SurfFlatRegion::CalcAuxSurf( double dLinTol, double dAngTolDeg) const
{
// la superficie deve essere validata
if ( m_nStatus != OK || m_vpLoop.empty())
return nullptr ;
// se già calcolata, la restituisco
if ( m_pSTM != nullptr)
return m_pSTM ;
// la creo
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM))
@@ -1073,7 +1070,7 @@ SurfFlatRegion::GetAuxSurf( void) const
ICurve* pLoop = GetMyLoop( i, j) ;
while ( pLoop != nullptr) {
// approssimo con linee a destra per non avere problemi in punti di contatto tra esterni e interni
if ( ! pLoop->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, vPL[j]))
if ( ! pLoop->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_RIGHT, vPL[j]))
return nullptr ;
pLoop = GetMyLoop( i, ++j) ;
}
@@ -1090,8 +1087,22 @@ SurfFlatRegion::GetAuxSurf( void) const
pSTM->DoSewing( *pChSTM) ;
}
}
// la salvo
m_pSTM = Release( pSTM) ;
// la restituisco
return Release( pSTM) ;
}
//----------------------------------------------------------------------------
const ISurfTriMesh*
SurfFlatRegion::GetAuxSurf( void) const
{
// la superficie deve essere validata
if ( m_nStatus != OK || m_vpLoop.empty())
return nullptr ;
// se già calcolata, la restituisco
if ( m_pSTM != nullptr)
return m_pSTM ;
// la creo e la salvo
m_pSTM = CalcAuxSurf( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
return m_pSTM ;
}
+1
View File
@@ -108,6 +108,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
{ if ( ! CopyFrom( stSrc))
LOG_ERROR( GetEGkLogger(), "SurfFlatRegion : copy error")
return *this ; }
SurfTriMesh* CalcAuxSurf( double dLinTol, double dAngTolDeg) const ;
friend class MyCAvSimpleSurfFrMove ;