diff --git a/install/scripts/test.py b/install/scripts/test.py index 255b897016..4b04cff8ac 100644 --- a/install/scripts/test.py +++ b/install/scripts/test.py @@ -213,6 +213,10 @@ def pre(self, node): # modelskin = GlobalModelSkinCache.capture(skin) # print('Skin found: ' + modelskin.getName()) +v = Vector3(6,6,6) +v += Vector3(10,10,10) +print(v) + # Test patch manipulation class PatchManipulator(SceneNodeVisitor) : def pre(self, node): diff --git a/plugins/script/interfaces/EClassInterface.h b/plugins/script/interfaces/EClassInterface.h index d6c25dd6d5..060fae0d17 100644 --- a/plugins/script/interfaces/EClassInterface.h +++ b/plugins/script/interfaces/EClassInterface.h @@ -50,7 +50,7 @@ class EntityClassVisitorWrapper : public EntityClassVisitor { public: - void visit(const IEntityClassPtr& eclass) + void visit(const IEntityClassPtr& eclass) override { // Wrap this method to python PYBIND11_OVERLOAD_PURE( @@ -67,7 +67,7 @@ class ModelDefVisitorWrapper : public ModelDefVisitor { public: - void visit(const IModelDefPtr& modelDef) + void visit(const IModelDefPtr& modelDef) override { // Wrap this method to python PYBIND11_OVERLOAD_PURE( diff --git a/plugins/script/interfaces/FileSystemInterface.h b/plugins/script/interfaces/FileSystemInterface.h index 7343780920..8de4f8e1c2 100644 --- a/plugins/script/interfaces/FileSystemInterface.h +++ b/plugins/script/interfaces/FileSystemInterface.h @@ -28,7 +28,7 @@ class FileVisitorWrapper : public VirtualFileSystemVisitor { public: - void visit(const std::string& filename) + void visit(const std::string& filename) override { // Wrap this method to python PYBIND11_OVERLOAD_PURE( diff --git a/plugins/script/interfaces/MathInterface.cpp b/plugins/script/interfaces/MathInterface.cpp index cfec95da89..f34bdc25c5 100644 --- a/plugins/script/interfaces/MathInterface.cpp +++ b/plugins/script/interfaces/MathInterface.cpp @@ -9,6 +9,7 @@ #include "math/Vector3.h" #include "math/Vector4.h" #include "render/Vertex3f.h" +#include "string/convert.h" namespace script { @@ -38,9 +39,14 @@ void MathInterface::registerInterface(py::module& scope, py::dict& globals) // Most important operators vec3.def(py::self + py::self); // __add__ vec3.def(py::self - py::self); // __sub__ - vec3.def(py::self += py::self); - vec3.def(py::self -= py::self); + vec3.def(py::self += py::self); // __iadd__ + vec3.def(py::self -= py::self); // __isub__ vec3.def(py::self < py::self); // __lt__ + vec3.def("__repr__", [](const Vector3& vec) + { + return "(" + string::to_string(vec.x()) + " " + string::to_string(vec.y()) + + " " + string::to_string(vec.z()) + ")"; + }); // Register Vertex3f, which extends Vector3 py::class_ vertex3f(scope, "Vertex3f"); @@ -66,6 +72,10 @@ void MathInterface::registerInterface(py::module& scope, py::dict& globals) vec2.def(py::self += py::self); vec2.def(py::self -= py::self); vec2.def(py::self < py::self); // __lt__ + vec2.def("__repr__", [](const Vector2& vec) + { + return "(" + string::to_string(vec.x()) + " " + string::to_string(vec.y()) + ")"; + }); // Add the Vector4 class py::class_ vec4(scope, "Vector4"); @@ -85,6 +95,11 @@ void MathInterface::registerInterface(py::module& scope, py::dict& globals) vec4.def(py::self - py::self); // __sub__ vec4.def(py::self += py::self); vec4.def(py::self -= py::self); + vec4.def("__repr__", [](const Vector4& vec) + { + return "(" + string::to_string(vec.x()) + " " + string::to_string(vec.y()) + " " + + string::to_string(vec.z()) + " " + string::to_string(vec.w()) + ")"; + }); // Add the Vector4 and Quaternion with the same interface scope.add_object("Quaternion", vec4); diff --git a/plugins/script/interfaces/PatchInterface.cpp b/plugins/script/interfaces/PatchInterface.cpp index 4a453b8e8c..f462ad357d 100644 --- a/plugins/script/interfaces/PatchInterface.cpp +++ b/plugins/script/interfaces/PatchInterface.cpp @@ -1,197 +1,187 @@ #include "PatchInterface.h" +#include +#include + #include "ipatch.h" #include "itextstream.h" -#include "../SceneNodeBuffer.h" -#include -namespace script { +#include "../SceneNodeBuffer.h" -class ScriptPatchNode : - public ScriptSceneNode +namespace script { - static const std::string _emptyShader; - static PatchControl _emptyPatchControl; -public: - ScriptPatchNode(const scene::INodePtr& node) : - ScriptSceneNode((node != NULL && Node_isPatch(node)) ? node : scene::INodePtr()) - {} - - // Checks if the given SceneNode structure is a PatchNode - static bool isPatch(const ScriptSceneNode& node) { - return Node_isPatch(node); - } - // "Cast" service for Python, returns a ScriptPatchNode. - // The returned node is non-NULL if the cast succeeded - static ScriptPatchNode getPatch(const ScriptSceneNode& node) { - // Try to cast the node onto a patch - IPatchNodePtr patchNode = std::dynamic_pointer_cast( - static_cast(node) - ); +ScriptPatchNode::ScriptPatchNode(const scene::INodePtr& node) : + ScriptSceneNode((node != NULL && Node_isPatch(node)) ? node : scene::INodePtr()) +{} - // Construct a patchNode (contained node may be NULL) - return (patchNode != NULL) ? ScriptPatchNode(node) : ScriptPatchNode(scene::INodePtr()); - } +bool ScriptPatchNode::isPatch(const ScriptSceneNode& node) +{ + return Node_isPatch(node); +} - // Resizes the patch to the given dimensions - void setDims(std::size_t width, std::size_t height) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; +ScriptPatchNode ScriptPatchNode::getPatch(const ScriptSceneNode& node) +{ + // Try to cast the node onto a patch + IPatchNodePtr patchNode = std::dynamic_pointer_cast( + static_cast(node) + ); - patchNode->getPatch().setDims(width, height); - } + // Construct a patchNode (contained node may be NULL) + return (patchNode != NULL) ? ScriptPatchNode(node) : ScriptPatchNode(scene::INodePtr()); +} - // Get the patch dimensions - std::size_t getWidth() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return 0; +void ScriptPatchNode::setDims(std::size_t width, std::size_t height) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - return patchNode->getPatch().getWidth(); - } + patchNode->getPatch().setDims(width, height); +} - std::size_t getHeight() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return 0; +std::size_t ScriptPatchNode::getWidth() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return 0; - return patchNode->getPatch().getHeight(); - } + return patchNode->getPatch().getWidth(); +} - PatchMesh getTesselatedPatchMesh() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return PatchMesh(); +std::size_t ScriptPatchNode::getHeight() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return 0; - return patchNode->getPatch().getTesselatedPatchMesh(); - } + return patchNode->getPatch().getHeight(); +} - // Return a defined patch control vertex at , - PatchControl& ctrlAt(std::size_t row, std::size_t col) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return _emptyPatchControl; +PatchMesh ScriptPatchNode::getTesselatedPatchMesh() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return PatchMesh(); - IPatch& patch = patchNode->getPatch(); + return patchNode->getPatch().getTesselatedPatchMesh(); +} - if (row > patch.getHeight() || col > patch.getWidth()) - { - rError() << "One or more patch control indices out of bounds: " << row << "," << col << std::endl; - return _emptyPatchControl; - } +PatchControl& ScriptPatchNode::ctrlAt(std::size_t row, std::size_t col) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return _emptyPatchControl; - return patchNode->getPatch().ctrlAt(row, col); - } + IPatch& patch = patchNode->getPatch(); - void insertColumns(std::size_t colIndex) + if (row > patch.getHeight() || col > patch.getWidth()) { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; - - return patchNode->getPatch().insertColumns(colIndex); + rError() << "One or more patch control indices out of bounds: " << row << "," << col << std::endl; + return _emptyPatchControl; } - void insertRows(std::size_t rowIndex) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; + return patchNode->getPatch().ctrlAt(row, col); +} - return patchNode->getPatch().insertRows(rowIndex); - } +void ScriptPatchNode::insertColumns(std::size_t colIndex) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - void removePoints(bool columns, std::size_t index) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; + return patchNode->getPatch().insertColumns(colIndex); +} - return patchNode->getPatch().removePoints(columns, index); - } +void ScriptPatchNode::insertRows(std::size_t rowIndex) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - void appendPoints(bool columns, bool beginning) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; + return patchNode->getPatch().insertRows(rowIndex); +} - return patchNode->getPatch().appendPoints(columns, beginning); - } +void ScriptPatchNode::removePoints(bool columns, std::size_t index) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - // Check if the patch has invalid control points or width/height are zero - bool isValid() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return false; + return patchNode->getPatch().removePoints(columns, index); +} - return patchNode->getPatch().isValid(); - } +void ScriptPatchNode::appendPoints(bool columns, bool beginning) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - // Check whether all control vertices are in the same 3D spot (with minimal tolerance) - bool isDegenerate() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return true; + return patchNode->getPatch().appendPoints(columns, beginning); +} - return patchNode->getPatch().isDegenerate(); - } +bool ScriptPatchNode::isValid() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return false; - void controlPointsChanged() - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; + return patchNode->getPatch().isValid(); +} - patchNode->getPatch().controlPointsChanged(); - } +bool ScriptPatchNode::isDegenerate() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return true; - // Shader handling - const std::string& getShader() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return _emptyShader; + return patchNode->getPatch().isDegenerate(); +} - return patchNode->getPatch().getShader(); - } +void ScriptPatchNode::controlPointsChanged() +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - void setShader(const std::string& name) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; + patchNode->getPatch().controlPointsChanged(); +} - patchNode->getPatch().setShader(name); - } +const std::string& ScriptPatchNode::getShader() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return _emptyShader; - bool hasVisibleMaterial() - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return false; + return patchNode->getPatch().getShader(); +} - return patchNode->getPatch().hasVisibleMaterial(); - } +void ScriptPatchNode::setShader(const std::string& name) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; - bool subdivisionsFixed() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return false; + patchNode->getPatch().setShader(name); +} - return patchNode->getPatch().subdivisionsFixed(); - } +bool ScriptPatchNode::hasVisibleMaterial() +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return false; - Subdivisions getSubdivisions() const - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return Subdivisions(); + return patchNode->getPatch().hasVisibleMaterial(); +} - return patchNode->getPatch().getSubdivisions(); - } +bool ScriptPatchNode::subdivisionsFixed() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return false; - void setFixedSubdivisions(bool isFixed, const Subdivisions& divisions) - { - IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); - if (patchNode == NULL) return; + return patchNode->getPatch().subdivisionsFixed(); +} - patchNode->getPatch().setFixedSubdivisions(isFixed, divisions); - } -}; +Subdivisions ScriptPatchNode::getSubdivisions() const +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return Subdivisions(); + + return patchNode->getPatch().getSubdivisions(); +} + +void ScriptPatchNode::setFixedSubdivisions(bool isFixed, const Subdivisions& divisions) +{ + IPatchNodePtr patchNode = std::dynamic_pointer_cast(_node.lock()); + if (patchNode == NULL) return; + + patchNode->getPatch().setFixedSubdivisions(isFixed, divisions); +} // Initialise static members const std::string ScriptPatchNode::_emptyShader; @@ -221,84 +211,70 @@ ScriptSceneNode PatchInterface::createPatchDef3() return ScriptSceneNode(node); } -void PatchInterface::registerInterface(boost::python::object& nspace) { - nspace["PatchControl"] = boost::python::class_("PatchControl") - .def_readwrite("vertex", &PatchControl::vertex) - .def_readwrite("texcoord", &PatchControl::texcoord) - ; - - nspace["Subdivisions"] = boost::python::class_("Subdivisions", - boost::python::init()) - .def(boost::python::init()) - // greebo: Pick the correct overload - this is hard to read, but it is necessary - .def("x", static_cast(&Subdivisions::x), - boost::python::return_value_policy()) - .def("y", static_cast(&Subdivisions::y), - boost::python::return_value_policy()) - ; - - nspace["PatchMeshVertex"] = boost::python::class_("PatchMeshVertex", - boost::python::init<>()) - .def_readwrite("vertex", &VertexNT::vertex) - .def_readwrite("texcoord", &VertexNT::texcoord) - .def_readwrite("normal", &VertexNT::normal) - ; +void PatchInterface::registerInterface(py::module& scope, py::dict& globals) +{ + py::class_ patchControl(scope, "PatchMeshControl"); + patchControl.def_readwrite("vertex", &PatchControl::vertex); + patchControl.def_readwrite("texcoord", &PatchControl::texcoord); + + py::class_ subdivisions(scope, "Subdivisions"); + subdivisions.def(py::init()); + subdivisions.def(py::init()); + + // greebo: Pick the correct overload - this is hard to read, but it is necessary + subdivisions.def("x", static_cast(&Subdivisions::x), + py::return_value_policy::reference); + subdivisions.def("y", static_cast(&Subdivisions::y), + py::return_value_policy::reference); + + py::class_ patchVertex(scope, "PatchMeshVertex"); + + patchVertex.def(py::init<>()); + patchVertex.def_readwrite("vertex", &VertexNT::vertex); + patchVertex.def_readwrite("texcoord", &VertexNT::texcoord); + patchVertex.def_readwrite("normal", &VertexNT::normal); // Declare the VertexNT vector - boost::python::class_ >("PatchMeshVertices") - .def(boost::python::vector_indexing_suite, true>()) - ; + py::bind_vector< std::vector >(scope, "PatchMeshVertices"); - nspace["PatchMesh"] = boost::python::class_("PatchMesh", - boost::python::init<>()) - .def_readonly("width", &PatchMesh::width) - .def_readonly("height", &PatchMesh::height) - .def_readonly("vertices", &PatchMesh::vertices) - ; + py::class_ patchMesh(scope, "PatchMesh"); + patchMesh.def(py::init<>()); + patchMesh.def_readonly("width", &PatchMesh::width); + patchMesh.def_readonly("height", &PatchMesh::height); + patchMesh.def_readonly("vertices", &PatchMesh::vertices); // Define a PatchNode interface - nspace["PatchNode"] = boost::python::class_ >("PatchNode", boost::python::init() ) - .def("setDims", &ScriptPatchNode::setDims) - .def("getWidth", &ScriptPatchNode::getWidth) - .def("getHeight", &ScriptPatchNode::getHeight) - .def("ctrlAt", &ScriptPatchNode::ctrlAt, - boost::python::return_internal_reference<>()) - .def("insertColumns", &ScriptPatchNode::insertColumns) - .def("insertRows", &ScriptPatchNode::insertRows) - .def("removePoints", &ScriptPatchNode::removePoints) - .def("appendPoints", &ScriptPatchNode::appendPoints) - .def("isValid", &ScriptPatchNode::isValid) - .def("isDegenerate", &ScriptPatchNode::isDegenerate) - .def("getShader", &ScriptPatchNode::getShader, - boost::python::return_value_policy()) - .def("setShader", &ScriptPatchNode::setShader) - .def("hasVisibleMaterial", &ScriptPatchNode::hasVisibleMaterial) - .def("subdivionsFixed", &ScriptPatchNode::subdivisionsFixed) // typo used to be there in previous releases, leave it in there for compatibility reasons - .def("subdivisionsFixed", &ScriptPatchNode::subdivisionsFixed) - .def("getSubdivisions", &ScriptPatchNode::getSubdivisions) - .def("setFixedSubdivisions", &ScriptPatchNode::setFixedSubdivisions) - .def("controlPointsChanged", &ScriptPatchNode::controlPointsChanged) - .def("getTesselatedPatchMesh", &ScriptPatchNode::getTesselatedPatchMesh) - ; - - // Add the "isPatch" and "getPatch" method to all ScriptSceneNodes - boost::python::object sceneNode = nspace["SceneNode"]; - - boost::python::objects::add_to_namespace(sceneNode, - "isPatch", boost::python::make_function(&ScriptPatchNode::isPatch)); - - boost::python::objects::add_to_namespace(sceneNode, - "getPatch", boost::python::make_function(&ScriptPatchNode::getPatch)); + py::class_ patchNode(scope, "PatchNode"); + + patchNode.def(py::init()); + patchNode.def("setDims", &ScriptPatchNode::setDims); + patchNode.def("getWidth", &ScriptPatchNode::getWidth); + patchNode.def("getHeight", &ScriptPatchNode::getHeight); + patchNode.def("ctrlAt", &ScriptPatchNode::ctrlAt, py::return_value_policy::reference_internal); + patchNode.def("insertColumns", &ScriptPatchNode::insertColumns); + patchNode.def("insertRows", &ScriptPatchNode::insertRows); + patchNode.def("removePoints", &ScriptPatchNode::removePoints); + patchNode.def("appendPoints", &ScriptPatchNode::appendPoints); + patchNode.def("isValid", &ScriptPatchNode::isValid); + patchNode.def("isDegenerate", &ScriptPatchNode::isDegenerate); + patchNode.def("getShader", &ScriptPatchNode::getShader, py::return_value_policy::reference); + patchNode.def("setShader", &ScriptPatchNode::setShader); + patchNode.def("hasVisibleMaterial", &ScriptPatchNode::hasVisibleMaterial); + patchNode.def("subdivionsFixed", &ScriptPatchNode::subdivisionsFixed); // typo used to be there in previous releases, leave it in there for compatibility reasons + patchNode.def("subdivisionsFixed", &ScriptPatchNode::subdivisionsFixed); + patchNode.def("getSubdivisions", &ScriptPatchNode::getSubdivisions); + patchNode.def("setFixedSubdivisions", &ScriptPatchNode::setFixedSubdivisions); + patchNode.def("controlPointsChanged", &ScriptPatchNode::controlPointsChanged); + patchNode.def("getTesselatedPatchMesh", &ScriptPatchNode::getTesselatedPatchMesh); // Define the GlobalPatchCreator interface - nspace["GlobalPatchCreator"] = boost::python::class_("GlobalPatchCreator") - .def("createPatchDef2", &PatchInterface::createPatchDef2) - .def("createPatchDef3", &PatchInterface::createPatchDef3) - ; + py::class_ patchCreator(scope, "PatchCreator"); + + patchCreator.def("createPatchDef2", &PatchInterface::createPatchDef2); + patchCreator.def("createPatchDef3", &PatchInterface::createPatchDef3); // Now point the Python variable "GlobalPatchCreator" to this instance - nspace["GlobalPatchCreator"] = boost::python::ptr(this); + globals["GlobalPatchCreator"] = this; } } // namespace script diff --git a/plugins/script/interfaces/PatchInterface.h b/plugins/script/interfaces/PatchInterface.h index 5ceaac2bbd..d1333bca58 100644 --- a/plugins/script/interfaces/PatchInterface.h +++ b/plugins/script/interfaces/PatchInterface.h @@ -1,12 +1,64 @@ -#ifndef _PATCH_INTERFACE_H_ -#define _PATCH_INTERFACE_H_ +#pragma once -#include #include "iscript.h" #include "SceneGraphInterface.h" -namespace script { +namespace script +{ + +class ScriptPatchNode : + public ScriptSceneNode +{ +private: + static const std::string _emptyShader; + static PatchControl _emptyPatchControl; +public: + ScriptPatchNode(const scene::INodePtr& node); + + // Checks if the given SceneNode structure is a PatchNode + static bool isPatch(const ScriptSceneNode& node); + + // "Cast" service for Python, returns a ScriptPatchNode. + // The returned node is non-NULL if the cast succeeded + static ScriptPatchNode getPatch(const ScriptSceneNode& node); + + // Resizes the patch to the given dimensions + void setDims(std::size_t width, std::size_t height); + + // Get the patch dimensions + std::size_t getWidth() const; + std::size_t getHeight() const; + + PatchMesh getTesselatedPatchMesh() const; + + // Return a defined patch control vertex at , + PatchControl& ctrlAt(std::size_t row, std::size_t col); + + void insertColumns(std::size_t colIndex); + void insertRows(std::size_t rowIndex); + + void removePoints(bool columns, std::size_t index); + void appendPoints(bool columns, bool beginning); + + // Check if the patch has invalid control points or width/height are zero + bool isValid() const; + + // Check whether all control vertices are in the same 3D spot (with minimal tolerance) + bool isDegenerate() const; + + void controlPointsChanged(); + + // Shader handling + const std::string& getShader() const; + void setShader(const std::string& name); + + bool hasVisibleMaterial(); + + bool subdivisionsFixed() const; + Subdivisions getSubdivisions() const; + void setFixedSubdivisions(bool isFixed, const Subdivisions& divisions); +}; class PatchInterface : public IScriptInterface @@ -16,10 +68,7 @@ class PatchInterface : ScriptSceneNode createPatchDef3(); // IScriptInterface implementation - void registerInterface(boost::python::object& nspace); + void registerInterface(py::module& scope, py::dict& globals) override; }; -typedef std::shared_ptr PatchInterfacePtr; } // namespace script - -#endif /* _PATCH_INTERFACE_H_ */ diff --git a/plugins/script/interfaces/SceneGraphInterface.cpp b/plugins/script/interfaces/SceneGraphInterface.cpp index c10c75af65..2f4509c633 100644 --- a/plugins/script/interfaces/SceneGraphInterface.cpp +++ b/plugins/script/interfaces/SceneGraphInterface.cpp @@ -8,6 +8,7 @@ #include "ModelInterface.h" #include "BrushInterface.h" #include "EntityInterface.h" +#include "PatchInterface.h" namespace script { @@ -148,6 +149,10 @@ void SceneGraphInterface::registerInterface(py::module& scope, py::dict& globals sceneNode.def("isEntity", &ScriptEntityNode::isEntity); sceneNode.def("getEntity", &ScriptEntityNode::getEntity); + // Add the "is/get" patch methods + sceneNode.def("isPatch", &ScriptPatchNode::isPatch); + sceneNode.def("getPatch", &ScriptPatchNode::getPatch); + py::class_ visitor(scope, "SceneNodeVisitor"); visitor.def(py::init<>()); visitor.def("pre", &scene::NodeVisitor::pre);