Refactor: move Pose .blend I/O to blenkernel

Ref T76372.
This commit is contained in:
Jacques Lucke 2020-11-06 17:58:12 +01:00
parent 60ad4a761a
commit 2acf01ec62
Notes: blender-bot 2023-02-14 06:25:25 +01:00
Referenced by issue #76372, Blenloader Decentralization
4 changed files with 187 additions and 180 deletions

View File

@ -30,6 +30,12 @@
extern "C" {
#endif
struct BlendWriter;
struct BlendDataReader;
struct BlendLibReader;
struct BlendExpander;
struct bArmature;
/* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */
struct AnimationEvalContext;
struct FCurve;
@ -216,6 +222,11 @@ void BKE_pose_rest(struct bPose *pose, bool selected_bones_only);
/* Tag pose for recalc. Also tag all related data to be recalc. */
void BKE_pose_tag_recalc(struct Main *bmain, struct bPose *pose);
void BKE_pose_blend_write(struct BlendWriter *writer, struct bPose *pose, struct bArmature *arm);
void BKE_pose_blend_read_data(struct BlendDataReader *reader, struct bPose *pose);
void BKE_pose_blend_read_lib(struct BlendLibReader *reader, struct Object *ob, struct bPose *pose);
void BKE_pose_blend_read_expand(struct BlendExpander *expander, struct bPose *pose);
#ifdef __cplusplus
};
#endif

View File

@ -61,6 +61,7 @@
#include "BKE_main.h"
#include "BKE_object.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BIK_api.h"
@ -1846,3 +1847,174 @@ void BKE_pose_check_uuids_unique_and_report(const bPose *pose)
BLI_gset_free(used_uuids, NULL);
}
void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm)
{
/* Write each channel */
if (pose == NULL) {
return;
}
BLI_assert(arm != NULL);
/* Write channels */
LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
if (chan->prop) {
IDP_BlendWrite(writer, chan->prop);
}
BKE_constraint_blend_write(writer, &chan->constraints);
animviz_motionpath_blend_write(writer, chan->mpath);
/* Prevent crashes with autosave,
* when a bone duplicated in edit-mode has not yet been assigned to its pose-channel.
* Also needed with memundo, in some cases we can store a step before pose has been
* properly rebuilt from previous undo step. */
Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, chan->name) :
chan->bone;
if (bone != NULL) {
/* gets restored on read, for library armatures */
chan->selectflag = bone->flag & BONE_SELECTED;
}
BLO_write_struct(writer, bPoseChannel, chan);
}
/* Write groups */
LISTBASE_FOREACH (bActionGroup *, grp, &pose->agroups) {
BLO_write_struct(writer, bActionGroup, grp);
}
/* write IK param */
if (pose->ikparam) {
const char *structname = BKE_pose_ikparam_get_name(pose);
if (structname) {
BLO_write_struct_by_name(writer, structname, pose->ikparam);
}
}
/* Write this pose */
BLO_write_struct(writer, bPose, pose);
}
void BKE_pose_blend_read_data(BlendDataReader *reader, bPose *pose)
{
if (!pose) {
return;
}
BLO_read_list(reader, &pose->chanbase);
BLO_read_list(reader, &pose->agroups);
pose->chanhash = NULL;
pose->chan_array = NULL;
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
BKE_pose_channel_runtime_reset(&pchan->runtime);
BKE_pose_channel_session_uuid_generate(pchan);
pchan->bone = NULL;
BLO_read_data_address(reader, &pchan->parent);
BLO_read_data_address(reader, &pchan->child);
BLO_read_data_address(reader, &pchan->custom_tx);
BLO_read_data_address(reader, &pchan->bbone_prev);
BLO_read_data_address(reader, &pchan->bbone_next);
BKE_constraint_blend_read_data(reader, &pchan->constraints);
BLO_read_data_address(reader, &pchan->prop);
IDP_BlendDataRead(reader, &pchan->prop);
BLO_read_data_address(reader, &pchan->mpath);
if (pchan->mpath) {
animviz_motionpath_blend_read_data(reader, pchan->mpath);
}
BLI_listbase_clear(&pchan->iktree);
BLI_listbase_clear(&pchan->siktree);
/* in case this value changes in future, clamp else we get undefined behavior */
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
pchan->draw_data = NULL;
}
pose->ikdata = NULL;
if (pose->ikparam != NULL) {
BLO_read_data_address(reader, &pose->ikparam);
}
}
void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose)
{
bArmature *arm = ob->data;
if (!pose || !arm) {
return;
}
/* always rebuild to match proxy or lib changes, but on Undo */
bool rebuild = false;
if (!BLO_read_lib_is_undo(reader)) {
if (ob->proxy || ob->id.lib != arm->id.lib) {
rebuild = true;
}
}
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer) {
arm->layer = pose->proxy_layer;
}
/* sync proxy active bone */
if (pose->proxy_act_bone[0]) {
Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
if (bone) {
arm->act_bone = bone;
}
}
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
BKE_constraint_blend_read_lib(reader, (ID *)ob, &pchan->constraints);
pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
IDP_BlendReadLib(reader, pchan->prop);
BLO_read_id_address(reader, arm->id.lib, &pchan->custom);
if (UNLIKELY(pchan->bone == NULL)) {
rebuild = true;
}
else if ((ob->id.lib == NULL) && arm->id.lib) {
/* local pose selection copied to armature, bit hackish */
pchan->bone->flag &= ~BONE_SELECTED;
pchan->bone->flag |= pchan->selectflag;
}
}
if (rebuild) {
Main *bmain = BLO_read_lib_get_main(reader);
DEG_id_tag_update_ex(
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
BKE_pose_tag_recalc(bmain, pose);
}
}
void BKE_pose_blend_read_expand(BlendExpander *expander, bPose *pose)
{
if (!pose) {
return;
}
LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
BKE_constraint_blend_read_expand(expander, &chan->constraints);
IDP_BlendReadExpand(expander, chan->prop);
BLO_expand(expander, chan->custom);
}
}

View File

@ -2568,69 +2568,6 @@ static void lib_link_constraint_channels(BlendLibReader *reader, ID *id, ListBas
/** \} */
/* -------------------------------------------------------------------- */
/** \name Read ID: Armature
* \{ */
static void lib_link_pose(BlendLibReader *reader, Object *ob, bPose *pose)
{
bArmature *arm = ob->data;
if (!pose || !arm) {
return;
}
/* always rebuild to match proxy or lib changes, but on Undo */
bool rebuild = false;
if (!BLO_read_lib_is_undo(reader)) {
if (ob->proxy || ob->id.lib != arm->id.lib) {
rebuild = true;
}
}
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer) {
arm->layer = pose->proxy_layer;
}
/* sync proxy active bone */
if (pose->proxy_act_bone[0]) {
Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
if (bone) {
arm->act_bone = bone;
}
}
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
BKE_constraint_blend_read_lib(reader, (ID *)ob, &pchan->constraints);
pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
IDP_BlendReadLib(reader, pchan->prop);
BLO_read_id_address(reader, arm->id.lib, &pchan->custom);
if (UNLIKELY(pchan->bone == NULL)) {
rebuild = true;
}
else if ((ob->id.lib == NULL) && arm->id.lib) {
/* local pose selection copied to armature, bit hackish */
pchan->bone->flag &= ~BONE_SELECTED;
pchan->bone->flag |= pchan->selectflag;
}
}
if (rebuild) {
DEG_id_tag_update_ex(
reader->main, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
BKE_pose_tag_recalc(reader->main, pose);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Read ID: Shape Keys
* \{ */
@ -2750,7 +2687,7 @@ static void lib_link_object(BlendLibReader *reader, Object *ob)
/* if id.us==0 a new base will be created later on */
/* WARNING! Also check expand_object(), should reflect the stuff below. */
lib_link_pose(reader, ob, ob->pose);
BKE_pose_blend_read_lib(reader, ob, ob->pose);
BKE_constraint_blend_read_lib(reader, &ob->id, &ob->constraints);
/* XXX deprecated - old animation system <<< */
@ -2816,54 +2753,6 @@ static void lib_link_object(BlendLibReader *reader, Object *ob)
}
}
static void direct_link_pose(BlendDataReader *reader, bPose *pose)
{
if (!pose) {
return;
}
BLO_read_list(reader, &pose->chanbase);
BLO_read_list(reader, &pose->agroups);
pose->chanhash = NULL;
pose->chan_array = NULL;
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
BKE_pose_channel_runtime_reset(&pchan->runtime);
BKE_pose_channel_session_uuid_generate(pchan);
pchan->bone = NULL;
BLO_read_data_address(reader, &pchan->parent);
BLO_read_data_address(reader, &pchan->child);
BLO_read_data_address(reader, &pchan->custom_tx);
BLO_read_data_address(reader, &pchan->bbone_prev);
BLO_read_data_address(reader, &pchan->bbone_next);
BKE_constraint_blend_read_data(reader, &pchan->constraints);
BLO_read_data_address(reader, &pchan->prop);
IDP_BlendDataRead(reader, &pchan->prop);
BLO_read_data_address(reader, &pchan->mpath);
if (pchan->mpath) {
animviz_motionpath_blend_read_data(reader, pchan->mpath);
}
BLI_listbase_clear(&pchan->iktree);
BLI_listbase_clear(&pchan->siktree);
/* in case this value changes in future, clamp else we get undefined behavior */
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
pchan->draw_data = NULL;
}
pose->ikdata = NULL;
if (pose->ikparam != NULL) {
BLO_read_data_address(reader, &pose->ikparam);
}
}
static void direct_link_object(BlendDataReader *reader, Object *ob)
{
PartEff *paf;
@ -2889,7 +2778,7 @@ static void direct_link_object(BlendDataReader *reader, Object *ob)
BKE_animdata_blend_read_data(reader, ob->adt);
BLO_read_data_address(reader, &ob->pose);
direct_link_pose(reader, ob->pose);
BKE_pose_blend_read_data(reader, ob->pose);
BLO_read_data_address(reader, &ob->mpath);
if (ob->mpath) {
@ -5177,19 +5066,6 @@ static void expand_id(BlendExpander *expander, ID *id)
expand_id_embedded_id(expander, id);
}
static void expand_pose(BlendExpander *expander, bPose *pose)
{
if (!pose) {
return;
}
LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
BKE_constraint_blend_read_expand(expander, &chan->constraints);
IDP_BlendReadExpand(expander, chan->prop);
BLO_expand(expander, chan->custom);
}
}
static void expand_object_expandModifiers(void *userData,
Object *UNUSED(ob),
ID **idpoin,
@ -5218,7 +5094,7 @@ static void expand_object(BlendExpander *expander, Object *ob)
BKE_shaderfx_foreach_ID_link(ob, expand_object_expandModifiers, expander);
}
expand_pose(expander, ob->pose);
BKE_pose_blend_read_expand(expander, ob->pose);
BLO_expand(expander, ob->poselib);
BKE_constraint_blend_read_expand(expander, &ob->constraints);

View File

@ -811,58 +811,6 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef)
}
}
static void write_pose(BlendWriter *writer, bPose *pose, bArmature *arm)
{
/* Write each channel */
if (pose == NULL) {
return;
}
BLI_assert(arm != NULL);
/* Write channels */
LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
if (chan->prop) {
IDP_BlendWrite(writer, chan->prop);
}
BKE_constraint_blend_write(writer, &chan->constraints);
animviz_motionpath_blend_write(writer, chan->mpath);
/* Prevent crashes with autosave,
* when a bone duplicated in edit-mode has not yet been assigned to its pose-channel.
* Also needed with memundo, in some cases we can store a step before pose has been
* properly rebuilt from previous undo step. */
Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, chan->name) :
chan->bone;
if (bone != NULL) {
/* gets restored on read, for library armatures */
chan->selectflag = bone->flag & BONE_SELECTED;
}
BLO_write_struct(writer, bPoseChannel, chan);
}
/* Write groups */
LISTBASE_FOREACH (bActionGroup *, grp, &pose->agroups) {
BLO_write_struct(writer, bActionGroup, grp);
}
/* write IK param */
if (pose->ikparam) {
const char *structname = BKE_pose_ikparam_get_name(pose);
if (structname) {
BLO_write_struct_by_name(writer, structname, pose->ikparam);
}
}
/* Write this pose */
BLO_write_struct(writer, bPose, pose);
}
static void write_defgroups(BlendWriter *writer, ListBase *defbase)
{
LISTBASE_FOREACH (bDeformGroup *, defgroup, defbase) {
@ -911,7 +859,7 @@ static void write_object(BlendWriter *writer, Object *ob, const void *id_address
}
}
write_pose(writer, ob->pose, arm);
BKE_pose_blend_write(writer, ob->pose, arm);
write_defgroups(writer, &ob->defbase);
write_fmaps(writer, &ob->fmaps);
BKE_constraint_blend_write(writer, &ob->constraints);