diff --git a/src/Mod/CAM/App/Command.cpp b/src/Mod/CAM/App/Command.cpp index 5162b5f019..968159f843 100644 --- a/src/Mod/CAM/App/Command.cpp +++ b/src/Mod/CAM/App/Command.cpp @@ -47,6 +47,16 @@ Command::Command(const char* name, const std::map& paramete , Annotations() {} +Command::Command( + const char* name, + const std::map& parameters, + const std::map>& annotations +) + : Name(name) + , Parameters(parameters) + , Annotations(annotations) +{} + Command::Command() : Annotations() {} diff --git a/src/Mod/CAM/App/Command.h b/src/Mod/CAM/App/Command.h index 6c7cc3c52f..f93ca2fbab 100644 --- a/src/Mod/CAM/App/Command.h +++ b/src/Mod/CAM/App/Command.h @@ -44,6 +44,11 @@ public: // constructors Command(); Command(const char* name, const std::map& parameters); + Command( + const char* name, + const std::map& parameters, + const std::map>& annotations + ); ~Command() override; // from base class unsigned int getMemSize() const override; diff --git a/src/Mod/CAM/App/Command.pyi b/src/Mod/CAM/App/Command.pyi index ac6d9747f3..7cf426a027 100644 --- a/src/Mod/CAM/App/Command.pyi +++ b/src/Mod/CAM/App/Command.pyi @@ -13,10 +13,11 @@ from Base.Placement import Placement @class_declarations("mutable Py::Dict parameters_copy_dict;") class Command(Persistence): """ - Command([name],[parameters]): Represents a basic Gcode command + Command([name],[parameters],[annotations]): Represents a basic Gcode command name (optional) is the name of the command, ex. G1 parameters (optional) is a dictionary containing string:number pairs, or a placement, or a vector + annotations (optional) is a dictionary containing string:string or string:number pairs """ @constmethod diff --git a/src/Mod/CAM/App/CommandPyImp.cpp b/src/Mod/CAM/App/CommandPyImp.cpp index 53a9253727..81cc040d63 100644 --- a/src/Mod/CAM/App/CommandPyImp.cpp +++ b/src/Mod/CAM/App/CommandPyImp.cpp @@ -71,9 +71,20 @@ PyObject* CommandPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Pytho int CommandPy::PyInit(PyObject* args, PyObject* kwd) { PyObject* parameters = nullptr; + PyObject* annotations = nullptr; const char* name = ""; - static const std::array kwlist {"name", "parameters", nullptr}; - if (Base::Wrapped_ParseTupleAndKeywords(args, kwd, "|sO!", kwlist, &name, &PyDict_Type, ¶meters)) { + static const std::array kwlist {"name", "parameters", "annotations", nullptr}; + if (Base::Wrapped_ParseTupleAndKeywords( + args, + kwd, + "|sO!O!", + kwlist, + &name, + &PyDict_Type, + ¶meters, + &PyDict_Type, + &annotations + )) { std::string sname(name); boost::to_upper(sname); try { @@ -112,16 +123,54 @@ int CommandPy::PyInit(PyObject* args, PyObject* kwd) } getCommandPtr()->Parameters[ckey] = cvalue; } + + // Parse annotations + pos = 0; + while (annotations && PyDict_Next(annotations, &pos, &key, &value)) { + std::string ckey; + if (PyUnicode_Check(key)) { + ckey = PyUnicode_AsUTF8(key); + } + else { + PyErr_SetString( + PyExc_TypeError, + "The annotations dictionary can only contain string keys" + ); + return -1; + } + + if (PyUnicode_Check(value)) { + std::string cvalue = PyUnicode_AsUTF8(value); + getCommandPtr()->setAnnotation(ckey, cvalue); + } + else if (PyObject_TypeCheck(value, &(PyLong_Type))) { + double cvalue = (double)PyLong_AsLong(value); + getCommandPtr()->setAnnotation(ckey, cvalue); + } + else if (PyObject_TypeCheck(value, &(PyFloat_Type))) { + double cvalue = PyFloat_AsDouble(value); + getCommandPtr()->setAnnotation(ckey, cvalue); + } + else { + PyErr_SetString( + PyExc_TypeError, + "The annotations dictionary can only contain string or number values" + ); + return -1; + } + } + parameters_copy_dict.clear(); return 0; } PyErr_Clear(); // set by PyArg_ParseTuple() + static const std::array kwlist_placement {"name", "parameters", nullptr}; if (Base::Wrapped_ParseTupleAndKeywords( args, kwd, "|sO!", - kwlist, + kwlist_placement, &name, &(Base::PlacementPy::Type), ¶meters