Cleanup: Move each recalcData to their respective TransData file

This commit is contained in:
Germano Cavalcante 2020-06-07 18:48:33 -03:00
parent 826769d1c7
commit e54fb1b819
Notes: blender-bot 2023-02-14 05:59:31 +01:00
Referenced by issue #78045, CTL-ALT-S does nothing in pose mode, crashes when called from the menu
20 changed files with 1559 additions and 1522 deletions

View File

@ -427,6 +427,11 @@ typedef struct TransDataContainer {
typedef struct TransInfo {
TransDataContainer *data_container;
int data_container_len;
/** eTransConvertType
* TODO: It should be a member of TransDataContainer. */
int data_type;
/** Combine length of all #TransDataContainer.data_len
* Use to check if nothing is selected or if we have a single selection. */
int data_len_all;

View File

@ -35,6 +35,8 @@
#include "BLI_math.h"
#include "BLI_string.h"
#include "BKE_action.h"
#include "BKE_anim_data.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_context.h"
@ -44,6 +46,7 @@
#include "BKE_gpencil.h"
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mask.h"
#include "BKE_modifier.h"
@ -68,6 +71,8 @@
#include "ED_node.h"
#include "ED_object.h"
#include "ED_particle.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "UI_view2d.h"
@ -80,8 +85,11 @@
#include "DEG_depsgraph_build.h"
#include "transform.h"
#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
bool transform_mode_use_local_origins(const TransInfo *t)
{
@ -2504,253 +2512,114 @@ void createTransData(bContext *C, TransInfo *t)
ViewLayer *view_layer = t->view_layer;
Object *ob = OBACT(view_layer);
bool has_transform_context = true;
t->data_len_all = -1;
eTransConvertType convert_type = TC_NONE;
/* if tests must match recalcData for correct updates */
if (t->options & CTX_CURSOR) {
t->flag |= T_CURSOR;
if (t->spacetype == SPACE_IMAGE) {
createTransCursor_image(t);
convert_type = TC_CURSOR_IMAGE;
}
else {
createTransCursor_view3d(t);
convert_type = TC_CURSOR_VIEW3D;
}
countAndCleanTransDataContainer(t);
}
else if ((t->options & CTX_SCULPT) && !(t->options & CTX_PAINT_CURVE)) {
createTransSculpt(t);
countAndCleanTransDataContainer(t);
convert_type = TC_SCULPT;
}
else if (t->options & CTX_TEXTURE) {
t->flag |= T_TEXTURE;
createTransTexspace(t);
countAndCleanTransDataContainer(t);
convert_type = TC_OBJECT_TEXSPACE;
}
else if (t->options & CTX_EDGE) {
t->flag |= T_EDIT;
convert_type = TC_MESH_EDGES;
/* Multi object editing. */
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
tc->data_ext = NULL;
}
t->flag |= T_EDIT;
createTransEdge(t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && t->flag & T_PROP_EDIT) {
sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
}
else if (t->options & CTX_GPENCIL_STROKES) {
t->options |= CTX_GPENCIL_STROKES;
t->flag |= T_POINTS | T_EDIT;
convert_type = TC_GPENCIL;
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
createTransGPencil(C, t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
}
else if (t->spacetype == SPACE_IMAGE) {
t->flag |= T_POINTS | T_2D_EDIT;
if (t->options & CTX_MASK) {
/* copied from below */
createTransMaskingData(C, t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data_selected_first(t);
set_prop_dist(t, true);
sort_trans_data_dist(t);
}
convert_type = TC_MASKING_DATA;
}
else if (t->options & CTX_PAINT_CURVE) {
if (!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
createTransPaintCurveVerts(C, t);
countAndCleanTransDataContainer(t);
}
else {
has_transform_context = false;
convert_type = TC_PAINT_CURVE_VERTS;
}
}
else if (t->obedit_type == OB_MESH) {
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
createTransUVs(C, t);
countAndCleanTransDataContainer(t);
t->flag |= T_EDIT;
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
}
else {
has_transform_context = false;
convert_type = TC_MESH_UV;
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
}
else if (t->spacetype == SPACE_ACTION) {
t->flag |= T_POINTS | T_2D_EDIT;
t->obedit_type = -1;
createTransActionData(C, t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data_selected_first(t);
/* don't do that, distance has been set in createTransActionData already */
// set_prop_dist(t, false);
sort_trans_data_dist(t);
}
convert_type = TC_ACTION_DATA;
}
else if (t->spacetype == SPACE_NLA) {
t->flag |= T_POINTS | T_2D_EDIT;
t->obedit_type = -1;
createTransNlaData(C, t);
countAndCleanTransDataContainer(t);
convert_type = TC_NLA_DATA;
}
else if (t->spacetype == SPACE_SEQ) {
t->flag |= T_POINTS | T_2D_EDIT;
t->obedit_type = -1;
t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point trasnform */
createTransSeqData(t);
countAndCleanTransDataContainer(t);
convert_type = TC_SEQ_DATA;
}
else if (t->spacetype == SPACE_GRAPH) {
t->flag |= T_POINTS | T_2D_EDIT;
t->obedit_type = -1;
createTransGraphEditData(C, t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
/* makes selected become first in array */
sort_trans_data_selected_first(t);
/* don't do that, distance has been set in createTransGraphEditData already */
set_prop_dist(t, false);
sort_trans_data_dist(t);
}
convert_type = TC_GRAPH_EDIT_DATA;
}
else if (t->spacetype == SPACE_NODE) {
t->flag |= T_POINTS | T_2D_EDIT;
t->obedit_type = -1;
createTransNodeData(C, t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
convert_type = TC_NODE_DATA;
}
else if (t->spacetype == SPACE_CLIP) {
t->flag |= T_POINTS | T_2D_EDIT;
t->obedit_type = -1;
if (t->options & CTX_MOVIECLIP) {
createTransTrackingData(C, t);
countAndCleanTransDataContainer(t);
convert_type = TC_TRACKING_DATA;
}
else if (t->options & CTX_MASK) {
/* copied from above */
createTransMaskingData(C, t);
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data_selected_first(t);
set_prop_dist(t, true);
sort_trans_data_dist(t);
}
}
else {
has_transform_context = false;
convert_type = TC_MASKING_DATA;
}
}
else if (t->obedit_type != -1) {
t->flag |= T_EDIT | T_POINTS;
/* Multi object editing. */
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
tc->data_ext = NULL;
}
if (t->obedit_type == OB_MESH) {
createTransEditVerts(t);
convert_type = TC_MESH_VERTS;
}
else if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
createTransCurveVerts(t);
convert_type = TC_CURVE_VERTS;
}
else if (t->obedit_type == OB_LATTICE) {
createTransLatticeVerts(t);
convert_type = TC_LATTICE_VERTS;
}
else if (t->obedit_type == OB_MBALL) {
createTransMBallVerts(t);
convert_type = TC_MBALL_VERTS;
}
else if (t->obedit_type == OB_ARMATURE) {
t->flag &= ~T_PROP_EDIT;
createTransArmatureVerts(t);
}
else {
printf("edit type not implemented!\n");
}
countAndCleanTransDataContainer(t);
t->flag |= T_EDIT | T_POINTS;
if (t->data_len_all) {
if (t->flag & T_PROP_EDIT) {
if (ELEM(t->obedit_type, OB_CURVE, OB_MESH)) {
sort_trans_data_selected_first(t);
if ((t->obedit_type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) {
/* already calculated by editmesh_set_connectivity_distance */
}
else {
set_prop_dist(t, 0);
}
sort_trans_data_dist(t);
}
else {
sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
}
else {
if (ELEM(t->obedit_type, OB_CURVE)) {
/* Needed because bezier handles can be partially selected
* and are still added into transform data. */
sort_trans_data_selected_first(t);
}
}
}
/* exception... hackish, we want bonesize to use bone orientation matrix (ton) */
if (t->mode == TFM_BONESIZE) {
t->flag &= ~(T_EDIT | T_POINTS);
t->flag |= T_POSE;
t->obedit_type = -1;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
tc->poseobj = tc->obedit;
tc->obedit = NULL;
}
convert_type = TC_ARMATURE_VERTS;
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
@ -2761,13 +2630,11 @@ void createTransData(bContext *C, TransInfo *t)
/* Multi object editing. */
initTransDataContainers_FromObjectData(t, ob, NULL, 0);
createTransPose(t);
countAndCleanTransDataContainer(t);
convert_type = TC_POSE;
}
else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
/* important that ob_armature can be set even when its not selected [#23412]
* lines below just check is also visible */
has_transform_context = false;
Object *ob_armature = BKE_modifiers_is_deformed_by_armature(ob);
if (ob_armature && ob_armature->mode & OB_MODE_POSE) {
Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
@ -2778,33 +2645,20 @@ void createTransData(bContext *C, TransInfo *t)
objects[0] = ob_armature;
uint objects_len = 1;
initTransDataContainers_FromObjectData(t, ob_armature, objects, objects_len);
createTransPose(t);
countAndCleanTransDataContainer(t);
has_transform_context = true;
convert_type = TC_POSE;
}
}
}
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) &&
PE_start_edit(PE_get_current(t->depsgraph, scene, ob))) {
createTransParticleVerts(C, t);
countAndCleanTransDataContainer(t);
t->flag |= T_POINTS;
if (t->data_len_all && t->flag & T_PROP_EDIT) {
sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
convert_type = TC_PARTICLE_VERTS;
}
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransPaintCurveVerts(C, t);
countAndCleanTransDataContainer(t);
}
else {
has_transform_context = false;
convert_type = TC_PAINT_CURVE_VERTS;
}
}
else if ((ob) && (ELEM(ob->mode,
@ -2813,7 +2667,6 @@ void createTransData(bContext *C, TransInfo *t)
OB_MODE_WEIGHT_GPENCIL,
OB_MODE_VERTEX_GPENCIL))) {
/* In grease pencil all transformations must be canceled if not Object or Edit. */
has_transform_context = false;
}
else {
/* Needed for correct Object.obmat after duplication, see: T62135. */
@ -2826,16 +2679,8 @@ void createTransData(bContext *C, TransInfo *t)
t->options |= CTX_OBMODE_XFORM_SKIP_CHILDREN;
}
createTransObject(C, t);
countAndCleanTransDataContainer(t);
t->flag |= T_OBJECT;
if (t->data_len_all && t->flag & T_PROP_EDIT) {
// selected objects are already first, no need to presort
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
/* Check if we're transforming the camera from the camera */
if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
View3D *v3d = t->view;
@ -2850,18 +2695,417 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_CAMERA;
}
}
convert_type = TC_OBJECT;
}
/* Check that 'countAndCleanTransDataContainer' ran. */
if (has_transform_context) {
BLI_assert(t->data_len_all != -1);
t->data_type = convert_type;
bool init_prop_edit = (t->flag & T_PROP_EDIT) != 0;
switch (convert_type) {
case TC_ACTION_DATA:
createTransActionData(C, t);
break;
case TC_POSE:
createTransPose(t);
init_prop_edit = false;
break;
case TC_ARMATURE_VERTS:
createTransArmatureVerts(t);
break;
case TC_CURSOR_IMAGE:
createTransCursor_image(t);
init_prop_edit = false;
break;
case TC_CURSOR_VIEW3D:
createTransCursor_view3d(t);
init_prop_edit = false;
break;
case TC_CURVE_VERTS:
createTransCurveVerts(t);
break;
case TC_GRAPH_EDIT_DATA:
createTransGraphEditData(C, t);
break;
case TC_GPENCIL:
createTransGPencil(C, t);
break;
case TC_LATTICE_VERTS:
createTransLatticeVerts(t);
break;
case TC_MASKING_DATA:
createTransMaskingData(C, t);
break;
case TC_MBALL_VERTS:
createTransMBallVerts(t);
break;
case TC_MESH_VERTS:
createTransEditVerts(t);
break;
case TC_MESH_EDGES:
createTransEdge(t);
break;
case TC_MESH_UV:
createTransUVs(C, t);
break;
case TC_NLA_DATA:
createTransNlaData(C, t);
init_prop_edit = false;
break;
case TC_NODE_DATA:
createTransNodeData(t);
break;
case TC_OBJECT:
createTransObject(C, t);
break;
case TC_OBJECT_TEXSPACE:
createTransTexspace(t);
init_prop_edit = false;
break;
case TC_PAINT_CURVE_VERTS:
createTransPaintCurveVerts(C, t);
init_prop_edit = false;
break;
case TC_PARTICLE_VERTS:
createTransParticleVerts(C, t);
break;
case TC_SCULPT:
createTransSculpt(t);
init_prop_edit = false;
break;
case TC_SEQ_DATA:
createTransSeqData(t);
init_prop_edit = false;
break;
case TC_TRACKING_DATA:
createTransTrackingData(C, t);
init_prop_edit = false;
break;
case TC_NONE:
default:
printf("edit type not implemented!\n");
BLI_assert(t->data_len_all == -1);
t->data_len_all = 0;
return;
}
countAndCleanTransDataContainer(t);
if (t->data_len_all && init_prop_edit) {
if (convert_type == TC_OBJECT) {
/* Selected objects are already first, no need to presort. */
}
else {
sort_trans_data_selected_first(t);
}
if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
/* Distance has already been set. */
}
else if (convert_type == TC_MESH_VERTS) {
if (t->flag & T_PROP_CONNECTED) {
/* Already calculated by editmesh_set_connectivity_distance. */
}
else {
set_prop_dist(t, false);
}
}
else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
set_prop_dist(t, false);
}
else {
set_prop_dist(t, true);
}
sort_trans_data_dist(t);
}
else {
BLI_assert(t->data_len_all == -1);
t->data_len_all = 0;
if (ELEM(t->obedit_type, OB_CURVE)) {
/* Needed because bezier handles can be partially selected
* and are still added into transform data. */
sort_trans_data_selected_first(t);
}
}
/* exception... hackish, we want bonesize to use bone orientation matrix (ton) */
if (t->mode == TFM_BONESIZE) {
t->flag &= ~(T_EDIT | T_POINTS);
t->flag |= T_POSE;
t->obedit_type = -1;
t->data_type = TC_NONE;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
tc->poseobj = tc->obedit;
tc->obedit = NULL;
}
}
BLI_assert((!(t->flag & T_EDIT)) == (!(t->obedit_type != -1)));
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Transform Data Recalc/Flush
* \{ */
void clipMirrorModifier(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->obedit;
ModifierData *md = ob->modifiers.first;
float tolerance[3] = {0.0f, 0.0f, 0.0f};
int axis = 0;
for (; md; md = md->next) {
if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
MirrorModifierData *mmd = (MirrorModifierData *)md;
if (mmd->flag & MOD_MIR_CLIPPING) {
axis = 0;
if (mmd->flag & MOD_MIR_AXIS_X) {
axis |= 1;
tolerance[0] = mmd->tolerance;
}
if (mmd->flag & MOD_MIR_AXIS_Y) {
axis |= 2;
tolerance[1] = mmd->tolerance;
}
if (mmd->flag & MOD_MIR_AXIS_Z) {
axis |= 4;
tolerance[2] = mmd->tolerance;
}
if (axis) {
float mtx[4][4], imtx[4][4];
int i;
if (mmd->mirror_ob) {
float obinv[4][4];
invert_m4_m4(obinv, mmd->mirror_ob->obmat);
mul_m4_m4m4(mtx, obinv, ob->obmat);
invert_m4_m4(imtx, mtx);
}
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
int clip;
float loc[3], iloc[3];
if (td->loc == NULL) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
copy_v3_v3(loc, td->loc);
copy_v3_v3(iloc, td->iloc);
if (mmd->mirror_ob) {
mul_m4_v3(mtx, loc);
mul_m4_v3(mtx, iloc);
}
clip = 0;
if (axis & 1) {
if (fabsf(iloc[0]) <= tolerance[0] || loc[0] * iloc[0] < 0.0f) {
loc[0] = 0.0f;
clip = 1;
}
}
if (axis & 2) {
if (fabsf(iloc[1]) <= tolerance[1] || loc[1] * iloc[1] < 0.0f) {
loc[1] = 0.0f;
clip = 1;
}
}
if (axis & 4) {
if (fabsf(iloc[2]) <= tolerance[2] || loc[2] * iloc[2] < 0.0f) {
loc[2] = 0.0f;
clip = 1;
}
}
if (clip) {
if (mmd->mirror_ob) {
mul_m4_v3(imtx, loc);
}
copy_v3_v3(td->loc, loc);
}
}
}
}
}
}
}
}
/* for the realtime animation recording feature, handle overlapping data */
void animrecord_check_state(TransInfo *t, struct Object *ob)
{
Scene *scene = t->scene;
ID *id = &ob->id;
wmTimer *animtimer = t->animtimer;
ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL;
/* sanity checks */
if (ELEM(NULL, scene, id, sad)) {
return;
}
/* check if we need a new strip if:
* - if animtimer is running
* - we're not only keying for available channels
* - the option to add new actions for each round is not enabled
*/
if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL) == 0 &&
(scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) {
/* if playback has just looped around,
* we need to add a new NLA track+strip to allow a clean pass to occur */
if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
AnimData *adt = BKE_animdata_from_id(id);
const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
/* perform push-down manually with some differences
* NOTE: BKE_nla_action_pushdown() sync warning...
*/
if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) {
float astart, aend;
/* only push down if action is more than 1-2 frames long */
calc_action_range(adt->action, &astart, &aend, 1);
if (aend > astart + 2.0f) {
NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action);
/* clear reference to action now that we've pushed it onto the stack */
id_us_min(&adt->action->id);
adt->action = NULL;
/* adjust blending + extend so that they will behave correctly */
strip->extendmode = NLASTRIP_EXTEND_NOTHING;
strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS | NLASTRIP_FLAG_SELECT |
NLASTRIP_FLAG_ACTIVE);
/* copy current "action blending" settings from adt to the strip,
* as it was keyframed with these settings, so omitting them will
* change the effect [T54766]
*/
if (is_first == false) {
strip->blendmode = adt->act_blendmode;
strip->influence = adt->act_influence;
if (adt->act_influence < 1.0f) {
/* enable "user-controlled" influence (which will insert a default keyframe)
* so that the influence doesn't get lost on the new update
*
* NOTE: An alternative way would have been to instead hack the influence
* to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
* is disabled but auto-blending isn't being used. However, that approach
* is a bit hacky/hard to discover, and may cause backwards compatibility issues,
* so it's better to just do it this way.
*/
strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
BKE_nlastrip_validate_fcurves(strip);
}
}
/* also, adjust the AnimData's action extend mode to be on
* 'nothing' so that previous result still play
*/
adt->act_extendmode = NLASTRIP_EXTEND_NOTHING;
}
}
}
}
}
static void recalcData_cursor(TransInfo *t)
{
DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE);
}
static void recalcData_obedit(TransInfo *t)
{
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->data_len) {
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
}
}
}
/* called for updating while transform acts, once per redraw */
void recalcData(TransInfo *t)
{
switch (t->data_type) {
case TC_ACTION_DATA:
recalcData_actedit(t);
break;
case TC_POSE:
recalcData_pose(t);
break;
case TC_ARMATURE_VERTS:
recalcData_edit_armature(t);
break;
case TC_CURVE_VERTS:
recalcData_curve(t);
break;
case TC_CURSOR_IMAGE:
case TC_CURSOR_VIEW3D:
recalcData_cursor(t);
break;
case TC_GRAPH_EDIT_DATA:
recalcData_graphedit(t);
break;
case TC_GPENCIL:
recalcData_gpencil_strokes(t);
break;
case TC_MASKING_DATA:
recalcData_mask_common(t);
break;
case TC_MESH_VERTS:
case TC_MESH_EDGES:
recalcData_mesh(t);
break;
case TC_MESH_UV:
recalcData_uv(t);
break;
case TC_NLA_DATA:
recalcData_nla(t);
break;
case TC_NODE_DATA:
flushTransNodes(t);
break;
case TC_OBJECT:
case TC_OBJECT_TEXSPACE:
recalcData_objects(t);
break;
case TC_PAINT_CURVE_VERTS:
flushTransPaintCurve(t);
break;
case TC_SCULPT:
recalcData_sculpt(t);
break;
case TC_SEQ_DATA:
recalcData_sequencer(t);
break;
case TC_TRACKING_DATA:
recalcData_tracking(t);
break;
case TC_MBALL_VERTS:
case TC_LATTICE_VERTS:
recalcData_obedit(t);
break;
case TC_PARTICLE_VERTS:
recalcData_particles(t);
break;
case TC_NONE:
default:
break;
}
}
/** \} */

View File

@ -52,72 +52,71 @@ void autokeyframe_pose(
bool motionpath_need_update_object(struct Scene *scene, struct Object *ob);
bool motionpath_need_update_pose(struct Scene *scene, struct Object *ob);
int special_transform_moving(TransInfo *t);
void remake_graph_transdata(TransInfo *t, struct ListBase *anim_data);
void special_aftertrans_update(struct bContext *C, TransInfo *t);
void sort_trans_data_dist(TransInfo *t);
void createTransData(struct bContext *C, TransInfo *t);
bool clipUVTransform(TransInfo *t, float vec[2], const bool resize);
void clipUVData(TransInfo *t);
/* transform_convert_action.c */
void flushTransIntFrameActionData(TransInfo *t);
/* transform_convert_armature.c */
void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *ob);
void restoreMirrorPoseBones(TransDataContainer *tc);
void restoreBones(TransDataContainer *tc);
/* transform_convert_graph.c */
void flushTransGraphData(TransInfo *t);
/* transform_convert_mask.c */
void flushTransMasking(TransInfo *t);
void recalcData(TransInfo *t);
/* transform_convert_mesh.c */
void trans_mesh_customdata_correction_init(TransInfo *t);
void trans_mesh_customdata_correction_apply(struct TransDataContainer *tc, bool is_final);
/* transform_convert_mesh_uv.c */
void flushTransUVs(TransInfo *t);
/* transform_convert_node.c */
void flushTransNodes(TransInfo *t);
/* transform_convert_object.c */
void trans_obdata_in_obmode_update_all(struct TransInfo *t);
void trans_obchild_in_obmode_update_all(struct TransInfo *t);
/* transform_convert_paintcurve.c */
void flushTransPaintCurve(TransInfo *t);
/* transform_convert_particle.c */
void flushTransParticles(TransInfo *t);
/* transform_convert_sequencer.c */
void flushTransSeq(TransInfo *t);
int transform_convert_sequencer_get_snap_bound(TransInfo *t);
/* transform_convert_tracking.c */
void flushTransTracking(TransInfo *t);
/********************* intern **********************/
typedef enum eTransConvertType {
TC_NONE = 0,
TC_ACTION_DATA,
TC_POSE,
TC_ARMATURE_VERTS,
TC_CURSOR_IMAGE,
TC_CURSOR_VIEW3D,
TC_CURVE_VERTS,
TC_GRAPH_EDIT_DATA,
TC_GPENCIL,
TC_LATTICE_VERTS,
TC_MASKING_DATA,
TC_MBALL_VERTS,
TC_MESH_VERTS,
TC_MESH_EDGES,
TC_MESH_UV,
TC_NLA_DATA,
TC_NODE_DATA,
TC_OBJECT,
TC_OBJECT_TEXSPACE,
TC_PAINT_CURVE_VERTS,
TC_PARTICLE_VERTS,
TC_SCULPT,
TC_SEQ_DATA,
TC_TRACKING_DATA,
} eTransConvertType;
/* transform_convert.c */
bool transform_mode_use_local_origins(const TransInfo *t);
void transform_around_single_fallback(TransInfo *t);
void remake_graph_transdata(TransInfo *t, struct ListBase *anim_data);
bool constraints_list_needinv(TransInfo *t, ListBase *list);
void calc_distanceCurveVerts(TransData *head, TransData *tail);
struct TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt);
char transform_convert_frame_side_dir_get(TransInfo *t, float cframe);
bool FrameOnMouseSide(char side, float frame, float cframe);
void clipMirrorModifier(TransInfo *t);
void animrecord_check_state(TransInfo *t, struct Object *ob);
/* transform_convert_action.c */
void createTransActionData(bContext *C, TransInfo *t);
void recalcData_actedit(TransInfo *t);
/* transform_convert_armature.c */
struct bKinematicConstraint *has_targetless_ik(struct bPoseChannel *pchan);
void createTransPose(TransInfo *t);
void createTransArmatureVerts(TransInfo *t);
void recalcData_edit_armature(TransInfo *t);
void recalcData_pose(TransInfo *t);
/* transform_convert_cursor.c */
void createTransCursor_image(TransInfo *t);
@ -125,55 +124,69 @@ void createTransCursor_view3d(TransInfo *t);
/* transform_convert_curve.c */
void createTransCurveVerts(TransInfo *t);
void recalcData_curve(TransInfo *t);
/* transform_convert_graph.c */
void createTransGraphEditData(bContext *C, TransInfo *t);
void recalcData_graphedit(TransInfo *t);
/* transform_convert_gpencil.c */
void createTransGPencil(bContext *C, TransInfo *t);
void recalcData_gpencil_strokes(TransInfo *t);
/* transform_convert_lattice.c */
void createTransLatticeVerts(TransInfo *t);
/* transform_convert_mask.c */
void createTransMaskingData(bContext *C, TransInfo *t);
void recalcData_mask_common(TransInfo *t);
/* transform_convert_mball.c */
void createTransMBallVerts(TransInfo *t);
/* transform_convert_mesh.c */
void createTransEditVerts(TransInfo *t);
void recalcData_mesh(TransInfo *t);
/* transform_convert_mesh_edge.c */
void createTransEdge(TransInfo *t);
/* transform_convert_mesh_uv.c */
void createTransUVs(bContext *C, TransInfo *t);
void recalcData_uv(TransInfo *t);
/* transform_convert_nla.c */
void createTransNlaData(bContext *C, TransInfo *t);
void recalcData_nla(TransInfo *t);
/* transform_convert_node.c */
void createTransNodeData(bContext *UNUSED(C), TransInfo *t);
void createTransNodeData(TransInfo *t);
void flushTransNodes(TransInfo *t);
/* transform_convert_object.c */
void clear_trans_object_base_flags(TransInfo *t);
void createTransObject(bContext *C, TransInfo *t);
void createTransTexspace(TransInfo *t);
void recalcData_objects(TransInfo *t);
/* transform_convert_paintcurve.c */
void createTransPaintCurveVerts(bContext *C, TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
/* transform_convert_particle.c */
void createTransParticleVerts(bContext *C, TransInfo *t);
void recalcData_particles(TransInfo *t);
/* transform_convert_sculpt.c */
void createTransSculpt(TransInfo *t);
void recalcData_sculpt(TransInfo *t);
/* transform_convert_sequence.c */
/* transform_convert_sequencer.c */
void createTransSeqData(TransInfo *t);
void recalcData_sequencer(TransInfo *t);
/* transform_convert_tracking.c */
void createTransTrackingData(bContext *C, TransInfo *t);
void cancelTransTracking(TransInfo *t);
void recalcData_tracking(TransInfo *t);
#endif

View File

@ -555,7 +555,7 @@ void createTransActionData(bContext *C, TransInfo *t)
* \{ */
/* This function helps flush transdata written to tempdata into the gp-frames */
void flushTransIntFrameActionData(TransInfo *t)
static void flushTransIntFrameActionData(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
tGPFtransdata *tfd = tc->custom.type.data;
@ -566,4 +566,56 @@ void flushTransIntFrameActionData(TransInfo *t)
}
}
/* helper for recalcData() - for Action Editor transforms */
void recalcData_actedit(TransInfo *t)
{
ViewLayer *view_layer = t->view_layer;
SpaceAction *saction = (SpaceAction *)t->area->spacedata.first;
bAnimContext ac = {NULL};
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.bmain = CTX_data_main(t->context);
ac.scene = t->scene;
ac.view_layer = t->view_layer;
ac.obact = OBACT(view_layer);
ac.area = t->area;
ac.region = t->region;
ac.sl = (t->area) ? t->area->spacedata.first : NULL;
ac.spacetype = (t->area) ? t->area->spacetype : 0;
ac.regiontype = (t->region) ? t->region->regiontype : 0;
ANIM_animdata_context_getdata(&ac);
/* perform flush */
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
/* flush transform values back to actual coordinates */
flushTransIntFrameActionData(t);
}
if (ac.datatype != ANIMCONT_MASK) {
/* Get animdata blocks visible in editor,
* assuming that these will be the ones where things changed. */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* just tag these animdata-blocks to recalc, assuming that some data there changed
* BUT only do this if realtime updates are enabled
*/
if ((saction->flag & SACTION_NOREALTIMEUPDATES) == 0) {
for (ale = anim_data.first; ale; ale = ale->next) {
/* set refresh tags for objects using this animation */
ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
}
}
/* now free temp channels */
ANIM_animdata_freelist(&anim_data);
}
}
/** \} */

View File

@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@ -39,11 +40,15 @@
#include "BIK_api.h"
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "transform.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
typedef struct BoneInitData {
@ -545,97 +550,6 @@ static void pose_mirror_info_restore(const PoseInitData_Mirror *pid)
}
}
/**
* if pose bone (partial) selected, copy data.
* context; posemode armature, with mirror editing enabled.
*/
void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *ob)
{
float flip_mtx[4][4];
unit_m4(flip_mtx);
flip_mtx[0][0] = -1;
LISTBASE_FOREACH (bPoseChannel *, pchan_orig, &ob->pose->chanbase) {
/* Clear the MIRROR flag from previous runs. */
pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR;
}
bPose *pose = ob->pose;
PoseInitData_Mirror *pid = NULL;
if ((t->mode != TFM_BONESIZE) && (pose->flag & POSE_MIRROR_RELATIVE)) {
pid = tc->custom.type.data;
}
TransData *td = tc->data;
for (int i = tc->data_len; i--; td++) {
bPoseChannel *pchan_orig = td->extra;
BLI_assert(pchan_orig->bone->flag & BONE_TRANSFORM);
/* No layer check, correct mirror is more important. */
bPoseChannel *pchan = BKE_pose_channel_get_mirrored(pose, pchan_orig->name);
if (pchan == NULL) {
continue;
}
/* Also do bbone scaling. */
pchan->bone->xwidth = pchan_orig->bone->xwidth;
pchan->bone->zwidth = pchan_orig->bone->zwidth;
/* We assume X-axis flipping for now. */
pchan->curve_in_x = pchan_orig->curve_in_x * -1;
pchan->curve_out_x = pchan_orig->curve_out_x * -1;
pchan->roll1 = pchan_orig->roll1 * -1; // XXX?
pchan->roll2 = pchan_orig->roll2 * -1; // XXX?
float pchan_mtx_final[4][4];
BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
if (pid) {
mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
}
BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
/* Set flag to let autokeyframe know to keyframe the mirrred bone. */
pchan->bone->flag |= BONE_TRANSFORM_MIRROR;
/* In this case we can do target-less IK grabbing. */
if (t->mode == TFM_TRANSLATION) {
bKinematicConstraint *data = has_targetless_ik(pchan);
if (data == NULL) {
continue;
}
mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc);
if (pid) {
/* TODO(germano): Realitve Mirror support */
}
data->flag |= CONSTRAINT_IK_AUTO;
/* Add a temporary auto IK constraint here, as we will only temporarily active this
* target-less bone during transform. (Target-less IK constraints are treated as if they are
* disabled unless they are transformed) */
add_temporary_ik_constraint(pchan, data);
Main *bmain = CTX_data_main(t->context);
update_deg_with_temporary_ik(bmain, ob);
}
if (pid) {
pid++;
}
}
}
void restoreMirrorPoseBones(TransDataContainer *tc)
{
bPose *pose = tc->poseobj->pose;
if (!(pose->flag & POSE_MIRROR_EDIT)) {
return;
}
for (PoseInitData_Mirror *pid = tc->custom.type.data; pid->pchan; pid++) {
pose_mirror_info_restore(pid);
}
}
/** \} */
/* -------------------------------------------------------------------- */
@ -793,55 +707,6 @@ void createTransPose(TransInfo *t)
t->flag &= ~T_PROP_EDIT_ALL;
}
void restoreBones(TransDataContainer *tc)
{
bArmature *arm;
BoneInitData *bid = tc->custom.type.data;
EditBone *ebo;
if (tc->obedit) {
arm = tc->obedit->data;
}
else {
BLI_assert(tc->poseobj != NULL);
arm = tc->poseobj->data;
}
while (bid->bone) {
ebo = bid->bone;
ebo->dist = bid->dist;
ebo->rad_head = bid->rad_head;
ebo->rad_tail = bid->rad_tail;
ebo->roll = bid->roll;
ebo->xwidth = bid->xwidth;
ebo->zwidth = bid->zwidth;
copy_v3_v3(ebo->head, bid->head);
copy_v3_v3(ebo->tail, bid->tail);
if (arm->flag & ARM_MIRROR_EDIT) {
EditBone *ebo_child;
/* Also move connected ebo_child, in case ebo_child's name aren't mirrored properly */
for (ebo_child = arm->edbo->first; ebo_child; ebo_child = ebo_child->next) {
if ((ebo_child->flag & BONE_CONNECTED) && (ebo_child->parent == ebo)) {
copy_v3_v3(ebo_child->head, ebo->tail);
ebo_child->rad_head = ebo->rad_tail;
}
}
/* Also move connected parent, in case parent's name isn't mirrored properly */
if ((ebo->flag & BONE_CONNECTED) && ebo->parent) {
EditBone *parent = ebo->parent;
copy_v3_v3(parent->tail, ebo->head);
parent->rad_tail = ebo->rad_head;
}
}
bid++;
}
}
void createTransArmatureVerts(TransInfo *t)
{
t->data_len_all = 0;
@ -1097,3 +962,337 @@ void createTransArmatureVerts(TransInfo *t)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Data Edit Armature
* \{ */
static void restoreBones(TransDataContainer *tc)
{
bArmature *arm;
BoneInitData *bid = tc->custom.type.data;
EditBone *ebo;
if (tc->obedit) {
arm = tc->obedit->data;
}
else {
BLI_assert(tc->poseobj != NULL);
arm = tc->poseobj->data;
}
while (bid->bone) {
ebo = bid->bone;
ebo->dist = bid->dist;
ebo->rad_head = bid->rad_head;
ebo->rad_tail = bid->rad_tail;
ebo->roll = bid->roll;
ebo->xwidth = bid->xwidth;
ebo->zwidth = bid->zwidth;
copy_v3_v3(ebo->head, bid->head);
copy_v3_v3(ebo->tail, bid->tail);
if (arm->flag & ARM_MIRROR_EDIT) {
EditBone *ebo_child;
/* Also move connected ebo_child, in case ebo_child's name aren't mirrored properly */
for (ebo_child = arm->edbo->first; ebo_child; ebo_child = ebo_child->next) {
if ((ebo_child->flag & BONE_CONNECTED) && (ebo_child->parent == ebo)) {
copy_v3_v3(ebo_child->head, ebo->tail);
ebo_child->rad_head = ebo->rad_tail;
}
}
/* Also move connected parent, in case parent's name isn't mirrored properly */
if ((ebo->flag & BONE_CONNECTED) && ebo->parent) {
EditBone *parent = ebo->parent;
copy_v3_v3(parent->tail, ebo->head);
parent->rad_tail = ebo->rad_head;
}
}
bid++;
}
}
void recalcData_edit_armature(TransInfo *t)
{
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
bArmature *arm = tc->obedit->data;
ListBase *edbo = arm->edbo;
EditBone *ebo, *ebo_parent;
TransData *td = tc->data;
int i;
/* Ensure all bones are correctly adjusted */
for (ebo = edbo->first; ebo; ebo = ebo->next) {
ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL;
if (ebo_parent) {
/* If this bone has a parent tip that has been moved */
if (ebo_parent->flag & BONE_TIPSEL) {
copy_v3_v3(ebo->head, ebo_parent->tail);
if (t->mode == TFM_BONE_ENVELOPE) {
ebo->rad_head = ebo_parent->rad_tail;
}
}
/* If this bone has a parent tip that has NOT been moved */
else {
copy_v3_v3(ebo_parent->tail, ebo->head);
if (t->mode == TFM_BONE_ENVELOPE) {
ebo_parent->rad_tail = ebo->rad_head;
}
}
}
/* on extrude bones, oldlength==0.0f, so we scale radius of points */
ebo->length = len_v3v3(ebo->head, ebo->tail);
if (ebo->oldlength == 0.0f) {
ebo->rad_head = 0.25f * ebo->length;
ebo->rad_tail = 0.10f * ebo->length;
ebo->dist = 0.25f * ebo->length;
if (ebo->parent) {
if (ebo->rad_head > ebo->parent->rad_tail) {
ebo->rad_head = ebo->parent->rad_tail;
}
}
}
else if (t->mode != TFM_BONE_ENVELOPE) {
/* if bones change length, lets do that for the deform distance as well */
ebo->dist *= ebo->length / ebo->oldlength;
ebo->rad_head *= ebo->length / ebo->oldlength;
ebo->rad_tail *= ebo->length / ebo->oldlength;
ebo->oldlength = ebo->length;
if (ebo_parent) {
ebo_parent->rad_tail = ebo->rad_head;
}
}
}
if (!ELEM(t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) {
/* fix roll */
for (i = 0; i < tc->data_len; i++, td++) {
if (td->extra) {
float vec[3], up_axis[3];
float qrot[4];
float roll;
ebo = td->extra;
if (t->state == TRANS_CANCEL) {
/* restore roll */
ebo->roll = td->ival;
}
else {
copy_v3_v3(up_axis, td->axismtx[2]);
sub_v3_v3v3(vec, ebo->tail, ebo->head);
normalize_v3(vec);
rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
mul_qt_v3(qrot, up_axis);
/* roll has a tendency to flip in certain orientations - [#34283], [#33974] */
roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false);
ebo->roll = angle_compat_rad(roll, td->ival);
}
}
}
}
if (arm->flag & ARM_MIRROR_EDIT) {
if (t->state != TRANS_CANCEL) {
ED_armature_edit_transform_mirror_update(tc->obedit);
}
else {
restoreBones(tc);
}
}
/* Tag for redraw/invalidate overlay cache. */
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Data Pose
* \{ */
/**
* if pose bone (partial) selected, copy data.
* context; posemode armature, with mirror editing enabled.
*/
static void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *ob)
{
float flip_mtx[4][4];
unit_m4(flip_mtx);
flip_mtx[0][0] = -1;
LISTBASE_FOREACH (bPoseChannel *, pchan_orig, &ob->pose->chanbase) {
/* Clear the MIRROR flag from previous runs. */
pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR;
}
bPose *pose = ob->pose;
PoseInitData_Mirror *pid = NULL;
if ((t->mode != TFM_BONESIZE) && (pose->flag & POSE_MIRROR_RELATIVE)) {
pid = tc->custom.type.data;
}
TransData *td = tc->data;
for (int i = tc->data_len; i--; td++) {
bPoseChannel *pchan_orig = td->extra;
BLI_assert(pchan_orig->bone->flag & BONE_TRANSFORM);
/* No layer check, correct mirror is more important. */
bPoseChannel *pchan = BKE_pose_channel_get_mirrored(pose, pchan_orig->name);
if (pchan == NULL) {
continue;
}
/* Also do bbone scaling. */
pchan->bone->xwidth = pchan_orig->bone->xwidth;
pchan->bone->zwidth = pchan_orig->bone->zwidth;
/* We assume X-axis flipping for now. */
pchan->curve_in_x = pchan_orig->curve_in_x * -1;
pchan->curve_out_x = pchan_orig->curve_out_x * -1;
pchan->roll1 = pchan_orig->roll1 * -1; // XXX?
pchan->roll2 = pchan_orig->roll2 * -1; // XXX?
float pchan_mtx_final[4][4];
BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
if (pid) {
mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
}
BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
/* Set flag to let autokeyframe know to keyframe the mirrred bone. */
pchan->bone->flag |= BONE_TRANSFORM_MIRROR;
/* In this case we can do target-less IK grabbing. */
if (t->mode == TFM_TRANSLATION) {
bKinematicConstraint *data = has_targetless_ik(pchan);
if (data == NULL) {
continue;
}
mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc);
if (pid) {
/* TODO(germano): Realitve Mirror support */
}
data->flag |= CONSTRAINT_IK_AUTO;
/* Add a temporary auto IK constraint here, as we will only temporarily active this
* target-less bone during transform. (Target-less IK constraints are treated as if they are
* disabled unless they are transformed) */
add_temporary_ik_constraint(pchan, data);
Main *bmain = CTX_data_main(t->context);
update_deg_with_temporary_ik(bmain, ob);
}
if (pid) {
pid++;
}
}
}
static void restoreMirrorPoseBones(TransDataContainer *tc)
{
bPose *pose = tc->poseobj->pose;
if (!(pose->flag & POSE_MIRROR_EDIT)) {
return;
}
for (PoseInitData_Mirror *pid = tc->custom.type.data; pid->pchan; pid++) {
pose_mirror_info_restore(pid);
}
}
void recalcData_pose(TransInfo *t)
{
if (t->mode == TFM_BONESIZE) {
/* Handle the exception where for TFM_BONESIZE in edit mode we pretend to be
* in pose mode (to use bone orientation matrix),
* in that case we have to do mirroring as well. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->poseobj;
bArmature *arm = ob->data;
if (ob->mode == OB_MODE_EDIT) {
if (arm->flag & ARM_MIRROR_EDIT) {
if (t->state != TRANS_CANCEL) {
ED_armature_edit_transform_mirror_update(ob);
}
else {
restoreBones(tc);
}
}
}
else if (ob->mode == OB_MODE_POSE) {
/* actually support TFM_BONESIZE in posemode as well */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
bPose *pose = ob->pose;
if (arm->flag & ARM_MIRROR_EDIT || pose->flag & POSE_MIRROR_EDIT) {
pose_transform_mirror_update(t, tc, ob);
}
}
}
}
else {
GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->poseobj;
bPose *pose = ob->pose;
if (pose->flag & POSE_MIRROR_EDIT) {
if (t->state != TRANS_CANCEL) {
pose_transform_mirror_update(t, tc, ob);
}
else {
restoreMirrorPoseBones(tc);
}
}
/* if animtimer is running, and the object already has animation data,
* check if the auto-record feature means that we should record 'samples'
* (i.e. un-editable animation values)
*
* context is needed for keying set poll() functions.
*/
/* TODO: autokeyframe calls need some setting to specify to add samples
* (FPoints) instead of keyframes? */
if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) {
int targetless_ik =
(t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
animrecord_check_state(t, ob);
autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
}
if (motionpath_need_update_pose(t->scene, ob)) {
BLI_gset_insert(motionpath_updates, ob);
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
/* Update motion paths once for all transformed bones in an object. */
GSetIterator gs_iter;
GSET_ITER (gs_iter, motionpath_updates) {
Object *ob = BLI_gsetIterator_getKey(&gs_iter);
ED_pose_recalculate_paths(t->context, t->scene, ob, POSE_PATH_CALC_RANGE_CURRENT_FRAME);
}
BLI_gset_free(motionpath_updates, NULL);
}
}
/** \} */

View File

@ -32,6 +32,9 @@
#include "BKE_curve.h"
#include "transform.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
/* -------------------------------------------------------------------- */
@ -419,4 +422,36 @@ void createTransCurveVerts(TransInfo *t)
#undef SEL_F3
}
void recalcData_curve(TransInfo *t)
{
if (t->state != TRANS_CANCEL) {
clipMirrorModifier(t);
applyProject(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Curve *cu = tc->obedit->data;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
Nurb *nu = nurbs->first;
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
if (t->state == TRANS_CANCEL) {
while (nu) {
/* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
BKE_nurb_handles_calc(nu);
nu = nu->next;
}
}
else {
/* Normal updating */
while (nu) {
BKE_nurb_test_2d(nu);
BKE_nurb_handles_calc(nu);
nu = nu->next;
}
}
}
}
/** \} */

View File

@ -25,11 +25,13 @@
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "ED_gpencil.h"
@ -376,4 +378,23 @@ void createTransGPencil(bContext *C, TransInfo *t)
}
}
/* force recalculation of triangles during transformation */
void recalcData_gpencil_strokes(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
GHash *strokes = BLI_ghash_ptr_new(__func__);
TransData *td = tc->data;
for (int i = 0; i < tc->data_len; i++, td++) {
bGPDstroke *gps = td->extra;
if ((gps != NULL) && (!BLI_ghash_haskey(strokes, gps))) {
BLI_ghash_insert(strokes, gps, gps);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gps);
}
}
BLI_ghash_free(strokes, NULL, NULL);
}
/** \} */

View File

@ -634,10 +634,28 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
*
* \{ */
static bool fcu_test_selected(FCurve *fcu)
{
BezTriple *bezt = fcu->bezt;
uint i;
if (bezt == NULL) { /* ignore baked */
return 0;
}
for (i = 0; i < fcu->totvert; i++, bezt++) {
if (BEZT_ISSEL_ANY(bezt)) {
return 1;
}
}
return 0;
}
/* this function is called on recalcData to apply the transforms applied
* to the transdata on to the actual keyframe data
*/
void flushTransGraphData(TransInfo *t)
static void flushTransGraphData(TransInfo *t)
{
SpaceGraph *sipo = (SpaceGraph *)t->area->spacedata.first;
TransData *td;
@ -733,4 +751,72 @@ void flushTransGraphData(TransInfo *t)
}
}
/* helper for recalcData() - for Graph Editor transforms */
void recalcData_graphedit(TransInfo *t)
{
SpaceGraph *sipo = (SpaceGraph *)t->area->spacedata.first;
ViewLayer *view_layer = t->view_layer;
ListBase anim_data = {NULL, NULL};
bAnimContext ac = {NULL};
int filter;
bAnimListElem *ale;
int dosort = 0;
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.bmain = CTX_data_main(t->context);
ac.scene = t->scene;
ac.view_layer = t->view_layer;
ac.obact = OBACT(view_layer);
ac.area = t->area;
ac.region = t->region;
ac.sl = (t->area) ? t->area->spacedata.first : NULL;
ac.spacetype = (t->area) ? t->area->spacetype : 0;
ac.regiontype = (t->region) ? t->region->regiontype : 0;
ANIM_animdata_context_getdata(&ac);
/* do the flush first */
flushTransGraphData(t);
/* get curves to check if a re-sort is needed */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* now test if there is a need to re-sort */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
/* ignore FC-Curves without any selected verts */
if (!fcu_test_selected(fcu)) {
continue;
}
/* watch it: if the time is wrong: do not correct handles yet */
if (test_time_fcurve(fcu)) {
dosort++;
}
else {
calchandles_fcurve_ex(fcu, BEZT_FLAG_TEMP_TAG);
}
/* set refresh tags for objects using this animation,
* BUT only if realtime updates are enabled
*/
if ((sipo->flag & SIPO_NOREALTIMEUPDATES) == 0) {
ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
}
}
/* do resort and other updates? */
if (dosort) {
remake_graph_transdata(t, &anim_data);
}
/* now free temp channels */
ANIM_animdata_freelist(&anim_data);
}
/** \} */

View File

@ -29,8 +29,12 @@
#include "BLI_math.h"
#include "BKE_context.h"
#include "BKE_lattice.h"
#include "transform.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
/* -------------------------------------------------------------------- */
@ -109,4 +113,19 @@ void createTransLatticeVerts(TransInfo *t)
}
}
void recalcData_lattice(TransInfo *t)
{
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Lattice *la = tc->obedit->data;
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
if (la->editlatt->latt->flag & LT_OUTSIDE) {
outside_lattice(la->editlatt->latt);
}
}
}
/** \} */

View File

@ -396,11 +396,11 @@ void createTransMaskingData(bContext *C, TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Masking Transform Flush
/** \name Recalc TransData Masking
*
* \{ */
void flushTransMasking(TransInfo *t)
static void flushTransMasking(TransInfo *t)
{
TransData2D *td;
TransDataMasking *tdm;
@ -439,4 +439,13 @@ void flushTransMasking(TransInfo *t)
}
}
void recalcData_mask_common(TransInfo *t)
{
Mask *mask = CTX_data_edit_mask(t->context);
flushTransMasking(t);
DEG_id_tag_update(&mask->id, 0);
}
/** \} */

View File

@ -44,9 +44,12 @@
#include "DEG_depsgraph_query.h"
#include "transform.h"
#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
/* Used for both mirror epsilon and TD_MIRROR_EDGE_ */
#define TRANSFORM_MAXDIST_MIRROR 0.00002f
@ -1302,3 +1305,66 @@ void trans_mesh_customdata_correction_apply(struct TransDataContainer *tc, bool
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Mesh Data
*
* \{ */
static void transform_apply_to_mirror(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->mirror.use_mirror_any) {
int i;
TransData *td;
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
if (td->flag & (TD_MIRROR_EDGE_X | TD_MIRROR_EDGE_Y | TD_MIRROR_EDGE_Z)) {
if (td->flag & TD_MIRROR_EDGE_X) {
td->loc[0] = 0.0f;
}
if (td->flag & TD_MIRROR_EDGE_Y) {
td->loc[1] = 0.0f;
}
if (td->flag & TD_MIRROR_EDGE_Z) {
td->loc[2] = 0.0f;
}
}
}
TransDataMirror *tdm;
for (i = 0, tdm = tc->mirror.data; i < tc->mirror.data_len; i++, tdm++) {
tdm->loc_dst[0] = tdm->loc_src[0] * tdm->sign_x;
tdm->loc_dst[1] = tdm->loc_src[1] * tdm->sign_y;
tdm->loc_dst[2] = tdm->loc_src[2] * tdm->sign_z;
}
}
}
}
void recalcData_mesh(TransInfo *t)
{
/* mirror modifier clipping? */
if (t->state != TRANS_CANCEL) {
/* apply clipping after so we never project past the clip plane [#25423] */
applyProject(t);
clipMirrorModifier(t);
}
if ((t->flag & T_NO_MIRROR) == 0 && (t->options & CTX_NO_MIRROR) == 0) {
transform_apply_to_mirror(t);
}
if (t->mode == TFM_EDGE_SLIDE) {
projectEdgeSlideData(t, false);
}
else if (t->mode == TFM_VERT_SLIDE) {
projectVertSlideData(t, false);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
EDBM_mesh_normals_update(em);
BKE_editmesh_looptri_calc(em);
}
}
/** \} */

View File

@ -266,7 +266,7 @@ void createTransUVs(bContext *C, TransInfo *t)
*
* \{ */
void flushTransUVs(TransInfo *t)
static void flushTransUVs(TransInfo *t)
{
SpaceImage *sima = t->area->spacedata.first;
const bool use_pixel_snap = ((sima->pixel_snap_mode != SI_PIXEL_SNAP_DISABLED) &&
@ -314,4 +314,21 @@ void flushTransUVs(TransInfo *t)
}
}
/* helper for recalcData() - for Image Editor transforms */
void recalcData_uv(TransInfo *t)
{
SpaceImage *sima = t->area->spacedata.first;
flushTransUVs(t);
if (sima->flag & SI_LIVE_UNWRAP) {
ED_uvedit_live_unwrap_re_solve();
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->data_len) {
DEG_id_tag_update(tc->obedit->data, 0);
}
}
}
/** \} */

View File

@ -34,6 +34,9 @@
#include "BKE_report.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
#include "RNA_access.h"
#include "transform.h"
#include "transform_convert.h"
@ -256,4 +259,232 @@ void createTransNlaData(bContext *C, TransInfo *t)
ANIM_animdata_freelist(&anim_data);
}
/* helper for recalcData() - for NLA Editor transforms */
void recalcData_nla(TransInfo *t)
{
SpaceNla *snla = (SpaceNla *)t->area->spacedata.first;
Scene *scene = t->scene;
double secf = FPS;
int i;
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
TransDataNla *tdn = tc->custom.type.data;
/* For each strip we've got, perform some additional validation of the values
* that got set before using RNA to set the value (which does some special
* operations when setting these values to make sure that everything works ok).
*/
for (i = 0; i < tc->data_len; i++, tdn++) {
NlaStrip *strip = tdn->strip;
PointerRNA strip_ptr;
short pExceeded, nExceeded, iter;
int delta_y1, delta_y2;
/* if this tdn has no handles, that means it is just a dummy that should be skipped */
if (tdn->handle == 0) {
continue;
}
/* set refresh tags for objects using this animation,
* BUT only if realtime updates are enabled
*/
if ((snla->flag & SNLA_NOREALTIMEUPDATES) == 0) {
ANIM_id_update(CTX_data_main(t->context), tdn->id);
}
/* if canceling transform, just write the values without validating, then move on */
if (t->state == TRANS_CANCEL) {
/* clear the values by directly overwriting the originals, but also need to restore
* endpoints of neighboring transition-strips
*/
/* start */
strip->start = tdn->h1[0];
if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION)) {
strip->prev->end = tdn->h1[0];
}
/* end */
strip->end = tdn->h2[0];
if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION)) {
strip->next->start = tdn->h2[0];
}
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
/* restore to original track (if needed) */
if (tdn->oldTrack != tdn->nlt) {
/* Just append to end of list for now,
* since strips get sorted in special_aftertrans_update(). */
BLI_remlink(&tdn->nlt->strips, strip);
BLI_addtail(&tdn->oldTrack->strips, strip);
}
continue;
}
/* firstly, check if the proposed transform locations would overlap with any neighboring strips
* (barring transitions) which are absolute barriers since they are not being moved
*
* this is done as a iterative procedure (done 5 times max for now)
*/
for (iter = 0; iter < 5; iter++) {
pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) &&
(tdn->h1[0] < strip->prev->end));
nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) &&
(tdn->h2[0] > strip->next->start));
if ((pExceeded && nExceeded) || (iter == 4)) {
/* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
* - Simply crop strip to fit within the bounds of the strips bounding it
* - If there were no neighbors, clear the transforms
* (make it default to the strip's current values).
*/
if (strip->prev && strip->next) {
tdn->h1[0] = strip->prev->end;
tdn->h2[0] = strip->next->start;
}
else {
tdn->h1[0] = strip->start;
tdn->h2[0] = strip->end;
}
}
else if (nExceeded) {
/* move backwards */
float offset = tdn->h2[0] - strip->next->start;
tdn->h1[0] -= offset;
tdn->h2[0] -= offset;
}
else if (pExceeded) {
/* more forwards */
float offset = strip->prev->end - tdn->h1[0];
tdn->h1[0] += offset;
tdn->h2[0] += offset;
}
else { /* all is fine and well */
break;
}
}
/* handle auto-snapping
* NOTE: only do this when transform is still running, or we can't restore
*/
if (t->state != TRANS_CANCEL) {
switch (snla->autosnap) {
case SACTSNAP_FRAME: /* snap to nearest frame */
case SACTSNAP_STEP: /* frame step - this is basically the same,
* since we don't have any remapping going on */
{
tdn->h1[0] = floorf(tdn->h1[0] + 0.5f);
tdn->h2[0] = floorf(tdn->h2[0] + 0.5f);
break;
}
case SACTSNAP_SECOND: /* snap to nearest second */
case SACTSNAP_TSTEP: /* second step - this is basically the same,
* since we don't have any remapping going on */
{
/* This case behaves differently from the rest, since lengths of strips
* may not be multiples of a second. If we just naively resize adjust
* the handles, things may not work correctly. Instead, we only snap
* the first handle, and move the other to fit.
*
* FIXME: we do run into problems here when user attempts to negatively
* scale the strip, as it then just compresses down and refuses
* to expand out the other end.
*/
float h1_new = (float)(floor(((double)tdn->h1[0] / secf) + 0.5) * secf);
float delta = h1_new - tdn->h1[0];
tdn->h1[0] = h1_new;
tdn->h2[0] += delta;
break;
}
case SACTSNAP_MARKER: /* snap to nearest marker */
{
tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
break;
}
}
}
/* Use RNA to write the values to ensure that constraints on these are obeyed
* (e.g. for transition strips, the values are taken from the neighbors)
*
* NOTE: we write these twice to avoid truncation errors which can arise when
* moving the strips a large distance using numeric input [#33852]
*/
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
/* Now, check if we need to try and move track:
* - we need to calculate both,
* as only one may have been altered by transform if only 1 handle moved.
*/
delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
if (delta_y1 || delta_y2) {
NlaTrack *track;
int delta = (delta_y2) ? delta_y2 : delta_y1;
int n;
/* Move in the requested direction,
* checking at each layer if there's space for strip to pass through,
* stopping on the last track available or that we're able to fit in.
*/
if (delta > 0) {
for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) {
/* check if space in this track for the strip */
if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
BKE_nlatrack_add_strip(track, strip);
tdn->nlt = track;
tdn->trackIndex++;
}
else { /* can't move any further */
break;
}
}
}
else {
/* make delta 'positive' before using it, since we now know to go backwards */
delta = -delta;
for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) {
/* check if space in this track for the strip */
if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
BKE_nlatrack_add_strip(track, strip);
tdn->nlt = track;
tdn->trackIndex--;
}
else { /* can't move any further */
break;
}
}
}
}
}
}
/** \} */

View File

@ -104,7 +104,7 @@ static bool is_node_parent_select(bNode *node)
return false;
}
void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
void createTransNodeData(TransInfo *t)
{
const float dpi_fac = UI_DPI_FAC;
TransData *td;

View File

@ -38,11 +38,15 @@
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "ED_keyframing.h"
#include "ED_object.h"
#include "DEG_depsgraph_query.h"
#include "transform.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
/* -------------------------------------------------------------------- */
@ -96,7 +100,7 @@ static void freeTransObjectCustomData(TransInfo *t,
* Nearly all of the logic here is in the 'ED_object_data_xform_container_*' API.
* \{ */
void trans_obdata_in_obmode_update_all(TransInfo *t)
static void trans_obdata_in_obmode_update_all(TransInfo *t)
{
TransDataObject *tdo = t->custom.type.data;
if (tdo->xds == NULL) {
@ -119,7 +123,7 @@ void trans_obdata_in_obmode_update_all(TransInfo *t)
*
* \{ */
void trans_obchild_in_obmode_update_all(TransInfo *t)
static void trans_obchild_in_obmode_update_all(TransInfo *t)
{
TransDataObject *tdo = t->custom.type.data;
if (tdo->xcs == NULL) {
@ -762,3 +766,66 @@ void createTransTexspace(TransInfo *t)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Data object
*
* \{ */
/* helper for recalcData() - for object transforms, typically in the 3D view */
void recalcData_objects(TransInfo *t)
{
bool motionpath_update = false;
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (int i = 0; i < tc->data_len; i++, td++) {
Object *ob = td->ob;
if (td->flag & TD_SKIP) {
continue;
}
/* if animtimer is running, and the object already has animation data,
* check if the auto-record feature means that we should record 'samples'
* (i.e. uneditable animation values)
*/
/* TODO: autokeyframe calls need some setting to specify to add samples
* (FPoints) instead of keyframes? */
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
animrecord_check_state(t, ob);
autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
}
motionpath_update |= motionpath_need_update_object(t->scene, ob);
/* sets recalc flags fully, instead of flushing existing ones
* otherwise proxies don't function correctly
*/
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
if (t->flag & T_TEXTURE) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
}
}
if (motionpath_update) {
/* Update motion paths once for all transformed objects. */
ED_objects_recalculate_paths(t->context, t->scene, OBJECT_PATH_CALC_RANGE_CURRENT_FRAME);
}
if (t->options & CTX_OBMODE_XFORM_SKIP_CHILDREN) {
trans_obchild_in_obmode_update_all(t);
}
if (t->options & CTX_OBMODE_XFORM_OBDATA) {
trans_obdata_in_obmode_update_all(t);
}
}
/** \} */

View File

@ -35,6 +35,9 @@
#include "ED_particle.h"
#include "transform.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
/* -------------------------------------------------------------------- */
@ -193,7 +196,7 @@ void createTransParticleVerts(bContext *C, TransInfo *t)
*
* \{ */
void flushTransParticles(TransInfo *t)
static void flushTransParticles(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Scene *scene = t->scene;
@ -245,3 +248,18 @@ void flushTransParticles(TransInfo *t)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Trasform Particles Data
*
* \{ */
void recalcData_particles(TransInfo *t)
{
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
flushTransParticles(t);
}
/** \} */

View File

@ -29,6 +29,8 @@
#include "BKE_paint.h"
#include "BKE_report.h"
#include "ED_sculpt.h"
#include "transform.h"
#include "transform_convert.h"
@ -100,3 +102,15 @@ void createTransSculpt(TransInfo *t)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Data object
*
* \{ */
void recalcData_sculpt(TransInfo *t)
{
ED_sculpt_update_modal_transform(t->context);
}
/** \} */

View File

@ -635,7 +635,7 @@ BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int s
}
}
void flushTransSeq(TransInfo *t)
static void flushTransSeq(TransInfo *t)
{
/* Editing null check already done */
ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep;
@ -770,6 +770,31 @@ void flushTransSeq(TransInfo *t)
}
}
/* helper for recalcData() - for sequencer transforms */
void recalcData_sequencer(TransInfo *t)
{
TransData *td;
int a;
Sequence *seq_prev = NULL;
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
TransDataSeq *tdsq = (TransDataSeq *)td->extra;
Sequence *seq = tdsq->seq;
if (seq != seq_prev) {
BKE_sequence_invalidate_cache_composite(t->scene, seq);
}
seq_prev = seq;
}
DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
flushTransSeq(t);
}
int transform_convert_sequencer_get_snap_bound(TransInfo *t)
{
TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;

View File

@ -608,11 +608,11 @@ void cancelTransTracking(TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Clip Editor Motion Tracking Transform Creation
/** \name recalc Motion Tracking TransData
*
* \{ */
void flushTransTracking(TransInfo *t)
static void flushTransTracking(TransInfo *t)
{
TransData *td;
TransData2D *td2d;
@ -689,4 +689,52 @@ void flushTransTracking(TransInfo *t)
}
}
/* helper for recalcData() - for Movie Clip transforms */
void recalcData_tracking(TransInfo *t)
{
SpaceClip *sc = t->area->spacedata.first;
if (ED_space_clip_check_show_trackedit(sc)) {
MovieClip *clip = ED_space_clip_get_clip(sc);
ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
MovieTrackingTrack *track;
int framenr = ED_space_clip_get_clip_frame_number(sc);
flushTransTracking(t);
track = tracksbase->first;
while (track) {
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
if (t->mode == TFM_TRANSLATION) {
if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) {
BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
}
if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) {
BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_POS);
}
}
else if (t->mode == TFM_RESIZE) {
if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) {
BKE_tracking_marker_clamp(marker, CLAMP_PAT_DIM);
}
if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) {
BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM);
}
}
else if (t->mode == TFM_ROTATION) {
if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) {
BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
}
}
}
track = track->next;
}
DEG_id_tag_update(&clip->id, 0);
}
}
/** \} */

File diff suppressed because it is too large Load Diff