parent
60ad4a761a
commit
2acf01ec62
Notes:
blender-bot
2023-02-14 06:25:25 +01:00
Referenced by issue #76372, Blenloader Decentralization
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue