Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py3
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py43
-rw-r--r--source/blender/blenkernel/intern/brush.c40
-rw-r--r--source/blender/blenkernel/intern/lib_id.c74
-rw-r--r--source/blender/blenkernel/intern/object.c50
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/editors/gizmo_library/CMakeLists.txt1
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_utils.c33
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c86
-rw-r--r--source/blender/functions/intern/field.cc18
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_abstract.cc2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_access_compare_override.c2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c15
-rw-r--r--source/blender/makesrna/intern/rna_object.c9
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c15
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c73
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc4
-rw-r--r--source/blender/python/generic/idprop_py_ui_api.c4
-rw-r--r--source/blender/python/gpu/gpu_py_buffer.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c2
-rw-r--r--tests/performance/api/config.py26
-rw-r--r--tests/performance/api/environment.py17
-rw-r--r--tests/performance/api/graph.py4
-rwxr-xr-xtests/performance/benchmark26
27 files changed, 378 insertions, 186 deletions
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 52af4fafd09..81a641a20cf 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -267,7 +267,8 @@ class OBJECT_PT_instancing(ObjectButtonsPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
- return (ob.type in {'MESH', 'EMPTY', 'POINTCLOUD'})
+ # FONT objects need (vertex) instancing for the 'Object Font' feature
+ return (ob.type in {'MESH', 'EMPTY', 'POINTCLOUD', 'FONT'})
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 30115618f3d..be669b1fe86 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -1659,7 +1659,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- layout.use_property_split = True
+ layout.use_property_split = False
st = context.space_data
strip = context.active_sequence_strip
@@ -1667,20 +1667,39 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
layout.active = not strip.mute
- col = layout.column()
-
- col.prop(strip, "volume", text="Volume")
- col.prop(strip, "pitch")
-
- col = layout.column()
- col.prop(strip, "pan")
- col.enabled = sound is not None and sound.use_mono
-
if sound is not None:
col = layout.column()
+
+ split = col.split(factor=0.4)
+ split.label(text="")
+ split.prop(sound, "use_mono")
if st.waveform_display_type == 'DEFAULT_WAVEFORMS':
- col.prop(strip, "show_waveform")
- col.prop(sound, "use_mono")
+ split = col.split(factor=0.4)
+ split.label(text="")
+ split.prop(strip, "show_waveform")
+
+ col = layout.column()
+
+ split = col.split(factor=0.4)
+ split.alignment = 'RIGHT'
+ split.label(text="Volume")
+ split.prop(strip, "volume", text="")
+
+ split = col.split(factor=0.4)
+ split.alignment = 'RIGHT'
+ split.label(text="Pitch")
+ split.prop(strip, "pitch", text="")
+
+ split = col.split(factor=0.4)
+ split.alignment = 'RIGHT'
+ split.label(text="Pan")
+ audio_channels = context.scene.render.ffmpeg.audio_channels
+ pan_text = ""
+ if audio_channels != 'MONO' and audio_channels != 'STEREO':
+ pan_text = "%.2f°" % (strip.pan * 90)
+ split.prop(strip, "pan", text=pan_text)
+ split.enabled = sound.use_mono and audio_channels != 'MONO'
+
class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel):
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 56c22df3b02..50264f348e9 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -148,8 +148,8 @@ static void brush_make_local(Main *bmain, ID *id, const int flags)
Brush *brush = (Brush *)id;
const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
- const bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
- const bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
+ bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
+ bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
BLI_assert(force_copy == false || force_copy != force_local);
bool is_local = false, is_lib = false;
@@ -166,27 +166,33 @@ static void brush_make_local(Main *bmain, ID *id, const int flags)
if (!force_local && !force_copy) {
BKE_library_ID_test_usages(bmain, brush, &is_local, &is_lib);
+ if (lib_local || is_local) {
+ if (!is_lib) {
+ force_local = true;
+ }
+ else {
+ force_copy = true;
+ }
+ }
}
- if (lib_local || is_local || force_copy || force_local) {
- if (!is_lib || force_local) {
- BKE_lib_id_clear_library_data(bmain, &brush->id);
- BKE_lib_id_expand_local(bmain, &brush->id);
+ if (force_local) {
+ BKE_lib_id_clear_library_data(bmain, &brush->id);
+ BKE_lib_id_expand_local(bmain, &brush->id);
- /* enable fake user by default */
- id_fake_user_set(&brush->id);
- }
- else {
- Brush *brush_new = (Brush *)BKE_id_copy(bmain, &brush->id); /* Ensures FAKE_USER is set */
+ /* enable fake user by default */
+ id_fake_user_set(&brush->id);
+ }
+ else if (force_copy) {
+ Brush *brush_new = (Brush *)BKE_id_copy(bmain, &brush->id); /* Ensures FAKE_USER is set */
- brush_new->id.us = 0;
+ brush_new->id.us = 0;
- /* setting newid is mandatory for complex make_lib_local logic... */
- ID_NEW_SET(brush, brush_new);
+ /* setting newid is mandatory for complex make_lib_local logic... */
+ ID_NEW_SET(brush, brush_new);
- if (!lib_local) {
- BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
- }
+ if (!lib_local) {
+ BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
}
}
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index cd0c3635dac..66b83272769 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -411,8 +411,8 @@ void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
}
const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
- const bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
- const bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
+ bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
+ bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
BLI_assert(force_copy == false || force_copy != force_local);
bool is_local = false, is_lib = false;
@@ -426,43 +426,49 @@ void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
if (!force_copy && !force_local) {
BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
+ if (lib_local || is_local) {
+ if (!is_lib) {
+ force_local = true;
+ }
+ else {
+ force_copy = true;
+ }
+ }
}
- if (lib_local || is_local || force_copy || force_local) {
- if (!is_lib || force_local) {
- BKE_lib_id_clear_library_data(bmain, id);
- BKE_lib_id_expand_local(bmain, id);
- }
- else {
- ID *id_new = BKE_id_copy(bmain, id);
-
- /* Should not fail in expected use cases,
- * but a few ID types cannot be copied (LIB, WM, SCR...). */
- if (id_new != NULL) {
- id_new->us = 0;
-
- /* setting newid is mandatory for complex make_lib_local logic... */
- ID_NEW_SET(id, id_new);
- Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id);
- if (key && key_new) {
- ID_NEW_SET(key, key_new);
- }
- bNodeTree *ntree = ntreeFromID(id), *ntree_new = ntreeFromID(id_new);
- if (ntree && ntree_new) {
- ID_NEW_SET(ntree, ntree_new);
- }
- if (GS(id->name) == ID_SCE) {
- Collection *master_collection = ((Scene *)id)->master_collection,
- *master_collection_new = ((Scene *)id_new)->master_collection;
- if (master_collection && master_collection_new) {
- ID_NEW_SET(master_collection, master_collection_new);
- }
- }
+ if (force_local) {
+ BKE_lib_id_clear_library_data(bmain, id);
+ BKE_lib_id_expand_local(bmain, id);
+ }
+ else if (force_copy) {
+ ID *id_new = BKE_id_copy(bmain, id);
+
+ /* Should not fail in expected use cases,
+ * but a few ID types cannot be copied (LIB, WM, SCR...). */
+ if (id_new != NULL) {
+ id_new->us = 0;
- if (!lib_local) {
- BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+ /* setting newid is mandatory for complex make_lib_local logic... */
+ ID_NEW_SET(id, id_new);
+ Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id);
+ if (key && key_new) {
+ ID_NEW_SET(key, key_new);
+ }
+ bNodeTree *ntree = ntreeFromID(id), *ntree_new = ntreeFromID(id_new);
+ if (ntree && ntree_new) {
+ ID_NEW_SET(ntree, ntree_new);
+ }
+ if (GS(id->name) == ID_SCE) {
+ Collection *master_collection = ((Scene *)id)->master_collection,
+ *master_collection_new = ((Scene *)id_new)->master_collection;
+ if (master_collection && master_collection_new) {
+ ID_NEW_SET(master_collection, master_collection_new);
}
}
+
+ if (!lib_local) {
+ BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d0d1db9b4f8..b4343578eab 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -331,8 +331,8 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
Object *ob = (Object *)id;
const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
const bool clear_proxy = (flags & LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING) == 0;
- const bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
- const bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
+ bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
+ bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
BLI_assert(force_copy == false || force_copy != force_local);
bool is_local = false, is_lib = false;
@@ -346,32 +346,38 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
if (!force_local && !force_copy) {
BKE_library_ID_test_usages(bmain, ob, &is_local, &is_lib);
+ if (lib_local || is_local) {
+ if (!is_lib) {
+ force_local = true;
+ }
+ else {
+ force_copy = true;
+ }
+ }
}
- if (lib_local || is_local || force_copy || force_local) {
- if (!is_lib || force_local) {
- BKE_lib_id_clear_library_data(bmain, &ob->id);
- BKE_lib_id_expand_local(bmain, &ob->id);
- if (clear_proxy) {
- if (ob->proxy_from != NULL) {
- ob->proxy_from->proxy = NULL;
- ob->proxy_from->proxy_group = NULL;
- }
- ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
+ if (force_local) {
+ BKE_lib_id_clear_library_data(bmain, &ob->id);
+ BKE_lib_id_expand_local(bmain, &ob->id);
+ if (clear_proxy) {
+ if (ob->proxy_from != NULL) {
+ ob->proxy_from->proxy = NULL;
+ ob->proxy_from->proxy_group = NULL;
}
+ ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
}
- else {
- Object *ob_new = (Object *)BKE_id_copy(bmain, &ob->id);
- id_us_min(&ob_new->id);
+ }
+ else if (force_copy) {
+ Object *ob_new = (Object *)BKE_id_copy(bmain, &ob->id);
+ id_us_min(&ob_new->id);
- ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL;
+ ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL;
- /* setting newid is mandatory for complex make_lib_local logic... */
- ID_NEW_SET(ob, ob_new);
+ /* setting newid is mandatory for complex make_lib_local logic... */
+ ID_NEW_SET(ob, ob_new);
- if (!lib_local) {
- BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
- }
+ if (!lib_local) {
+ BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
}
}
@@ -5312,7 +5318,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
unsigned int i;
Mesh *me_eval = ob->runtime.mesh_deform_eval ? ob->runtime.mesh_deform_eval :
- ob->runtime.mesh_deform_eval;
+ BKE_object_get_evaluated_mesh(ob);
const int *index;
if (me_eval && (index = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX))) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3e9ea8db758..9704e8bb413 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4500,7 +4500,8 @@ static void add_loose_objects_to_scene(Main *mainvar,
* or for a collection when *lib has been set. */
LISTBASE_FOREACH (Object *, ob, &mainvar->objects) {
bool do_it = (ob->id.tag & LIB_TAG_DOIT) != 0;
- if (do_it || ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0)) {
+ if (do_it ||
+ ((ob->id.tag & LIB_TAG_INDIRECT) != 0 && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0)) {
if (do_append) {
if (ob->id.us == 0) {
do_it = true;
@@ -4648,7 +4649,7 @@ static void add_collections_to_scene(Main *mainvar,
LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
Object *ob = coll_ob->ob;
if ((ob->id.tag & (LIB_TAG_PRE_EXISTING | LIB_TAG_DOIT | LIB_TAG_INDIRECT)) == 0 &&
- (ob->id.lib == lib) && (object_in_any_scene(bmain, ob) == 0)) {
+ (ob->id.lib == lib) && (object_in_any_scene(bmain, ob) == false)) {
do_add_collection = true;
break;
}
diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt
index eeb1e60166b..bfe8334b390 100644
--- a/source/blender/editors/gizmo_library/CMakeLists.txt
+++ b/source/blender/editors/gizmo_library/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
../../makesdna
../../makesrna
../../windowmanager
+ ../../../../intern/clog
../../../../intern/eigen
../../../../intern/glew-mx
../../../../intern/guardedalloc
diff --git a/source/blender/editors/gizmo_library/gizmo_library_utils.c b/source/blender/editors/gizmo_library/gizmo_library_utils.c
index 7d0ae5afb9b..a0db2a8e627 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_utils.c
@@ -39,9 +39,13 @@
#include "ED_view3d.h"
+#include "CLG_log.h"
+
/* own includes */
#include "gizmo_library_intern.h"
+static CLG_LogRef LOG = {"ed.gizmo.library_utils"};
+
/* factor for precision tweaking */
#define GIZMO_PRECISION_FAC 0.05f
@@ -182,7 +186,7 @@ bool gizmo_window_project_2d(bContext *C,
bool use_offset,
float r_co[2])
{
- float mat[4][4];
+ float mat[4][4], imat[4][4];
{
float mat_identity[4][4];
struct WM_GizmoMatrixParams params = {NULL};
@@ -193,6 +197,14 @@ bool gizmo_window_project_2d(bContext *C,
WM_gizmo_calc_matrix_final_params(gz, &params, mat);
}
+ if (!invert_m4_m4(imat, mat)) {
+ CLOG_WARN(&LOG,
+ "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted "
+ "(projection will fail)",
+ gz->type->idname,
+ gz->parent_gzgroup->type->idname);
+ }
+
/* rotate mouse in relation to the center and relocate it */
if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
/* For 3d views, transform 2D mouse pos onto plane. */
@@ -202,8 +214,6 @@ bool gizmo_window_project_2d(bContext *C,
plane_from_point_normal_v3(plane, mat[3], mat[2]);
bool clip_ray = ((RegionView3D *)region->regiondata)->is_persp;
if (ED_view3d_win_to_3d_on_plane(region, plane, mval, clip_ray, co)) {
- float imat[4][4];
- invert_m4_m4(imat, mat);
mul_m4_v3(imat, co);
r_co[0] = co[(axis + 1) % 3];
r_co[1] = co[(axis + 2) % 3];
@@ -213,8 +223,6 @@ bool gizmo_window_project_2d(bContext *C,
}
float co[3] = {mval[0], mval[1], 0.0f};
- float imat[4][4];
- invert_m4_m4(imat, mat);
mul_m4_v3(imat, co);
copy_v2_v2(r_co, co);
return true;
@@ -223,7 +231,7 @@ bool gizmo_window_project_2d(bContext *C,
bool gizmo_window_project_3d(
bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3])
{
- float mat[4][4];
+ float mat[4][4], imat[4][4];
{
float mat_identity[4][4];
struct WM_GizmoMatrixParams params = {NULL};
@@ -234,20 +242,25 @@ bool gizmo_window_project_3d(
WM_gizmo_calc_matrix_final_params(gz, &params, mat);
}
+ if (!invert_m4_m4(imat, mat)) {
+ CLOG_WARN(&LOG,
+ "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted "
+ "(projection will fail)",
+ gz->type->idname,
+ gz->parent_gzgroup->type->idname);
+ }
+
if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
/* NOTE: we might want a custom reference point passed in,
* instead of the gizmo center. */
ED_view3d_win_to_3d(v3d, region, mat[3], mval, r_co);
- invert_m4(mat);
- mul_m4_v3(mat, r_co);
+ mul_m4_v3(imat, r_co);
return true;
}
float co[3] = {mval[0], mval[1], 0.0f};
- float imat[4][4];
- invert_m4_m4(imat, mat);
mul_m4_v3(imat, co);
copy_v2_v2(r_co, co);
return true;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b9f3706b084..a6dd95cac04 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -137,7 +137,6 @@ void ED_view3d_smooth_view_ex(
{
RegionView3D *rv3d = region->regiondata;
struct SmoothView3DStore sms = {{0}};
- bool ok = false;
/* initialize sms */
view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
@@ -200,29 +199,30 @@ void ED_view3d_smooth_view_ex(
sms.to_camera = true; /* restore view3d values in end */
}
- /* skip smooth viewing for external render engine draw */
- if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) {
- bool changed = false; /* zero means no difference */
+ bool changed = false; /* zero means no difference */
- if (sview->camera_old != sview->camera) {
- changed = true;
- }
- else if (sms.dst.dist != rv3d->dist) {
- changed = true;
- }
- else if (sms.dst.lens != v3d->lens) {
- changed = true;
- }
- else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) {
- changed = true;
- }
- else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) {
- changed = true;
- }
+ if (sview->camera_old != sview->camera) {
+ changed = true;
+ }
+ else if (sms.dst.dist != rv3d->dist) {
+ changed = true;
+ }
+ else if (sms.dst.lens != v3d->lens) {
+ changed = true;
+ }
+ else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) {
+ changed = true;
+ }
+ else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) {
+ changed = true;
+ }
+
+ /* The new view is different from the previous state. */
+ if (changed) {
+
+ /* Skip smooth viewing for external render engine draw. */
+ if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) {
- /* The new view is different from the old one
- * so animate the view */
- if (changed) {
/* original values */
if (sview->camera_old) {
Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old);
@@ -279,27 +279,25 @@ void ED_view3d_smooth_view_ex(
}
/* #TIMER1 is hard-coded in key-map. */
rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0);
-
- ok = true;
}
- }
+ else {
+ if (sms.to_camera == false) {
+ copy_v3_v3(rv3d->ofs, sms.dst.ofs);
+ copy_qt_qt(rv3d->viewquat, sms.dst.quat);
+ rv3d->dist = sms.dst.dist;
+ v3d->lens = sms.dst.lens;
- /* if we get here nothing happens */
- if (ok == false) {
- if (sms.to_camera == false) {
- copy_v3_v3(rv3d->ofs, sms.dst.ofs);
- copy_qt_qt(rv3d->viewquat, sms.dst.quat);
- rv3d->dist = sms.dst.dist;
- v3d->lens = sms.dst.lens;
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ }
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- }
+ if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
+ view3d_boxview_copy(area, region);
+ }
- if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
- view3d_boxview_copy(area, region);
- }
+ ED_region_tag_redraw(region);
- ED_region_tag_redraw(region);
+ WM_event_add_mousemove(win);
+ }
}
}
@@ -320,6 +318,7 @@ void ED_view3d_smooth_view(bContext *C,
/* only meant for timer usage */
static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, bool sync_boxview)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
RegionView3D *rv3d = region->regiondata;
struct SmoothView3DStore *sms = rv3d->sms;
float step, step_inv;
@@ -333,6 +332,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b
/* end timer */
if (step >= 1.0f) {
+ wmWindow *win = CTX_wm_window(C);
/* if we went to camera, store the original */
if (sms->to_camera) {
@@ -355,9 +355,12 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b
MEM_freeN(rv3d->sms);
rv3d->sms = NULL;
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
+ WM_event_remove_timer(wm, win, rv3d->smooth_timer);
rv3d->smooth_timer = NULL;
rv3d->rflag &= ~RV3D_NAVIGATING;
+
+ /* Event handling won't know if a UI item has been moved under the pointer. */
+ WM_event_add_mousemove(win);
}
else {
/* ease in/out */
@@ -380,12 +383,9 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ if (ED_screen_animation_playing(wm)) {
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
-
- /* Event handling won't know if a UI item has been moved under the pointer. */
- WM_event_add_mousemove(CTX_wm_window(C));
}
if (sync_boxview && (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW)) {
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 06730a8b830..f680c7ba5ff 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -24,6 +24,8 @@
#include "FN_field.hh"
#include "FN_multi_function_parallel.hh"
+#include "FN_field.hh"
+
namespace blender::fn {
/* --------------------------------------------------------------------
@@ -185,8 +187,8 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
const Span<GField> operation_inputs = operation.inputs();
if (field_with_index.current_input_index < operation_inputs.size()) {
- /* Not all inputs are handled yet. Push the next input field to the stack and increment the
- * input index. */
+ /* Not all inputs are handled yet. Push the next input field to the stack and increment
+ * the input index. */
fields_to_check.push({operation_inputs[field_with_index.current_input_index]});
field_with_index.current_input_index++;
}
@@ -250,8 +252,8 @@ struct PartiallyInitializedArray : NonCopyable, NonMovable {
};
/**
- * Evaluate fields in the given context. If possible, multiple fields should be evaluated together,
- * because that can be more efficient when they share common sub-fields.
+ * Evaluate fields in the given context. If possible, multiple fields should be evaluated
+ * together, because that can be more efficient when they share common sub-fields.
*
* \param scope: The resource scope that owns data that makes up the output virtual arrays. Make
* sure the scope is not destructed when the output virtual arrays are still used.
@@ -294,8 +296,8 @@ Vector<const GVArray *> evaluate_fields(ResourceScope &scope,
Vector<const GVArray *> field_context_inputs = get_field_context_inputs(
scope, mask, context, field_tree_info.deduplicated_field_inputs);
- /* Finish fields that output an input varray directly. For those we don't have to do any further
- * processing. */
+ /* Finish fields that output an input varray directly. For those we don't have to do any
+ * further processing. */
for (const int out_index : fields_to_evaluate.index_range()) {
const GFieldRef &field = fields_to_evaluate[out_index];
if (!field.node().is_input()) {
@@ -426,8 +428,8 @@ Vector<const GVArray *> evaluate_fields(ResourceScope &scope,
procedure_executor.call(IndexRange(1), mf_params, mf_context);
}
- /* Copy data to supplied destination arrays if necessary. In some cases the evaluation above has
- * written the computed data in the right place already. */
+ /* Copy data to supplied destination arrays if necessary. In some cases the evaluation above
+ * has written the computed data in the right place already. */
if (!dst_varrays.is_empty()) {
for (const int out_index : fields_to_evaluate.index_range()) {
GVMutableArray *output_varray = get_dst_varray_if_available(out_index);
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.cc b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
index 910e04f3bf5..3665494c046 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
@@ -118,7 +118,7 @@ void ABCAbstractWriter::update_bounding_box(Object *object)
if (!bb) {
if (object->type != OB_CAMERA) {
- CLOG_WARN(&LOG, "Bounding box is null!\n");
+ CLOG_WARN(&LOG, "Bounding box is null!");
}
bounding_box_.min.x = bounding_box_.min.y = bounding_box_.min.z = 0;
bounding_box_.max.x = bounding_box_.max.y = bounding_box_.max.z = 0;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 13213f70fed..8520786a030 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1942,6 +1942,7 @@ typedef struct MeshCacheModifierData {
float factor;
char deform_mode;
+ char defgrp_name[64];
char _pad[7];
/* play_mode == MOD_MESHCACHE_PLAY_CFEA */
@@ -1958,6 +1959,11 @@ typedef struct MeshCacheModifierData {
char filepath[1024];
} MeshCacheModifierData;
+/* MeshCache modifier flags. */
+enum {
+ MOD_MESHCACHE_INVERT_VERTEX_GROUP = 1 << 0,
+};
+
enum {
MOD_MESHCACHE_TYPE_MDD = 1,
MOD_MESHCACHE_TYPE_PC2 = 2,
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index 2c552970c82..f8a36c1b2e6 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -788,7 +788,7 @@ bool RNA_struct_override_matches(Main *bmain,
continue;
}
- CLOG_INFO(&LOG, 5, "Override Checking %s\n", rna_path);
+ CLOG_INFO(&LOG, 5, "Override Checking %s", rna_path);
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(override, rna_path);
if (ignore_overridden && op != NULL) {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index f11d845c582..fb4fd4528d6 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -755,6 +755,7 @@ RNA_MOD_VGROUP_NAME_SET(LaplacianDeform, anchor_grp_name);
RNA_MOD_VGROUP_NAME_SET(LaplacianSmooth, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Lattice, name);
RNA_MOD_VGROUP_NAME_SET(Mask, vgroup);
+RNA_MOD_VGROUP_NAME_SET(MeshCache, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(MeshDeform, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(NormalEdit, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Shrinkwrap, vgroup_name);
@@ -6045,6 +6046,20 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Influence", "Influence of the deformation");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_ui_text(
+ prop,
+ "Vertex Group",
+ "Name of the Vertex Group which determines the influence of the modifier per point");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshCacheModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MESHCACHE_INVERT_VERTEX_GROUP);
+ RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
/* -------------------------------------------------------------------- */
/* Axis Conversion */
prop = RNA_def_property(srna, "forward_axis", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index d3cd3158db1..99865078cbe 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -224,6 +224,12 @@ static EnumPropertyItem instance_items_empty[] = {
INSTANCE_ITEM_COLLECTION,
{0, NULL, 0, NULL, NULL},
};
+
+static EnumPropertyItem instance_items_font[] = {
+ {0, "NONE", 0, "None", ""},
+ {OB_DUPLIVERTS, "VERTS", 0, "Vertices", "Use Object Font on characters"},
+ {0, NULL, 0, NULL, NULL},
+};
#endif
#undef INSTANCE_ITEMS_SHARED
#undef INSTANCE_ITEM_COLLECTION
@@ -762,6 +768,9 @@ static const EnumPropertyItem *rna_Object_instance_type_itemf(bContext *UNUSED(C
else if (ob->type == OB_POINTCLOUD) {
item = instance_items_pointcloud;
}
+ else if (ob->type == OB_FONT) {
+ item = instance_items_font;
+ }
else {
item = instance_items_nogroup;
}
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index d9837f21833..cd87e4d10c1 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -845,6 +845,17 @@ static void rna_Sequence_audio_update(Main *UNUSED(bmain), Scene *scene, Pointer
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
}
+static void rna_Sequence_pan_range(
+ PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ Scene *scene = (Scene *)ptr->owner_id;
+
+ *min = -FLT_MAX;
+ *max = FLT_MAX;
+ *softmax = 1 + (int)(scene->r.ffcodecdata.audio_channels > 2);
+ *softmin = -*softmax;
+}
+
static int rna_Sequence_input_count_get(PointerRNA *ptr)
{
Sequence *seq = (Sequence *)(ptr->data);
@@ -2559,8 +2570,10 @@ static void rna_def_sound(BlenderRNA *brna)
prop = RNA_def_property(srna, "pan", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pan");
- RNA_def_property_range(prop, -2.0f, 2.0f);
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -2, 2, 1, 2);
RNA_def_property_ui_text(prop, "Pan", "Playback panning of the sound (only for Mono sources)");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Sequence_pan_range");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update");
prop = RNA_def_property(srna, "show_waveform", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 6ef64ad8bc9..74f9887a973 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -36,8 +36,11 @@
#include "DNA_screen_types.h"
#include "BKE_context.h"
+#include "BKE_deform.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
@@ -53,6 +56,7 @@
#include "MOD_meshcache_util.h" /* utility functions */
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
+#include "MOD_util.h"
static void initData(ModifierData *md)
{
@@ -84,11 +88,16 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
static void meshcache_do(MeshCacheModifierData *mcmd,
Scene *scene,
Object *ob,
+ Mesh *mesh,
float (*vertexCos_Real)[3],
int numVerts)
{
const bool use_factor = mcmd->factor < 1.0f;
- float(*vertexCos_Store)[3] = (use_factor ||
+ int influence_group_index;
+ MDeformVert *dvert;
+ MOD_get_vgroup(ob, mesh, mcmd->defgrp_name, &dvert, &influence_group_index);
+
+ float(*vertexCos_Store)[3] = (use_factor || influence_group_index != -1 ||
(mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
MEM_malloc_arrayN(
numVerts, sizeof(*vertexCos_Store), __func__) :
@@ -256,7 +265,29 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
if (vertexCos_Store) {
if (ok) {
- if (use_factor) {
+ if (influence_group_index != -1) {
+ const float global_factor = (mcmd->flag & MOD_MESHCACHE_INVERT_VERTEX_GROUP) ?
+ -mcmd->factor :
+ mcmd->factor;
+ const float global_offset = (mcmd->flag & MOD_MESHCACHE_INVERT_VERTEX_GROUP) ?
+ mcmd->factor :
+ 0.0f;
+ if (mesh->dvert != NULL) {
+ for (int i = 0; i < numVerts; i++) {
+ /* For each vertex, compute its blending factor between the mesh cache (for `fac = 0`)
+ * and the former position of the vertex (for `fac = 1`). */
+ const MDeformVert *currentIndexDVert = dvert + i;
+ const float local_vertex_fac = global_offset +
+ BKE_defvert_find_weight(currentIndexDVert,
+ influence_group_index) *
+ global_factor;
+ interp_v3_v3v3(
+ vertexCos_Real[i], vertexCos_Real[i], vertexCos_Store[i], local_vertex_fac);
+ }
+ }
+ }
+ else if (use_factor) {
+ /* Influence_group_index is -1. */
interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
}
else {
@@ -270,34 +301,59 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
+ Mesh *mesh_src = NULL;
+
+ if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
+ /* `mesh_src` is only needed for vertex groups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
+ meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
+ struct BMEditMesh *editData,
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
+ Mesh *mesh_src = NULL;
+
+ if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
+ /* `mesh_src` is only needed for vertex groups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ }
+ if (mesh_src != NULL) {
+ BKE_mesh_wrapper_ensure_mdata(mesh_src);
+ }
+
+ meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA ob_ptr;
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
uiLayoutSetPropSep(layout, true);
@@ -307,6 +363,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "factor", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(layout, ptr, "deform_mode", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, NULL, ICON_NONE);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
modifier_panel_end(layout, ptr);
}
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 10237ac13c7..ba557c3976c 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -330,8 +330,8 @@ static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
ui_data->max = ui_data->soft_max = (double)value->max;
ui_data->default_array = (double *)MEM_mallocN(sizeof(double[3]), "mod_prop_default");
ui_data->default_array_len = 3;
- for (int i = 3; i < 3; i++) {
- ui_data->default_array[i] = (double)value->value[i];
+ for (const int i : IndexRange(3)) {
+ ui_data->default_array[i] = double(value->value[i]);
}
return property;
}
diff --git a/source/blender/python/generic/idprop_py_ui_api.c b/source/blender/python/generic/idprop_py_ui_api.c
index 42856d88472..7827bd48dfe 100644
--- a/source/blender/python/generic/idprop_py_ui_api.c
+++ b/source/blender/python/generic/idprop_py_ui_api.c
@@ -468,7 +468,7 @@ static void idprop_ui_data_to_dict_int(IDProperty *property, PyObject *dict)
Py_DECREF(list);
}
else {
- PyDict_SetItemString(dict, "default", item = PyLong_FromLong(ui_data->step));
+ PyDict_SetItemString(dict, "default", item = PyLong_FromLong(ui_data->default_value));
Py_DECREF(item);
}
}
@@ -499,7 +499,7 @@ static void idprop_ui_data_to_dict_float(IDProperty *property, PyObject *dict)
Py_DECREF(list);
}
else {
- PyDict_SetItemString(dict, "default", item = PyFloat_FromDouble(ui_data->step));
+ PyDict_SetItemString(dict, "default", item = PyFloat_FromDouble(ui_data->default_value));
Py_DECREF(item);
}
}
diff --git a/source/blender/python/gpu/gpu_py_buffer.c b/source/blender/python/gpu/gpu_py_buffer.c
index 0fef59d6352..abfde7b48c8 100644
--- a/source/blender/python/gpu/gpu_py_buffer.c
+++ b/source/blender/python/gpu/gpu_py_buffer.c
@@ -485,7 +485,7 @@ static int pygpu_buffer__sq_ass_item(BPyGPUBuffer *self, int i, PyObject *v)
case GPU_DATA_UINT:
case GPU_DATA_UINT_24_8:
case GPU_DATA_10_11_11_REV:
- return PyArg_Parse(v, "b:Expected ints", &self->buf.as_uint[i]) ? 0 : -1;
+ return PyArg_Parse(v, "I:Expected unsigned ints", &self->buf.as_uint[i]) ? 0 : -1;
default:
return 0; /* should never happen */
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 68731a91dc9..7a93a076621 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -753,7 +753,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not a valid type", member);
}
else {
- CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not found\n", member);
+ CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not found", member);
}
}
else {
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 1f47b152a2b..83a9a6c6383 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -3749,7 +3749,7 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
const char *keymap_id = NULL;
/* Support for the gizmo owning the tool keymap. */
- if (tref_rt->gizmo_group[0] != '\0' && tref_rt->keymap_fallback[0] != '\n') {
+ if (tref_rt->gizmo_group[0] != '\0' && tref_rt->keymap_fallback[0] != '\0') {
wmGizmoMap *gzmap = NULL;
wmGizmoGroup *gzgroup = NULL;
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index dc15b579e9d..88bf3ff453c 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -705,7 +705,7 @@ bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data,
}
if (failure) {
- CLOG_ERROR(&LOG, "Failed to get buffer, %s\n", err_out);
+ CLOG_ERROR(&LOG, "Failed to get buffer, %s", err_out);
return false;
}
diff --git a/tests/performance/api/config.py b/tests/performance/api/config.py
index d3a79eede14..b5e2b390aa3 100644
--- a/tests/performance/api/config.py
+++ b/tests/performance/api/config.py
@@ -25,6 +25,7 @@ class TestEntry:
category: str = ''
revision: str = ''
git_hash: str = ''
+ environment: Dict = field(default_factory=dict)
executable: str = ''
date: int = 0
device_type: str = 'CPU'
@@ -160,7 +161,13 @@ class TestConfig:
def read_blender_executables(env, name) -> List:
config = TestConfig._read_config_module(env.base_dir / name)
builds = getattr(config, 'builds', {})
- return [pathlib.Path(build) for build in builds.values()]
+ executables = []
+
+ for executable in builds.values():
+ executable, _ = TestConfig._split_environment_variables(executable)
+ executables.append(pathlib.Path(executable))
+
+ return executables
@staticmethod
def _read_config_module(base_dir: pathlib.Path) -> None:
@@ -191,9 +198,10 @@ class TestConfig:
# Get entries for specified commits, tags and branches.
for revision_name, revision_commit in self.revisions.items():
+ revision_commit, environment = self._split_environment_variables(revision_commit)
git_hash = env.resolve_git_hash(revision_commit)
date = env.git_hash_date(git_hash)
- entries += self._get_entries(revision_name, git_hash, '', date)
+ entries += self._get_entries(revision_name, git_hash, '', environment, date)
# Optimization to avoid rebuilds.
revisions_to_build = set()
@@ -204,6 +212,7 @@ class TestConfig:
# Get entries for revisions based on existing builds.
for revision_name, executable in self.builds.items():
+ executable, environment = self._split_environment_variables(executable)
executable_path = env._blender_executable_from_path(pathlib.Path(executable))
if not executable_path:
sys.stderr.write(f'Error: build {executable} not found\n')
@@ -214,7 +223,7 @@ class TestConfig:
env.set_default_blender_executable()
mtime = executable_path.stat().st_mtime
- entries += self._get_entries(revision_name, git_hash, executable, mtime)
+ entries += self._get_entries(revision_name, git_hash, executable, environment, mtime)
# Detect number of categories for more compact printing.
categories = set()
@@ -229,6 +238,7 @@ class TestConfig:
revision_name: str,
git_hash: str,
executable: pathlib.Path,
+ environment: str,
date: int) -> None:
entries = []
for test in self.tests.tests:
@@ -241,10 +251,12 @@ class TestConfig:
# Test if revision hash or executable changed.
if entry.git_hash != git_hash or \
entry.executable != executable or \
+ entry.environment != environment or \
entry.benchmark_type != self.benchmark_type or \
entry.date != date:
# Update existing entry.
entry.git_hash = git_hash
+ entry.environment = environment
entry.executable = executable
entry.benchmark_type = self.benchmark_type
entry.date = date
@@ -256,6 +268,7 @@ class TestConfig:
revision=revision_name,
git_hash=git_hash,
executable=executable,
+ environment=environment,
date=date,
test=test_name,
category=test_category,
@@ -266,3 +279,10 @@ class TestConfig:
entries.append(entry)
return entries
+
+ @staticmethod
+ def _split_environment_variables(revision):
+ if isinstance(revision, str):
+ return revision, {}
+ else:
+ return revision[0], revision[1]
diff --git a/tests/performance/api/environment.py b/tests/performance/api/environment.py
index 76c731b6118..750d991ebc8 100644
--- a/tests/performance/api/environment.py
+++ b/tests/performance/api/environment.py
@@ -104,9 +104,10 @@ class TestEnvironment:
self._init_default_blender_executable()
return True
- def set_blender_executable(self, executable_path: pathlib.Path) -> None:
+ def set_blender_executable(self, executable_path: pathlib.Path, environment: Dict = {}) -> None:
# Run all Blender commands with this executable.
self.blender_executable = executable_path
+ self.blender_executable_environment = environment
def _blender_executable_name(self) -> pathlib.Path:
if platform.system() == "Windows":
@@ -150,6 +151,7 @@ class TestEnvironment:
def set_default_blender_executable(self) -> None:
self.blender_executable = self.default_blender_executable
+ self.blender_executable_environment = {}
def set_log_file(self, filepath: pathlib.Path, clear=True) -> None:
# Log all commands and output to this file.
@@ -161,7 +163,7 @@ class TestEnvironment:
def unset_log_file(self) -> None:
self.log_file = None
- def call(self, args: List[str], cwd: pathlib.Path, silent=False) -> List[str]:
+ def call(self, args: List[str], cwd: pathlib.Path, silent: bool=False, environment: Dict={}) -> List[str]:
# Execute command with arguments in specified directory,
# and return combined stdout and stderr output.
@@ -173,7 +175,13 @@ class TestEnvironment:
f = open(self.log_file, 'a')
f.write('\n' + ' '.join([str(arg) for arg in args]) + '\n\n')
- proc = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ env = os.environ
+ if len(environment):
+ env = env.copy()
+ for key, value in environment.items():
+ env[key] = value
+
+ proc = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
# Read line by line
lines = []
@@ -208,7 +216,8 @@ class TestEnvironment:
else:
common_args += ['--background']
- return self.call([self.blender_executable] + common_args + args, cwd=self.base_dir)
+ return self.call([self.blender_executable] + common_args + args, cwd=self.base_dir,
+ environment=self.blender_executable_environment)
def run_in_blender(self,
function: Callable[[Dict], Dict],
diff --git a/tests/performance/api/graph.py b/tests/performance/api/graph.py
index 4ee5ae7cf0e..fe4d4800894 100644
--- a/tests/performance/api/graph.py
+++ b/tests/performance/api/graph.py
@@ -42,7 +42,7 @@ class TestGraph:
# Generate one graph for every device x category x result key combination.
for category, category_entries in categories.items():
- entries = sorted(category_entries, key=lambda entry: (entry.revision, entry.test))
+ entries = sorted(category_entries, key=lambda entry: (entry.revision, entry.test, entry.date))
outputs = set()
for entry in entries:
@@ -58,8 +58,6 @@ class TestGraph:
self.json = json.dumps(data, indent=2)
def chart(self, device_name: str, chart_name: str, entries: List, chart_type: str, output: str) -> Dict:
- entries = sorted(entries, key=lambda entry: entry.date)
-
# Gather used tests.
tests = {}
for entry in entries:
diff --git a/tests/performance/benchmark b/tests/performance/benchmark
index ad1e07d0ef3..343af3be7d1 100755
--- a/tests/performance/benchmark
+++ b/tests/performance/benchmark
@@ -83,15 +83,20 @@ def match_entry(entry: api.TestEntry, args: argparse.Namespace):
entry.test.find(args.test) != -1 or \
entry.category.find(args.test) != -1
-def run_entry(env: api.TestEnvironment, config: api.TestConfig, row: List, entry: api.TestEntry):
+def run_entry(env: api.TestEnvironment,
+ config: api.TestConfig,
+ row: List,
+ entry: api.TestEntry,
+ update_only: bool):
# Check if entry needs to be run.
- if entry.status not in ('queued', 'outdated'):
+ if update_only and entry.status not in ('queued', 'outdated'):
print_row(config, row, end='\r')
return False
# Run test entry.
revision = entry.revision
git_hash = entry.git_hash
+ environment = entry.environment
testname = entry.test
testcategory = entry.category
device_type = entry.device_type
@@ -116,13 +121,15 @@ def run_entry(env: api.TestEnvironment, config: api.TestConfig, row: List, entry
print_row(config, row, end='\r')
executable_ok = True
if len(entry.executable):
- env.set_blender_executable(pathlib.Path(entry.executable))
+ env.set_blender_executable(pathlib.Path(entry.executable), environment)
else:
env.checkout(git_hash)
executable_ok = env.build()
if not executable_ok:
entry.status = 'failed'
entry.error_msg = 'Failed to build'
+ else:
+ env.set_blender_executable(env.blender_executable, environment)
# Run test and update output and status.
if executable_ok:
@@ -219,7 +226,7 @@ def cmd_reset(env: api.TestEnvironment, argv: List):
config.queue.write()
-def cmd_run(env: api.TestEnvironment, argv: List):
+def cmd_run(env: api.TestEnvironment, argv: List, update_only: bool):
# Run tests.
parser = argparse.ArgumentParser()
parser.add_argument('config', nargs='?', default=None)
@@ -233,7 +240,7 @@ def cmd_run(env: api.TestEnvironment, argv: List):
for row in config.queue.rows(use_revision_columns(config)):
if match_entry(row[0], args):
for entry in row:
- if run_entry(env, config, row, entry):
+ if run_entry(env, config, row, entry, update_only):
updated = True
# Write queue every time in case running gets interrupted,
# so it can be resumed.
@@ -268,8 +275,9 @@ def main():
' \n'
' list List available tests, devices and configurations\n'
' \n'
- ' run [<config>] [<test>] Execute tests for configuration\n'
- ' reset [<config>] [<test>] Clear tests results from config, for re-running\n'
+ ' run [<config>] [<test>] Execute all tests in configuration\n'
+ ' update [<config>] [<test>] Execute only queued and outdated tests\n'
+ ' reset [<config>] [<test>] Clear tests results in configuration\n'
' status [<config>] [<test>] List configurations and their tests\n'
' \n'
' graph a.json b.json... -o out.html Create graph from results in JSON files\n')
@@ -304,7 +312,9 @@ def main():
if args.command == 'list':
cmd_list(env, argv)
elif args.command == 'run':
- cmd_run(env, argv)
+ cmd_run(env, argv, update_only=False)
+ elif args.command == 'update':
+ cmd_run(env, argv, update_only=True)
elif args.command == 'reset':
cmd_reset(env, argv)
elif args.command == 'status':