forked from blender/blender
main sync #3
@ -247,6 +247,7 @@ static int count_items(PyObject *seq, int dim)
|
|||||||
static int validate_array_length(PyObject *rvalue,
|
static int validate_array_length(PyObject *rvalue,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
|
const bool prop_is_param_dyn_alloc,
|
||||||
int lvalue_dim,
|
int lvalue_dim,
|
||||||
int *r_totitem,
|
int *r_totitem,
|
||||||
const char *error_prefix)
|
const char *error_prefix)
|
||||||
@ -266,26 +267,20 @@ static int validate_array_length(PyObject *rvalue,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
|
if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
|
||||||
if (RNA_property_array_length(ptr, prop) != tot) {
|
const int tot_expected = RNA_property_array_length(ptr, prop);
|
||||||
#if 0
|
if (tot_expected != tot) {
|
||||||
/* length is flexible */
|
*r_totitem = tot;
|
||||||
if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) {
|
if (!prop_is_param_dyn_alloc) {
|
||||||
/* BLI_snprintf(error_str, error_str_size,
|
|
||||||
* "%s.%s: array length cannot be changed to %d",
|
|
||||||
* RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */
|
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"%s %s.%s: array length cannot be changed to %d",
|
"%s %s.%s: array length cannot be changed to %d (expected %d)",
|
||||||
error_prefix,
|
error_prefix,
|
||||||
RNA_struct_identifier(ptr->type),
|
RNA_struct_identifier(ptr->type),
|
||||||
RNA_property_identifier(prop),
|
RNA_property_identifier(prop),
|
||||||
tot);
|
tot,
|
||||||
|
tot_expected);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
*r_totitem = tot;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = tot;
|
len = tot;
|
||||||
@ -340,6 +335,7 @@ static int validate_array_length(PyObject *rvalue,
|
|||||||
static int validate_array(PyObject *rvalue,
|
static int validate_array(PyObject *rvalue,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
|
const bool prop_is_param_dyn_alloc,
|
||||||
int lvalue_dim,
|
int lvalue_dim,
|
||||||
ItemTypeCheckFunc check_item_type,
|
ItemTypeCheckFunc check_item_type,
|
||||||
const char *item_type_str,
|
const char *item_type_str,
|
||||||
@ -410,7 +406,8 @@ static int validate_array(PyObject *rvalue,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return validate_array_length(rvalue, ptr, prop, lvalue_dim, r_totitem, error_prefix);
|
return validate_array_length(
|
||||||
|
rvalue, ptr, prop, prop_is_param_dyn_alloc, lvalue_dim, r_totitem, error_prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,15 +524,26 @@ static int py_to_array(PyObject *seq,
|
|||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
|
|
||||||
// totdim = RNA_property_array_dimension(ptr, prop, dim_size); /* UNUSED */
|
// totdim = RNA_property_array_dimension(ptr, prop, dim_size); /* UNUSED */
|
||||||
|
const int flag = RNA_property_flag(prop);
|
||||||
|
|
||||||
if (validate_array(seq, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix) ==
|
/* Use #ParameterDynAlloc which defines it's own array length. */
|
||||||
-1) {
|
const bool prop_is_param_dyn_alloc = param_data && (flag & PROP_DYNAMIC);
|
||||||
|
|
||||||
|
if (validate_array(seq,
|
||||||
|
ptr,
|
||||||
|
prop,
|
||||||
|
prop_is_param_dyn_alloc,
|
||||||
|
0,
|
||||||
|
check_item_type,
|
||||||
|
item_type_str,
|
||||||
|
&totitem,
|
||||||
|
error_prefix) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totitem) {
|
if (totitem) {
|
||||||
/* NOTE: this code is confusing. */
|
/* NOTE: this code is confusing. */
|
||||||
if (param_data && RNA_property_flag(prop) & PROP_DYNAMIC) {
|
if (prop_is_param_dyn_alloc) {
|
||||||
/* not freeing allocated mem, RNA_parameter_list_free() will do this */
|
/* not freeing allocated mem, RNA_parameter_list_free() will do this */
|
||||||
ParameterDynAlloc *param_alloc = (ParameterDynAlloc *)param_data;
|
ParameterDynAlloc *param_alloc = (ParameterDynAlloc *)param_data;
|
||||||
param_alloc->array_tot = (int)totitem;
|
param_alloc->array_tot = (int)totitem;
|
||||||
@ -626,9 +634,16 @@ static int py_to_array_index(PyObject *py,
|
|||||||
copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index);
|
copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (validate_array(
|
const bool prop_is_param_dyn_alloc = false;
|
||||||
py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix) ==
|
if (validate_array(py,
|
||||||
-1) {
|
ptr,
|
||||||
|
prop,
|
||||||
|
prop_is_param_dyn_alloc,
|
||||||
|
lvalue_dim,
|
||||||
|
check_item_type,
|
||||||
|
item_type_str,
|
||||||
|
&totitem,
|
||||||
|
error_prefix) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +195,76 @@ class TestPropArrayMultiDimensional(unittest.TestCase):
|
|||||||
del id_type.temp
|
del id_type.temp
|
||||||
|
|
||||||
|
|
||||||
|
class TestPropArrayDynamicAssign(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Pixels are dynamic in the sense the size can change however the assignment does not define the size.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dims = 12
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.image = bpy.data.images.new("", self.dims, self.dims)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
bpy.data.images.remove(self.image)
|
||||||
|
self.image = None
|
||||||
|
|
||||||
|
def test_assign_fixed_under_1px(self):
|
||||||
|
image = self.image
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
image.pixels = [1.0, 1.0, 1.0, 1.0]
|
||||||
|
|
||||||
|
def test_assign_fixed_under_0px(self):
|
||||||
|
image = self.image
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
image.pixels = []
|
||||||
|
|
||||||
|
def test_assign_fixed_over_by_1px(self):
|
||||||
|
image = self.image
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
image.pixels = ([1.0, 1.0, 1.0, 1.0] * (self.dims * self.dims)) + [1.0]
|
||||||
|
|
||||||
|
def test_assign_fixed(self):
|
||||||
|
# Valid assignment, ensure it works as intended.
|
||||||
|
image = self.image
|
||||||
|
values = [1.0, 0.0, 1.0, 0.0] * (self.dims * self.dims)
|
||||||
|
image.pixels = values
|
||||||
|
self.assertEqual(tuple(values), tuple(image.pixels))
|
||||||
|
|
||||||
|
|
||||||
|
class TestPropArrayDynamicArg(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Index array, a dynamic array argument which defines it's own length.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dims = 8
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.me = bpy.data.meshes.new("")
|
||||||
|
self.me.vertices.add(self.dims)
|
||||||
|
self.ob = bpy.data.objects.new("", self.me)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
bpy.data.objects.remove(self.ob)
|
||||||
|
bpy.data.meshes.remove(self.me)
|
||||||
|
self.me = None
|
||||||
|
self.ob = None
|
||||||
|
|
||||||
|
def test_param_dynamic(self):
|
||||||
|
ob = self.ob
|
||||||
|
vg = ob.vertex_groups.new(name="")
|
||||||
|
|
||||||
|
# Add none.
|
||||||
|
vg.add(index=(), weight=1.0, type='REPLACE')
|
||||||
|
for i in range(self.dims):
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
vg.weight(i)
|
||||||
|
|
||||||
|
# Add all.
|
||||||
|
vg.add(index=range(self.dims), weight=1.0, type='REPLACE')
|
||||||
|
self.assertEqual(tuple([1.0] * self.dims), tuple([vg.weight(i) for i in range(self.dims)]))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
||||||
|
Loading…
Reference in New Issue
Block a user