diff --git a/src/Mod/Path/App/CommandPy.xml b/src/Mod/Path/App/CommandPy.xml
index 14e6df4109..1588b9dbe1 100644
--- a/src/Mod/Path/App/CommandPy.xml
+++ b/src/Mod/Path/App/CommandPy.xml
@@ -43,7 +43,7 @@ pairs, or a placement, or a vector
- toGCode(): returns a GCode representation of the command
+ setFromGCode(): sets the path from the contents of the given GCode string
@@ -51,5 +51,8 @@ pairs, or a placement, or a vector
transform(Placement): returns a copy of this command transformed by the given placement
+
+ mutable Py::Dict parameters_copy_dict;
+
diff --git a/src/Mod/Path/App/CommandPyImp.cpp b/src/Mod/Path/App/CommandPyImp.cpp
index 98dc904264..88bd30fce5 100644
--- a/src/Mod/Path/App/CommandPyImp.cpp
+++ b/src/Mod/Path/App/CommandPyImp.cpp
@@ -56,6 +56,11 @@ std::string CommandPy::representation(void) const
return str.str();
}
+//
+// Py::Dict parameters_copy_dict is now a class member to avoid delete/create/copy on every read access from python code
+// Now the pre-filled Py::Dict is returned which is more consistent with normal python behaviour.
+// It should be cleared whenever the c++ Parameters object is changed eg setParameters() or other objects invalidate its content, eg setPlacement()
+// https://forum.freecadweb.org/viewtopic.php?f=15&t=50583
PyObject *CommandPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
{
@@ -117,6 +122,7 @@ int CommandPy::PyInit(PyObject* args, PyObject* kwd)
}
getCommandPtr()->Parameters[ckey]=cvalue;
}
+ parameters_copy_dict.clear();
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
@@ -157,11 +163,13 @@ void CommandPy::setName(Py::String arg)
Py::Dict CommandPy::getParameters(void) const
{
- Py::Dict dict;
- for(std::map::iterator i = getCommandPtr()->Parameters.begin(); i != getCommandPtr()->Parameters.end(); ++i) {
- dict.setItem(i->first, Py::Float(i->second));
+ // dict now a class member , https://forum.freecadweb.org/viewtopic.php?f=15&t=50583
+ if (parameters_copy_dict.length()==0) {
+ for(std::map::iterator i = getCommandPtr()->Parameters.begin(); i != getCommandPtr()->Parameters.end(); ++i) {
+ parameters_copy_dict.setItem(i->first, Py::Float(i->second));
+ }
}
- return dict;
+ return parameters_copy_dict;
}
void CommandPy::setParameters(Py::Dict arg)
@@ -200,6 +208,7 @@ void CommandPy::setParameters(Py::Dict arg)
throw Py::TypeError("The dictionary can only contain number values");
}
getCommandPtr()->Parameters[ckey]=cvalue;
+ parameters_copy_dict.clear();
}
}
@@ -224,6 +233,7 @@ PyObject* CommandPy::setFromGCode(PyObject *args)
std::string gcode(pstr);
try {
getCommandPtr()->setFromGCode(gcode);
+ parameters_copy_dict.clear();
}
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_ValueError, e.what());
@@ -249,6 +259,7 @@ void CommandPy::setPlacement(Py::Object arg)
Py::Type PlacementType(pyType.o);
if(arg.isType(PlacementType)) {
getCommandPtr()->setFromPlacement( *static_cast((*arg))->getPlacementPtr() );
+ parameters_copy_dict.clear();
} else
throw Py::TypeError("Argument must be a placement");
}
@@ -259,6 +270,7 @@ PyObject* CommandPy::transform(PyObject *args)
if ( PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &placement) ) {
Base::PlacementPy *p = static_cast(placement);
Path::Command trCmd = getCommandPtr()->transform( *p->getPlacementPtr() );
+ parameters_copy_dict.clear();
return new CommandPy(new Path::Command(trCmd));
} else
throw Py::TypeError("Argument must be a placement");
@@ -302,6 +314,7 @@ int CommandPy::setCustomAttributes(const char* attr, PyObject* obj)
return 0;
}
getCommandPtr()->Parameters[satt]=cvalue;
+ parameters_copy_dict.clear();
return 1;
}
}