diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2018-04-12 15:42:55 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2018-04-12 15:42:55 +0300 |
commit | 3df270b1cf0c55750fd3752ac38a3d96947b7a43 (patch) | |
tree | b37adbb7d5d506fd5b15495de736c07742e02688 | |
parent | 4d250c4469759c3f9776f4744b11f664a9bc10b1 (diff) | |
parent | 31067c975759255c013a2b4d872082155d41479e (diff) |
Merge branch 'blender2.8' into topbar
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(°_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 |