diff --git a/install/scripts/test.py b/install/scripts/test.py index 5a8f44ff2f..34261fc2e1 100644 --- a/install/scripts/test.py +++ b/install/scripts/test.py @@ -313,3 +313,60 @@ def visit(self, node): camview = GlobalCameraManager.getActiveView() print(camview.getCameraOrigin()) camview.setCameraOrigin(dr.Vector3(50,0,50)) + +# Layer Functionality +def printLayers(): + class LayerPrinter(dr.LayerVisitor): + def visit(self, layerID, layerName): + print(layerID, layerName) + layerPrinter = LayerPrinter() + GlobalLayerManager.foreachLayer(layerPrinter) + print("=================") + +print("Layers:") +printLayers() + +print("Test create") +print(GlobalLayerManager.createLayer("One")) +print(GlobalLayerManager.createLayer("Two")) +print(GlobalLayerManager.createLayer("Forty-two", 42)) +print(GlobalLayerManager.createLayer("TwoAgain", 2)) +printLayers() + +print("Test delete") +print(GlobalLayerManager.deleteLayer("NotALayer")) +print(GlobalLayerManager.deleteLayer("TwoAgain")) +printLayers() + +print("Test get") +print(GlobalLayerManager.getLayerID("Forty-two")) +print(GlobalLayerManager.getLayerName(42)) + +print("Test exists") +print(GlobalLayerManager.layerExists(123)) +print(GlobalLayerManager.layerExists(42)) + +print("Test rename") +print(GlobalLayerManager.renameLayer(42, "Forty-two")) +print(GlobalLayerManager.renameLayer(42, "Two")) +print(GlobalLayerManager.renameLayer(42, "HHGTTG")) + +print("Test active") +GlobalLayerManager.setActiveLayer(3) +print(GlobalLayerManager.getActiveLayer()) +GlobalLayerManager.setActiveLayer(2) +print(GlobalLayerManager.getActiveLayer()) + +print("Test visible") +GlobalLayerManager.setLayerVisibility("One", False) +print(GlobalLayerManager.layerIsVisible("One")) +GlobalLayerManager.setLayerVisibility("One", True) +print(GlobalLayerManager.layerIsVisible("One")) + +GlobalLayerManager.setLayerVisibility(1, False) +print(GlobalLayerManager.layerIsVisible(1)) +GlobalLayerManager.setLayerVisibility(1, True) +print(GlobalLayerManager.layerIsVisible(1)) + +GlobalLayerManager.setSelected(0, True) +GlobalLayerManager.moveSelectionToLayer(1) diff --git a/plugins/script/Makefile.am b/plugins/script/Makefile.am index 80ed34bf43..13a2fddce3 100644 --- a/plugins/script/Makefile.am +++ b/plugins/script/Makefile.am @@ -42,4 +42,5 @@ script_la_SOURCES = ScriptingSystem.cpp \ interfaces/SelectionSetInterface.cpp \ interfaces/SelectionGroupInterface.cpp \ interfaces/SoundInterface.cpp \ - interfaces/GameInterface.cpp + interfaces/GameInterface.cpp \ + interfaces/LayerInterface.cpp diff --git a/plugins/script/ScriptingSystem.cpp b/plugins/script/ScriptingSystem.cpp index 812cd2ba31..bfbd55b49e 100644 --- a/plugins/script/ScriptingSystem.cpp +++ b/plugins/script/ScriptingSystem.cpp @@ -43,6 +43,7 @@ #include "interfaces/SelectionSetInterface.h" #include "interfaces/SelectionGroupInterface.h" #include "interfaces/CameraInterface.h" +#include "interfaces/LayerInterface.h" #include "PythonModule.h" @@ -448,6 +449,7 @@ void ScriptingSystem::initialiseModule(const IApplicationContext& ctx) addInterface("SelectionSetInterface", std::make_shared()); addInterface("SelectionGroupInterface", std::make_shared()); addInterface("CameraInterface", std::make_shared()); + addInterface("LayerInterface", std::make_shared()); GlobalCommandSystem().addCommand( "RunScript", diff --git a/plugins/script/interfaces/LayerInterface.cpp b/plugins/script/interfaces/LayerInterface.cpp new file mode 100644 index 0000000000..b02b16b3d5 --- /dev/null +++ b/plugins/script/interfaces/LayerInterface.cpp @@ -0,0 +1,338 @@ +#include "LayerInterface.h" + +#include + +namespace script +{ + +namespace +{ +inline scene::ILayerManager& getMapLayerManager() +{ + if (!GlobalMapModule().getRoot()) + { + throw std::runtime_error("No map loaded."); + } + + return GlobalMapModule().getRoot()->getLayerManager(); +} + +} + +int LayerInterface::createLayer(const std::string &name) +{ + try + { + return getMapLayerManager().createLayer(name); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return -1; + } +} + +int LayerInterface::createLayer(const std::string &name, int layerID) +{ + try + { + return getMapLayerManager().createLayer(name, layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return -1; + } +} + +void LayerInterface::deleteLayer(const std::string &name) +{ + try + { + getMapLayerManager().deleteLayer(name); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::foreachLayer(LayerVisitor &visitor) +{ + try + { + getMapLayerManager().foreachLayer([&](int layerId, const std::string& layerName) + { + visitor.visit(layerId, layerName); + }); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +int LayerInterface::getLayerID(const std::string& name) +{ + try + { + return getMapLayerManager().getLayerID(name); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return -1; + } +} + +std::string LayerInterface::getLayerName(int layerID) +{ + try + { + return getMapLayerManager().getLayerName(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return ""; + } +} + +bool LayerInterface::layerExists(int layerID) +{ + try + { + return getMapLayerManager().layerExists(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return false; + } +} + +bool LayerInterface::renameLayer(int layerID, const std::string &newLayerName) +{ + try + { + return getMapLayerManager().renameLayer(layerID, newLayerName); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return false; + } +} + +int LayerInterface::getFirstVisibleLayer() +{ + try + { + return getMapLayerManager().getFirstVisibleLayer(); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return -1; + } +} + +int LayerInterface::getActiveLayer() +{ + try + { + return getMapLayerManager().getActiveLayer(); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return -1; + } +} + +void LayerInterface::setActiveLayer(int layerID) +{ + try + { + getMapLayerManager().setActiveLayer(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +bool LayerInterface::layerIsVisible(const std::string &layerName) +{ + try + { + return getMapLayerManager().layerIsVisible(layerName); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return false; + } +} + +bool LayerInterface::layerIsVisible(int layerID) +{ + try + { + return getMapLayerManager().layerIsVisible(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + return false; + } +} + +void LayerInterface::setLayerVisibility(const std::string &layerName, bool visible) +{ + try + { + getMapLayerManager().setLayerVisibility(layerName, visible); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::setLayerVisibility(int layerID, bool visible) +{ + try + { + getMapLayerManager().setLayerVisibility(layerID, visible); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::addSelectionToLayer(const std::string &layerName) +{ + try + { + getMapLayerManager().addSelectionToLayer(layerName); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::addSelectionToLayer(int layerID) +{ + try + { + getMapLayerManager().addSelectionToLayer(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::moveSelectionToLayer(const std::string &layerName) +{ + try + { + getMapLayerManager().moveSelectionToLayer(layerName); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::moveSelectionToLayer(int layerID) +{ + try + { + getMapLayerManager().moveSelectionToLayer(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::removeSelectionFromLayer(const std::string &layerName) +{ + try + { + getMapLayerManager().removeSelectionFromLayer(layerName); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::removeSelectionFromLayer(int layerID) +{ + try + { + getMapLayerManager().removeSelectionFromLayer(layerID); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::setSelected(int layerID, bool selected) +{ + try + { + getMapLayerManager().setSelected(layerID, selected); + } + catch (const std::runtime_error& ex) + { + rError() << ex.what() << std::endl; + } +} + +void LayerInterface::registerInterface(py::module& scope, py::dict& globals) +{ + // Expose the LayerVisitor interface + py::class_ visitor(scope, "LayerVisitor"); + + visitor.def(py::init<>()); + visitor.def("visit", &LayerVisitor::visit); + + // Add the module declaration to the given python namespace + py::class_ layerManager(scope, "LayerManager"); + + layerManager.def("createLayer", py::overload_cast(&LayerInterface::createLayer)); + layerManager.def("createLayer", py::overload_cast(&LayerInterface::createLayer)); + layerManager.def("deleteLayer", &LayerInterface::deleteLayer); + layerManager.def("foreachLayer", &LayerInterface::foreachLayer); + layerManager.def("getLayerID", &LayerInterface::getLayerID); + layerManager.def("getLayerName", &LayerInterface::getLayerName); + layerManager.def("layerExists", &LayerInterface::layerExists); + layerManager.def("renameLayer", &LayerInterface::renameLayer); + layerManager.def("getFirstVisibleLayer", &LayerInterface::getFirstVisibleLayer); + layerManager.def("getActiveLayer", &LayerInterface::getActiveLayer); + layerManager.def("setActiveLayer", &LayerInterface::setActiveLayer); + layerManager.def("layerIsVisible", py::overload_cast(&LayerInterface::layerIsVisible)); + layerManager.def("layerIsVisible", py::overload_cast(&LayerInterface::layerIsVisible)); + layerManager.def("setLayerVisibility", py::overload_cast(&LayerInterface::setLayerVisibility)); + layerManager.def("setLayerVisibility", py::overload_cast(&LayerInterface::setLayerVisibility)); + layerManager.def("addSelectionToLayer", py::overload_cast(&LayerInterface::addSelectionToLayer)); + layerManager.def("addSelectionToLayer", py::overload_cast(&LayerInterface::addSelectionToLayer)); + layerManager.def("moveSelectionToLayer", py::overload_cast(&LayerInterface::moveSelectionToLayer)); + layerManager.def("moveSelectionToLayer", py::overload_cast(&LayerInterface::moveSelectionToLayer)); + layerManager.def("removeSelectionFromLayer", py::overload_cast(&LayerInterface::removeSelectionFromLayer)); + layerManager.def("removeSelectionFromLayer", py::overload_cast(&LayerInterface::removeSelectionFromLayer)); + layerManager.def("setSelected", &LayerInterface::setSelected); + + // Now point the Python variable "GlobalLayerManager" to this instance + globals["GlobalLayerManager"] = this; +} + + +} diff --git a/plugins/script/interfaces/LayerInterface.h b/plugins/script/interfaces/LayerInterface.h new file mode 100644 index 0000000000..9aa91ec51e --- /dev/null +++ b/plugins/script/interfaces/LayerInterface.h @@ -0,0 +1,70 @@ +#pragma once + +#include + +#include "iscript.h" +#include "iscriptinterface.h" +#include "ilayer.h" + +#include "SceneGraphInterface.h" + +namespace script +{ + +class LayerVisitor +{ +public: + virtual ~LayerVisitor() {} + virtual void visit(int layerID, const std::string& layerName) = 0; +}; + +// Wrap around the LayerVisitor interface +class LayerVisitorWrapper : + public LayerVisitor +{ +public: + void visit(int layerID, const std::string& layerName) override + { + // Wrap this method to python + PYBIND11_OVERLOAD_PURE( + void, /* Return type */ + LayerVisitor, /* Parent class */ + visit, /* Name of function in C++ (must match Python name) */ + layerID, /* Argument(s) */ + layerName + ); + } +}; + +class LayerInterface : + public IScriptInterface +{ +public: + int createLayer(const std::string& name); + int createLayer(const std::string& name, int layerID); + void deleteLayer(const std::string& name); + void foreachLayer(LayerVisitor& visitor); + int getLayerID(const std::string &name); + std::string getLayerName(int layerID); + bool layerExists(int layerID); + bool renameLayer(int layerID, const std::string& newLayerName); + int getFirstVisibleLayer(); + int getActiveLayer(); + void setActiveLayer(int layerID); + bool layerIsVisible(const std::string& layerName); + bool layerIsVisible(int layerID); + void setLayerVisibility(const std::string& layerName, bool visible); + void setLayerVisibility(int layerID, bool visible); + void addSelectionToLayer(const std::string& layerName); + void addSelectionToLayer(int layerID); + void moveSelectionToLayer(const std::string& layerName); + void moveSelectionToLayer(int layerID); + void removeSelectionFromLayer(const std::string& layerName); + void removeSelectionFromLayer(int layerID); + void setSelected(int layerID, bool selected); + + // IScriptInterface implementation + void registerInterface(py::module& scope, py::dict& globals) override; +}; + +} // namespace script diff --git a/tools/msvc/script.vcxproj b/tools/msvc/script.vcxproj index e213ac1f34..8281e09837 100644 --- a/tools/msvc/script.vcxproj +++ b/tools/msvc/script.vcxproj @@ -217,6 +217,7 @@ + @@ -247,6 +248,7 @@ + diff --git a/tools/msvc/script.vcxproj.filters b/tools/msvc/script.vcxproj.filters index acc9a5fdcb..929b070cba 100644 --- a/tools/msvc/script.vcxproj.filters +++ b/tools/msvc/script.vcxproj.filters @@ -94,6 +94,9 @@ src\interfaces + + src\interfaces + @@ -177,5 +180,8 @@ src\interfaces + + src\interfaces + \ No newline at end of file