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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-04-18 23:17:04 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-04-18 23:19:44 +0300
commit638938e5a8c30c405c3b4e96ab4f78095003958b (patch)
treef6a3e274c4a555ee48a5e284a8e150ef57307f87
parente8c9e85401ef6162656cf3b10c5aec509ae8a850 (diff)
Armature: remove remains of the object-level deformation data cache.
Now that B-Bone shape data is kept in bPoseChannel_Runtime, the armature level cache only holds one quaternion value per bone. It can also be moved to runtime, and the structure removed. This has an additional effect that, as far as I can tell, now the Armature modifier can run as soon as all of the bones it actually needs are done, thus making T59848 a purely depsgraph level problem.
-rw-r--r--intern/opencolorio/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/BKE_armature.h11
-rw-r--r--source/blender/blenkernel/intern/armature.c159
-rw-r--r--source/blender/blenkernel/intern/armature_update.c9
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h10
-rw-r--r--source/blender/makesdna/DNA_action_types.h6
-rw-r--r--source/blender/makesdna/DNA_object_types.h9
-rw-r--r--source/blender/makesdna/DNA_vec_types.h9
9 files changed, 32 insertions, 184 deletions
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt
index da0956cee86..4d95c1b701b 100644
--- a/intern/opencolorio/CMakeLists.txt
+++ b/intern/opencolorio/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../guardedalloc
../../source/blender/blenlib
../../source/blender/gpu
+ ../../source/blender/makesdna
)
set(INC_SYS
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 50457c5b3f0..e171eec023f 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -335,17 +335,6 @@ void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph,
struct Object *object,
int pchan_index);
-/* BBOne deformation cache.
- *
- * The idea here is to pre-calculate deformation queternions, matricies and such
- * used by armature_deform_verts().
- */
-struct ObjectBBoneDeform;
-struct ObjectBBoneDeform *BKE_armature_cached_bbone_deformation_get(struct Object *object);
-void BKE_armature_cached_bbone_deformation_free_data(struct Object *object);
-void BKE_armature_cached_bbone_deformation_free(struct Object *object);
-void BKE_armature_cached_bbone_deformation_update(struct Object *object);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 91c760223aa..6cbc9901b0b 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -932,17 +932,6 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param,
/* ************ Armature Deform ******************* */
-typedef struct bPoseChanDeform {
- DualQuat *dual_quat;
-} bPoseChanDeform;
-
-/* Definition of cached object bbone deformations. */
-typedef struct ObjectBBoneDeform {
- DualQuat *dualquats;
- bPoseChanDeform *pdef_info_array;
- int num_pchan;
-} ObjectBBoneDeform;
-
static void allocate_bbone_cache(bPoseChannel *pchan, int segments)
{
bPoseChannel_Runtime *runtime = &pchan->runtime;
@@ -1171,12 +1160,8 @@ float distfactor_to_bone(
}
}
-static float dist_bone_deform(bPoseChannel *pchan,
- const bPoseChanDeform *pdef_info,
- float vec[3],
- DualQuat *dq,
- float mat[3][3],
- const float co[3])
+static float dist_bone_deform(
+ bPoseChannel *pchan, float vec[3], DualQuat *dq, float mat[3][3], const float co[3])
{
Bone *bone = pchan->bone;
float fac, contrib = 0.0;
@@ -1194,7 +1179,8 @@ static float dist_bone_deform(bPoseChannel *pchan,
if (bone->segments > 1 && pchan->runtime.bbone_segments == bone->segments)
b_bone_deform(pchan, co, fac, vec, dq, mat);
else
- pchan_deform_accumulate(pdef_info->dual_quat, pchan->chan_mat, co, fac, vec, dq, mat);
+ pchan_deform_accumulate(
+ &pchan->runtime.deform_dual_quat, pchan->chan_mat, co, fac, vec, dq, mat);
}
}
@@ -1202,7 +1188,6 @@ static float dist_bone_deform(bPoseChannel *pchan,
}
static void pchan_bone_deform(bPoseChannel *pchan,
- const bPoseChanDeform *pdef_info,
float weight,
float vec[3],
DualQuat *dq,
@@ -1218,33 +1203,12 @@ static void pchan_bone_deform(bPoseChannel *pchan,
if (bone->segments > 1 && pchan->runtime.bbone_segments == bone->segments)
b_bone_deform(pchan, co, weight, vec, dq, mat);
else
- pchan_deform_accumulate(pdef_info->dual_quat, pchan->chan_mat, co, weight, vec, dq, mat);
+ pchan_deform_accumulate(
+ &pchan->runtime.deform_dual_quat, pchan->chan_mat, co, weight, vec, dq, mat);
(*contrib) += weight;
}
-typedef struct ArmatureBBoneDefmatsData {
- bPoseChanDeform *pdef_info_array;
- DualQuat *dualquats;
- bool use_quaternion;
-} ArmatureBBoneDefmatsData;
-
-static void armature_bbone_defmats_cb(void *userdata, Link *iter, int index)
-{
- ArmatureBBoneDefmatsData *data = userdata;
- bPoseChannel *pchan = (bPoseChannel *)iter;
-
- if (!(pchan->bone->flag & BONE_NO_DEFORM)) {
- bPoseChanDeform *pdef_info = &data->pdef_info_array[index];
- const bool use_quaternion = data->use_quaternion;
-
- if (use_quaternion) {
- pdef_info->dual_quat = &data->dualquats[index];
- mat4_to_dquat(pdef_info->dual_quat, pchan->bone->arm_mat, pchan->chan_mat);
- }
- }
-}
-
void armature_deform_verts(Object *armOb,
Object *target,
const Mesh *mesh,
@@ -1256,10 +1220,8 @@ void armature_deform_verts(Object *armOb,
const char *defgrp_name,
bGPDstroke *gps)
{
- const bPoseChanDeform *pdef_info = NULL;
bArmature *arm = armOb->data;
bPoseChannel *pchan, **defnrToPC = NULL;
- int *defnrToPCIndex = NULL;
MDeformVert *dverts = NULL;
bDeformGroup *dg;
float obinv[4][4], premat[4][4], postmat[4][4];
@@ -1288,20 +1250,6 @@ void armature_deform_verts(Object *armOb,
mul_m4_m4m4(postmat, obinv, armOb->obmat);
invert_m4_m4(premat, postmat);
- /* Use pre-calculated bbone deformation.
- *
- * TODO(sergey): Make this code robust somehow when there are dependency
- * cycles involved. */
- ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(armOb);
- if (bbone_deform == NULL || bbone_deform->pdef_info_array == NULL) {
- CLOG_ERROR(&LOG,
- "Armature does not have bbone cache %s, "
- "usually happens due to a dependency cycle.\n",
- armOb->id.name + 2);
- return;
- }
- const bPoseChanDeform *pdef_info_array = bbone_deform->pdef_info_array;
-
/* get the def_nr for the overall armature vertex group if present */
armature_def_nr = defgroup_name_index(target, defgrp_name);
@@ -1340,19 +1288,10 @@ void armature_deform_verts(Object *armOb,
if (use_dverts) {
defnrToPC = MEM_callocN(sizeof(*defnrToPC) * defbase_tot, "defnrToBone");
- defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * defbase_tot, "defnrToIndex");
/* TODO(sergey): Some considerations here:
*
- * - Make it more generic function, maybe even keep together with chanhash.
* - Check whether keeping this consistent across frames gives speedup.
- * - Don't use hash for small armatures.
*/
- GHash *idx_hash = BLI_ghash_ptr_new("pose channel index by name");
- int pchan_index = 0;
- for (pchan = armOb->pose->chanbase.first; pchan != NULL;
- pchan = pchan->next, ++pchan_index) {
- BLI_ghash_insert(idx_hash, pchan, POINTER_FROM_INT(pchan_index));
- }
for (i = 0, dg = target->defbase.first; dg; i++, dg = dg->next) {
defnrToPC[i] = BKE_pose_channel_find_name(armOb->pose, dg->name);
/* exclude non-deforming bones */
@@ -1360,12 +1299,8 @@ void armature_deform_verts(Object *armOb,
if (defnrToPC[i]->bone->flag & BONE_NO_DEFORM) {
defnrToPC[i] = NULL;
}
- else {
- defnrToPCIndex[i] = POINTER_AS_INT(BLI_ghash_lookup(idx_hash, defnrToPC[i]));
- }
}
}
- BLI_ghash_free(idx_hash, NULL, NULL);
}
}
}
@@ -1440,7 +1375,6 @@ void armature_deform_verts(Object *armOb,
if (index >= 0 && index < defbase_tot && (pchan = defnrToPC[index])) {
float weight = dw->weight;
Bone *bone = pchan->bone;
- pdef_info = pdef_info_array + defnrToPCIndex[index];
deformed = 1;
@@ -1457,7 +1391,7 @@ void armature_deform_verts(Object *armOb,
acum_weight += weight;
}
- pchan_bone_deform(pchan, pdef_info, weight, vec, dq, smat, co, &contrib);
+ pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib);
/* if acumulated weight limit exceed, exit loop */
if ((target->type == OB_GPENCIL) && (acum_weight >= 1.0f)) {
@@ -1468,18 +1402,16 @@ void armature_deform_verts(Object *armOb,
/* if there are vertexgroups but not groups with bones
* (like for softbody groups) */
if (deformed == 0 && use_envelope) {
- pdef_info = pdef_info_array;
- for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) {
+ for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
if (!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
+ contrib += dist_bone_deform(pchan, vec, dq, smat, co);
}
}
}
else if (use_envelope) {
- pdef_info = pdef_info_array;
- for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) {
+ for (pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
if (!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
+ contrib += dist_bone_deform(pchan, vec, dq, smat, co);
}
}
@@ -1533,8 +1465,6 @@ void armature_deform_verts(Object *armOb,
if (defnrToPC)
MEM_freeN(defnrToPC);
- if (defnrToPCIndex)
- MEM_freeN(defnrToPCIndex);
}
/* ************ END Armature Deform ******************* */
@@ -2724,70 +2654,3 @@ bPoseChannel *BKE_armature_splineik_solver_find_root(bPoseChannel *pchan,
}
return rootchan;
}
-
-/* ****************************** BBone cache ****************************** */
-
-ObjectBBoneDeform *BKE_armature_cached_bbone_deformation_get(Object *object)
-{
- return object->runtime.cached_bbone_deformation;
-}
-
-void BKE_armature_cached_bbone_deformation_free_data(Object *object)
-{
- ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(object);
- if (bbone_deform == NULL) {
- return;
- }
- /* Free arrays. */
- MEM_SAFE_FREE(bbone_deform->pdef_info_array);
- MEM_SAFE_FREE(bbone_deform->dualquats);
- /* Tag that we've got no data, so we are safe for sequential calls to
- * data free. */
- bbone_deform->num_pchan = 0;
-}
-
-void BKE_armature_cached_bbone_deformation_free(Object *object)
-{
- ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(object);
- if (bbone_deform == NULL) {
- return;
- }
- BKE_armature_cached_bbone_deformation_free_data(object);
- MEM_freeN(bbone_deform);
- object->runtime.cached_bbone_deformation = NULL;
-}
-
-void BKE_armature_cached_bbone_deformation_update(Object *object)
-{
- BLI_assert(object->type == OB_ARMATURE);
- BLI_assert(object->pose != NULL);
- bPose *pose = object->pose;
- const int totchan = BLI_listbase_count(&pose->chanbase);
- const bool use_quaternion = true;
- /* Make sure cache exists. */
- ObjectBBoneDeform *bbone_deform = BKE_armature_cached_bbone_deformation_get(object);
- if (bbone_deform == NULL) {
- bbone_deform = MEM_callocN(sizeof(*bbone_deform), "bbone deform cache");
- object->runtime.cached_bbone_deformation = bbone_deform;
- }
- /* Make sure arrays are allocateds at the proper size. */
- BKE_armature_cached_bbone_deformation_free_data(object);
- DualQuat *dualquats = NULL;
- if (use_quaternion) {
- dualquats = MEM_calloc_arrayN(sizeof(DualQuat), totchan, "dualquats");
- }
- bPoseChanDeform *pdef_info_array = MEM_calloc_arrayN(
- sizeof(bPoseChanDeform), totchan, "bPoseChanDeform");
- /* Calculate deofrmation matricies. */
- ArmatureBBoneDefmatsData data = {
- .pdef_info_array = pdef_info_array,
- .dualquats = dualquats,
- .use_quaternion = use_quaternion,
- };
- BLI_task_parallel_listbase(&pose->chanbase, &data, armature_bbone_defmats_cb, totchan > 1024);
- /* Store pointers. */
- bbone_deform->dualquats = dualquats;
- atomic_cas_ptr(
- (void **)&bbone_deform->pdef_info_array, bbone_deform->pdef_info_array, pdef_info_array);
- bbone_deform->num_pchan = totchan;
-}
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index bf33b1c7c50..0f1ebc70b5b 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -618,8 +618,6 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Objec
}
BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase));
-
- BKE_armature_cached_bbone_deformation_free_data(object);
}
void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *object)
@@ -714,6 +712,9 @@ void BKE_pose_bone_done(struct Depsgraph *depsgraph, struct Object *object, int
if (pchan->bone) {
invert_m4_m4(imat, pchan->bone->arm_mat);
mul_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat);
+ if (!(pchan->bone->flag & BONE_NO_DEFORM)) {
+ mat4_to_dquat(&pchan->runtime.deform_dual_quat, pchan->bone->arm_mat, pchan->chan_mat);
+ }
}
if (DEG_is_active(depsgraph) && armature->edbo == NULL) {
bPoseChannel *pchan_orig = pchan->orig_pchan;
@@ -798,7 +799,6 @@ static void pose_eval_done_common(struct Depsgraph *depsgraph, Object *object)
bPose *pose = object->pose;
UNUSED_VARS_NDEBUG(pose);
BLI_assert(pose != NULL);
- BKE_armature_cached_bbone_deformation_update(object);
BKE_object_eval_boundbox(depsgraph, object);
}
static void pose_eval_cleanup_common(Object *object)
@@ -838,8 +838,6 @@ void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, Object *object)
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
BLI_assert(object->pose->chan_array != NULL || BLI_listbase_is_empty(&object->pose->chanbase));
-
- BKE_armature_cached_bbone_deformation_free_data(object);
}
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, Object *object)
@@ -877,5 +875,6 @@ void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, Object *object,
BLI_assert(pchan != NULL);
BLI_assert(pchan_from != NULL);
BKE_pose_copyesult_pchan_result(pchan, pchan_from);
+ copy_dq_dq(&pchan->runtime.deform_dual_quat, &pchan_from->runtime.deform_dual_quat);
BKE_pchan_bbone_segments_cache_copy(pchan, pchan_from);
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 303d63d6a8b..77086d9c6ac 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -444,7 +444,6 @@ void BKE_object_free_derived_caches(Object *ob)
object_update_from_subsurf_ccg(ob);
BKE_object_free_derived_mesh_caches(ob);
- BKE_armature_cached_bbone_deformation_free(ob);
if (ob->runtime.mesh_eval != NULL) {
Mesh *mesh_eval = ob->runtime.mesh_eval;
@@ -3886,7 +3885,6 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
runtime->mesh_deform_eval = NULL;
runtime->curve_cache = NULL;
runtime->gpencil_cache = NULL;
- runtime->cached_bbone_deformation = NULL;
}
/*
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index cde3f282427..7a4ac14970f 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -27,6 +27,8 @@
* \ingroup bli
*/
+#include "DNA_vec_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -215,14 +217,6 @@ void rotate_eulO(float eul[3], const short order, char axis, float angle);
/******************************* Dual Quaternions ****************************/
-typedef struct DualQuat {
- float quat[4];
- float trans[4];
-
- float scale[4][4];
- float scale_weight;
-} DualQuat;
-
void copy_dq_dq(DualQuat *r, const DualQuat *dq);
void normalize_dq(DualQuat *dq, float totw);
void add_weighted_dq_dq(DualQuat *r, const DualQuat *dq, float weight);
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index fd3409b266c..01f1dc42c44 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -31,6 +31,7 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
#include "DNA_view2d_types.h"
+#include "DNA_vec_types.h"
#include "DNA_userdef_types.h" /* ThemeWireColor */
struct Collection;
@@ -183,8 +184,11 @@ struct DualQuat;
struct Mat4;
typedef struct bPoseChannel_Runtime {
+ /* Cached dual quaternion for deformation. */
+ struct DualQuat deform_dual_quat;
+
+ /* B-Bone shape data: copy of the segment count for validation. */
int bbone_segments;
- char _pad[4];
/* Rest and posed matrices for segments. */
struct Mat4 *bbone_rest_mats;
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index dc23a6a1ee2..781a2216029 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -118,11 +118,6 @@ typedef struct LodLevel {
int obhysteresis;
} LodLevel;
-/* Forward declaration for cache bbone deformation information.
- *
- * TODO(sergey): Consider moving it to more appropriate place. */
-struct ObjectBBoneDeform;
-
struct CustomData_MeshMasks;
/* Not saved in file! */
@@ -166,10 +161,6 @@ typedef struct Object_Runtime {
/** Runtime grease pencil drawing data */
struct GpencilBatchCache *gpencil_cache;
-
- struct ObjectBBoneDeform *cached_bbone_deformation;
-
- void *_pad1;
} Object_Runtime;
typedef struct Object {
diff --git a/source/blender/makesdna/DNA_vec_types.h b/source/blender/makesdna/DNA_vec_types.h
index 06e6d881d0e..72a6056e239 100644
--- a/source/blender/makesdna/DNA_vec_types.h
+++ b/source/blender/makesdna/DNA_vec_types.h
@@ -83,4 +83,13 @@ typedef struct rctf {
float ymin, ymax;
} rctf;
+/** dual quaternion. */
+typedef struct DualQuat {
+ float quat[4];
+ float trans[4];
+
+ float scale[4][4];
+ float scale_weight;
+} DualQuat;
+
#endif