Preparing IDF plugin to support EMN/EMP files

This commit is contained in:
Cirilo Bernardo 2015-12-17 14:46:09 +11:00
parent 008d8a540a
commit 879c445b55
2 changed files with 233 additions and 154 deletions

View File

@ -37,6 +37,10 @@
#define PLUGIN_3D_IDF_REVNO 0 #define PLUGIN_3D_IDF_REVNO 0
static SCENEGRAPH* loadIDFOutline( const wxString& aFileName );
static SCENEGRAPH* loadIDFBoard( const wxString& aFileName );
static SGNODE* getColor( IFSG_SHAPE& shape ) static SGNODE* getColor( IFSG_SHAPE& shape )
{ {
IFSG_APPEARANCE material( shape ); IFSG_APPEARANCE material( shape );
@ -146,21 +150,25 @@ void GetPluginVersion( unsigned char* Major,
// number of extensions supported // number of extensions supported
#ifdef _WIN32 #ifdef _WIN32
#define NEXTS 1
#else
#define NEXTS 2 #define NEXTS 2
#else
#define NEXTS 4
#endif #endif
// number of filter sets supported // number of filter sets supported
#define NFILS 1 #define NFILS 2
static char ext0[] = "idf"; static char ext0[] = "idf";
static char ext1[] = "emn";
#ifdef _WIN32 #ifdef _WIN32
static char fil0[] = "IDF 2.0/3.0 (*.idf)|*.idf"; static char fil0[] = "IDF (*.idf)|*.idf";
static char fil0[] = "IDF BRD v2/v3 (*.emn)|*.emn";
#else #else
static char ext1[] = "IDF"; static char ext2[] = "IDF";
static char fil0[] = "IDF 2.0/3.0 (*.idf;*.IDF)|*.idf;*.IDF"; static char ext3[] = "EMN";
static char fil0[] = "IDF (*.idf;*.IDF)|*.idf;*.IDF";
static char fil1[] = "IDF BRD (*.emn;*.EMN)|*.emn;*.EMN";
#endif #endif
static struct FILE_DATA static struct FILE_DATA
@ -171,10 +179,13 @@ static struct FILE_DATA
FILE_DATA() FILE_DATA()
{ {
extensions[0] = ext0; extensions[0] = ext0;
extensions[1] = ext1;
filters[0] = fil0; filters[0] = fil0;
filters[1] = fil1;
#ifndef _WIN32 #ifndef _WIN32
extensions[1] = ext1; extensions[2] = ext2;
extensions[3] = ext3;
#endif #endif
return; return;
@ -183,8 +194,8 @@ static struct FILE_DATA
} file_data; } file_data;
static bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items ); static bool getOutlineModel( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items );
static bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg ); static bool addSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg );
int GetNExtensions( void ) int GetNExtensions( void )
@ -229,10 +240,139 @@ SCENEGRAPH* Load( char const* aFileName )
if( NULL == aFileName ) if( NULL == aFileName )
return NULL; return NULL;
wxFileName fname;
fname.Assign( wxString::FromUTF8Unchecked( aFileName ) );
wxString ext = fname.GetExt();
if( !ext.Cmp( wxT( "idf" ) ) || !ext.Cmp( wxT( "IDF" ) ) )
{
return loadIDFOutline( fname.GetFullPath() );
}
if( !ext.Cmp( wxT( "emn" ) ) || !ext.Cmp( wxT( "EMN" ) ) )
{
return loadIDFBoard( fname.GetFullPath() );
}
return NULL;
}
static bool getOutlineModel( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items )
{
// empty outlines are not unusual so we fail quietly
if( items->size() < 1 )
return false;
int nvcont = 0;
int iseg = 0;
std::list< IDF_OUTLINE* >::const_iterator scont = items->begin();
std::list< IDF_OUTLINE* >::const_iterator econt = items->end();
std::list<IDF_SEGMENT*>::iterator sseg;
std::list<IDF_SEGMENT*>::iterator eseg;
IDF_SEGMENT lseg;
while( scont != econt )
{
nvcont = model.NewContour();
if( nvcont < 0 )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] cannot create an outline\n";
#endif
return false;
}
if( (*scont)->size() < 1 )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] invalid contour: no vertices\n";
#endif
return false;
}
sseg = (*scont)->begin();
eseg = (*scont)->end();
iseg = 0;
while( sseg != eseg )
{
lseg = **sseg;
if( !addSegment( model, &lseg, nvcont, iseg ) )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] cannot add segment\n";
#endif
return false;
}
++iseg;
++sseg;
}
++scont;
}
return true;
}
static bool addSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg )
{
// note: in all cases we must add all but the last point in the segment
// to avoid redundant points
if( seg->angle != 0.0 )
{
if( seg->IsCircle() )
{
if( iseg != 0 )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] adding a circle to an existing vertex list\n";
#endif
return false;
}
return model.AppendCircle( seg->center.x, seg->center.y, seg->radius, icont );
}
else
{
return model.AppendArc( seg->center.x, seg->center.y, seg->radius,
seg->offsetAngle, seg->angle, icont );
}
}
if( !model.AddVertex( icont, seg->startPoint.x, seg->startPoint.y ) )
return false;
return true;
}
static SCENEGRAPH* loadIDFOutline( const wxString& aFileName )
{
// load and render the file // load and render the file
IDF3_BOARD brd( IDF3::CAD_ELEC ); IDF3_BOARD brd( IDF3::CAD_ELEC );
SCENEGRAPH* data = NULL;
try
{
IDF3_COMP_OUTLINE* outline = IDF3_COMP_OUTLINE* outline =
brd.GetComponentOutline( wxString::FromUTF8Unchecked( aFileName ) ); brd.GetComponentOutline( aFileName );
if( NULL == outline ) if( NULL == outline )
{ {
@ -246,7 +386,7 @@ SCENEGRAPH* Load( char const* aFileName )
VRML_LAYER vpcb; VRML_LAYER vpcb;
if( !PopulateVRML( vpcb, outline->GetOutlines() ) ) if( !getOutlineModel( vpcb, outline->GetOutlines() ) )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
@ -356,7 +496,28 @@ SCENEGRAPH* Load( char const* aFileName )
++sidx; ++sidx;
} }
SCENEGRAPH* data = (SCENEGRAPH*)tx0->GetRawPtr(); data = (SCENEGRAPH*)tx0->GetRawPtr();
// delete the API wrappers
delete shape;
delete face;
delete coordIdx;
delete cp;
delete tx0;
}
catch( const IDF_ERROR& e )
{
std::cerr << e.what() << "\n";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] cannot load the outline '" << aFileName.ToUTF8() << "'\n";
return NULL;
}
catch( ... )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] cannot load the outline '" << aFileName.ToUTF8() << "'\n";
return NULL;
}
// DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS // DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS
#ifdef DEBUG #ifdef DEBUG
@ -366,117 +527,12 @@ SCENEGRAPH* Load( char const* aFileName )
S3D::WriteVRML( output, true, (SGNODE*)(data), true, true ); S3D::WriteVRML( output, true, (SGNODE*)(data), true, true );
#endif #endif
// delete the API wrappers
delete shape;
delete face;
delete coordIdx;
delete cp;
delete tx0;
return data; return data;
} }
static bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items ) static SCENEGRAPH* loadIDFBoard( const wxString& aFileName )
{ {
// empty outlines are not unusual so we fail quietly // XXX - TO BE IMPLEMENTED
if( items->size() < 1 ) return NULL;
return false;
int nvcont = 0;
int iseg = 0;
std::list< IDF_OUTLINE* >::const_iterator scont = items->begin();
std::list< IDF_OUTLINE* >::const_iterator econt = items->end();
std::list<IDF_SEGMENT*>::iterator sseg;
std::list<IDF_SEGMENT*>::iterator eseg;
IDF_SEGMENT lseg;
while( scont != econt )
{
nvcont = model.NewContour();
if( nvcont < 0 )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] cannot create an outline\n";
#endif
return false;
}
if( (*scont)->size() < 1 )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] invalid contour: no vertices\n";
#endif
return false;
}
sseg = (*scont)->begin();
eseg = (*scont)->end();
iseg = 0;
while( sseg != eseg )
{
lseg = **sseg;
if( !AddSegment( model, &lseg, nvcont, iseg ) )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] cannot add segment\n";
#endif
return false;
}
++iseg;
++sseg;
}
++scont;
}
return true;
}
static bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg )
{
// note: in all cases we must add all but the last point in the segment
// to avoid redundant points
if( seg->angle != 0.0 )
{
if( seg->IsCircle() )
{
if( iseg != 0 )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] adding a circle to an existing vertex list\n";
#endif
return false;
}
return model.AppendCircle( seg->center.x, seg->center.y, seg->radius, icont );
}
else
{
return model.AppendArc( seg->center.x, seg->center.y, seg->radius,
seg->offsetAngle, seg->angle, icont );
}
}
if( !model.AddVertex( icont, seg->startPoint.x, seg->startPoint.y ) )
return false;
return true;
} }

View File

@ -2724,18 +2724,41 @@ bool IDF3_BOARD::ReadFile( const wxString& aFullFileName, bool aNoSubstituteOutl
wxFileName brdname( aFullFileName ); wxFileName brdname( aFullFileName );
wxFileName libname( aFullFileName ); wxFileName libname( aFullFileName );
wxString ext = brdname.GetExt();
if( !ext.Cmp( "EMN" ) )
{
libname.SetExt( wxT( "EMP" ) );
}
else if( !ext.Cmp( "emn" ) )
{
libname.SetExt( wxT( "emp" ) );
}
else
{
ostringstream ostr;
ostr << "\n* invalid file name: '" << aFullFileName.ToUTF8() << "'";
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
brdname.SetExt( wxT( "emn" ) ); brdname.SetExt( wxT( "emn" ) );
libname.SetExt( wxT( "emp" ) );
std::string bfname = TO_UTF8( aFullFileName ); std::string bfname = TO_UTF8( aFullFileName );
if( !wxFileExists( bfname ) )
{
brdname.SetExt( wxT( "EMN" ) );
libname.SetExt( wxT( "EMP" ) );
}
try try
{ {
if( !brdname.IsOk() ) if( !brdname.IsOk() )
{ {
ostringstream ostr; ostringstream ostr;
ostr << "\n* invalid file name: '" << bfname << "'"; ostr << "\n* invalid file name: '" << aFullFileName.ToUTF8() << "'";
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) ); throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} }
@ -2743,7 +2766,7 @@ bool IDF3_BOARD::ReadFile( const wxString& aFullFileName, bool aNoSubstituteOutl
if( !brdname.FileExists() ) if( !brdname.FileExists() )
{ {
ostringstream ostr; ostringstream ostr;
ostr << "\n* no such file: '" << bfname << "'"; ostr << "\n* no such file: '" << aFullFileName.ToUTF8() << "'";
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) ); throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} }