From 3ff8ca0cafda96709e9946a0b2f1a00a10fae1b1 Mon Sep 17 00:00:00 2001 From: Cirilo Bernardo Date: Mon, 14 Dec 2015 08:45:22 +1100 Subject: [PATCH] Refactored to use new generic plugin base --- 3d-viewer/3d_cache/3d_plugin_manager.cpp | 248 +++---------- 3d-viewer/3d_cache/3d_plugin_manager.h | 8 +- 3d-viewer/CMakeLists.txt | 4 + include/plugins/3d/3d_plugin.h | 152 +++++--- include/plugins/kicad_plugin.h | 112 ++++++ plugins/3d/CMakeLists.txt | 4 +- plugins/3d/idf/s3d_plugin_idf.cpp | 144 +++++--- plugins/3d/idf/s3d_plugin_idf.h | 57 --- plugins/ldr/3d/pluginldr3D.cpp | 364 +++++++++++++++++++ plugins/ldr/3d/pluginldr3D.h | 90 +++++ plugins/ldr/README.txt | 2 + plugins/ldr/pluginldr.cpp | 438 +++++++++++++++++++++++ plugins/ldr/pluginldr.h | 158 ++++++++ utils/idftools/vrml_layer.cpp | 4 +- 14 files changed, 1418 insertions(+), 367 deletions(-) create mode 100644 include/plugins/kicad_plugin.h delete mode 100644 plugins/3d/idf/s3d_plugin_idf.h create mode 100644 plugins/ldr/3d/pluginldr3D.cpp create mode 100644 plugins/ldr/3d/pluginldr3D.h create mode 100644 plugins/ldr/README.txt create mode 100644 plugins/ldr/pluginldr.cpp create mode 100644 plugins/ldr/pluginldr.h diff --git a/3d-viewer/3d_cache/3d_plugin_manager.cpp b/3d-viewer/3d_cache/3d_plugin_manager.cpp index 282572fe61..2f952af38f 100644 --- a/3d-viewer/3d_cache/3d_plugin_manager.cpp +++ b/3d-viewer/3d_cache/3d_plugin_manager.cpp @@ -44,145 +44,7 @@ #include "3d_plugin_manager.h" #include "plugins/3d/3d_plugin.h" #include "3d_cache/sg/scenegraph.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; -} - +#include "plugins/ldr/3d/pluginldr3D.h" S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER() { @@ -195,14 +57,14 @@ S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER() #ifdef DEBUG if( !m_ExtMap.empty() ) { - std::multimap< const wxString, S3D_PLUGIN_ITEM* >::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 sM = m_ExtMap.begin(); + std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::const_iterator eM = m_ExtMap.end(); std::cout << "* Extension [plugin name]:\n"; while( sM != eM ) { std::cout << " + '" << sM->first.ToUTF8() << "' ["; - std::cout << sM->second->GetPluginName().ToUTF8() << "]\n"; + std::cout << sM->second->GetKicadPluginName() << "]\n"; ++sM; } @@ -239,8 +101,8 @@ S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER() S3D_PLUGIN_MANAGER::~S3D_PLUGIN_MANAGER() { - std::list< S3D_PLUGIN_ITEM* >::iterator sP = m_Plugins.begin(); - std::list< S3D_PLUGIN_ITEM* >::iterator eP = m_Plugins.end(); + std::list< KICAD_PLUGIN_LDR_3D* >::iterator sP = m_Plugins.begin(); + std::list< KICAD_PLUGIN_LDR_3D* >::iterator eP = m_Plugins.end(); while( sP != eP ) { @@ -271,6 +133,7 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void ) std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() ); checkPluginPath( testpath, searchpaths ); #endif + fn.Assign( wxStandardPaths::Get().GetPluginsDir() ); fn.AppendDir( wxT( "kicad" ) ); fn.AppendDir( wxT( "plugins" ) ); @@ -321,42 +184,42 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void ) 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 - std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n"; - std::cout << "* [DEBUG] adding plugin\n"; + std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n"; + std::cout << "* [DEBUG] adding plugin\n"; #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"; + std::cerr << " * [INFO] adding " << nf << " filters\n"; + #endif - if( lpp ) - { - int nf = lpp->GetNFilters(); - - for( int i = 0; i < nf; ++i ) - addFilterString( lpp->GetFileFilter( i ) ); - - } - - addExtensionMap( pp ); - - // close the loaded library - pp->Close(); - } - else + for( int i = 0; i < nf; ++i ) { -#ifdef DEBUG - std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n"; - std::cout << "* [DEBUG] deleting plugin\n"; -#endif - delete pp; + char const* cp = pp->GetFileFilter( i ); + + if( cp ) + addFilterString( wxString::FromUTF8Unchecked( cp ) ); } + + addExtensionMap( pp ); + + // close the loaded library + pp->Close(); + } + else + { +#ifdef DEBUG + std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n"; + std::cout << "* [DEBUG] deleting plugin\n"; +#endif + delete pp; } ++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 if( NULL == aPlugin ) return; - S3D_PLUGIN* pp = aPlugin->GetPlugin(); + int nExt = aPlugin->GetNExtensions(); - if( NULL == pp ) - return; - - int nExt = pp->GetNExtensions(); + #ifdef DEBUG + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [INFO] adding " << nExt << " extensions\n"; + #endif 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() ) { - 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 ); wxString ext = raw.GetExt(); - std::pair < std::multimap< const wxString, S3D_PLUGIN_ITEM* >::iterator, - std::multimap< const wxString, S3D_PLUGIN_ITEM* >::iterator > items; + std::pair < std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator, + std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator > items; 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 ) { - S3D_PLUGIN* pplug = sL->second->GetPlugin(); - - if( NULL != pplug && pplug->CanRender() ) + if( sL->second->CanRender() ) { - SCENEGRAPH* sp = pplug->Load( aFileName ); + SCENEGRAPH* sp = sL->second->Load( aFileName ); if( NULL != sp ) return sp; @@ -589,8 +454,13 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName ) void S3D_PLUGIN_MANAGER::ClosePlugins( void ) { - std::list< S3D_PLUGIN_ITEM* >::iterator sP = m_Plugins.begin(); - std::list< S3D_PLUGIN_ITEM* >::iterator eP = m_Plugins.end(); + std::list< KICAD_PLUGIN_LDR_3D* >::iterator sP = m_Plugins.begin(); + 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 ) { diff --git a/3d-viewer/3d_cache/3d_plugin_manager.h b/3d-viewer/3d_cache/3d_plugin_manager.h index af03e18375..76d0afc62f 100644 --- a/3d-viewer/3d_cache/3d_plugin_manager.h +++ b/3d-viewer/3d_cache/3d_plugin_manager.h @@ -34,7 +34,7 @@ #include class wxWindow; -class S3D_PLUGIN_ITEM; +class KICAD_PLUGIN_LDR_3D; struct S3D_INFO; class SCENEGRAPH; @@ -42,10 +42,10 @@ class S3D_PLUGIN_MANAGER { private: /// 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 - std::multimap< const wxString, S3D_PLUGIN_ITEM* > m_ExtMap; + std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* > m_ExtMap; /// list of file filters std::list< wxString > m_FileFilters; @@ -66,7 +66,7 @@ private: void addFilterString( const wxString& aFilterString ); /// add entries to the extension map - void addExtensionMap( S3D_PLUGIN_ITEM* aPlugin ); + void addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin ); public: S3D_PLUGIN_MANAGER(); diff --git a/3d-viewer/CMakeLists.txt b/3d-viewer/CMakeLists.txt index 435995c58c..e356900782 100644 --- a/3d-viewer/CMakeLists.txt +++ b/3d-viewer/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/include/gal/opengl ${GLEW_INCLUDE_DIR} ${GLM_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR} ${INC_AFTER} ) @@ -21,6 +22,7 @@ set( DIR_RAY 3d_rendering/3d_render_raytracing ) set( DIR_RAY_ACC ${DIR_RAY}/accelerators ) set( DIR_RAY_2D ${DIR_RAY}/shapes2D ) set( DIR_RAY_3D ${DIR_RAY}/shapes3D ) +set( DIR_3D_PLUGINS ${CMAKE_SOURCE_DIR}/plugins/ldr ) set(3D-VIEWER_SRCS dialogs/dialog_3D_view_option_base.cpp @@ -45,6 +47,8 @@ set(3D-VIEWER_SRCS vrml_v2_modelparser.cpp x3dmodelparser.cpp CImage.cpp + ${DIR_3D_PLUGINS}/pluginldr.cpp + ${DIR_3D_PLUGINS}/3d/pluginldr3D.cpp 3d_cache/3d_cache_wrapper.cpp 3d_cache/3d_cache.cpp 3d_cache/3d_plugin_manager.cpp diff --git a/include/plugins/3d/3d_plugin.h b/include/plugins/3d/3d_plugin.h index abd00d293d..8fffb8f458 100644 --- a/include/plugins/3d/3d_plugin.h +++ b/include/plugins/3d/3d_plugin.h @@ -30,69 +30,109 @@ #ifndef PLUGIN_3D_H #define PLUGIN_3D_H -#include +// +// KICAD_PLUGIN CLASS INTERFACE +// +// WARNING: DO NOT EDIT THIS FILE OUTSIDE THE KICAD TREE +// + +// 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 + +#include "../kicad_plugin.h" + + +KICAD_PLUGIN_EXPORT char const* GetKicadPluginClass( void ) +{ + return KICAD_PLUGIN_CLASS; +} + + +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; +} + +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; -class S3D_PLUGIN -{ -public: - virtual ~S3D_PLUGIN() - { - return; - } +/** + * Function GetNExtensions + * + * @return the number of extensions supported by the plugin + */ +KICAD_PLUGIN_EXPORT int GetNExtensions( void ); - /** - * Function GetNExtensions - * - * @return the number of extensions supported by the plugin - */ - virtual int GetNExtensions( void ) const = 0; +/** + * Function GetModelExtension + * + * @param aIndex is the extension to return; valid values are + * 0 to GetNExtensions() - 1. + * @return the requested extension or a null string if aIndex + * was invalid. + */ +KICAD_PLUGIN_EXPORT char const* GetModelExtension( int aIndex ); - /** - * Function GetModelExtension - * - * @param aIndex is the extension to return; valid values are - * 0 to GetNExtensions() - 1. - * @return the requested extension or a null string if aIndex - * was invalid. - */ - virtual const wxString GetModelExtension( int aIndex ) const = 0; +/** + * Function GetNFilters + * @returns the number of file filters + */ +KICAD_PLUGIN_EXPORT int GetNFilters( void ); - /** - * Function GetNFilters - * @returns the number of file filters - */ - virtual int GetNFilters( void ) const = 0; +/** + * Function GetFileFilter + * + * @return the file filter string for the given index + */ +KICAD_PLUGIN_EXPORT char const* GetFileFilter( int aIndex ); - /** - * Function GetFileFilter - * - * @return the file filter string for the given index - */ - virtual const wxString GetFileFilter( int aIndex ) const = 0; +/** + * Function CanRender + * + * @return true if the plugin can render a model, that is + * the Load() function is implemented + */ +KICAD_PLUGIN_EXPORT bool CanRender( void ); - /** - * Function CanRender - * - * @return true if the plugin can render a model, that is - * the Load() function is implemented - */ - virtual bool CanRender( void ) const = 0; - - /** - * Function Load - * reads the model file and creates a generic display structure - * - * @param aFileName is the full path of the model file - * @param aModel is a handle to a null pointer; on successful - * reading of the model data aModel will point to a representation - * for rendering - * @param returns true if the model was successfully loaded and false - * if there is no rendering support for the model or there were - * problems reading the model - */ - virtual SCENEGRAPH* Load( const wxString& aFileName ) = 0; -}; +/** + * Function Load + * reads the model file and creates a generic display structure + * + * @param aFileName is the full path of the model file + * @param aModel is a handle to a null pointer; on successful + * reading of the model data aModel will point to a representation + * for rendering + * @param returns true if the model was successfully loaded and false + * if there is no rendering support for the model or there were + * problems reading the model + */ +KICAD_PLUGIN_EXPORT SCENEGRAPH* Load( char const* aFileName ); #endif // PLUGIN_3D_H diff --git a/include/plugins/kicad_plugin.h b/include/plugins/kicad_plugin.h new file mode 100644 index 0000000000..43460f01a8 --- /dev/null +++ b/include/plugins/kicad_plugin.h @@ -0,0 +1,112 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Cirilo Bernardo + * + * 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 + #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 diff --git a/plugins/3d/CMakeLists.txt b/plugins/3d/CMakeLists.txt index 918c1b6188..7e518dab2c 100644 --- a/plugins/3d/CMakeLists.txt +++ b/plugins/3d/CMakeLists.txt @@ -1,3 +1,3 @@ -add_subdirectory( dummy ) -add_subdirectory( tetra ) +#add_subdirectory( dummy ) +#add_subdirectory( tetra ) add_subdirectory( idf ) diff --git a/plugins/3d/idf/s3d_plugin_idf.cpp b/plugins/3d/idf/s3d_plugin_idf.cpp index 75b658fe8a..609f55a85f 100644 --- a/plugins/3d/idf/s3d_plugin_idf.cpp +++ b/plugins/3d/idf/s3d_plugin_idf.cpp @@ -25,105 +25,138 @@ #include #include #include -#include "s3d_plugin_idf.h" +#include +#include "plugins/3d/3d_plugin.h" #include "plugins/3dapi/ifsg_all.h" #include "idf_parser.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 -extern "C" __attribute__((__visibility__("default"))) S3D_PLUGIN* Get3DPlugin( void ) -{ - return &idf_plugin; -} -#else -extern "C" __declspec( dllexport ) S3D_PLUGIN* Get3DPlugin( void ) - { - return &idf_plugin; - } + static char ext1[] = "IDF"; + static char fil1[] = "IDF 2.0/3.0 (*.idf;*.IDF)|*.idf;*.IDF"; #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 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" ) ); - -#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; + return NEXTS; } -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() ) - return wxString( "" ); + if( aIndex < 0 || aIndex >= NFILS ) + return NULL; - return m_extensions[aIndex]; + return file_data.filters[aIndex]; } -int S3D_PLUGIN_IDF::GetNFilters( void ) const -{ - 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 +KICAD_PLUGIN_EXPORT bool CanRender( void ) { // this plugin supports rendering of IDF component outlines 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 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 ) { #ifdef DEBUG std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [INFO] no outline for file '"; - std::cerr << aFileName.ToUTF8() << "'\n"; + std::cerr << aFileName << "'\n"; #endif return NULL; } @@ -135,7 +168,7 @@ SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName ) #ifdef DEBUG std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [INFO] no valid outline data in '"; - std::cerr << aFileName.ToUTF8() << "'\n"; + std::cerr << aFileName << "'\n"; #endif return NULL; } @@ -150,12 +183,11 @@ SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName ) #ifdef DEBUG std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << " * [INFO] no vertex data in '"; - std::cerr << aFileName.ToUTF8() << "'\n"; + std::cerr << aFileName << "'\n"; #endif return NULL; } - std::cerr << "XXX - Got " << vertices.size() / 3 << " vertices and " << indices.size() << " indices\n"; std::vector< SGPOINT > vlist; size_t nvert = vertices.size() / 3; size_t j = 0; diff --git a/plugins/3d/idf/s3d_plugin_idf.h b/plugins/3d/idf/s3d_plugin_idf.h deleted file mode 100644 index 8f52412d6a..0000000000 --- a/plugins/3d/idf/s3d_plugin_idf.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2015 Cirilo Bernardo - * - * 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 -#include - -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 diff --git a/plugins/ldr/3d/pluginldr3D.cpp b/plugins/ldr/3d/pluginldr3D.cpp new file mode 100644 index 0000000000..572cecc75c --- /dev/null +++ b/plugins/ldr/3d/pluginldr3D.cpp @@ -0,0 +1,364 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Cirilo Bernardo + * + * 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 +#include +#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 ); +} diff --git a/plugins/ldr/3d/pluginldr3D.h b/plugins/ldr/3d/pluginldr3D.h new file mode 100644 index 0000000000..c413fcfc55 --- /dev/null +++ b/plugins/ldr/3d/pluginldr3D.h @@ -0,0 +1,90 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Cirilo Bernardo + * + * 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 diff --git a/plugins/ldr/README.txt b/plugins/ldr/README.txt new file mode 100644 index 0000000000..5a894e62fa --- /dev/null +++ b/plugins/ldr/README.txt @@ -0,0 +1,2 @@ +This directory will contain Plugin Loaders for use by +KiCad to load the supported Plugin Classes. diff --git a/plugins/ldr/pluginldr.cpp b/plugins/ldr/pluginldr.cpp new file mode 100644 index 0000000000..d25d190914 --- /dev/null +++ b/plugins/ldr/pluginldr.cpp @@ -0,0 +1,438 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Cirilo Bernardo + * + * 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 +#else +#include +#include +#endif + +#include +#include + +#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; +} diff --git a/plugins/ldr/pluginldr.h b/plugins/ldr/pluginldr.h new file mode 100644 index 0000000000..473adf4ad5 --- /dev/null +++ b/plugins/ldr/pluginldr.h @@ -0,0 +1,158 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Cirilo Bernardo + * + * 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 +#include +#include + +// 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 diff --git a/utils/idftools/vrml_layer.cpp b/utils/idftools/vrml_layer.cpp index d31dcffc5b..36b27b525f 100644 --- a/utils/idftools/vrml_layer.cpp +++ b/utils/idftools/vrml_layer.cpp @@ -1809,10 +1809,8 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList, if( !vp ) return false; - size_t i, j, k; + size_t i; size_t vsize = ordmap.size(); - j = 0; - k = vsize; // top vertices for( i = 0; i < vsize; ++i )