diff --git a/src/App/PropertyStandard.cpp b/src/App/PropertyStandard.cpp
index 606b47e07f..96e3984005 100644
--- a/src/App/PropertyStandard.cpp
+++ b/src/App/PropertyStandard.cpp
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include "PropertyStandard.h"
#include "Application.h"
@@ -663,7 +664,7 @@ long PropertyIntegerConstraint::getMinimum() const
return _ConstStruct->LowerBound;
}
// return the min of int, not long
- return std::numeric_limits::min();
+ return std::numeric_limits::lowest();
}
long PropertyIntegerConstraint::getMaximum() const
@@ -700,41 +701,64 @@ void PropertyIntegerConstraint::setPyObject(PyObject* value)
_lValue = temp;
hasSetValue();
}
- else if (PyTuple_Check(value) && PyTuple_Size(value) == 4) {
- long values[4];
- for (int i = 0; i < 4; i++) {
- PyObject* item;
- item = PyTuple_GetItem(value, i);
- if (PyLong_Check(item)) {
- values[i] = PyLong_AsLong(item);
+ else {
+ long valConstr[] = {0,
+ std::numeric_limits::lowest(),
+ std::numeric_limits::max(),
+ 1};
+
+ if (PyDict_Check(value)) {
+ Py::Tuple dummy;
+ static const std::array kw = {"value",
+ "min",
+ "max",
+ "step",
+ nullptr};
+
+ if (!Base::Wrapped_ParseTupleAndKeywords(dummy.ptr(),
+ value,
+ "l|lll",
+ kw,
+ &(valConstr[0]),
+ &(valConstr[1]),
+ &(valConstr[2]),
+ &(valConstr[3]))) {
+ throw Py::Exception();
}
- else {
- throw Base::TypeError("Type in tuple must be int");
+ }
+ else if (PyTuple_Check(value)) {
+ if (!PyArg_ParseTuple(value,
+ "llll",
+ &(valConstr[0]),
+ &(valConstr[1]),
+ &(valConstr[2]),
+ &(valConstr[3]))) {
+ throw Py::Exception();
}
}
+ else {
+ std::string error = std::string("type must be int, dict or tuple, not ");
+ error += value->ob_type->tp_name;
+ throw Base::TypeError(error);
+ }
Constraints* c = new Constraints();
c->setDeletable(true);
- c->LowerBound = values[1];
- c->UpperBound = values[2];
- c->StepSize = std::max(1, values[3]);
- if (values[0] > c->UpperBound) {
- values[0] = c->UpperBound;
+ c->LowerBound = valConstr[1];
+ c->UpperBound = valConstr[2];
+ c->StepSize = std::max(1, valConstr[3]);
+ if (valConstr[0] > c->UpperBound) {
+ valConstr[0] = c->UpperBound;
}
- else if (values[0] < c->LowerBound) {
- values[0] = c->LowerBound;
+ else if (valConstr[0] < c->LowerBound) {
+ valConstr[0] = c->LowerBound;
}
setConstraints(c);
aboutToSetValue();
- _lValue = values[0];
+ _lValue = valConstr[0];
hasSetValue();
}
- else {
- std::string error = std::string("type must be int, not ");
- error += value->ob_type->tp_name;
- throw Base::TypeError(error);
- }
}
//**************************************************************************
@@ -1122,7 +1146,7 @@ double PropertyFloatConstraint::getMinimum() const
if (_ConstStruct) {
return _ConstStruct->LowerBound;
}
- return std::numeric_limits::min();
+ return std::numeric_limits::lowest();
}
double PropertyFloatConstraint::getMaximum() const
@@ -1159,7 +1183,7 @@ void PropertyFloatConstraint::setPyObject(PyObject* value)
hasSetValue();
}
else if (PyLong_Check(value)) {
- double temp = (double)PyLong_AsLong(value);
+ double temp = static_cast(PyLong_AsLong(value));
if (_ConstStruct) {
if (temp > _ConstStruct->UpperBound) {
temp = _ConstStruct->UpperBound;
@@ -1173,23 +1197,48 @@ void PropertyFloatConstraint::setPyObject(PyObject* value)
_dValue = temp;
hasSetValue();
}
- else if (PyTuple_Check(value) && PyTuple_Size(value) == 4) {
- double values[4];
- for (int i = 0; i < 4; i++) {
- PyObject* item;
- item = PyTuple_GetItem(value, i);
- if (PyFloat_Check(item)) {
- values[i] = PyFloat_AsDouble(item);
- }
- else if (PyLong_Check(item)) {
- values[i] = PyLong_AsLong(item);
- }
- else {
- throw Base::TypeError("Type in tuple must be float or int");
+ else {
+ double valConstr[] = {0.0,
+ std::numeric_limits::lowest(),
+ std::numeric_limits::max(),
+ 1.0};
+
+ if (PyDict_Check(value)) {
+ Py::Tuple dummy;
+ static const std::array kw = {"value",
+ "min",
+ "max",
+ "step",
+ nullptr};
+
+ if (!Base::Wrapped_ParseTupleAndKeywords(dummy.ptr(),
+ value,
+ "d|ddd",
+ kw,
+ &(valConstr[0]),
+ &(valConstr[1]),
+ &(valConstr[2]),
+ &(valConstr[3]))) {
+ throw Py::Exception();
}
}
+ else if (PyTuple_Check(value)) {
+ if (!PyArg_ParseTuple(value,
+ "dddd",
+ &(valConstr[0]),
+ &(valConstr[1]),
+ &(valConstr[2]),
+ &(valConstr[3]))) {
+ throw Py::Exception();
+ }
+ }
+ else {
+ std::string error = std::string("type must be float, dict or tuple, not ");
+ error += value->ob_type->tp_name;
+ throw Base::TypeError(error);
+ }
- double stepSize = values[3];
+ double stepSize = valConstr[3];
// need a value > 0
if (stepSize < DBL_EPSILON) {
throw Base::ValueError("Step size must be greater than zero");
@@ -1197,26 +1246,21 @@ void PropertyFloatConstraint::setPyObject(PyObject* value)
Constraints* c = new Constraints();
c->setDeletable(true);
- c->LowerBound = values[1];
- c->UpperBound = values[2];
+ c->LowerBound = valConstr[1];
+ c->UpperBound = valConstr[2];
c->StepSize = stepSize;
- if (values[0] > c->UpperBound) {
- values[0] = c->UpperBound;
+ if (valConstr[0] > c->UpperBound) {
+ valConstr[0] = c->UpperBound;
}
- else if (values[0] < c->LowerBound) {
- values[0] = c->LowerBound;
+ else if (valConstr[0] < c->LowerBound) {
+ valConstr[0] = c->LowerBound;
}
setConstraints(c);
aboutToSetValue();
- _dValue = values[0];
+ _dValue = valConstr[0];
hasSetValue();
}
- else {
- std::string error = std::string("type must be float, not ");
- error += value->ob_type->tp_name;
- throw Base::TypeError(error);
- }
}
//**************************************************************************
diff --git a/src/Mod/Fem/femobjects/mesh_netgen.py b/src/Mod/Fem/femobjects/mesh_netgen.py
index 9d7048a4d9..ec9f5e9067 100644
--- a/src/Mod/Fem/femobjects/mesh_netgen.py
+++ b/src/Mod/Fem/femobjects/mesh_netgen.py
@@ -77,11 +77,11 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="OptimizationSteps3d",
group="Mesh Parameters",
doc="Number of 3d optimization steps",
- value=3,
+ value={"value": 3, "min": 0},
)
)
prop.append(
@@ -98,11 +98,11 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="OptimizationSteps2d",
group="Mesh Parameters",
doc="Number of 2d optimization steps",
- value=3,
+ value={"value": 3, "min": 0},
)
)
prop.append(
@@ -134,20 +134,20 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="Safety",
group="Mesh Parameters",
doc="Radius of local environment (times h)",
- value=5.0,
+ value={"value": 5.0, "min": 0, "step": 0.1},
)
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="RelinnerSafety",
group="Mesh Parameters",
doc="Radius of active environment (times h)",
- value=3.0,
+ value={"value": 3.0, "min": 0, "step": 0.1},
)
)
prop.append(
@@ -170,11 +170,11 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="GrowthRate",
group="Mesh Parameters",
doc="Grading for local h",
- value=0.3,
+ value={"value": 0.3, "min": 0, "step": 0.1},
)
)
prop.append(
@@ -215,11 +215,11 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="CloseEdgeFactor",
group="Mesh Parameters",
doc="Factor to restrict meshing based on close edges",
- value=2.0,
+ value={"value": 2.0, "min": 0, "step": 0.1},
)
)
prop.append(
@@ -260,29 +260,29 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="CurvatureSafety",
group="Mesh Parameters",
doc="Safety factor for curvatures (elements per radius)",
- value=2.0,
+ value={"value": 2.0, "min": 0, "step": 0.1},
)
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="SegmentsPerEdge",
group="Mesh Parameters",
doc="Minimal number of segments per edge",
- value=2.0,
+ value={"value": 2.0, "min": 0, "step": 0.1},
)
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="ElementSizeWeight",
group="Mesh Parameters",
- doc="Weight of element size respect to element shape",
- value=0.2,
+ doc="Weight of element size respect to element shape",
+ value={"value": 0.2, "min": 0, "step": 0.1},
)
)
@@ -316,47 +316,47 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="GiveUpTolerance2d",
group="Mesh Parameters",
doc="Give up quality class, 2d meshing",
- value=200,
+ value={"value": 200, "min": 0},
)
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="GiveUpTolerance",
group="Mesh Parameters",
doc="Give up quality class, 3d meshing",
- value=10,
+ value={"value": 10, "min": 0},
)
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="GiveUpToleranceOpenQuads",
group="Mesh Parameters",
doc="Give up quality class, for closing open quads, greater than 100 for free pyramids",
- value=15,
+ value={"value": 15, "min": 0},
)
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="MaxOuterSteps",
group="Mesh Parameters",
doc="Maximal outer steps",
- value=10,
+ value={"value": 10, "min": 0},
)
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="StarShapeClass",
group="Mesh Parameters",
doc="Class starting star-shape filling",
- value=5,
+ value={"value": 5, "min": 0},
)
)
prop.append(
@@ -370,20 +370,20 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="Sloppy",
group="Mesh Parameters",
doc="Quality tolerances are handled less careful",
- value=10,
+ value={"value": 10, "min": 0},
)
)
prop.append(
_PropHelper(
- type="App::PropertyFloat",
+ type="App::PropertyFloatConstraint",
name="BadElementLimit",
group="Mesh Parameters",
doc="Limit for max element angle (150-180)",
- value=175,
+ value={"value": 175, "min": 0},
)
)
prop.append(
@@ -424,11 +424,11 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
)
prop.append(
_PropHelper(
- type="App::PropertyInteger",
+ type="App::PropertyIntegerConstraint",
name="ElementOrder",
group="Mesh Parameters",
doc="High order element curvature",
- value=False,
+ value={"value": 1, "min": 1},
)
)
prop.append(