Cleanup: Move each recalcData to their respective TransData file
This commit is contained in:
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
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue