Files
EgtExchange/ExportSvg.cpp
T
Dario Sassi 03842e7d8d EgtExchange :
- modifica a ExportSvg.
2019-12-06 11:13:13 +00:00

684 lines
23 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2019-2019
//----------------------------------------------------------------------------
// File : ExportStl.cpp Data : 15.09.19 Versione : 2.1i2
// Contenuto : Implementazione della classe per l'esportazione in formato SVG.
//
//
//
// Modifiche : 15.09.19 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "ExportSvg.h"
#include "DllMain.h"
#include "/EgtDev/Include/EExDllMain.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkCurveBezier.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/SELkKeyProc.h"
#include "/EgtDev/Include/EgtKeyCodes.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <fstream>
using namespace std ;
//----------------------------------------------------------------------------
IExportSvg*
CreateExportSvg( void)
{
// verifico la chiave e le opzioni
if ( ! TestKeyForEEx( GetEExKey(), KEYOPT_EEX_EXPBASE, GetEExLogger()))
return false ;
// creo l'oggetto
return static_cast<IExportSvg*> ( new(nothrow) ExportSvg) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::SetOptions( int nFilter)
{
m_nFilter = nFilter ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::Export( IGeomDB* pGDB, int nId, const string& sFile)
{
// verifico il DB geometrico
if ( pGDB == nullptr) {
LOG_ERROR( GetEExLogger(), "ExportSvg : Error on GeomDB")
return false ;
}
// verifico l'Id dell'oggetto da esportare
if ( ! pGDB->ExistsObj( nId)) {
LOG_ERROR( GetEExLogger(), "ExportSvg : Error on Id")
return false ;
}
// apro il file di testo in scrittura
m_Writer.Close() ;
if ( ! m_Writer.Init( sFile)) {
LOG_ERROR( GetEExLogger(), "ExportSvg : Error on open file")
return false ;
}
// Inizializzazioni
m_vtMove = V_NULL ;
m_usNames.clear() ;
bool bOk = true ;
// recupero ingombro dell'esportazione
BBox3d b3All ;
pGDB->GetGlobalBBox( nId, b3All, BBF_EXACT) ;
// scrivo la sezione di intestazione
double dDimX = b3All.GetMax().x - b3All.GetMin().x ;
double dDimY = b3All.GetMax().y - b3All.GetMin().y ;
if ( ! ExportHeader( dDimX, dDimY))
bOk = false ;
// scrivo le entità
if ( ! ExportEntities( pGDB, nId, b3All))
bOk = false ;
// terminazione file
if ( ! ExportFooter())
bOk = false ;
// chiudo il file
if ( ! m_Writer.Close())
bOk = false ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportHeader( double dDimX, double dDimY)
{
if ( ! m_Writer.OutText( "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"))
return false ;
const double COEFF = 0.05 ;
double dExtraX = COEFF * dDimX ;
double dExtraY = COEFF * dDimY ;
string sOut = "<svg viewBox=\"" + ToString( - dExtraX, 0) + " " + ToString( - dExtraY, 0) + " " +
ToString( dDimX + 2 * dExtraX, 0) + " " + ToString( dDimY + 2 * dExtraY, 0) + "\"" +
" xmlns=\"http://www.w3.org/2000/svg\">" ;
if ( ! m_Writer.OutText( sOut))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportFooter( void)
{
if ( ! m_Writer.OutText( "</svg>"))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportEntities( IGeomDB* pGDB, int nId, const BBox3d& b3All)
{
// determino il vettore movimento (le Z sono ignorate)
m_vtMove = ( b3All.IsEmpty() ? V_NULL : Point3d( 0, 0, 0) - Point3d( b3All.GetMin().x, b3All.GetMax().y, 0)) ;
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
if ( IsNull( pIter))
return false ;
pIter->GoTo( nId) ;
// esporto l'oggetto e i suoi eventuali figli
return ExportGdbObject( *pIter) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportGdbObject( const IGdbIterator& iIter)
{
// se oggetto geometrico
if ( iIter.GetGdbType() == GDB_TY_GEO) {
// recupero l'oggetto geometrico
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
if ( pGeoObj == nullptr)
return true ;
// recupero il riferimento globale dell'oggetto
Frame3d frFrame ;
if ( ! iIter.GetGlobFrame( frFrame))
return false ;
// recupero il livello dell'oggetto
int nLev = GDB_LV_USER ;
iIter.GetCalcLevel( nLev) ;
// recupero il modo dell'oggetto
int nMode = GDB_MD_STD ;
iIter.GetCalcMode( nMode) ;
// recupero lo stato dell'oggetto
int nStat = GDB_ST_ON ;
iIter.GetCalcStatus( nStat) ;
// se il filtro lo abilita
if ( TestFilter( nLev, nMode, nStat)) {
// recupero eventuale nome
string sName = "" ;
if ( iIter.GetName( sName)) {
if ( m_usNames.find( sName) == m_usNames.end())
m_usNames.emplace( sName) ;
else
sName += "_" + ToString( iIter.GetId()) ;
}
else
sName += "_" + ToString( iIter.GetId()) ;
// recupero il colore
Color colObj ;
iIter.GetCalcMaterial( colObj) ;
// emetto l'oggetto
switch ( pGeoObj->GetType()) {
case CRV_LINE :
if ( ! ExportLine( sName, colObj, pGeoObj, frFrame))
return false ;
break ;
case CRV_ARC :
if ( ! ExportArc( sName, colObj, pGeoObj, frFrame, false))
return false ;
break ;
case CRV_BEZ :
if ( ! ExportBezier( sName, colObj, pGeoObj, frFrame, false))
return false ;
break ;
case CRV_COMPO :
if ( ! ExportComposite( sName, colObj, pGeoObj, frFrame, false))
return false ;
break ;
case SRF_FLATRGN :
if ( ! ExportFlatRegion( sName, colObj, pGeoObj, frFrame))
return false ;
break ;
case SRF_TRIMESH :
if ( ! ExportTriMesh( sName, colObj, pGeoObj, frFrame))
return false ;
break ;
case EXT_TEXT :
if ( ! ExportText( sName, colObj, pGeoObj, frFrame))
return false ;
break ;
}
}
return true ;
}
// se gruppo
else if ( iIter.GetGdbType() == GDB_TY_GROUP) {
// esploro il gruppo
return ScanGroup( iIter) ;
}
// altrimenti errore
else
return false ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ScanGroup( const IGdbIterator& iIter)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
if ( IsNull( pIter))
return false ;
// scandisco il gruppo
bool bOk = true ;
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext = pIter->GoToNext()) {
if ( ! ExportGdbObject( *pIter))
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::TestFilter( int nLev, int nMode, int nStat)
{
if ( ( nLev == GDB_LV_USER && ( m_nFilter & EEXFLT_LEVUSER) == 0) ||
( nLev == GDB_LV_SYSTEM && ( m_nFilter & EEXFLT_LEVSYSTEM) == 0) ||
( nLev == GDB_LV_TEMP && ( m_nFilter & EEXFLT_LEVTEMP) == 0))
return false ;
if ( ( nMode == GDB_MD_STD && ( m_nFilter & EEXFLT_MODESTD) == 0) ||
( nMode == GDB_MD_LOCKED && ( m_nFilter & EEXFLT_MODELOCKED) == 0) ||
( nMode == GDB_MD_HIDDEN && ( m_nFilter & EEXFLT_MODEHIDDEN) == 0))
return false ;
if ( ( nStat == GDB_ST_OFF && ( m_nFilter & EEXFLT_STAOFF) == 0) ||
( nStat == GDB_ST_ON && ( m_nFilter & EEXFLT_STAON) == 0) ||
( nStat == GDB_ST_SEL && ( m_nFilter & EEXFLT_STASEL) == 0))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportLine( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const ICurveLine* pLine = GetCurveLine( pGeoObj) ;
if ( pLine == nullptr)
return false ;
// verifico giacitura nel piano XY
Plane3d plPlane ;
if ( ! pLine->IsFlat( plPlane, 10 * EPS_SMALL) ||
! plPlane.ToGlob( frFrame) ||
! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), Z_AX))
return true ;
// questo oggetto non può avere fill
bool bFill = false ;
// assegno tipo
string sOut = " <path" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// aggiungo inizio dati geometrici
sOut += " d=\"" ;
// punto iniziale
sOut +=GetStartString( pLine, frFrame) ;
// arco
sOut += GetCurveString( pLine, frFrame) ;
// termino i dati geometrici
sOut += "\"" ;
// colore e spessore
sOut += " fill=\"" + ( bFill ? GetColorString( colObj) : "none") + "\" stroke=\"" + GetColorString( colObj) + "\" stroke-width=\"1\"" ;
// termino
sOut += " />" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportArc( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame, bool bFill)
{
// verifico oggetto
const ICurveArc* pArc = GetCurveArc( pGeoObj) ;
if ( pArc == nullptr)
return false ;
// verifico giacitura nel piano XY
Plane3d plPlane ;
if ( ! static_cast<const ICurve*>( pArc)->IsFlat( plPlane, 10 * EPS_SMALL) ||
! plPlane.ToGlob( frFrame) ||
! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), Z_AX))
return true ;
// assegno tipo
string sOut = " <path" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// aggiungo inizio dati geometrici
sOut += " d=\"" ;
// punto iniziale
sOut +=GetStartString( pArc, frFrame) ;
// arco
sOut += GetCurveString( pArc, frFrame) ;
// termino i dati geometrici
sOut += "\"" ;
// colore e spessore
sOut += " fill=\"" + ( bFill ? GetColorString( colObj) : "none") + "\" stroke=\"" + GetColorString( colObj) + "\" stroke-width=\"1\"" ;
// termino
sOut += " />" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportBezier( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame, bool bFill)
{
// verifico oggetto
const ICurveBezier* pBez = GetCurveBezier( pGeoObj) ;
if ( pBez == nullptr)
return false ;
// verifico giacitura nel piano XY
Plane3d plPlane ;
if ( ! static_cast<const ICurve*>( pBez)->IsFlat( plPlane, 10 * EPS_SMALL) ||
! plPlane.ToGlob( frFrame) ||
! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), Z_AX))
return true ;
// assegno tipo
string sOut = " <path" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// aggiungo inizio dati geometrici
sOut += " d=\"" ;
// punto iniziale
sOut +=GetStartString( pBez, frFrame) ;
// curva di Bezier
sOut += GetCurveString( pBez, frFrame) ;
// termino i dati geometrici
sOut += "\"" ;
// colore e spessore
sOut += " fill=\"" + ( bFill ? GetColorString( colObj) : "none") + "\" stroke=\"" + GetColorString( colObj) + "\" stroke-width=\"1\"" ;
// termino
sOut += " />" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportComposite( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame, bool bFill)
{
// verifico oggetto
const ICurveComposite* pCompo = GetCurveComposite( pGeoObj) ;
if ( pCompo == nullptr)
return false ;
// verifico giacitura nel piano XY
Plane3d plPlane ;
if ( ! pCompo->IsFlat( plPlane, 10 * EPS_SMALL) ||
! plPlane.ToGlob( frFrame) ||
! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), Z_AX))
return true ;
// assegno tipo
string sOut = " <path" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// aggiungo inizio dati geometrici
sOut += " d=\"" ;
// punto iniziale
sOut += GetStartString( pCompo, frFrame) ;
// curva composita
sOut += GetCurveString( pCompo, frFrame) ;
// termino i dati geometrici
sOut += "\"" ;
// colore e spessore
sOut += " fill=\"" + ( bFill ? GetColorString( colObj) : "none") + "\" stroke=\"" + GetColorString( colObj) + "\" stroke-width=\"1\"" ;
// termino
sOut += " />" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportFlatRegion( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeoObj) ;
if ( pSfr == nullptr)
return false ;
// verifico giacitura nel piano XY
Vector3d vtN = pSfr->GetNormVersor() ;
if ( ! AreSameOrOppositeVectorApprox( vtN, Z_AX))
return true ;
// questo oggetto deve avere fill
bool bFill = true ;
// assegno tipo
string sOut = " <path" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// aggiungo inizio dati geometrici
sOut += " d=\"" ;
// ciclo sui chunk
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) {
// ciclo sui loop
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) {
// recupero il loop
PtrOwner<ICurve> pLoop( pSfr->GetLoop( nC, nL)) ;
if ( IsNull( pLoop))
return false ;
// punto iniziale
sOut += GetStartString( pLoop, frFrame) ;
// curva
if ( pLoop->GetType() == CRV_LINE)
sOut += GetCurveString( GetCurveLine( pLoop), frFrame) ;
else if ( pLoop->GetType() == CRV_ARC)
sOut += GetCurveString( GetCurveArc( pLoop), frFrame) ;
else if ( pLoop->GetType() == CRV_BEZ)
sOut += GetCurveString( GetCurveBezier( pLoop), frFrame) ;
else if ( pLoop->GetType() == CRV_COMPO)
sOut += GetCurveString( GetCurveComposite( pLoop), frFrame) ;
else
return false ;
}
}
// termino i dati geometrici
sOut += "\"" ;
// colore e spessore
sOut += " fill=\"" + ( bFill ? GetColorString( colObj) : "none") +
"\" fill-opacity=\"" + ToString( colObj.GetAlpha(), 2) +
"\" stroke=\"" + GetColorString( colObj) +
"\" stroke-opacity=\"" + ToString( colObj.GetAlpha(), 2) +
"\" stroke-width=\"1\"" ;
// termino
sOut += " />" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportTriMesh( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeoObj) ;
if ( pStm == nullptr)
return false ;
// verifico giacitura nel piano XY
for ( int nF = 0 ; nF < pStm->GetFacetCount() ; ++ nF) {
Point3d ptCen ; Vector3d vtN ;
if ( ! pStm->GetFacetCenter( nF, ptCen, vtN) || ! AreSameOrOppositeVectorApprox( vtN, Z_AX))
return true ;
}
// questo oggetto deve avere fill
bool bFill = true ;
// assegno tipo
string sOut = " <path" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// aggiungo inizio dati geometrici
sOut += " d=\"" ;
// ciclo sulle facce
for ( int nF = 0 ; nF < pStm->GetFacetCount() ; ++ nF) {
POLYLINEVECTOR vPL ;
if ( ! pStm->GetFacetLoops( nF, vPL))
return false ;
// ciclo sui loop di una faccia
for ( int nL = 0 ; nL < int( vPL.size()) ; ++ nL) {
PtrOwner<ICurveComposite> pLoop( CreateCurveComposite()) ;
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( vPL[nL]))
return false ;
// punto iniziale
sOut += GetStartString( pLoop, frFrame) ;
// curva
sOut += GetCurveString( pLoop, frFrame) ;
}
}
// termino i dati geometrici
sOut += "\"" ;
// colore e spessore
sOut += " fill=\"" + ( bFill ? GetColorString( colObj) : "none") +
"\" fill-opacity=\"" + ToString( colObj.GetAlpha(), 2) +
"\" stroke=\"" + GetColorString( colObj) +
"\" stroke-opacity=\"" + ToString( colObj.GetAlpha(), 2) +
"\" stroke-width=\"1\"" ;
// termino
sOut += " />" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
bool
ExportSvg::ExportText( const string& sName, const Color& colObj, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const IExtText* pText = GetExtText( pGeoObj) ;
if ( pText == nullptr)
return false ;
// verifico giacitura nel piano XY
Vector3d vtN = pText->GetNormVersor() ;
if ( ! AreSameOrOppositeVectorApprox( vtN, Z_AX))
return true ;
// assegno tipo
string sOut = " <text" ;
// aggiungo nome e Id
sOut += " id=\"" + sName + "\"" ;
// recupero posizione
Point3d ptStart ; pText->GetStartPoint( ptStart) ;
ptStart.ToGlob( frFrame) ;
ptStart += m_vtMove ;
sOut += " transform=\"translate(" + ToString( ptStart.x, 3) + "," + ToString( -ptStart.y, 3) + ")" ;
// eventuale rotazione
double dAngH ;
pText->GetDirVersor().ToSpherical( nullptr, nullptr, &dAngH) ;
sOut += "rotate(" + ToString( -dAngH, 3) + ")\"" ;
// famiglia del font
string sFont = pText->GetFont() ;
sOut += " font-family=\"" + sFont + "\"" ;
// dimensione del font
double dH = pText->GetHeight() ;
sOut += " font-size=\"" + ToString( dH, 3) + "\"" ;
// lunghezza suggerita
Point3d ptEnd ; pText->GetEndPoint( ptEnd) ;
ptEnd.ToGlob( frFrame) ;
ptEnd += m_vtMove ;
double dLen = DistXY( ptStart, ptEnd) ;
sOut += " textLength=\"" + ToString( dLen, 3) + "\"" ;
// colore
sOut += " fill=\"" + GetColorString( colObj) + "\">" ;
// recupero il contenuto e converto i caratteri speciali
string sText = pText->GetText() ;
ReplaceString( sText, "&", "&#38;") ;
ReplaceString( sText, "<", "&#60;") ;
sOut += sText ;
// termino
sOut += "</text>" ;
// emetto
return m_Writer.OutText( sOut) ;
}
//----------------------------------------------------------------------------
string
ExportSvg::GetStartString( const ICurve* pCrv, const Frame3d& frFrame)
{
// verifica
if ( pCrv == nullptr)
return "" ;
Point3d ptStart ; pCrv->GetStartPoint( ptStart) ;
ptStart.ToGlob( frFrame) ;
ptStart += m_vtMove ;
return " M " + ToString( ptStart.x, 3) + "," + ToString( -ptStart.y, 3) ;
}
//----------------------------------------------------------------------------
string
ExportSvg::GetCurveString( const ICurveLine* pLine, const Frame3d& frFrame)
{
// verifica
if ( pLine == nullptr)
return "" ;
// recupero il punto finale
Point3d ptEnd = pLine->GetEnd() ;
ptEnd.ToGlob( frFrame) ;
ptEnd += m_vtMove ;
// aggiungo il punto
return " L " + ToString( ptEnd.x, 3) + "," + ToString( -ptEnd.y, 3) ;
}
//----------------------------------------------------------------------------
string
ExportSvg::GetCurveString( const ICurveArc* pArc, const Frame3d& frFrame)
{
// verifica
if ( pArc == nullptr)
return "" ;
// recupero i dati geometrici dell'arco (estremi, angolo al centro e senso)
Point3d ptStart ; pArc->GetStartPoint( ptStart) ;
ptStart.ToGlob( frFrame) ;
ptStart += m_vtMove ;
Point3d ptEnd ; pArc->GetEndPoint( ptEnd) ;
ptEnd.ToGlob( frFrame) ;
ptEnd += m_vtMove ;
double dRad = pArc->GetRadius() ;
bool bCCW = ( ( pArc->GetAngCenter() > 0 && pArc->GetNormVersor().IsZplus()) ||
( pArc->GetAngCenter() < 0 && pArc->GetNormVersor().IsZminus())) ;
// se arco esportabile in una parte
if ( abs( pArc->GetAngCenter()) <= ANG_STRAIGHT + 10 * EPS_ANG_SMALL) {
return " A " + ToString( dRad, 3) + "," + ToString( dRad, 3) + " 0 0," + ( bCCW ? "0 " : "1 ") +
ToString( ptEnd.x, 3) + "," + ToString( -ptEnd.y, 3) ;
}
// altrimenti lo esporto in due parti
else {
// recupero il punto medio
Point3d ptMid ; pArc->GetMidPoint( ptMid) ;
ptMid.ToGlob( frFrame) ;
ptMid += m_vtMove ;
return " A " + ToString( dRad, 3) + "," + ToString( dRad, 3) + " 0 0," + ( bCCW ? "0 " : "1 ") +
ToString( ptMid.x, 3) + "," + ToString( -ptMid.y, 3) +
" A " + ToString( dRad, 3) + "," + ToString( dRad, 3) + " 0 0," + ( bCCW ? "0 " : "1 ") +
ToString( ptEnd.x, 3) + "," + ToString( -ptEnd.y, 3) ;
}
}
//----------------------------------------------------------------------------
string
ExportSvg::GetCurveString( const ICurveBezier* pBez, const Frame3d& frFrame)
{
// verifica
if ( pBez == nullptr)
return "" ;
// approssimo con archi e rette
const double BEZ_LIN_APPROX = 0.01 ;
const double BEZ_ANG_APPROX_DEG = 5.0 ;
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
PolyArc PA ;
if ( ! pBez->ApproxWithArcs( BEZ_LIN_APPROX, BEZ_ANG_APPROX_DEG, PA) || ! pCC->FromPolyArc( PA))
return "" ;
return GetCurveString( pCC, frFrame) ;
}
//----------------------------------------------------------------------------
string
ExportSvg::GetCurveString( const ICurveComposite* pCompo, const Frame3d& frFrame)
{
// verifica
if ( pCompo == nullptr)
return "" ;
// ciclo sulle curve elementari
string sOut ;
const ICurve* pCrv = pCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
if ( pCrv->GetType() == CRV_LINE)
sOut += GetCurveString( GetCurveLine( pCrv), frFrame) ;
else if ( pCrv->GetType() == CRV_ARC)
sOut += GetCurveString( GetCurveArc( pCrv), frFrame) ;
else if ( pCrv->GetType() == CRV_BEZ)
sOut += GetCurveString( GetCurveBezier( pCrv), frFrame) ;
else
return false ;
pCrv = pCompo->GetNextCurve() ;
}
return sOut ;
}
//----------------------------------------------------------------------------
string
ExportSvg::GetColorString( const Color& colObj)
{
string sCol = "rgb(" + ToString( colObj.GetIntRed()) + "," +
ToString( colObj.GetIntGreen()) + "," +
ToString( colObj.GetIntBlue()) + ")" ;
return sCol ;
}