[Bf-blender-cvs] [f4fe405da9c] blender2.8: Manipulator: Add API target_get/set/range wrappers

Campbell Barton noreply at git.blender.org
Tue Aug 22 10:53:34 CEST 2017


Commit: f4fe405da9ccb453c58a9949c0b80864da567c64
Author: Campbell Barton
Date:   Tue Aug 22 18:55:19 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBf4fe405da9ccb453c58a9949c0b80864da567c64

Manipulator: Add API target_get/set/range wrappers

Allows Python manipulators access the values of target properties
needed for Python to make use of the general target property interface.

===================================================================

M	release/scripts/modules/bpy_types.py
M	source/blender/makesrna/intern/rna_wm_manipulator_api.c
M	source/blender/python/intern/bpy_rna_manipulator.c

===================================================================

diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 407f0a35fb3..78c70225a04 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -618,7 +618,12 @@ class Manipulator(StructRNA, metaclass=OrderedMeta):
             return delattr(properties, attr)
         return super().__delattr__(attr)
 
-    target_set_handler = _bpy._rna_manipulator_target_set_handler
+    from _bpy import (
+        _rna_manipulator_target_set_handler as target_set_handler,
+        _rna_manipulator_target_get_value as target_get_value,
+        _rna_manipulator_target_set_value as target_set_value,
+        _rna_manipulator_target_get_range as target_get_range,
+    )
 
     # Convenience wrappers around private `_gawain` module.
     def draw_custom_shape(self, shape, *, matrix=None, select_id=None):
diff --git a/source/blender/makesrna/intern/rna_wm_manipulator_api.c b/source/blender/makesrna/intern/rna_wm_manipulator_api.c
index f40a2208cf9..a0d474968d0 100644
--- a/source/blender/makesrna/intern/rna_wm_manipulator_api.c
+++ b/source/blender/makesrna/intern/rna_wm_manipulator_api.c
@@ -71,6 +71,10 @@ static void rna_manipulator_draw_preset_facemap(
 	ED_manipulator_draw_preset_facemap(C, mpr, scene, ob, facemap, select_id);
 }
 
+/* -------------------------------------------------------------------- */
+/** \name Manipulator Property Define
+ * \{ */
+
 static void rna_manipulator_target_set_prop(
         wmManipulator *mpr, ReportList *reports, const char *target_propname,
         PointerRNA *ptr, const char *propname, int index)
@@ -158,6 +162,27 @@ static PointerRNA rna_manipulator_target_set_operator(
 	return mpr->op_data.ptr;
 }
 
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Manipulator Property Access
+ * \{ */
+
+static int rna_manipulator_target_is_valid(
+        wmManipulator *mpr, ReportList *reports, const char *target_propname)
+{
+	wmManipulatorProperty *mpr_prop =
+	        WM_manipulator_target_property_find(mpr, target_propname);
+	if (mpr_prop == NULL) {
+		BKE_reportf(reports, RPT_ERROR, "Manipulator target property '%s.%s' not found",
+		            mpr->type->idname, target_propname);
+		return false;
+	}
+	return WM_manipulator_target_property_is_valid(mpr_prop);
+}
+
+/** \} */
+
 #else
 
 void RNA_api_manipulator(StructRNA *srna)
@@ -218,6 +243,7 @@ void RNA_api_manipulator(StructRNA *srna)
 	/* -------------------------------------------------------------------- */
 	/* Property API */
 
+	/* Define Properties */
 	/* note, 'target_set_handler' is defined in 'bpy_rna_manipulator.c' */
 	func = RNA_def_function(srna, "target_set_prop", "rna_manipulator_target_set_prop");
 	RNA_def_function_flag(func, FUNC_USE_REPORTS);
@@ -243,6 +269,16 @@ void RNA_api_manipulator(StructRNA *srna)
 	RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
 	RNA_def_function_return(func, parm);
 
+	/* Access Properties */
+	/* note, 'target_get', 'target_set' is defined in 'bpy_rna_manipulator.c' */
+	func = RNA_def_function(srna, "target_is_valid", "rna_manipulator_target_is_valid");
+	RNA_def_function_flag(func, FUNC_USE_REPORTS);
+	parm = RNA_def_string(func, "property", NULL, 0, "", "Property identifier");
+	RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+	RNA_def_function_ui_description(func, "");
+	parm = RNA_def_boolean(func, "result", 0, "", "");
+	RNA_def_function_return(func, parm);
+
 }
 
 
diff --git a/source/blender/python/intern/bpy_rna_manipulator.c b/source/blender/python/intern/bpy_rna_manipulator.c
index 7543f53cf20..01a606e405a 100644
--- a/source/blender/python/intern/bpy_rna_manipulator.c
+++ b/source/blender/python/intern/bpy_rna_manipulator.c
@@ -30,6 +30,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_alloca.h"
 
 #include "BKE_main.h"
 
@@ -48,6 +49,11 @@
 
 #include "bpy_rna.h"
 
+
+/* -------------------------------------------------------------------- */
+/** \name Manipulator Target Property Define API
+ * \{ */
+
 enum {
 	BPY_MANIPULATOR_FN_SLOT_GET = 0,
 	BPY_MANIPULATOR_FN_SLOT_SET,
@@ -75,7 +81,7 @@ static void py_rna_manipulator_handler_get_cb(
 	if (mpr_prop->type->data_type == PROP_FLOAT) {
 		float *value = value_p;
 		if (mpr_prop->type->array_length == 1) {
-			if (((*value = PyFloat_AsDouble(ret)) == -1.0f && PyErr_Occurred()) == 0) {
+			if ((*value = PyFloat_AsDouble(ret)) == -1.0f && PyErr_Occurred()) {
 				goto fail;
 			}
 		}
@@ -333,20 +339,275 @@ fail:
 	return NULL;
 }
 
-int BPY_rna_manipulator_module(PyObject *mod_par)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Manipulator Target Property Access API
+ * \{ */
+
+PyDoc_STRVAR(bpy_manipulator_target_get_value_doc,
+".. method:: target_get_value(target):\n"
+"\n"
+"   Get the value of this target property.\n"
+"\n"
+"   :arg target: Target property name.\n"
+"   :type target: string\n"
+"   :return: The value of the target property.\n"
+"   :rtype: Single value or array based on the target type\n"
+);
+static PyObject *bpy_manipulator_target_get_value(PyObject *UNUSED(self), PyObject *args, PyObject *kwds)
 {
-	static PyMethodDef method_def = {
-	    "target_set_handler", (PyCFunction)bpy_manipulator_target_set_handler, METH_VARARGS | METH_KEYWORDS,
-	    bpy_manipulator_target_set_handler_doc};
+	struct {
+		PyObject *self;
+		char *target;
+	} params = {
+		.self = NULL,
+		.target = NULL,
+	};
 
-	PyObject *func = PyCFunction_New(&method_def, NULL);
-	PyObject *func_inst = PyInstanceMethod_New(func);
+	static const char * const _keywords[] = {"self", "target", NULL};
+#define KW_FMT "Os:target_get_value"
+#if PY_VERSION_HEX >= 0x03070000
+	static _PyArg_Parser _parser = {KW_FMT, _keywords, 0};
+	if (!_PyArg_ParseTupleAndKeywordsFast(
+	        args, kwds,
+	        &_parser,
+	        &params.self,
+	        &params.target))
+#else
+	if (!PyArg_ParseTupleAndKeywords(
+	        args, kwds,
+	        KW_FMT, (char **)_keywords,
+	        &params.self,
+	        &params.target))
+#endif
+	{
+		goto fail;
+	}
+#undef KW_FMT
 
+	wmManipulator *mpr = ((BPy_StructRNA *)params.self)->ptr.data;
 
-	/* TODO, return a type that binds nearly to a method. */
-	PyModule_AddObject(mod_par, "_rna_manipulator_target_set_handler", func_inst);
+	wmManipulatorProperty *mpr_prop =
+	        WM_manipulator_target_property_find(mpr, params.target);
+	if (mpr_prop == NULL) {
+		PyErr_Format(PyExc_ValueError,
+		             "Manipulator target property '%s.%s' not found",
+		             mpr->type->idname, params.target);
+		goto fail;
+	}
 
-	return 0;
+	const int array_len = WM_manipulator_target_property_array_length(mpr, mpr_prop);
+	switch (mpr_prop->type->data_type) {
+		case PROP_FLOAT:
+		{
+			if (array_len != 0) {
+				float *value = BLI_array_alloca(value, array_len);
+				WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value);
+				return PyC_Tuple_PackArray_F32(value, array_len);
+			}
+			else {
+				float value = WM_manipulator_target_property_value_get(mpr, mpr_prop);
+				return PyFloat_FromDouble(value);
+			}
+			break;
+		}
+		default:
+		{
+			PyErr_SetString(PyExc_RuntimeError, "Not yet supported type");
+			goto fail;
+		}
+	}
+
+fail:
+	return NULL;
+}
+
+PyDoc_STRVAR(bpy_manipulator_target_set_value_doc,
+".. method:: target_set_value(target):\n"
+"\n"
+"   Set the value of this target property.\n"
+"\n"
+"   :arg target: Target property name.\n"
+"   :type target: string\n"
+);
+static PyObject *bpy_manipulator_target_set_value(PyObject *UNUSED(self), PyObject *args, PyObject *kwds)
+{
+	struct {
+		PyObject *self;
+		char *target;
+		PyObject *value;
+	} params = {
+		.self = NULL,
+		.target = NULL,
+		.value = NULL,
+	};
+
+	static const char * const _keywords[] = {"self", "target", "value", NULL};
+#define KW_FMT "OsO:target_set_value"
+#if PY_VERSION_HEX >= 0x03070000
+	static _PyArg_Parser _parser = {KW_FMT, _keywords, 0};
+	if (!_PyArg_ParseTupleAndKeywordsFast(
+	        args, kwds,
+	        &_parser,
+	        &params.self,
+	        &params.target,
+	        &params.value))
+#else
+	if (!PyArg_ParseTupleAndKeywords(
+	        args, kwds,
+	        KW_FMT, (char **)_keywords,
+	        &params.self,
+	        &params.target,
+	        &params.value))
+#endif
+	{
+		goto fail;
+	}
+#undef KW_FMT
+
+	wmManipulator *mpr = ((BPy_StructRNA *)params.self)->ptr.data;
+
+	wmManipulatorProperty *mpr_prop =
+	        WM_manipulator_target_property_find(mpr, params.target);
+	if (mpr_prop == NULL) {
+		PyErr_Format(PyExc_ValueError,
+		             "Manipulator target property '%s.%s' not found",
+		             mpr->type->idname, params.target);
+		goto fail;
+	}
+
+	const int array_len = WM_manipulator_target_property_array_length(mpr, mpr_prop);
+	switch (mpr_prop->type->data_type) {
+		case PROP_FLOAT:
+		{
+			if (array_len != 0) {
+				float *value = BLI_array_alloca(value, array_len);
+				if (PyC_AsArray(value, params.value, mpr_prop->type->array_length, &PyFloat_Type, false,
+				                "Manipulator target property array") == -1)
+				{
+					goto fail;
+				}
+				WM_manipulator_target_property_value_set_array(BPy_GetContext(), mpr, mpr_prop, value);
+			}
+			else {
+				float value;
+				if ((value = PyFloat_AsDouble(params.value)) == -1.0f && PyErr_Occurred()) {
+					goto fail;
+				}
+				WM_manipulator_target_property_value_set(BPy_GetContext(), mpr, mpr_prop, value);
+			}
+			Py_RETURN_NONE;
+		}
+		default:
+		{
+			PyErr_SetString(PyExc_RuntimeError, "Not yet supported type");
+			goto fail;
+		}
+	}
+
+fail:
+	return NULL;
 }
 
 
+PyDoc_STRVAR(bpy_manipulator_target_get_range_doc,
+".. method:: target_get_range(target):\n"
+"\n"
+"   Get the range for this target property.\n"
+"\n"
+"   :arg target: Target property name.\n"
+"   :Get the range for this target property"
+"   :return: The range of this property (min, max).\n"
+"   :rtype: tuple pair.\n"
+);
+static PyObject *bpy_manipulator_target_get_range(PyObject *UNUSED(self), PyObject *args, PyObject *kwds)
+{
+	struct {
+		PyObject *self;
+		char *target;
+	} params = {
+		.self = NULL,
+		.target = NULL,
+	};
+
+	static c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list