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:
authorJulian Eisel <eiseljulian@gmail.com>2018-04-12 15:42:55 +0300
committerJulian Eisel <eiseljulian@gmail.com>2018-04-12 15:42:55 +0300
commit3df270b1cf0c55750fd3752ac38a3d96947b7a43 (patch)
treeb37adbb7d5d506fd5b15495de736c07742e02688
parent4d250c4469759c3f9776f4744b11f664a9bc10b1 (diff)
parent31067c975759255c013a2b4d872082155d41479e (diff)
Merge branch 'blender2.8' into topbar
-rw-r--r--build_files/build_environment/cmake/openal.cmake1
-rw-r--r--build_files/build_environment/cmake/openimageio.cmake1
-rw-r--r--intern/rigidbody/RBI_api.h1
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp28
-rw-r--r--release/scripts/startup/bl_operators/bmesh/find_adjacent.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py2
-rw-r--r--release/scripts/startup/bl_ui/space_info.py5
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc4
-rw-r--r--source/blender/blenfont/intern/blf_font.c14
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c11
-rw-r--r--source/blender/blenkernel/BKE_layer.h15
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/intern/group.c26
-rw-r--r--source/blender/blenkernel/intern/layer.c66
-rw-r--r--source/blender/blenkernel/intern/object_update.c11
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c70
-rw-r--r--source/blender/blenkernel/intern/undo_system.c5
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c33
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/versioning_270.c17
-rw-r--r--source/blender/depsgraph/CMakeLists.txt2
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc48
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h26
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc126
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc51
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc86
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h28
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc124
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc80
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc31
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc11
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type_defines.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_types.h2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc239
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc21
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.cc2
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c12
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c98
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c38
-rw-r--r--source/blender/draw/intern/draw_manager_profiling.c11
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c22
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c2
-rw-r--r--source/blender/editors/armature/pose_edit.c58
-rw-r--r--source/blender/editors/include/ED_armature.h6
-rw-r--r--source/blender/editors/include/ED_object.h11
-rw-r--r--source/blender/editors/interface/interface_region_popup.c17
-rw-r--r--source/blender/editors/interface/interface_widgets.c24
-rw-r--r--source/blender/editors/interface/view2d.c6
-rw-r--r--source/blender/editors/object/object_add.c2
-rw-r--r--source/blender/editors/object/object_edit.c16
-rw-r--r--source/blender/editors/screen/area.c24
-rw-r--r--source/blender/editors/screen/screen_context.c2
-rw-r--r--source/blender/editors/screen/workspace_edit.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_graph/space_graph.c2
-rw-r--r--source/blender/editors/space_info/info_stats.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c17
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c4
-rw-r--r--source/blender/editors/transform/transform.c16
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_generics.c10
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp371
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h14
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c4
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c20
-rw-r--r--source/blender/gpu/intern/gpu_shader.c14
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c36
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl3
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl18
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl8
-rw-r--r--source/blender/makesdna/DNA_ID.h1
-rw-r--r--source/blender/makesdna/DNA_layer_types.h1
-rw-r--r--source/blender/makesdna/DNA_scene_types.h31
-rw-r--r--source/blender/makesrna/intern/rna_access.c6
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c24
-rw-r--r--source/blender/makesrna/intern/rna_scene.c47
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectTransform.c2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c27
-rw-r--r--source/blender/render/intern/source/pipeline.c4
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c33
-rw-r--r--source/blender/windowmanager/intern/wm_window.c5
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c3
88 files changed, 1003 insertions, 1300 deletions
diff --git a/build_files/build_environment/cmake/openal.cmake b/build_files/build_environment/cmake/openal.cmake
index d63c4443ca0..3331361bfbc 100644
--- a/build_files/build_environment/cmake/openal.cmake
+++ b/build_files/build_environment/cmake/openal.cmake
@@ -25,6 +25,7 @@ if(BUILD_MODE STREQUAL Release)
-DALSOFT_CONFIG=Off
-DALSOFT_HRTF_DEFS=Off
-DALSOFT_INSTALL=On
+ -DALSOFT_BACKEND_SNDIO=Off
)
if(UNIX)
diff --git a/build_files/build_environment/cmake/openimageio.cmake b/build_files/build_environment/cmake/openimageio.cmake
index 07f6b3cdbef..fdc71508e47 100644
--- a/build_files/build_environment/cmake/openimageio.cmake
+++ b/build_files/build_environment/cmake/openimageio.cmake
@@ -90,6 +90,7 @@ set(OPENIMAGEIO_EXTRA_ARGS
-DUSE_PYTHON=OFF
-DUSE_PYTHON3=OFF
-DUSE_OCIO=OFF
+ -DUSE_WEBP=${WITH_WEBP}
-DOIIO_BUILD_TOOLS=${OIIO_TOOLS}
-DOIIO_BUILD_TESTS=OFF
-DBUILD_TESTING=OFF
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 688ca91c774..556ca959e64 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -299,6 +299,7 @@ void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float l
void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper);
/* 6dof spring specific */
+void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper);
void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness);
void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping);
void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 17bb3817908..a9fbcb28529 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -954,7 +954,7 @@ rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigi
make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
- btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true);
+ btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2);
return (rbConstraint *)con;
}
@@ -1034,32 +1034,38 @@ void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, flo
constraint->setLimit(axis, lower, upper);
}
+void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper)
+{
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+ constraint->setLimit(axis, lower, upper);
+}
+
void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
-
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
constraint->setStiffness(axis, stiffness);
}
void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
-
- // invert damping range so that 0 = no damping
- constraint->setDamping(axis, 1.0f - damping);
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+ constraint->setDamping(axis, damping);
}
void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
-
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
constraint->enableSpring(axis, enable);
}
void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
{
- btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
-
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
constraint->setEquilibriumPoint();
}
diff --git a/release/scripts/startup/bl_operators/bmesh/find_adjacent.py b/release/scripts/startup/bl_operators/bmesh/find_adjacent.py
index 1555f465aa5..ff2e09c6bb5 100644
--- a/release/scripts/startup/bl_operators/bmesh/find_adjacent.py
+++ b/release/scripts/startup/bl_operators/bmesh/find_adjacent.py
@@ -213,7 +213,6 @@ def find_next(ele_dst, ele_src):
# ... So we have the highest chance of stepping onto the opposite element.
diff_best = 0
ele_best = None
- ele_best_tot = 0
ele_best_ls = []
for ele_test in candidates:
depth_test_a = elems_depth_measure(ele_dst, ele_test, other_edges_over_edge)
@@ -227,12 +226,10 @@ def find_next(ele_dst, ele_src):
if diff_test > diff_best:
diff_best = diff_test
ele_best = ele_test
- ele_best_tot = 1
ele_best_ls[:] = [ele_best]
elif diff_test == diff_best:
if ele_best is None:
ele_best = ele_test
- ele_best_tot += 1
ele_best_ls.append(ele_test)
if len(ele_best_ls) > 1:
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 26fb05363ff..15b175617d6 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -490,7 +490,7 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel):
layout.prop(ffmpeg, "use_lossless_output")
# Output quality
- use_crf = needs_codec and ffmpeg.codec in {'H264', 'MPEG4'}
+ use_crf = needs_codec and ffmpeg.codec in {'H264', 'MPEG4', 'WEBM'}
if use_crf:
layout.prop(ffmpeg, "constant_rate_factor")
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 4bd7b3b1cb6..cbe6449d1df 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -48,8 +48,9 @@ class INFO_HT_header(Header):
layout.template_ID(window, "workspace", new="workspace.workspace_add_menu", unlink="workspace.workspace_delete")
layout.template_search_preview(window, "screen", workspace, "screens", new="screen.new", unlink="screen.delete", rows=2, cols=6)
- act_mode_item = bpy.types.Object.bl_rna.properties["mode"].enum_items[layer.objects.active.mode]
- layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
+ if layer.objects.active:
+ act_mode_item = bpy.types.Object.bl_rna.properties["mode"].enum_items[layer.objects.active.mode]
+ layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
row = layout.row()
row.active = not workspace.use_scene_settings
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 3221ebe7778..d54719c47e2 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -858,9 +858,11 @@ static void import_endjob(void *user_data)
base = BKE_view_layer_base_find(view_layer, ob);
BKE_view_layer_base_select(view_layer, base);
- DEG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update_ex(data->bmain, &ob->id,
+ OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME | DEG_TAG_BASE_FLAGS_UPDATE);
}
+ DEG_id_tag_update(&data->scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
DEG_relations_tag_update(data->bmain);
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 301f06e22b5..c12303dcfc0 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -420,15 +420,15 @@ static void blf_font_draw_ascii_ex(
FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info,
int pen_y)
{
- unsigned char c;
+ unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
- FT_Vector delta;
int pen_x = 0;
GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
BLF_KERNING_VARS(font, has_kerning, kern_mode);
blf_font_ensure_ascii_table(font);
+ blf_font_ensure_ascii_kerning(font, kern_mode);
blf_batch_draw_begin(font);
@@ -437,13 +437,14 @@ static void blf_font_draw_ascii_ex(
if ((g = glyph_ascii_table[c]) == NULL)
continue;
if (has_kerning)
- BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
+ BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
/* do not return this loop if clipped, we want every character tested */
blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
pen_x += g->advance_i;
g_prev = g;
+ c_prev = c;
}
blf_batch_draw_end();
@@ -501,9 +502,8 @@ static void blf_font_draw_buffer_ex(
FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info,
int pen_y)
{
- unsigned int c;
+ unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
- FT_Vector delta;
int pen_x = (int)font->pos[0];
int pen_y_basis = (int)font->pos[1] + pen_y;
size_t i = 0;
@@ -519,6 +519,7 @@ static void blf_font_draw_buffer_ex(
BLF_KERNING_VARS(font, has_kerning, kern_mode);
blf_font_ensure_ascii_table(font);
+ blf_font_ensure_ascii_kerning(font, kern_mode);
/* another buffer specific call for color conversion */
@@ -530,7 +531,7 @@ static void blf_font_draw_buffer_ex(
if (UNLIKELY(g == NULL))
continue;
if (has_kerning)
- BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
+ BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
chx = pen_x + ((int)g->pos_x);
chy = pen_y_basis + g->height;
@@ -632,6 +633,7 @@ static void blf_font_draw_buffer_ex(
pen_x += g->advance_i;
g_prev = g;
+ c_prev = c;
}
if (r_info) {
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 21c11d96b07..96854db66dd 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -230,7 +230,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
}
i = (int)((gc->p2_width - (gc->pad * 2)) / gc->glyph_width_max);
- gc->p2_height = (int)blf_next_p2((unsigned int)(((gc->glyphs_len_max / i) + 1) * gc->glyph_height_max));
+ gc->p2_height = (int)blf_next_p2((unsigned int)(((gc->glyphs_len_max / i) + 1) * gc->glyph_height_max + (gc->pad * 2)));
if (gc->p2_height > font->tex_size_max) {
gc->p2_height = font->tex_size_max;
@@ -242,7 +242,10 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, gc->p2_width, gc->p2_height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
+
+ unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height, "BLF texture init");
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, gc->p2_width, gc->p2_height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
+ MEM_freeN(pixels);
}
GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
@@ -341,8 +344,8 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
}
}
- g->bitmap = (unsigned char *)MEM_mallocN((size_t)(g->width * g->height), "glyph bitmap");
- memcpy((void *)g->bitmap, (void *)bitmap.buffer, (size_t)(g->width * g->height));
+ g->bitmap = (unsigned char *)MEM_mallocN((size_t)g->width * (size_t)g->height, "glyph bitmap");
+ memcpy((void *)g->bitmap, (void *)bitmap.buffer, (size_t)g->width * (size_t)g->height);
}
g->advance = ((float)slot->advance.x) / 64.0f;
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 8140dc5b31d..9c06ae4f40d 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -169,14 +169,13 @@ void BKE_collection_engine_property_value_set_bool(struct IDProperty *props, con
/* evaluation */
-void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *eval_ctx,
- struct ID *owner_id,
- struct ViewLayer *view_layer);
-void BKE_layer_eval_layer_collection(const struct EvaluationContext *eval_ctx,
- struct LayerCollection *layer_collection,
- struct LayerCollection *parent_layer_collection);
-void BKE_layer_eval_layer_collection_post(const struct EvaluationContext *eval_ctx,
- struct ViewLayer *view_layer);
+void BKE_layer_eval_view_layer(const struct EvaluationContext *eval_ctx,
+ struct ID *owner_id,
+ struct ViewLayer *view_layer);
+
+void BKE_layer_eval_view_layer_indexed(const struct EvaluationContext *eval_ctx,
+ struct ID *owner_id,
+ int view_layer_index);
/* iterators */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index c5eefedcfad..ff05ffc8df7 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -247,7 +247,7 @@ void BKE_object_data_select_update(
void BKE_object_eval_flush_base_flags(
const struct EvaluationContext *eval_ctx,
- struct Object *object, struct Base *base,
+ struct Object *object, int base_index,
const bool is_from_set);
void BKE_object_handle_data_update(
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 20da1e7b7ac..7566d370c45 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -381,33 +381,9 @@ void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx
/* ******** Dependency graph evaluation ******** */
-static void group_eval_layer_collections(
- const struct EvaluationContext *eval_ctx,
- Group *group,
- ListBase *layer_collections,
- LayerCollection *parent_layer_collection)
-{
- LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
- /* Evaluate layer collection itself. */
- BKE_layer_eval_layer_collection(eval_ctx,
- layer_collection,
- parent_layer_collection);
- /* Evaluate nested collections. */
- group_eval_layer_collections(eval_ctx,
- group,
- &layer_collection->layer_collections,
- layer_collection);
- }
-}
-
void BKE_group_eval_view_layers(const struct EvaluationContext *eval_ctx,
Group *group)
{
DEG_debug_print_eval(__func__, group->id.name, group);
- BKE_layer_eval_layer_collection_pre(eval_ctx, &group->id, group->view_layer);
- group_eval_layer_collections(eval_ctx,
- group,
- &group->view_layer->layer_collections,
- NULL);
- BKE_layer_eval_layer_collection_post(eval_ctx, group->view_layer);
+ BKE_layer_eval_view_layer(eval_ctx, &group->id, group->view_layer);
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 65e76e619f2..50c7dc0c02f 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -216,6 +216,8 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
MEM_freeN(view_layer->id_properties);
}
+ MEM_SAFE_FREE(view_layer->object_bases_array);
+
MEM_freeN(view_layer);
}
@@ -503,6 +505,8 @@ void BKE_view_layer_copy_data(
view_layer_dst->basact = base_dst;
}
}
+
+ view_layer_dst->object_bases_array = NULL;
}
/**
@@ -2253,8 +2257,7 @@ static void idproperty_reset(IDProperty **props, IDProperty *props_ref)
}
}
-void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *UNUSED(eval_ctx),
- ID *owner_id, ViewLayer *view_layer)
+static void layer_eval_layer_collection_pre(ID *owner_id, ViewLayer *view_layer)
{
DEG_debug_print_eval(__func__, view_layer->name, view_layer);
Scene *scene = (GS(owner_id->name) == ID_SCE) ? (Scene *)owner_id : NULL;
@@ -2296,9 +2299,9 @@ static bool layer_collection_visible_get(const EvaluationContext *eval_ctx, Laye
}
}
-void BKE_layer_eval_layer_collection(const EvaluationContext *eval_ctx,
- LayerCollection *layer_collection,
- LayerCollection *parent_layer_collection)
+static void layer_eval_layer_collection(const EvaluationContext *eval_ctx,
+ LayerCollection *layer_collection,
+ LayerCollection *parent_layer_collection)
{
if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) {
/* TODO)sergey): Try to make it more generic and handled by depsgraph messaging. */
@@ -2356,18 +2359,65 @@ void BKE_layer_eval_layer_collection(const EvaluationContext *eval_ctx,
}
}
-void BKE_layer_eval_layer_collection_post(const struct EvaluationContext *UNUSED(eval_ctx),
- ViewLayer *view_layer)
+static void layer_eval_layer_collection_post(ViewLayer *view_layer)
{
DEG_debug_print_eval(__func__, view_layer->name, view_layer);
- /* if base is not selectabled, clear select */
+ /* Create array of bases, for fast index-based lookup. */
+ const int num_object_bases = BLI_listbase_count(&view_layer->object_bases);
+ MEM_SAFE_FREE(view_layer->object_bases_array);
+ view_layer->object_bases_array = MEM_malloc_arrayN(
+ num_object_bases, sizeof(Base *), "view_layer->object_bases_array");
+ int base_index = 0;
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ /* if base is not selectabled, clear select. */
if ((base->flag & BASE_SELECTABLED) == 0) {
base->flag &= ~BASE_SELECTED;
}
+ /* Store base in the array. */
+ view_layer->object_bases_array[base_index++] = base;
}
}
+static void layer_eval_collections_recurse(const EvaluationContext *eval_ctx,
+ ListBase *layer_collections,
+ LayerCollection *parent_layer_collection)
+{
+ for (LayerCollection *layer_collection = layer_collections->first;
+ layer_collection != NULL;
+ layer_collection = layer_collection->next)
+ {
+ layer_eval_layer_collection(eval_ctx,
+ layer_collection,
+ parent_layer_collection);
+ layer_eval_collections_recurse(eval_ctx,
+ &layer_collection->layer_collections,
+ layer_collection);
+ }
+}
+
+void BKE_layer_eval_view_layer(const struct EvaluationContext *eval_ctx,
+ struct ID *owner_id,
+ ViewLayer *view_layer)
+{
+ layer_eval_layer_collection_pre(owner_id, view_layer);
+ layer_eval_collections_recurse(eval_ctx,
+ &view_layer->layer_collections,
+ NULL);
+ layer_eval_layer_collection_post(view_layer);
+}
+
+void BKE_layer_eval_view_layer_indexed(const struct EvaluationContext *eval_ctx,
+ struct ID *owner_id,
+ int view_layer_index)
+{
+ BLI_assert(GS(owner_id->name) == ID_SCE);
+ BLI_assert(view_layer_index >= 0);
+ Scene *scene = (Scene *)owner_id;
+ ViewLayer *view_layer = BLI_findlink(&scene->view_layers, view_layer_index);
+ BLI_assert(view_layer != NULL);
+ BKE_layer_eval_view_layer(eval_ctx, owner_id, view_layer);
+}
+
/**
* Free any static allocated memory.
*/
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index de2002624c0..7904e479933 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -433,9 +433,16 @@ void BKE_object_data_select_update(const EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_object_eval_flush_base_flags(const EvaluationContext *UNUSED(eval_ctx),
- Object *object, Base *base, bool is_from_set)
+void BKE_object_eval_flush_base_flags(const EvaluationContext *eval_ctx,
+ Object *object, int base_index, bool is_from_set)
{
+ ViewLayer *view_layer = eval_ctx->view_layer;
+ BLI_assert(view_layer->object_bases_array != NULL);
+ BLI_assert(base_index >= 0);
+ BLI_assert(base_index < MEM_allocN_len(view_layer->object_bases_array) / sizeof(Base *));
+ Base *base = view_layer->object_bases_array[base_index];
+ BLI_assert(base->object == object);
+
DEG_debug_print_eval(__func__, object->id.name, object);
/* Make sure we have the base collection settings is already populated.
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 69e36f66dad..ff521260993 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -704,6 +704,39 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* --------------------- */
+static void rigidbody_constraint_set_limits(RigidBodyCon *rbc, void (*set_limits)(rbConstraint*,int,float,float))
+{
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
+ set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
+ else
+ set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y)
+ set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->limit_lin_y_lower, rbc->limit_lin_y_upper);
+ else
+ set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z)
+ set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->limit_lin_z_lower, rbc->limit_lin_z_upper);
+ else
+ set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X)
+ set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->limit_ang_x_lower, rbc->limit_ang_x_upper);
+ else
+ set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y)
+ set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->limit_ang_y_lower, rbc->limit_ang_y_upper);
+ else
+ set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z)
+ set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
+ else
+ set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
+}
+
/**
* Create physics sim representation of constraint given rigid body constraint settings
*
@@ -822,40 +855,13 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
- ATTR_FALLTHROUGH;
- case RBC_TYPE_6DOF:
- if (rbc->type == RBC_TYPE_6DOF) /* a litte awkward but avoids duplicate code for limits */
- rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
-
- if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
- else
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
-
- if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y)
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->limit_lin_y_lower, rbc->limit_lin_y_upper);
- else
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
-
- if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z)
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->limit_lin_z_lower, rbc->limit_lin_z_upper);
- else
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
-
- if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X)
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->limit_ang_x_lower, rbc->limit_ang_x_upper);
- else
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
- if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y)
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->limit_ang_y_lower, rbc->limit_ang_y_upper);
- else
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
+ rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring);
+ break;
+ case RBC_TYPE_6DOF:
+ rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
- if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z)
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
- else
- RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
+ rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
break;
case RBC_TYPE_MOTOR:
rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 760c6a60976..40cdd57fc3b 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -39,6 +39,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_library_override.h"
#include "BKE_main.h"
#include "BKE_undo_system.h"
@@ -392,6 +393,10 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, bContext *C, const char
undosys_stack_validate(ustack, false);
bool is_not_empty = ustack->step_active != NULL;
+ /* Might not be final place for this to be called - probably only want to call it from some
+ * undo handlers, not all of them? */
+ BKE_main_override_static_operations_create(CTX_data_main(C));
+
/* Remove all undos after (also when 'ustack->step_active == NULL'). */
while (ustack->steps.last != ustack->step_active) {
UndoStep *us_iter = ustack->steps.last;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 85582ceea4c..0a2527bafd2 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -582,24 +582,33 @@ static AVStream *alloc_video_stream(FFMpegContext *context, RenderData *rd, int
}
if (context->ffmpeg_preset) {
- char const *preset_name;
+ /* 'preset' is used by h.264, 'deadline' is used by webm/vp9. I'm not
+ * setting those properties conditionally based on the video codec,
+ * as the FFmpeg encoder simply ignores unknown settings anyway. */
+ char const *preset_name = NULL; /* used by h.264 */
+ char const *deadline_name = NULL; /* used by webm/vp9 */
switch (context->ffmpeg_preset) {
- case FFM_PRESET_ULTRAFAST: preset_name = "ultrafast"; break;
- case FFM_PRESET_SUPERFAST: preset_name = "superfast"; break;
- case FFM_PRESET_VERYFAST: preset_name = "veryfast"; break;
- case FFM_PRESET_FASTER: preset_name = "faster"; break;
- case FFM_PRESET_FAST: preset_name = "fast"; break;
- case FFM_PRESET_MEDIUM: preset_name = "medium"; break;
- case FFM_PRESET_SLOW: preset_name = "slow"; break;
- case FFM_PRESET_SLOWER: preset_name = "slower"; break;
- case FFM_PRESET_VERYSLOW: preset_name = "veryslow"; break;
+ case FFM_PRESET_GOOD:
+ preset_name = "medium";
+ deadline_name = "good";
+ break;
+ case FFM_PRESET_BEST:
+ preset_name = "slower";
+ deadline_name = "best";
+ break;
+ case FFM_PRESET_REALTIME:
+ preset_name = "superfast";
+ deadline_name = "realtime";
+ break;
default:
printf("Unknown preset number %i, ignoring.\n", context->ffmpeg_preset);
- preset_name = NULL;
}
if (preset_name != NULL) {
av_dict_set(&opts, "preset", preset_name, 0);
}
+ if (deadline_name != NULL) {
+ av_dict_set(&opts, "deadline", deadline_name, 0);
+ }
}
#if 0
@@ -1676,7 +1685,7 @@ void BKE_ffmpeg_image_type_verify(RenderData *rd, ImageFormatData *imf)
{
BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_H264);
rd->ffcodecdata.constant_rate_factor = FFM_CRF_MEDIUM;
- rd->ffcodecdata.ffmpeg_preset = FFM_PRESET_MEDIUM;
+ rd->ffcodecdata.ffmpeg_preset = FFM_PRESET_GOOD;
rd->ffcodecdata.type = FFMPEG_MKV;
}
if (rd->ffcodecdata.type == FFMPEG_OGG) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 21d55f07e75..3140f3a588b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6217,6 +6217,7 @@ static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
view_layer->properties_evaluated = NULL;
BLI_listbase_clear(&view_layer->drawdata);
+ view_layer->object_bases_array = NULL;
}
/**
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index bd4e4c2e35c..7228c3522f0 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1817,6 +1817,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ int preset = scene->r.ffcodecdata.ffmpeg_preset;
+ if (preset == FFM_PRESET_NONE || preset >= FFM_PRESET_GOOD) {
+ continue;
+ }
+ if (preset <= FFM_PRESET_FAST) {
+ preset = FFM_PRESET_REALTIME;
+ }
+ else if (preset >= FFM_PRESET_SLOW) {
+ preset = FFM_PRESET_BEST;
+ }
+ else {
+ preset = FFM_PRESET_GOOD;
+ }
+ scene->r.ffcodecdata.ffmpeg_preset = preset;
+ }
}
}
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index c2f69343456..8f6eee244f7 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -44,13 +44,11 @@ set(SRC
intern/builder/deg_builder_cycle.cc
intern/builder/deg_builder_map.cc
intern/builder/deg_builder_nodes.cc
- intern/builder/deg_builder_nodes_layer_collection.cc
intern/builder/deg_builder_nodes_rig.cc
intern/builder/deg_builder_nodes_view_layer.cc
intern/builder/deg_builder_pchanmap.cc
intern/builder/deg_builder_relations.cc
intern/builder/deg_builder_relations_keys.cc
- intern/builder/deg_builder_relations_layer_collection.cc
intern/builder/deg_builder_relations_rig.cc
intern/builder/deg_builder_relations_view_layer.cc
intern/builder/deg_builder_transitive.cc
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 3a8d6e70aca..8600022b7c3 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -86,11 +86,12 @@ typedef enum eDepsObjectIteratorMode {
typedef struct DEGObjectIterData {
struct Depsgraph *graph;
+ eDepsObjectIteratorMode mode;
+ int flag;
+
struct Scene *scene;
struct EvaluationContext eval_ctx;
- int flag;
- eDepsObjectIteratorMode mode;
int visibility_check; /* eObjectVisibilityCheck. */
/* **** Iteration over dupli-list. *** */
@@ -127,9 +128,9 @@ void DEG_iterator_objects_end(struct BLI_Iterator *iter);
#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, mode_, flag_) \
{ \
DEGObjectIterData data_ = { \
- .graph = (graph_), \
- .mode = (mode_), \
- .flag = (flag_), \
+ graph_, \
+ mode_, \
+ flag_ \
}; \
\
ITER_BEGIN(DEG_iterator_objects_begin, \
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index eff6b34fee6..a5a28ce0a8c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -136,6 +136,7 @@ DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph)
: bmain_(bmain),
graph_(graph),
scene_(NULL),
+ view_layer_(NULL),
cow_id_hash_(NULL)
{
}
@@ -321,17 +322,6 @@ ID *DepsgraphNodeBuilder::ensure_cow_id(ID *id_orig)
return id_node->id_cow;
}
-ID *DepsgraphNodeBuilder::expand_cow_id(IDDepsNode *id_node)
-{
- return deg_expand_copy_on_write_datablock(graph_, id_node, this, true);
-}
-
-ID *DepsgraphNodeBuilder::expand_cow_id(ID *id_orig)
-{
- IDDepsNode *id_node = add_id_node(id_orig);
- return expand_cow_id(id_node);
-}
-
/* **** Build functions for entity nodes **** */
void DepsgraphNodeBuilder::begin_build() {
@@ -399,7 +389,7 @@ void DepsgraphNodeBuilder::build_group(Group *group)
}
/* Build group objects. */
LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
- build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, base->object, DEG_ID_LINKED_INDIRECTLY);
}
/* Operation to evaluate the whole view layer.
*
@@ -414,10 +404,10 @@ void DepsgraphNodeBuilder::build_group(Group *group)
function_bind(BKE_group_eval_view_layers,
_1,
group_cow),
- DEG_OPCODE_VIEW_LAYER_DONE);
+ DEG_OPCODE_VIEW_LAYER_EVAL);
}
-void DepsgraphNodeBuilder::build_object(Base *base,
+void DepsgraphNodeBuilder::build_object(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state)
{
@@ -429,7 +419,7 @@ void DepsgraphNodeBuilder::build_object(Base *base,
* directly.
*/
if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
- build_object_flags(base, object, linked_state);
+ build_object_flags(base_index, object, linked_state);
}
id_node->linked_state = max(id_node->linked_state, linked_state);
return;
@@ -439,12 +429,12 @@ void DepsgraphNodeBuilder::build_object(Base *base,
id_node->linked_state = linked_state;
object->customdata_mask = 0;
/* Various flags, flushing from bases/collections. */
- build_object_flags(base, object, linked_state);
+ build_object_flags(base_index, object, linked_state);
/* Transform. */
build_object_transform(object);
/* Parent. */
if (object->parent != NULL) {
- build_object(NULL, object->parent, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY);
}
/* Modifiers. */
if (object->modifiers.first != NULL) {
@@ -483,7 +473,7 @@ void DepsgraphNodeBuilder::build_object(Base *base,
/* Object that this is a proxy for. */
if (object->proxy) {
object->proxy->proxy_from = object;
- build_object(NULL, object->proxy, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, object->proxy, DEG_ID_LINKED_INDIRECTLY);
}
/* Object dupligroup. */
if (object->dup_group != NULL) {
@@ -492,11 +482,11 @@ void DepsgraphNodeBuilder::build_object(Base *base,
}
void DepsgraphNodeBuilder::build_object_flags(
- Base *base,
+ int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state)
{
- if (base == NULL) {
+ if (base_index == -1) {
return;
}
/* TODO(sergey): Is this really best component to be used? */
@@ -505,7 +495,9 @@ void DepsgraphNodeBuilder::build_object_flags(
add_operation_node(&object->id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
function_bind(BKE_object_eval_flush_base_flags,
- _1, object_cow, base, is_from_set),
+ _1,
+ object_cow, base_index,
+ is_from_set),
DEG_OPCODE_OBJECT_BASE_FLAGS);
}
@@ -877,7 +869,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object)
switch (part->ren_as) {
case PART_DRAW_OB:
if (part->dup_ob != NULL) {
- build_object(NULL,
+ build_object(-1,
part->dup_ob,
DEG_ID_LINKED_INDIRECTLY);
}
@@ -1083,13 +1075,13 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
*/
Curve *cu = (Curve *)obdata;
if (cu->bevobj != NULL) {
- build_object(NULL, cu->bevobj, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, cu->bevobj, DEG_ID_LINKED_INDIRECTLY);
}
if (cu->taperobj != NULL) {
- build_object(NULL, cu->taperobj, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, cu->taperobj, DEG_ID_LINKED_INDIRECTLY);
}
if (object->type == OB_FONT && cu->textoncurve != NULL) {
- build_object(NULL, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY);
}
break;
}
@@ -1208,7 +1200,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
build_image((Image *)id);
}
else if (id_type == ID_OB) {
- build_object(NULL, (Object *)id, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY);
}
else if (id_type == ID_SCE) {
/* Scenes are used by compositor trees, and handled by render
@@ -1405,7 +1397,7 @@ void DepsgraphNodeBuilder::modifier_walk(void *user_data,
}
switch (GS(id->name)) {
case ID_OB:
- data->builder->build_object(NULL,
+ data->builder->build_object(-1,
(Object *)id,
DEG_ID_LINKED_INDIRECTLY);
break;
@@ -1430,7 +1422,7 @@ void DepsgraphNodeBuilder::constraint_walk(bConstraint * /*con*/,
}
switch (GS(id->name)) {
case ID_OB:
- data->builder->build_object(NULL,
+ data->builder->build_object(-1,
(Object *)id,
DEG_ID_LINKED_INDIRECTLY);
break;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index fd72ae527b8..df94671b4c6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -89,16 +89,6 @@ struct DepsgraphNodeBuilder {
return (T *)get_cow_id(&orig->id);
}
- /* Get fully expanded (ready for use) copy-on-write datablock for the given
- * original datablock.
- */
- ID *expand_cow_id(IDDepsNode *id_node);
- ID *expand_cow_id(ID *id_orig);
- template<typename T>
- T *expand_cow_datablock(T *orig) {
- return (T *)expand_cow_id(&orig->id);
- }
-
/* For a given COW datablock get corresponding original one. */
template<typename T>
T *get_orig_datablock(const T *cow) const {
@@ -171,10 +161,10 @@ struct DepsgraphNodeBuilder {
ViewLayer *view_layer,
eDepsNode_LinkedState_Type linked_state);
void build_group(Group *group);
- void build_object(Base *base,
+ void build_object(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state);
- void build_object_flags(Base *base,
+ void build_object_flags(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state);
void build_object_data(Object *object);
@@ -214,17 +204,6 @@ struct DepsgraphNodeBuilder {
void build_movieclip(MovieClip *clip);
void build_lightprobe(Object *object);
- struct LayerCollectionState {
- int index;
- LayerCollection *parent;
- };
- void build_layer_collection(ID *owner_id,
- LayerCollection *layer_collection,
- LayerCollectionState *state);
- void build_layer_collections(ID *owner_id,
- ListBase *layer_collections,
- LayerCollectionState *state);
- void build_view_layer_collections(ID *owner_id, ViewLayer *view_layer);
protected:
struct SavedEntryTag {
ID *id;
@@ -253,6 +232,7 @@ protected:
/* State which demotes currently built entities. */
Scene *scene_;
+ ViewLayer *view_layer_;
GHash *cow_id_hash_;
BuilderMap built_map_;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
deleted file mode 100644
index 2ee526b7128..00000000000
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2013 Blender Foundation.
- * All rights reserved.
- *
- * Original Author: Joshua Leung
- * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013)
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
- * \ingroup depsgraph
- *
- * Methods for constructing depsgraph's nodes
- */
-
-#include "intern/builder/deg_builder_nodes.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "MEM_guardedalloc.h"
-
-extern "C" {
-#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-
-#include "BKE_layer.h"
-
-#include "DNA_scene_types.h"
-
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_build.h"
-} /* extern "C" */
-
-#include "intern/builder/deg_builder.h"
-#include "intern/eval/deg_eval_copy_on_write.h"
-#include "intern/nodes/deg_node.h"
-#include "intern/nodes/deg_node_component.h"
-#include "intern/nodes/deg_node_operation.h"
-#include "intern/depsgraph_types.h"
-#include "intern/depsgraph_intern.h"
-#include "util/deg_util_foreach.h"
-
-namespace DEG {
-
-void DepsgraphNodeBuilder::build_layer_collection(
- ID *owner_id,
- LayerCollection *layer_collection,
- LayerCollectionState *state)
-{
- /* TODO(sergey): This will attempt to create component for each collection.
- * Harmless but could be optimized.
- */
- ComponentDepsNode *comp = add_component_node(
- owner_id,
- DEG_NODE_TYPE_LAYER_COLLECTIONS);
-
- add_operation_node(comp,
- function_bind(BKE_layer_eval_layer_collection,
- _1,
- layer_collection,
- state->parent),
- DEG_OPCODE_VIEW_LAYER_EVAL,
- layer_collection->scene_collection->name,
- state->index);
- ++state->index;
-
- /* Recurs into nested layer collections. */
- LayerCollection *parent = state->parent;
- state->parent = layer_collection;
- build_layer_collections(owner_id, &layer_collection->layer_collections, state);
- state->parent = parent;
-}
-
-void DepsgraphNodeBuilder::build_layer_collections(ID *owner_id,
- ListBase *layer_collections,
- LayerCollectionState *state)
-{
- LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
- build_layer_collection(owner_id, layer_collection, state);
- }
-}
-
-void DepsgraphNodeBuilder::build_view_layer_collections(
- ID *owner_id,
- ViewLayer *view_layer)
-{
- LayerCollectionState state;
- state.index = 0;
- ComponentDepsNode *comp = add_component_node(
- owner_id,
- DEG_NODE_TYPE_LAYER_COLLECTIONS);
- add_operation_node(comp,
- function_bind(BKE_layer_eval_layer_collection_pre,
- _1,
- owner_id,
- view_layer),
- DEG_OPCODE_VIEW_LAYER_INIT);
- add_operation_node(comp,
- function_bind(BKE_layer_eval_layer_collection_post,
- _1,
- view_layer),
- DEG_OPCODE_VIEW_LAYER_DONE);
- state.parent = NULL;
- build_layer_collections(owner_id, &view_layer->layer_collections, &state);
-}
-
-} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index c438efc1644..208462713a5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -313,7 +313,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
/* Custom shape. */
if (pchan->custom != NULL) {
- build_object(NULL, pchan->custom, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY);
}
pchan_index++;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 859ad36d06d..390619aeeaa 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -76,35 +76,14 @@ void DepsgraphNodeBuilder::build_view_layer(
add_time_source();
/* Setup currently building context. */
scene_ = scene;
- /* Expand Scene Cow datablock to get proper pointers to bases. */
+ view_layer_ = view_layer;
+ /* Get pointer to a CoW version of scene ID. */
Scene *scene_cow;
- ViewLayer *view_layer_cow;
if (DEG_depsgraph_use_copy_on_write()) {
- /* NOTE: We need to create ID nodes for all objects coming from bases,
- * otherwise remapping will not replace objects with their CoW versions
- * for CoW bases.
- */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
- Object *object = base->object;
- add_id_node(&object->id);
- }
- /* Create ID node for nested ID of nodetree as well, otherwise remapping
- * will not work correct either.
- */
- if (scene->nodetree != NULL) {
- add_id_node(&scene->nodetree->id);
- }
- /* Make sure we've got ID node, so we can get pointer to CoW datablock.
- */
- scene_cow = expand_cow_datablock(scene);
- view_layer_cow = (ViewLayer *)BLI_findstring(
- &scene_cow->view_layers,
- view_layer->name,
- offsetof(ViewLayer, name));
+ scene_cow = get_cow_datablock(scene);
}
else {
scene_cow = scene;
- view_layer_cow = view_layer;
}
/* Scene objects. */
int select_color = 1;
@@ -112,17 +91,15 @@ void DepsgraphNodeBuilder::build_view_layer(
* but object is expected to be an original one. Hence we go into some
* tricks here iterating over the view layer.
*/
- for (Base *base_orig = (Base *)view_layer->object_bases.first,
- *base_cow = (Base *)view_layer_cow->object_bases.first;
- base_orig != NULL;
- base_orig = base_orig->next, base_cow = base_cow->next)
- {
+ int base_index = 0;
+ LISTBASE_FOREACH(Base *, base, &view_layer->object_bases) {
/* object itself */
- build_object(base_cow, base_orig->object, linked_state);
- base_orig->object->select_color = select_color++;
+ build_object(base_index, base->object, linked_state);
+ base->object->select_color = select_color++;
+ ++base_index;
}
if (scene->camera != NULL) {
- build_object(NULL, scene->camera, DEG_ID_LINKED_INDIRECTLY);
+ build_object(-1, scene->camera, DEG_ID_LINKED_INDIRECTLY);
}
/* Rigidbody. */
if (scene->rigidbody_world != NULL) {
@@ -157,7 +134,15 @@ void DepsgraphNodeBuilder::build_view_layer(
build_movieclip(clip);
}
/* Collections. */
- build_view_layer_collections(&scene->id, view_layer_cow);
+ int view_layer_index = BLI_findindex(&scene->view_layers, view_layer);
+ BLI_assert(view_layer_index != -1);
+ add_operation_node(&scene->id,
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ function_bind(BKE_layer_eval_view_layer_indexed,
+ _1,
+ &scene_cow->id,
+ view_layer_index),
+ DEG_OPCODE_VIEW_LAYER_EVAL);
/* Parameters evaluation for scene relations mainly. */
add_operation_node(&scene->id,
DEG_NODE_TYPE_PARAMETERS,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 88c62182466..ff1728eb89f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -115,51 +115,6 @@ extern "C" {
namespace DEG {
-namespace {
-
-struct BuilderWalkUserData {
- DepsgraphRelationBuilder *builder;
-};
-
-void modifier_walk(void *user_data,
- struct Object * /*object*/,
- struct ID **idpoin,
- int /*cb_flag*/)
-{
- BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
- ID *id = *idpoin;
- if (id == NULL) {
- return;
- }
- switch (GS(id->name)) {
- case ID_OB:
- data->builder->build_object(NULL, (Object *)id);
- break;
- case ID_TE:
- data->builder->build_texture((Tex *)id);
- break;
- default:
- /* pass */
- break;
- }
-}
-
-void constraint_walk(bConstraint * /*con*/,
- ID **idpoin,
- bool /*is_reference*/,
- void *user_data)
-{
- BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
- if (*idpoin) {
- ID *id = *idpoin;
- if (GS(id->name) == ID_OB) {
- data->builder->build_object(NULL, (Object *)id);
- }
- }
-}
-
-} /* namespace */
-
/* ***************** */
/* Relations Builder */
@@ -550,7 +505,7 @@ void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object)
}
OperationKey view_layer_done_key(&scene_->id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
- DEG_OPCODE_VIEW_LAYER_DONE);
+ DEG_OPCODE_VIEW_LAYER_EVAL);
OperationKey object_flags_key(&object->id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
DEG_OPCODE_OBJECT_BASE_FLAGS);
@@ -2118,4 +2073,43 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node
}
}
+/* **** ID traversal callbacks functions **** */
+
+void DepsgraphRelationBuilder::modifier_walk(void *user_data,
+ struct Object * /*object*/,
+ struct ID **idpoin,
+ int /*cb_flag*/)
+{
+ BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
+ ID *id = *idpoin;
+ if (id == NULL) {
+ return;
+ }
+ switch (GS(id->name)) {
+ case ID_OB:
+ data->builder->build_object(NULL, (Object *)id);
+ break;
+ case ID_TE:
+ data->builder->build_texture((Tex *)id);
+ break;
+ default:
+ /* pass */
+ break;
+ }
+}
+
+void DepsgraphRelationBuilder::constraint_walk(bConstraint * /*con*/,
+ ID **idpoin,
+ bool /*is_reference*/,
+ void *user_data)
+{
+ BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
+ if (*idpoin) {
+ ID *id = *idpoin;
+ if (GS(id->name) == ID_OB) {
+ data->builder->build_object(NULL, (Object *)id);
+ }
+ }
+}
+
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 1720f19eb22..df6fb100d22 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -264,20 +264,6 @@ struct DepsgraphRelationBuilder
EffectorWeights *eff,
bool add_absorption, const char *name);
- struct LayerCollectionState {
- int index;
- OperationKey init_key;
- OperationKey done_key;
- OperationKey prev_key;
- };
- void build_layer_collection(ID *owner_id,
- LayerCollection *layer_collection,
- LayerCollectionState *state);
- void build_layer_collections(ID *owner_id,
- ListBase *layer_collections,
- LayerCollectionState *state);
- void build_view_layer_collections(struct ID *owner_id, ViewLayer *view_layer);
-
void build_copy_on_write_relations();
void build_copy_on_write_relations(IDDepsNode *id_node);
@@ -334,6 +320,20 @@ protected:
const KeyTo& key_to);
private:
+ struct BuilderWalkUserData {
+ DepsgraphRelationBuilder *builder;
+ };
+
+ static void modifier_walk(void *user_data,
+ struct Object *object,
+ struct ID **idpoin,
+ int cb_flag);
+
+ static void constraint_walk(bConstraint *con,
+ ID **idpoin,
+ bool is_reference,
+ void *user_data);
+
/* State which never changes, same for the whole builder time. */
Main *bmain_;
Depsgraph *graph_;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
deleted file mode 100644
index e2154558ed7..00000000000
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2013 Blender Foundation.
- * All rights reserved.
- *
- * Original Author: Joshua Leung
- * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013)
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
- * \ingroup depsgraph
- *
- * Methods for constructing depsgraph
- */
-
-#include "intern/builder/deg_builder_relations.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <cstring> /* required for STREQ later on. */
-
-#include "MEM_guardedalloc.h"
-
-extern "C" {
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_node_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-#include "BKE_layer.h"
-#include "BKE_main.h"
-#include "BKE_node.h"
-
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_build.h"
-} /* extern "C" */
-
-#include "intern/builder/deg_builder.h"
-#include "intern/builder/deg_builder_pchanmap.h"
-
-#include "intern/nodes/deg_node.h"
-#include "intern/nodes/deg_node_component.h"
-#include "intern/nodes/deg_node_operation.h"
-
-#include "intern/depsgraph_intern.h"
-#include "intern/depsgraph_types.h"
-
-#include "util/deg_util_foreach.h"
-
-namespace DEG {
-
-void DepsgraphRelationBuilder::build_layer_collection(
- ID *owner_id,
- LayerCollection *layer_collection,
- LayerCollectionState *state)
-{
- OperationKey layer_key(owner_id,
- DEG_NODE_TYPE_LAYER_COLLECTIONS,
- DEG_OPCODE_VIEW_LAYER_EVAL,
- layer_collection->scene_collection->name,
- state->index);
- add_relation(state->prev_key, layer_key, "Layer collection order");
-
- ++state->index;
- state->prev_key = layer_key;
-
- /* Recurs into nested layer collections. */
- build_layer_collections(owner_id, &layer_collection->layer_collections, state);
-}
-
-void DepsgraphRelationBuilder::build_layer_collections(
- ID *owner_id,
- ListBase *layer_collections,
- LayerCollectionState *state)
-{
- LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
- /* Recurs into the layer. */
- build_layer_collection(owner_id, layer_collection, state);
- }
-}
-
-void DepsgraphRelationBuilder::build_view_layer_collections(
- ID *owner_id,
- ViewLayer *view_layer)
-{
- LayerCollectionState state;
- state.index = 0;
-
- OperationKey init_key(owner_id,
- DEG_NODE_TYPE_LAYER_COLLECTIONS,
- DEG_OPCODE_VIEW_LAYER_INIT);
- OperationKey done_key(owner_id,
- DEG_NODE_TYPE_LAYER_COLLECTIONS,
- DEG_OPCODE_VIEW_LAYER_DONE);
-
- state.init_key = init_key;
- state.done_key = done_key;
- state.prev_key = init_key;
-
- build_layer_collections(owner_id, &view_layer->layer_collections, &state);
-
- add_relation(state.prev_key, done_key, "Layer collection order");
-}
-
-} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index 2147ffce7b8..c80e0d568f3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -51,6 +51,7 @@ extern "C" {
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_constraint.h"
} /* extern "C" */
#include "DEG_depsgraph.h"
@@ -406,6 +407,11 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
}
/* Buil constraints. */
if (pchan->constraints.first != NULL) {
+ /* Build relations for indirectly linked objects. */
+ BuilderWalkUserData data;
+ data.builder = this;
+ BKE_constraints_id_loop(&pchan->constraints, constraint_walk, &data);
+
/* constraints stack and constraint dependencies */
build_constraints(&object->id, DEG_NODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index 074d20bb750..339046dfac0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -112,8 +112,6 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) {
build_movieclip(clip);
}
- /* Collections. */
- build_view_layer_collections(&scene_->id, view_layer);
/* TODO(sergey): Do this flush on CoW object? */
foreach (OperationDepsNode *node, graph_->operations) {
IDDepsNode *id_node = node->owner->owner;
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index a2e6993e442..3500f38467d 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -590,12 +590,14 @@ void DEG_debug_print_eval(const char *function_name,
if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
- printf("%s on %s %s(%p)%s\n",
- function_name,
- object_name,
- DEG::deg_color_for_pointer(object_address).c_str(),
- object_address,
- DEG::deg_color_end().c_str());
+ fprintf(stdout,
+ "%s on %s %s(%p)%s\n",
+ function_name,
+ object_name,
+ DEG::deg_color_for_pointer(object_address).c_str(),
+ object_address,
+ DEG::deg_color_end().c_str());
+ fflush(stdout);
}
void DEG_debug_print_eval_subdata(const char *function_name,
@@ -608,17 +610,19 @@ void DEG_debug_print_eval_subdata(const char *function_name,
if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
- printf("%s on %s %s(%p)%s %s %s %s(%p)%s\n",
- function_name,
- object_name,
- DEG::deg_color_for_pointer(object_address).c_str(),
- object_address,
- DEG::deg_color_end().c_str(),
- subdata_comment,
- subdata_name,
- DEG::deg_color_for_pointer(subdata_address).c_str(),
- subdata_address,
- DEG::deg_color_end().c_str());
+ fprintf(stdout,
+ "%s on %s %s(%p)%s %s %s %s(%p)%s\n",
+ function_name,
+ object_name,
+ DEG::deg_color_for_pointer(object_address).c_str(),
+ object_address,
+ DEG::deg_color_end().c_str(),
+ subdata_comment,
+ subdata_name,
+ DEG::deg_color_for_pointer(subdata_address).c_str(),
+ subdata_address,
+ DEG::deg_color_end().c_str());
+ fflush(stdout);
}
void DEG_debug_print_eval_subdata_index(const char *function_name,
@@ -632,18 +636,20 @@ void DEG_debug_print_eval_subdata_index(const char *function_name,
if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
- printf("%s on %s %s(%p)^%s %s %s[%d] %s(%p)%s\n",
- function_name,
- object_name,
- DEG::deg_color_for_pointer(object_address).c_str(),
- object_address,
- DEG::deg_color_end().c_str(),
- subdata_comment,
- subdata_name,
- subdata_index,
- DEG::deg_color_for_pointer(subdata_address).c_str(),
- subdata_address,
- DEG::deg_color_end().c_str());
+ fprintf(stdout,
+ "%s on %s %s(%p)^%s %s %s[%d] %s(%p)%s\n",
+ function_name,
+ object_name,
+ DEG::deg_color_for_pointer(object_address).c_str(),
+ object_address,
+ DEG::deg_color_end().c_str(),
+ subdata_comment,
+ subdata_name,
+ subdata_index,
+ DEG::deg_color_for_pointer(subdata_address).c_str(),
+ subdata_address,
+ DEG::deg_color_end().c_str());
+ fflush(stdout);
}
void DEG_debug_print_eval_time(const char *function_name,
@@ -654,11 +660,13 @@ void DEG_debug_print_eval_time(const char *function_name,
if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
- printf("%s on %s %s(%p)%s at time %f\n",
- function_name,
- object_name,
- DEG::deg_color_for_pointer(object_address).c_str(),
- object_address,
- DEG::deg_color_end().c_str(),
- time);
+ fprintf(stdout,
+ "%s on %s %s(%p)%s at time %f\n",
+ function_name,
+ object_name,
+ DEG::deg_color_for_pointer(object_address).c_str(),
+ object_address,
+ DEG::deg_color_end().c_str(),
+ time);
+ fflush(stdout);
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 63c9aa1407a..4e70e56ae71 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -45,6 +45,7 @@ extern "C" {
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/depsgraph_intern.h"
#include "intern/nodes/deg_node_id.h"
@@ -77,20 +78,44 @@ short DEG_get_eval_flags_for_id(const Depsgraph *graph, ID *id)
Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
{
- const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
+ const DEG::Depsgraph *deg_graph =
+ reinterpret_cast<const DEG::Depsgraph *>(graph);
Scene *scene_orig = deg_graph->scene;
- return reinterpret_cast<Scene *>(deg_graph->get_cow_id(&scene_orig->id));
+ Scene *scene_cow =
+ reinterpret_cast<Scene *>(deg_graph->get_cow_id(&scene_orig->id));
+ /* TODO(sergey): Shall we expand datablock here? Or is it OK to assume
+ * that calleer is OK with just a pointer in case scene is not up[dated
+ * yet?
+ */
+ return scene_cow;
}
ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
{
- const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
+ const DEG::Depsgraph *deg_graph =
+ reinterpret_cast<const DEG::Depsgraph *>(graph);
Scene *scene_cow = DEG_get_evaluated_scene(graph);
+ /* We update copy-on-write scene in the following cases:
+ * - It was not expanded yet.
+ * - It was tagged for update of CoW component.
+ * This allows us to have proper view layer pointer.
+ */
+ if (DEG_depsgraph_use_copy_on_write() &&
+ (!DEG::deg_copy_on_write_is_expanded(&scene_cow->id) ||
+ scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE))
+ {
+ const DEG::IDDepsNode *id_node =
+ deg_graph->find_id_node(&deg_graph->scene->id);
+ DEG::deg_update_copy_on_write_datablock(deg_graph, id_node);
+ }
+ /* Do name-based lookup. */
+ /* TODO(sergey): Can this be optimized? */
ViewLayer *view_layer_orig = deg_graph->view_layer;
ViewLayer *view_layer_cow =
(ViewLayer *)BLI_findstring(&scene_cow->view_layers,
view_layer_orig->name,
offsetof(ViewLayer, name));
+ BLI_assert(view_layer_cow != NULL);
return view_layer_cow;
}
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index b3796f56083..d1de12f4591 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -136,7 +136,7 @@ void depsgraph_select_tag_to_component_opcode(
* road.
*/
*component_type = DEG_NODE_TYPE_LAYER_COLLECTIONS;
- *operation_code = DEG_OPCODE_VIEW_LAYER_DONE;
+ *operation_code = DEG_OPCODE_VIEW_LAYER_EVAL;
}
else if (id_type == ID_OB) {
*component_type = DEG_NODE_TYPE_LAYER_COLLECTIONS;
@@ -156,7 +156,7 @@ void depsgraph_base_flags_tag_to_component_opcode(
const ID_Type id_type = GS(id->name);
if (id_type == ID_SCE) {
*component_type = DEG_NODE_TYPE_LAYER_COLLECTIONS;
- *operation_code = DEG_OPCODE_VIEW_LAYER_INIT;
+ *operation_code = DEG_OPCODE_VIEW_LAYER_EVAL;
}
else if (id_type == ID_OB) {
*component_type = DEG_NODE_TYPE_LAYER_COLLECTIONS;
@@ -280,6 +280,13 @@ void depsgraph_tag_component(Depsgraph *graph,
operation_node->tag_update(graph);
}
}
+ /* If component depends on copy-on-write, tag it as well. */
+ if (DEG_depsgraph_use_copy_on_write() && component_node->depends_on_cow()) {
+ ComponentDepsNode *cow_comp =
+ id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
+ cow_comp->tag_update(graph);
+ id_node->id_orig->recalc |= ID_RECALC_COPY_ON_WRITE;
+ }
}
/* This is a tag compatibility with legacy code.
diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
index 15144a8f31f..c4fc9591611 100644
--- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc
+++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
@@ -127,9 +127,7 @@ static const char *stringify_opcode(eDepsOperation_Code opcode)
STRINGIFY_OPCODE(MASK_ANIMATION);
STRINGIFY_OPCODE(MASK_EVAL);
/* Collections. */
- STRINGIFY_OPCODE(VIEW_LAYER_INIT);
STRINGIFY_OPCODE(VIEW_LAYER_EVAL);
- STRINGIFY_OPCODE(VIEW_LAYER_DONE);
/* Copy on write. */
STRINGIFY_OPCODE(COPY_ON_WRITE);
/* Shading. */
diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h
index 3aa204490eb..d6c410347f6 100644
--- a/source/blender/depsgraph/intern/depsgraph_types.h
+++ b/source/blender/depsgraph/intern/depsgraph_types.h
@@ -245,9 +245,7 @@ typedef enum eDepsOperation_Code {
DEG_OPCODE_POINT_CACHE_RESET,
/* Collections. ------------------------------------- */
- DEG_OPCODE_VIEW_LAYER_INIT,
DEG_OPCODE_VIEW_LAYER_EVAL,
- DEG_OPCODE_VIEW_LAYER_DONE,
/* Copy on Write. ------------------------------------ */
DEG_OPCODE_COPY_ON_WRITE,
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 3c40abe6a68..1d2169f5ec4 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -311,15 +311,6 @@ BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
return (id_cow->name[0] != '\0');
}
-/* Check whether datablock was already expanded during depsgraph
- * construction.
- */
-static bool check_datablock_expanded_at_construction(const ID *id_orig)
-{
- const ID_Type id_type = GS(id_orig->name);
- return (id_type == ID_SCE);
-}
-
/* Those are datablocks which are not covered by dependency graph and hence
* does not need any remapping or anything.
*
@@ -467,219 +458,6 @@ void update_special_pointers(const Depsgraph *depsgraph,
}
}
-void update_copy_on_write_layer_collections(
- ListBase *layer_collections_cow,
- const ListBase *layer_collections_orig);
-
-void update_copy_on_write_layer_collection(
- LayerCollection *layer_collection_cow,
- const LayerCollection *layer_collection_orig)
-{
- // Make a local copy of original layer collection, so we can start
- // modifying it.
- LayerCollection local = *layer_collection_orig;
- // Copy all pointer data from original CoW version of layer collection.
- local.next = layer_collection_cow->next;
- local.prev = layer_collection_cow->prev;
- local.scene_collection = layer_collection_cow->scene_collection;
- local.object_bases = layer_collection_cow->object_bases;
- local.overrides = layer_collection_cow->overrides;
- local.layer_collections = layer_collection_cow->layer_collections;
- local.properties = layer_collection_cow->properties;
- local.properties_evaluated = layer_collection_cow->properties_evaluated;
- // Synchronize pointer-related data.
- IDP_Reset(local.properties, layer_collection_orig->properties);
- // Copy synchronized version back.
- *layer_collection_cow = local;
- // Recurs into nested layer collections.
- update_copy_on_write_layer_collections(
- &layer_collection_cow->layer_collections,
- &layer_collection_orig->layer_collections);
-}
-
-void update_copy_on_write_layer_collections(
- ListBase *layer_collections_cow,
- const ListBase *layer_collections_orig)
-{
- const LayerCollection *layer_collection_orig =
- (const LayerCollection *)layer_collections_orig->first;
- LayerCollection *layer_collection_cow =
- (LayerCollection *)layer_collections_cow->first;
- while (layer_collection_orig != NULL) {
- update_copy_on_write_layer_collection(layer_collection_cow,
- layer_collection_orig);
- layer_collection_orig = layer_collection_orig->next;
- layer_collection_cow = layer_collection_cow->next;
- }
-}
-
-void update_copy_on_write_view_layer(const Depsgraph *depsgraph,
- ViewLayer *view_layer_cow,
- const ViewLayer *view_layer_orig)
-{
- // Update pointers to active base.
- if (view_layer_orig->basact == NULL) {
- view_layer_cow->basact = NULL;
- }
- else {
- const Object *obact_orig = view_layer_orig->basact->object;
- Object *obact_cow = (Object *)depsgraph->get_cow_id(&obact_orig->id);
- view_layer_cow->basact = BKE_view_layer_base_find(view_layer_cow, obact_cow);
- }
- // Update base flags.
- //
- // TODO(sergey): We should probably check visibled/selectabled.
- // flag here?
- const Base *base_orig = (Base *)view_layer_orig->object_bases.first;
- Base *base_cow = (Base *)view_layer_cow->object_bases.first;;
- while (base_orig != NULL) {
- base_cow->flag = base_orig->flag;
- base_orig = base_orig->next;
- base_cow = base_cow->next;
- }
- // Synchronize settings.
- view_layer_cow->active_collection = view_layer_orig->active_collection;
- view_layer_cow->flag = view_layer_orig->flag;
- view_layer_cow->layflag = view_layer_orig->layflag;
- view_layer_cow->passflag = view_layer_orig->passflag;
- view_layer_cow->pass_alpha_threshold = view_layer_orig->pass_alpha_threshold;
- // Synchronize ID properties.
- IDP_Reset(view_layer_cow->properties, view_layer_orig->properties);
- IDP_Reset(view_layer_cow->id_properties, view_layer_orig->id_properties);
- // Synchronize layer collections.
- update_copy_on_write_layer_collections(
- &view_layer_cow->layer_collections,
- &view_layer_orig->layer_collections);
-}
-
-void update_copy_on_write_view_layers(const Depsgraph *depsgraph,
- Scene *scene_cow,
- const Scene *scene_orig)
-{
- const ViewLayer *view_layer_orig = (const ViewLayer *)scene_orig->view_layers.first;
- ViewLayer *view_layer_cow = (ViewLayer *)scene_cow->view_layers.first;
- while (view_layer_orig != NULL) {
- update_copy_on_write_view_layer(depsgraph,
- view_layer_cow,
- view_layer_orig);
- view_layer_orig = view_layer_orig->next;
- view_layer_cow = view_layer_cow->next;
- }
-}
-
-void update_copy_on_write_scene_collections(
- ListBase *collections_cow,
- const ListBase *collections_orig);
-
-void update_copy_on_write_scene_collection(
- SceneCollection *collection_cow,
- const SceneCollection *collection_orig)
-{
- collection_cow->active_object_index = collection_orig->active_object_index;
- update_copy_on_write_scene_collections(
- &collection_cow->scene_collections,
- &collection_orig->scene_collections);
-}
-
-void update_copy_on_write_scene_collections(
- ListBase *collections_cow,
- const ListBase *collections_orig)
-{
- const SceneCollection *nested_collection_orig =
- (const SceneCollection *)collections_orig->first;
- SceneCollection *nested_collection_cow =
- (SceneCollection *)collections_cow->first;
- while (nested_collection_orig != NULL) {
- update_copy_on_write_scene_collection(
- nested_collection_cow,
- nested_collection_orig);
- nested_collection_orig = nested_collection_orig->next;
- nested_collection_cow = nested_collection_cow->next;
- }
-}
-
-/* Update copy-on-write version of scene from original scene. */
-void update_copy_on_write_scene(const Depsgraph *depsgraph,
- Scene *scene_cow,
- const Scene *scene_orig)
-{
- // Some non-pointer data sync, current frame for now.
- // TODO(sergey): Are we missing something here?
- scene_cow->r.cfra = scene_orig->r.cfra;
- scene_cow->r.subframe = scene_orig->r.subframe;
- // Update view layers and collections.
- update_copy_on_write_view_layers(depsgraph, scene_cow, scene_orig);
- update_copy_on_write_scene_collection(scene_cow->collection,
- scene_orig->collection);
- /* Synchronize active render engine. */
- BLI_strncpy(scene_cow->view_render.engine_id,
- scene_orig->view_render.engine_id,
- sizeof(scene_cow->view_render.engine_id));
- BKE_toolsettings_free(scene_cow->toolsettings);
- scene_cow->toolsettings = BKE_toolsettings_copy(scene_orig->toolsettings, 0);
- /* TODO(sergey): What else do we need here? */
-}
-
-/* Update copy-on-write version of armature object from original scene. */
-void update_copy_on_write_object(const Depsgraph * /*depsgraph*/,
- Object *object_cow,
- const Object *object_orig)
-{
- /* TODO(sergey): This function might be split into a smaller ones,
- * reused for different updates. And maybe even moved to BKE.
- */
- /* Update armature/pose related flags. */
- bPose *pose_cow = object_cow->pose;
- const bPose *pose_orig = object_orig->pose;
- extract_pose_from_pose(pose_cow, pose_orig);
- /* Update object itself. */
- BKE_object_transform_copy(object_cow, object_orig);
- object_cow->mode = object_orig->mode;
-}
-
-/* Update copy-on-write version of datablock from it's original ID without re-building
- * the whole datablock from scratch.
- *
- * Used for such special cases as scene collections and armatures, which can not use full
- * re-alloc due to pointers used as function bindings.
- */
-void update_copy_on_write_datablock(const Depsgraph *depsgraph,
- const ID *id_orig, ID *id_cow)
-{
- bool ok = false;
- const ID_Type id_type = GS(id_orig->name);
- switch (id_type) {
- case ID_SCE: {
- const Scene *scene_orig = (const Scene *)id_orig;
- Scene *scene_cow = (Scene *)id_cow;
- update_copy_on_write_scene(depsgraph, scene_cow, scene_orig);
- ok = true;
- break;
- }
- case ID_OB: {
- const Object *object_orig = (const Object *)id_orig;
- Object *object_cow = (Object *)id_cow;
- if (object_orig->type == OB_ARMATURE) {
- update_copy_on_write_object(depsgraph,
- object_cow,
- object_orig);
- ok = true;
- }
- break;
- }
- case ID_AR:
- /* Nothing to do currently. */
- ok = true;
- break;
- default:
- break;
- }
- // TODO(sergey): Other ID types here.
- if (!ok) {
- BLI_assert(!"Missing update logic of expanded datablock");
- }
-}
-
/* This callback is used to validate that all nested ID datablocks are
* properly expanded.
*/
@@ -710,8 +488,6 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
DepsgraphNodeBuilder *node_builder,
bool create_placeholders)
{
- BLI_assert(!create_placeholders ||
- check_datablock_expanded_at_construction(id_node->id_orig));
const ID *id_orig = id_node->id_orig;
ID *id_cow = id_node->id_cow;
/* No need to expand such datablocks, their copied ID is same as original
@@ -833,15 +609,6 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph,
if (!deg_copy_on_write_is_needed(id_orig)) {
return id_cow;
}
- /* Special case for datablocks which are expanded at the dependency graph
- * construction time. This datablocks must never change pointers of their
- * nested data since it is used for function bindings.
- */
- if (check_datablock_expanded_at_construction(id_orig)) {
- BLI_assert(check_datablock_expanded(id_cow) == true);
- update_copy_on_write_datablock(depsgraph, id_orig, id_cow);
- return id_cow;
- }
/* For the rest if datablock types we use simple logic:
* - Free previously expanded data, if any.
* - Perform full datablock copy.
@@ -1019,6 +786,12 @@ void deg_evaluate_copy_on_write(const EvaluationContext * /*eval_ctx*/,
const IDDepsNode *id_node)
{
DEBUG_PRINT("%s on %s\n", __func__, id_node->id_orig->name);
+ if (id_node->id_orig == &depsgraph->scene->id) {
+ /* NOTE: This is handled by eval_ctx setup routines, which
+ * ensures scene and view layer pointers are valid.
+ */
+ return;
+ }
deg_update_copy_on_write_datablock(depsgraph, id_node);
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 8be8a4b31ba..f7f55610d22 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -135,10 +135,8 @@ BLI_INLINE void flush_handle_id_node(IDDepsNode *id_node)
}
/* TODO(sergey): We can reduce number of arguments here. */
-BLI_INLINE void flush_handle_component_node(Depsgraph *graph,
- IDDepsNode *id_node,
+BLI_INLINE void flush_handle_component_node(IDDepsNode *id_node,
ComponentDepsNode *comp_node,
- bool use_copy_on_write,
FlushQueue *queue)
{
/* We only handle component once. */
@@ -146,16 +144,6 @@ BLI_INLINE void flush_handle_component_node(Depsgraph *graph,
return;
}
comp_node->done = COMPONENT_STATE_DONE;
- /* Currently this is needed to get object->mesh to be replaced with
- * original mesh (rather than being evaluated_mesh).
- *
- * TODO(sergey): This is something we need to avoid.
- */
- if (use_copy_on_write && comp_node->depends_on_cow()) {
- ComponentDepsNode *cow_comp =
- id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
- cow_comp->tag_update(graph);
- }
/* Tag all required operations in component for update. */
foreach (OperationDepsNode *op, comp_node->operations) {
/* We don't want to flush tags in "upstream" direction for
@@ -168,7 +156,7 @@ BLI_INLINE void flush_handle_component_node(Depsgraph *graph,
}
op->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
}
- /* When some target changes bone, we might need to re-run the
+ /* when some target changes bone, we might need to re-run the
* whole IK solver, otherwise result might be unpredictable.
*/
if (comp_node->type == DEG_NODE_TYPE_BONE) {
@@ -266,7 +254,6 @@ void flush_editors_id_update(Main *bmain,
*/
void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
{
- const bool use_copy_on_write = DEG_depsgraph_use_copy_on_write();
/* Sanity checks. */
BLI_assert(bmain != NULL);
BLI_assert(graph != NULL);
@@ -296,10 +283,8 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
ComponentDepsNode *comp_node = op_node->owner;
IDDepsNode *id_node = comp_node->owner;
flush_handle_id_node(id_node);
- flush_handle_component_node(graph,
- id_node,
+ flush_handle_component_node(id_node,
comp_node,
- use_copy_on_write,
&queue);
/* Flush to nodes along links. */
op_node = flush_schedule_children(op_node, &queue);
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
index 6c33856555e..786faa6e86c 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
@@ -381,7 +381,7 @@ DEG_COMPONENT_NODE_DEFINE(Animation, ANIMATION, ID_RECALC_ANIMA
DEG_COMPONENT_NODE_DEFINE(BatchCache, BATCH_CACHE, ID_RECALC_DRAW_CACHE);
DEG_COMPONENT_NODE_DEFINE(Bone, BONE, ID_RECALC_GEOMETRY);
DEG_COMPONENT_NODE_DEFINE(Cache, CACHE, ID_RECALC);
-DEG_COMPONENT_NODE_DEFINE(CopyOnWrite, COPY_ON_WRITE, ID_RECALC);
+DEG_COMPONENT_NODE_DEFINE(CopyOnWrite, COPY_ON_WRITE, ID_RECALC_COPY_ON_WRITE);
DEG_COMPONENT_NODE_DEFINE(Geometry, GEOMETRY, ID_RECALC_GEOMETRY);
DEG_COMPONENT_NODE_DEFINE(LayerCollections, LAYER_COLLECTIONS, ID_RECALC_COLLECTIONS);
DEG_COMPONENT_NODE_DEFINE(Parameters, PARAMETERS, ID_RECALC);
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index c80e0cdf4f7..4976cd01d11 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -426,12 +426,6 @@ static void clay_engine_init(void *vedata)
e_data.copy_sh = DRW_shader_create_fullscreen(datatoc_clay_copy_glsl, NULL);
}
- if (!e_data.hair_sh) {
- e_data.hair_sh = DRW_shader_create(
- datatoc_clay_particle_vert_glsl, NULL, datatoc_clay_particle_strand_frag_glsl,
- "#define MAX_MATERIAL 512\n");
- }
-
if (!stl->storage) {
stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage");
}
@@ -604,6 +598,12 @@ static DRWShadingGroup *CLAY_hair_shgroup_create(DRWPass *pass, int id)
{
CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get();
+ if (!e_data.hair_sh) {
+ e_data.hair_sh = DRW_shader_create(
+ datatoc_clay_particle_vert_glsl, NULL, datatoc_clay_particle_strand_frag_glsl,
+ "#define MAX_MATERIAL 512\n");
+ }
+
DRWShadingGroup *grp = DRW_shgroup_create(e_data.hair_sh, pass);
DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array);
DRW_shgroup_uniform_block(grp, "material_block", sldata->mat_ubo);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 56c9ed4555d..7496142a26e 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -107,50 +107,6 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
if (!e_data.shadow_sh) {
e_data.shadow_sh = DRW_shader_create(
datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_frag_glsl, NULL);
-
- DynStr *ds_frag = BLI_dynstr_new();
- BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
- BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
- char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
- BLI_dynstr_free(ds_frag);
-
- e_data.shadow_store_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define ESM\n");
- e_data.shadow_store_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define ESM\n"
- "#define CSM\n");
-
- e_data.shadow_store_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define VSM\n");
- e_data.shadow_store_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define VSM\n"
- "#define CSM\n");
-
- MEM_freeN(store_shadow_shader_str);
-
- e_data.shadow_copy_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
- datatoc_shadow_copy_frag_glsl,
- "#define ESM\n"
- "#define COPY\n");
- e_data.shadow_copy_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
- datatoc_shadow_copy_frag_glsl,
- "#define ESM\n"
- "#define COPY\n"
- "#define CSM\n");
-
- e_data.shadow_copy_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
- datatoc_shadow_copy_frag_glsl,
- "#define VSM\n"
- "#define COPY\n");
- e_data.shadow_copy_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
- datatoc_shadow_copy_frag_glsl,
- "#define VSM\n"
- "#define COPY\n"
- "#define CSM\n");
}
if (!sldata->lamps) {
@@ -204,6 +160,60 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
linfo->shadow_cube_target_size = new_cube_target_size;
linfo->shadow_render_data.cube_texel_size = 1.0 / (float)linfo->shadow_cube_target_size;
}
+
+ /* only compile the ones needed. reduce startup time. */
+ if ((sh_method == SHADOW_ESM) && !e_data.shadow_store_cube_sh[SHADOW_ESM]) {
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
+ char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.shadow_store_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
+ store_shadow_shader_str,
+ "#define ESM\n");
+ e_data.shadow_store_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
+ store_shadow_shader_str,
+ "#define ESM\n"
+ "#define CSM\n");
+ MEM_freeN(store_shadow_shader_str);
+
+ e_data.shadow_copy_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
+ datatoc_shadow_copy_frag_glsl,
+ "#define ESM\n"
+ "#define COPY\n");
+ e_data.shadow_copy_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
+ datatoc_shadow_copy_frag_glsl,
+ "#define ESM\n"
+ "#define COPY\n"
+ "#define CSM\n");
+ }
+ else if ((sh_method == SHADOW_VSM) && !e_data.shadow_store_cube_sh[SHADOW_VSM]) {
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
+ char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.shadow_store_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
+ store_shadow_shader_str,
+ "#define VSM\n");
+ e_data.shadow_store_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
+ store_shadow_shader_str,
+ "#define VSM\n"
+ "#define CSM\n");
+ MEM_freeN(store_shadow_shader_str);
+
+ e_data.shadow_copy_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
+ datatoc_shadow_copy_frag_glsl,
+ "#define VSM\n"
+ "#define COPY\n");
+ e_data.shadow_copy_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
+ datatoc_shadow_copy_frag_glsl,
+ "#define VSM\n"
+ "#define COPY\n"
+ "#define CSM\n");
+ }
}
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 55d528e49b0..0530d05c199 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -55,11 +55,11 @@ static void particle_batch_cache_clear(ParticleSystem *psys);
typedef struct ParticleBatchCache {
Gwn_VertBuf *pos;
- Gwn_IndexBuf *segments;
+ Gwn_IndexBuf *indices;
Gwn_Batch *hairs;
- int segment_count;
+ int elems_count;
int point_count;
/* settings to determine if cache is invalid */
@@ -134,7 +134,7 @@ static void particle_batch_cache_clear(ParticleSystem *psys)
GWN_BATCH_DISCARD_SAFE(cache->hairs);
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
- GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
+ GWN_INDEXBUF_DISCARD_SAFE(cache->indices);
}
void DRW_particle_batch_cache_free(ParticleSystem *psys)
@@ -145,8 +145,8 @@ void DRW_particle_batch_cache_free(ParticleSystem *psys)
static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache)
{
- if (cache->pos == NULL || cache->segments == NULL) {
- cache->segment_count = 0;
+ if (cache->pos == NULL || cache->indices == NULL) {
+ cache->elems_count = 0;
cache->point_count = 0;
if (psys->pathcache && (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
@@ -154,7 +154,7 @@ static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache)
ParticleCacheKey *path = psys->pathcache[i];
if (path->segments > 0) {
- cache->segment_count += path->segments;
+ cache->elems_count += path->segments + 2;
cache->point_count += path->segments + 1;
}
}
@@ -167,7 +167,7 @@ static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache)
ParticleCacheKey *path = psys->childcache[i];
if (path->segments > 0) {
- cache->segment_count += path->segments;
+ cache->elems_count += path->segments + 2;
cache->point_count += path->segments + 1;
}
}
@@ -178,7 +178,7 @@ static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache)
/* Gwn_Batch cache usage. */
static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, ModifierData *md, ParticleBatchCache *cache)
{
- if (cache->pos != NULL && cache->segments != NULL) {
+ if (cache->pos != NULL && cache->indices != NULL) {
return;
}
@@ -186,7 +186,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
- GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
+ GWN_INDEXBUF_DISCARD_SAFE(cache->indices);
static Gwn_VertFormat format = { 0 };
static struct { uint pos, tan, ind; } attr_id;
@@ -225,7 +225,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
GWN_vertbuf_data_alloc(cache->pos, cache->point_count);
Gwn_IndexBufBuilder elb;
- GWN_indexbuf_init(&elb, GWN_PRIM_LINES, cache->segment_count, cache->point_count);
+ GWN_indexbuf_init_ex(&elb, GWN_PRIM_LINE_STRIP, cache->elems_count, cache->point_count, true);
if (uv_layers) {
DM_ensure_tessface(psmd->dm_final);
@@ -295,7 +295,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
}
}
- GWN_indexbuf_add_line_verts(&elb, curr_point, curr_point + 1);
+ GWN_indexbuf_add_generic_vert(&elb, curr_point);
curr_point++;
}
@@ -316,6 +316,10 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
}
}
+ /* finish the segment and add restart primitive */
+ GWN_indexbuf_add_generic_vert(&elb, curr_point);
+ GWN_indexbuf_add_primitive_restart(&elb);
+
curr_point++;
}
}
@@ -398,7 +402,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
}
}
- GWN_indexbuf_add_line_verts(&elb, curr_point, curr_point + 1);
+ GWN_indexbuf_add_generic_vert(&elb, curr_point);
curr_point++;
}
@@ -420,6 +424,10 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
}
}
+ /* finish the segment and add restart primitive */
+ GWN_indexbuf_add_generic_vert(&elb, curr_point);
+ GWN_indexbuf_add_primitive_restart(&elb);
+
curr_point++;
}
}
@@ -441,7 +449,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
MEM_freeN(uv_id);
}
- cache->segments = GWN_indexbuf_build(&elb);
+ cache->indices = GWN_indexbuf_build(&elb);
}
static void particle_batch_cache_ensure_pos(Object *object, ParticleSystem *psys, ParticleBatchCache *cache)
@@ -473,7 +481,7 @@ static void particle_batch_cache_ensure_pos(Object *object, ParticleSystem *psys
}
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
- GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
+ GWN_INDEXBUF_DISCARD_SAFE(cache->indices);
if (format.attrib_ct == 0) {
/* initialize vertex format */
@@ -525,7 +533,7 @@ Gwn_Batch *DRW_particles_batch_cache_get_hair(ParticleSystem *psys, ModifierData
if (cache->hairs == NULL) {
ensure_seg_pt_count(psys, cache);
particle_batch_cache_ensure_pos_and_seg(psys, md, cache);
- cache->hairs = GWN_batch_create(GWN_PRIM_LINES, cache->pos, cache->segments);
+ cache->hairs = GWN_batch_create(GWN_PRIM_LINE_STRIP, cache->pos, cache->indices);
}
return cache->hairs;
diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c
index 47769b1fb18..d2ed22c57b7 100644
--- a/source/blender/draw/intern/draw_manager_profiling.c
+++ b/source/blender/draw/intern/draw_manager_profiling.c
@@ -225,7 +225,13 @@ void DRW_stats_draw(rcti *rect)
double init_tot_time = 0.0, background_tot_time = 0.0, render_tot_time = 0.0, tot_time = 0.0;
- UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ int fontid = BLF_default();
+ UI_FontThemeColor(fontid, TH_TEXT_HI);
+ BLF_enable(fontid, BLF_SHADOW);
+ BLF_shadow(fontid, 5, (const float[4]){0.0f, 0.0f, 0.0f, 0.75f});
+ BLF_shadow_offset(fontid, 0, -1);
+
+ BLF_batch_draw_begin();
/* ------------------------------------------ */
/* ---------------- CPU stats --------------- */
@@ -351,4 +357,7 @@ void DRW_stats_draw(rcti *rect)
draw_stat(rect, 16 + timer->lvl, v, stat_string, sizeof(stat_string));
v++;
}
+
+ BLF_batch_draw_end();
+ BLF_disable(fontid, BLF_SHADOW);
}
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 5b4971f0730..c7fbe1dd42b 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -98,8 +98,9 @@ static void drw_deferred_shader_queue_free(ListBase *queue)
static void drw_deferred_shader_compilation_exec(void *custom_data, short *stop, short *do_update, float *progress)
{
DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
+ void *ogl_context = comp->ogl_context;
- WM_opengl_context_activate(comp->ogl_context);
+ WM_opengl_context_activate(ogl_context);
while (true) {
BLI_spin_lock(&comp->list_lock);
@@ -137,12 +138,13 @@ static void drw_deferred_shader_compilation_exec(void *custom_data, short *stop,
*progress = (float)comp->shaders_done / (float)total;
*do_update = true;
+ glFinish();
BLI_mutex_unlock(&comp->compilation_lock);
drw_deferred_shader_free(comp->mat_compiling);
}
- WM_opengl_context_release(comp->ogl_context);
+ WM_opengl_context_release(ogl_context);
}
static void drw_deferred_shader_compilation_free(void *custom_data)
@@ -154,7 +156,10 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
BLI_spin_end(&comp->list_lock);
BLI_mutex_end(&comp->compilation_lock);
- WM_opengl_context_dispose(comp->ogl_context);
+ if (comp->ogl_context) {
+ /* Only destroy if the job owns the context. */
+ WM_opengl_context_dispose(comp->ogl_context);
+ }
MEM_freeN(comp);
}
@@ -198,13 +203,18 @@ static void drw_deferred_shader_add(
BLI_spin_lock(&old_comp->list_lock);
BLI_movelisttolist(&comp->queue, &old_comp->queue);
BLI_spin_unlock(&old_comp->list_lock);
+ /* Do not recreate context, just pass ownership. */
+ comp->ogl_context = old_comp->ogl_context;
+ old_comp->ogl_context = NULL;
}
BLI_addtail(&comp->queue, dsh);
- /* Create one context per task. */
- comp->ogl_context = WM_opengl_context_create();
- WM_opengl_context_activate(DST.ogl_context);
+ /* Create only one context. */
+ if (comp->ogl_context == NULL) {
+ comp->ogl_context = WM_opengl_context_create();
+ WM_opengl_context_activate(DST.ogl_context);
+ }
WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free);
WM_jobs_timer(wm_job, 0.1, NC_MATERIAL | ND_SHADING_DRAW, 0);
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 2f9d32eadb6..4af8089ffea 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -2726,7 +2726,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
/* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
if (ob != CTX_data_edit_object(C))
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 15ffd09ebd4..520ecc797aa 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -82,46 +82,62 @@ Object *ED_pose_object_from_context(bContext *C)
}
/* This function is used to process the necessary updates for */
-void ED_armature_enter_posemode(bContext *C, Base *base)
+bool ED_object_posemode_enter_ex(struct Main *bmain, Object *ob)
{
- ReportList *reports = CTX_wm_reports(C);
- Object *ob = base->object;
-
- if (ID_IS_LINKED(ob)) {
- BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
- return;
- }
+ BLI_assert(!ID_IS_LINKED(ob));
+ bool ok = false;
switch (ob->type) {
case OB_ARMATURE:
ob->restore_mode = ob->mode;
ob->mode |= OB_MODE_POSE;
/* Inform all CoW versions that we changed the mode. */
- DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
-
+ DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_COPY_ON_WRITE);
+ ok = true;
+
break;
default:
- return;
+ break;
}
-
- /* XXX: disabled as this would otherwise cause a nasty loop... */
- //ED_object_mode_toggle(C, ob->mode);
+
+ return ok;
+}
+bool ED_object_posemode_enter(bContext *C, Object *ob)
+{
+ ReportList *reports = CTX_wm_reports(C);
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
+ return false;
+ }
+ struct Main *bmain = CTX_data_main(C);
+ bool ok = ED_object_posemode_enter_ex(bmain, ob);
+ if (ok) {
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
+ }
+ return ok;
}
-void ED_armature_exit_posemode(bContext *C, Base *base)
+bool ED_object_posemode_exit_ex(struct Main *bmain, Object *ob)
{
- if (base) {
- Object *ob = base->object;
-
+ bool ok = false;
+ if (ob) {
ob->restore_mode = ob->mode;
ob->mode &= ~OB_MODE_POSE;
/* Inform all CoW versions that we changed the mode. */
- DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE);
-
+ DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_COPY_ON_WRITE);
+ ok = true;
+ }
+ return ok;
+}
+bool ED_object_posemode_exit(bContext *C, Object *ob)
+{
+ struct Main *bmain = CTX_data_main(C);
+ bool ok = ED_object_posemode_exit_ex(bmain, ob);
+ if (ok) {
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
}
+ return ok;
}
/* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 0181cc20cdc..0dcc4f32e43 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -205,8 +205,10 @@ void ED_armature_ebone_listbase_free(struct ListBase *lb);
void ED_armature_ebone_listbase_copy(struct ListBase *lb_dst, struct ListBase *lb_src);
/* poseobject.c */
-void ED_armature_exit_posemode(struct bContext *C, struct Base *base);
-void ED_armature_enter_posemode(struct bContext *C, struct Base *base);
+bool ED_object_posemode_exit_ex(struct Main *bmain, struct Object *ob);
+bool ED_object_posemode_exit(struct bContext *C, struct Object *ob);
+bool ED_object_posemode_enter_ex(struct Main *bmain, struct Object *ob);
+bool ED_object_posemode_enter(struct bContext *C, struct Object *ob);
void ED_pose_de_selectall(struct Object *ob, int select_mode, const bool ignore_visibility);
void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select);
void ED_pose_recalculate_paths(struct bContext *C, struct Scene *scene, struct Object *ob);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index ebd9313f7c5..83119062203 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -119,11 +119,12 @@ struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, st
void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr);
/* bitflags for enter/exit editmode */
-#define EM_FREEDATA 1
-#define EM_FREEUNDO 2
-#define EM_WAITCURSOR 4
-#define EM_DO_UNDO 8
-#define EM_IGNORE_LAYER 16
+enum {
+ EM_FREEDATA = (1 << 0),
+ EM_WAITCURSOR = (1 << 1),
+ EM_DO_UNDO = (1 << 2),
+ EM_IGNORE_LAYER = (1 << 3),
+};
void ED_object_editmode_exit_ex(
struct bContext *C, struct Scene *scene, struct Object *obedit, int flag);
void ED_object_editmode_exit(struct bContext *C, int flag);
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index c3d6d635c17..67383ec73a6 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -302,19 +302,36 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
static void ui_block_region_draw(const bContext *C, ARegion *ar)
{
+ ScrArea *ctx_area = CTX_wm_area(C);
+ ARegion *ctx_region = CTX_wm_region(C);
uiBlock *block;
if (ar->do_draw & RGN_DRAW_REFRESH_UI) {
+ ScrArea *handle_ctx_area;
+ ARegion *handle_ctx_region;
uiBlock *block_next;
+
ar->do_draw &= ~RGN_DRAW_REFRESH_UI;
for (block = ar->uiblocks.first; block; block = block_next) {
block_next = block->next;
if (block->handle->can_refresh) {
+ handle_ctx_area = block->handle->ctx_area;
+ handle_ctx_region = block->handle->ctx_region;
+
+ if (handle_ctx_area) {
+ CTX_wm_area_set((bContext *)C, handle_ctx_area);
+ }
+ if (handle_ctx_region) {
+ CTX_wm_region_set((bContext *)C, handle_ctx_region);
+ }
ui_popup_block_refresh((bContext *)C, block->handle, NULL, NULL);
}
}
}
+ CTX_wm_area_set((bContext *)C, ctx_area);
+ CTX_wm_region_set((bContext *)C, ctx_region);
+
for (block = ar->uiblocks.first; block; block = block->next)
UI_block_draw(C, block);
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 3bdad2891d5..84f0adf333f 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1711,6 +1711,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
int selsta_draw, selwidth_draw;
if (drawstr[0] != 0) {
+ /* We are drawing on top of widget bases. Flush cache. */
+ glEnable(GL_BLEND);
+ UI_widgetbase_draw_cache_flush();
+ glDisable(GL_BLEND);
if (but->selsta >= but->ofs) {
selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs);
@@ -1752,6 +1756,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
else {
t = 0;
}
+ /* We are drawing on top of widget bases. Flush cache. */
+ glEnable(GL_BLEND);
+ UI_widgetbase_draw_cache_flush();
+ glDisable(GL_BLEND);
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -3035,6 +3043,11 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
widgetbase_draw(&wtb, &wcol_tmp);
+ /* We are drawing on top of widget bases. Flush cache. */
+ glEnable(GL_BLEND);
+ UI_widgetbase_draw_cache_flush();
+ glDisable(GL_BLEND);
+
/* cursor */
x = rect->xmin + 0.5f * BLI_rcti_size_x(rect);
y = rect->ymin + v * BLI_rcti_size_y(rect);
@@ -3505,7 +3518,6 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
}
widgetbase_draw(&wtb, wcol);
-
if (but->a1 == UI_PALETTE_COLOR && ((Palette *)but->rnapoin.id.data)->active_color == (int)but->a2) {
float width = rect->xmax - rect->xmin;
float height = rect->ymax - rect->ymin;
@@ -3514,6 +3526,11 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
bw += (bw < 0.5f) ? 0.5f : -0.5f;
+ /* We are drawing on top of widget bases. Flush cache. */
+ glEnable(GL_BLEND);
+ UI_widgetbase_draw_cache_flush();
+ glDisable(GL_BLEND);
+
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -3878,6 +3895,11 @@ static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundbox
#endif
widgetbase_draw(&wtb, wcol);
+ /* We are drawing on top of widget bases. Flush cache. */
+ glEnable(GL_BLEND);
+ UI_widgetbase_draw_cache_flush();
+ glDisable(GL_BLEND);
+
#ifdef USE_TAB_SHADED_HIGHLIGHT
/* draw outline (3d look) */
ui_draw_but_TAB_outline(rect, rad, theme_col_tab_highlight, (unsigned char *)wcol->inner);
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 6d39a66e123..375711194a3 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1892,7 +1892,9 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin);
-
+
+ BLF_batch_draw_begin();
+
for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) {
/* make prints look nicer for scrollers */
@@ -1919,6 +1921,8 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
break;
}
}
+
+ BLF_batch_draw_end();
}
}
}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index bfeb48f9308..4334a80cd39 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -432,7 +432,7 @@ Object *ED_object_add_type(
/* for as long scene has editmode... */
if (CTX_data_edit_object(C))
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */
/* deselects all, sets scene->basact */
ob = BKE_object_add(bmain, scene, view_layer, type, name);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 9306213581e..f4066360805 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -466,7 +466,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
if (!is_mode_set)
ED_object_editmode_enter(C, EM_WAITCURSOR);
else
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR); /* had EM_DO_UNDO but op flag calls undo too [#24685] */
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR); /* had EM_DO_UNDO but op flag calls undo too [#24685] */
ED_space_image_uv_sculpt_update(CTX_wm_manager(C), scene);
@@ -512,7 +512,7 @@ static int posemode_exec(bContext *C, wmOperator *op)
Base *base = CTX_data_active_base(C);
Object *ob = base->object;
const int mode_flag = OB_MODE_POSE;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
+ bool is_mode_set = (ob->mode & mode_flag) != 0;
if (!is_mode_set) {
if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
@@ -523,13 +523,15 @@ static int posemode_exec(bContext *C, wmOperator *op)
if (ob->type == OB_ARMATURE) {
if (ob == CTX_data_edit_object(C)) {
ED_object_editmode_exit(C, EM_FREEDATA | EM_DO_UNDO);
- ED_armature_enter_posemode(C, base);
+ is_mode_set = false;
}
- else if (is_mode_set)
- ED_armature_exit_posemode(C, base);
- else
- ED_armature_enter_posemode(C, base);
+ if (is_mode_set) {
+ ED_object_posemode_exit(C, ob);
+ }
+ else {
+ ED_object_posemode_enter(C, ob);
+ }
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 4c28992aefe..c641499f39f 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -2070,15 +2070,29 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
/* before setting the view */
if (vertical) {
/* we always keep the scroll offset - so the total view gets increased with the scrolled away part */
- if (v2d->cur.ymax < - 0.001f)
- y = min_ii(y, v2d->cur.ymin);
-
+ if (v2d->cur.ymax < -FLT_EPSILON) {
+ /* Clamp to lower view boundary */
+ if (v2d->tot.ymin < -v2d->winy) {
+ y = min_ii(y, 0);
+ }
+ else {
+ y = min_ii(y, v2d->cur.ymin);
+ }
+ }
+
y = -y;
}
else {
/* don't jump back when panels close or hide */
- if (!is_context_new)
- x = max_ii(x, v2d->cur.xmax);
+ if (!is_context_new) {
+ if (v2d->tot.xmax > v2d->winx) {
+ x = max_ii(x, 0);
+ }
+ else {
+ x = max_ii(x, v2d->cur.xmax);
+ }
+ }
+
y = -y;
}
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index e0c73b1782e..98a6670d10f 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -93,7 +93,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
- Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ Object *obedit = view_layer ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 48453103c90..5891b8c2556 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -193,7 +193,9 @@ bool ED_workspace_change(
WM_window_set_active_layout(win, workspace_new, layout_new);
WM_window_set_active_workspace(win, workspace_new);
- /* update screen *after* changing workspace - which also causes the actual screen change */
+ /* update screen *after* changing workspace - which also causes the
+ * actual screen change and updates context (including CTX_wm_workspace) */
+ screen_change_update(C, win, screen_new);
workspace_change_update(workspace_new, workspace_old, C, wm);
BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index fb0ff23a57f..043f32c56e7 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -630,7 +630,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
int colorid = (file_selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
int shade = (params->highlight_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ? 35 : 0;
- BLI_assert(i > 0 || FILENAME_IS_CURRPAR(file->relpath));
+ BLI_assert(i == 0 || !FILENAME_IS_CURRPAR(file->relpath));
draw_tile(sx, sy - 1, layout->tile_w + 4, sfile->layout->tile_h + layout->tile_border_y, colorid, shade);
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index b03c6a2eb0b..104fff986cf 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -703,7 +703,7 @@ static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID
if (sgraph->ads && (ID *)sgraph->ads->filter_grp == old_id) {
sgraph->ads->filter_grp = (Group *)new_id;
}
- if ((ID *)sgraph->ads->source == old_id) {
+ if (sgraph->ads && (ID *)sgraph->ads->source == old_id) {
sgraph->ads->source = new_id;
}
}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 157171481bc..c7d4fa1465b 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -389,7 +389,7 @@ static void stats_update(ViewLayer *view_layer)
/* Pose Mode */
stats_object_pose(ob, &stats);
}
- else if (stats_is_object_dynamic_topology_sculpt(ob, ob->mode)) {
+ else if (ob && stats_is_object_dynamic_topology_sculpt(ob, ob->mode)) {
/* Dynamic-topology sculpt mode */
stats_object_sculpt_dynamic_topology(ob, &stats);
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index bfa8633ab7d..2f44420f3b7 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -195,7 +195,7 @@ static eOLDrawState tree_element_set_active_object(
}
if (ob != OBEDIT_FROM_VIEW_LAYER(view_layer))
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
return OL_DRAWSEL_NORMAL;
}
@@ -667,13 +667,16 @@ static eOLDrawState tree_element_active_pose(
}
if (set != OL_SETSEL_NONE) {
- if (OBEDIT_FROM_VIEW_LAYER(view_layer))
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
+ if (OBEDIT_FROM_VIEW_LAYER(view_layer)) {
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
+ }
- if (ob->mode & OB_MODE_POSE)
- ED_armature_exit_posemode(C, base);
- else
- ED_armature_enter_posemode(C, base);
+ if (ob->mode & OB_MODE_POSE) {
+ ED_object_posemode_exit(C, ob);
+ }
+ else {
+ ED_object_posemode_enter(C, ob);
+ }
}
else {
if (ob->mode & OB_MODE_POSE) {
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index c19dcc0e1cb..735e2b5a37a 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -420,7 +420,7 @@ static void object_delete_cb(
// check also library later
if (ob == CTX_data_edit_object(C)) {
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
}
ED_object_base_free_and_unlink(CTX_data_main(C), scene, ob);
/* leave for ED_outliner_id_unref to handle */
@@ -989,7 +989,7 @@ static void object_delete_hierarchy_cb(
/* Check also library later. */
for (; obedit && (obedit != base->object); obedit = obedit->parent);
if (obedit == base->object) {
- ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
}
outline_delete_hierarchy(C, reports, scene, base);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 596bf28f6b7..f63bcb1571d 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1850,6 +1850,8 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
view3d_draw_border(C, ar);
view3d_draw_grease_pencil(C);
+ BLF_batch_draw_begin();
+
if (U.uiflag & USER_SHOW_ROTVIEWICON) {
draw_view_axis(rv3d, &rect);
}
@@ -1866,6 +1868,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
Object *ob = OBACT(view_layer);
draw_selected_name(scene, ob, &rect);
}
+
#if 0 /* TODO */
if (grid_unit) { /* draw below the viewport name */
char numstr[32] = "";
@@ -1880,6 +1883,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
numstr[0] ? numstr : grid_unit, sizeof(numstr));
}
#endif
+ BLF_batch_draw_end();
}
static void view3d_draw_view(const bContext *C, ARegion *ar)
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index a4bce5b0f1d..3aeb38970d2 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1707,20 +1707,10 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
TransInfo *t = (TransInfo *)customdata;
if (t->helpline != HLP_NONE) {
- float vecrot[3], cent[2];
+ float cent[2];
float mval[3] = { x, y, 0.0f };
- copy_v3_v3(vecrot, t->center);
- if (t->flag & T_EDIT) {
- Object *ob = t->obedit;
- if (ob) mul_m4_v3(ob->obmat, vecrot);
- }
- else if (t->flag & T_POSE) {
- Object *ob = t->poseobj;
- if (ob) mul_m4_v3(ob->obmat, vecrot);
- }
-
- projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
gpuPushMatrix();
@@ -2624,7 +2614,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
if (td->con) {
const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
-
+
bConstraintOb cob = {NULL};
bConstraint *con;
float ctime = (float)(t->scene->r.cfra);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 4e409e7f77f..f612dc0e474 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -999,7 +999,7 @@ static void setNearestAxis3d(TransInfo *t)
* of two 2D points 30 pixels apart (that's the last factor in the formula) after
* projecting them with ED_view3d_win_to_delta and then get the length of that vector.
*/
- zfac = mul_project_m4_v3_zfac(t->persmat, t->center);
+ zfac = mul_project_m4_v3_zfac(t->persmat, t->center_global);
zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f;
for (i = 0; i < 3; i++) {
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index b42e00a2bb4..6a813eb2a55 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1916,14 +1916,6 @@ void calculateCenter(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
/* ED_view3d_calc_zfac() defines a factor for perspective depth correction, used in ED_view3d_win_to_delta() */
- float vec[3];
- if (t->flag & (T_EDIT | T_POSE)) {
- Object *ob = t->obedit ? t->obedit : t->poseobj;
- mul_v3_m4v3(vec, ob->obmat, t->center);
- }
- else {
- copy_v3_v3(vec, t->center);
- }
/* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
* and never used in other cases.
@@ -1932,7 +1924,7 @@ void calculateCenter(TransInfo *t)
* for a region different from RGN_TYPE_WINDOW.
*/
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
- t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, vec, NULL);
+ t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, t->center_global, NULL);
}
else {
t->zfac = 0.0f;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index a0da68849f7..b159bade13d 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -52,8 +52,6 @@ BlenderFileLoader::~BlenderFileLoader()
NodeGroup *BlenderFileLoader::Load()
{
- ObjectInstanceRen *obi;
-
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "\n=== Importing triangular meshes into Blender ===" << endl;
}
@@ -81,6 +79,24 @@ NodeGroup *BlenderFileLoader::Load()
_z_offset = 0.f;
}
+ EvaluationContext *eval_ctx = DEG_evaluation_context_new(DAG_EVAL_RENDER);
+ Depsgraph *depsgraph = DEG_graph_new();
+
+ ViewLayer *view_layer = (ViewLayer*)BLI_findstring(&_re->scene->view_layers, _view_layer->name, offsetof(ViewLayer, name));
+
+ DEG_evaluation_context_init_from_view_layer_for_render(
+ eval_ctx,
+ depsgraph,
+ _re->scene,
+ view_layer);
+
+ BKE_scene_graph_update_tagged(
+ eval_ctx,
+ depsgraph,
+ _re->main,
+ _re->scene,
+ view_layer);
+
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Frustum: l " << _viewplane_left << " r " << _viewplane_right
@@ -90,32 +106,39 @@ NodeGroup *BlenderFileLoader::Load()
#endif
int id = 0;
- unsigned cnt = 1;
- unsigned cntStep = (unsigned)ceil(0.01f * _re->totinstance);
- for (obi = (ObjectInstanceRen *)_re->instancetable.first; obi; obi = obi->next) {
- if (_pRenderMonitor) {
- if (_pRenderMonitor->testBreak())
- break;
- if (cnt % cntStep == 0) {
- stringstream ss;
- ss << "Freestyle: Mesh loading " << (100 * cnt / _re->totinstance) << "%";
- _pRenderMonitor->setInfo(ss.str());
- _pRenderMonitor->progress((float)cnt / _re->totinstance);
- }
- cnt++;
- }
-
- char *name = obi->ob->id.name;
- //printf("%c%c:%s\n", name[0], name[1], name+2);
- //print_m4("obi->mat", obi->mat);
- if (obi->obr->totvlak > 0) {
- insertShapeNode(obi, ++id);
- }
- else if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Warning: " << (name + 2) << " is not a vlak-based object (ignored)" << endl;
+ DEG_OBJECT_ITER_BEGIN(
+ depsgraph, ob, DEG_ITER_OBJECT_MODE_RENDER,
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
+ DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI)
+ {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
+ break;
+ }
+
+ bool apply_modifiers = true;
+ bool calc_undeformed = false;
+ bool calc_tessface = false;
+ Mesh *mesh = BKE_mesh_new_from_object(eval_ctx,
+ _re->main,
+ _re->scene,
+ ob,
+ apply_modifiers,
+ eModifierMode_Render,
+ calc_tessface,
+ calc_undeformed);
+
+ if (mesh) {
+ insertShapeNode(ob, mesh, ++id);
+ BKE_libblock_free_ex(_re->main, &mesh->id, true, false);
}
}
+ DEG_OBJECT_ITER_END;
+
+ DEG_graph_free(depsgraph);
+ DEG_evaluation_context_free(eval_ctx);
// Return the built scene.
return _Scene;
@@ -363,82 +386,87 @@ int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3
return 0;
}
-// Checks if edge rotation (if necessary) can prevent the given quad from
-// being decomposed into a degenerate triangle
-bool BlenderFileLoader::testEdgeRotation(float v1[3], float v2[3], float v3[3], float v4[3])
+static bool testEdgeMark(Mesh *me, FreestyleEdge *fed, const MLoopTri *lt, int i)
{
- if (testDegenerateTriangle(v1, v2, v3) == 2 || testDegenerateTriangle(v1, v3, v4) == 2) {
- if (testDegenerateTriangle(v1, v2, v4) == 2 || testDegenerateTriangle(v2, v3, v4) == 2) {
-#if 0
- if (G.debug & G_DEBUG_FREESTYLE) {
- printf("BlenderFileLoader::testEdgeRotation: edge rotation is unsuccessful.\n");
- }
-#endif
- return false;
- }
- return true;
+ MLoop *mloop = &me->mloop[lt->tri[i]];
+ MLoop *mloop_next = &me->mloop[lt->tri[(i+1)%3]];
+ MEdge *medge = &me->medge[mloop->e];
+
+ if (!ELEM(mloop_next->v, medge->v1, medge->v2)) {
+ /* Not an edge in the original mesh before triangulation. */
+ return false;
}
- return false;
+
+ return (fed[mloop->e].flag & FREESTYLE_EDGE_MARK) != 0;
}
-void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
+void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
{
- ObjectRen *obr = obi->obr;
- char *name = obi->ob->id.name + 2;
+ char *name = ob->id.name + 2;
+
+ // Compute loop triangles
+ int tottri = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *mlooptri = (MLoopTri*)MEM_malloc_arrayN(tottri, sizeof(*mlooptri), __func__);
+ BKE_mesh_recalc_looptri(
+ me->mloop, me->mpoly,
+ me->mvert,
+ me->totloop, me->totpoly,
+ mlooptri);
+
+ // Compute loop normals
+ BKE_mesh_calc_normals_split(me);
+ float (*lnors)[3] = NULL;
+
+ if (CustomData_has_layer(&me->ldata, CD_NORMAL)) {
+ lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL);
+ }
- // We parse vlak nodes and count the number of faces after the clipping by
- // the near and far view planes is applied (Note: mesh vertices are in the
- // camera coordinate system).
- VlakRen *vlr = NULL;
+ // Get other mesh data
+ MVert *mvert = me->mvert;
+ MLoop *mloop = me->mloop;
+ MPoly *mpoly = me->mpoly;
+ FreestyleEdge *fed = (FreestyleEdge*)CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE);
+ FreestyleFace *ffa = (FreestyleFace*)CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
+
+ // Compute matrix including camera transform
+ float obmat[4][4], nmat[4][4];
+ mul_m4_m4m4(obmat, _re->viewmat, ob->obmat);
+ invert_m4_m4(nmat, obmat);
+ transpose_m4(nmat);
+
+ // We count the number of triangles after the clipping by the near and far view
+ // planes is applied (Note: mesh vertices are in the camera coordinate system).
unsigned numFaces = 0;
- float v1[3], v2[3], v3[3], v4[3];
- float n1[3], n2[3], n3[3], n4[3], facenormal[3];
- int clip_1[3], clip_2[3];
+ float v1[3], v2[3], v3[3];
+ float n1[3], n2[3], n3[3], facenormal[3];
+ int clip[3];
int wire_material = 0;
- for (int a = 0; a < obr->totvlak; a++) {
- if ((a & 255) == 0)
- vlr = obr->vlaknodes[a>>8].vlak;
- else
- vlr++;
- if (vlr->mat->mode & MA_ONLYCAST)
+ for (int a = 0; a < tottri; a++) {
+ const MLoopTri *lt = &mlooptri[a];
+ const MPoly *mp = &mpoly[lt->poly];
+ Material *mat = give_current_material(ob, mp->mat_nr + 1);
+
+ if (mat && mat->mode & MA_ONLYCAST) {
continue;
- if (vlr->mat->material_type == MA_TYPE_WIRE) {
+ }
+ if (mat && mat->material_type == MA_TYPE_WIRE) {
wire_material = 1;
continue;
}
- copy_v3_v3(v1, vlr->v1->co);
- copy_v3_v3(v2, vlr->v2->co);
- copy_v3_v3(v3, vlr->v3->co);
- if (vlr->v4)
- copy_v3_v3(v4, vlr->v4->co);
- if (obi->flag & R_TRANSFORMED) {
- mul_m4_v3(obi->mat, v1);
- mul_m4_v3(obi->mat, v2);
- mul_m4_v3(obi->mat, v3);
- if (vlr->v4)
- mul_m4_v3(obi->mat, v4);
- }
+
+ copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co);
+ copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co);
+ copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co);
+
+ mul_m4_v3(obmat, v1);
+ mul_m4_v3(obmat, v2);
+ mul_m4_v3(obmat, v3);
+
v1[2] += _z_offset;
v2[2] += _z_offset;
v3[2] += _z_offset;
- if (vlr->v4)
- v4[2] += _z_offset;
-#if 0
- print_v3("v1", v1);
- print_v3("v2", v2);
- print_v3("v3", v3);
- if (vlr->v4)
- print_v3("v4", v4);
-#endif
- if (!vlr->v4 || !testEdgeRotation(v1, v2, v3, v4)) {
- numFaces += countClippedFaces(v1, v2, v3, clip_1);
- if (vlr->v4)
- numFaces += countClippedFaces(v1, v3, v4, clip_2);
- }
- else {
- numFaces += countClippedFaces(v1, v2, v4, clip_1);
- numFaces += countClippedFaces(v2, v3, v4, clip_2);
- }
+
+ numFaces += countClippedFaces(v1, v2, v3, clip);
}
if (wire_material) {
if (G.debug & G_DEBUG_FREESTYLE) {
@@ -450,8 +478,10 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
cout << "numFaces " << numFaces << endl;
}
#endif
- if (numFaces == 0)
+ if (numFaces == 0) {
+ MEM_freeN(mlooptri);
return;
+ }
// We allocate memory for the meshes to be imported
NodeGroup *currentMesh = new NodeGroup;
@@ -494,99 +524,60 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
// We parse the vlak nodes again and import meshes while applying the clipping
// by the near and far view planes.
- int p;
- for (p = 0; p < obr->totvlak; ++p) { // we parse the faces of the mesh
- if ((p & 255) == 0)
- vlr = obr->vlaknodes[p>>8].vlak;
- else
- vlr++;
- if ((vlr->mat->mode & MA_ONLYCAST) || vlr->mat->material_type == MA_TYPE_WIRE)
+ for (int a = 0; a < tottri; a++) {
+ const MLoopTri *lt = &mlooptri[a];
+ const MPoly *mp = &mpoly[lt->poly];
+ Material *mat = give_current_material(ob, mp->mat_nr + 1);
+
+ if (mat && ((mat->mode & MA_ONLYCAST) || mat->material_type == MA_TYPE_WIRE))
continue;
- copy_v3_v3(v1, vlr->v1->co);
- copy_v3_v3(v2, vlr->v2->co);
- copy_v3_v3(v3, vlr->v3->co);
- if (vlr->v4)
- copy_v3_v3(v4, vlr->v4->co);
- if (obi->flag & R_TRANSFORMED) {
- mul_m4_v3(obi->mat, v1);
- mul_m4_v3(obi->mat, v2);
- mul_m4_v3(obi->mat, v3);
- if (vlr->v4)
- mul_m4_v3(obi->mat, v4);
- }
+
+ copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co);
+ copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co);
+ copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co);
+
+ mul_m4_v3(obmat, v1);
+ mul_m4_v3(obmat, v2);
+ mul_m4_v3(obmat, v3);
+
v1[2] += _z_offset;
v2[2] += _z_offset;
v3[2] += _z_offset;
- if (vlr->v4)
- v4[2] += _z_offset;
- if (_smooth && (vlr->flag & R_SMOOTH)) {
- copy_v3_v3(n1, vlr->v1->n);
- copy_v3_v3(n2, vlr->v2->n);
- copy_v3_v3(n3, vlr->v3->n);
- if (vlr->v4)
- copy_v3_v3(n4, vlr->v4->n);
- if (obi->flag & R_TRANSFORMED) {
- mul_m3_v3(obi->nmat, n1);
- mul_m3_v3(obi->nmat, n2);
- mul_m3_v3(obi->nmat, n3);
- normalize_v3(n1);
- normalize_v3(n2);
- normalize_v3(n3);
- if (vlr->v4) {
- mul_m3_v3(obi->nmat, n4);
- normalize_v3(n4);
- }
- }
+
+ if (_smooth && (mp->flag & ME_SMOOTH) && lnors) {
+ copy_v3_v3(n1, lnors[lt->tri[0]]);
+ copy_v3_v3(n2, lnors[lt->tri[1]]);
+ copy_v3_v3(n3, lnors[lt->tri[2]]);
+
+ mul_mat3_m4_v3(nmat, n1);
+ mul_mat3_m4_v3(nmat, n2);
+ mul_mat3_m4_v3(nmat, n3);
+
+ normalize_v3(n1);
+ normalize_v3(n2);
+ normalize_v3(n3);
}
else {
- RE_vlakren_get_normal(_re, obi, vlr, facenormal);
-#ifndef NDEBUG
- /* test if normals are inverted in rendering [T39669] */
- float tnor[3];
- if (vlr->v4)
- normal_quad_v3(tnor, v4, v3, v2, v1);
- else
- normal_tri_v3(tnor, v3, v2, v1);
- BLI_assert(dot_v3v3(tnor, facenormal) > 0.0f);
-#endif
+ normal_tri_v3(facenormal, v3, v2, v1);
+
copy_v3_v3(n1, facenormal);
copy_v3_v3(n2, facenormal);
copy_v3_v3(n3, facenormal);
- if (vlr->v4)
- copy_v3_v3(n4, facenormal);
}
- unsigned int numTris_1, numTris_2;
- bool edge_rotation;
- if (!vlr->v4 || !testEdgeRotation(v1, v2, v3, v4)) {
- numTris_1 = countClippedFaces(v1, v2, v3, clip_1);
- numTris_2 = (!vlr->v4) ? 0 : countClippedFaces(v1, v3, v4, clip_2);
- edge_rotation = false;
- }
- else {
- numTris_1 = countClippedFaces(v1, v2, v4, clip_1);
- numTris_2 = countClippedFaces(v2, v3, v4, clip_2);
- edge_rotation = true;
- if (G.debug & G_DEBUG_FREESTYLE) {
- printf("BlenderFileLoader::insertShapeNode: edge rotation is performed.\n");
- }
- }
- if (numTris_1 == 0 && numTris_2 == 0)
+ unsigned int numTris = countClippedFaces(v1, v2, v3, clip);
+ if (numTris == 0)
continue;
- bool fm, em1, em2, em3, em4;
- fm = (vlr->freestyle_face_mark) != 0;
- em1 = (vlr->freestyle_edge_mark & R_EDGE_V1V2) != 0;
- em2 = (vlr->freestyle_edge_mark & R_EDGE_V2V3) != 0;
- if (!vlr->v4) {
- em3 = (vlr->freestyle_edge_mark & R_EDGE_V3V1) != 0;
- em4 = false;
- }
- else {
- em3 = (vlr->freestyle_edge_mark & R_EDGE_V3V4) != 0;
- em4 = (vlr->freestyle_edge_mark & R_EDGE_V4V1) != 0;
+
+ bool fm = (ffa) ? (ffa[lt->poly].flag & FREESTYLE_FACE_MARK) != 0 : false;
+ bool em1 = false, em2 = false, em3 = false;
+
+ if (fed) {
+ em1 = testEdgeMark(me, fed, lt, 0);
+ em2 = testEdgeMark(me, fed, lt, 1);
+ em3 = testEdgeMark(me, fed, lt, 2);
}
- Material *mat = vlr->mat;
if (mat) {
tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]);
tmpMat.setDiffuse(mat->r, mat->g, mat->b, mat->alpha);
@@ -629,43 +620,19 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
float triCoords[5][3], triNormals[5][3];
bool edgeMarks[5]; // edgeMarks[i] is for the edge between i-th and (i+1)-th vertices
- if (numTris_1 > 0) {
- if (!edge_rotation) {
- clipTriangle(numTris_1, triCoords, v1, v2, v3, triNormals, n1, n2, n3,
- edgeMarks, em1, em2, (!vlr->v4) ? em3 : false, clip_1);
- }
- else {
- clipTriangle(numTris_1, triCoords, v1, v2, v4, triNormals, n1, n2, n4,
- edgeMarks, em1, false, em4, clip_1);
- }
- for (i = 0; i < numTris_1; i++) {
- addTriangle(&ls, triCoords[0], triCoords[i + 1], triCoords[i + 2],
- triNormals[0], triNormals[i + 1], triNormals[i + 2],
- fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1],
- (i == numTris_1 - 1) ? edgeMarks[i + 2] : false);
- _numFacesRead++;
- }
- }
-
- if (numTris_2 > 0) {
- if (!edge_rotation) {
- clipTriangle(numTris_2, triCoords, v1, v3, v4, triNormals, n1, n3, n4,
- edgeMarks, false, em3, em4, clip_2);
- }
- else {
- clipTriangle(numTris_2, triCoords, v2, v3, v4, triNormals, n2, n3, n4,
- edgeMarks, em2, em3, false, clip_2);
- }
- for (i = 0; i < numTris_2; i++) {
- addTriangle(&ls, triCoords[0], triCoords[i + 1], triCoords[i + 2],
- triNormals[0], triNormals[i + 1], triNormals[i + 2],
- fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1],
- (i == numTris_2 - 1) ? edgeMarks[i + 2] : false);
- _numFacesRead++;
- }
+ clipTriangle(numTris, triCoords, v1, v2, v3, triNormals, n1, n2, n3,
+ edgeMarks, em1, em2, em3, clip);
+ for (i = 0; i < numTris; i++) {
+ addTriangle(&ls, triCoords[0], triCoords[i + 1], triCoords[i + 2],
+ triNormals[0], triNormals[i + 1], triNormals[i + 2],
+ fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1],
+ (i == numTris - 1) ? edgeMarks[i + 2] : false);
+ _numFacesRead++;
}
}
+ MEM_freeN(mlooptri);
+
// We might have several times the same vertex. We want a clean
// shape with no real-vertex. Here, we are making a cleaning pass.
float *cleanVertices = NULL;
@@ -804,8 +771,8 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
cleanNIndices, niSize, MIndices, viSize, 0, 0, 0);
// sets the id of the rep
rep->setId(Id(id, 0));
- rep->setName(obi->ob->id.name + 2);
- rep->setLibraryPath(obi->ob->id.lib ? obi->ob->id.lib->name : NULL);
+ rep->setName(ob->id.name + 2);
+ rep->setLibraryPath(ob->id.lib ? ob->id.lib->name : NULL);
const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]),
Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2]));
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
index ad92416801d..f9a8c787c08 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
@@ -40,19 +40,30 @@
#include "../system/RenderMonitor.h"
extern "C" {
+#include "MEM_guardedalloc.h"
+
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "renderdatabase.h"
#include "render_types.h"
+#include "BKE_customdata.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_scene.h"
+#include "BLI_iterator.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
}
+#include "DEG_depsgraph_query.h"
+
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
@@ -96,9 +107,8 @@ public:
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
protected:
- void insertShapeNode(ObjectInstanceRen *obi, int id);
+ void insertShapeNode(Object *ob, Mesh *mesh, int id);
int testDegenerateTriangle(float v1[3], float v2[3], float v3[3]);
- bool testEdgeRotation(float v1[3], float v2[3], float v3[3], float v4[3]);
int countClippedFaces(float v1[3], float v2[3], float v3[3], int clip[3]);
void clipLine(float v1[3], float v2[3], float c[3], float z);
void clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3],
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 7cd403d2721..b245c9a161f 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -2270,7 +2270,9 @@ void GPU_pass_release(GPUPass *pass)
static void gpu_pass_free(GPUPass *pass)
{
BLI_assert(pass->refcount == 0);
- GPU_shader_free(pass->shader);
+ if (pass->shader) {
+ GPU_shader_free(pass->shader);
+ }
MEM_SAFE_FREE(pass->fragmentcode);
MEM_SAFE_FREE(pass->geometrycode);
MEM_SAFE_FREE(pass->vertexcode);
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index b8c3e164055..d9e8351c094 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -44,6 +44,8 @@
#include "BLI_utildefines.h"
+#include "PIL_time.h"
+
#include "gpu_select_private.h"
@@ -96,7 +98,7 @@ void gpu_select_query_begin(
g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids");
glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
- gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT);
+ gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT | GPU_SCISSOR_BIT);
/* disable writing to the framebuffer */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -114,6 +116,7 @@ void gpu_select_query_begin(
glDepthMask(GL_FALSE);
}
else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
+ glDisable(GL_SCISSOR_TEST); /* allows fast clear */
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
@@ -172,8 +175,21 @@ uint gpu_select_query_end(void)
glEndQuery(GL_SAMPLES_PASSED);
}
+ /* We need to sync to get the results anyway.
+ * If we don't do that the driver will do. */
+ glFinish();
+
for (i = 0; i < g_query_state.active_query; i++) {
- uint result;
+ uint result = 0;
+ /* Wait until the result is available. This can happen even if glFinish() was called. */
+ while (result == 0) {
+ glGetQueryObjectuiv(g_query_state.queries[i], GL_QUERY_RESULT_AVAILABLE, &result);
+ if (result == 0) {
+ /* (fclem) Not sure if this is better than calling
+ * glGetQueryObjectuiv() indefinitely. */
+ PIL_sleep_ms(1);
+ }
+ }
glGetQueryObjectuiv(g_query_state.queries[i], GL_QUERY_RESULT, &result);
if (result > 0) {
if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) {
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index db5c2d1bcb5..e0b11edb197 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -828,27 +828,27 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
switch (shader) {
case GPU_SHADER_2D_WIDGET_BASE_INST:
case GPU_SHADER_2D_NODELINK_INST:
- defines = "#define USE_INSTANCE;\n";
+ defines = "#define USE_INSTANCE\n";
break;
case GPU_SHADER_SMOKE_COBA:
- defines = "#define USE_COBA;\n";
+ defines = "#define USE_COBA\n";
break;
case GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE:
- defines = "#define UNIFORM_SCALE;\n";
+ defines = "#define UNIFORM_SCALE\n";
break;
case GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS:
- defines = "#define AXIS_NAME;\n";
+ defines = "#define AXIS_NAME\n";
break;
case GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR:
case GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID:
- defines = "#define USE_INSTANCE_COLOR;\n";
+ defines = "#define USE_INSTANCE_COLOR\n";
break;
case GPU_SHADER_3D_FLAT_COLOR_U32:
case GPU_SHADER_3D_UNIFORM_COLOR_U32:
- defines = "#define USE_COLOR_U32;\n";
+ defines = "#define USE_COLOR_U32\n";
break;
case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR:
- defines = "#define USE_FLAT_NORMAL;\n";
+ defines = "#define USE_FLAT_NORMAL\n";
break;
default:
break;
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index e635174eca2..5d89bd59277 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -521,35 +521,23 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
BLI_assert(w == BLI_rcti_size_x(rect) + 1);
BLI_assert(h == BLI_rcti_size_y(rect) + 1);
- Gwn_VertFormat *format = immVertexFormat();
- unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ float x1 = rect->xmin;
+ float x2 = rect->xmin + w;
+ float y1 = rect->ymin;
+ float y2 = rect->ymin + h;
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
- GPU_texture_bind(color, 0);
-
- immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
- immUniform1f("alpha", 1.0f);
-
- immBegin(GWN_PRIM_TRI_STRIP, 4);
-
- immAttrib2f(texcoord, 0.0f, 0.0f);
- immVertex2f(pos, rect->xmin, rect->ymin);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
+ GPU_shader_bind(shader);
- immAttrib2f(texcoord, 1.0f, 0.0f);
- immVertex2f(pos, rect->xmin + w, rect->ymin);
-
- immAttrib2f(texcoord, 0.0f, 1.0f);
- immVertex2f(pos, rect->xmin, rect->ymin + h);
-
- immAttrib2f(texcoord, 1.0f, 1.0f);
- immVertex2f(pos, rect->xmin + w, rect->ymin + h);
+ GPU_texture_bind(color, 0);
+ glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), 0.0f, 0.0f, 1.0f, 1.0f);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x1, y1, x2, y2);
+ glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f);
- immEnd();
+ GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4);
GPU_texture_unbind(color);
-
- immUnbindProgram();
}
void GPU_viewport_unbind(GPUViewport *UNUSED(viewport))
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
index 929674ab446..f660cae8d12 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
@@ -25,7 +25,8 @@ void main()
fragColor = finalColor;
if (butCo > 0.5) {
- fragColor = mix(do_checkerboard(), fragColor, fragColor.a);
+ vec4 checker = do_checkerboard();
+ fragColor = mix(checker, fragColor, fragColor.a);
}
if (butCo > 0.0) {
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
index 9f28d9bb3a3..0c351a3bce4 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
@@ -1,4 +1,4 @@
-#define BIT_RANGE(x) ((1u << x) - 1u)
+#define BIT_RANGE(x) uint((1 << x) - 1)
/* 2 bits for corner */
/* Attention! Not the same order as in UI_interface.h!
@@ -7,11 +7,11 @@
#define BOTTOM_RIGHT 1u
#define TOP_RIGHT 2u
#define TOP_LEFT 3u
-#define CNR_FLAG_RANGE BIT_RANGE(2u)
+#define CNR_FLAG_RANGE BIT_RANGE(2)
/* 4bits for corner id */
#define CORNER_VEC_OFS 2u
-#define CORNER_VEC_RANGE BIT_RANGE(4u)
+#define CORNER_VEC_RANGE BIT_RANGE(4)
const vec2 cornervec[36] = vec2[36](
vec2(0.0, 1.0), vec2(0.02, 0.805), vec2(0.067, 0.617), vec2(0.169, 0.45), vec2(0.293, 0.293), vec2(0.45, 0.169), vec2(0.617, 0.076), vec2(0.805, 0.02), vec2(1.0, 0.0),
vec2(-1.0, 0.0), vec2(-0.805, 0.02), vec2(-0.617, 0.067), vec2(-0.45, 0.169), vec2(-0.293, 0.293), vec2(-0.169, 0.45), vec2(-0.076, 0.617), vec2(-0.02, 0.805), vec2(0.0, 1.0),
@@ -21,7 +21,7 @@ const vec2 cornervec[36] = vec2[36](
/* 4bits for jitter id */
#define JIT_OFS 6u
-#define JIT_RANGE BIT_RANGE(4u)
+#define JIT_RANGE BIT_RANGE(4)
const vec2 jit[9] = vec2[9](
vec2( 0.468813, -0.481430), vec2(-0.155755, -0.352820),
vec2( 0.219306, -0.238501), vec2(-0.393286, -0.110949),
@@ -31,22 +31,22 @@ const vec2 jit[9] = vec2[9](
);
/* 2bits for other flags */
-#define INNER_FLAG (1u << 10u) /* is inner vert */
-#define EMBOSS_FLAG (1u << 11u) /* is emboss vert */
+#define INNER_FLAG uint(1 << 10) /* is inner vert */
+#define EMBOSS_FLAG uint(1 << 11) /* is emboss vert */
/* 2bits for color */
#define COLOR_OFS 12u
-#define COLOR_RANGE BIT_RANGE(2u)
+#define COLOR_RANGE BIT_RANGE(2)
#define COLOR_INNER 0u
#define COLOR_EDGE 1u
#define COLOR_EMBOSS 2u
/* 2bits for trias type */
-#define TRIA_FLAG (1u << 14u) /* is tria vert */
+#define TRIA_FLAG uint(1 << 14) /* is tria vert */
#define TRIA_FIRST INNER_FLAG /* is first tria (reuse INNER_FLAG) */
/* We can reuse the CORNER_* bits for tria */
-#define TRIA_VEC_RANGE BIT_RANGE(6u)
+#define TRIA_VEC_RANGE BIT_RANGE(6)
const vec2 triavec[34] = vec2[34](
/* horizontal tria */
vec2(-0.352077, 0.532607), vec2(-0.352077, -0.549313), vec2( 0.330000, -0.008353),
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl
index 441f97e95f0..2f5353a7c86 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl
@@ -1,4 +1,4 @@
-#define BIT_RANGE(x) ((1u << x) - 1u)
+#define BIT_RANGE(x) uint((1 << x) - 1)
/* 2 bits for corner */
/* Attention! Not the same order as in UI_interface.h!
@@ -7,11 +7,11 @@
#define BOTTOM_RIGHT 1u
#define TOP_RIGHT 2u
#define TOP_LEFT 3u
-#define CNR_FLAG_RANGE BIT_RANGE(2u)
+#define CNR_FLAG_RANGE BIT_RANGE(2)
/* 4bits for corner id */
#define CORNER_VEC_OFS 2u
-#define CORNER_VEC_RANGE BIT_RANGE(4u)
+#define CORNER_VEC_RANGE BIT_RANGE(4)
const vec2 cornervec[36] = vec2[36](
vec2(0.0, 1.0), vec2(0.02, 0.805), vec2(0.067, 0.617), vec2(0.169, 0.45), vec2(0.293, 0.293), vec2(0.45, 0.169), vec2(0.617, 0.076), vec2(0.805, 0.02), vec2(1.0, 0.0),
vec2(-1.0, 0.0), vec2(-0.805, 0.02), vec2(-0.617, 0.067), vec2(-0.45, 0.169), vec2(-0.293, 0.293), vec2(-0.169, 0.45), vec2(-0.076, 0.617), vec2(-0.02, 0.805), vec2(0.0, 1.0),
@@ -19,7 +19,7 @@ const vec2 cornervec[36] = vec2[36](
vec2(1.0, 0.0), vec2(0.805, -0.02), vec2(0.617, -0.067), vec2(0.45, -0.169), vec2(0.293, -0.293), vec2(0.169, -0.45), vec2(0.076, -0.617), vec2(0.02, -0.805), vec2(0.0, -1.0)
);
-#define INNER_FLAG (1u << 10u) /* is inner vert */
+#define INNER_FLAG uint(1 << 10) /* is inner vert */
uniform mat4 ModelViewProjectionMatrix;
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index fd8cd8b2855..778aaec7d19 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -472,6 +472,7 @@ enum {
ID_RECALC_GEOMETRY = 1 << 4,
ID_RECALC_TRANSFORM = 1 << 5,
ID_RECALC_COLLECTIONS = 1 << 6,
+ ID_RECALC_COPY_ON_WRITE = 1 << 7,
/* Special flag to check if SOMETHING was changed. */
ID_RECALC_ALL = (~(int)0),
};
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 806c1ca76fc..2ee0eff7a9c 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -97,6 +97,7 @@ typedef struct ViewLayer {
/* Runtime data */
ListBase drawdata; /* ViewLayerEngineData */
+ struct Base **object_bases_array;
} ViewLayer;
typedef struct SceneCollection {
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 3575ad976a5..696918d97a5 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -95,17 +95,28 @@ typedef struct AviCodecData {
typedef enum eFFMpegPreset {
FFM_PRESET_NONE,
- FFM_PRESET_ULTRAFAST,
- FFM_PRESET_SUPERFAST,
- FFM_PRESET_VERYFAST,
- FFM_PRESET_FASTER,
- FFM_PRESET_FAST,
- FFM_PRESET_MEDIUM,
- FFM_PRESET_SLOW,
- FFM_PRESET_SLOWER,
- FFM_PRESET_VERYSLOW,
-} eFFMpegPreset;
+#ifdef DNA_DEPRECATED
+ /* Previously used by h.264 to control encoding speed vs. file size. */
+ FFM_PRESET_ULTRAFAST, /* DEPRECATED */
+ FFM_PRESET_SUPERFAST, /* DEPRECATED */
+ FFM_PRESET_VERYFAST, /* DEPRECATED */
+ FFM_PRESET_FASTER, /* DEPRECATED */
+ FFM_PRESET_FAST, /* DEPRECATED */
+ FFM_PRESET_MEDIUM, /* DEPRECATED */
+ FFM_PRESET_SLOW, /* DEPRECATED */
+ FFM_PRESET_SLOWER, /* DEPRECATED */
+ FFM_PRESET_VERYSLOW, /* DEPRECATED */
+#endif
+
+ /* Used by WEBM/VP9 and h.264 to control encoding speed vs. file size.
+ * WEBM/VP9 use these values directly, whereas h.264 map those to
+ * respectively the MEDIUM, SLOWER, and SUPERFAST presets.
+ */
+ FFM_PRESET_GOOD = 10, /* the default and recommended for most applications */
+ FFM_PRESET_BEST, /* recommended if you have lots of time and want the best compression efficiency */
+ FFM_PRESET_REALTIME, /* recommended for live / fast encoding */
+} eFFMpegPreset;
/* Mapping from easily-understandable descriptions to CRF values.
* Assumes we output 8-bit video. Needs to be remapped if 10-bit
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index bb8ee89c5ab..4a267313ac9 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1864,7 +1864,7 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char *
else {
flag = prop->flag;
if ((flag & PROP_EDITABLE) == 0 || (flag & PROP_REGISTER)) {
- *r_info = "This property is for internal use only and can't be edited.";
+ *r_info = N_("This property is for internal use only and can't be edited");
}
}
@@ -1872,13 +1872,13 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char *
if (id) {
if (ID_IS_LINKED(id) && (prop->flag & PROP_LIB_EXCEPTION) == 0) {
if (!(*r_info)[0]) {
- *r_info = "Can't edit this property from a linked data-block.";
+ *r_info = N_("Can't edit this property from a linked data-block.");
}
return false;
}
if (id->override_static != NULL && !RNA_property_overridable(ptr, prop)) {
if (!(*r_info)[0]) {
- *r_info = "Can't edit this property from an override data-block.";
+ *r_info = N_("Can't edit this property from an override data-block.");
}
return false;
}
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index ae325651a31..d252c04742f 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -1292,49 +1292,49 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Z Angle Stiffness", "Stiffness on the Z rotational axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
- prop = RNA_def_property(srna, "spring_damping_x", PROP_FLOAT, PROP_FACTOR);
+ prop = RNA_def_property(srna, "spring_damping_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_x");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_x_set", NULL);
RNA_def_property_ui_text(prop, "Damping X", "Damping on the X axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
- prop = RNA_def_property(srna, "spring_damping_y", PROP_FLOAT, PROP_FACTOR);
+ prop = RNA_def_property(srna, "spring_damping_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_y");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_y_set", NULL);
RNA_def_property_ui_text(prop, "Damping Y", "Damping on the Y axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
- prop = RNA_def_property(srna, "spring_damping_z", PROP_FLOAT, PROP_FACTOR);
+ prop = RNA_def_property(srna, "spring_damping_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_z");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_z_set", NULL);
RNA_def_property_ui_text(prop, "Damping Z", "Damping on the Z axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
- prop = RNA_def_property(srna, "spring_damping_ang_x", PROP_FLOAT, PROP_FACTOR);
+ prop = RNA_def_property(srna, "spring_damping_ang_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_x");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_x_set", NULL);
RNA_def_property_ui_text(prop, "Damping X Angle", "Damping on the X rotational axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
- prop = RNA_def_property(srna, "spring_damping_ang_y", PROP_FLOAT, PROP_FACTOR);
+ prop = RNA_def_property(srna, "spring_damping_ang_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_y");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_y_set", NULL);
RNA_def_property_ui_text(prop, "Damping Y Angle", "Damping on the Y rotational axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
- prop = RNA_def_property(srna, "spring_damping_ang_z", PROP_FLOAT, PROP_FACTOR);
+ prop = RNA_def_property(srna, "spring_damping_ang_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_z");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_z_set", NULL);
RNA_def_property_ui_text(prop, "Damping Z Angle", "Damping on the Z rotational axis");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 2594eb654e8..568980d6976 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -5221,8 +5221,6 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
{FFMPEG_AVI, "AVI", 0, "AVI", ""},
{FFMPEG_MOV, "QUICKTIME", 0, "Quicktime", ""},
{FFMPEG_DV, "DV", 0, "DV", ""},
-// {FFMPEG_H264, "H264", 0, "H.264", ""}, not a container
-// {FFMPEG_XVID, "XVID", 0, "Xvid", ""}, not a container
{FFMPEG_OGG, "OGG", 0, "Ogg", ""},
{FFMPEG_MKV, "MKV", 0, "Matroska", ""},
{FFMPEG_FLV, "FLASH", 0, "Flash", ""},
@@ -5231,31 +5229,30 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
static const EnumPropertyItem ffmpeg_codec_items[] = {
{AV_CODEC_ID_NONE, "NONE", 0, "No Video", "Disables video output, for audio-only renders"},
- {AV_CODEC_ID_MPEG1VIDEO, "MPEG1", 0, "MPEG-1", ""},
- {AV_CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""},
- {AV_CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4(divx)", ""},
- {AV_CODEC_ID_HUFFYUV, "HUFFYUV", 0, "HuffYUV", ""},
+ {AV_CODEC_ID_DNXHD, "DNXHD", 0, "DNxHD", ""},
{AV_CODEC_ID_DVVIDEO, "DV", 0, "DV", ""},
- {AV_CODEC_ID_H264, "H264", 0, "H.264", ""},
- {AV_CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
- {AV_CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""},
{AV_CODEC_ID_FFV1, "FFV1", 0, "FFmpeg video codec #1", ""},
- {AV_CODEC_ID_QTRLE, "QTRLE", 0, "QT rle / QT Animation", ""},
- {AV_CODEC_ID_DNXHD, "DNXHD", 0, "DNxHD", ""},
+ {AV_CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""},
+ {AV_CODEC_ID_H264, "H264", 0, "H.264", ""},
+ {AV_CODEC_ID_HUFFYUV, "HUFFYUV", 0, "HuffYUV", ""},
+ {AV_CODEC_ID_MPEG1VIDEO, "MPEG1", 0, "MPEG-1", ""},
+ {AV_CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""},
+ {AV_CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4 (divx)", ""},
{AV_CODEC_ID_PNG, "PNG", 0, "PNG", ""},
+ {AV_CODEC_ID_QTRLE, "QTRLE", 0, "QT rle / QT Animation", ""},
+ {AV_CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
+ {AV_CODEC_ID_VP9, "WEBM", 0, "WEBM / VP9", ""},
{0, NULL, 0, NULL, NULL}
};
+ /* Recommendations come from the FFmpeg wiki, https://trac.ffmpeg.org/wiki/Encode/VP9.
+ * The label for BEST has been changed to "Slowest" so that it fits the "Encoding Speed"
+ * property label in the UI. */
static const EnumPropertyItem ffmpeg_preset_items[] = {
- {FFM_PRESET_ULTRAFAST, "ULTRAFAST", 0, "Ultra fast; biggest file", ""},
- {FFM_PRESET_SUPERFAST, "SUPERFAST", 0, "Super fast", ""},
- {FFM_PRESET_VERYFAST, "VERYFAST", 0, "Very fast", ""},
- {FFM_PRESET_FASTER, "FASTER", 0, "Faster", ""},
- {FFM_PRESET_FAST, "FAST", 0, "Fast", ""},
- {FFM_PRESET_MEDIUM, "MEDIUM", 0, "Medium speed", ""},
- {FFM_PRESET_SLOW, "SLOW", 0, "Slow", ""},
- {FFM_PRESET_SLOWER, "SLOWER", 0, "Slower", ""},
- {FFM_PRESET_VERYSLOW, "VERYSLOW", 0, "Very slow; smallest file", ""},
+ {FFM_PRESET_BEST, "BEST", 0, "Slowest",
+ "Recommended if you have lots of time and want the best compression efficiency"},
+ {FFM_PRESET_GOOD, "GOOD", 0, "Good", "The default and recommended for most applications"},
+ {FFM_PRESET_REALTIME, "REALTIME", 0, "Realtime", "Recommended for fast encoding"},
{0, NULL, 0, NULL, NULL}
};
@@ -5274,13 +5271,13 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
static const EnumPropertyItem ffmpeg_audio_codec_items[] = {
{AV_CODEC_ID_NONE, "NONE", 0, "No Audio", "Disables audio output, for video-only renders"},
- {AV_CODEC_ID_MP2, "MP2", 0, "MP2", ""},
- {AV_CODEC_ID_MP3, "MP3", 0, "MP3", ""},
- {AV_CODEC_ID_AC3, "AC3", 0, "AC3", ""},
{AV_CODEC_ID_AAC, "AAC", 0, "AAC", ""},
- {AV_CODEC_ID_VORBIS, "VORBIS", 0, "Vorbis", ""},
+ {AV_CODEC_ID_AC3, "AC3", 0, "AC3", ""},
{AV_CODEC_ID_FLAC, "FLAC", 0, "FLAC", ""},
+ {AV_CODEC_ID_MP2, "MP2", 0, "MP2", ""},
+ {AV_CODEC_ID_MP3, "MP3", 0, "MP3", ""},
{AV_CODEC_ID_PCM_S16LE, "PCM", 0, "PCM", ""},
+ {AV_CODEC_ID_VORBIS, "VORBIS", 0, "Vorbis", ""},
{0, NULL, 0, NULL, NULL}
};
#endif
@@ -5391,7 +5388,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "ffmpeg_preset");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, ffmpeg_preset_items);
- RNA_def_property_enum_default(prop, FFM_PRESET_MEDIUM);
+ RNA_def_property_enum_default(prop, FFM_PRESET_GOOD);
RNA_def_property_ui_text(prop, "Encoding speed",
"Tradeoff between encoding speed and compression ratio");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
index 3c165cfcb8a..74e23aed7de 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
@@ -202,7 +202,7 @@ void register_node_type_sh_vect_transform(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_CONVERTOR, 0);
+ sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_OP_VECTOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_init(&ntype, node_shader_init_vect_transform);
node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out);
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 93ac53cdfcc..08c2fd4fa7a 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -271,6 +271,9 @@ void RE_GetViewPlane(struct Render *re, rctf *r_viewplane, rcti *r_disprect);
void RE_Database_FromScene(
struct Render *re, struct Main *bmain, struct Scene *scene,
unsigned int lay, int use_camera_view);
+void RE_Database_CameraOnly(
+ struct Render *re, struct Main *bmain, struct Scene *scene,
+ unsigned int lay, int use_camera_view);
void RE_Database_Preprocess(struct EvaluationContext *eavl_ctx, struct Render *re);
void RE_Database_Free(struct Render *re);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 419316d6217..003c69ccbd4 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -5178,6 +5178,33 @@ static void database_init_objects(const EvaluationContext *eval_ctx, Render *re,
RE_makeRenderInstances(re);
}
+void RE_Database_CameraOnly(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view)
+{
+ Object *camera;
+ float mat[4][4];
+
+ re->main= bmain;
+ re->scene= scene;
+ re->lay= lay;
+
+ /* scene needs to be set to get camera */
+ camera= RE_GetCamera(re);
+
+ /* if no camera, viewmat should have been set! */
+ if (use_camera_view && camera) {
+ /* called before but need to call again in case of lens animation from the
+ * above call to BKE_scene_graph_update_for_newframe, fixes bug. [#22702].
+ * following calls don't depend on 'RE_SetCamera' */
+ RE_SetCamera(re, camera);
+ RE_GetCameraModelMatrix(re, camera, mat);
+ invert_m4(mat);
+ RE_SetView(re, mat);
+
+ /* force correct matrix for scaled cameras */
+ DEG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB);
+ }
+}
+
/* used to be 'rotate scene' */
void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view)
{
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index d6e45788942..9ad9c653e54 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -3327,10 +3327,8 @@ void RE_RenderFreestyleExternal(Render *re)
for (rv = re->result->views.first; rv; rv = rv->next) {
RE_SetActiveRenderView(re, rv->name);
- RE_Database_FromScene(re, re->main, re->scene, re->lay, 1);
- RE_Database_Preprocess(NULL, re);
+ RE_Database_CameraOnly(re, re->main, re->scene, re->lay, 1);
add_freestyle(re, 1);
- RE_Database_Free(re);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index c6e007d9091..ea83ac0de4e 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -481,35 +481,24 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
const float halfx = GLA_PIXEL_OFS / sizex;
const float halfy = GLA_PIXEL_OFS / sizey;
- Gwn_VertFormat *format = immVertexFormat();
- unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
const int activeTex = 7; /* arbitrary */
glActiveTexture(GL_TEXTURE0 + activeTex);
glBindTexture(GL_TEXTURE_2D, triple->bind);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
-
- immUniform1f("alpha", alpha);
- immUniform1i("image", activeTex);
-
- immBegin(GWN_PRIM_TRI_FAN, 4);
-
- immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, 0.0f, 0.0f);
-
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, sizex, 0.0f);
+ float x1 = halfx;
+ float x2 = ratiox + halfx;
+ float y1 = halfy;
+ float y2 = ratioy + halfy;
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, sizex, sizey);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
+ GPU_shader_bind(shader);
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, 0.0f, sizey);
+ glUniform1i(GPU_shader_get_uniform(shader, "image"), activeTex);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), 0.0f, 0.0f, sizex, sizey);
+ glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
- immEnd();
- immUnbindProgram();
+ GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4);
glBindTexture(GL_TEXTURE_2D, 0);
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 2a84656ab3f..35a95c39545 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -653,6 +653,11 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
if (ghostwin) {
GHOST_RectangleHandle bounds;
+ /* XXX Fix crash when a new window is created.
+ * However this should be move somewhere else. (fclem) */
+ BLF_batch_reset();
+ gpu_batch_presets_reset();
+
win->gwnctx = GWN_context_create();
/* the new window has already been made drawable upon creation */
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 78edafa04b6..ba415d0479a 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -681,8 +681,7 @@ void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int of
void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4]) RET_NONE
void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned char col[3]) RET_NONE
void UI_GetThemeColorShadeAlpha4ubv(int colorid, int coloffset, int alphaoffset, unsigned char col[4]) RET_NONE
-void UI_widget_batch_preset_reset(void) RET_NONE
-void UI_widget_batch_preset_exit(void) RET_NONE
+void UI_widgetbase_draw_cache_flush(void) RET_NONE
/* rna template */
void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *proptypename, const char *text) RET_NONE