[Bf-blender-cvs] [04accc6fd95] temp-angavrilov: Shape Key editing: propagate updates through basis chains.
Commit: 04accc6fd95d8a40d6522676670283765246eb65 Author: Alexander Gavrilov Date: Sun Feb 5 17:20:41 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB04accc6fd95d8a40d6522676670283765246eb65 Shape Key editing: propagate updates through basis chains. It is possible to organize shape keys into a tree through the reference key setting. Mesh editing and sculpting a reference key is supposed to update all its children, but this was only done for one level of dependencies. === M source/blender/blenkernel/BKE_key.h M source/blender/blenkernel/intern/key.cc M source/blender/bmesh/intern/bmesh_mesh_convert.cc M source/blender/editors/curve/editcurve.c M source/blender/editors/sculpt_paint/sculpt.cc === diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 10c95253f38..5d6f5e3c201 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -185,6 +185,12 @@ bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index); */ bool BKE_keyblock_is_basis(const struct Key *key, int index); +/** + * Returns an array containing true for every key that has this one as basis. + * If none are found, returns null. + */ +bool *BKE_keyblock_get_dependent_keys(const struct Key *key, int index); + /* */ /** \name Key-Block Data Access * \{ */ diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index b8ff350917e..b8d8442b93d 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2592,3 +2592,50 @@ bool BKE_keyblock_is_basis(const Key *key, const int index) return false; } + +bool *BKE_keyblock_get_dependent_keys(const struct Key *key, int index) +{ + /* Simple checks. */ + if (key->type != KEY_RELATIVE) { +return nullptr; + } + + const int count = BLI_listbase_count(>block); + + if (index < 0 || index >= count) { +return nullptr; + } + + /* Seed the table with the specified key. */ + bool *marked = static_cast(MEM_callocN(sizeof(bool) * count, __func__)); + + marked[index] = true; + + /* Iterative breadth-first search through the key list. */ + int updated, total = 0; + + do { +const KeyBlock *kb; +int i; + +updated = 0; + +for (i = 0, kb = static_cast(key->block.first); kb; i++, kb = kb->next) { + if (!marked[i] && kb->relative >= 0 && kb->relative < count && marked[kb->relative]) { +marked[i] = true; +updated++; +total++; + } +} + } while (updated > 0); + + if (total == 0) { +MEM_freeN(marked); +return nullptr; + } + else { +/* After the search is complete, exclude the original key. */ +marked[index] = false; +return marked; + } +} diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index d58337400a2..55b6b37e7b1 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -721,6 +721,7 @@ static void bm_to_mesh_shape(BMesh *bm, BMIter iter; BMVert *eve; float(*ofs)[3] = nullptr; + bool *dependent = nullptr; /* Editing the basis key updates others. */ if ((key->type == KEY_RELATIVE) && @@ -729,7 +730,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Original key-indices are only used to check the vertex existed when entering edit-mode. */ (cd_shape_keyindex_offset != -1) && /* Offsets are only needed if the current shape is a basis for others. */ - BKE_keyblock_is_basis(key, bm->shapenr - 1)) { + (dependent = BKE_keyblock_get_dependent_keys(key, bm->shapenr - 1)) != nullptr) { BLI_assert(actkey != nullptr); /* Assured by `actkey_has_layer` check. */ const int actkey_uuid = bm_to_mesh_shape_layer_index_from_kb(bm, actkey); @@ -755,6 +756,8 @@ static void bm_to_mesh_shape(BMesh *bm, * ones, creating a mess when doing e.g. subdivide + translate. */ MEM_freeN(ofs); ofs = nullptr; +MEM_freeN(dependent); +dependent = nullptr; break; } } @@ -781,7 +784,9 @@ static void bm_to_mesh_shape(BMesh *bm, } } - LISTBASE_FOREACH (KeyBlock *, currkey, >block) { + int currkey_i; + + LISTBASE_FOREACH_INDEX (KeyBlock *, currkey, >block, currkey_i) { int keyi; float(*currkey_data)[3]; @@ -792,8 +797,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Common case, the layer data is available, use it where possible. */ if (cd_shape_offset != -1) { - const bool apply_offset = (ofs != nullptr) && (currkey != actkey) && -
[Bf-blender-cvs] [14f715c2705] temp-angavrilov: Mesh Edit: implement an operator to smooth shape key deformation.
Commit: 14f715c2705d59345a288c36db84f6410556afb2 Author: Alexander Gavrilov Date: Sat Feb 4 18:25:43 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB14f715c2705d59345a288c36db84f6410556afb2 Mesh Edit: implement an operator to smooth shape key deformation. Similar to the difference between Corrective Smooth and simple Smooth modifiers, when editing shape keys it sometimes makes sense to smooth the deformation defined by the key rather than the final shape. This implements a simple shape key smoothing operator, accessible via the Vertex menu next to Blend From Shape. The operator applies a simple iterative smoothing process (identical to the one implemented by the Smooth tool) to the offsets of vertices from the relative basis key rather than their positions. In order to provide more flexibility for dealing with shape keys intended to be used in conjunction with other ones, the operator provides an option to modify the relative basis used for smoothing via selecting another key. The following modes are supported: Only Active Key: The default mode smoothes the deformation of the key itself. The additional reference key is not used. Include Key: Includes the deformation of the reference key into the smoothing. This can be used when the key currently being edited is intended to be applied on top of another one to smooth their combined deformation. Exclude Key: This exludes the deformation of the reference key from smoothing. Intended for the opposite case of smoothing the difference between two keys being intended to be used alternatively to each other. Relative To Key: This effectively overrides the Relative To setting of the active key, simply replacing the basis key for the purpose of this operator only. Like ordinary Smooth, the operator supports locking smoothing of certain axis directions. In addition, it supports restricting direction based on the vertex normal to allow separately smoothing inflation and sliding. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/editors/mesh/editmesh_tools.c M source/blender/editors/mesh/mesh_intern.h M source/blender/editors/mesh/mesh_ops.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index a5addd6990c..491fdb0f1fb 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -4184,6 +4184,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.separator() layout.operator("mesh.blend_from_shape") +layout.operator("mesh.smooth_shape") layout.operator("mesh.shape_propagate_to_all", text="Propagate to Shapes") layout.separator() diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 412887fee7d..11b472d568a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4067,6 +4067,470 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot) /** \} */ +/* */ +/** \name Smooth Shape Operator + * \{ */ + +enum { + MESH_SHAPE_RELATIVE_OWN, + MESH_SHAPE_RELATIVE_INCLUDE, + MESH_SHAPE_RELATIVE_EXCLUDE, + MESH_SHAPE_RELATIVE_BASIS +}; + +struct ShapeKeyRelativeInfo { + int mode; + int active_basis; + int ref_key, ref_basis; +}; + +static bool edbm_shape_relative_info_validate(BMesh *bm, struct ShapeKeyRelativeInfo *info) +{ + int totshape_ref = CustomData_number_of_layers(>vdata, CD_SHAPEKEY); + int active_key = bm->shapenr - 1; + + switch (info->mode) { +case MESH_SHAPE_RELATIVE_OWN: + return info->active_basis >= 0 && info->active_basis < totshape_ref; +case MESH_SHAPE_RELATIVE_BASIS: + return info->ref_key >= 0 && info->ref_key < totshape_ref && info->ref_key != active_key; +case MESH_SHAPE_RELATIVE_INCLUDE: +case MESH_SHAPE_RELATIVE_EXCLUDE: + if (info->ref_key == 0) { +/* Including or excluding the basis is a no-op. */ +info->mode = MESH_SHAPE_RELATIVE_OWN; +return info->active_basis >= 0 && info->active_basis < totshape_ref; + } + return info->active_basis >= 0 && info->active_basis < totshape_ref && info->ref_key > 0 && + info->ref_key < totshape_ref && info->ref_basis >= 0 && + info->ref_basis < totshape_ref && info->ref_key != active_key; +default: + return false; + } +} + +static void edbm_shape_get_relative_offset(BMesh *bm, +
[Bf-blender-cvs] [b72d576f9ff] temp-angavrilov: Mesh Edit: implement X symmetry in the Blend From Shape operator.
Commit: b72d576f9ff83986773801a275e5220b53d5cdba Author: Alexander Gavrilov Date: Sat Feb 4 18:26:46 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rBb72d576f9ff83986773801a275e5220b53d5cdba Mesh Edit: implement X symmetry in the Blend From Shape operator. === M source/blender/editors/mesh/editmesh_tools.c === diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index edf82382298..412887fee7d 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3927,6 +3927,14 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) shape = BLI_findindex(>block, kb); if (kb) { + const bool use_symmetry = (me->symmetry & ME_SYMMETRY_X) != 0; + + if (use_symmetry) { +const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; + +EDBM_verts_mirror_cache_begin(em, 0, false, true, false, use_topology); + } + /* Perform blending on selected vertices. */ BM_ITER_MESH (eve, , em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { @@ -3950,6 +3958,12 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) interp_v3_v3v3(eve->co, eve->co, co, blend); } } + + if (use_symmetry) { +EDBM_verts_mirror_apply(em, BM_ELEM_SELECT, 0); +EDBM_verts_mirror_cache_end(em); + } + EDBM_update(me, &(const struct EDBMUpdate_Params){ .calc_looptri = true, ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5bdc02f4446] temp-angavrilov: Subdivision Surface: add dependency graph tracking when cpu mesh is needed.
Commit: 5bdc02f4446d5ccd2e212b09fa61b77bbb3d8ae9 Author: Alexander Gavrilov Date: Wed Jan 25 11:37:40 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB5bdc02f4446d5ccd2e212b09fa61b77bbb3d8ae9 Subdivision Surface: add dependency graph tracking when cpu mesh is needed. Constraints targeting mesh vertex groups, as well as likely modifiers now tag their targets with a dependency graph flag to notify that the fully evaluated mesh is needed on the CPU. This is used to disable GPU subdiv in those cases. In addition, the evaluated mesh is used by sculpt and paint modes. === M source/blender/blenkernel/BKE_subdiv_modifier.h M source/blender/blenkernel/intern/subdiv_modifier.cc M source/blender/depsgraph/DEG_depsgraph.h M source/blender/depsgraph/DEG_depsgraph_build.h M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/depsgraph_build.cc M source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c M source/blender/modifiers/intern/MOD_array.cc M source/blender/modifiers/intern/MOD_boolean.cc M source/blender/modifiers/intern/MOD_datatransfer.cc M source/blender/modifiers/intern/MOD_mesh_to_volume.cc M source/blender/modifiers/intern/MOD_meshdeform.c M source/blender/modifiers/intern/MOD_shrinkwrap.c M source/blender/modifiers/intern/MOD_subsurf.cc M source/blender/modifiers/intern/MOD_surfacedeform.cc M source/blender/modifiers/intern/MOD_weightvgproximity.cc === diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index dd01c4ffd07..f20e2028b37 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -7,6 +7,7 @@ #pragma once +#include "BKE_DerivedMesh.h" #include "BKE_subdiv.h" #include "BLI_sys_types.h" @@ -68,12 +69,15 @@ bool BKE_subsurf_modifier_use_custom_loop_normals(const struct SubsurfModifierDa * and supported by the GPU. It is mainly useful for showing UI messages. */ bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh( -const struct SubsurfModifierData *smd, const struct Mesh *mesh); +const struct Depsgraph *depsgraph, +const struct Object *ob, +const struct Mesh *mesh, +const struct SubsurfModifierData *smd); /** * \param skip_check_is_last: When true, we assume that the modifier passed is the last enabled * modifier in the stack. */ -bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Scene *scene, +bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Depsgraph *depsgraph, const struct Object *ob, const struct Mesh *mesh, const struct SubsurfModifierData *smd, diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 60d55af215c..eb69f8bb5c9 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -14,6 +14,7 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_subdiv.h" +#include "DEG_depsgraph_query.h" #include "GPU_capabilities.h" #include "GPU_context.h" @@ -112,8 +113,25 @@ static bool is_subdivision_evaluation_possible_on_gpu() return true; } -bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfModifierData *smd, -const Mesh *mesh) +static bool subsurf_modifier_has_cpu_dependents(const Depsgraph *depsgraph, const Object *ob) +{ + /* The sculpt mode UI requires the mesh. */ + if (ob->mode & OB_MODE_ALL_SCULPT) { +return true; + } + + /* Some dependencies request it through depsgraph. */ + if (DEG_get_eval_flags_for_id(depsgraph, >id) & DAG_EVAL_NEED_CPU_SUBSURF) { +return true; + } + + return false; +} + +bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const Depsgraph *depsgraph, +const Object *ob, +const Mesh *mesh, +const SubsurfModifierData *smd) { if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) { /* GPU subdivision is explicitly disabled, so we don't force it. */ @@ -125,10 +143,11 @@ bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfMod return false; } - return subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh); + return
[Bf-blender-cvs] [c0d9c7cf467] temp-angavrilov: Subdivision Surface: fix a serious performance hit when mixing CPU & GPU.
Commit: c0d9c7cf4671c85e30959a3526f9a3eb4b5c1382 Author: Alexander Gavrilov Date: Wed Jan 25 11:34:58 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rBc0d9c7cf4671c85e30959a3526f9a3eb4b5c1382 Subdivision Surface: fix a serious performance hit when mixing CPU & GPU. Subdivision surface efficiency relies on caching pre-computed topology data for evaluation between frames. However, while rBeed45d2a239a introduced a second GPU subdiv evaluator type, it still only kept one slot for caching this runtime data per mesh. The result is that if the mesh is also needed on CPU, for instance due to a modifier on a different object (e.g. shrinkwrap), the two evaluators are used at the same time and fight over the single slot. This causes the topology data to be discarded and recomputed twice per frame. Since avoiding duplicate evaluation is a complex task, this fix simply adds a second separate cache slot for the GPU data, so that the cost is simply running subdivision twice, not recomputing topology twice. To help diagnostics, I also add a message to show when GPU evaluation is actually used to the modifier panel. Two frame counters are used to suppress flicker in the UI panel. Differential Revision: https://developer.blender.org/D17117 === M source/blender/blenkernel/BKE_subdiv_modifier.h M source/blender/blenkernel/intern/mesh_wrapper.cc M source/blender/blenkernel/intern/subdiv_modifier.cc M source/blender/modifiers/intern/MOD_subsurf.cc === diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index d65df26da77..dd01c4ffd07 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -32,8 +32,13 @@ typedef struct SubsurfRuntimeData { SubdivSettings settings; /* Cached subdivision surface descriptor, with topology and settings. */ - struct Subdiv *subdiv; - bool set_by_draw_code; + struct Subdiv *subdiv_cpu; + struct Subdiv *subdiv_gpu; + + /* Recent usage markers for UI diagnostics. To avoid UI flicker due to races + * between evaluation and UI redraw, they are set to 2 when an evaluator is used, + * and count down every frame. */ + char used_cpu, used_gpu; /* Cached mesh wrapper data, to be used for GPU subdiv or lazy evaluation on CPU. */ bool has_gpu_subdiv; diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 9c8c36cacb8..3b036274477 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -350,7 +350,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me) BKE_mesh_calc_normals_split(subdiv_mesh); } - if (subdiv != runtime_data->subdiv) { + if (subdiv != runtime_data->subdiv_cpu && subdiv != runtime_data->subdiv_gpu) { BKE_subdiv_free(subdiv); } diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 3221e43d4e6..60d55af215c 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -49,6 +49,8 @@ bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_ * was already allocated. */ if (runtime_data) { runtime_data->settings = settings; + + runtime_data->used_cpu = runtime_data->used_gpu = 0; } return false; @@ -162,15 +164,18 @@ Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtim const Mesh *mesh, const bool for_draw_code) { - if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) { -BKE_subdiv_free(runtime_data->subdiv); -runtime_data->subdiv = nullptr; + if (for_draw_code) { +runtime_data->used_gpu = 2; /* countdown in frames */ + +return runtime_data->subdiv_gpu = BKE_subdiv_update_from_mesh( + runtime_data->subdiv_gpu, _data->settings, mesh); + } + else { +runtime_data->used_cpu = 2; + +return runtime_data->subdiv_cpu = BKE_subdiv_update_from_mesh( + runtime_data->subdiv_cpu, _data->settings, mesh); } - Subdiv *subdiv = BKE_subdiv_update_from_mesh( - runtime_data->subdiv, _data->settings, mesh); - runtime_data->subdiv = subdiv; - runtime_data->set_by_draw_code = for_draw_code; - return subdiv; } int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode) diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 75377f00bb3..7f6a9696b56 1006
[Bf-blender-cvs] [08eb1cbb539] temp-angavrilov: Shape Keys: support locking to protect from accidental editing.
Commit: 08eb1cbb539e075848a30eaabf4e55010fc386ad Author: Alexander Gavrilov Date: Tue Jan 24 16:53:10 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB08eb1cbb539e075848a30eaabf4e55010fc386ad Shape Keys: support locking to protect from accidental editing. It is very common for graphical editors with layers to support locking individual layers to protect them from accidental edits due to misclicks. Blender itself already supports locking vertex groups. This adds lock toggles for shape keys, with lock/unlock all operators. The flags are checked by sculpt brushes, edit mode transform tools, and Smooth, Propagate and Blend From Shape operators. This selection aims to cover operations that only deform the mesh, where the shape key selection matters. Topology changing operations always apply to all keys, and thus incorrect shape key selection is less impactful. === M release/scripts/startup/bl_ui/properties_data_mesh.py M source/blender/blenkernel/BKE_key.h M source/blender/blenkernel/intern/key.cc M source/blender/editors/include/ED_mesh.h M source/blender/editors/mesh/editmesh_tools.c M source/blender/editors/mesh/mesh_data.cc M source/blender/editors/object/object_intern.h M source/blender/editors/object/object_ops.c M source/blender/editors/object/object_shapekey.c M source/blender/editors/sculpt_paint/sculpt.cc M source/blender/editors/transform/transform_convert_curve.c M source/blender/editors/transform/transform_convert_lattice.c M source/blender/editors/transform/transform_convert_mesh.c M source/blender/editors/transform/transform_convert_sculpt.c M source/blender/makesdna/DNA_key_types.h M source/blender/makesrna/intern/rna_key.c === diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 1ff76a73e7e..f65516a34b2 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -70,6 +70,9 @@ class MESH_MT_shape_key_context_menu(Menu): op.all = True op.apply_mix = True layout.separator() +layout.operator("object.shape_key_lock", icon='LOCKED', text="Lock All").action = 'LOCK' +layout.operator("object.shape_key_lock", icon='UNLOCKED', text="Unlock All").action = 'UNLOCK' +layout.separator() layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP' layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM' @@ -140,6 +143,7 @@ class MESH_UL_shape_keys(UIList): else: row.label(text="") row.prop(key_block, "mute", text="", emboss=False) +row.prop(key_block, "lock_shape", text="", emboss=False) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index d868969f9b9..10c95253f38 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -87,9 +87,13 @@ struct KeyBlock *BKE_keyblock_add(struct Key *key, const char *name); */ struct KeyBlock *BKE_keyblock_add_ctime(struct Key *key, const char *name, bool do_force); /** - * Get the appropriate #KeyBlock given an index. + * Get the appropriate #KeyBlock given an index, excluding the first (0th) key. Key may be null. */ struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index); +/** + * Get the appropriate #KeyBlock given an index. Key may be null. + */ +struct KeyBlock *BKE_keyblock_find_index(struct Key *key, int index); /** * Get the appropriate #KeyBlock given a name to search for. */ diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 7d835c2464d..b8ff350917e 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1899,12 +1899,7 @@ KeyBlock *BKE_keyblock_from_object(Object *ob) { Key *key = BKE_key_from_object(ob); - if (key) { -KeyBlock *kb = static_cast(BLI_findlink(>block, ob->shapenr - 1)); -return kb; - } - - return nullptr; + return BKE_keyblock_find_index(key, ob->shapenr - 1); } KeyBlock *BKE_keyblock_from_object_reference(Object *ob) @@ -1935,6 +1930,15 @@ KeyBlock *BKE_keyblock_from_key(Key *key, int index) return nullptr; } +KeyBlock *BKE_keyblock_find_index(Key *key, int index) +{ + if (key) { +return static_cast(BLI_findlink(>block, index)); + }
[Bf-blender-cvs] [67f51bff7cf] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: 67f51bff7cfcc31c3c974b5a81e5a23d27410841 Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB67f51bff7cfcc31c3c974b5a81e5a23d27410841 Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f9bae39b016..c6e75a78091 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 38f80760d61..db63f8f19a5 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [e92905beabd] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: e92905beabd66e4749e5596dc5f9df6380c5ec51 Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBe92905beabd66e4749e5596dc5f9df6380c5ec51 Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 1a0b33ca2b1..5f5f29a1b36 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -752,6 +752,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -773,71 +783,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [87126c214e2] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: 87126c214e26133c141a216fe8455b3eb1642124 Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB87126c214e26133c141a216fe8455b3eb1642124 Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 1ce457480e5..a5addd6990c 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6811,6 +6811,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 4c45e1433ab..53ce28a057d 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3912,5 +3912,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index d2835639686..7afd4421341 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -580,6 +580,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 8c9587e7a9a..b0aea51e590 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) draw_ctx->object_pose != nullptr; const float wire_alpha = pd->overlay.bone_wire_alpha; - const bool use_wire_alpha = (wire_alpha < 1.0f); + const float wire_fade
[Bf-blender-cvs] [e9f16918b33] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: e9f16918b33a24b0a227e9bde05b6d6de82b4787 Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBe9f16918b33a24b0a227e9bde05b6d6de82b4787 Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.cc M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index cae4687faac..8d5a9f3cdda 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -342,6 +342,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -352,6 +356,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 757ac57c171..6c707814e61 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -268,20 +268,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [b696da4ae9a] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: b696da4ae9a86aad52446ceaa972209db37b7fc1 Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBb696da4ae9a86aad52446ceaa972209db37b7fc1 Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index af9b9e527e6..25439bd5a5e 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [5a11b2f5a2f] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: 5a11b2f5a2f0e2d8822b6556f968a2cf0b5eb94a Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB5a11b2f5a2f0e2d8822b6556f968a2cf0b5eb94a Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [212d9e09a48] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: 212d9e09a48ffbe328f307d7f110c5a49b006c94 Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB212d9e09a48ffbe328f307d7f110c5a49b006c94 Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d0b978b7adf..92bad9f9168 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index eff12af02d2..56a8fb14876 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 7aaeb41572b..171ec3ae7f5 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -36,6 +36,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [84ec6527186] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 84ec6527186231eaf6987943cdff8d5bb4ba7c9a Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB84ec6527186231eaf6987943cdff8d5bb4ba7c9a Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 1a0b33ca2b1..5f5f29a1b36 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -752,6 +752,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -773,71 +783,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [9b1b2092c83] temp-angavrilov: Shape Keys: support locking to protect from accidental editing.
Commit: 9b1b2092c83e5f0fdd911557c9e302460621871f Author: Alexander Gavrilov Date: Tue Jan 24 16:53:10 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB9b1b2092c83e5f0fdd911557c9e302460621871f Shape Keys: support locking to protect from accidental editing. It is very common for graphical editors with layers to support locking individual layers to protect them from accidental edits due to misclicks. Blender itself already supports locking vertex groups. This adds lock toggles for shape keys, with lock/unlock all operators. The flags are checked by sculpt brushes, edit mode transform tools, and Smooth, Propagate and Blend From Shape operators. This selection aims to cover operations that only deform the mesh, where the shape key selection matters. Topology changing operations always apply to all keys, and thus incorrect shape key selection is less impactful. === M release/scripts/startup/bl_ui/properties_data_mesh.py M source/blender/blenkernel/BKE_key.h M source/blender/blenkernel/intern/key.cc M source/blender/editors/include/ED_mesh.h M source/blender/editors/mesh/editmesh_tools.c M source/blender/editors/mesh/mesh_data.cc M source/blender/editors/object/object_intern.h M source/blender/editors/object/object_ops.c M source/blender/editors/object/object_shapekey.c M source/blender/editors/sculpt_paint/sculpt.cc M source/blender/editors/transform/transform_convert_curve.c M source/blender/editors/transform/transform_convert_lattice.c M source/blender/editors/transform/transform_convert_mesh.c M source/blender/editors/transform/transform_convert_sculpt.c M source/blender/makesdna/DNA_key_types.h M source/blender/makesrna/intern/rna_key.c === diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 1ff76a73e7e..f65516a34b2 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -70,6 +70,9 @@ class MESH_MT_shape_key_context_menu(Menu): op.all = True op.apply_mix = True layout.separator() +layout.operator("object.shape_key_lock", icon='LOCKED', text="Lock All").action = 'LOCK' +layout.operator("object.shape_key_lock", icon='UNLOCKED', text="Unlock All").action = 'UNLOCK' +layout.separator() layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP' layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM' @@ -140,6 +143,7 @@ class MESH_UL_shape_keys(UIList): else: row.label(text="") row.prop(key_block, "mute", text="", emboss=False) +row.prop(key_block, "lock_shape", text="", emboss=False) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index d868969f9b9..10c95253f38 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -87,9 +87,13 @@ struct KeyBlock *BKE_keyblock_add(struct Key *key, const char *name); */ struct KeyBlock *BKE_keyblock_add_ctime(struct Key *key, const char *name, bool do_force); /** - * Get the appropriate #KeyBlock given an index. + * Get the appropriate #KeyBlock given an index, excluding the first (0th) key. Key may be null. */ struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index); +/** + * Get the appropriate #KeyBlock given an index. Key may be null. + */ +struct KeyBlock *BKE_keyblock_find_index(struct Key *key, int index); /** * Get the appropriate #KeyBlock given a name to search for. */ diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 7d835c2464d..b8ff350917e 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1899,12 +1899,7 @@ KeyBlock *BKE_keyblock_from_object(Object *ob) { Key *key = BKE_key_from_object(ob); - if (key) { -KeyBlock *kb = static_cast(BLI_findlink(>block, ob->shapenr - 1)); -return kb; - } - - return nullptr; + return BKE_keyblock_find_index(key, ob->shapenr - 1); } KeyBlock *BKE_keyblock_from_object_reference(Object *ob) @@ -1935,6 +1930,15 @@ KeyBlock *BKE_keyblock_from_key(Key *key, int index) return nullptr; } +KeyBlock *BKE_keyblock_find_index(Key *key, int index) +{ + if (key) { +return static_cast(BLI_findlink(>block, index)); + }
[Bf-blender-cvs] [7faa8c84b35] temp-angavrilov: Subdivision Surface: fix a serious performance hit when mixing CPU & GPU.
Commit: 7faa8c84b35397dee81532c235ebda487d71a8b7 Author: Alexander Gavrilov Date: Wed Jan 25 11:34:58 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB7faa8c84b35397dee81532c235ebda487d71a8b7 Subdivision Surface: fix a serious performance hit when mixing CPU & GPU. Subdivision surface efficiency relies on caching pre-computed topology data for evaluation between frames. However, while rBeed45d2a239a introduced a second GPU subdiv evaluator type, it still only kept one slot for caching this runtime data per mesh. The result is that if the mesh is also needed on CPU, for instance due to a modifier on a different object (e.g. shrinkwrap), the two evaluators are used at the same time and fight over the single slot. This causes the topology data to be discarded and recomputed twice per frame. Since avoiding duplicate evaluation is a complex task, this fix simply adds a second separate cache slot for the GPU data, so that the cost is simply running subdivision twice, not recomputing topology twice. To help diagnostics, I also add a message to show when GPU evaluation is actually used to the modifier panel. Two frame counters are used to suppress flicker in the UI panel. Differential Revision: https://developer.blender.org/D17117 === M source/blender/blenkernel/BKE_subdiv_modifier.h M source/blender/blenkernel/intern/mesh_wrapper.cc M source/blender/blenkernel/intern/subdiv_modifier.cc M source/blender/modifiers/intern/MOD_subsurf.cc === diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index d65df26da77..dd01c4ffd07 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -32,8 +32,13 @@ typedef struct SubsurfRuntimeData { SubdivSettings settings; /* Cached subdivision surface descriptor, with topology and settings. */ - struct Subdiv *subdiv; - bool set_by_draw_code; + struct Subdiv *subdiv_cpu; + struct Subdiv *subdiv_gpu; + + /* Recent usage markers for UI diagnostics. To avoid UI flicker due to races + * between evaluation and UI redraw, they are set to 2 when an evaluator is used, + * and count down every frame. */ + char used_cpu, used_gpu; /* Cached mesh wrapper data, to be used for GPU subdiv or lazy evaluation on CPU. */ bool has_gpu_subdiv; diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 9c8c36cacb8..3b036274477 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -350,7 +350,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me) BKE_mesh_calc_normals_split(subdiv_mesh); } - if (subdiv != runtime_data->subdiv) { + if (subdiv != runtime_data->subdiv_cpu && subdiv != runtime_data->subdiv_gpu) { BKE_subdiv_free(subdiv); } diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 3221e43d4e6..60d55af215c 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -49,6 +49,8 @@ bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_ * was already allocated. */ if (runtime_data) { runtime_data->settings = settings; + + runtime_data->used_cpu = runtime_data->used_gpu = 0; } return false; @@ -162,15 +164,18 @@ Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtim const Mesh *mesh, const bool for_draw_code) { - if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) { -BKE_subdiv_free(runtime_data->subdiv); -runtime_data->subdiv = nullptr; + if (for_draw_code) { +runtime_data->used_gpu = 2; /* countdown in frames */ + +return runtime_data->subdiv_gpu = BKE_subdiv_update_from_mesh( + runtime_data->subdiv_gpu, _data->settings, mesh); + } + else { +runtime_data->used_cpu = 2; + +return runtime_data->subdiv_cpu = BKE_subdiv_update_from_mesh( + runtime_data->subdiv_cpu, _data->settings, mesh); } - Subdiv *subdiv = BKE_subdiv_update_from_mesh( - runtime_data->subdiv, _data->settings, mesh); - runtime_data->subdiv = subdiv; - runtime_data->set_by_draw_code = for_draw_code; - return subdiv; } int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode) diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 75377f00bb3..7f6a9696b56 1006
[Bf-blender-cvs] [ee58795cae8] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: ee58795cae8467edcff8470abc5ae24ce25a8255 Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBee58795cae8467edcff8470abc5ae24ce25a8255 Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f9bae39b016..c6e75a78091 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [5d7a0461432] temp-angavrilov: Subdivision Surface: add dependency graph tracking when cpu mesh is needed.
Commit: 5d7a04614321c2ecce62a055653b1023ade9a1e7 Author: Alexander Gavrilov Date: Wed Jan 25 11:37:40 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB5d7a04614321c2ecce62a055653b1023ade9a1e7 Subdivision Surface: add dependency graph tracking when cpu mesh is needed. Constraints targeting mesh vertex groups, as well as likely modifiers now tag their targets with a dependency graph flag to notify that the fully evaluated mesh is needed on the CPU. This is used to disable GPU subdiv in those cases. In addition, the evaluated mesh is used by sculpt and paint modes. === M source/blender/blenkernel/BKE_subdiv_modifier.h M source/blender/blenkernel/intern/subdiv_modifier.cc M source/blender/depsgraph/DEG_depsgraph.h M source/blender/depsgraph/DEG_depsgraph_build.h M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/depsgraph_build.cc M source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c M source/blender/modifiers/intern/MOD_array.cc M source/blender/modifiers/intern/MOD_boolean.cc M source/blender/modifiers/intern/MOD_datatransfer.cc M source/blender/modifiers/intern/MOD_mesh_to_volume.cc M source/blender/modifiers/intern/MOD_meshdeform.c M source/blender/modifiers/intern/MOD_shrinkwrap.c M source/blender/modifiers/intern/MOD_subsurf.cc M source/blender/modifiers/intern/MOD_surfacedeform.cc M source/blender/modifiers/intern/MOD_weightvgproximity.cc === diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index dd01c4ffd07..f20e2028b37 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -7,6 +7,7 @@ #pragma once +#include "BKE_DerivedMesh.h" #include "BKE_subdiv.h" #include "BLI_sys_types.h" @@ -68,12 +69,15 @@ bool BKE_subsurf_modifier_use_custom_loop_normals(const struct SubsurfModifierDa * and supported by the GPU. It is mainly useful for showing UI messages. */ bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh( -const struct SubsurfModifierData *smd, const struct Mesh *mesh); +const struct Depsgraph *depsgraph, +const struct Object *ob, +const struct Mesh *mesh, +const struct SubsurfModifierData *smd); /** * \param skip_check_is_last: When true, we assume that the modifier passed is the last enabled * modifier in the stack. */ -bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Scene *scene, +bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Depsgraph *depsgraph, const struct Object *ob, const struct Mesh *mesh, const struct SubsurfModifierData *smd, diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 60d55af215c..eb69f8bb5c9 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -14,6 +14,7 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_subdiv.h" +#include "DEG_depsgraph_query.h" #include "GPU_capabilities.h" #include "GPU_context.h" @@ -112,8 +113,25 @@ static bool is_subdivision_evaluation_possible_on_gpu() return true; } -bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfModifierData *smd, -const Mesh *mesh) +static bool subsurf_modifier_has_cpu_dependents(const Depsgraph *depsgraph, const Object *ob) +{ + /* The sculpt mode UI requires the mesh. */ + if (ob->mode & OB_MODE_ALL_SCULPT) { +return true; + } + + /* Some dependencies request it through depsgraph. */ + if (DEG_get_eval_flags_for_id(depsgraph, >id) & DAG_EVAL_NEED_CPU_SUBSURF) { +return true; + } + + return false; +} + +bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const Depsgraph *depsgraph, +const Object *ob, +const Mesh *mesh, +const SubsurfModifierData *smd) { if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) { /* GPU subdivision is explicitly disabled, so we don't force it. */ @@ -125,10 +143,11 @@ bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfMod return false; } - return subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh); + return
[Bf-blender-cvs] [85af3685d0f] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: 85af3685d0f72af8984e966307ece8e7e2f3ec14 Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB85af3685d0f72af8984e966307ece8e7e2f3ec14 Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 2f5b70bb3da..39a40621455 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6839,6 +6839,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 4c45e1433ab..53ce28a057d 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3912,5 +3912,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index d2835639686..7afd4421341 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -580,6 +580,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 8c9587e7a9a..b0aea51e590 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) draw_ctx->object_pose != nullptr; const float wire_alpha = pd->overlay.bone_wire_alpha; - const bool use_wire_alpha = (wire_alpha < 1.0f); + const float wire_fade
[Bf-blender-cvs] [4c73c394db1] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: 4c73c394db1fb4390fd0808eb4bb6d0a6bf3d65b Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB4c73c394db1fb4390fd0808eb4bb6d0a6bf3d65b Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.cc M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index cae4687faac..8d5a9f3cdda 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -342,6 +342,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -352,6 +356,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 757ac57c171..6c707814e61 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -268,20 +268,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [e39be6c46b0] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: e39be6c46b049cf787ef6ad19167142ef3eb38be Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBe39be6c46b049cf787ef6ad19167142ef3eb38be Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f4c958d5ec6] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: f4c958d5ec6aaf5547ea6bb4443e8221a74b67d3 Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBf4c958d5ec6aaf5547ea6bb4443e8221a74b67d3 Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 99b33840051..f2854440e2a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [27e86f9d84a] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: 27e86f9d84ac8c9ad0054cdab9db55146f4ddc8b Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB27e86f9d84ac8c9ad0054cdab9db55146f4ddc8b Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d0b978b7adf..92bad9f9168 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index eff12af02d2..56a8fb14876 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 7aaeb41572b..171ec3ae7f5 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -36,6 +36,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f7dd7d54547] master: Python API: add a method for reordering modifiers.
Commit: f7dd7d545472b8571a64ec96eb94eed1aada0523 Author: Alexander Gavrilov Date: Tue Jan 10 18:25:58 2023 +0200 Branches: master https://developer.blender.org/rBf7dd7d545472b8571a64ec96eb94eed1aada0523 Python API: add a method for reordering modifiers. Add an `object.modifiers.move()` method, similar to the one for constraints and some other collections. Currently reordering modifiers requires using operators, which depend on context. The implementation is straightforward, except for the need to make the severity of errors reported by the underlying editor code into a parameter, so that the new Python API function reports any problems as Python exceptions, and refactoring the code to allow aborting a blocked move before making any changes. I also turn the negative index condition from an assert into an error. Differential Revision: https://developer.blender.org/D16966 === M source/blender/editors/include/ED_object.h M source/blender/editors/object/object_modifier.cc M source/blender/editors/space_outliner/outliner_dragdrop.cc M source/blender/makesrna/intern/rna_object.c === diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 82f8505509a..baa84b550aa 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -10,6 +10,7 @@ #include "BLI_compiler_attrs.h" #include "DNA_object_enums.h" #include "DNA_userdef_enums.h" +#include "DNA_windowmanager_types.h" #ifdef __cplusplus extern "C" { @@ -558,15 +559,19 @@ bool ED_object_modifier_remove(struct ReportList *reports, struct ModifierData *md); void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob); bool ED_object_modifier_move_down(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_up(struct ReportList *reports, +eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_to_index(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md, - int index); + int index, + bool allow_partial); bool ED_object_modifier_convert_psys_to_mesh(struct ReportList *reports, struct Main *bmain, diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 1bfd156b664..9964d658994 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -415,83 +415,139 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob) DEG_relations_tag_update(bmain); } -bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) +static bool object_modifier_check_move_before(ReportList *reports, + eReportType error_type, + ModifierData *md, + ModifierData *md_prev) { - if (md->prev) { + if (md_prev) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); if (mti->type != eModifierTypeType_OnlyDeform) { - const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md->prev->type); + const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md_prev->type); if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) { -BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); +BKE_report(reports, error_type, "Cannot move above a modifier requiring original data"); return false; } } - -BLI_listbase_swaplinks(>modifiers, md, md->prev); } else { -BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the start of the list"); +BKE_report(reports, error_type, "Cannot move modifier beyond the start of the list"); return false; } return true; } -bool ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) +bool ED_object_modifier_move_up(ReportList *reports, +
[Bf-blender-cvs] [25f8381d9f3] temp-angavrilov: Shape Keys: support locking to protect from accidental editing.
Commit: 25f8381d9f39d9720dd957435a0c8493e5c95daf Author: Alexander Gavrilov Date: Tue Jan 24 16:53:10 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB25f8381d9f39d9720dd957435a0c8493e5c95daf Shape Keys: support locking to protect from accidental editing. It is very common for graphical editors with layers to support locking individual layers to protect them from accidental edits due to misclicks. Blender itself already supports locking vertex groups. This adds lock toggles for shape keys, with lock/unlock all operators. The flags are checked by sculpt brushes, edit mode transform tools, and Smooth, Propagate and Blend From Shape operators. This selection aims to cover operations that only deform the mesh, where the shape key selection matters. Topology changing operations always apply to all keys, and thus incorrect shape key selection is less impactful. === M release/scripts/startup/bl_ui/properties_data_mesh.py M source/blender/blenkernel/BKE_key.h M source/blender/blenkernel/intern/key.cc M source/blender/editors/include/ED_mesh.h M source/blender/editors/mesh/editmesh_tools.c M source/blender/editors/mesh/mesh_data.cc M source/blender/editors/object/object_intern.h M source/blender/editors/object/object_ops.c M source/blender/editors/object/object_shapekey.c M source/blender/editors/sculpt_paint/sculpt.cc M source/blender/editors/transform/transform_convert_curve.c M source/blender/editors/transform/transform_convert_lattice.c M source/blender/editors/transform/transform_convert_mesh.c M source/blender/editors/transform/transform_convert_sculpt.c M source/blender/makesdna/DNA_key_types.h M source/blender/makesrna/intern/rna_key.c === diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 714dcca9673..98b4cfc9f1d 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -70,6 +70,9 @@ class MESH_MT_shape_key_context_menu(Menu): op.all = True op.apply_mix = True layout.separator() +layout.operator("object.shape_key_lock", icon='LOCKED', text="Lock All").action = 'LOCK' +layout.operator("object.shape_key_lock", icon='UNLOCKED', text="Unlock All").action = 'UNLOCK' +layout.separator() layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP' layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM' @@ -140,6 +143,7 @@ class MESH_UL_shape_keys(UIList): else: row.label(text="") row.prop(key_block, "mute", text="", emboss=False) +row.prop(key_block, "lock_shape", text="", emboss=False) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index d868969f9b9..10c95253f38 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -87,9 +87,13 @@ struct KeyBlock *BKE_keyblock_add(struct Key *key, const char *name); */ struct KeyBlock *BKE_keyblock_add_ctime(struct Key *key, const char *name, bool do_force); /** - * Get the appropriate #KeyBlock given an index. + * Get the appropriate #KeyBlock given an index, excluding the first (0th) key. Key may be null. */ struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index); +/** + * Get the appropriate #KeyBlock given an index. Key may be null. + */ +struct KeyBlock *BKE_keyblock_find_index(struct Key *key, int index); /** * Get the appropriate #KeyBlock given a name to search for. */ diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 7d835c2464d..b8ff350917e 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1899,12 +1899,7 @@ KeyBlock *BKE_keyblock_from_object(Object *ob) { Key *key = BKE_key_from_object(ob); - if (key) { -KeyBlock *kb = static_cast(BLI_findlink(>block, ob->shapenr - 1)); -return kb; - } - - return nullptr; + return BKE_keyblock_find_index(key, ob->shapenr - 1); } KeyBlock *BKE_keyblock_from_object_reference(Object *ob) @@ -1935,6 +1930,15 @@ KeyBlock *BKE_keyblock_from_key(Key *key, int index) return nullptr; } +KeyBlock *BKE_keyblock_find_index(Key *key, int index) +{ + if (key) { +return static_cast(BLI_findlink(>block, index)); + }
[Bf-blender-cvs] [5de299d74dd] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 5de299d74ddd65c8279967ed9ce36b33af0df6bb Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB5de299d74ddd65c8279967ed9ce36b33af0df6bb Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 1a0b33ca2b1..5f5f29a1b36 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -752,6 +752,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -773,71 +783,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [449b4c7812a] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: 449b4c7812ad8654acfafb462b429411594214a9 Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB449b4c7812ad8654acfafb462b429411594214a9 Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f9bae39b016..c6e75a78091 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [040ab81d4e3] temp-angavrilov: Python API: add a method for reordering modifiers.
Commit: 040ab81d4e34571fdf30cea017b6716898c45096 Author: Alexander Gavrilov Date: Tue Jan 10 18:25:58 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB040ab81d4e34571fdf30cea017b6716898c45096 Python API: add a method for reordering modifiers. Add an `object.modifiers.move()` method, similar to the one for constraints and some other collections. Currently reordering modifiers requires using operators, which depend on context. The implementation is straightforward, except for the need to make the severity of errors reported by the underlying editor code into a parameter, so that the new Python API function reports any problems as Python exceptions. I also turn the negative index condition from an assert into an error. Differential Revision: https://developer.blender.org/D16966 === M source/blender/editors/include/ED_object.h M source/blender/editors/object/object_modifier.cc M source/blender/editors/space_outliner/outliner_dragdrop.cc M source/blender/makesrna/intern/rna_object.c === diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 82f8505509a..baa84b550aa 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -10,6 +10,7 @@ #include "BLI_compiler_attrs.h" #include "DNA_object_enums.h" #include "DNA_userdef_enums.h" +#include "DNA_windowmanager_types.h" #ifdef __cplusplus extern "C" { @@ -558,15 +559,19 @@ bool ED_object_modifier_remove(struct ReportList *reports, struct ModifierData *md); void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob); bool ED_object_modifier_move_down(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_up(struct ReportList *reports, +eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_to_index(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md, - int index); + int index, + bool allow_partial); bool ED_object_modifier_convert_psys_to_mesh(struct ReportList *reports, struct Main *bmain, diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 1bfd156b664..9964d658994 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -415,83 +415,139 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob) DEG_relations_tag_update(bmain); } -bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) +static bool object_modifier_check_move_before(ReportList *reports, + eReportType error_type, + ModifierData *md, + ModifierData *md_prev) { - if (md->prev) { + if (md_prev) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); if (mti->type != eModifierTypeType_OnlyDeform) { - const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md->prev->type); + const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md_prev->type); if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) { -BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); +BKE_report(reports, error_type, "Cannot move above a modifier requiring original data"); return false; } } - -BLI_listbase_swaplinks(>modifiers, md, md->prev); } else { -BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the start of the list"); +BKE_report(reports, error_type, "Cannot move modifier beyond the start of the list"); return false; } return true; } -bool ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) +bool ED_object_modifier_move_up(ReportList *reports, +eReportType error_type, +Object *ob, +Modifi
[Bf-blender-cvs] [a1280b682f7] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: a1280b682f7a524fe682e8e8a1e48ea797500ce5 Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBa1280b682f7a524fe682e8e8a1e48ea797500ce5 Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 2f5b70bb3da..39a40621455 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6839,6 +6839,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 4c45e1433ab..53ce28a057d 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3912,5 +3912,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index d2835639686..7afd4421341 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -580,6 +580,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 8c9587e7a9a..b0aea51e590 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) draw_ctx->object_pose != nullptr; const float wire_alpha = pd->overlay.bone_wire_alpha; - const bool use_wire_alpha = (wire_alpha < 1.0f); + const float wire_fade
[Bf-blender-cvs] [a55a21be865] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: a55a21be8651d817aeb7ba82d949b4f95d9a2048 Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBa55a21be8651d817aeb7ba82d949b4f95d9a2048 Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.cc M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 5a6eb9916e6..154e42b65b1 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -337,6 +337,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -347,6 +351,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 4e3bff3640a..47641d6006c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -238,20 +238,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [816e70e8e2d] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: 816e70e8e2d0ead9f52b1b73a017fc66f79f2bcd Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB816e70e8e2d0ead9f52b1b73a017fc66f79f2bcd Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [14ec00dc00a] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: 14ec00dc00a8df372474285359e1e026512469b8 Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB14ec00dc00a8df372474285359e1e026512469b8 Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 99b33840051..f2854440e2a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [92fb80d9315] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: 92fb80d93159a4ecbac2d7cba47d24fdbe09e851 Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB92fb80d93159a4ecbac2d7cba47d24fdbe09e851 Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d0b978b7adf..92bad9f9168 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index eff12af02d2..56a8fb14876 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 7aaeb41572b..171ec3ae7f5 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -36,6 +36,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [522a6d88610] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: 522a6d88610a6438757b1a6be43c2dbb2d678dca Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB522a6d88610a6438757b1a6be43c2dbb2d678dca Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index bb11ed80ac2..005dd34106e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6830,6 +6830,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index ddb9f157d18..9d82d9ad203 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3911,5 +3911,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2093c8a2331..3954187f0c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -563,6 +563,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 8c9587e7a9a..b0aea51e590 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) draw_ctx->object_pose != nullptr; const float wire_alpha = pd->overlay.bone_wire_alpha; - const bool use_wire_alpha = (wire_alpha < 1.0f); + const float wire_fade
[Bf-blender-cvs] [96d62a7daeb] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 96d62a7daeb6be994b1b61fac1b43f9f49b3aab4 Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB96d62a7daeb6be994b1b61fac1b43f9f49b3aab4 Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 1a0b33ca2b1..5f5f29a1b36 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -752,6 +752,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -773,71 +783,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [2da9aa44a67] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: 2da9aa44a6707bf7fc00e5038141d717c9070743 Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB2da9aa44a6707bf7fc00e5038141d717c9070743 Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f9bae39b016..c6e75a78091 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [59cfa73b180] temp-angavrilov: Python API: add a method for reordering modifiers.
Commit: 59cfa73b180b4327427f65f7b9b7184e161f7498 Author: Alexander Gavrilov Date: Tue Jan 10 18:25:58 2023 +0200 Branches: temp-angavrilov https://developer.blender.org/rB59cfa73b180b4327427f65f7b9b7184e161f7498 Python API: add a method for reordering modifiers. Add an `object.modifiers.move()` method, similar to the one for constraints and some other collections. Currently reordering modifiers requires using operators, which depend on context. The implementation is straightforward, except for the need to make the severity of errors reported by the underlying editor code into a parameter, so that the new Python API function reports any problems as Python exceptions. I also turn the negative index condition from an assert into an error. Differential Revision: https://developer.blender.org/D16966 === M source/blender/editors/include/ED_object.h M source/blender/editors/object/object_modifier.cc M source/blender/editors/space_outliner/outliner_dragdrop.cc M source/blender/makesrna/intern/rna_object.c === diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9e8d9636a29..23d6a4672a2 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -10,6 +10,7 @@ #include "BLI_compiler_attrs.h" #include "DNA_object_enums.h" #include "DNA_userdef_enums.h" +#include "DNA_windowmanager_types.h" #ifdef __cplusplus extern "C" { @@ -534,12 +535,15 @@ bool ED_object_modifier_remove(struct ReportList *reports, struct ModifierData *md); void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob); bool ED_object_modifier_move_down(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_up(struct ReportList *reports, +eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_to_index(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md, int index); diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 57d62b3a95b..1fb8aa05e37 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -415,7 +415,10 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob) DEG_relations_tag_update(bmain); } -bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) +bool ED_object_modifier_move_up(ReportList *reports, +eReportType error_type, +Object *ob, +ModifierData *md) { if (md->prev) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); @@ -424,7 +427,7 @@ bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *m const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md->prev->type); if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) { -BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); +BKE_report(reports, error_type, "Cannot move above a modifier requiring original data"); return false; } } @@ -432,14 +435,17 @@ bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *m BLI_listbase_swaplinks(>modifiers, md, md->prev); } else { -BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the start of the list"); +BKE_report(reports, error_type, "Cannot move modifier beyond the start of the list"); return false; } return true; } -bool ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) +bool ED_object_modifier_move_down(ReportList *reports, + eReportType error_type, + Object *ob, + ModifierData *md) { if (md->next) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); @@ -448,7 +454,7 @@ bool ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData const ModifierTypeInfo *nmti = BKE_modifier_get_i
[Bf-blender-cvs] [bd3964efe37] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: bd3964efe3767566760a22aeb67fd78a23ec0ee3 Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBbd3964efe3767566760a22aeb67fd78a23ec0ee3 Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.cc M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 4146a8ca51a..f2e30e523a4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -337,6 +337,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -347,6 +351,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 36d5dc7f68d..635897247c9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -238,20 +238,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [2e7b6441994] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: 2e7b64419941a78c535528c480b1ffcc458dc122 Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB2e7b64419941a78c535528c480b1ffcc458dc122 Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [884505dbb85] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: 884505dbb85ef286e847ebce9998cd1ae220c747 Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB884505dbb85ef286e847ebce9998cd1ae220c747 Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 99b33840051..f2854440e2a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [f4b8fdedd55] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: f4b8fdedd55e2a10d012c9807d014879fc4176df Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBf4b8fdedd55e2a10d012c9807d014879fc4176df Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6df9dc1e86d..673e68b2e95 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 9b3cabb6c79..6cae1003966 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 251b6e4d83d..d82d98777b8 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -37,6 +37,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ea1c31a2443] master: Fix T103074: flipped vertex group meaning in Multi-Modifier Armature.
Commit: ea1c31a24438442a4fa866d13af1563d76ffa3fc Author: Alexander Gavrilov Date: Thu Dec 15 23:37:14 2022 +0200 Branches: master https://developer.blender.org/rBea1c31a24438442a4fa866d13af1563d76ffa3fc Fix T103074: flipped vertex group meaning in Multi-Modifier Armature. For some reason the Armature modifier in the Multi-Modifier mode interpreted the vertex group in a way essentially opposite to the regular mode. Moreover, this depended not on the Multi-Modifier checkbox, but on whether the mode was actually active. This fixes the flip and adds versioning code to patch old files. One difficulty is that whether the Multi-Modifier flag is valid can be different between the viewport and render. The versioning code assumes any modifier enabled in either to be active. This change is not forward compatible, so min version is also bumped. Differential Revision: https://developer.blender.org/D16787 === M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenkernel/intern/armature_deform.c M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index c95c3a1a934..f5514fcc632 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 7 +#define BLENDER_FILE_SUBVERSION 8 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 4 +#define BLENDER_FILE_MIN_SUBVERSION 8 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 64a3937c191..973fdbd0c57 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ - float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ + float prevco_weight = 0.0f; /* weight for optional cached vertexcos */ if (use_quaternion) { memset(, 0, sizeof(DualQuat)); @@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, /* hackish: the blending factor can be used for blending with vert_coords_prev too */ if (vert_coords_prev) { - prevco_weight = armature_weight; + /* This weight specifies the contribution from the coordinates at the start of this + * modifier evaluation, while armature_weight is normally the opposite of that. */ + prevco_weight = 1.0f - armature_weight; armature_weight = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 6b4f374bf0e..ddb9f157d18 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3858,6 +3858,48 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 8)) { +const int CV_SCULPT_SELECTION_ENABLED = (1 << 1); +LISTBASE_FOREACH (Curves *, curves_id, >hair_curves) { + curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; +} +LISTBASE_FOREACH (Curves *, curves_id, >hair_curves) { + BKE_id_attribute_rename(_id->id, ".selection_point_float", ".selection", nullptr); + BKE_id_attribute_rename(_id->id, ".selection_curve_float", ".selection", nullptr); +} + +/* Toggle the Invert Vertex Group flag on Armature modifiers in some cases. */ +LISTBASE_FOREACH (Object *, ob, >objects) { + bool after_armature = false; + LISTBASE_FOREACH (ModifierData *, md, >modifiers) { +if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->multi) { +/* Toggle the invert vertex group flag on operational Multi Modifier entries. */ +if (after_armature && amd->defgrp_name[0]) { + amd->deformflag ^= ARM_DEF_INVERT_VGROUP; +} + } + else { +/* Disabled multi modifiers don't reset propagation, but non-mult
[Bf-blender-cvs] [033b58e23c1] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 033b58e23c1029b2fc2e1b4a7fd10468b8ce5bc3 Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB033b58e23c1029b2fc2e1b4a7fd10468b8ce5bc3 Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 8a7c89ac46d..3f1be16d6fc 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -776,6 +776,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -797,71 +807,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [503b799287d] temp-angavrilov: Fix T103074: flipped vertex group meaning in Multi-Modifier Armature.
Commit: 503b799287dccc62ade7c44a46d63d76b4786a89 Author: Alexander Gavrilov Date: Thu Dec 15 23:37:14 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB503b799287dccc62ade7c44a46d63d76b4786a89 Fix T103074: flipped vertex group meaning in Multi-Modifier Armature. For some reason the Armature modifier in the Multi-Modifier mode interpreted the vertex group in a way essentially opposite to the regular mode. Moreover, this depended not on the Multi-Modifier checkbox, but on whether the mode was actually active. This fixes the flip and adds versioning code to patch old files. One difficulty is that whether the Multi-Modifier flag is valid can be different between the viewport and render. The versioning code assumes any modifier enabled in either to be active. This change is not forward compatible, so min version is also bumped. Differential Revision: https://developer.blender.org/D16787 === M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenkernel/intern/armature_deform.c M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index c95c3a1a934..f5514fcc632 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 7 +#define BLENDER_FILE_SUBVERSION 8 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 4 +#define BLENDER_FILE_MIN_SUBVERSION 8 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 64a3937c191..973fdbd0c57 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ - float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ + float prevco_weight = 0.0f; /* weight for optional cached vertexcos */ if (use_quaternion) { memset(, 0, sizeof(DualQuat)); @@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, /* hackish: the blending factor can be used for blending with vert_coords_prev too */ if (vert_coords_prev) { - prevco_weight = armature_weight; + /* This weight specifies the contribution from the coordinates at the start of this + * modifier evaluation, while armature_weight is normally the opposite of that. */ + prevco_weight = 1.0f - armature_weight; armature_weight = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 73efe8fbcaa..368268e4cb7 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3845,6 +3845,38 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 8)) { +LISTBASE_FOREACH (Object *, ob, >objects) { + bool after_armature = false; + LISTBASE_FOREACH (ModifierData *, md, >modifiers) { +if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->multi) { +/* Toggle the invert vertex group flag on operational Multi Modifier entries. */ +if (after_armature && amd->defgrp_name[0]) { + amd->deformflag ^= ARM_DEF_INVERT_VGROUP; +} + } + else { +/* Disabled multi modifiers don't reset propagation, but non-multi ones do. */ +after_armature = false; + } + /* Multi Modifier is only valid and operational after an active Armature modifier. */ + if (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) { +after_armature = true; + } +} +else if (ELEM(md->type, eModifierType_Lattice, eModifierType_MeshDeform)) { + /* These modifiers will also allow a following Multi Modifier to work. */ + after_armature = (md->mode & (eModifierMode_Realtime |
[Bf-blender-cvs] [672872cf1de] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: 672872cf1de6e7784e50b0aad280168f0b51489b Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB672872cf1de6e7784e50b0aad280168f0b51489b Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3dad2a1a19a..7b04439823d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [7e8c0c63a01] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: 7e8c0c63a01c063aa3d1a29f620c08bfc5611382 Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB7e8c0c63a01c063aa3d1a29f620c08bfc5611382 Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 83066cb70bf..9fd6e25c3bc 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6831,6 +6831,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index dbd61b9c3e2..73efe8fbcaa 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3864,5 +3864,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) BKE_id_attribute_rename(_id->id, ".selection_point_float", ".selection", nullptr); BKE_id_attribute_rename(_id->id, ".selection_curve_float", ".selection", nullptr); } + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2093c8a2331..3954187f0c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -563,6 +563,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 7c333a71643..6f1a1bed2c5 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) d
[Bf-blender-cvs] [bb339ef2711] temp-angavrilov: Shrinkwrap: support smoothing the mesh after wrapping.
Commit: bb339ef2711889436218381d84c64e215547f590 Author: Alexander Gavrilov Date: Thu Sep 1 19:18:51 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBbb339ef2711889436218381d84c64e215547f590 Shrinkwrap: support smoothing the mesh after wrapping. Adds a smoothing post-processing option for the shrinkwrap modifier. On any other setting than 0 iterations, the algorithm adds the laplacian of the deltas to the base mesh to produce a smooth-looking deformed mesh -- this makes it possible to avoid losing detail on parts of the mesh that are not affected by the shrinkwrap displacement. Deltas that would otherwise lose magnitude as a result of smoothing are not updated to avoid further volume loss; this keeps the result much closer to the surface of the target while still adjusting other shrinkwrapped (and non-shrinkwrapped) vertexes to follow the smooth surface. Differential Revision: https://developer.blender.org/D6414 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/makesdna/DNA_modifier_types.h M source/blender/makesrna/intern/rna_modifier.c M source/blender/modifiers/intern/MOD_shrinkwrap.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index d196f044c58..8a7c89ac46d 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -63,6 +63,10 @@ struct ShrinkwrapCalcData { const float (*vert_normals)[3]; /* Vertices being shrink-wrapped. */ float (*vertexCos)[3]; + /* Cached vertex deltas. */ + float (*deltas)[3]; + /* Cached vertex weights */ + float *weights; int numVerts; const MDeformVert *dvert; /* Pointer to mdeform array */ @@ -326,6 +330,19 @@ void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh) mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); } +/** Output the computed vertex position either to the final coordinate or the delta array. */ +BLI_INLINE void shrinkwrap_save_result( +ShrinkwrapCalcData *calc, int i, float *co, float *result, float weight) +{ + if (calc->deltas) { +sub_v3_v3v3(calc->deltas[i], result, co); +mul_v3_fl(calc->deltas[i], weight); + } + else { +interp_v3_v3v3(co, co, result, weight); /* linear interpolation */ + } +} + /** * Shrink-wrap to the nearest vertex * @@ -354,6 +371,10 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -390,7 +411,7 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, copy_v3_v3(tmp_co, nearest->co); BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -517,6 +538,10 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { /* calc->vert contains verts from evaluated mesh. */ /* These coordinates are deformed by vertexCos only for normal projection @@ -607,7 +632,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, hit->co); } -interp_v3_v3v3(co, co, hit->co, weight); +shrinkwrap_save_result(calc, i, co, hit->co, weight); } } @@ -1115,6 +1140,10 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -1159,7 +1188,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat /* Convert the coordinates back to mesh coordinates */ BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ + +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -1359,6 +1389,137 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) 0, calc->numVerts, , shrinkwrap_calc_nearest_surface_point_cb_ex, ); } +static void shrinkwrap_smooth( +ShrinkwrapCalcData *calc, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) +{ + if (mesh == NULL) { +return; + } + + /* Number of neighboring vertices for the given
[Bf-blender-cvs] [5c856b0bd7f] temp-angavrilov: Armature: apply Y scale to B-Bone segments.
Commit: 5c856b0bd7f92b74bed9d1fb33bbf99e57ba95ab Author: Alexander Gavrilov Date: Tue Jun 15 13:52:23 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB5c856b0bd7f92b74bed9d1fb33bbf99e57ba95ab Armature: apply Y scale to B-Bone segments. This fixes a strange behavior where the segments were not actually scaled in the Y direction to match their actual length, thus producing gaps or overlap depending on the shape of the curve. For transformation the change should be very small if enough segments are used, but this will affect the results of the Copy Transforms and Armature constraints, so a backwards compatibility option is provided. Newly created bones default to the new behavior. === M release/scripts/startup/bl_ui/properties_data_bone.py M source/blender/blenkernel/BKE_armature.h M source/blender/blenkernel/intern/armature.c M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/makesdna/DNA_armature_types.h M source/blender/makesrna/intern/rna_armature.c === diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 14f6da83be2..d2fae3b71d7 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -162,6 +162,8 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): col.prop(bbone, "bbone_easeout", text="Out", text_ctxt=i18n_contexts.id_armature) col.prop(bone, "use_scale_easing") +topcol.prop(bone, "use_unscaled_segments") + col = topcol.column(align=True) col.prop(bone, "bbone_handle_type_start", text="Start Handle") diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index eff05e471aa..f9d4cf7a246 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -469,7 +469,7 @@ typedef struct BBoneSplineParameters { float length; /* Non-uniform scale correction. */ - bool do_scale; + bool do_scale, do_scale_segments; float scale[3]; /* Handle control bone data. */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e433c26cc54..89ca69510b8 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -944,6 +944,8 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan, param->segments = bone->segments; param->length = bone->length; + param->do_scale_segments = (bone->bbone_flag & BBONE_SCALE_SEGMENTS) != 0; + if (!rest) { float scale[3]; @@ -1309,6 +1311,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, const float axis[3], float roll, float scalex, + float scaley, float scalez, float result[4][4]) { @@ -1326,6 +1329,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, /* BBone scale... */ mul_v3_fl(result[0], scalex); + mul_v3_fl(result[1], scaley); mul_v3_fl(result[2], scalez); } @@ -1393,6 +1397,8 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, equalize_cubic_bezier( bezt_controls, MAX_BBONE_SUBDIV, param->segments, segment_scales, bezt_points); + const float scale_fac = param->segments / length; + /* Deformation uses N+1 matrices computed at points between the segments. */ if (for_deform) { /* Bezier derivatives. */ @@ -1405,6 +1411,32 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, sub_v3_v3v3(bezt_deriv2[i], bezt_deriv1[i + 1], bezt_deriv1[i]); } +/* Inner segment points. */ +float points[MAX_BBONE_SUBDIV][3], tangents[MAX_BBONE_SUBDIV][3]; + +copy_v3_v3(points[0], bezt_controls[0]); + +for (int a = 1; a < param->segments; a++) { + evaluate_cubic_bezier(bezt_controls, bezt_points[a], points[a], tangents[a]); +} + +/* Segment lengths. */ +float seg_length[MAX_BBONE_SUBDIV + 1]; + +if (param->do_scale_segments) { + for (int a = 1; a < param->segments; a++) { +seg_length[a] = len_v3v3(points[a - 1], points[a]) * scale_fac; + } + + seg_length[param->segments] = len_v3v3(points[param->segments - 1], bezt_controls[3]) * +scale_fac; +} +else { + for (int a = 1; a <= param->segments; a++) { +seg_length[a] = 1; + } +} + /* End points require special handling to fix zero
[Bf-blender-cvs] [05b1e13ad6b] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: 05b1e13ad6bdf0846e19b4786d1b477f6e6e1e4d Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB05b1e13ad6bdf0846e19b4786d1b477f6e6e1e4d Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.c M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 4146a8ca51a..f2e30e523a4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -337,6 +337,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -347,6 +351,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 36d5dc7f68d..635897247c9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -238,20 +238,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [c850daba6cb] temp-angavrilov: Temporary Hack: provide B-Bone scale versioning for files with old patch.
Commit: c850daba6cb7ec289c37e549f370b5518430456b Author: Alexander Gavrilov Date: Tue Jun 22 16:38:26 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBc850daba6cb7ec289c37e549f370b5518430456b Temporary Hack: provide B-Bone scale versioning for files with old patch. Run the versioning code for the conversion of bbone scale to an xyz vector if it has fields that correspond to the old version of the patch before that change requiring versioning. The actual Y (length) scale value from the old patch isn't versioned and will be lost, requiring manual fixing. === M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 38ecfaf41ea..dbd61b9c3e2 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -2140,7 +2140,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } /* Initialize length-wise scale B-Bone settings. */ -if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag")) { +if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag") || +DNA_struct_elem_find(fd->filesdna, "Bone", "float", "scale_in_len")) { /* Update armature data and pose channels. */ LISTBASE_FOREACH (bArmature *, arm, >armatures) { do_version_bones_bbone_len_scale(>bonebase); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ca0eb6bd071] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: ca0eb6bd071fb6a0b6aceef79ceaf5ac4ff30c63 Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBca0eb6bd071fb6a0b6aceef79ceaf5ac4ff30c63 Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6df9dc1e86d..673e68b2e95 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 9b3cabb6c79..6cae1003966 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 251b6e4d83d..d82d98777b8 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -37,6 +37,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5ad594dab90] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: 5ad594dab90e3d202e0ee48ee3c45ec7c66dd6a5 Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB5ad594dab90e3d202e0ee48ee3c45ec7c66dd6a5 Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 99b33840051..f2854440e2a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [a38c6a11b7e] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: a38c6a11b7ef48093b6d8f23e6318b5c22740473 Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBa38c6a11b7ef48093b6d8f23e6318b5c22740473 Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [2d763058ca1] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 2d763058ca1d3591e05a46524e98ed6ec9dee3f6 Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB2d763058ca1d3591e05a46524e98ed6ec9dee3f6 Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 8a7c89ac46d..3f1be16d6fc 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -776,6 +776,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -797,71 +807,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [067fff710dc] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: 067fff710dc15a84c58e00ca79c3b93b9503b13c Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB067fff710dc15a84c58e00ca79c3b93b9503b13c Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3dad2a1a19a..7b04439823d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [c7dae821c3a] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: c7dae821c3a369822f3012da0aab6c8ff9a8ad25 Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBc7dae821c3a369822f3012da0aab6c8ff9a8ad25 Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 83066cb70bf..9fd6e25c3bc 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6831,6 +6831,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index dbd61b9c3e2..73efe8fbcaa 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3864,5 +3864,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) BKE_id_attribute_rename(_id->id, ".selection_point_float", ".selection", nullptr); BKE_id_attribute_rename(_id->id, ".selection_curve_float", ".selection", nullptr); } + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2093c8a2331..3954187f0c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -563,6 +563,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 7c333a71643..6f1a1bed2c5 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) d
[Bf-blender-cvs] [f8b0e8a92a2] temp-angavrilov: Shrinkwrap: support smoothing the mesh after wrapping.
Commit: f8b0e8a92a2218ed1d3a87325e5b75bc7627fa4b Author: Alexander Gavrilov Date: Thu Sep 1 19:18:51 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBf8b0e8a92a2218ed1d3a87325e5b75bc7627fa4b Shrinkwrap: support smoothing the mesh after wrapping. Adds a smoothing post-processing option for the shrinkwrap modifier. On any other setting than 0 iterations, the algorithm adds the laplacian of the deltas to the base mesh to produce a smooth-looking deformed mesh -- this makes it possible to avoid losing detail on parts of the mesh that are not affected by the shrinkwrap displacement. Deltas that would otherwise lose magnitude as a result of smoothing are not updated to avoid further volume loss; this keeps the result much closer to the surface of the target while still adjusting other shrinkwrapped (and non-shrinkwrapped) vertexes to follow the smooth surface. Differential Revision: https://developer.blender.org/D6414 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/makesdna/DNA_modifier_types.h M source/blender/makesrna/intern/rna_modifier.c M source/blender/modifiers/intern/MOD_shrinkwrap.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index d196f044c58..8a7c89ac46d 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -63,6 +63,10 @@ struct ShrinkwrapCalcData { const float (*vert_normals)[3]; /* Vertices being shrink-wrapped. */ float (*vertexCos)[3]; + /* Cached vertex deltas. */ + float (*deltas)[3]; + /* Cached vertex weights */ + float *weights; int numVerts; const MDeformVert *dvert; /* Pointer to mdeform array */ @@ -326,6 +330,19 @@ void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh) mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); } +/** Output the computed vertex position either to the final coordinate or the delta array. */ +BLI_INLINE void shrinkwrap_save_result( +ShrinkwrapCalcData *calc, int i, float *co, float *result, float weight) +{ + if (calc->deltas) { +sub_v3_v3v3(calc->deltas[i], result, co); +mul_v3_fl(calc->deltas[i], weight); + } + else { +interp_v3_v3v3(co, co, result, weight); /* linear interpolation */ + } +} + /** * Shrink-wrap to the nearest vertex * @@ -354,6 +371,10 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -390,7 +411,7 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, copy_v3_v3(tmp_co, nearest->co); BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -517,6 +538,10 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { /* calc->vert contains verts from evaluated mesh. */ /* These coordinates are deformed by vertexCos only for normal projection @@ -607,7 +632,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, hit->co); } -interp_v3_v3v3(co, co, hit->co, weight); +shrinkwrap_save_result(calc, i, co, hit->co, weight); } } @@ -1115,6 +1140,10 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -1159,7 +1188,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat /* Convert the coordinates back to mesh coordinates */ BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ + +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -1359,6 +1389,137 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) 0, calc->numVerts, , shrinkwrap_calc_nearest_surface_point_cb_ex, ); } +static void shrinkwrap_smooth( +ShrinkwrapCalcData *calc, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) +{ + if (mesh == NULL) { +return; + } + + /* Number of neighboring vertices for the given
[Bf-blender-cvs] [55c4ad77f36] temp-angavrilov: Armature: apply Y scale to B-Bone segments.
Commit: 55c4ad77f36f7b9e261e0fbae3e9169723e0719c Author: Alexander Gavrilov Date: Tue Jun 15 13:52:23 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB55c4ad77f36f7b9e261e0fbae3e9169723e0719c Armature: apply Y scale to B-Bone segments. This fixes a strange behavior where the segments were not actually scaled in the Y direction to match their actual length, thus producing gaps or overlap depending on the shape of the curve. For transformation the change should be very small if enough segments are used, but this will affect the results of the Copy Transforms and Armature constraints, so a backwards compatibility option is provided. Newly created bones default to the new behavior. === M release/scripts/startup/bl_ui/properties_data_bone.py M source/blender/blenkernel/BKE_armature.h M source/blender/blenkernel/intern/armature.c M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/makesdna/DNA_armature_types.h M source/blender/makesrna/intern/rna_armature.c === diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 14f6da83be2..d2fae3b71d7 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -162,6 +162,8 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): col.prop(bbone, "bbone_easeout", text="Out", text_ctxt=i18n_contexts.id_armature) col.prop(bone, "use_scale_easing") +topcol.prop(bone, "use_unscaled_segments") + col = topcol.column(align=True) col.prop(bone, "bbone_handle_type_start", text="Start Handle") diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index eff05e471aa..f9d4cf7a246 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -469,7 +469,7 @@ typedef struct BBoneSplineParameters { float length; /* Non-uniform scale correction. */ - bool do_scale; + bool do_scale, do_scale_segments; float scale[3]; /* Handle control bone data. */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e433c26cc54..89ca69510b8 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -944,6 +944,8 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan, param->segments = bone->segments; param->length = bone->length; + param->do_scale_segments = (bone->bbone_flag & BBONE_SCALE_SEGMENTS) != 0; + if (!rest) { float scale[3]; @@ -1309,6 +1311,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, const float axis[3], float roll, float scalex, + float scaley, float scalez, float result[4][4]) { @@ -1326,6 +1329,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, /* BBone scale... */ mul_v3_fl(result[0], scalex); + mul_v3_fl(result[1], scaley); mul_v3_fl(result[2], scalez); } @@ -1393,6 +1397,8 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, equalize_cubic_bezier( bezt_controls, MAX_BBONE_SUBDIV, param->segments, segment_scales, bezt_points); + const float scale_fac = param->segments / length; + /* Deformation uses N+1 matrices computed at points between the segments. */ if (for_deform) { /* Bezier derivatives. */ @@ -1405,6 +1411,32 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, sub_v3_v3v3(bezt_deriv2[i], bezt_deriv1[i + 1], bezt_deriv1[i]); } +/* Inner segment points. */ +float points[MAX_BBONE_SUBDIV][3], tangents[MAX_BBONE_SUBDIV][3]; + +copy_v3_v3(points[0], bezt_controls[0]); + +for (int a = 1; a < param->segments; a++) { + evaluate_cubic_bezier(bezt_controls, bezt_points[a], points[a], tangents[a]); +} + +/* Segment lengths. */ +float seg_length[MAX_BBONE_SUBDIV + 1]; + +if (param->do_scale_segments) { + for (int a = 1; a < param->segments; a++) { +seg_length[a] = len_v3v3(points[a - 1], points[a]) * scale_fac; + } + + seg_length[param->segments] = len_v3v3(points[param->segments - 1], bezt_controls[3]) * +scale_fac; +} +else { + for (int a = 1; a <= param->segments; a++) { +seg_length[a] = 1; + } +} + /* End points require special handling to fix zero
[Bf-blender-cvs] [9afd7a50996] temp-angavrilov: Fix T103074: flipped vertex group meaning in Multi-Modifier Armature.
Commit: 9afd7a5099695a3325b0eff75dd381b0030c1a1e Author: Alexander Gavrilov Date: Thu Dec 15 23:37:14 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB9afd7a5099695a3325b0eff75dd381b0030c1a1e Fix T103074: flipped vertex group meaning in Multi-Modifier Armature. For some reason the Armature modifier in the Multi-Modifier mode interpreted the vertex group in a way essentially opposite to the regular mode. Moreover, this depended not on the Multi-Modifier checkbox, but on whether the mode was actually active. This fixes the flip and adds versioning code to patch old files. One difficulty is that whether the Multi-Modifier flag is valid can be different between the viewport and render. The versioning code assumes any modifier enabled in either to be active. This change is not forward compatible, so min version is also bumped. Differential Revision: https://developer.blender.org/D16787 === M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenkernel/intern/armature_deform.c M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index c95c3a1a934..f5514fcc632 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 7 +#define BLENDER_FILE_SUBVERSION 8 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 4 +#define BLENDER_FILE_MIN_SUBVERSION 8 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 64a3937c191..973fdbd0c57 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ - float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ + float prevco_weight = 0.0f; /* weight for optional cached vertexcos */ if (use_quaternion) { memset(, 0, sizeof(DualQuat)); @@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, /* hackish: the blending factor can be used for blending with vert_coords_prev too */ if (vert_coords_prev) { - prevco_weight = armature_weight; + /* This weight specifies the contribution from the coordinates at the start of this + * modifier evaluation, while armature_weight is normally the opposite of that. */ + prevco_weight = 1.0f - armature_weight; armature_weight = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 73efe8fbcaa..368268e4cb7 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3845,6 +3845,38 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 8)) { +LISTBASE_FOREACH (Object *, ob, >objects) { + bool after_armature = false; + LISTBASE_FOREACH (ModifierData *, md, >modifiers) { +if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->multi) { +/* Toggle the invert vertex group flag on operational Multi Modifier entries. */ +if (after_armature && amd->defgrp_name[0]) { + amd->deformflag ^= ARM_DEF_INVERT_VGROUP; +} + } + else { +/* Disabled multi modifiers don't reset propagation, but non-multi ones do. */ +after_armature = false; + } + /* Multi Modifier is only valid and operational after an active Armature modifier. */ + if (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) { +after_armature = true; + } +} +else if (ELEM(md->type, eModifierType_Lattice, eModifierType_MeshDeform)) { + /* These modifiers will also allow a following Multi Modifier to work. */ + after_armature = (md->mode & (eModifierMode_Realtime |
[Bf-blender-cvs] [9839922f322] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: 9839922f32231c97fbb6e4fe827ee65212630e26 Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB9839922f32231c97fbb6e4fe827ee65212630e26 Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.c M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 4146a8ca51a..f2e30e523a4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -337,6 +337,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -347,6 +351,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 36d5dc7f68d..635897247c9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -238,20 +238,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [cdcd79e02d9] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: cdcd79e02d9659375c040937e621eeeb1ac2e682 Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBcdcd79e02d9659375c040937e621eeeb1ac2e682 Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [094f6057b11] temp-angavrilov: Temporary Hack: provide B-Bone scale versioning for files with old patch.
Commit: 094f6057b11b37e05974e3247f9b941de2d9ddab Author: Alexander Gavrilov Date: Tue Jun 22 16:38:26 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB094f6057b11b37e05974e3247f9b941de2d9ddab Temporary Hack: provide B-Bone scale versioning for files with old patch. Run the versioning code for the conversion of bbone scale to an xyz vector if it has fields that correspond to the old version of the patch before that change requiring versioning. The actual Y (length) scale value from the old patch isn't versioned and will be lost, requiring manual fixing. === M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 38ecfaf41ea..dbd61b9c3e2 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -2140,7 +2140,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } /* Initialize length-wise scale B-Bone settings. */ -if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag")) { +if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag") || +DNA_struct_elem_find(fd->filesdna, "Bone", "float", "scale_in_len")) { /* Update armature data and pose channels. */ LISTBASE_FOREACH (bArmature *, arm, >armatures) { do_version_bones_bbone_len_scale(>bonebase); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [448629cb299] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: 448629cb299aa80757191d7169fc3be22ba4612b Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB448629cb299aa80757191d7169fc3be22ba4612b Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 99b33840051..f2854440e2a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [b37940a19ca] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: b37940a19ca1bdcca35552c1bb862ca9e06f8c04 Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBb37940a19ca1bdcca35552c1bb862ca9e06f8c04 Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6df9dc1e86d..673e68b2e95 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 9b3cabb6c79..6cae1003966 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 251b6e4d83d..d82d98777b8 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -37,6 +37,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [626f791f366] temp-angavrilov: Shrinkwrap: support smoothing the mesh after wrapping.
Commit: 626f791f366e9a71018bd38074ce189e68b5de73 Author: Alexander Gavrilov Date: Thu Sep 1 19:18:51 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB626f791f366e9a71018bd38074ce189e68b5de73 Shrinkwrap: support smoothing the mesh after wrapping. Adds a smoothing post-processing option for the shrinkwrap modifier. On any other setting than 0 iterations, the algorithm adds the laplacian of the deltas to the base mesh to produce a smooth-looking deformed mesh -- this makes it possible to avoid losing detail on parts of the mesh that are not affected by the shrinkwrap displacement. Deltas that would otherwise lose magnitude as a result of smoothing are not updated to avoid further volume loss; this keeps the result much closer to the surface of the target while still adjusting other shrinkwrapped (and non-shrinkwrapped) vertexes to follow the smooth surface. Differential Revision: https://developer.blender.org/D6414 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/makesdna/DNA_modifier_types.h M source/blender/makesrna/intern/rna_modifier.c M source/blender/modifiers/intern/MOD_shrinkwrap.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index d196f044c58..8a7c89ac46d 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -63,6 +63,10 @@ struct ShrinkwrapCalcData { const float (*vert_normals)[3]; /* Vertices being shrink-wrapped. */ float (*vertexCos)[3]; + /* Cached vertex deltas. */ + float (*deltas)[3]; + /* Cached vertex weights */ + float *weights; int numVerts; const MDeformVert *dvert; /* Pointer to mdeform array */ @@ -326,6 +330,19 @@ void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh) mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); } +/** Output the computed vertex position either to the final coordinate or the delta array. */ +BLI_INLINE void shrinkwrap_save_result( +ShrinkwrapCalcData *calc, int i, float *co, float *result, float weight) +{ + if (calc->deltas) { +sub_v3_v3v3(calc->deltas[i], result, co); +mul_v3_fl(calc->deltas[i], weight); + } + else { +interp_v3_v3v3(co, co, result, weight); /* linear interpolation */ + } +} + /** * Shrink-wrap to the nearest vertex * @@ -354,6 +371,10 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -390,7 +411,7 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, copy_v3_v3(tmp_co, nearest->co); BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -517,6 +538,10 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { /* calc->vert contains verts from evaluated mesh. */ /* These coordinates are deformed by vertexCos only for normal projection @@ -607,7 +632,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, hit->co); } -interp_v3_v3v3(co, co, hit->co, weight); +shrinkwrap_save_result(calc, i, co, hit->co, weight); } } @@ -1115,6 +1140,10 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -1159,7 +1188,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat /* Convert the coordinates back to mesh coordinates */ BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ + +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -1359,6 +1389,137 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) 0, calc->numVerts, , shrinkwrap_calc_nearest_surface_point_cb_ex, ); } +static void shrinkwrap_smooth( +ShrinkwrapCalcData *calc, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) +{ + if (mesh == NULL) { +return; + } + + /* Number of neighboring vertices for the given
[Bf-blender-cvs] [08ac1d41935] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 08ac1d41935b2e446a83fd237c1b939abf3af8fa Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB08ac1d41935b2e446a83fd237c1b939abf3af8fa Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 8a7c89ac46d..3f1be16d6fc 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -776,6 +776,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -797,71 +807,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [b99af032c64] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: b99af032c6459adbe0acf45f5136fabb9fd60c41 Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBb99af032c6459adbe0acf45f5136fabb9fd60c41 Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3dad2a1a19a..7b04439823d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [d8743dac597] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: d8743dac597a6af59e7443930af58e05bf4fdd0d Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBd8743dac597a6af59e7443930af58e05bf4fdd0d Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 83066cb70bf..9fd6e25c3bc 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6831,6 +6831,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index dbd61b9c3e2..73efe8fbcaa 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3864,5 +3864,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) BKE_id_attribute_rename(_id->id, ".selection_point_float", ".selection", nullptr); BKE_id_attribute_rename(_id->id, ".selection_curve_float", ".selection", nullptr); } + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2093c8a2331..3954187f0c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -563,6 +563,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 7c333a71643..6f1a1bed2c5 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) d
[Bf-blender-cvs] [02281951d0f] temp-angavrilov: Fix T103074: flipped vertex group meaning in Multi-Modifier Armature.
Commit: 02281951d0fbda1231401cd38d7a8164b2213680 Author: Alexander Gavrilov Date: Thu Dec 15 23:37:14 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB02281951d0fbda1231401cd38d7a8164b2213680 Fix T103074: flipped vertex group meaning in Multi-Modifier Armature. For some reason the Armature modifier in the Multi-Modifier mode interpreted the vertex group in a way essentially opposite to the regular mode. Moreover, this depended not on the Multi-Modifier checkbox, but on whether the mode was actually active. This fixes the flip and adds versioning code to patch old files. One difficulty is that whether the Multi-Modifier flag is valid can be different between the viewport and render. The versioning code assumes any modifier enabled in either to be active. This change is not forward compatible, so min version is also bumped. Differential Revision: https://developer.blender.org/D16787 === M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenkernel/intern/armature_deform.c M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index c95c3a1a934..f5514fcc632 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 7 +#define BLENDER_FILE_SUBVERSION 8 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 4 +#define BLENDER_FILE_MIN_SUBVERSION 8 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 64a3937c191..973fdbd0c57 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ - float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ + float prevco_weight = 0.0f; /* weight for optional cached vertexcos */ if (use_quaternion) { memset(, 0, sizeof(DualQuat)); @@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, /* hackish: the blending factor can be used for blending with vert_coords_prev too */ if (vert_coords_prev) { - prevco_weight = armature_weight; + /* This weight specifies the contribution from the coordinates at the start of this + * modifier evaluation, while armature_weight is normally the opposite of that. */ + prevco_weight = 1.0f - armature_weight; armature_weight = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 73efe8fbcaa..368268e4cb7 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3845,6 +3845,38 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 8)) { +LISTBASE_FOREACH (Object *, ob, >objects) { + bool after_armature = false; + LISTBASE_FOREACH (ModifierData *, md, >modifiers) { +if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->multi) { +/* Toggle the invert vertex group flag on operational Multi Modifier entries. */ +if (after_armature && amd->defgrp_name[0]) { + amd->deformflag ^= ARM_DEF_INVERT_VGROUP; +} + } + else { +/* Disabled multi modifiers don't reset propagation, but non-multi ones do. */ +after_armature = false; + } + /* Multi Modifier is only valid and operational after an active Armature modifier. */ + if (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) { +after_armature = true; + } +} +else if (ELEM(md->type, eModifierType_Lattice, eModifierType_MeshDeform)) { + /* These modifiers will also allow a following Multi Modifier to work. */ + after_armature = (md->mode & (eModifierMode_Realtime |
[Bf-blender-cvs] [8de65bac729] temp-angavrilov: Armature: apply Y scale to B-Bone segments.
Commit: 8de65bac729dd8c01507ca07b5c0225bf92bc646 Author: Alexander Gavrilov Date: Tue Jun 15 13:52:23 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB8de65bac729dd8c01507ca07b5c0225bf92bc646 Armature: apply Y scale to B-Bone segments. This fixes a strange behavior where the segments were not actually scaled in the Y direction to match their actual length, thus producing gaps or overlap depending on the shape of the curve. For transformation the change should be very small if enough segments are used, but this will affect the results of the Copy Transforms and Armature constraints, so a backwards compatibility option is provided. Newly created bones default to the new behavior. === M release/scripts/startup/bl_ui/properties_data_bone.py M source/blender/blenkernel/BKE_armature.h M source/blender/blenkernel/intern/armature.c M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/makesdna/DNA_armature_types.h M source/blender/makesrna/intern/rna_armature.c === diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 14f6da83be2..d2fae3b71d7 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -162,6 +162,8 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): col.prop(bbone, "bbone_easeout", text="Out", text_ctxt=i18n_contexts.id_armature) col.prop(bone, "use_scale_easing") +topcol.prop(bone, "use_unscaled_segments") + col = topcol.column(align=True) col.prop(bone, "bbone_handle_type_start", text="Start Handle") diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index eff05e471aa..f9d4cf7a246 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -469,7 +469,7 @@ typedef struct BBoneSplineParameters { float length; /* Non-uniform scale correction. */ - bool do_scale; + bool do_scale, do_scale_segments; float scale[3]; /* Handle control bone data. */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e433c26cc54..89ca69510b8 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -944,6 +944,8 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan, param->segments = bone->segments; param->length = bone->length; + param->do_scale_segments = (bone->bbone_flag & BBONE_SCALE_SEGMENTS) != 0; + if (!rest) { float scale[3]; @@ -1309,6 +1311,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, const float axis[3], float roll, float scalex, + float scaley, float scalez, float result[4][4]) { @@ -1326,6 +1329,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, /* BBone scale... */ mul_v3_fl(result[0], scalex); + mul_v3_fl(result[1], scaley); mul_v3_fl(result[2], scalez); } @@ -1393,6 +1397,8 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, equalize_cubic_bezier( bezt_controls, MAX_BBONE_SUBDIV, param->segments, segment_scales, bezt_points); + const float scale_fac = param->segments / length; + /* Deformation uses N+1 matrices computed at points between the segments. */ if (for_deform) { /* Bezier derivatives. */ @@ -1405,6 +1411,32 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, sub_v3_v3v3(bezt_deriv2[i], bezt_deriv1[i + 1], bezt_deriv1[i]); } +/* Inner segment points. */ +float points[MAX_BBONE_SUBDIV][3], tangents[MAX_BBONE_SUBDIV][3]; + +copy_v3_v3(points[0], bezt_controls[0]); + +for (int a = 1; a < param->segments; a++) { + evaluate_cubic_bezier(bezt_controls, bezt_points[a], points[a], tangents[a]); +} + +/* Segment lengths. */ +float seg_length[MAX_BBONE_SUBDIV + 1]; + +if (param->do_scale_segments) { + for (int a = 1; a < param->segments; a++) { +seg_length[a] = len_v3v3(points[a - 1], points[a]) * scale_fac; + } + + seg_length[param->segments] = len_v3v3(points[param->segments - 1], bezt_controls[3]) * +scale_fac; +} +else { + for (int a = 1; a <= param->segments; a++) { +seg_length[a] = 1; + } +} + /* End points require special handling to fix zero
[Bf-blender-cvs] [f3a51d99c22] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: f3a51d99c2225852459d27b672d1b54f52d8ad55 Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBf3a51d99c2225852459d27b672d1b54f52d8ad55 Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.c M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 4146a8ca51a..f2e30e523a4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -337,6 +337,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -347,6 +351,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 36d5dc7f68d..635897247c9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -238,20 +238,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [ea9ea63c522] temp-angavrilov: Temporary Hack: provide B-Bone scale versioning for files with old patch.
Commit: ea9ea63c5227e0cc168119530d61a2175d1d73e8 Author: Alexander Gavrilov Date: Tue Jun 22 16:38:26 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBea9ea63c5227e0cc168119530d61a2175d1d73e8 Temporary Hack: provide B-Bone scale versioning for files with old patch. Run the versioning code for the conversion of bbone scale to an xyz vector if it has fields that correspond to the old version of the patch before that change requiring versioning. The actual Y (length) scale value from the old patch isn't versioned and will be lost, requiring manual fixing. === M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 38ecfaf41ea..dbd61b9c3e2 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -2140,7 +2140,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } /* Initialize length-wise scale B-Bone settings. */ -if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag")) { +if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag") || +DNA_struct_elem_find(fd->filesdna, "Bone", "float", "scale_in_len")) { /* Update armature data and pose channels. */ LISTBASE_FOREACH (bArmature *, arm, >armatures) { do_version_bones_bbone_len_scale(>bonebase); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [b451c7096d0] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: b451c7096d03ad86aba1dbb6de0b6b40aa1623d3 Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBb451c7096d03ad86aba1dbb6de0b6b40aa1623d3 Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2032,6 +2032,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [a52d1912c96] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: a52d1912c9617bf2f07dd56754bd14ee7abe3291 Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBa52d1912c9617bf2f07dd56754bd14ee7abe3291 Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 99b33840051..f2854440e2a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [ecb3af5a015] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: ecb3af5a01518ce186489b11c4cd4836a8d98f80 Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBecb3af5a01518ce186489b11c4cd4836a8d98f80 Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6df9dc1e86d..673e68b2e95 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 9b3cabb6c79..6cae1003966 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 251b6e4d83d..d82d98777b8 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -37,6 +37,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [a3ac91da27d] master: Cloth: share self and object collision BVH trees when possible.
Commit: a3ac91da27dd80a98a1c4674c52170e84bff83a3 Author: Alexander Gavrilov Date: Wed Dec 28 23:39:36 2022 +0200 Branches: master https://developer.blender.org/rBa3ac91da27dd80a98a1c4674c52170e84bff83a3 Cloth: share self and object collision BVH trees when possible. Both cloth object collision and self collision use a BVH tree representing the current cloth shape. The only difference between them is the epsilon threshold value. If these values are the same, it is possible to use the same tree for both uses, thus easily reducing the overhead in the case when both collision modes are used by the same cloth object. Differential Revision: https://developer.blender.org/D16914 === M source/blender/blenkernel/BKE_cloth.h M source/blender/blenkernel/intern/cloth.cc M source/blender/blenkernel/intern/collision.c === diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8185e1883a9..d26a96bea21 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -72,7 +72,7 @@ typedef struct Cloth { unsigned char pad2; short pad3; struct BVHTree *bvhtree; /* collision tree for this cloth object */ - struct BVHTree *bvhselftree; /* collision tree for this cloth object */ + struct BVHTree *bvhselftree; /* collision tree for this cloth object (may be same as bvhtree) */ struct MVertTri *tri; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ struct EdgeSet *edgeset;/* used for selfcollisions */ diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index 4f28bf5157c..fe9117b4713 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -461,7 +461,7 @@ void cloth_free_modifier(ClothModifierData *clmd) BLI_bvhtree_free(cloth->bvhtree); } -if (cloth->bvhselftree) { +if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) { BLI_bvhtree_free(cloth->bvhselftree); } @@ -538,7 +538,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd) BLI_bvhtree_free(cloth->bvhtree); } -if (cloth->bvhselftree) { +if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) { BLI_bvhtree_free(cloth->bvhselftree); } @@ -820,7 +820,14 @@ static bool cloth_from_object( } clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon); - clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon); + + if (compare_ff(clmd->coll_parms->selfepsilon, clmd->coll_parms->epsilon, 1e-6f)) { +/* Share the BVH tree if the epsilon is the same. */ +clmd->clothObject->bvhselftree = clmd->clothObject->bvhtree; + } + else { +clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon); + } return true; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index bf814b7c595..cf0af615b6f 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1559,6 +1559,7 @@ int cloth_bvh_collision( BVHTreeOverlap **overlap_obj = NULL; uint coll_count_self = 0; BVHTreeOverlap *overlap_self = NULL; + bool bvh_updated = false; if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh == NULL) { return 0; @@ -1569,6 +1570,7 @@ int cloth_bvh_collision( if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { bvhtree_update_from_cloth(clmd, false, false); +bvh_updated = true; /* Enable self collision if this is a hair sim */ const bool is_hair = (clmd->hairdata != NULL); @@ -1605,7 +1607,9 @@ int cloth_bvh_collision( } if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { -bvhtree_update_from_cloth(clmd, false, true); +if (cloth->bvhselftree != cloth->bvhtree || !bvh_updated) { + bvhtree_update_from_cloth(clmd, false, true); +} overlap_self = BLI_bvhtree_overlap_self( cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [e1df731c91b] master: Cloth: precompute barycentric coordinates for collision points.
Commit: e1df731c91bc7b9b3349a87c4fcf18bc2f29d668 Author: Alexander Gavrilov Date: Fri Jan 6 13:48:36 2023 +0200 Branches: master https://developer.blender.org/rBe1df731c91bc7b9b3349a87c4fcf18bc2f29d668 Cloth: precompute barycentric coordinates for collision points. Profiling shows that this computation consumes a noticeable amount of time, so it is worth moving it to an earlier part of the code that is executed less frequently and is multithreaded. Differential Revision: https://developer.blender.org/D16933 === M source/blender/blenkernel/BKE_collision.h M source/blender/blenkernel/intern/collision.c === diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index c390d0a8802..d36758c9c4d 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -55,6 +55,8 @@ typedef struct CollPair { #else int ap1, ap2, ap3, bp1, bp2, bp3; #endif + /* Barycentric weights of the collision point. */ + float aw1, aw2, aw3, bw1, bw2, bw3; int pointsb[4]; } CollPair; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index cf0af615b6f..095666e7eac 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -670,7 +670,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd, const bool is_hair = (clmd->hairdata != NULL); for (int i = 0; i < collision_count; i++, collpair++) { float i1[3], i2[3], i3[3]; -float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; zero_v3(i1); zero_v3(i2); @@ -682,23 +681,13 @@ static int cloth_collision_response_static(ClothModifierData *clmd, } /* Compute barycentric coordinates and relative "velocity" for both collision points. */ -if (is_hair) { - w2 = line_point_factor_v3( - collpair->pa, cloth->verts[collpair->ap1].tx, cloth->verts[collpair->ap2].tx); - - w1 = 1.0f - w2; +float w1 = collpair->aw1, w2 = collpair->aw2, w3 = collpair->aw3; +float u1 = collpair->bw1, u2 = collpair->bw2, u3 = collpair->bw3; +if (is_hair) { interp_v3_v3v3(v1, cloth->verts[collpair->ap1].tv, cloth->verts[collpair->ap2].tv, w2); } else { - collision_compute_barycentric(collpair->pa, -cloth->verts[collpair->ap1].tx, -cloth->verts[collpair->ap2].tx, -cloth->verts[collpair->ap3].tx, -, -, -); - collision_interpolateOnTriangle(v1, cloth->verts[collpair->ap1].tv, cloth->verts[collpair->ap2].tv, @@ -708,14 +697,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd, w3); } -collision_compute_barycentric(collpair->pb, - collmd->current_xnew[collpair->bp1].co, - collmd->current_xnew[collpair->bp2].co, - collmd->current_xnew[collpair->bp3].co, - , - , - ); - collision_interpolateOnTriangle(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, @@ -834,7 +815,6 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd, for (int i = 0; i < collision_count; i++, collpair++) { float ia[3][3] = {{0.0f}}; float ib[3][3] = {{0.0f}}; -float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; /* Only handle static collisions here. */ @@ -842,22 +822,9 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd, continue; } -/* Compute barycentric coordinates for both collision points. */ -collision_compute_barycentric(collpair->pa, - cloth->verts[collpair->ap1].tx, - cloth->verts[collpair->ap2].tx, - cloth->verts[collpair->ap3].tx, - , - , - ); - -collision_compute_barycentric(collpair->pb, - cloth->
[Bf-blender-cvs] [4fb0eb3a6e8] master: Minor fixes after introducing special BVH traversal for self-collision.
Commit: 4fb0eb3a6e86af03724c3f31d5bbdcca0daba524 Author: Alexander Gavrilov Date: Fri Jan 6 02:34:39 2023 +0200 Branches: master https://developer.blender.org/rB4fb0eb3a6e86af03724c3f31d5bbdcca0daba524 Minor fixes after introducing special BVH traversal for self-collision. - Add parentheses to suppress an assertion on some compilers. - It turns out cloth self-collision math is not precisely symmetric, so sort the triangle index pair to restore behavior exactly identical to the version before the new traversal. Follow up to rB0796210c8df32 === M source/blender/blenkernel/intern/collision.c M source/blender/blenlib/intern/BLI_kdopbvh.c === diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index cd34ae29efb..bf814b7c595 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1115,8 +1115,15 @@ static void cloth_selfcollision(void *__restrict userdata, float epsilon = clmd->coll_parms->selfepsilon; float pa[3], pb[3], vect[3]; - tri_a = >clothObject->tri[data->overlap[index].indexA]; - tri_b = >clothObject->tri[data->overlap[index].indexB]; + /* Collision math is currently not symmetric, so ensure a stable order for each pair. */ + int indexA = data->overlap[index].indexA, indexB = data->overlap[index].indexB; + + if (indexA > indexB) { +SWAP(int, indexA, indexB); + } + + tri_a = >clothObject->tri[indexA]; + tri_b = >clothObject->tri[indexB]; BLI_assert(cloth_bvh_selfcollision_is_active(clmd, clmd->clothObject, tri_a, tri_b)); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 174a53be6da..4e958209f78 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1335,7 +1335,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( /* 'RETURN_PAIRS' was not implemented without 'max_interactions'. */ BLI_assert(overlap_pairs || max_interactions); /* Self-overlap does not support max interactions (it's not symmetrical). */ - BLI_assert(!use_self || tree1 == tree2 && !max_interactions); + BLI_assert(!use_self || (tree1 == tree2 && !max_interactions)); const int root_node_len = BLI_bvhtree_overlap_thread_num(tree1); const int thread_num = use_threading ? root_node_len : 1; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [0796210c8df] master: BVH: implement an optimized self-overlap traversal.
Commit: 0796210c8df32fedd8854ad828159d19cc530458 Author: Alexander Gavrilov Date: Wed Dec 28 22:19:36 2022 +0200 Branches: master https://developer.blender.org/rB0796210c8df32fedd8854ad828159d19cc530458 BVH: implement an optimized self-overlap traversal. Previously cloth self-collision and other code that wants self-overlap data was using an ordinary BVH overlap utility function. This works, but is suboptimal because it fails to take advantage of the fact that it is comparing two identical trees. The standard traversal for self-collision essentially devolves into enumerating all elements of the tree, and then matching them to the tree starting at the root. However, the tree itself naturally partitions the space, so overlapping elements are likely to be mostly placed nearby in the tree structure as well. Instead, self-overlap can be computed by recursively computing ordinary overlap between siblings within each subtree. This only considers each pair of leaves once, and provides significantly better locality. It also avoids outputting every overlap pair twice in different order. Differential Revision: https://developer.blender.org/D16915 === M source/blender/blenkernel/intern/collision.c M source/blender/blenlib/BLI_kdopbvh.h M source/blender/blenlib/intern/BLI_kdopbvh.c M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc M source/blender/editors/uvedit/uvedit_select.c === diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 2acdc6543b5..cd34ae29efb 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1521,8 +1521,9 @@ static bool cloth_bvh_obj_overlap_cb(void *userdata, static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { - /* No need for equal combinations (eg. (0,1) & (1,0)). */ - if (index_a < index_b) { + /* This shouldn't happen, but just in case. Note that equal combinations + * (eg. (0,1) & (1,0)) would be filtered out by BLI_bvhtree_overlap_self. */ + if (index_a != index_b) { ClothModifierData *clmd = (ClothModifierData *)userdata; struct Cloth *clothObject = clmd->clothObject; const MVertTri *tri_a, *tri_b; @@ -1599,8 +1600,8 @@ int cloth_bvh_collision( if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { bvhtree_update_from_cloth(clmd, false, true); -overlap_self = BLI_bvhtree_overlap( -cloth->bvhselftree, cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); +overlap_self = BLI_bvhtree_overlap_self( +cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); } do { diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 17759b6a8ac..463c95cf4f3 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -73,9 +73,11 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; enum { - /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ BVH_OVERLAP_USE_THREADING = (1 << 0), BVH_OVERLAP_RETURN_PAIRS = (1 << 1), + /* Use a specialized self-overlap traversal to only test and output every + * pair once, rather than twice in different order as usual. */ + BVH_OVERLAP_SELF = (1 << 2), }; enum { /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ @@ -163,6 +165,9 @@ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); /** * Call #BLI_bvhtree_update_node() first for every node/point/triangle. + * + * Note that this does not rebalance the tree, so if the shape of the mesh changes + * too much, operations on the tree may become suboptimal. */ void BLI_bvhtree_update_tree(BVHTree *tree); @@ -191,6 +196,12 @@ BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1, unsigned int *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata); +/** Compute overlaps of the tree with itself. This is faster than BLI_bvhtree_overlap + * because it only tests and returns each symmetrical pair once. */ +BVHTreeOverlap *BLI_bvhtree_overlap_self(const BVHTree *tree, + unsigned int *r_overlap_num, + BVHTree_OverlapCallback callback, + void *userdata); int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
[Bf-blender-cvs] [90f194616b5] master: Depsgraph: clear update flags when skipping through no-op nodes.
Commit: 90f194616b51d3c5df32cb947de83616aa3dcbde Author: Alexander Gavrilov Date: Mon Dec 26 19:39:41 2022 +0200 Branches: master https://developer.blender.org/rB90f194616b51d3c5df32cb947de83616aa3dcbde Depsgraph: clear update flags when skipping through no-op nodes. As an optimization, dependency graph evaluation skips through no-op nodes at the scheduling stage. However, that leaves update flags enabled on the node, and the most problematic one is the USER_MODIFIED flag, which get flushed to children every time the no-op node is tagged. This in turn can cause simulation caches downstream to be permanently stuck in an outdated state until the depsgraph is rebuilt and the stuck flag cleared out. Differential Revision: https://developer.blender.org/D16868 === M source/blender/depsgraph/intern/eval/deg_eval.cc M source/blender/depsgraph/intern/node/deg_node_operation.h === diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 5ca32d00ba5..3bdc33b8d01 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -105,8 +105,7 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod * times. * This is a thread-safe modification as the node's flags are only read for a non-scheduled nodes * and this node has been scheduled. */ - operation_node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | -DEPSOP_FLAG_USER_MODIFIED); + operation_node->flag &= ~DEPSOP_FLAG_CLEAR_ON_EVAL; } void deg_task_run_func(TaskPool *pool, void *taskdata) @@ -270,6 +269,10 @@ void schedule_node(DepsgraphEvalState *state, bool is_scheduled = atomic_fetch_and_or_uint8((uint8_t *)>scheduled, uint8_t(true)); if (!is_scheduled) { if (node->is_noop()) { + /* Clear flags to avoid affecting subsequent update propagation. + * For normal nodes these are cleared when it is evaluated. */ + node->flag &= ~DEPSOP_FLAG_CLEAR_ON_EVAL; + /* skip NOOP node, schedule children right away */ schedule_children(state, node, schedule_fn); } diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 1bc4b36141e..df4a157d486 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -224,6 +224,10 @@ enum OperationFlag { /* Set of flags which gets flushed along the relations. */ DEPSOP_FLAG_FLUSH = (DEPSOP_FLAG_USER_MODIFIED), + + /* Set of flags which get cleared upon evaluation. */ + DEPSOP_FLAG_CLEAR_ON_EVAL = (DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | + DEPSOP_FLAG_USER_MODIFIED), }; /* Atomic Operation - Base type for all operations */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [ebec9eb75ea] master: Fix T103118: depsgraph issues for bbone property drivers on non-bbones.
Commit: ebec9eb75ead22edd4fe66157241f825bb3dd1cd Author: Alexander Gavrilov Date: Tue Dec 27 17:31:37 2022 +0200 Branches: master https://developer.blender.org/rBebec9eb75ead22edd4fe66157241f825bb3dd1cd Fix T103118: depsgraph issues for bbone property drivers on non-bbones. The BONE_SEGMENTS operation node is only created if the bone is actually a B-Bone. One location in the code wasn't checking that before trying to create a relation. === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 53d56c3db36..0c5dfdf5ced 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1675,8 +1675,11 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu) continue; } - OperationCode target_op = driver_targets_bbone ? OperationCode::BONE_SEGMENTS : - OperationCode::BONE_LOCAL; + OperationCode target_op = OperationCode::BONE_LOCAL; + if (driver_targets_bbone) { +target_op = check_pchan_has_bbone_segments(object, pchan) ? OperationCode::BONE_SEGMENTS : + OperationCode::BONE_DONE; + } OperationKey bone_key(>id, NodeType::BONE, pchan->name, target_op); add_relation(driver_key, bone_key, "Arm Bone -> Driver -> Bone"); } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [d605a63cdc3] temp-angavrilov: BVH: recurse into the larger node in overlap computation.
Commit: d605a63cdc3ecc7c8efd73f72dab0cb8f606dcd7 Author: Alexander Gavrilov Date: Thu Dec 29 21:13:16 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rBd605a63cdc3ecc7c8efd73f72dab0cb8f606dcd7 BVH: recurse into the larger node in overlap computation. Currently the overlap computation code always recurses into the left node if possible, only entering the right one once the left is a leaf. This effectively tests every left leaf against the whole tree on the right. Similarly to the self overlap optimization it probably makes sense to recurse into children more evenly. An obvious heuristic is to compare the spatial dimensions of the nodes. To make sure it is up to date, recompute the main axis when updating the tree for a change of coordinates, and reorder children to match just in case (this matters for raycast). === M source/blender/blenlib/intern/BLI_kdopbvh.c === diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 174a53be6da..e8de19bb7c5 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -449,6 +449,15 @@ static void node_join(BVHTree *tree, BVHNode *node) break; } } + + /* Update the main axis and reorder children along it. + * The expectation is that the coordinates change slowly and thus + * no changes are required in most of the cases. */ + const char split_axis = get_largest_axis(node->bv); + + node->main_axis = split_axis / 2; + + bvh_insertionsort(node->children, 0, node->node_num, split_axis); } #ifdef USE_PRINT_TREE @@ -1091,6 +1100,13 @@ static bool tree_overlap_test(const BVHNode *node1, return 1; } +/** Dimension of the node along the main axis. */ +MINLINE float tree_node_main_dimension(const BVHNode *node) +{ + const float *bv = node->bv + (node->main_axis << 1); + return bv[1] - bv[0]; +} + static void tree_overlap_traverse(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2) @@ -1122,6 +1138,14 @@ static void tree_overlap_traverse(BVHOverlapData_Thread *data_thread, } } } +else if (node2->node_num && + tree_node_main_dimension(node2) > tree_node_main_dimension(node1)) { + for (j = 0; j < data->tree2->tree_type; j++) { +if (node2->children[j]) { + tree_overlap_traverse(data_thread, node1, node2->children[j]); +} + } +} else { for (j = 0; j < data->tree1->tree_type; j++) { if (node1->children[j]) { @@ -1169,6 +1193,14 @@ static void tree_overlap_traverse_cb(BVHOverlapData_Thread *data_thread, } } } +else if (node2->node_num && + tree_node_main_dimension(node2) > tree_node_main_dimension(node1)) { + for (j = 0; j < data->tree2->tree_type; j++) { +if (node2->children[j]) { + tree_overlap_traverse_cb(data_thread, node1, node2->children[j]); +} + } +} else { for (j = 0; j < data->tree1->tree_type; j++) { if (node1->children[j]) { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [73ede47c9df] temp-angavrilov: BVH: implement an optimized self-overlap traversal.
Commit: 73ede47c9df005c9059a958d3a261aa97cd86be4 Author: Alexander Gavrilov Date: Wed Dec 28 22:19:36 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB73ede47c9df005c9059a958d3a261aa97cd86be4 BVH: implement an optimized self-overlap traversal. Previously cloth self-collision and other code that wants self-overlap data was using an ordinary BVH overlap utility function. This works, but is suboptimal because it fails to take advantage of the fact that it is comparing two identical trees. The standard traversal for self-collision essentially devolves into enumerating all elements of the tree, and then matching them to the tree starting at the root. However, the tree itself naturally partitions the space, so overlapping elements are likely to be mostly placed nearby in the tree structure as well. Instead, self-overlap can be computed by recursively computing ordinary overlap between siblings within each subtree. This still only considers each pair of leaves once, and provides significantly better locality. It also avoids outputting every overlap pair twice in different order. === M source/blender/blenkernel/intern/collision.c M source/blender/blenlib/BLI_kdopbvh.h M source/blender/blenlib/intern/BLI_kdopbvh.c M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc M source/blender/editors/uvedit/uvedit_select.c === diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index d4dd102476a..194979ac6de 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1521,8 +1521,9 @@ static bool cloth_bvh_obj_overlap_cb(void *userdata, static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { - /* No need for equal combinations (eg. (0,1) & (1,0)). */ - if (index_a < index_b) { + /* This shouldn't happen, but just in case. Note that equal combinations + * (eg. (0,1) & (1,0)) would be filtered out by BLI_bvhtree_overlap_self. */ + if (index_a != index_b) { ClothModifierData *clmd = (ClothModifierData *)userdata; struct Cloth *clothObject = clmd->clothObject; const MVertTri *tri_a, *tri_b; @@ -1603,8 +1604,8 @@ int cloth_bvh_collision( bvhtree_update_from_cloth(clmd, false, true); } -overlap_self = BLI_bvhtree_overlap( -cloth->bvhselftree, cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); +overlap_self = BLI_bvhtree_overlap_self( +cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); } do { diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 17759b6a8ac..8516bccd0d4 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -73,9 +73,11 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; enum { - /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ BVH_OVERLAP_USE_THREADING = (1 << 0), BVH_OVERLAP_RETURN_PAIRS = (1 << 1), + /* Optimize self-overlap to only test and output every pair once, + * rather than twice in different order as usual. */ + BVH_OVERLAP_SELF = (1 << 2), }; enum { /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ @@ -163,6 +165,9 @@ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); /** * Call #BLI_bvhtree_update_node() first for every node/point/triangle. + * + * Note that this does not rebalance the tree, so if the shape of the mesh changes + * too much, operations on the tree may become suboptimal. */ void BLI_bvhtree_update_tree(BVHTree *tree); @@ -191,6 +196,12 @@ BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1, unsigned int *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata); +/** Compute overlaps of the tree with itself. This is faster than BLI_bvhtree_overlap + * because it only tests and returns each symmetrical pair once. */ +BVHTreeOverlap *BLI_bvhtree_overlap_self(const BVHTree *tree, + unsigned int *r_overlap_num, + BVHTree_OverlapCallback callback, + void *userdata); int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index de71147f015..174a53be6da 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdop
[Bf-blender-cvs] [71f3d2e4cea] temp-angavrilov: Shrinkwrap: support smoothing the mesh after wrapping.
Commit: 71f3d2e4ceadd850f9b7e376522fd760dc7ab383 Author: Alexander Gavrilov Date: Thu Sep 1 19:18:51 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB71f3d2e4ceadd850f9b7e376522fd760dc7ab383 Shrinkwrap: support smoothing the mesh after wrapping. Adds a smoothing post-processing option for the shrinkwrap modifier. On any other setting than 0 iterations, the algorithm adds the laplacian of the deltas to the base mesh to produce a smooth-looking deformed mesh -- this makes it possible to avoid losing detail on parts of the mesh that are not affected by the shrinkwrap displacement. Deltas that would otherwise lose magnitude as a result of smoothing are not updated to avoid further volume loss; this keeps the result much closer to the surface of the target while still adjusting other shrinkwrapped (and non-shrinkwrapped) vertexes to follow the smooth surface. Differential Revision: https://developer.blender.org/D6414 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/makesdna/DNA_modifier_types.h M source/blender/makesrna/intern/rna_modifier.c M source/blender/modifiers/intern/MOD_shrinkwrap.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index d196f044c58..8a7c89ac46d 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -63,6 +63,10 @@ struct ShrinkwrapCalcData { const float (*vert_normals)[3]; /* Vertices being shrink-wrapped. */ float (*vertexCos)[3]; + /* Cached vertex deltas. */ + float (*deltas)[3]; + /* Cached vertex weights */ + float *weights; int numVerts; const MDeformVert *dvert; /* Pointer to mdeform array */ @@ -326,6 +330,19 @@ void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh) mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); } +/** Output the computed vertex position either to the final coordinate or the delta array. */ +BLI_INLINE void shrinkwrap_save_result( +ShrinkwrapCalcData *calc, int i, float *co, float *result, float weight) +{ + if (calc->deltas) { +sub_v3_v3v3(calc->deltas[i], result, co); +mul_v3_fl(calc->deltas[i], weight); + } + else { +interp_v3_v3v3(co, co, result, weight); /* linear interpolation */ + } +} + /** * Shrink-wrap to the nearest vertex * @@ -354,6 +371,10 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -390,7 +411,7 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, copy_v3_v3(tmp_co, nearest->co); BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -517,6 +538,10 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, return; } + if (calc->weights) { +calc->weights[i] = weight; + } + if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { /* calc->vert contains verts from evaluated mesh. */ /* These coordinates are deformed by vertexCos only for normal projection @@ -607,7 +632,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, hit->co); } -interp_v3_v3v3(co, co, hit->co, weight); +shrinkwrap_save_result(calc, i, co, hit->co, weight); } } @@ -1115,6 +1140,10 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat return; } + if (calc->weights) { +calc->weights[i] = weight; + } + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); @@ -1159,7 +1188,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat /* Convert the coordinates back to mesh coordinates */ BLI_space_transform_invert(>local2target, tmp_co); -interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ + +shrinkwrap_save_result(calc, i, co, tmp_co, weight); } } @@ -1359,6 +1389,137 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) 0, calc->numVerts, , shrinkwrap_calc_nearest_surface_point_cb_ex, ); } +static void shrinkwrap_smooth( +ShrinkwrapCalcData *calc, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) +{ + if (mesh == NULL) { +return; + } + + /* Number of neighboring vertices for the given
[Bf-blender-cvs] [ab061c5ca9f] temp-angavrilov: Cloth: share self and object collision BVH when possible.
Commit: ab061c5ca9f644e00f536cbe6c77bb9c40910eee Author: Alexander Gavrilov Date: Wed Dec 28 23:39:36 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rBab061c5ca9f644e00f536cbe6c77bb9c40910eee Cloth: share self and object collision BVH when possible. The only difference between the two BVH structures is the epsilon value, so if the actual values happen to be the same, they can be shared. === M source/blender/blenkernel/BKE_cloth.h M source/blender/blenkernel/intern/cloth.cc M source/blender/blenkernel/intern/collision.c === diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8185e1883a9..d26a96bea21 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -72,7 +72,7 @@ typedef struct Cloth { unsigned char pad2; short pad3; struct BVHTree *bvhtree; /* collision tree for this cloth object */ - struct BVHTree *bvhselftree; /* collision tree for this cloth object */ + struct BVHTree *bvhselftree; /* collision tree for this cloth object (may be same as bvhtree) */ struct MVertTri *tri; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ struct EdgeSet *edgeset;/* used for selfcollisions */ diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index 23bbaaf58b2..905492a6e12 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -461,7 +461,7 @@ void cloth_free_modifier(ClothModifierData *clmd) BLI_bvhtree_free(cloth->bvhtree); } -if (cloth->bvhselftree) { +if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) { BLI_bvhtree_free(cloth->bvhselftree); } @@ -538,7 +538,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd) BLI_bvhtree_free(cloth->bvhtree); } -if (cloth->bvhselftree) { +if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) { BLI_bvhtree_free(cloth->bvhselftree); } @@ -820,7 +820,14 @@ static bool cloth_from_object( } clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon); - clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon); + + if (compare_ff(clmd->coll_parms->selfepsilon, clmd->coll_parms->epsilon, 1e-6f)) { +/* Share the BVH tree if the epsilon is the same. */ +clmd->clothObject->bvhselftree = clmd->clothObject->bvhtree; + } + else { +clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon); + } return true; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 2acdc6543b5..d4dd102476a 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1551,6 +1551,7 @@ int cloth_bvh_collision( BVHTreeOverlap **overlap_obj = NULL; uint coll_count_self = 0; BVHTreeOverlap *overlap_self = NULL; + bool bvh_updated = false; if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh == NULL) { return 0; @@ -1561,6 +1562,7 @@ int cloth_bvh_collision( if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { bvhtree_update_from_cloth(clmd, false, false); +bvh_updated = true; /* Enable self collision if this is a hair sim */ const bool is_hair = (clmd->hairdata != NULL); @@ -1597,7 +1599,9 @@ int cloth_bvh_collision( } if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { -bvhtree_update_from_cloth(clmd, false, true); +if (cloth->bvhselftree != cloth->bvhtree || !bvh_updated) { + bvhtree_update_from_cloth(clmd, false, true); +} overlap_self = BLI_bvhtree_overlap( cloth->bvhselftree, cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [aca47dc1861] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: aca47dc186114a8548cc2914a039127a02130c7f Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rBaca47dc186114a8548cc2914a039127a02130c7f Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3dad2a1a19a..7b04439823d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<
[Bf-blender-cvs] [57c7828c6a6] temp-angavrilov: Bone Overlay: support bone wireframe opacity depth fade.
Commit: 57c7828c6a653c60ad443975365f03f5c3525694 Author: Alexander Gavrilov Date: Sat Dec 11 18:04:34 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB57c7828c6a653c60ad443975365f03f5c3525694 Bone Overlay: support bone wireframe opacity depth fade. Add an option that allows fade based on the depth from the camera, using exponential decay with the slider specifying the 'half-life' depth. This is intended as a way to automatically hide bones in distant parts of the mesh while focused on a specific part. === M release/scripts/startup/bl_ui/space_view3d.py M source/blender/blenloader/intern/versioning_300.cc M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/draw/engines/overlay/overlay_private.hh M source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh A source/blender/draw/engines/overlay/shaders/overlay_armature_alpha_lib.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl M source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl M source/blender/makesdna/DNA_view3d_defaults.h M source/blender/makesdna/DNA_view3d_types.h M source/blender/makesrna/intern/rna_space.c === diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 311fe6076db..6628459b8ca 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6826,6 +6826,12 @@ class VIEW3D_PT_overlay_bones(Panel): if VIEW3D_PT_overlay_bones.is_using_wireframe(context): col.prop(overlay, "bone_wire_alpha") +row = col.row() +row.prop(overlay, "bone_wire_use_fade_depth", text="") +sub = row.row() +sub.active = overlay.bone_wire_use_fade_depth +sub.prop(overlay, "bone_wire_fade_depth") + class VIEW3D_PT_overlay_texture_paint(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index dee57a34275..b1e207375f6 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3851,5 +3851,20 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) LISTBASE_FOREACH (Curves *, curves_id, >hair_curves) { curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; } + + +/* Initialize the bone wireframe opacity depth fade setting. */ +if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_fade_depth")) { + LISTBASE_FOREACH (bScreen *, screen, >screens) { +LISTBASE_FOREACH (ScrArea *, area, >areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, >spacedata) { +if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.bone_wire_fade_depth = 1.0f; +} + } +} + } +} } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2093c8a2331..3954187f0c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -563,6 +563,7 @@ set(GLSL_SRC engines/basic/shaders/basic_depth_frag.glsl engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_alpha_lib.glsl engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl engines/overlay/shaders/overlay_armature_dof_vert.glsl engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 7c333a71643..6f1a1bed2c5 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -86,6 +86,8 @@ struct ArmatureDrawContext { bool transparent; bool show_relations; + float *p_fade_depth_bias; + const ThemeWireColor *bcolor; /* pchan color */ }; @@ -126,7 +128,14 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata) draw_ctx->object_pose != nullptr; const float wire_alpha = pd->overlay.bone_wire
[Bf-blender-cvs] [1eb92e44f1e] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 1eb92e44f1ed4c7589888d34b80825b7a1cc6ae6 Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB1eb92e44f1ed4c7589888d34b80825b7a1cc6ae6 Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 8a7c89ac46d..3f1be16d6fc 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -776,6 +776,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -797,71 +807,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [48b4ecd86bd] temp-angavrilov: Force Fields: implement new true power and custom falloff options.
Commit: 48b4ecd86bdfb17b6a28a4beaf8c010c3a7efb8a Author: Alexander Gavrilov Date: Sun Sep 12 19:35:48 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB48b4ecd86bdfb17b6a28a4beaf8c010c3a7efb8a Force Fields: implement new true power and custom falloff options. The 'power' falloff option in Blender force fields does not actually generate a true power falloff function, as pointed out in D2389. However, that patch adds a special 'gravity' falloff option to Force fields, without addressing the shortcoming in the common options. The reason for not using the true curve in the options, as far as one can tell, is that the power curve goes up to infinity as the distance is reduced to 0, while the falloff options are designed so that the maximum value of the curve is 1. However, in reality forces with a power falloff don't actually go to infinity, because real objects have a nonzero size, and the force reaches its maximum at the surface of the object. This can be used to integrate an option to use a true power falloff with the design of falloff settings, if it requires a nonzero 'minimum' distance to be set, and uses a curve that reaches 1 at that distance. Since this is adding a new feature to the minimum distance value, it is also a good opportunity to add a feature to the maximum distance. Specifically, the new options can be used to apply arbitrary brush-style falloff curves between min and max, including a fully custom curve option. When used together with power falloff, the two curves are multiplied together. While the true power option allows creating more physically correct forces, the custom curves aid artistic effects. Differential Revision: https://developer.blender.org/D8075 === M release/scripts/startup/bl_ui/properties_physics_common.py M release/scripts/startup/bl_ui/properties_physics_field.py M source/blender/blenkernel/BKE_effect.h M source/blender/blenkernel/BKE_particle.h M source/blender/blenkernel/intern/effect.c M source/blender/blenkernel/intern/object.cc M source/blender/blenkernel/intern/particle.c M source/blender/makesdna/DNA_object_force_types.h M source/blender/makesrna/intern/rna_object_force.c === diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 4146a8ca51a..f2e30e523a4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -337,6 +337,10 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_min", text="") row.prop_decorator(field, "distance_min") +col = layout.column() +col.active = field.use_min_distance and field.distance_min > 0 +col.prop(field, "use_true_power") + col = layout.column(align=False, heading="Max Distance") col.use_property_decorate = False row = col.row(align=True) @@ -347,6 +351,13 @@ def basic_force_field_falloff_ui(self, field): sub.prop(field, "distance_max", text="") row.prop_decorator(field, "distance_max") +col = layout.column() +col.active = field.use_max_distance and field.distance_max > field.distance_min +col.prop(field, "falloff_curve_type", text="Curve") + +if field.falloff_curve_type == 'CUSTOM': +col.template_curve_mapping(field, "falloff_curve", type='NONE', brush=True) + classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 36d5dc7f68d..635897247c9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -238,20 +238,36 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): col = flow.column() col.prop(field, "radial_falloff", text="Power") -col = flow.column() -col.prop(field, "use_radial_min", text="Use Min Angle") - -sub = col.column() +col = layout.column(align=False, heading="Min Angle") +col.use_property_decorate = False +row = col.row(align=True) +sub = row.row(align=True) +sub.prop(field, "use_radial_min", text="") +sub = sub.row(align=True) sub.active = field.use_radial_min -sub.prop(field, "radial_min", text="Min Angle") - -col = flow.column() -col.prop(field, "use_radial_max", text="Use Max Angle") +sub.prop(field, "radial_min", text="") +row.prop_decorator(field
[Bf-blender-cvs] [396547d68f1] temp-angavrilov: Fix T103074: flipped vertex group meaning in Multi-Modifier Armature.
Commit: 396547d68f17df8ed3334b768d33d22781804c40 Author: Alexander Gavrilov Date: Thu Dec 15 23:37:14 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB396547d68f17df8ed3334b768d33d22781804c40 Fix T103074: flipped vertex group meaning in Multi-Modifier Armature. For some reason the Armature modifier in the Multi-Modifier mode interpreted the vertex group in a way essentially opposite to the regular mode. Moreover, this depended not on the Multi-Modifier checkbox, but on whether the mode was actually active. This fixes the flip and adds versioning code to patch old files. One difficulty is that whether the Multi-Modifier flag is valid can be different between the viewport and render. The versioning code assumes any modifier enabled in either to be active. This change is not forward compatible, so min version is also bumped. Differential Revision: https://developer.blender.org/D16787 === M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenkernel/intern/armature_deform.c M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 2ddda93c93b..915b28e5f9b 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 6 +#define BLENDER_FILE_SUBVERSION 7 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 4 +#define BLENDER_FILE_MIN_SUBVERSION 7 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 64a3937c191..973fdbd0c57 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ - float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ + float prevco_weight = 0.0f; /* weight for optional cached vertexcos */ if (use_quaternion) { memset(, 0, sizeof(DualQuat)); @@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, /* hackish: the blending factor can be used for blending with vert_coords_prev too */ if (vert_coords_prev) { - prevco_weight = armature_weight; + /* This weight specifies the contribution from the coordinates at the start of this + * modifier evaluation, while armature_weight is normally the opposite of that. */ + prevco_weight = 1.0f - armature_weight; armature_weight = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index b1e207375f6..645971ee09d 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3836,6 +3836,35 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } } + + if (!MAIN_VERSION_ATLEAST(bmain, 305, 7)) { +LISTBASE_FOREACH (Object *, ob, >objects) { + bool after_armature = false; + LISTBASE_FOREACH (ModifierData *, md, >modifiers) { +if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->multi) { +/* Toggle the invert vertex group flag on operational Multi Modifier entries. */ +if (after_armature && amd->defgrp_name[0]) { + amd->deformflag ^= ARM_DEF_INVERT_VGROUP; +} + } + else { +/* Disabled multi modifiers don't reset propagation, but non-multi ones do. */ +after_armature = false; + } + /* Multi Modifier is only valid and operational after an active Armature modifier. */ + if (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) { +after_armature = true; + } +} +else { + after_armature = false; +} + } +} + } + /** * Versioning code until next subversion bump goes here. * ___ Bf-blender-cvs mailing list Bf-blender-cvs@ble
[Bf-blender-cvs] [368f60fefd1] temp-angavrilov: Depsgraph: clear update flags when skipping through no-op nodes.
Commit: 368f60fefd1730534cf4cd8bbbea62af5daa5134 Author: Alexander Gavrilov Date: Mon Dec 26 19:39:41 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB368f60fefd1730534cf4cd8bbbea62af5daa5134 Depsgraph: clear update flags when skipping through no-op nodes. As an optimization, dependency graph evaluation skips through no-op nodes at the scheduling stage. However, that leaves update flags enabled on the node, and the most problematic one is the USER_MODIFIED flag, which get flushed to children every time the no-op node is tagged. This in turn can cause simulation caches downstream to be permanently stuck in an outdated state until the depsgraph is rebuilt and the stuck flag cleared out. Differential Revision: https://developer.blender.org/D16868 === M source/blender/depsgraph/intern/eval/deg_eval.cc M source/blender/depsgraph/intern/node/deg_node_operation.h === diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 5ca32d00ba5..739007a2ad4 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -104,9 +104,9 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod /* Clear the flag early on, allowing partial updates without re-evaluating the same node multiple * times. * This is a thread-safe modification as the node's flags are only read for a non-scheduled nodes - * and this node has been scheduled. */ - operation_node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | -DEPSOP_FLAG_USER_MODIFIED); + * and this node has been scheduled. + * These also have to be cleared for no-op nodes in schedule_node. */ + operation_node->flag &= ~DEPSOP_FLAG_CLEAR_ON_EVAL; } void deg_task_run_func(TaskPool *pool, void *taskdata) @@ -270,6 +270,10 @@ void schedule_node(DepsgraphEvalState *state, bool is_scheduled = atomic_fetch_and_or_uint8((uint8_t *)>scheduled, uint8_t(true)); if (!is_scheduled) { if (node->is_noop()) { + /* Clear flags to avoid affecting subsequent update propagation. + * For normal nodes these are cleared in evaluate_node. */ + node->flag &= ~DEPSOP_FLAG_CLEAR_ON_EVAL; + /* skip NOOP node, schedule children right away */ schedule_children(state, node, schedule_fn); } diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 1bc4b36141e..df4a157d486 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -224,6 +224,10 @@ enum OperationFlag { /* Set of flags which gets flushed along the relations. */ DEPSOP_FLAG_FLUSH = (DEPSOP_FLAG_USER_MODIFIED), + + /* Set of flags which get cleared upon evaluation. */ + DEPSOP_FLAG_CLEAR_ON_EVAL = (DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | + DEPSOP_FLAG_USER_MODIFIED), }; /* Atomic Operation - Base type for all operations */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [1d1234fc046] temp-angavrilov: Armature: apply Y scale to B-Bone segments.
Commit: 1d1234fc0462225184e2aa36f79e8ce7b2d2d85c Author: Alexander Gavrilov Date: Tue Jun 15 13:52:23 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB1d1234fc0462225184e2aa36f79e8ce7b2d2d85c Armature: apply Y scale to B-Bone segments. This fixes a strange behavior where the segments were not actually scaled in the Y direction to match their actual length, thus producing gaps or overlap depending on the shape of the curve. For transformation the change should be very small if enough segments are used, but this will affect the results of the Copy Transforms and Armature constraints, so a backwards compatibility option is provided. Newly created bones default to the new behavior. === M release/scripts/startup/bl_ui/properties_data_bone.py M source/blender/blenkernel/BKE_armature.h M source/blender/blenkernel/intern/armature.c M source/blender/draw/engines/overlay/overlay_armature.cc M source/blender/makesdna/DNA_armature_types.h M source/blender/makesrna/intern/rna_armature.c === diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 8e1808949b3..026e581b2ba 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -162,6 +162,8 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): col.prop(bbone, "bbone_easeout", text="Out", text_ctxt=i18n_contexts.id_armature) col.prop(bone, "use_scale_easing") +topcol.prop(bone, "use_unscaled_segments") + col = topcol.column(align=True) col.prop(bone, "bbone_handle_type_start", text="Start Handle") diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index eff05e471aa..f9d4cf7a246 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -469,7 +469,7 @@ typedef struct BBoneSplineParameters { float length; /* Non-uniform scale correction. */ - bool do_scale; + bool do_scale, do_scale_segments; float scale[3]; /* Handle control bone data. */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e433c26cc54..89ca69510b8 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -944,6 +944,8 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan, param->segments = bone->segments; param->length = bone->length; + param->do_scale_segments = (bone->bbone_flag & BBONE_SCALE_SEGMENTS) != 0; + if (!rest) { float scale[3]; @@ -1309,6 +1311,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, const float axis[3], float roll, float scalex, + float scaley, float scalez, float result[4][4]) { @@ -1326,6 +1329,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, /* BBone scale... */ mul_v3_fl(result[0], scalex); + mul_v3_fl(result[1], scaley); mul_v3_fl(result[2], scalez); } @@ -1393,6 +1397,8 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, equalize_cubic_bezier( bezt_controls, MAX_BBONE_SUBDIV, param->segments, segment_scales, bezt_points); + const float scale_fac = param->segments / length; + /* Deformation uses N+1 matrices computed at points between the segments. */ if (for_deform) { /* Bezier derivatives. */ @@ -1405,6 +1411,32 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, sub_v3_v3v3(bezt_deriv2[i], bezt_deriv1[i + 1], bezt_deriv1[i]); } +/* Inner segment points. */ +float points[MAX_BBONE_SUBDIV][3], tangents[MAX_BBONE_SUBDIV][3]; + +copy_v3_v3(points[0], bezt_controls[0]); + +for (int a = 1; a < param->segments; a++) { + evaluate_cubic_bezier(bezt_controls, bezt_points[a], points[a], tangents[a]); +} + +/* Segment lengths. */ +float seg_length[MAX_BBONE_SUBDIV + 1]; + +if (param->do_scale_segments) { + for (int a = 1; a < param->segments; a++) { +seg_length[a] = len_v3v3(points[a - 1], points[a]) * scale_fac; + } + + seg_length[param->segments] = len_v3v3(points[param->segments - 1], bezt_controls[3]) * +scale_fac; +} +else { + for (int a = 1; a <= param->segments; a++) { +seg_length[a] = 1; + } +} + /* End points require special handling to fix zero
[Bf-blender-cvs] [6875225676e] temp-angavrilov: Depsgraph: connect up drivers on various physics properties.
Commit: 6875225676e6541c5d9114c2582cc0bb36950cd4 Author: Alexander Gavrilov Date: Sat Jan 9 21:19:37 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB6875225676e6541c5d9114c2582cc0bb36950cd4 Depsgraph: connect up drivers on various physics properties. It seems drivers for physics properties weren't being linked to evaluation nodes. This connects settings used by modifiers to Geometry; particle settings and rigid body data to Transform which seems to contain rigid body evaluation; and force fields to object Transform, since fields can exist on empties. Differential Revision: https://developer.blender.org/D10088 === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/depsgraph/intern/builder/deg_builder_rna.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 53d56c3db36..32cd56b3584 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2029,6 +2029,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + /* Constraints. */ + if (rbw->constraints != nullptr) { +build_collection(nullptr, nullptr, rbw->constraints); +FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { + if (object->rigidbody_constraint == nullptr) { +continue; + } + if (object->rigidbody_object != nullptr) { +/* Avoid duplicate relations for constraints attached to objects. */ +continue; + } + + /* Simulation uses object transformation after parenting and solving constraints. */ + OperationKey object_transform_simulation_init_key( + >id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); + add_relation(object_transform_simulation_init_key, + rb_simulate_key, + "Object Transform -> Rigidbody Sim Eval"); +} +FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } } void DepsgraphRelationBuilder::build_particle_systems(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 1a4356c4a92..b300490066b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -283,7 +283,16 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNA_struct_is_a(ptr->type, _MeshUVLoop) || RNA_struct_is_a(ptr->type, _MeshLoopColor) || RNA_struct_is_a(ptr->type, _VertexGroupElement) || - RNA_struct_is_a(ptr->type, _ShaderFx)) { + RNA_struct_is_a(ptr->type, _ShaderFx) || + ELEM(ptr->type, +_CollisionSettings, +_SoftBodySettings, +_ClothSettings, +_ClothCollisionSettings, +_DynamicPaintSurface, +_DynamicPaintCanvasSettings, +_DynamicPaintBrushSettings) || + (ELEM(ptr->type, _EffectorWeights) && GS(node_identifier.id->name) == ID_OB)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ @@ -383,6 +392,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } + else if (GS(node_identifier.id->name) == ID_PA && + ELEM(ptr->type, _EffectorWeights, _FieldSettings, _ParticleSettings)) { +node_identifier.type = NodeType::PARTICLE_SETTINGS; +return node_identifier; + } + else if (ELEM(ptr->type, +_EffectorWeights, +_RigidBodyWorld, +_FieldSettings, +_RigidBodyObject, +_RigidBodyConstraint)) { +node_identifier.type = NodeType::TRANSFORM; +return node_identifier; + } if (prop != nullptr) { /* All unknown data effectively falls under "parameter evaluation". */ node_identifier.type = NodeType::PARAMETERS; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [2cee38ff47a] temp-angavrilov: Dope Sheet: distinguish Constant and Linear from other interpolation modes.
Commit: 2cee38ff47aa3b829f596fd740278a728b3a5097 Author: Alexander Gavrilov Date: Sat Feb 5 14:11:29 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB2cee38ff47aa3b829f596fd740278a728b3a5097 Dope Sheet: distinguish Constant and Linear from other interpolation modes. There is an option to display handles and interpolation modes in the dope sheet, but the only interpolation mode it distinguishes is Bezier. This adds distinct display for Constant and Linear: - Constant is drawn as a thicker line. - Linear is drawn the same as now. - Other non-Bezier modes are drawn as a double line. Constant, Linear and Bezier are the most common modes, so it makes sense to distinguish them from all others. Differential Revision: https://developer.blender.org/D15855 === M source/blender/editors/animation/keyframes_draw.c M source/blender/editors/animation/keyframes_keylist.cc M source/blender/editors/include/ED_keyframes_keylist.h === diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6df9dc1e86d..673e68b2e95 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -287,14 +287,30 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) { + float width = ctx->ipo_size; + bool fill = true; + + switch (ab->block.ipo) { +case BEZT_IPO_CONST: + width *= 1.7f; + break; + +case BEZT_IPO_LIN: + break; + +default: + width *= 2.0f; + fill = false; + } + UI_draw_roundbox_4fv( &(const rctf){ .xmin = ab->cfra, .xmax = ab->next->cfra, - .ymin = ypos - ctx->ipo_size, - .ymax = ypos + ctx->ipo_size, + .ymin = ypos - width, + .ymax = ypos + width, }, - true, + fill, 3.0f, (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 9b3cabb6c79..6cae1003966 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -749,6 +749,10 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, /* Remember non-bezier interpolation info. */ if (prev->ipo != BEZT_IPO_BEZ) { info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; +info->ipo = prev->ipo; + } + else { +info->ipo = -1; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); @@ -765,6 +769,13 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) col->block.conflict |= (col->block.flag ^ block->flag); col->block.flag |= block->flag; col->block.sel |= block->sel; + +/* Combine interpolations; detect conflicts and use max value. */ +if (col->block.ipo != block->ipo) { + col->block.conflict |= ACTKEYBLOCK_FLAG_NON_BEZIER; +} + +col->block.ipo = MAX2(col->block.ipo, block->ipo); } if (block->flag) { diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 251b6e4d83d..d82d98777b8 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -37,6 +37,9 @@ typedef struct ActKeyBlockInfo { /* Selection flag. */ char sel; + + /* Interpolation mode. */ + signed char ipo; } ActKeyBlockInfo; /* Keyframe Column Struct */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [e2901615314] temp-angavrilov: Fix T103118: depsgraph issues for bbone property drivers on non-bbones.
Commit: e29016153149f4545d5a4623cdc660a8ca7d3216 Author: Alexander Gavrilov Date: Tue Dec 27 17:31:37 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rBe29016153149f4545d5a4623cdc660a8ca7d3216 Fix T103118: depsgraph issues for bbone property drivers on non-bbones. The BONE_SEGMENTS operation node is only created if the bone is actually a B-Bone. One location in the code wasn't checking that before trying to create a relation. === M source/blender/depsgraph/intern/builder/deg_builder_relations.cc === diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 32cd56b3584..b8581b16aef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1675,8 +1675,11 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu) continue; } - OperationCode target_op = driver_targets_bbone ? OperationCode::BONE_SEGMENTS : - OperationCode::BONE_LOCAL; + OperationCode target_op = OperationCode::BONE_LOCAL; + if (driver_targets_bbone) { +target_op = check_pchan_has_bbone_segments(object, pchan) ? OperationCode::BONE_SEGMENTS : + OperationCode::BONE_DONE; + } OperationKey bone_key(>id, NodeType::BONE, pchan->name, target_op); add_relation(driver_key, bone_key, "Arm Bone -> Driver -> Bone"); } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [37991f985bc] temp-angavrilov: Animation: support filtering for curves that have cycle issues.
Commit: 37991f985bc32386e59beadc2ea6d090a2933cfd Author: Alexander Gavrilov Date: Mon May 3 17:27:53 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB37991f985bc32386e59beadc2ea6d090a2933cfd Animation: support filtering for curves that have cycle issues. It is possible to have curves with cyclic extrapolation that have a mismatch in their end keyframes, causing a jump. Also, since the looping behavior is defined per curve rather than at action level, it is possible for curve loop periods to get out of sync with each other. This commit adds an option to compare curves against the manual frame range specified in the action, and treat any mismatches as errors for the purpose of F-Curve filtering. When enabled, the check verifies that end values of cyclic curves match, curves within a cyclic action have valid cyclic extrapolation, and the action period evenly divides by the curve period (since a curve looping at e.g. half of the action period length still repeats in sync with the action). Ref: D11803 Differential Revision: https://developer.blender.org/D13349 === M release/scripts/startup/bl_ui/space_dopesheet.py M source/blender/editors/animation/anim_filter.c M source/blender/makesdna/DNA_action_types.h M source/blender/makesrna/intern/rna_action.c === diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index f95650ccc23..a857daa6561 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -63,6 +63,12 @@ class DopesheetFilterPopoverBase: else: # graph and dopesheet editors - F-Curves and drivers only col.prop(dopesheet, "show_only_errors", icon='NONE') +col.separator() + +col2 = col.column(align=True) +col2.active = dopesheet.show_only_errors +col2.prop(dopesheet, "show_cycle_errors") + # Name/Membership Filters # XXX: Perhaps these should just stay in the headers (exclusively)? @classmethod diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..4f5201a6665 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -63,6 +63,7 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -1207,6 +1208,53 @@ static bool skip_fcurve_with_name( return true; } +/* Check if the F-Curve doesn't cycle properly based on action settings. */ +static bool fcurve_has_cycle_errors(const FCurve *fcu, const bAction *act) +{ + /* Check if the curve is cyclic. */ + const eFCU_Cycle_Type cycle_type = BKE_fcurve_get_cycle_type(fcu); + + if (cycle_type == FCU_CYCLE_NONE) { +/* Curves in a cyclic action should be cyclic; in an ordinary action either way is fine. */ +return BKE_action_is_cyclic(act); + } + + /* Check if the curve has enough points. */ + if (fcu->totvert < 2 || !fcu->bezt) { +return true; + } + + const BezTriple *first = >bezt[0], *last = >bezt[fcu->totvert - 1]; + + if (BKE_action_is_cyclic(act)) { +/* Check that it has a nonzero period length. */ +const float curve_period = last->vec[1][0] - first->vec[1][0]; + +if (curve_period < 0.1f) { + return true; +} + +/* Check that the action period is divisible by the curve period. */ +const float action_period = act->frame_end - act->frame_start; +const float gap = action_period - roundf(action_period / curve_period) * curve_period; + +if (fabsf(gap) > 1e-3f) { + return true; +} + } + + /* In case of a perfect cycle, check that the start and end values match. */ + if (cycle_type == FCU_CYCLE_PERFECT) { +const float magnitude = max_fff(fabsf(first->vec[1][1]), fabsf(last->vec[1][1]), 0.01f); + +if (fabsf(first->vec[1][1] - last->vec[1][1]) > magnitude * 1e-4f) { + return true; +} + } + + return false; +} + /** * Check if F-Curve has errors and/or is disabled * @@ -1253,6 +1301,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, + bAction *act, void *owner, ID *owner_id) { @@ -1304,7 +1353,9 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, /* error-based filtering... */ if ((ads) &&
[Bf-blender-cvs] [ce0642a3993] temp-angavrilov: Temporary Hack: provide B-Bone scale versioning for files with old patch.
Commit: ce0642a3993ae742ff0a09c7cf22e0899c9a0f3f Author: Alexander Gavrilov Date: Tue Jun 22 16:38:26 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rBce0642a3993ae742ff0a09c7cf22e0899c9a0f3f Temporary Hack: provide B-Bone scale versioning for files with old patch. Run the versioning code for the conversion of bbone scale to an xyz vector if it has fields that correspond to the old version of the patch before that change requiring versioning. The actual Y (length) scale value from the old patch isn't versioned and will be lost, requiring manual fixing. === M source/blender/blenloader/intern/versioning_300.cc === diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 11392d04991..dee57a34275 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -2138,7 +2138,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } /* Initialize length-wise scale B-Bone settings. */ -if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag")) { +if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag") || +DNA_struct_elem_find(fd->filesdna, "Bone", "float", "scale_in_len")) { /* Update armature data and pose channels. */ LISTBASE_FOREACH (bArmature *, arm, >armatures) { do_version_bones_bbone_len_scale(>bonebase); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [8148d083207] temp-angavrilov: BVH: implement an optimized self-overlap traversal.
Commit: 8148d0832072e97b36a6610380f8b9d27f2673f9 Author: Alexander Gavrilov Date: Wed Dec 28 22:19:36 2022 +0200 Branches: temp-angavrilov https://developer.blender.org/rB8148d0832072e97b36a6610380f8b9d27f2673f9 BVH: implement an optimized self-overlap traversal. Previously cloth self-collision and other code that wants self-overlap data was using an ordinary BVH overlap utility function. This works, but is suboptimal because it fails to take advantage of the fact that it is comparing two identical trees. The standard traversal for self-collision essentially devolves into enumerating all elements of the tree, and then matching them to the tree starting at the root. However, the tree itself naturally partitions the space, so overlapping elements are likely to be mostly placed nearby in the tree structure as well. Instead, self-overlap can be computed by recursively computing ordinary overlap between siblings within each subtree. This still only considers each pair of leaves once, and provides significantly better locality. It also avoids outputting every overlap pair twice in different order. In addition, the generic traversal probably should recurse into the spatially bigger node first to achieve a similar locality effect. === M source/blender/blenkernel/intern/collision.c M source/blender/blenlib/BLI_kdopbvh.h M source/blender/blenlib/intern/BLI_kdopbvh.c M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc M source/blender/editors/uvedit/uvedit_select.c === diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 2acdc6543b5..cd34ae29efb 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1521,8 +1521,9 @@ static bool cloth_bvh_obj_overlap_cb(void *userdata, static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { - /* No need for equal combinations (eg. (0,1) & (1,0)). */ - if (index_a < index_b) { + /* This shouldn't happen, but just in case. Note that equal combinations + * (eg. (0,1) & (1,0)) would be filtered out by BLI_bvhtree_overlap_self. */ + if (index_a != index_b) { ClothModifierData *clmd = (ClothModifierData *)userdata; struct Cloth *clothObject = clmd->clothObject; const MVertTri *tri_a, *tri_b; @@ -1599,8 +1600,8 @@ int cloth_bvh_collision( if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { bvhtree_update_from_cloth(clmd, false, true); -overlap_self = BLI_bvhtree_overlap( -cloth->bvhselftree, cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); +overlap_self = BLI_bvhtree_overlap_self( +cloth->bvhselftree, _count_self, cloth_bvh_self_overlap_cb, clmd); } do { diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 17759b6a8ac..8516bccd0d4 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -73,9 +73,11 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; enum { - /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ BVH_OVERLAP_USE_THREADING = (1 << 0), BVH_OVERLAP_RETURN_PAIRS = (1 << 1), + /* Optimize self-overlap to only test and output every pair once, + * rather than twice in different order as usual. */ + BVH_OVERLAP_SELF = (1 << 2), }; enum { /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ @@ -163,6 +165,9 @@ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); /** * Call #BLI_bvhtree_update_node() first for every node/point/triangle. + * + * Note that this does not rebalance the tree, so if the shape of the mesh changes + * too much, operations on the tree may become suboptimal. */ void BLI_bvhtree_update_tree(BVHTree *tree); @@ -191,6 +196,12 @@ BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1, unsigned int *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata); +/** Compute overlaps of the tree with itself. This is faster than BLI_bvhtree_overlap + * because it only tests and returns each symmetrical pair once. */ +BVHTreeOverlap *BLI_bvhtree_overlap_self(const BVHTree *tree, + unsigned int *r_overlap_num, + BVHTree_OverlapCallback callback, + void *userdata); int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num); diff --git a/source/blender/blenlib/in
[Bf-blender-cvs] [8191e65b58f] temp-angavrilov: Shrinkwrap: fix stability of the Target Normal Project mode.
Commit: 8191e65b58ff88e0edb6b8bc7908822f7465c206 Author: Alexander Gavrilov Date: Sat Sep 3 17:03:11 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB8191e65b58ff88e0edb6b8bc7908822f7465c206 Shrinkwrap: fix stability of the Target Normal Project mode. This mode works by using an iterative process to solve a system of equations for each triangle to find a point on its surface that has the smooth normal pointing at the original point. If a point within the triangle is not found, the next triangle is searched. All instability with vertices jumping to the opposite side of the mesh is caused by incorrectly discarding triangles for various reasons when the solution is close to the triangle edge. In order to optimize performance the old code was aggressively aborting iteration when the local gradient at the edge was pointing outside domain. However, it is wrong because it can be caused by a sharp valley diagonal to the domain boundary with the bottom gently sloping towards a minimum within the domain. Now iteration is only aborted if the solution deviates nonsensically far from the domain. Otherwise, the iteration proceeds as usual, and the final result is checked against domain borders with epsilon. In addition, iterations can now be aborted based on the value of the Jacobian determinant, or the number of linear search correction steps. Both can signify a singularity, which can be caused by the lack of a real solution to the equation. Finally, custom correction clearly has to be done after the linear search phase of the iterative solver, because the linear correction math assumes running after a normal Newton method step, not some kind of custom clamping. Differential Revision: https://developer.blender.org/D15892 === M source/blender/blenkernel/intern/shrinkwrap.cc M source/blender/blenlib/BLI_math_solvers.h M source/blender/blenlib/intern/math_solvers.c === diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index e3ae489b966..db5614abaaf 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -776,6 +776,16 @@ static void target_project_tri_jacobian(void *userdata, const float x[3], float madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]); } +/* Retrieve maximum deviation of the barycentric weights outside the triangle. */ +static float target_project_tri_error(float x[3]) +{ + float error = 0.0f; + error = max_ff(error, -x[0]); + error = max_ff(error, -x[1]); + error = max_ff(error, x[0] + x[1] - 1.0f); + return error; +} + /* Clamp barycentric weights to the triangle. */ static void target_project_tri_clamp(float x[3]) { @@ -797,71 +807,26 @@ static bool target_project_tri_correct(void * /*userdata*/, float step[3], float x_next[3]) { - /* Insignificant correction threshold */ - const float epsilon = 1e-5f; - /* Dot product threshold for checking if step is 'clearly' pointing outside. */ - const float dir_epsilon = 0.5f; - bool fixed = false, locked = false; - - /* The barycentric coordinate domain is a triangle bounded by - * the X and Y axes, plus the x+y=1 diagonal. First, clamp the - * movement against the diagonal. Note that step is subtracted. */ - float sum = x[0] + x[1]; - float sstep = -(step[0] + step[1]); - - if (sum + sstep > 1.0f) { -float ldist = 1.0f - sum; - -/* If already at the boundary, slide along it. */ -if (ldist < epsilon * float(M_SQRT2)) { - float step_len = len_v2(step); - - /* Abort if the solution is clearly outside the domain. */ - if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) { -return false; - } - - /* Project the new position onto the diagonal. */ - add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f); - fixed = locked = true; -} -else { - /* Scale a significant step down to arrive at the boundary. */ - mul_v3_fl(step, ldist / sstep); - fixed = true; -} - } - - /* Weight 0 and 1 boundary checks - along axis. */ - for (int i = 0; i < 2; i++) { -if (step[i] > x[i]) { - /* If already at the boundary, slide along it. */ - if (x[i] < epsilon) { -float step_len = len_v2(step); - -/* Abort if the solution is clearly outside the domain. */ -if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) { - return false; -} + const float error = target_project_tri_error(x_next); -/* Reset precision errors to stay at the boundary. */ -step[i] = x[i]; -fixed = true; - } - else { -/* Scale a significant step down to arrive
[Bf-blender-cvs] [8148eb167cf] temp-angavrilov: Eevee: implement conditional evaluation of Mix node branches.
Commit: 8148eb167cfce075261327ecdcdc86a83c4034c2 Author: Alexander Gavrilov Date: Sun Oct 9 21:15:48 2022 +0300 Branches: temp-angavrilov https://developer.blender.org/rB8148eb167cfce075261327ecdcdc86a83c4034c2 Eevee: implement conditional evaluation of Mix node branches. If the material effectively combines multiple distinct materials using some kind of mask texture, it is wasteful to evaluate all of them when the mask fully excludes some. Cycles already supports this optimization for Mix Shader nodes. This implements a similar feature for Mix Shader and Mix Color Blend nodes in Eevee: shader matches Cycles, and mixing colors can be used for a similar purpose in NPR shaders. To achieve that, a Conditional node type directly supported by code generation is added. Shader nodes can add these conditionals as needed, and the code generator partitions the node graph into a branch tree and appropriately generates conditionals. Empty conditionals are automatically eliminated to avoid any performance impact. This processing is done separately for every sub-graph to minimize dependency cross-contamination. Differential Revision: https://developer.blender.org/D16218 === M source/blender/gpu/GPU_material.h M source/blender/gpu/intern/gpu_codegen.cc M source/blender/gpu/intern/gpu_node_graph.cc M source/blender/gpu/intern/gpu_node_graph.h M source/blender/nodes/shader/nodes/node_shader_mix.cc M source/blender/nodes/shader/nodes/node_shader_mix_shader.cc === diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3dad2a1a19a..7b04439823d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -195,6 +195,51 @@ bool GPU_stack_link(GPUMaterial *mat, GPUNodeStack *out, ...); +/** Comparison operator for conditionals. */ +typedef enum { + GPU_CMP_NE = 0, + GPU_CMP_LT, + GPU_CMP_LE, + GPU_CMP_EQ, + GPU_CMP_GE, + GPU_CMP_GT, +} GPUComparisonOp; + +/** + * Create a runtime ternary conditional, choosing between two inputs based on + * comparing a scalar float input with a constant threshold. + * + * \param cmp_input: Input to compare with the threshold. + * \param result_type: Type of value to produce. + * \param if_true: Input to use when the condition is true. + * \param if_false: Input to use when the condition is false. If null, this signifies + * the conditional is an optimization hint the input is unused if the condition is false. + * Depending on context, a valid default value is used, or the conditional may be discarded + * if it produces no performance benefit. + */ +GPUNodeLink *GPU_link_conditional(GPUMaterial *mat, + GPUNodeLink *cmp_input, + GPUComparisonOp cmp, + float threshold, + eGPUType result_type, + GPUNodeLink *if_true, + GPUNodeLink *if_false); + +/** + * Introduces a predicate for evaluating a stack input only when necessary. + * The conditional is only added if both inputs are non-constant. + * + * \param cmp_input: Input to compare with the threshold. + * \param inout_if_true: Stack entry to wrap in the conditional, suppressing evaluation when false. + * The link field within the entry is updated in place. + * \return true if the conditional was actually added. + */ +bool GPU_stack_link_conditional(GPUMaterial *mat, +GPUNodeStack *cmp_input, +GPUComparisonOp cmp, +float threshold, +GPUNodeStack *inout_if_true); + void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link); void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link); diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..f9f43e61291 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -205,9 +206,25 @@ static std::ostream <<(std::ostream , const GPUInput *input) } } -static std::ostream <<(std::ostream , const GPUOutput *output) +static std::ostream <<(std::ostream , GPUComparisonOp cmp) { - return stream << SRC_NAME("out", output, outputs, "tmp") << output->id; + switch (cmp) { +case GPU_CMP_NE: + return stream << "!="; +case GPU_CMP_LT: + return stream << "<"; +case GPU_CMP_LE: + return stream <<