Files
EgtGeomKernel/OutScl.cpp
T

474 lines
13 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2013-2013
//----------------------------------------------------------------------------
// File : OutScl.cpp Data : 31.12.12 Versione : 1.1a1
// Contenuto : Implementazione della classe output SCL.
//
//
//
// Modifiche : 31.12.12 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "OutScl.h"
#include "/EgtDev/Include/EgnStringUtils.h"
#include "/EgtDev/Include/EgnStringConverter.h"
using namespace std ;
//----------------------------------------------------------------------------
OutScl::OutScl( void)
{
}
//----------------------------------------------------------------------------
OutScl::~OutScl( void)
{
Close() ;
}
//----------------------------------------------------------------------------
bool
OutScl::Open( const string& sOutScl)
{
// apro il file
m_ofFile.open( stringtoW( sOutScl)) ;
if ( ! m_ofFile.good())
return false ;
// scrivo linee iniziali
Start() ;
New() ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::Close( void)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// scrivo linee finali
End() ;
// chiudo il file
m_ofFile.close() ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::Start( void)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// emetto stringa
m_ofFile << "{" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::End( void)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// emetto stringa
m_ofFile << "}" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::New( void)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// emetto stringa
m_ofFile << "NewFile() ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::Remark( string sRemark)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// emetto stringa
m_ofFile << "// " << sRemark << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::SetMaterial( double dRed, double dGreen, double dBlue)
{
int nRed ;
int nGreen ;
int nBlue ;
string sMat ;
// componenti colore nell'intervallo 0-255
nRed = max( 0, min( int( 255 * dRed), 255)) ;
nGreen = max( 0, min( int( 255 * dGreen), 255)) ;
nBlue = max( 0, min( int( 255 * dBlue), 255)) ;
// calcolo nome materiale
sMat = "RGB" + ToString( nRed, 3) + ToString( nGreen, 3) + ToString( nBlue, 3) ;
// definizione materiale
return SetMaterial( sMat, ( nRed / 255.), ( nGreen / 255.), ( nBlue / 255.)) ;
}
//----------------------------------------------------------------------------
bool
OutScl::SetMaterial( string sMaterial, double dRed, double dGreen, double dBlue)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// salvo nome materiale
m_sMaterial = sMaterial ;
// emetto comando di creazione materiale
m_ofFile << "AddMaterial( \"" << sMaterial << "\", " <<
ToString( dRed, 3) << ", " << ToString( dGreen, 3) << ", " << ToString( dBlue, 3) << ") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::SetPartLay( string sPart, string sLay)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
m_sPartLay = sPart + "\\" + sLay ;
// emetto comando di creazione pezzo
m_ofFile << "CreatePart( \"" << sPart << "\") ;" << endl ;
// emetto comando di creazione layer
m_ofFile << "CreateLayer( \"" << sLay << "\", \"" << sPart << "\") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::SetPartLayRef( string sPart, string sLay, const Frame3d& frFrame)
{
double dAngC ;
double dAngA ;
double dAngC1 ;
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
m_sPartLay = sPart + "\\" + sLay ;
// calcolo angoli di rotazione del frame
frFrame.GetRotationsCAC1( dAngC, dAngA, dAngC1) ;
// emetto comando di creazione pezzo
m_ofFile << "CreatePart( \"" << sPart << "\") ;" << endl ;
// emetto comando di creazione layer
m_ofFile << "CreateLayer( \"" << sLay << "\", \"" << sPart << "\") ;" << endl ;
// emetto comando di modifica riferimento
m_ofFile << "ModifyLayerRef( \"" << sLay << "\", \"" << sPart << "\"," ;
m_ofFile << "30,0," << ToString( frFrame.Orig()) << "," ;
m_ofFile << ToString( dAngC) << "," << ToString( dAngA) << "," << ToString( dAngC1) << ") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::Line2P( const Point3d& ptP1, const Point3d& ptP2)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// verifico non sia praticamente nulla
if ( AreSamePointNear( ptP1, ptP2))
return true ;
// emetto linea
m_ofFile << "Line3D( \"" << m_sPartLay << "\", \"" << m_sMaterial << "\", " ;
m_ofFile << ToString( ptP1) << ", " << ToString( ptP2) ;
m_ofFile << ") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::Arc3P( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// emetto arco
m_ofFile << "Arc3P( \"" << m_sPartLay << "\", \"" << m_sMaterial << "\", " ;
m_ofFile << ToString( ptP1) << ", " << ToString( ptP2) << ", " << ToString( ptP3) ;
m_ofFile << ") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::ArcCPA( const Point3d& ptCen, const Point3d& ptMed, double dAngCenDeg)
{
Point3d ptP1 ;
Point3d ptP3 ;
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// calcolo i due punti estremi
ptP1 = ptMed ;
ptP1.Rotate( ptCen, Vector3d( 0, 0, 1), - 0.5 * dAngCenDeg * DEGTORAD) ;
ptP3 = ptMed ;
ptP3.Rotate( ptCen, Vector3d( 0, 0, 1), 0.5 * dAngCenDeg * DEGTORAD) ;
// emetto arco
m_ofFile << "Arc3P( \"" << m_sPartLay << "\", \"" << m_sMaterial << "\", " ;
m_ofFile << ToString( ptP1, 8) << ", " << ToString( ptMed, 8) << ", " << ToString( ptP3, 8) ;
m_ofFile << ") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::CircleCR( const Point3d& ptCen, double dRad)
{
// verifico sia aperto
if ( ! m_ofFile.is_open())
return false ;
// emetto arco
m_ofFile << "CircCR( \"" << m_sPartLay << "\", \"" << m_sMaterial << "\", " ;
m_ofFile << ToString( ptCen.x) << "," << ToString( ptCen.y) << ", " << ToString( dRad) ;
m_ofFile << ") ;" << endl ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::ArcCurvOrTgOrNone( const CrvPointDiffGeom& oDiffG)
{
bool bCCW ;
double dAngCenDeg ;
Point3d ptCen ;
// curvatura
if ( oDiffG.nStatus == CrvPointDiffGeom::NCRV && fabs( oDiffG.dCurv) > EPS_ZERO) {
// tratto di arco
ptCen = oDiffG.ptP + oDiffG.vtN / oDiffG.dCurv ;
bCCW = ( oDiffG.vtT ^ oDiffG.vtN).z > 0 ;
dAngCenDeg = ( bCCW ? 1 : -1) * 4 * oDiffG.dCurv * RADTODEG ;
ArcCPA( ptCen, oDiffG.ptP, dAngCenDeg) ;
// raggio
Line2P( oDiffG.ptP, ptCen) ;
}
// altrimenti, tangente
else if ( oDiffG.nStatus == CrvPointDiffGeom::TANG && ! oDiffG.vtT.IsSmall())
Line2P( oDiffG.ptP - oDiffG.vtT, oDiffG.ptP + oDiffG.vtT) ;
// altrimenti cerchietto
else
CircleCR( oDiffG.ptP, 1) ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::PutCurve( const IGeoObj* pCurve, int nFlag)
{
if ( pCurve == nullptr)
return false ;
switch ( pCurve->GetType()) {
case CRV_LINE :
return PutCurveLine( *GetCurveLine( pCurve)) ;
case CRV_ARC :
return PutCurveArc( *GetCurveArc( pCurve), nFlag) ;
case CRV_BEZ :
return PutCurveBez( *GetCurveBezier( pCurve), nFlag) ;
case CRV_COMPO :
return PutCurveCompo( *GetCurveComposite( pCurve), nFlag) ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
OutScl::PutCurveLine( const ICurveLine& CrvLine)
{
// scrittura comandi SCL
Remark( "CurveLine") ;
Line2P( CrvLine.GetStart(), CrvLine.GetEnd()) ;
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::PutCurveArc( const ICurveArc& CrvArc, int nFlag)
{
bool bFound ;
double dU ;
Point3d ptIni ;
Point3d ptFin ;
PolyLine PL ;
CrvPointDiffGeom oDiffG ;
// ciclo sui segmenti
Remark( "CurveArc") ;
CrvArc.ApproxWithLines( 0.1, 5, PL) ;
for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) {
Line2P( ptIni, ptFin) ;
}
// se richieste derivate e curvature
if ( ( nFlag & 1) != 0) {
// ciclo per disegnare le derivate
Remark( "ArcTangents+Der2") ;
for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
// ricavo il punto, la tangente, la normale e la curvatura
CrvArc.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ;
// curvatura o tangente o niente
ArcCurvOrTgOrNone( oDiffG) ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag)
{
bool bFound ;
double dU ;
Point3d ptIni ;
Point3d ptFin ;
PolyLine PL ;
CrvPointDiffGeom oDiffG ;
// se richiesto anche il poligono di controllo
if ( ( nFlag & 2) != 0)
PutPolygBez( CrvBez) ;
// ciclo per disegnare i segmenti
Remark( "BezierCurve") ;
CrvBez.ApproxWithLines( 0.1, 5, PL) ;
for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) {
Line2P( ptIni, ptFin) ;
}
// se richieste derivate e curvature
if ( ( nFlag & 1) != 0) {
// ciclo per disegnare le derivate e le curvature
Remark( "BezierTangents+Der2") ;
for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
// ricavo il punto, la tangente, la normale e la curvatura
CrvBez.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ;
// curvatura o tangente o niente
ArcCurvOrTgOrNone( oDiffG) ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::PutPolygBez( const ICurveBezier& CrvBez)
{
int i ;
Point3d ptIni ;
Point3d ptFin ;
// ciclo per disegnare il poligono di controllo
Remark( "BezierPolygon") ;
ptIni = CrvBez.GetControlPoint( 0) ;
for ( i = 1 ; i <= CrvBez.GetDegree() ; ++ i) {
ptFin = CrvBez.GetControlPoint( i) ;
// disegno
Line2P( ptIni, ptFin) ;
// nuovo iniziale prende i valori del finale
ptIni = ptFin ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
OutScl::PutCurveCompo( const ICurveComposite& CrvCompo, int nFlag)
{
bool bFound ;
double dU ;
Point3d ptIni ;
Point3d ptFin ;
PolyLine PL ;
CrvPointDiffGeom oDiffG ;
CrvPointDiffGeom oDiffGs ;
// ciclo per disegnare i segmenti
Remark( "CurveComposite") ;
CrvCompo.ApproxWithLines( 0.1, 5, PL) ;
for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) {
Line2P( ptIni, ptFin) ;
}
// se richieste derivate e curvature
if ( ( nFlag & 1) != 0) {
// ciclo per disegnare le derivate e le curvature
Remark( "CompositeTangents+Der2") ;
for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
// ricavo il punto, la tangente, la normale e la curvatura
CrvCompo.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ;
// emetto curvatura o tangente o niente
ArcCurvOrTgOrNone( oDiffG) ;
// se punto con possibili discontinuità
if ( oDiffG.nFlag == CrvPointDiffGeom::TO_VERIFY) {
// ricavo il punto, la tangente, la normale e la curvatura dall'intorno superiore
CrvCompo.GetPointDiffGeom( dU, ICurve::FROM_PLUS, oDiffGs) ;
// se ci sono delle discontinuità
if ( ThereIsDiscontinuity( oDiffG, oDiffGs))
// emetto curvatura o tangente o niente
ArcCurvOrTgOrNone( oDiffGs) ;
}
}
}
return true ;
}