//---------------------------------------------------------------------------- // 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 ; }