Merge branch 'blender-v4.5-release'

This commit is contained in:
Bastien Montagne
2025-06-16 16:31:38 +02:00
6 changed files with 58 additions and 58 deletions

View File

@@ -447,9 +447,22 @@ Using low-level functions:
.. code-block:: python
obj = bpy.context.object
obj.animation_data_create()
obj.animation_data.action = bpy.data.actions.new(name="MyAction")
fcu_z = obj.animation_data.action.fcurves.new(data_path="location", index=2)
# Create the action, with a slot for the object, a layer, and a keyframe strip:
action = bpy.data.actions.new(name="MyAction")
slot = action.slots.new(obj.id_type, obj.name)
strip = action.layers.new("MyLayer").strips.new(type='KEYFRAME')
# Create a channelbag to hold the F-Curves for the slot:
channelbag = strip.channelbag(slot, ensure=True)
# Create the F-Curve with two keyframes:
fcu_z = channelbag.fcurves.new(data_path="location", index=2)
fcu_z.keyframe_points.add(2)
fcu_z.keyframe_points[0].co = 10.0, 0.0
fcu_z.keyframe_points[1].co = 20.0, 1.0
# Assign the action and the slot to the object:
adt = obj.animation_data_create()
adt.action = action
adt.action_slot = slot

View File

@@ -12,7 +12,6 @@
#include "BLI_utildefines.h"
#include <cstdarg>
#include <optional>
#include "bmesh_class.hh"
@@ -240,15 +239,6 @@ union eBMOpSlotSubType_Union {
eBMOpSlotSubType_Int intg;
};
enum eBMOpSlotFlag : uint8_t {
/**
* This flag is set when the operators value has been set.
* Use this so it's possible to have non-zero defaults for properties.
*/
BMO_OP_SLOT_FLAG_IS_SET = (1 << 0),
};
ENUM_OPERATORS(eBMOpSlotFlag, BMO_OP_SLOT_FLAG_IS_SET)
struct BMO_FlagSet {
int value;
const char *identifier;
@@ -262,8 +252,8 @@ struct BMOpSlot {
eBMOpSlotType slot_type;
eBMOpSlotSubType_Union slot_subtype;
eBMOpSlotFlag flag;
int len;
// int flag; /* UNUSED */
// int index; /* index within slot array */ /* UNUSED */
union {
int i;
@@ -559,16 +549,10 @@ void BMO_op_flag_disable(BMesh *bm, BMOperator *op, int op_flag);
void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float f);
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
std::optional<float> BMO_slot_float_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name);
void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int i);
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
std::optional<int> BMO_slot_int_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name);
void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, bool i);
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
std::optional<bool> BMO_slot_bool_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name);
/**
* Return a copy of the element buffer.
*/

View File

@@ -295,8 +295,6 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
else {
slot_dst->data = slot_src->data;
}
slot_dst->flag = slot_src->flag;
}
/*
@@ -314,7 +312,6 @@ void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_n
}
slot->data.f = f;
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
}
void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i)
@@ -326,7 +323,6 @@ void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_nam
}
slot->data.i = i;
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
}
void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i)
@@ -338,7 +334,6 @@ void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
}
slot->data.i = i;
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
}
void BMO_slot_mat_set(BMOperator *op,
@@ -367,7 +362,6 @@ void BMO_slot_mat_set(BMOperator *op,
zero_m4(static_cast<float(*)[4]>(slot->data.p));
}
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
}
void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
@@ -415,7 +409,6 @@ void BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_nam
}
slot->data.p = p;
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
}
void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
@@ -429,51 +422,31 @@ void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
}
copy_v3_v3(slot->data.vec, vec);
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
}
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
return BMO_slot_float_get_optional(slot_args, slot_name).value_or(0.0f);
}
std::optional<float> BMO_slot_float_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
return std::nullopt;
}
if ((slot->flag & BMO_OP_SLOT_FLAG_IS_SET) == 0) {
return std::nullopt;
return 0.0f;
}
return slot->data.f;
}
std::optional<int> BMO_slot_int_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name)
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
return std::nullopt;
}
if ((slot->flag & BMO_OP_SLOT_FLAG_IS_SET) == 0) {
return std::nullopt;
return 0;
}
return slot->data.i;
}
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
return BMO_slot_int_get_optional(slot_args, slot_name).value_or(0);
}
std::optional<bool> BMO_slot_bool_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
@@ -483,10 +456,6 @@ std::optional<bool> BMO_slot_bool_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLO
return slot->data.i;
}
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
return BMO_slot_bool_get_optional(slot_args, slot_name).value_or(false);
}
void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len)
{

View File

@@ -387,9 +387,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
* This lets the test ignore that tiny bit of math error so users won't notice. */
const float angle_epsilon = RAD2DEGF(0.0001f);
/* When unset, don't limit dissolving vertices at all. */
const float angle_threshold =
BMO_slot_float_get_optional(op->slots_in, "angle_threshold").value_or(M_PI);
const float angle_threshold = BMO_slot_float_get(op->slots_in, "angle_threshold");
/* Use verts when told to... except, do *not* use verts when angle_threshold is 0.0. */
const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts") &&

View File

@@ -261,6 +261,11 @@ add_blender_test(
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_text.py
)
add_blender_test(
script_pyapi_bmesh
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bmesh.py
)
add_blender_test(
script_pyapi_grease_pencil
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_grease_pencil.py

View File

@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: Apache-2.0
# ./blender.bin --background --python tests/python/bl_pyapi_bmesh.py -- --verbose
import bmesh
import unittest
class TestBMeshBasic(unittest.TestCase):
def test_create_uvsphere(self):
bm = bmesh.new()
bmesh.ops.create_uvsphere(
bm,
u_segments=8,
v_segments=5,
radius=1.0,
)
self.assertEqual(len(bm.verts), 34)
self.assertEqual(len(bm.edges), 72)
self.assertEqual(len(bm.faces), 40)
bm.free()
if __name__ == "__main__":
import sys
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
unittest.main()