[Bf-blender-cvs] [c092cc35b30] master: Expose BLI_string_flip_side_name as bpy.utils.flip_name

Demeter Dzadik noreply at git.blender.org
Tue Nov 9 15:19:58 CET 2021


Commit: c092cc35b30fa121ff579f00bbaf8e2dc981a3f2
Author: Demeter Dzadik
Date:   Wed Nov 10 01:14:56 2021 +1100
Branches: master
https://developer.blender.org/rBc092cc35b30fa121ff579f00bbaf8e2dc981a3f2

Expose BLI_string_flip_side_name as bpy.utils.flip_name

Expose a new function in `bpy.utils.flip_name(name, strip_number=False)
that allows flipping bone names, eg "Bone.L" -> "Bone.R".

Useful for add-ons to avoid re-implementing Blender's name flipping.

Ref D12322

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

M	release/scripts/modules/bpy/utils/__init__.py
M	source/blender/python/intern/bpy.c

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

diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 3f0248970c6..950a254072e 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -26,6 +26,7 @@ not associated with blenders internal data.
 __all__ = (
     "blend_paths",
     "escape_identifier",
+    "flip_name",
     "unescape_identifier",
     "keyconfig_init",
     "keyconfig_set",
@@ -61,6 +62,7 @@ from _bpy import (
     _utils_units as units,
     blend_paths,
     escape_identifier,
+    flip_name,
     unescape_identifier,
     register_class,
     resource_path,
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 7646109c1b0..3377b2c283e 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -22,9 +22,13 @@
  * A script writer should never directly access this module.
  */
 
+/* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
+#define PY_SSIZE_T_CLEAN
+
 #include <Python.h>
 
 #include "BLI_string.h"
+#include "BLI_string_utils.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_appdir.h"
@@ -149,6 +153,52 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
   return list;
 }
 
+PyDoc_STRVAR(bpy_flip_name_doc,
+             ".. function:: flip_name(name, strip_digits=False)\n"
+             "\n"
+             "   Flip a name between left/right sides, useful for \n"
+             "   mirroring bone names.\n"
+             "\n"
+             "   :arg name: Bone name to flip.\n"
+             "   :type name: string\n"
+             "   :arg strip_digits: Whether to remove ``.###`` suffix.\n"
+             "   :type strip_digits: bool\n"
+             "   :return: The flipped name.\n"
+             "   :rtype: string\n");
+static PyObject *bpy_flip_name(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
+{
+  const char *name_src = NULL;
+  Py_ssize_t name_src_len;
+  bool strip_digits = false;
+
+  static const char *_keywords[] = {"", "strip_digits", NULL};
+  static _PyArg_Parser _parser = {
+      "s#" /* `name` */
+      "|$" /* Optional, keyword only arguments. */
+      "O&" /* `strip_digits` */
+      /* Name to show in the case of an error. */
+      ":flip_name",
+      _keywords,
+      0,
+  };
+  if (!_PyArg_ParseTupleAndKeywordsFast(
+          args, kw, &_parser, &name_src, &name_src_len, PyC_ParseBool, &strip_digits)) {
+    return NULL;
+  }
+
+  /* Worst case we gain one extra byte (besides null-terminator) by changing
+  "Left" to "Right", because only the first appearance of "Left" gets replaced. */
+  const size_t size = name_src_len + 2;
+  char *name_dst = PyMem_MALLOC(size);
+  const size_t name_dst_len = BLI_string_flip_side_name(name_dst, name_src, strip_digits, size);
+
+  PyObject *result = PyUnicode_FromStringAndSize(name_dst, name_dst_len);
+
+  PyMem_FREE(name_dst);
+
+  return result;
+}
+
 // PyDoc_STRVAR(bpy_user_resource_doc[] = /* now in bpy/utils.py */
 static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
 {
@@ -338,6 +388,12 @@ static PyMethodDef meth_bpy_blend_paths = {
     METH_VARARGS | METH_KEYWORDS,
     bpy_blend_paths_doc,
 };
+static PyMethodDef meth_bpy_flip_name = {
+    "flip_name",
+    (PyCFunction)bpy_flip_name,
+    METH_VARARGS | METH_KEYWORDS,
+    bpy_flip_name_doc,
+};
 static PyMethodDef meth_bpy_user_resource = {
     "user_resource",
     (PyCFunction)bpy_user_resource,
@@ -472,6 +528,8 @@ void BPy_init_modules(struct bContext *C)
   PyModule_AddObject(mod,
                      meth_bpy_unescape_identifier.ml_name,
                      (PyObject *)PyCFunction_New(&meth_bpy_unescape_identifier, NULL));
+  PyModule_AddObject(
+      mod, meth_bpy_flip_name.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_flip_name, NULL));
 
   /* register funcs (bpy_rna.c) */
   PyModule_AddObject(mod,



More information about the Bf-blender-cvs mailing list