[Bf-blender-cvs] [ef68a37e5d5] master: Custom Properties: Add boolean type

Hans Goudey noreply at git.blender.org
Fri Jan 13 19:39:39 CET 2023


Commit: ef68a37e5d55e17adf4cc8e3349eaf0243dbf15e
Author: Hans Goudey
Date:   Fri Jan 13 12:31:27 2023 -0600
Branches: master
https://developer.blender.org/rBef68a37e5d55e17adf4cc8e3349eaf0243dbf15e

Custom Properties: Add boolean type

A proper boolean custom property type is commonly requested. This
commit simply adds a new `IDP_BOOLEAN` type that can be used for
boolean and boolean array custom properties. This can also be used
for exposing boolean node sockets in the geometry nodes modifier.

I've just extended the places existing IDProperty types are used, and
tested with the custom property edit operator and the python console.
Adding another IDProperty type is a straightforward extension of the
existing design.

Differential Revision: https://developer.blender.org/D12815

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

M	release/scripts/modules/rna_prop_ui.py
M	release/scripts/startup/bl_operators/wm.py
M	source/blender/blenkernel/BKE_idprop.h
M	source/blender/blenkernel/intern/idprop.c
M	source/blender/blenkernel/intern/idprop_utils.c
M	source/blender/blenloader/BLO_read_write.h
M	source/blender/blenloader/intern/readfile.cc
M	source/blender/blenloader/intern/versioning_300.cc
M	source/blender/blenloader/intern/writefile.cc
M	source/blender/io/alembic/exporter/abc_custom_props.cc
M	source/blender/io/collada/collada_utils.cpp
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/intern/rna_ID.c
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/python/generic/idprop_py_api.c
M	source/blender/python/generic/idprop_py_ui_api.c

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

diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 5f4a6b8cf38..f6c01bde9cd 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -81,25 +81,26 @@ def rna_idprop_ui_create(
 ):
     """Create and initialize a custom property with limits, defaults and other settings."""
 
+    # Assign the value
+    item[prop] = default
+
+    rna_idprop_ui_prop_update(item, prop)
+    ui_data = item.id_properties_ui(prop)
     proptype, _ = rna_idprop_value_item_type(default)
 
-    # Sanitize limits
     if proptype is bool:
-        min = soft_min = False
-        max = soft_max = True
+        ui_data = item.id_properties_ui(prop)
+        ui_data.update(
+            description=description,
+            default=default,
+        )
+        return
 
     if soft_min is None:
         soft_min = min
     if soft_max is None:
         soft_max = max
 
-    # Assign the value
-    item[prop] = default
-
-    rna_idprop_ui_prop_update(item, prop)
-
-    # Update the UI settings.
-    ui_data = item.id_properties_ui(prop)
     ui_data.update(
         subtype=subtype,
         min=min,
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 39789cba0c4..fe43051281d 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -14,6 +14,7 @@ from bpy.props import (
     FloatProperty,
     IntProperty,
     StringProperty,
+    BoolVectorProperty,
     IntVectorProperty,
     FloatVectorProperty,
 )
@@ -1325,6 +1326,8 @@ rna_custom_property_type_items = (
     ('FLOAT_ARRAY', "Float Array", "An array of floating-point values"),
     ('INT', "Integer", "A single integer"),
     ('INT_ARRAY', "Integer Array", "An array of integers"),
+    ('BOOL', "Boolean", "A true or false value"),
+    ('BOOL_ARRAY', "Boolean Array", "An array of true or false values"),
     ('STRING', "String", "A string value"),
     ('PYTHON', "Python", "Edit a python value directly, for unsupported property types"),
 )
@@ -1410,6 +1413,14 @@ class WM_OT_properties_edit(Operator):
         default=1,
     )
 
+    # Boolean properties.
+
+    # This property stores values for both array and non-array properties.
+    default_bool: BoolVectorProperty(
+        name="Default Value",
+        size=32,
+    )
+
     # Float properties.
 
     # This property stores values for both array and non-array properties.
@@ -1520,6 +1531,10 @@ class WM_OT_properties_edit(Operator):
             if is_array:
                 return 'FLOAT_ARRAY'
             return 'FLOAT'
+        elif prop_type == bool:
+            if is_array:
+                return 'BOOL_ARRAY'
+            return 'BOOL'
         elif prop_type == str:
             if is_array:
                 return 'PYTHON'
@@ -1571,8 +1586,10 @@ class WM_OT_properties_edit(Operator):
             self.default_int = self._convert_new_value_array(rna_data["default"], int, 32)
         elif self.property_type == 'STRING':
             self.default_string = rna_data["default"]
+        elif self.property_type in {'BOOL', 'BOOL_ARRAY'}:
+            self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32)
 
-        if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY'}:
+        if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
             self.array_length = len(item[name])
 
         # The dictionary does not contain the description if it was empty.
@@ -1591,16 +1608,26 @@ class WM_OT_properties_edit(Operator):
         if prop_type_new == 'FLOAT':
             return self._convert_new_value_single(item[name_old], float)
 
+        if prop_type_new == 'BOOL':
+            return self._convert_new_value_single(item[name_old], bool)
+
         if prop_type_new == 'INT_ARRAY':
             prop_type_old = self.get_property_type(item, name_old)
-            if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY'}:
+            if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY', 'BOOL_ARRAY'}:
                 return self._convert_new_value_array(item[name_old], int, self.array_length)
 
         if prop_type_new == 'FLOAT_ARRAY':
             prop_type_old = self.get_property_type(item, name_old)
-            if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}:
+            if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
                 return self._convert_new_value_array(item[name_old], float, self.array_length)
 
+        if prop_type_new == 'BOOL_ARRAY':
+            prop_type_old = self.get_property_type(item, name_old)
+            if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}:
+                return self._convert_new_value_array(item[name_old], bool, self.array_length)
+            else:
+                return [False] * self.array_length
+
         if prop_type_new == 'STRING':
             return self.convert_custom_property_to_string(item, name_old)
 
@@ -1622,6 +1649,9 @@ class WM_OT_properties_edit(Operator):
             self.soft_min_float = float(self.soft_min_int)
             self.soft_max_float = float(self.soft_max_int)
             self.default_float = self._convert_new_value_array(self.default_int, float, 32)
+        elif prop_type_new in {'BOOL', 'BOOL_ARRAY'} and prop_type_old in {'INT', 'INT_ARRAY'}:
+            self.default_bool = self._convert_new_value_array(self.default_int, bool, 32)
+
         # Don't convert between string and float/int defaults here, it's not expected like the other conversions.
 
     # Fill the property's UI data with the values chosen in the operator.
@@ -1637,6 +1667,12 @@ class WM_OT_properties_edit(Operator):
                 default=self.default_int[0] if prop_type_new == 'INT' else self.default_int[:self.array_length],
                 description=self.description,
             )
+        if prop_type_new in {'BOOL', 'BOOL_ARRAY'}:
+            ui_data = item.id_properties_ui(name)
+            ui_data.update(
+                default=self.default_bool[0] if prop_type_new == 'BOOL' else self.default_bool[:self.array_length],
+                description=self.description,
+            )
         elif prop_type_new in {'FLOAT', 'FLOAT_ARRAY'}:
             ui_data = item.id_properties_ui(name)
             ui_data.update(
@@ -1879,6 +1915,15 @@ class WM_OT_properties_edit(Operator):
             col.prop(self, "soft_max_int", text="Max")
 
             layout.prop(self, "step_int")
+        elif self.property_type in {'BOOL', 'BOOL_ARRAY'}:
+            if self.property_type == 'BOOL_ARRAY':
+                layout.prop(self, "array_length")
+                col = layout.column(align=True)
+                col.prop(self, "default_bool", index=0, text="Default")
+                for i in range(1, self.array_length):
+                    col.prop(self, "default_bool", index=i, text=" ")
+            else:
+                layout.prop(self, "default_bool", index=0)
         elif self.property_type == 'STRING':
             layout.prop(self, "default_string")
 
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 9ac4b4e4619..84412fd139f 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -243,6 +243,7 @@ void IDP_ClearProperty(struct IDProperty *prop);
 void IDP_Reset(struct IDProperty *prop, const struct IDProperty *reference);
 
 #define IDP_Int(prop) ((prop)->data.val)
+#define IDP_Bool(prop) ((prop)->data.val)
 #define IDP_Array(prop) ((prop)->data.pointer)
 /* C11 const correctness for casts */
 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
@@ -334,6 +335,8 @@ typedef enum eIDPropertyUIDataType {
   IDP_UI_DATA_TYPE_STRING = 2,
   /** IDP_ID. */
   IDP_UI_DATA_TYPE_ID = 3,
+  /** IDP_BOOLEAN or IDP_ARRAY with subtype IDP_BOOLEAN. */
+  IDP_UI_DATA_TYPE_BOOLEAN = 4,
 } eIDPropertyUIDataType;
 
 bool IDP_ui_data_supported(const struct IDProperty *prop);
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 00e7425c8af..b8f0db0699d 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -50,6 +50,8 @@ static size_t idp_size_table[] = {
     sizeof(ListBase),  /* Group type. */
     sizeof(void *),
     sizeof(double),
+    0,
+    sizeof(int8_t), /* Boolean type. */
 };
 
 /* -------------------------------------------------------------------- */
@@ -272,6 +274,12 @@ IDPropertyUIData *IDP_ui_data_copy(const IDProperty *prop)
       dst->default_array = MEM_dupallocN(src->default_array);
       break;
     }
+    case IDP_UI_DATA_TYPE_BOOLEAN: {
+      const IDPropertyUIDataBool *src = (const IDPropertyUIDataBool *)prop->ui_data;
+      IDPropertyUIDataBool *dst = (IDPropertyUIDataBool *)dst_ui_data;
+      dst->default_array = MEM_dupallocN(src->default_array);
+      break;
+    }
     case IDP_UI_DATA_TYPE_FLOAT: {
       const IDPropertyUIDataFloat *src = (const IDPropertyUIDataFloat *)prop->ui_data;
       IDPropertyUIDataFloat *dst = (IDPropertyUIDataFloat *)dst_ui_data;
@@ -497,6 +505,7 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src)
         case IDP_INT:
         case IDP_FLOAT:
         case IDP_DOUBLE:
+        case IDP_BOOLEAN:
           other->data = prop->data;
           break;
         case IDP_GROUP:
@@ -708,6 +717,8 @@ int IDP_coerce_to_int_or_zero(const IDProperty *prop)
       return (int)IDP_Double(prop);
     case IDP_FLOAT:
       return (int)IDP_Float(prop);
+    case IDP_BOOLEAN:
+      return (int)IDP_Bool(prop);
     default:
       return 0;
   }
@@ -722,6 +733,8 @@ double IDP_coerce_to_double_or_zero(const IDProperty *prop)
       return (double)IDP_Float(prop);
     case IDP_INT:
       return (double)IDP_Int(prop);
+    case IDP_BOOLEAN:
+      return (double)IDP_Bool(prop);
     default:
       return 0.0;
   }
@@ -736,6 +749,8 @@ float IDP_coerce_to_float_or_zero(const IDProperty *prop)
       return (float)IDP_Double(prop);
     case IDP_INT:
       return (float)IDP_Int(prop);
+    case IDP_BOOLEAN:
+      return (float

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list