summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Rajagopalan <manoj@nanorex.com>2008-03-19 05:26:08 +0000
committerManoj Rajagopalan <manoj@nanorex.com>2008-03-19 05:26:08 +0000
commit60ab1ecf7c57e00421a4d91932539e34a871bc91 (patch)
tree7bf2ab0b14fce17bd394396a09edd2b828f297de
parent48eafb6bce830297b025082648f430e6505c5743 (diff)
downloadnanoengineer-60ab1ecf7c57e00421a4d91932539e34a871bc91.tar.gz
nanoengineer-60ab1ecf7c57e00421a4d91932539e34a871bc91.zip
NXGraphicsManager initial commit.
The part that verifies a loaded commit using qobject_cast is commented out for the moment because that will include propagating changes to NXRenderingEngine, NXRendererPlugin and related class-hierarchies and these in turn require extensive testing. This is next on the agenda. application.qrc still had a reference to a deleted nanoENGINEER-1.ico file and this was breaking builds. Corrected.
-rw-r--r--cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h79
-rw-r--r--cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp256
-rw-r--r--cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro2
-rw-r--r--cad/plugins/NanoVision-1/src/application.qrc1
4 files changed, 337 insertions, 1 deletions
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h b/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h
new file mode 100644
index 000000000..e47c92e12
--- /dev/null
+++ b/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h
@@ -0,0 +1,79 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#ifndef NX_GRAPHICSMANAGER_H
+#define NX_GRAPHICSMANAGER_H
+
+#include "Nanorex/Utility/NXLogger.h"
+#include "Nanorex/Utility/NXUtility.h"
+#include "Nanorex/Utility/NXProperties.h"
+#include "NXRenderingEngine.h"
+#include "NXRendererPlugin.h"
+
+#include <QObject>
+
+#include <map>
+#include <vector>
+#include <string>
+
+
+namespace Nanorex {
+
+
+class NXGraphicsManager : public QObject {
+
+ Q_OBJECT;
+
+private:
+ typedef std::map<std::string, NXRendererPlugin*> RenderStyleRendererPluginTable;
+ typedef std::map<std::string, std::string> StringMap;
+
+public:
+
+ NXGraphicsManager();
+ ~NXGraphicsManager();
+
+ /// Discover rendering engine based on user-prefs and concomitant
+ /// renderer-plugins
+ void loadPlugins(NXProperties *const properties);
+
+ /// List of all styles supported
+ std::vector<std::string> getRenderStyles(void);
+
+ NXRenderingEngine* getRenderingEngine(void);
+
+ NXRendererPlugin* getRenderer(std::string const& renderStyleCode) const;
+
+ std::string getRenderStyleName(std::string const& renderStyleCode);
+
+ NXRendererPlugin* getDefaultRenderer(void);
+
+private:
+
+ NXProperties properties;
+ NXRenderingEngine *renderingEngine;
+
+ // Note: a render-style code, like "bas" is what we'd find in MMP files
+ // NE-1 uses 3-letter codes but the user could use arbitrarily long
+ // ones. We must provide a UI so that registering a new one does not
+ // clobber the old ones without prompting the user first.
+
+ /// Map between render-style codes and plugins
+ /// E.g.: "bas" <---> (NXRendererPlugin*) nxBallAndStickOpenGLRendererInstance
+ RenderStyleRendererPluginTable renderStyleRendererPluginTable;
+ NXRendererPlugin *defaultPlugin;
+
+ /// Map between render-style codes and proper display names
+ /// E.g.: "bas" <---> "Ball and Stick"
+ StringMap renderStyleNameTable;
+
+ /// Map between render-style codes and the file-name for the library
+ /// providing the code
+ StringMap renderStyleFileNameTable;
+
+ void loadRenderingEngine(NXProperties *const props);
+ void loadRendererPlugins(NXProperties *const props);
+};
+
+} // namespace Nanorex
+
+#endif // NX_GRAPHICSMANAGER_H
diff --git a/cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp b/cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp
new file mode 100644
index 000000000..c4381000c
--- /dev/null
+++ b/cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp
@@ -0,0 +1,256 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#include <Nanorex/Interface/NXGraphicsManager.h>
+#include <Nanorex/Utility/NXStringTokenizer.h>
+
+#include <QDir>
+#include <QFileInfo>
+#include <QPluginLoader>
+
+#include <sstream>
+
+using namespace std;
+
+namespace Nanorex {
+
+NXGraphicsManager::NXGraphicsManager()
+ : properties(),
+ renderingEngine(NULL),
+ renderStyleRendererPluginTable(),
+ renderStyleNameTable(),
+ renderStyleFileNameTable()
+{
+}
+
+
+NXGraphicsManager::~NXGraphicsManager()
+{
+}
+
+
+void NXGraphicsManager::loadPlugins(NXProperties *const props)
+{
+ loadRenderingEngine(props);
+ loadRendererPlugins(props);
+}
+
+
+/// Called by findAndLoadPlugin() to load a plugin from an existing file.
+/// Returns false if qobject_cast() failed indicating that plugin does not
+/// match the expected interface. If successful, then the pointer referenced
+/// by pluginStore is updated to point to the loaded instance.
+/// This function is called to load both the rendering-engine and renderer-plugins
+template<typename PluginType>
+ static bool loadPlugin(PluginType **pluginStore,
+ QFileInfo const fileInfo)
+{
+ QPluginLoader pluginLoader(fileInfo.absoluteFilePath());
+ QObject *pluginObject = pluginLoader.instance();
+ /// @fixme Uncomment and commit after testing builds with NXRenderingEngine
+ /// Qt-plugin modifications go through
+/* if(pluginObject != (QObject*) 0)
+ *pluginStore = qobject_cast<PluginType*>(pluginObject);
+ else */
+ *pluginStore = (PluginType*) 0;
+
+ bool success = ((*pluginStore) != (PluginType*)0);
+ return success;
+}
+
+
+/// Locates and loads a plugin given the basename of the file and an initial
+/// path to examine. If a load from the initial path is unsuccessful or if the
+/// path provided is empty, then it retrieves the plugins-search-path
+/// from application-settings and searches it in order for the first file it
+/// could successfully find and load. If an engine could be successfully loaded
+/// then it returns true and the plugin-pointer referenced by pluginStore is
+/// updated to point to the loaded instance. cleanPath then holds the absolute
+/// directory specification and absPath holds the full path to the library file.
+template<typename PluginType>
+ static bool findAndLoadPlugin(string const& baseName, string const& path,
+ string const& pluginsSearchPath,
+ PluginType **pluginStore, QDir *cleanPath,
+ string *absPath)
+{
+#if defined(WIN32)
+ string const fileExt = ".dll";
+#elif defined(__APPLE__)
+ string const fileExt = ".dylib";
+#else
+ string const fileExt = ".so";
+#endif
+
+ string const fileName = baseName + fileExt;
+ bool pluginFoundAndLoaded = false;
+
+ if(!path.empty()) {
+ // user-defined specific path for this plugin - search this first
+ *cleanPath = QDir(path.c_str()).absolutePath();
+ QFileInfo fileInfo(cleanPath->absoluteFilePath(fileName.c_str()));
+ *absPath = qPrintable(fileInfo.absoluteFilePath());
+ bool const pluginFound = fileInfo.exists();
+ bool pluginLoaded = false;
+ if(pluginFound)
+ pluginLoaded = loadPlugin(pluginStore, fileInfo);
+ pluginFoundAndLoaded = pluginFound && pluginLoaded;
+ if(!pluginFoundAndLoaded) {
+ string const pluginNotFoundMsg = "Could not find renderer-plugin " +
+ fileName + " in specific path " +
+ qPrintable(cleanPath->absolutePath()) +
+ " - examining plugins-search-path from application-settings";
+ NXLOG_WARNING("NXGraphicsManager", pluginNotFoundMsg);
+ }
+ }
+
+ if(!pluginFoundAndLoaded) {
+ // either plugin was not found in given path or no specific path was
+ // provided for the plugin - search in plugin-paths list
+ NXStringTokenizer tokenizer(pluginsSearchPath, ";");
+ while(!pluginFoundAndLoaded && tokenizer.hasMoreTokens()) {
+ string const token = tokenizer.getNextToken();
+ *cleanPath = QDir(token.c_str()).absolutePath();
+ QFileInfo fileInfo(cleanPath->absoluteFilePath(fileName.c_str()));
+ *absPath = qPrintable(fileInfo.absoluteFilePath());
+ bool const pluginFound = fileInfo.exists();
+ bool pluginLoaded = false;
+ if(pluginFound)
+ pluginLoaded = loadPlugin(pluginStore, fileInfo);
+ pluginFoundAndLoaded = pluginFound && pluginLoaded;
+ }
+ if(!pluginFoundAndLoaded) {
+ string const pluginNotFoundMsg = "Could not find renderer-plugin " +
+ fileName + " in paths " + pluginsSearchPath;
+ NXLOG_SEVERE("NXGraphicsManager", pluginNotFoundMsg);
+ }
+ }
+
+ return pluginFoundAndLoaded;
+}
+
+
+
+/// Loads the rendering-engine from application settings
+void NXGraphicsManager::loadRenderingEngine(NXProperties *const props)
+{
+ /// @fixme What if pluginsSearchPath is empty?
+
+ string baseName = props->getProperty("RenderingEngine.plugin");
+ string filePath = props->getProperty("RenderingEngine.pluginPath");
+ string const pluginsSearchPath =
+ props->getProperty("Miscellaneous/PluginsSearchPath");
+
+ QDir cleanPath;
+ string absPath;
+ bool renderingEngineLoaded = findAndLoadPlugin(baseName, filePath,
+ pluginsSearchPath,
+ &renderingEngine,
+ &cleanPath, &absPath);
+
+ if(renderingEngineLoaded) {
+ properties.setProperty("RenderingEngine.plugin",
+ qPrintable(cleanPath.absolutePath()));
+ string const msg = "Rendering-engine loaded from file " + absPath;
+ NXLOG_INFO("NXGraphicsManager", msg);
+ }
+}
+
+
+void NXGraphicsManager::loadRendererPlugins(NXProperties *const props)
+{
+ string const pluginsSearchPath =
+ props->getProperty("Miscellaneous/PluginsSearchPath");
+
+ int pluginNum = 0; // counter
+
+ while(true) {
+ ostringstream pluginKeyStream;
+ pluginKeyStream << "RenderStyle." << pluginNum;
+ ++pluginNum;
+ string const pluginKey = pluginKeyStream.str();
+ string const pluginCode = props->getProperty(pluginKey + ".code");
+ string pluginBaseName = props->getProperty(pluginKey + ".plugin");
+
+ // if code and plugin filename are absent then there are no more plugins
+ if(pluginCode.empty() && pluginBaseName.empty())
+ break;
+
+ // else if only one of them is mentioned then error condition
+ else if(pluginCode.empty() || pluginBaseName.empty()) {
+ // error condition, both are required, only one is present
+ string msg = "Both render-style code and plugin library filename "
+ "must be provided for " + pluginKey + " (check app-settings file)";
+ NXLOG_SEVERE("NXGraphicsManager", msg);
+ // this could be a mistake with just this plugin-spec, continue
+ // with next plugin - maybe that one is ok
+ continue;
+ }
+
+ // both code and plugin file have values - try to load
+ else {
+ string const pluginPath =
+ props->getProperty(pluginKey + ".pluginPath");
+
+ QDir cleanPath;
+ string absPath;
+ NXRendererPlugin *rendererPlugin = NULL;
+ bool const rendererPluginLoaded =
+ findAndLoadPlugin(pluginBaseName, pluginPath, pluginsSearchPath,
+ &rendererPlugin, &cleanPath, &absPath);
+
+ // if successful, record entries in tables
+ if(rendererPluginLoaded) {
+ string pluginName = props->getProperty(pluginKey + ".name");
+ if(pluginName.empty())
+ pluginName = pluginCode;
+ properties.setProperty("Renderer."+pluginCode+".plugin",
+ absPath);
+ properties.setProperty("Renderer."+pluginCode+".name",
+ pluginName);
+ renderStyleRendererPluginTable[pluginCode] = rendererPlugin;
+ renderStyleNameTable[pluginCode] = pluginName;
+ renderStyleFileNameTable[pluginCode] = absPath;
+ // break out of plugin-search loop upon first successful load
+ break;
+ }
+ }
+ }
+}
+
+
+vector<string> NXGraphicsManager::getRenderStyles(void)
+{
+ vector<string> renderStyles;
+ RenderStyleRendererPluginTable::const_iterator renderStyleTableIter;
+ for(renderStyleTableIter = renderStyleRendererPluginTable.begin();
+ renderStyleTableIter != renderStyleRendererPluginTable.end();
+ ++renderStyleTableIter)
+ {
+ renderStyles.push_back(renderStyleTableIter->first);
+ }
+ return renderStyles;
+}
+
+
+NXRendererPlugin*
+ NXGraphicsManager::getRenderer(string const& renderStyleCode) const
+{
+ RenderStyleRendererPluginTable::const_iterator renderStyleCodeIter =
+ renderStyleRendererPluginTable.find(renderStyleCode);
+ if(renderStyleCodeIter == renderStyleRendererPluginTable.end())
+ return (NXRendererPlugin*) NULL;
+ else
+ return renderStyleCodeIter->second;
+}
+
+
+string NXGraphicsManager::getRenderStyleName(string const& renderStyleCode)
+{
+ StringMap::const_iterator renderStyleCodeIter =
+ renderStyleNameTable.find(renderStyleCode);
+ if(renderStyleCodeIter == renderStyleNameTable.end())
+ return string();
+ else
+ return renderStyleCodeIter->second;
+}
+
+} // namespace Nanorex
diff --git a/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro b/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro
index efb479b67..b13d000c7 100644
--- a/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro
+++ b/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro
@@ -8,6 +8,7 @@ HEADERS += \
../../../include/Nanorex/Interface/NXDataImportExportPlugin.h \
../../../include/Nanorex/Interface/NXDataStoreInfo.h \
../../../include/Nanorex/Interface/NXEntityManager.h \
+ ../../../include/Nanorex/Interface/NXGraphicsManager.h \
../../../include/Nanorex/Interface/NXMoleculeData.h \
../../../include/Nanorex/Interface/NXMoleculeSet.h \
../../../include/Nanorex/Interface/NXNanoVisionResultCodes.h \
@@ -29,6 +30,7 @@ INCLUDEPATH += ../../../include \
SOURCES += ../../Interface/NXDataStoreInfo.cpp \
../../Interface/NXEntityManager.cpp \
+ ../../Interface/NXGraphicsManager.cpp \
../../Interface/NXMoleculeData.cpp \
../../Interface/NXMoleculeSet.cpp \
../../Interface/NXNumbers.cpp \
diff --git a/cad/plugins/NanoVision-1/src/application.qrc b/cad/plugins/NanoVision-1/src/application.qrc
index ba7e53d21..885ab31cf 100644
--- a/cad/plugins/NanoVision-1/src/application.qrc
+++ b/cad/plugins/NanoVision-1/src/application.qrc
@@ -8,7 +8,6 @@
<file>Icons/home.png</file>
<file>Icons/results_tree.png</file>
<file>Icons/nh5_file.png</file>
- <file>Icons/nanoENGINEER-1.ico</file>
<file>Icons/input_file.png</file>
<file>Icons/input_files.png</file>
<file>Icons/input_parameters.png</file>