Merge branch 'blender-v4.5-release'
This commit is contained in:
@@ -447,9 +447,22 @@ Using low-level functions:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
obj = bpy.context.object
|
obj = bpy.context.object
|
||||||
obj.animation_data_create()
|
|
||||||
obj.animation_data.action = bpy.data.actions.new(name="MyAction")
|
# Create the action, with a slot for the object, a layer, and a keyframe strip:
|
||||||
fcu_z = obj.animation_data.action.fcurves.new(data_path="location", index=2)
|
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.add(2)
|
||||||
fcu_z.keyframe_points[0].co = 10.0, 0.0
|
fcu_z.keyframe_points[0].co = 10.0, 0.0
|
||||||
fcu_z.keyframe_points[1].co = 20.0, 1.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
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "bmesh_class.hh"
|
#include "bmesh_class.hh"
|
||||||
|
|
||||||
@@ -240,15 +239,6 @@ union eBMOpSlotSubType_Union {
|
|||||||
eBMOpSlotSubType_Int intg;
|
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 {
|
struct BMO_FlagSet {
|
||||||
int value;
|
int value;
|
||||||
const char *identifier;
|
const char *identifier;
|
||||||
@@ -262,8 +252,8 @@ struct BMOpSlot {
|
|||||||
eBMOpSlotType slot_type;
|
eBMOpSlotType slot_type;
|
||||||
eBMOpSlotSubType_Union slot_subtype;
|
eBMOpSlotSubType_Union slot_subtype;
|
||||||
|
|
||||||
eBMOpSlotFlag flag;
|
|
||||||
int len;
|
int len;
|
||||||
|
// int flag; /* UNUSED */
|
||||||
// int index; /* index within slot array */ /* UNUSED */
|
// int index; /* index within slot array */ /* UNUSED */
|
||||||
union {
|
union {
|
||||||
int i;
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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.
|
* Return a copy of the element buffer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -295,8 +295,6 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
|
|||||||
else {
|
else {
|
||||||
slot_dst->data = slot_src->data;
|
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->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)
|
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->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)
|
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->data.i = i;
|
||||||
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BMO_slot_mat_set(BMOperator *op,
|
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));
|
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],
|
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->data.p = p;
|
||||||
slot->flag |= BMO_OP_SLOT_FLAG_IS_SET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
|
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);
|
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)
|
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);
|
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
||||||
BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
|
BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
|
||||||
if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
|
if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
|
||||||
return std::nullopt;
|
return 0.0f;
|
||||||
}
|
|
||||||
if ((slot->flag & BMO_OP_SLOT_FLAG_IS_SET) == 0) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return slot->data.f;
|
return slot->data.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> BMO_slot_int_get_optional(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
|
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
|
||||||
const char *slot_name)
|
|
||||||
{
|
{
|
||||||
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
||||||
BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
|
BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
|
||||||
if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
|
if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
|
||||||
return std::nullopt;
|
return 0;
|
||||||
}
|
|
||||||
if ((slot->flag & BMO_OP_SLOT_FLAG_IS_SET) == 0) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return slot->data.i;
|
return slot->data.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BMO_slot_int_get(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)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
||||||
BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
|
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;
|
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)
|
void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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. */
|
* This lets the test ignore that tiny bit of math error so users won't notice. */
|
||||||
const float angle_epsilon = RAD2DEGF(0.0001f);
|
const float angle_epsilon = RAD2DEGF(0.0001f);
|
||||||
|
|
||||||
/* When unset, don't limit dissolving vertices at all. */
|
const float angle_threshold = BMO_slot_float_get(op->slots_in, "angle_threshold");
|
||||||
const float angle_threshold =
|
|
||||||
BMO_slot_float_get_optional(op->slots_in, "angle_threshold").value_or(M_PI);
|
|
||||||
|
|
||||||
/* Use verts when told to... except, do *not* use verts when angle_threshold is 0.0. */
|
/* 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") &&
|
const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts") &&
|
||||||
|
|||||||
@@ -261,6 +261,11 @@ add_blender_test(
|
|||||||
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_text.py
|
--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(
|
add_blender_test(
|
||||||
script_pyapi_grease_pencil
|
script_pyapi_grease_pencil
|
||||||
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_grease_pencil.py
|
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_grease_pencil.py
|
||||||
|
|||||||
31
tests/python/bl_pyapi_bmesh.py
Normal file
31
tests/python/bl_pyapi_bmesh.py
Normal 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()
|
||||||
Reference in New Issue
Block a user