Refactored to use new generic plugin base

This commit is contained in:
Cirilo Bernardo 2015-12-14 08:45:22 +11:00
parent 86042d86a6
commit 3ff8ca0caf
14 changed files with 1418 additions and 367 deletions

View File

@ -44,145 +44,7 @@
#include "3d_plugin_manager.h" #include "3d_plugin_manager.h"
#include "plugins/3d/3d_plugin.h" #include "plugins/3d/3d_plugin.h"
#include "3d_cache/sg/scenegraph.h" #include "3d_cache/sg/scenegraph.h"
#include "plugins/ldr/3d/pluginldr3D.h"
class S3D_PLUGIN_ITEM
{
private:
#ifdef _WIN32
HMODULE m_dlHandle;
#else
void* m_dlHandle; // handle to the opened plugin
#endif
S3D_PLUGIN* m_plugin; // pointer to an instance
wxString m_pluginName; // plugin name
public:
S3D_PLUGIN_ITEM( const wxString& aPluginPath );
~S3D_PLUGIN_ITEM();
bool Open( void );
void Close( void );
S3D_PLUGIN* GetPlugin( void );
const wxString GetPluginName( void );
};
S3D_PLUGIN_ITEM::S3D_PLUGIN_ITEM( const wxString& aPluginPath )
{
m_pluginName = aPluginPath;
m_dlHandle = NULL;
m_plugin = NULL;
return;
}
S3D_PLUGIN_ITEM::~S3D_PLUGIN_ITEM()
{
Close();
}
bool S3D_PLUGIN_ITEM::Open( void )
{
if( NULL != m_dlHandle )
return true;
if( m_pluginName.IsEmpty() )
return false;
m_plugin = NULL;
#ifdef _WIN32
// NOTE: MSWin uses UTF-16 encoding
#if defined( UNICODE ) || defined( _UNICODE )
m_dlHandle = LoadLibrary( m_pluginName.wc_str() );
#else
m_dlHandle = LoadLibrary( m_pluginName.ToUTF8() );
#endif
#else
m_dlHandle = dlopen( m_pluginName.ToUTF8(), RTLD_LAZY | RTLD_LOCAL );
#endif
if( NULL == m_dlHandle )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * could not open file: '" << m_pluginName.ToUTF8() << "'\n";
return false;
}
else
{
#ifdef _WIN32
typedef S3D_PLUGIN* (*pPLUGIN)( void );
pPLUGIN Get3DPlugin = (pPLUGIN) GetProcAddress( m_dlHandle, "Get3DPlugin" );
#else
S3D_PLUGIN* (*Get3DPlugin)( void );
*(void **) (&Get3DPlugin) = dlsym( m_dlHandle, "Get3DPlugin" );
#endif
if( NULL == Get3DPlugin )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
#ifdef _WIN32
std::cerr << " * [INFO] could not find symbol\n";
#else
char* err = dlerror();
std::cerr << " * [INFO] could not find symbol: '" << err << "'\n";
#endif
}
else
{
// set the 3D Model Plugin object
m_plugin = (*Get3DPlugin)();
return true;
}
}
#ifdef _WIN32
FreeLibrary( m_dlHandle );
#else
dlclose( m_dlHandle );
#endif
m_dlHandle = NULL;
return false;
}
void S3D_PLUGIN_ITEM::Close( void )
{
m_plugin = NULL;
if( m_dlHandle )
{
#ifdef _WIN32
FreeLibrary( m_dlHandle );
#else
dlclose( m_dlHandle );
#endif
m_dlHandle = NULL;
}
return;
}
S3D_PLUGIN* S3D_PLUGIN_ITEM::GetPlugin( void )
{
if( NULL == m_plugin && !Open() )
return NULL;
return m_plugin;
}
const wxString S3D_PLUGIN_ITEM::GetPluginName( void )
{
return m_pluginName;
}
S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER() S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
{ {
@ -195,14 +57,14 @@ S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
#ifdef DEBUG #ifdef DEBUG
if( !m_ExtMap.empty() ) if( !m_ExtMap.empty() )
{ {
std::multimap< const wxString, S3D_PLUGIN_ITEM* >::const_iterator sM = m_ExtMap.begin(); std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::const_iterator sM = m_ExtMap.begin();
std::multimap< const wxString, S3D_PLUGIN_ITEM* >::const_iterator eM = m_ExtMap.end(); std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::const_iterator eM = m_ExtMap.end();
std::cout << "* Extension [plugin name]:\n"; std::cout << "* Extension [plugin name]:\n";
while( sM != eM ) while( sM != eM )
{ {
std::cout << " + '" << sM->first.ToUTF8() << "' ["; std::cout << " + '" << sM->first.ToUTF8() << "' [";
std::cout << sM->second->GetPluginName().ToUTF8() << "]\n"; std::cout << sM->second->GetKicadPluginName() << "]\n";
++sM; ++sM;
} }
@ -239,8 +101,8 @@ S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
S3D_PLUGIN_MANAGER::~S3D_PLUGIN_MANAGER() S3D_PLUGIN_MANAGER::~S3D_PLUGIN_MANAGER()
{ {
std::list< S3D_PLUGIN_ITEM* >::iterator sP = m_Plugins.begin(); std::list< KICAD_PLUGIN_LDR_3D* >::iterator sP = m_Plugins.begin();
std::list< S3D_PLUGIN_ITEM* >::iterator eP = m_Plugins.end(); std::list< KICAD_PLUGIN_LDR_3D* >::iterator eP = m_Plugins.end();
while( sP != eP ) while( sP != eP )
{ {
@ -271,6 +133,7 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() ); std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
checkPluginPath( testpath, searchpaths ); checkPluginPath( testpath, searchpaths );
#endif #endif
fn.Assign( wxStandardPaths::Get().GetPluginsDir() ); fn.Assign( wxStandardPaths::Get().GetPluginsDir() );
fn.AppendDir( wxT( "kicad" ) ); fn.AppendDir( wxT( "kicad" ) );
fn.AppendDir( wxT( "plugins" ) ); fn.AppendDir( wxT( "plugins" ) );
@ -321,27 +184,28 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
while( sPL != ePL ) while( sPL != ePL )
{ {
S3D_PLUGIN_ITEM* pp = new S3D_PLUGIN_ITEM( *sPL ); KICAD_PLUGIN_LDR_3D* pp = new KICAD_PLUGIN_LDR_3D;
if( pp ) if( pp->Open( sPL->ToUTF8() ) )
{
if( pp->Open() )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n"; std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n";
std::cout << "* [DEBUG] adding plugin\n"; std::cout << "* [DEBUG] adding plugin\n";
#endif #endif
m_Plugins.push_back( pp ); m_Plugins.push_back( pp );
int nf = pp->GetNFilters();
S3D_PLUGIN* lpp = pp->GetPlugin(); #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
if( lpp ) std::cerr << " * [INFO] adding " << nf << " filters\n";
{ #endif
int nf = lpp->GetNFilters();
for( int i = 0; i < nf; ++i ) for( int i = 0; i < nf; ++i )
addFilterString( lpp->GetFileFilter( i ) ); {
char const* cp = pp->GetFileFilter( i );
if( cp )
addFilterString( wxString::FromUTF8Unchecked( cp ) );
} }
addExtensionMap( pp ); addExtensionMap( pp );
@ -357,7 +221,6 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
#endif #endif
delete pp; delete pp;
} }
}
++sPL; ++sPL;
} }
@ -523,26 +386,30 @@ void S3D_PLUGIN_MANAGER::addFilterString( const wxString& aFilterString )
} }
void S3D_PLUGIN_MANAGER::addExtensionMap( S3D_PLUGIN_ITEM* aPlugin ) void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin )
{ {
// add entries to the extension map // add entries to the extension map
if( NULL == aPlugin ) if( NULL == aPlugin )
return; return;
S3D_PLUGIN* pp = aPlugin->GetPlugin(); int nExt = aPlugin->GetNExtensions();
if( NULL == pp ) #ifdef DEBUG
return; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] adding " << nExt << " extensions\n";
int nExt = pp->GetNExtensions(); #endif
for( int i = 0; i < nExt; ++i ) for( int i = 0; i < nExt; ++i )
{ {
wxString ws = pp->GetModelExtension( i ); char const* cp = aPlugin->GetModelExtension( i );
wxString ws;
if( cp )
ws = wxString::FromUTF8Unchecked( cp );
if( !ws.empty() ) if( !ws.empty() )
{ {
m_ExtMap.insert( std::pair< const wxString, S3D_PLUGIN_ITEM* >( ws, aPlugin ) ); m_ExtMap.insert( std::pair< const wxString, KICAD_PLUGIN_LDR_3D* >( ws, aPlugin ) );
} }
} }
@ -562,19 +429,17 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName )
wxFileName raw( aFileName ); wxFileName raw( aFileName );
wxString ext = raw.GetExt(); wxString ext = raw.GetExt();
std::pair < std::multimap< const wxString, S3D_PLUGIN_ITEM* >::iterator, std::pair < std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator,
std::multimap< const wxString, S3D_PLUGIN_ITEM* >::iterator > items; std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator > items;
items = m_ExtMap.equal_range( ext ); items = m_ExtMap.equal_range( ext );
std::multimap< const wxString, S3D_PLUGIN_ITEM* >::iterator sL = items.first; std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator sL = items.first;
while( sL != items.second ) while( sL != items.second )
{ {
S3D_PLUGIN* pplug = sL->second->GetPlugin(); if( sL->second->CanRender() )
if( NULL != pplug && pplug->CanRender() )
{ {
SCENEGRAPH* sp = pplug->Load( aFileName ); SCENEGRAPH* sp = sL->second->Load( aFileName );
if( NULL != sp ) if( NULL != sp )
return sp; return sp;
@ -589,8 +454,13 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName )
void S3D_PLUGIN_MANAGER::ClosePlugins( void ) void S3D_PLUGIN_MANAGER::ClosePlugins( void )
{ {
std::list< S3D_PLUGIN_ITEM* >::iterator sP = m_Plugins.begin(); std::list< KICAD_PLUGIN_LDR_3D* >::iterator sP = m_Plugins.begin();
std::list< S3D_PLUGIN_ITEM* >::iterator eP = m_Plugins.end(); std::list< KICAD_PLUGIN_LDR_3D* >::iterator eP = m_Plugins.end();
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] closing " << m_Plugins.size() << " plugins\n";
#endif
while( sP != eP ) while( sP != eP )
{ {

View File

@ -34,7 +34,7 @@
#include <wx/string.h> #include <wx/string.h>
class wxWindow; class wxWindow;
class S3D_PLUGIN_ITEM; class KICAD_PLUGIN_LDR_3D;
struct S3D_INFO; struct S3D_INFO;
class SCENEGRAPH; class SCENEGRAPH;
@ -42,10 +42,10 @@ class S3D_PLUGIN_MANAGER
{ {
private: private:
/// list of discovered plugins /// list of discovered plugins
std::list< S3D_PLUGIN_ITEM* > m_Plugins; std::list< KICAD_PLUGIN_LDR_3D* > m_Plugins;
/// mapping of extensions to available plugins /// mapping of extensions to available plugins
std::multimap< const wxString, S3D_PLUGIN_ITEM* > m_ExtMap; std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* > m_ExtMap;
/// list of file filters /// list of file filters
std::list< wxString > m_FileFilters; std::list< wxString > m_FileFilters;
@ -66,7 +66,7 @@ private:
void addFilterString( const wxString& aFilterString ); void addFilterString( const wxString& aFilterString );
/// add entries to the extension map /// add entries to the extension map
void addExtensionMap( S3D_PLUGIN_ITEM* aPlugin ); void addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin );
public: public:
S3D_PLUGIN_MANAGER(); S3D_PLUGIN_MANAGER();

View File

@ -12,6 +12,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/include/gal/opengl ${CMAKE_SOURCE_DIR}/include/gal/opengl
${GLEW_INCLUDE_DIR} ${GLEW_INCLUDE_DIR}
${GLM_INCLUDE_DIR} ${GLM_INCLUDE_DIR}
${CMAKE_SOURCE_DIR}
${INC_AFTER} ${INC_AFTER}
) )
@ -21,6 +22,7 @@ set( DIR_RAY 3d_rendering/3d_render_raytracing )
set( DIR_RAY_ACC ${DIR_RAY}/accelerators ) set( DIR_RAY_ACC ${DIR_RAY}/accelerators )
set( DIR_RAY_2D ${DIR_RAY}/shapes2D ) set( DIR_RAY_2D ${DIR_RAY}/shapes2D )
set( DIR_RAY_3D ${DIR_RAY}/shapes3D ) set( DIR_RAY_3D ${DIR_RAY}/shapes3D )
set( DIR_3D_PLUGINS ${CMAKE_SOURCE_DIR}/plugins/ldr )
set(3D-VIEWER_SRCS set(3D-VIEWER_SRCS
dialogs/dialog_3D_view_option_base.cpp dialogs/dialog_3D_view_option_base.cpp
@ -45,6 +47,8 @@ set(3D-VIEWER_SRCS
vrml_v2_modelparser.cpp vrml_v2_modelparser.cpp
x3dmodelparser.cpp x3dmodelparser.cpp
CImage.cpp CImage.cpp
${DIR_3D_PLUGINS}/pluginldr.cpp
${DIR_3D_PLUGINS}/3d/pluginldr3D.cpp
3d_cache/3d_cache_wrapper.cpp 3d_cache/3d_cache_wrapper.cpp
3d_cache/3d_cache.cpp 3d_cache/3d_cache.cpp
3d_cache/3d_plugin_manager.cpp 3d_cache/3d_plugin_manager.cpp

View File

@ -30,24 +30,65 @@
#ifndef PLUGIN_3D_H #ifndef PLUGIN_3D_H
#define PLUGIN_3D_H #define PLUGIN_3D_H
#include <wx/string.h> //
// KICAD_PLUGIN CLASS INTERFACE
//
// WARNING: DO NOT EDIT THIS FILE OUTSIDE THE KICAD TREE
//
class SCENEGRAPH; // Note: the plugin class name must match the name expected by the loader
#define KICAD_PLUGIN_CLASS "PLUGIN_3D"
#define MAJOR 1
#define MINOR 0
#define REVISION 0
#define PATCH 0
class S3D_PLUGIN #include "../kicad_plugin.h"
KICAD_PLUGIN_EXPORT char const* GetKicadPluginClass( void )
{ {
public: return KICAD_PLUGIN_CLASS;
virtual ~S3D_PLUGIN() }
KICAD_PLUGIN_EXPORT void GetClassVersion( unsigned char* Major,
unsigned char* Minor, unsigned char* Revision, unsigned char* Patch )
{ {
if( Major )
*Major = MAJOR;
if( Minor )
*Minor = MINOR;
if( Revision )
*Revision = REVISION;
if( Patch )
*Patch = PATCH;
return; return;
} }
KICAD_PLUGIN_EXPORT bool CheckClassVersion( unsigned char Major,
unsigned char Minor, unsigned char Revision, unsigned char Patch )
{
if( Major != MAJOR )
return false;
// at the moment there are no incompatibility rules other than the Major Version check
return true;
}
class SCENEGRAPH;
/** /**
* Function GetNExtensions * Function GetNExtensions
* *
* @return the number of extensions supported by the plugin * @return the number of extensions supported by the plugin
*/ */
virtual int GetNExtensions( void ) const = 0; KICAD_PLUGIN_EXPORT int GetNExtensions( void );
/** /**
* Function GetModelExtension * Function GetModelExtension
@ -57,20 +98,20 @@ public:
* @return the requested extension or a null string if aIndex * @return the requested extension or a null string if aIndex
* was invalid. * was invalid.
*/ */
virtual const wxString GetModelExtension( int aIndex ) const = 0; KICAD_PLUGIN_EXPORT char const* GetModelExtension( int aIndex );
/** /**
* Function GetNFilters * Function GetNFilters
* @returns the number of file filters * @returns the number of file filters
*/ */
virtual int GetNFilters( void ) const = 0; KICAD_PLUGIN_EXPORT int GetNFilters( void );
/** /**
* Function GetFileFilter * Function GetFileFilter
* *
* @return the file filter string for the given index * @return the file filter string for the given index
*/ */
virtual const wxString GetFileFilter( int aIndex ) const = 0; KICAD_PLUGIN_EXPORT char const* GetFileFilter( int aIndex );
/** /**
* Function CanRender * Function CanRender
@ -78,7 +119,7 @@ public:
* @return true if the plugin can render a model, that is * @return true if the plugin can render a model, that is
* the Load() function is implemented * the Load() function is implemented
*/ */
virtual bool CanRender( void ) const = 0; KICAD_PLUGIN_EXPORT bool CanRender( void );
/** /**
* Function Load * Function Load
@ -92,7 +133,6 @@ public:
* if there is no rendering support for the model or there were * if there is no rendering support for the model or there were
* problems reading the model * problems reading the model
*/ */
virtual SCENEGRAPH* Load( const wxString& aFileName ) = 0; KICAD_PLUGIN_EXPORT SCENEGRAPH* Load( char const* aFileName );
};
#endif // PLUGIN_3D_H #endif // PLUGIN_3D_H

View File

@ -0,0 +1,112 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file kicad_plugin.h
* defines the most basic functions which all kicad plugins must implement.
* In the implementation the definitions must make use of the KICAD_PLUGIN_EXPORT
* to ensure symbol visibility.
*/
#ifndef KICAD_PLUGIN_H
#define KICAD_PLUGIN_H
#ifndef _WIN32
#ifndef KICAD_PLUGIN_EXPORT
#define KICAD_PLUGIN_EXPORT extern "C" __attribute__((__visibility__("default")))
#endif
#else
#include <cstdint>
#ifndef KICAD_PLUGIN_EXPORT
#define KICAD_PLUGIN_EXPORT extern "C" __declspec( dllexport )
#endif
#endif
/**
* Function GetKicadPluginClass
* returns the name of the implemented plugin class; for
* example 3DPLUGIN. This should be implemented in a source
* module which is compiled as part of every implementation
* of a specific plugin class.
*
* @return is the NULL-terminated UTF-8 string representing the
* plugin class
*/
KICAD_PLUGIN_EXPORT char const* GetKicadPluginClass( void );
/**
* Function GetClassVersion
* retrieves the version of the Plugin Class. This value is used to
* ensure API compatibility of a plugin as per typical practice. This must
* be implemented in a source module which is compiled as part of every
* implementation of a specific plugin class
*
* @param Major will hold the Plugin Class Major version
* @param Minor will hold the Plugin Class Minor version
* @param Revision will hold the Plugin Class Revision
* @param Patch will hold the Plugin Class Patch level
*/
KICAD_PLUGIN_EXPORT void GetClassVersion( unsigned char* Major,
unsigned char* Minor, unsigned char* Revision, unsigned char* Patch );
/**
* Function CheckClassVersion
* returns true if the class version reported by the Plugin Loader
* is compatible with the specific implementation of a plugin.
* This function must be defined by each specific plugin and it is
* the plugin developer's responsibility to ensure that the Plugin
* is in fact compatible with the Plugin Loader. The Plugin Loader
* shall reject any Plugin with a different Major number regardless
* of the return value of this function.
*/
KICAD_PLUGIN_EXPORT bool CheckClassVersion( unsigned char Major,
unsigned char Minor, unsigned char Revision, unsigned char Patch );
/**
* Function GetKicadPluginName
* returns the name of the plugin instance; for example IDFv3.
* This string may be used to check for name conflicts or to
* display informational messages about loaded plugins. This method
* must be implemented in specific instantiations of a plugin class.
*
* @return is the NULL-terminated UTF-8 string representing the
* plugin name
*/
KICAD_PLUGIN_EXPORT const char* GetKicadPluginName( void );
/**
* Function GetVersion
* retrieves the version of the instantiated plugin for informational
* purposes. Do not confuse this with GetAPIVersion which is used to
* determine API compatibility.
*
* @param Major will hold the Plugin Major version
* @param Minor will hold the Plugin Minor version
* @param Revision will hold the Plugin Revision
* @param Patch will hold the Plugin Patch level
*/
KICAD_PLUGIN_EXPORT void GetVersion( unsigned char* Major,
unsigned char* Minor, unsigned char* Revision, unsigned char* Patch );
#endif // KICAD_PLUGIN_H

View File

@ -1,3 +1,3 @@
add_subdirectory( dummy ) #add_subdirectory( dummy )
add_subdirectory( tetra ) #add_subdirectory( tetra )
add_subdirectory( idf ) add_subdirectory( idf )

View File

@ -25,105 +25,138 @@
#include <cmath> #include <cmath>
#include <string> #include <string>
#include <map> #include <map>
#include "s3d_plugin_idf.h" #include <wx/string.h>
#include "plugins/3d/3d_plugin.h"
#include "plugins/3dapi/ifsg_all.h" #include "plugins/3dapi/ifsg_all.h"
#include "idf_parser.h" #include "idf_parser.h"
#include "vrml_layer.h" #include "vrml_layer.h"
#define PLUGIN_3D_IDF_MAJOR 1
#define PLUGIN_3D_IDF_MINOR 0
#define PLUGIN_3D_IDF_REVNO 0
#define PLUGIN_3D_IDF_PATCH 0
static S3D_PLUGIN_IDF idf_plugin;
KICAD_PLUGIN_EXPORT const char* GetKicadPluginName( void )
{
return "PLUGIN_3D_IDF";
}
KICAD_PLUGIN_EXPORT void GetVersion( unsigned char* Major,
unsigned char* Minor, unsigned char* Revision, unsigned char* Patch )
{
if( Major )
*Major = PLUGIN_3D_IDF_MAJOR;
if( Minor )
*Minor = PLUGIN_3D_IDF_MINOR;
if( Revision )
*Revision = PLUGIN_3D_IDF_REVNO;
if( Patch )
*Patch = PLUGIN_3D_IDF_PATCH;
return;
}
// number of extensions supported
#ifdef _WIN32
#define NEXTS 1
#else
#define NEXTS 2
#endif
// number of filter sets supported
#define NFILS 1
static char ext0[] = "idf";
static char fil0[] = "IDF 2.0/3.0 (*.idf)|*.idf";
#ifndef _WIN32 #ifndef _WIN32
extern "C" __attribute__((__visibility__("default"))) S3D_PLUGIN* Get3DPlugin( void ) static char ext1[] = "IDF";
{ static char fil1[] = "IDF 2.0/3.0 (*.idf;*.IDF)|*.idf;*.IDF";
return &idf_plugin;
}
#else
extern "C" __declspec( dllexport ) S3D_PLUGIN* Get3DPlugin( void )
{
return &idf_plugin;
}
#endif #endif
static struct FILE_DATA
{
char const* extensions[NEXTS];
char const* filters[NFILS];
FILE_DATA()
{
extensions[0] = ext0;
filters[0] = fil0;
#ifndef _WIN32
extensions[1] = ext1;
filters[1] = fil1;
#endif
return;
}
} file_data;
static bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items ); static bool PopulateVRML( 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 );
S3D_PLUGIN_IDF::S3D_PLUGIN_IDF() KICAD_PLUGIN_EXPORT int GetNExtensions( void )
{ {
m_extensions.push_back( wxString::FromUTF8Unchecked( "idf" ) ); return NEXTS;
#ifdef _WIN32
// assume a case-insensitive file system
m_filters.push_back( wxT( "IDF 2.0/3.0 (*.idf)|*.idf" ) );
#else
// assume the filesystem is case sensitive
m_extensions.push_back( wxString::FromUTF8Unchecked( "IDF" ) );
m_filters.push_back( wxT( "IDF 2.0/3.0 (*.idf;*.IDF)|*.idf;*.IDF" ) );
#endif
return;
} }
S3D_PLUGIN_IDF::~S3D_PLUGIN_IDF() KICAD_PLUGIN_EXPORT char const* GetModelExtension( int aIndex )
{ {
return; if( aIndex < 0 || aIndex >= NEXTS )
return NULL;
return file_data.extensions[aIndex];
} }
int S3D_PLUGIN_IDF::GetNExtensions( void ) const KICAD_PLUGIN_EXPORT int GetNFilters( void )
{ {
return (int) m_extensions.size(); return NFILS;
} }
const wxString S3D_PLUGIN_IDF::GetModelExtension( int aIndex ) const KICAD_PLUGIN_EXPORT char const* GetFileFilter( int aIndex )
{ {
if( aIndex < 0 || aIndex >= (int) m_extensions.size() ) if( aIndex < 0 || aIndex >= NFILS )
return wxString( "" ); return NULL;
return m_extensions[aIndex]; return file_data.filters[aIndex];
} }
int S3D_PLUGIN_IDF::GetNFilters( void ) const KICAD_PLUGIN_EXPORT bool CanRender( void )
{
return (int)m_filters.size();
}
const wxString S3D_PLUGIN_IDF::GetFileFilter( int aIndex ) const
{
if( aIndex < 0 || aIndex >= (int)m_filters.size() )
return wxEmptyString;
return m_filters[aIndex];
}
bool S3D_PLUGIN_IDF::CanRender( void ) const
{ {
// this plugin supports rendering of IDF component outlines // this plugin supports rendering of IDF component outlines
return true; return true;
} }
SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName ) KICAD_PLUGIN_EXPORT SCENEGRAPH* Load( char const* aFileName )
{ {
if( NULL == aFileName )
return NULL;
// load and render the file // load and render the file
IDF3_BOARD brd( IDF3::CAD_ELEC ); IDF3_BOARD brd( IDF3::CAD_ELEC );
IDF3_COMP_OUTLINE* outline = brd.GetComponentOutline( aFileName ); IDF3_COMP_OUTLINE* outline =
brd.GetComponentOutline( wxString::FromUTF8Unchecked( aFileName ) );
if( NULL == outline ) if( NULL == outline )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] no outline for file '"; std::cerr << " * [INFO] no outline for file '";
std::cerr << aFileName.ToUTF8() << "'\n"; std::cerr << aFileName << "'\n";
#endif #endif
return NULL; return NULL;
} }
@ -135,7 +168,7 @@ SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName )
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] no valid outline data in '"; std::cerr << " * [INFO] no valid outline data in '";
std::cerr << aFileName.ToUTF8() << "'\n"; std::cerr << aFileName << "'\n";
#endif #endif
return NULL; return NULL;
} }
@ -150,12 +183,11 @@ SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName )
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] no vertex data in '"; std::cerr << " * [INFO] no vertex data in '";
std::cerr << aFileName.ToUTF8() << "'\n"; std::cerr << aFileName << "'\n";
#endif #endif
return NULL; return NULL;
} }
std::cerr << "XXX - Got " << vertices.size() / 3 << " vertices and " << indices.size() << " indices\n";
std::vector< SGPOINT > vlist; std::vector< SGPOINT > vlist;
size_t nvert = vertices.size() / 3; size_t nvert = vertices.size() / 3;
size_t j = 0; size_t j = 0;

View File

@ -1,57 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file 3d_plugin_idf.h
* is a 3D plugin to support the rendering of IDF component outlines
*/
#ifndef PLUGIN_3D_IDF_H
#define PLUGIN_3D_IDF_H
#include <vector>
#include <plugins/3d/3d_plugin.h>
class SCENEGRAPH;
class S3D_PLUGIN_IDF : public S3D_PLUGIN
{
private:
std::vector< wxString > m_extensions; // supported extensions
std::vector< wxString > m_filters; // file filters
public:
S3D_PLUGIN_IDF();
virtual ~S3D_PLUGIN_IDF();
virtual int GetNExtensions( void ) const;
virtual const wxString GetModelExtension( int aIndex ) const;
virtual int GetNFilters( void ) const;
virtual const wxString GetFileFilter( int aIndex ) const;
bool CanRender( void ) const;
SCENEGRAPH* Load( const wxString& aFileName );
};
#endif // PLUGIN_3D_IDF_H

View File

@ -0,0 +1,364 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sstream>
#include <iostream>
#include "plugins/ldr/3d/pluginldr3D.h"
#define PLUGIN_CLASS_3D "PLUGIN_3D"
#define PLUGIN_3D_MAJOR 1
#define PLUGIN_3D_MINOR 0
#define PLUGIN_3D_REVISION 0
#define PLUGIN_3D_PATCH 0
KICAD_PLUGIN_LDR_3D::KICAD_PLUGIN_LDR_3D()
{
ok = false;
m_getNExtensions = NULL;
m_getModelExtension = NULL;
m_getNFilters = NULL;
m_getFileFilter = NULL;
m_canRender = NULL;
m_load = NULL;
return;
}
KICAD_PLUGIN_LDR_3D::~KICAD_PLUGIN_LDR_3D()
{
Close();
return;
}
bool KICAD_PLUGIN_LDR_3D::Open( const wxString& aFullFileName )
{
m_error.clear();
if( ok )
Close();
if( !open( aFullFileName, PLUGIN_CLASS_3D ) )
{
if( m_error.empty() )
{
std::ostringstream ostr;
ostr << "Failed to open plugin '" << aFullFileName.ToUTF8() << "'";
m_error = ostr.str();
}
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] failed on file " << aFullFileName.ToUTF8() << "\n";
std::cerr << " * [INFO] error: " << m_error << "\n";
#endif
return false;
}
// the version checks passed and the base KICAD_PLUGIN functions have been linked;
// now we link the remaining functions expected by PLUGIN_3D and confirm that the
// plugin is loaded
LINK_ITEM( m_getNExtensions, PLUGIN_3D_GET_N_EXTENSIONS, "GetNExtensions" );
LINK_ITEM( m_getModelExtension, PLUGIN_3D_GET_MODEL_EXTENSION, "GetModelExtension" );
LINK_ITEM( m_getNFilters, PLUGIN_3D_GET_N_FILTERS, "GetNFilters" );
LINK_ITEM( m_getFileFilter, PLUGIN_3D_GET_FILE_FILTER, "GetFileFilter" );
LINK_ITEM( m_canRender, PLUGIN_3D_CAN_RENDER, "CanRender" );
LINK_ITEM( m_load, PLUGIN_3D_LOAD, "Load" );
#ifdef DEBUG
bool fail = false;
if( !m_getNExtensions )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
std::cerr << " * missing function: GetNExtensions\n";
fail = true;
}
if( !m_getModelExtension )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: GetModelExtension\n";
}
if( !m_getNFilters )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: GetNFilters\n";
}
if( !m_getFileFilter )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: GetFileFilter\n";
}
if( !m_canRender )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: CanRender\n";
}
if( !m_load )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: Load\n";
}
#endif
if( !m_getNExtensions || !m_getModelExtension || !m_getNFilters
|| !m_getFileFilter || !m_canRender || !m_load )
{
Close();
std::ostringstream ostr;
ostr << "Failed to open plugin '" << aFullFileName.ToUTF8() << "'; missing functions";
m_error = ostr.str();
return false;
}
ok = true;
return true;
}
void KICAD_PLUGIN_LDR_3D::Close( void )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] closing plugin\n";
#endif
ok = false;
m_getNExtensions = NULL;
m_getModelExtension = NULL;
m_getNFilters = NULL;
m_getFileFilter = NULL;
m_canRender = NULL;
m_load = NULL;
close();
return;
}
void KICAD_PLUGIN_LDR_3D::GetLoaderVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch ) const
{
if( Major )
*Major = PLUGIN_3D_MAJOR;
if( Minor )
*Minor = PLUGIN_3D_MINOR;
if( Revision )
*Revision = PLUGIN_3D_REVISION;
if( Patch )
*Patch = PLUGIN_3D_PATCH;
return;
}
// these functions are shadows of the 3D Plugin functions from 3d_plugin.h
int KICAD_PLUGIN_LDR_3D::GetNExtensions( void )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return 0;
}
if( NULL == m_getNExtensions )
{
m_error = "[BUG] GetNExtensions is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return 0;
}
return m_getNExtensions();
}
char const* KICAD_PLUGIN_LDR_3D::GetModelExtension( int aIndex )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return NULL;
}
if( NULL == m_getModelExtension )
{
m_error = "[BUG] GetModelExtension is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return NULL;
}
return m_getModelExtension( aIndex );
}
int KICAD_PLUGIN_LDR_3D::GetNFilters( void )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return 0;
}
if( NULL == m_getNFilters )
{
m_error = "[BUG] GetNFilters is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return 0;
}
int n = m_getNFilters();
return m_getNFilters();
}
char const* KICAD_PLUGIN_LDR_3D::GetFileFilter( int aIndex )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return NULL;
}
if( NULL == m_getFileFilter )
{
m_error = "[BUG] GetFileFilter is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return NULL;
}
return m_getFileFilter( aIndex );
}
bool KICAD_PLUGIN_LDR_3D::CanRender( void )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return false;
}
if( NULL == m_canRender )
{
m_error = "[BUG] CanRender is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return false;
}
return m_canRender();
}
SCENEGRAPH* KICAD_PLUGIN_LDR_3D::Load( char const* aFileName )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return NULL;
}
if( NULL == m_load )
{
m_error = "[BUG] Load is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return NULL;
}
return m_load( aFileName );
}

View File

@ -0,0 +1,90 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file pluginldr.h
* defines the most basic functions which all kicad plugin loaders require.
*/
#ifndef PLUGINLDR3D_H
#define PLUGINLDR3D_H
#include "../pluginldr.h"
class SCENEGRAPH;
// typedefs of the functions exported by the 3D Plugin Class
typedef int (*PLUGIN_3D_GET_N_EXTENSIONS) ( void );
typedef char const* (*PLUGIN_3D_GET_MODEL_EXTENSION) ( int aIndex );
typedef int (*PLUGIN_3D_GET_N_FILTERS) ( void );
typedef char const* (*PLUGIN_3D_GET_FILE_FILTER) ( int aIndex );
typedef bool (*PLUGIN_3D_CAN_RENDER) ( void );
typedef SCENEGRAPH* (*PLUGIN_3D_LOAD) ( char const* aFileName );
class KICAD_PLUGIN_LDR_3D : public KICAD_PLUGIN_LDR
{
private:
bool ok; // set TRUE if all functions are linked
PLUGIN_3D_GET_N_EXTENSIONS m_getNExtensions;
PLUGIN_3D_GET_MODEL_EXTENSION m_getModelExtension;
PLUGIN_3D_GET_N_FILTERS m_getNFilters;
PLUGIN_3D_GET_FILE_FILTER m_getFileFilter;
PLUGIN_3D_CAN_RENDER m_canRender;
PLUGIN_3D_LOAD m_load;
public:
KICAD_PLUGIN_LDR_3D();
virtual ~KICAD_PLUGIN_LDR_3D();
// virtuals inherited from KICAD_PLUGIN_LDR
bool Open( const wxString& aFullFileName );
void Close( void );
void GetLoaderVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch ) const;
// these functions are shadows of the 3D Plugin functions from 3d_plugin.h
int GetNExtensions( void );
char const* GetModelExtension( int aIndex );
int GetNFilters( void );
char const* GetFileFilter( int aIndex );
bool CanRender( void );
SCENEGRAPH* Load( char const* aFileName );
};
#endif // PLUGINMGR3D_H

2
plugins/ldr/README.txt Normal file
View File

@ -0,0 +1,2 @@
This directory will contain Plugin Loaders for use by
KiCad to load the supported Plugin Classes.

438
plugins/ldr/pluginldr.cpp Normal file
View File

@ -0,0 +1,438 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#include <pwd.h>
#endif
#include <sstream>
#include <iostream>
#include "pluginldr.h"
KICAD_PLUGIN_LDR::KICAD_PLUGIN_LDR()
{
ok = false;
m_getPluginClass = NULL;
m_getClassVersion = NULL;
m_checkClassVersion = NULL;
m_getPluginName = NULL;
m_getVersion = NULL;
m_dlHandle = NULL;
return;
}
KICAD_PLUGIN_LDR::~KICAD_PLUGIN_LDR()
{
close();
return;
}
bool KICAD_PLUGIN_LDR::open( const wxString& aFullFileName, const char* aPluginClass )
{
m_error.clear();
if( ok )
Close();
if( aFullFileName.empty() )
return false;
m_fileName.clear();
#ifdef _WIN32
// NOTE: MSWin uses UTF-16 encoding
#if defined( UNICODE ) || defined( _UNICODE )
m_dlHandle = LoadLibrary( aFullFileName.wc_str() );
#else
m_dlHandle = LoadLibrary( aFullFileName.ToUTF8() );
#endif
#else
m_dlHandle = dlopen( aFullFileName.ToUTF8(), RTLD_LAZY | RTLD_LOCAL );
#endif
if( NULL == m_dlHandle )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * could not open file: '" << aFullFileName.ToUTF8() << "'\n";
#endif
return false;
}
LINK_ITEM( m_getPluginClass, GET_PLUGIN_CLASS, "GetKicadPluginClass" );
LINK_ITEM( m_getClassVersion, GET_CLASS_VERSION, "GetClassVersion" );
LINK_ITEM( m_checkClassVersion, CHECK_CLASS_VERSION , "CheckClassVersion" );
LINK_ITEM( m_getPluginName, GET_PLUGIN_NAME, "GetKicadPluginName" );
LINK_ITEM( m_getVersion, GET_VERSION, "GetVersion" );
#ifdef DEBUG
bool fail = false;
if( !m_getPluginClass )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
std::cerr << " * missing function: GetKicadPluginClass\n";
fail = true;
}
if( !m_getClassVersion )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: GetClassVersion\n";
}
if( !m_checkClassVersion )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: CheckClassVersion\n";
}
if( !m_getPluginName )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
fail = true;
}
std::cerr << " * missing function: GetKicadPluginName\n";
}
if( !m_getVersion )
{
if( !fail )
{
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * incompatible plugin: " << aFullFileName.ToUTF8() << "\n";
}
std::cerr << " * missing function: GetVersion\n";
}
#endif
if( !m_getPluginClass || !m_getClassVersion || !m_checkClassVersion
|| !m_getPluginName || !m_getVersion )
{
m_error = "incompatible plugin interface (missing functions)";
close();
return false;
}
// note: since 'ok' is not yet set at this point we must use the function
// pointers directly rather than invoking the functions exposed by this class
// check that the Plugin Class matches
char const* pclassName = m_getPluginClass();
if( !pclassName || strcmp( aPluginClass, pclassName ) )
{
m_error = "Loader type (";
m_error.append( aPluginClass );
m_error.append( ") does not match Plugin type (" );
if( pclassName )
m_error.append( pclassName );
else
m_error.append( "NULL" );
m_error.append( ")" );
close();
return false;
}
// perform a universally enforced version check (major number must match)
unsigned char lMajor;
unsigned char lMinor;
unsigned char lRevno;
unsigned char lPatch;
unsigned char pMajor;
unsigned char pMinor;
unsigned char pRevno;
unsigned char pPatch;
m_getClassVersion( &pMajor, &pMinor, &pRevno, &pPatch );
GetLoaderVersion( &lMajor, &lMinor, &lRevno, &lPatch );
// major version changes by definition are incompatible and
// that is enforced here.
if( pMajor != lMajor )
{
std::ostringstream ostr;
ostr << "Loader Major version (" << lMajor;
ostr << ") does not match Plugin Major version (" << pMajor << ")";
m_error = ostr.str();
close();
return false;
}
if( !m_checkClassVersion( lMajor, lMinor, lRevno, lPatch ) )
{
std::ostringstream ostr;
ostr << "Plugin Version (" << pMajor << "." << pMinor << "." << pRevno << "." << pPatch;
ostr << ") does not support Loader Version (" << pMajor << "." << pMinor;
ostr << "." << pRevno << "." << pPatch << ")";
m_error = ostr.str();
close();
return false;
}
m_fileName = aFullFileName;
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] opened plugin " << m_fileName.ToUTF8() << "\n";
char const* cp = m_getPluginName();
if( !cp )
std::cerr << " * [INFO] plugin name: '" << cp << "'\n";
#endif
ok = true;
return true;
}
void KICAD_PLUGIN_LDR::close( void )
{
ok = false;
m_getPluginClass = NULL;
m_getClassVersion = NULL;
m_checkClassVersion = NULL;
m_getPluginName = NULL;
m_getVersion = NULL;
if( NULL != m_dlHandle )
{
#ifdef _WIN32
FreeLibrary( m_dlHandle );
#else
dlclose( m_dlHandle );
#endif
m_dlHandle = NULL;
}
return;
}
bool KICAD_PLUGIN_LDR::reopen( void )
{
m_error.clear();
if( m_fileName.empty() )
return false;
wxString fname = m_fileName;
return Open( fname );
}
std::string KICAD_PLUGIN_LDR::GetLastError( void ) const
{
return m_error;
}
char const* KICAD_PLUGIN_LDR::GetKicadPluginClass( void )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return NULL;
}
if( NULL == m_getPluginClass )
{
m_error = "[BUG] GetPluginClass is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return NULL;
}
return m_getPluginClass();
}
bool KICAD_PLUGIN_LDR::GetClassVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch )
{
m_error.clear();
if( Major )
*Major = 0;
if( Minor )
*Minor = 0;
if( Revision )
*Revision = 0;
if( Patch )
*Patch = 0;
unsigned char major;
unsigned char minor;
unsigned char revno;
unsigned char patch;
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return false;
}
if( NULL == m_checkClassVersion )
{
m_error = "[BUG] CheckClassVersion is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return false;
}
m_getClassVersion( &major, &minor, &revno, &patch );
if( Major )
*Major = major;
if( Minor )
*Minor = minor;
if( Revision )
*Revision = revno;
if( Patch )
*Patch = patch;
return true;
}
bool KICAD_PLUGIN_LDR::CheckClassVersion( unsigned char Major, unsigned char Minor,
unsigned char Revision, unsigned char Patch )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return NULL;
}
if( NULL == m_checkClassVersion )
{
m_error = "[BUG] CheckClassVersion is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return NULL;
}
return m_checkClassVersion( Major, Minor, Revision, Patch );
}
const char* KICAD_PLUGIN_LDR::GetKicadPluginName( void )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return NULL;
}
if( NULL == m_getPluginName )
{
m_error = "[BUG] GetKicadPluginName is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return NULL;
}
return m_getPluginName();
}
bool KICAD_PLUGIN_LDR::GetVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch )
{
m_error.clear();
if( !ok && !reopen() )
{
if( m_error.empty() )
m_error = "[INFO] no open plugin / plugin could not be opened";
return false;
}
if( NULL == m_getVersion )
{
m_error = "[BUG] GetKicadPluginName is not linked";
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * " << m_error << "\n";
return false;
}
m_getVersion( Major, Minor, Revision, Patch );
return true;
}

158
plugins/ldr/pluginldr.h Normal file
View File

@ -0,0 +1,158 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file pluginldr.h
* defines the most basic functions which all kicad plugin loaders require.
*/
#ifndef PLUGINLDR_H
#define PLUGINLDR_H
#include <dlfcn.h>
#include <string>
#include <wx/string.h>
// helper functions to link functions
#ifdef _WIN32
#define LINK_ITEM( funcPtr, funcType, funcName ) \
funcPtr = (funcType) GetProcAddress( m_dlHandle, funcName );
#else
#define LINK_ITEM( funcPtr, funcType, funcName ) \
*(void**) (&funcPtr) = dlsym( m_dlHandle, funcName );
#endif
// typedefs of the functions exported by the 3D Plugin Class
typedef char const* (*GET_PLUGIN_CLASS) ( void );
typedef void (*GET_CLASS_VERSION) ( unsigned char*, unsigned char*,
unsigned char*, unsigned char* );
typedef bool (*CHECK_CLASS_VERSION) ( unsigned char, unsigned char,
unsigned char, unsigned char );
typedef const char* (*GET_PLUGIN_NAME) ( void );
typedef void (*GET_VERSION) ( unsigned char*, unsigned char*,
unsigned char*, unsigned char* );
class KICAD_PLUGIN_LDR
{
private:
bool ok; // set TRUE if all functions are linked
GET_PLUGIN_CLASS m_getPluginClass;
GET_CLASS_VERSION m_getClassVersion;
CHECK_CLASS_VERSION m_checkClassVersion;
GET_PLUGIN_NAME m_getPluginName;
GET_VERSION m_getVersion;
wxString m_fileName; // name of last opened Plugin
protected:
std::string m_error; // error message
/**
* Function open
* opens a plugin of the specified class and links the extensions
* required by kicad_plugin. Returns true on success otherwise
* false.
*/
bool open( const wxString& aFullFileName, const char* aPluginClass );
/**
* Function close
* nullifies internal pointers in preparation for closing the plugin
*/
void close( void );
/**
* Function reopen
* reopens a plugin and returns true on success
*/
bool reopen( void );
// handle to the opened plugin
#ifdef _WIN32
HMODULE m_dlHandle;
#else
void* m_dlHandle;
#endif
public:
KICAD_PLUGIN_LDR();
virtual ~KICAD_PLUGIN_LDR();
/**
* Function GetLoaderVersion
* returns the version information of the Plugin Loader
* for plugin compatibility checking.
*/
virtual void GetLoaderVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch ) const = 0;
/**
* Function Open
* opens a plugin of the given class, performs version compatibility checks,
* and links all required functions.
*
* @return true on success, otherwise false and a message may be accessible
* via GetLastError()
*/
virtual bool Open( const wxString& aFullFileName ) = 0;
/**
* Function Close
* cleans up and closes/unloads the plugin
*/
virtual void Close( void ) = 0;
/**
* Function GetLastError
* returns the value of the internal error string
*/
std::string GetLastError( void ) const;
// the following functions are the equivalent of those required by kicad_plugin.h
// returns the Plugin Class or NULL if no plugin loaded
char const* GetKicadPluginClass( void );
// returns false if no plugin loaded
bool GetClassVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch );
// returns false if the class version check fails or no plugin is loaded
bool CheckClassVersion( unsigned char Major, unsigned char Minor,
unsigned char Revision, unsigned char Patch );
// returns the Plugin Name or NULL if no plugin loaded
const char* GetKicadPluginName( void );
// returns false if no plugin is loaded
bool GetVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Revision, unsigned char* Patch );
};
#endif // PLUGINLDR_H

View File

@ -1809,10 +1809,8 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
if( !vp ) if( !vp )
return false; return false;
size_t i, j, k; size_t i;
size_t vsize = ordmap.size(); size_t vsize = ordmap.size();
j = 0;
k = vsize;
// top vertices // top vertices
for( i = 0; i < vsize; ++i ) for( i = 0; i < vsize; ++i )