kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #24789
[PATCH 10/12] Convert idf2vrml to use wxApp etc for option processing
From: Cirilo Bernardo <cirilo.bernardo@xxxxxxxxx>
---
utils/idftools/idf2vrml.cpp | 267 +++++++++++++++++++++-----------------------
1 file changed, 126 insertions(+), 141 deletions(-)
diff --git a/utils/idftools/idf2vrml.cpp b/utils/idftools/idf2vrml.cpp
index df66e4b..05e375e 100644
--- a/utils/idftools/idf2vrml.cpp
+++ b/utils/idftools/idf2vrml.cpp
@@ -31,6 +31,11 @@
* would be more likely if we used a 1:1 scale.
*/
+#include <wx/app.h>
+#include <wx/cmdline.h>
+#include <wx/log.h>
+#include <wx/string.h>
+#include <wx/filename.h>
#include <iostream>
#include <iomanip>
@@ -60,15 +65,97 @@
#define MIN_ANG 0.01
#endif
-extern char* optarg;
-extern int optopt;
+class IDF2VRML : public wxAppConsole
+{
+public:
+ virtual bool OnInit();
+ virtual int OnRun();
+ virtual void OnInitCmdLine(wxCmdLineParser& parser);
+ virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
+
+private:
+ double m_ScaleFactor;
+ bool m_Compact;
+ bool m_NoOutlineSubs;
+ wxString m_filename;
+};
-using namespace std;
-using namespace boost;
+static const wxCmdLineEntryDesc cmdLineDesc[] =
+{
+ { wxCMD_LINE_OPTION, "f", NULL, "input file name",
+ wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
+ { wxCMD_LINE_OPTION, "s", NULL, "scale factor",
+ wxCMD_LINE_VAL_DOUBLE, wxCMD_LINE_PARAM_OPTIONAL },
+ { wxCMD_LINE_SWITCH, "k", NULL, "produce KiCad-friendly VRML output; default is compact VRML",
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+ { wxCMD_LINE_SWITCH, "d", NULL, "suppress substitution of default outlines",
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+ { wxCMD_LINE_SWITCH, "z", NULL, "suppress rendering of zero-height outlines",
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+ { wxCMD_LINE_SWITCH, "m", NULL, "print object mapping to stdout for debugging",
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+ { wxCMD_LINE_SWITCH, "h", NULL, "display this message",
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
+ { wxCMD_LINE_NONE }
+};
+
+
+wxIMPLEMENT_APP( IDF2VRML );
+
+bool nozeroheights;
+bool showObjectMapping;
+
+bool IDF2VRML::OnInit()
+{
+ m_ScaleFactor = 1.0;
+ m_Compact = true;
+ m_NoOutlineSubs = false;
+ nozeroheights = false;
+ showObjectMapping = false;
+
+ if( !wxAppConsole::OnInit() )
+ return false;
+
+ return true;
+}
-#define CLEANUP do { \
-setlocale( LC_ALL, "C" ); \
-} while( 0 );
+
+void IDF2VRML::OnInitCmdLine( wxCmdLineParser& parser )
+{
+ parser.SetDesc( cmdLineDesc );
+ parser.SetSwitchChars( "-" );
+ return;
+}
+
+
+bool IDF2VRML::OnCmdLineParsed( wxCmdLineParser& parser )
+{
+ if( parser.Found( "k" ) )
+ m_Compact = false;
+
+ double scale;
+
+ if( parser.Found( "s", &scale ) )
+ m_ScaleFactor = scale;
+
+ wxString fname;
+
+ if( parser.Found( "f", &fname ) )
+ m_filename = fname;
+
+ if( parser.Found( "d" ) )
+ m_NoOutlineSubs = true;
+
+ if( parser.Found( "z" ) )
+ nozeroheights = true;
+
+ if( parser.Found( "m" ) )
+ showObjectMapping = true;
+
+ return true;
+}
+
+using namespace boost;
// define colors
struct VRML_COLOR
@@ -128,22 +215,7 @@ VRML_IDS* GetColor( boost::ptr_map<const std::string, VRML_IDS>& cmap,
int& index, const std::string& uid );
-void PrintUsage( void )
-{
- cout << "-\nUsage: idf2vrml -f input_file.emn -s scale_factor {-k} {-d} {-z} {-m}\n";
- cout << "flags:\n";
- cout << " -k: produce KiCad-friendly VRML output; default is compact VRML\n";
- cout << " -d: suppress substitution of default outlines\n";
- cout << " -z: suppress rendering of zero-height outlines\n";
- cout << " -m: print object mapping to stdout for debugging purposes\n";
- cout << "example to produce a model for use by KiCad: idf2vrml -f input.emn -s 0.3937008 -k\n\n";
- return;
-}
-
-bool nozeroheights;
-bool showObjectMapping;
-
-int main( int argc, char **argv )
+int IDF2VRML::OnRun()
{
// IDF implicitly requires the C locale
setlocale( LC_ALL, "C" );
@@ -158,138 +230,53 @@ int main( int argc, char **argv )
// a KiCad friendly output then we must avoid DEF+USE;
// otherwise we employ DEF+USE to minimize file size
- std::string inputFilename;
- double scaleFactor = 1.0;
- bool compact = true;
- bool nooutlinesubs = false;
- int ichar;
-
- nozeroheights = false;
- showObjectMapping = false;
-
- while( ( ichar = getopt( argc, argv, ":f:s:kdzm" ) ) != -1 )
+ if( m_ScaleFactor < 0.001 || m_ScaleFactor > 10.0 )
{
- switch( ichar )
- {
- case 'f':
- inputFilename = optarg;
- break;
-
- case 's':
- do
- {
- errno = 0;
- char* cp = NULL;
- scaleFactor = strtod( optarg, &cp );
-
- if( errno || cp == optarg )
- {
- cerr << "* invalid scale factor: '" << optarg << "'\n";
- return -1;
- }
-
- if( scaleFactor < 0.001 || scaleFactor > 10 )
- {
- cerr << "* scale factor out of range (" << scaleFactor << "); range is 0.001 to 10.0\n";
- return -1;
- }
-
- } while( 0 );
- break;
-
- case 'k':
- compact = false;
- break;
-
- case 'd':
- nooutlinesubs = true;
- break;
-
- case 'z':
- nozeroheights = true;
- break;
-
- case 'm':
- showObjectMapping = true;
- break;
-
- case ':':
- cerr << "* Missing parameter to option '-" << ((char) optopt) << "'\n";
- PrintUsage();
- return -1;
- break;
-
- default:
- cerr << "* Unexpected option: '-";
-
- if( ichar == '?' )
- cerr << ((char) optopt) << "'\n";
- else
- cerr << ((char) ichar) << "'\n";
-
- PrintUsage();
- return -1;
- break;
- }
- }
-
- if( inputFilename.empty() )
- {
- cerr << "* no IDF filename supplied\n";
- PrintUsage();
+ wxLogMessage("scale factor out of range (%d); range is 0.001 to 10.0", m_ScaleFactor);
return -1;
}
IDF3_BOARD pcb( IDF3::CAD_ELEC );
- cout << "** Reading file: " << inputFilename << "\n";
+ wxLogMessage( "Reading file: '%s'", m_filename );
- if( !pcb.ReadFile( FROM_UTF8( inputFilename.c_str() ), nooutlinesubs ) )
+ if( !pcb.ReadFile( m_filename, m_NoOutlineSubs ) )
{
- cerr << "** Failed to read IDF data:\n";
- cerr << pcb.GetError() << "\n\n";
-
+ wxLogMessage( "Failed to read IDF data: %s", pcb.GetError() );
return -1;
}
// set the scale and output precision ( scale 1 == precision 5)
- pcb.SetUserScale( scaleFactor );
+ pcb.SetUserScale( m_ScaleFactor );
- if( scaleFactor < 0.01 )
+ if( m_ScaleFactor < 0.01 )
pcb.SetUserPrecision( 8 );
- else if( scaleFactor < 0.1 )
+ else if( m_ScaleFactor < 0.1 )
pcb.SetUserPrecision( 7 );
- else if( scaleFactor < 1.0 )
+ else if( m_ScaleFactor < 1.0 )
pcb.SetUserPrecision( 6 );
- else if( scaleFactor < 10.0 )
+ else if( m_ScaleFactor < 10.0 )
pcb.SetUserPrecision( 5 );
else
pcb.SetUserPrecision( 4 );
// Create the VRML file and write the header
- char* bnp = (char*) malloc( inputFilename.size() + 1 );
- strcpy( bnp, inputFilename.c_str() );
-
- std::string fname = basename( bnp );
- free( bnp );
- std::string::iterator itf = fname.end();
- *(--itf) = 'l';
- *(--itf) = 'r';
- *(--itf) = 'w';
-
- cout << "Writing file: '" << fname << "'\n";
+ wxFileName fname( m_filename );
+ fname.SetExt( "wrl" );
+ fname.Normalize();
+ wxLogMessage( "Writing file: '%s'", fname.GetFullName() );
std::ofstream ofile;
- ofile.open( fname.c_str(), std::ios_base::out );
+ ofile.open( fname.GetFullPath().ToUTF8(), std::ios_base::out );
- ofile << fixed; // do not use exponents in VRML output
+ ofile << std::fixed; // do not use exponents in VRML output
WriteHeader( pcb, ofile );
// STEP 1: Render the PCB alone
MakeBoard( pcb, ofile );
// STEP 2: Render the components
- MakeComponents( pcb, ofile, compact );
+ MakeComponents( pcb, ofile, m_Compact );
// STEP 3: Render the OTHER outlines
MakeOtherOutlines( pcb, ofile );
@@ -341,8 +328,7 @@ bool MakeBoard( IDF3_BOARD& board, std::ofstream& file )
if( board.GetBoardOutlinesSize() < 1 )
{
- ERROR_IDF << "\n";
- cerr << "* Cannot proceed; no board outline in IDF object\n";
+ wxLogMessage( "Cannot proceed; no board outline in IDF object" );
return false;
}
@@ -436,14 +422,13 @@ bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items, bo
if( nvcont < 0 )
{
- ERROR_IDF << "\n";
- cerr << "* cannot create an outline\n";
+ wxLogMessage( "Cannot create an outline" );
return false;
}
if( (*scont)->size() < 1 )
{
- ERROR_IDF << "invalid contour: no vertices\n";
+ wxLogMessage( "Invalid contour: no vertices" );
return false;
}
@@ -481,7 +466,7 @@ bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg )
{
if( iseg != 0 )
{
- ERROR_IDF << "adding a circle to an existing vertex list\n";
+ wxLogMessage( "Adding a circle to an existing vertex list" );
return false;
}
@@ -511,7 +496,7 @@ bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool
if( compact && !vID->objectName.empty() )
{
- file << "translation " << setprecision( precision ) << vID->dX;
+ file << "translation " << std::setprecision( precision ) << vID->dX;
file << " " << vID->dY << " ";
if( vID->bottom )
@@ -524,14 +509,14 @@ bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool
tx = cos( M_PI2 - vID->dA / 2.0 );
ty = sin( M_PI2 - vID->dA / 2.0 );
- file << "rotation " << setprecision( precision );
+ file << "rotation " << std::setprecision( precision );
file << tx << " " << ty << " 0 ";
- file << setprecision(5) << M_PI << "\n";
+ file << std::setprecision(5) << M_PI << "\n";
}
else
{
file << vID->dZ << "\n";
- file << "rotation 0 0 1 " << setprecision(5) << vID->dA << "\n";
+ file << "rotation 0 0 1 " << std::setprecision(5) << vID->dA << "\n";
}
file << "children [\n";
@@ -569,7 +554,7 @@ bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool
file << "material Material {\n";
// material definition
- file << "diffuseColor " << setprecision(3) << color->diff[0] << " ";
+ file << "diffuseColor " << std::setprecision(3) << color->diff[0] << " ";
file << color->diff[1] << " " << color->diff[2] << "\n";
file << "specularColor " << color->spec[0] << " " << color->spec[1];
file << " " << color->spec[2] << "\n";
@@ -591,16 +576,16 @@ bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool
{
if( !layer->WriteVertices( top_z, file, precision ) )
{
- cerr << "* errors writing planar vertices to " << vID->objectName << "\n";
- cerr << "** " << layer->GetError() << "\n";
+ wxLogMessage( "Errors writing planar vertices to %s\n%s",
+ vID->objectName, layer->GetError() );
}
}
else
{
if( !layer->Write3DVertices( top_z, bottom_z, file, precision ) )
{
- cerr << "* errors writing 3D vertices to " << vID->objectName << "\n";
- cerr << "** " << layer->GetError() << "\n";
+ wxLogMessage( "Errors writing 3D vertices to %s\n%s",
+ vID->objectName, layer->GetError() );
}
}
@@ -886,7 +871,7 @@ VRML_IDS* GetColor( boost::ptr_map<const std::string, VRML_IDS>& cmap, int& inde
id->objectName = ostr.str();
if( showObjectMapping )
- cout << "* " << ostr.str() << " = '" << uid << "'\n";
+ wxLogMessage( "* %s = '%s'", ostr.str(), uid );
cmap.insert( uid, id );
Follow ups
References
-
[PATCH 00/12] A few well-aged patches
From: Simon Richter, 2016-05-27
-
[PATCH 01/12] Use std::atomic for portable locale init counting
From: Simon Richter, 2016-05-27
-
[PATCH 02/12] Add missing C++ stdlib headers
From: Simon Richter, 2016-05-27
-
[PATCH 03/12] Open namespace around definitions
From: Simon Richter, 2016-05-27
-
[PATCH 04/12] Avoid C99 style compound statement
From: Simon Richter, 2016-05-27
-
[PATCH 05/12] Avoid conflicting declaration for Pgm()
From: Simon Richter, 2016-05-27
-
[PATCH 06/12] Make sure KIFACE_GETTER linkage is consistent
From: Simon Richter, 2016-05-27
-
[PATCH 07/12] Work around VC++ 2015 bug.
From: Simon Richter, 2016-05-27
-
[PATCH 08/12] windows: provide performance measurement primitives
From: Simon Richter, 2016-05-27
-
[PATCH 09/12] Narrow assumption on OpenSSL use
From: Simon Richter, 2016-05-27