[Bf-blender-cvs] [04accc6fd95] temp-angavrilov: Shape Key editing: propagate updates through basis chains.

2023-02-05 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-02-04 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-26 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-24 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-12 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-06 Thread Alexander Gavrilov
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.

2023-01-05 Thread Alexander Gavrilov
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.

2023-01-05 Thread Alexander Gavrilov
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.

2023-01-02 Thread Alexander Gavrilov
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.

2023-01-02 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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.

2022-12-29 Thread Alexander Gavrilov
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 <<

  1   2   3   4   5   6   7   8   9   10   >