dedb4f23cf
- migliorata gestione materiale (colore ora caso speciale) - si invalida rappresentazione grafica alla modifica del materiale - spostato comando COUNTER di TSC in EgtGeneral.
512 lines
15 KiB
C++
512 lines
15 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/EgkPoint3d.h"
|
|
#include "/EgtDev/Include/EgkCurveLine.h"
|
|
#include "/EgtDev/Include/EgkCurveArc.h"
|
|
#include "/EgtDev/Include/EgkCurveBezier.h"
|
|
#include "/EgtDev/Include/EgkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.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 ;
|
|
// inizializzo
|
|
m_sMaterial.clear() ;
|
|
m_sPartLay.clear() ;
|
|
// 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( const 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( const 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( const string& sPart, const 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( const string& sPart, const 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::PutCurrRef( void)
|
|
{
|
|
// salvo il materiale corrente
|
|
string sOldMat = m_sMaterial ;
|
|
|
|
// asse X
|
|
SetMaterial( "Red", 1, 0, 0) ;
|
|
Line2P( Point3d( 0,0,0), Point3d( 10,0,0)) ;
|
|
// asse Y
|
|
SetMaterial( "Green", 0, 1, 0) ;
|
|
Line2P( Point3d( 0,0,0), Point3d( 0,10,0)) ;
|
|
// asse Z
|
|
SetMaterial( "Blue", 0, 0, 1) ;
|
|
Line2P( Point3d( 0,0,0), Point3d( 0,0,10)) ;
|
|
|
|
// ripristino il materiale corrente
|
|
m_sMaterial = sOldMat ;
|
|
|
|
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::NormalOrNone( const CrvPointDiffGeom& oDiffG)
|
|
{
|
|
const double NORM_LEN = 10 ;
|
|
|
|
|
|
// normale
|
|
if ( oDiffG.nStatus == CrvPointDiffGeom::NCRV && fabs( oDiffG.dCurv) > EPS_ZERO) {
|
|
double dLen = __min( NORM_LEN, 1 / oDiffG.dCurv) ;
|
|
Line2P( oDiffG.ptP - NORM_LEN * oDiffG.vtN, oDiffG.ptP + dLen * oDiffG.vtN) ;
|
|
}
|
|
// segmento perpendicolare alla tangente
|
|
else if ( oDiffG.nStatus == CrvPointDiffGeom::TANG && ! oDiffG.vtT.IsSmall()) {
|
|
Vector3d vtN = oDiffG.vtT ^ Z_AX ;
|
|
if ( ! vtN.Normalize()) {
|
|
vtN = oDiffG.vtT ^ Y_AX ;
|
|
vtN.Normalize() ;
|
|
}
|
|
Line2P( oDiffG.ptP - NORM_LEN * vtN, oDiffG.ptP + NORM_LEN * vtN) ;
|
|
}
|
|
// altrimenti cerchietto
|
|
else
|
|
CircleCR( oDiffG.ptP, 1) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
OutScl::PutGeoObj( const IGeoObj* pGeoObj, int nFlag)
|
|
{
|
|
if (( pGeoObj->GetType() & GEO_CURVE) != 0) {
|
|
const ICurve* pCurve ;
|
|
// recupero e controllo la curva
|
|
if ( ( pCurve = GetCurve( pGeoObj)) == nullptr)
|
|
return false ;
|
|
// eseguo output
|
|
return PutCurve( pCurve, nFlag) ;
|
|
}
|
|
else
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
OutScl::PutCurve( const ICurve* pCurve, int nFlag)
|
|
{
|
|
bool bFound ;
|
|
PolyLine PL ;
|
|
|
|
|
|
// ciclo per disegnare i segmenti
|
|
Remark( "Curve") ;
|
|
Point3d ptIni ;
|
|
Point3d ptFin ;
|
|
pCurve->ApproxWithLines( 0.1, 5, PL) ;
|
|
for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin))
|
|
Line2P( ptIni, ptFin) ;
|
|
|
|
// se richieste tangenti e curvature
|
|
if ( ( nFlag & 1) != 0) {
|
|
// ciclo per disegnare le derivate e le curvature
|
|
Remark( "Curve:Tangents+Der2") ;
|
|
double dU ;
|
|
for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
|
|
// ricavo il punto, la tangente, la normale e la curvatura
|
|
CrvPointDiffGeom oDiffG ;
|
|
pCurve->GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ;
|
|
// 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
|
|
CrvPointDiffGeom oDiffGs ;
|
|
pCurve->GetPointDiffGeom( dU, ICurve::FROM_PLUS, oDiffGs) ;
|
|
// se ci sono delle discontinuità
|
|
if ( ThereIsDiscontinuity( oDiffG, oDiffGs))
|
|
// emetto curvatura o tangente o niente
|
|
ArcCurvOrTgOrNone( oDiffGs) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// se richieste normali
|
|
if ( ( nFlag & 2) != 0) {
|
|
// ciclo per disegnare le derivate e le curvature
|
|
Remark( "Curve:Normals") ;
|
|
double dU ;
|
|
for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
|
|
// ricavo il punto, la tangente, la normale e la curvatura
|
|
CrvPointDiffGeom oDiffG ;
|
|
pCurve->GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ;
|
|
// curvatura o tangente o niente
|
|
NormalOrNone( 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
|
|
CrvPointDiffGeom oDiffGs ;
|
|
pCurve->GetPointDiffGeom( dU, ICurve::FROM_PLUS, oDiffGs) ;
|
|
// se ci sono delle discontinuità
|
|
if ( ThereIsDiscontinuity( oDiffG, oDiffGs))
|
|
// normale o niente
|
|
NormalOrNone( oDiffGs) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// se curva di Bezier e richiesto anche il poligono di controllo
|
|
if ( pCurve->GetType() == CRV_BEZ && ( nFlag & 4) != 0)
|
|
PutPolygBez( *(GetCurveBezier( pCurve))) ;
|
|
|
|
// se richiesto il box
|
|
if ( ( nFlag & 8) != 0) {
|
|
BBox3d b3B ;
|
|
if ( pCurve->GetLocalBBox( b3B))
|
|
PutBBox( b3B) ;
|
|
}
|
|
|
|
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::PutBBox( const BBox3d& b3B)
|
|
{
|
|
Point3d ptMin ;
|
|
Point3d ptMax ;
|
|
|
|
|
|
if ( b3B.GetMinMax( ptMin, ptMax)) {
|
|
Remark( "BoundingBox") ;
|
|
// giro a Zmin
|
|
Line2P( Point3d( ptMin.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMin.y, ptMin.z)) ;
|
|
Line2P( Point3d( ptMax.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMax.y, ptMin.z)) ;
|
|
Line2P( Point3d( ptMax.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMax.y, ptMin.z)) ;
|
|
Line2P( Point3d( ptMin.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMin.y, ptMin.z)) ;
|
|
// giro a Zmax
|
|
Line2P( Point3d( ptMin.x, ptMin.y, ptMax.z), Point3d( ptMax.x, ptMin.y, ptMax.z)) ;
|
|
Line2P( Point3d( ptMax.x, ptMin.y, ptMax.z), Point3d( ptMax.x, ptMax.y, ptMax.z)) ;
|
|
Line2P( Point3d( ptMax.x, ptMax.y, ptMax.z), Point3d( ptMin.x, ptMax.y, ptMax.z)) ;
|
|
Line2P( Point3d( ptMin.x, ptMax.y, ptMax.z), Point3d( ptMin.x, ptMin.y, ptMax.z)) ;
|
|
// giunzione tra i due giri
|
|
Line2P( Point3d( ptMin.x, ptMin.y, ptMin.z), Point3d( ptMin.x, ptMin.y, ptMax.z)) ;
|
|
Line2P( Point3d( ptMax.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMin.y, ptMax.z)) ;
|
|
Line2P( Point3d( ptMax.x, ptMax.y, ptMin.z), Point3d( ptMax.x, ptMax.y, ptMax.z)) ;
|
|
Line2P( Point3d( ptMin.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMax.y, ptMax.z)) ;
|
|
}
|
|
|
|
return true ;
|
|
} |