Refactor: Transform, reduce array bit size by removing TransData::ext

Now that the `t->data` and `t->data_ext` arrays have the same ordering,
it is no longer necessary to include each member of `t->data_ext` in
`t->data`. Access can be done using the same index.

Pull Request: https://projects.blender.org/blender/blender/pulls/141563
This commit is contained in:
Germano Cavalcante
2025-07-08 20:47:56 +02:00
committed by Germano Cavalcante
parent 145b2173bd
commit ff9cc9c170
38 changed files with 456 additions and 461 deletions

View File

@@ -412,6 +412,7 @@ struct TransDataMirror : public TransDataBasic {
float *loc_src;
};
/** For objects, poses. 1 single allocation per #TransInfo! */
struct TransDataExtension {
/** Initial object drot. */
float drot[3];
@@ -506,8 +507,6 @@ struct TransData : public TransDataBasic {
float axismtx[3][3];
/** For objects/bones, the first constraint in its constraint stack. */
bConstraint *con;
/** For objects, poses. 1 single allocation per #TransInfo! */
TransDataExtension *ext;
/** For curves, stores handle flags for modification/cancel. */
TransDataCurveHandleFlags *hdata;
/** If set, copy of Object or #bPoseChannel protection. */
@@ -1088,7 +1087,6 @@ void postTrans(bContext *C, TransInfo *t);
void resetTransModal(TransInfo *t);
void resetTransRestrictions(TransInfo *t);
void applyTransObjects(TransInfo *t);
void restoreTransObjects(TransInfo *t);
void calculateCenter2D(TransInfo *t);
@@ -1119,7 +1117,10 @@ void calculatePropRatio(TransInfo *t);
* (use for objects or pose-bones)
* Similar to #ElementRotation.
*/
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot);
void transform_data_ext_rotate(TransData *td,
TransDataExtension *td_ext,
float mat[3][3],
bool use_drot);
Object *transform_object_deform_pose_armature_get(const TransInfo *t, Object *ob);

View File

@@ -357,13 +357,14 @@ static short transform_orientation_or_default(const TransInfo *t)
}
static const float (*transform_object_axismtx_get(const TransInfo *t,
const TransDataContainer * /*tc*/,
const TransDataContainer *tc,
const TransData *td))[3]
{
if (transform_orientation_or_default(t) == V3D_ORIENT_GIMBAL) {
BLI_assert(t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL));
if (t->options & (CTX_POSE_BONE | CTX_OBJECT)) {
return td->ext->axismtx_gimbal;
TransDataExtension *td_ext = &tc->data_ext[td - tc->data];
return td_ext->axismtx_gimbal;
}
}
return td->axismtx;

View File

@@ -389,7 +389,8 @@ static void pose_mirror_info_init(PoseInitData_Mirror *pid,
/** \name Convert Armature
* \{ */
static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
static void add_pose_transdata(
TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td, TransDataExtension *td_ext)
{
Bone *bone = pchan->bone;
float pmat[3][3], omat[3][3];
@@ -415,35 +416,35 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->loc = pchan->loc;
copy_v3_v3(td->iloc, pchan->loc);
td->ext->scale = pchan->scale;
copy_v3_v3(td->ext->iscale, pchan->scale);
td_ext->scale = pchan->scale;
copy_v3_v3(td_ext->iscale, pchan->scale);
if (pchan->rotmode > 0) {
td->ext->rot = pchan->eul;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = nullptr;
td_ext->rot = pchan->eul;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = nullptr;
copy_v3_v3(td->ext->irot, pchan->eul);
copy_v3_v3(td_ext->irot, pchan->eul);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
td->ext->rot = nullptr;
td->ext->rotAxis = pchan->rotAxis;
td->ext->rotAngle = &pchan->rotAngle;
td->ext->quat = nullptr;
td_ext->rot = nullptr;
td_ext->rotAxis = pchan->rotAxis;
td_ext->rotAngle = &pchan->rotAngle;
td_ext->quat = nullptr;
td->ext->irotAngle = pchan->rotAngle;
copy_v3_v3(td->ext->irotAxis, pchan->rotAxis);
td_ext->irotAngle = pchan->rotAngle;
copy_v3_v3(td_ext->irotAxis, pchan->rotAxis);
}
else {
td->ext->rot = nullptr;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = pchan->quat;
td_ext->rot = nullptr;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = pchan->quat;
copy_qt_qt(td->ext->iquat, pchan->quat);
copy_qt_qt(td_ext->iquat, pchan->quat);
}
td->ext->rotOrder = pchan->rotmode;
td_ext->rotOrder = pchan->rotmode;
/* Proper way to get parent transform + our own transform + constraints transform. */
copy_m3_m4(omat, ob->object_to_world().ptr());
@@ -471,13 +472,13 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
copy_m3_m4(tmat, pchan->constinv);
invert_m3_m3(cmat, tmat);
mul_m3_series(td->mtx, cmat, omat, pmat);
mul_m3_series(td->ext->r_mtx, cmat, omat, rpmat);
mul_m3_series(td_ext->r_mtx, cmat, omat, rpmat);
}
else {
mul_m3_series(td->mtx, omat, pmat);
mul_m3_series(td->ext->r_mtx, omat, rpmat);
mul_m3_series(td_ext->r_mtx, omat, rpmat);
}
invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
invert_m3_m3(td_ext->r_smtx, td_ext->r_mtx);
}
pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
@@ -489,7 +490,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
if (pchan->parent) {
/* Same as `td->smtx` but without `pchan->bone->bone_mat`. */
td->flag |= TD_PBONE_LOCAL_MTX_C;
mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
mul_m3_m3m3(td_ext->l_smtx, pchan->bone->bone_mat, td->smtx);
}
else {
td->flag |= TD_PBONE_LOCAL_MTX_P;
@@ -502,8 +503,8 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
normalize_m3(td->axismtx);
if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) {
if (!gimbal_axis_pose(ob, pchan, td->ext->axismtx_gimbal)) {
copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx);
if (!gimbal_axis_pose(ob, pchan, td_ext->axismtx_gimbal)) {
copy_m3_m3(td_ext->axismtx_gimbal, td->axismtx);
}
}
@@ -659,7 +660,6 @@ static void createTransPose(bContext * /*C*/, TransInfo *t)
Object *ob = tc->poseobj;
TransData *td;
TransDataExtension *tdx;
int i;
PoseInitData_Mirror *pid = static_cast<PoseInitData_Mirror *>(tc->custom.type.data);
int pid_index = 0;
@@ -678,10 +678,6 @@ static void createTransPose(bContext * /*C*/, TransInfo *t)
/* Initialize trans data. */
td = tc->data = MEM_calloc_arrayN<TransData>(tc->data_len, "TransPoseBone");
tdx = tc->data_ext = MEM_calloc_arrayN<TransDataExtension>(tc->data_len, "TransPoseBoneExt");
for (i = 0; i < tc->data_len; i++, td++, tdx++) {
td->ext = tdx;
td->val = nullptr;
}
if (mirror) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
@@ -706,10 +702,10 @@ static void createTransPose(bContext * /*C*/, TransInfo *t)
/* Use pose channels to fill trans data. */
td = tc->data;
tdx = tc->data_ext;
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
if (pchan->bone->flag & BONE_TRANSFORM) {
add_pose_transdata(t, pchan, ob, td);
td++;
add_pose_transdata(t, pchan, ob, td++, tdx++);
}
}
@@ -836,7 +832,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
copy_m3_m3(td->mtx, mtx);
td->loc = nullptr;
td->ext = nullptr;
td++;
}
@@ -850,7 +845,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
copy_m3_m3(td->mtx, mtx);
td->loc = nullptr;
td->ext = nullptr;
td++;
}
@@ -879,8 +873,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
copy_m3_m3(td->axismtx, td->mtx);
normalize_m3(td->axismtx);
td->ext = nullptr;
td++;
}
}
@@ -893,8 +885,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
copy_v3_v3(td->center, ebo->head);
td->flag = TD_SELECTED;
td->ext = nullptr;
td++;
}
}
@@ -931,7 +921,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
td->ival = ebo->roll;
}
td->ext = nullptr;
td->val = nullptr;
td++;
@@ -953,7 +942,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
td->extra = ebo; /* To fix roll. */
td->ival = ebo->roll;
td->ext = nullptr;
td->val = nullptr;
td++;

View File

@@ -38,7 +38,6 @@ static void createTransCursor_2D_impl(TransInfo *t, float cursor_location[2])
tc->data_len = 1;
td = tc->data = MEM_callocN<TransData>("TransTexspace");
td2d = tc->data_2d = MEM_calloc_arrayN<TransData2D>(tc->data_len, "TransObData2D(Cursor)");
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransCursorExt");
}
td->flag = TD_SELECTED;
@@ -124,6 +123,7 @@ static void recalcData_cursor_sequencer(TransInfo *t)
static void createTransCursor_view3d(bContext * /*C*/, TransInfo *t)
{
TransData *td;
TransDataExtension *td_ext;
Scene *scene = t->scene;
if (!ID_IS_EDITABLE(scene)) {
@@ -137,7 +137,7 @@ static void createTransCursor_view3d(bContext * /*C*/, TransInfo *t)
TransDataContainer *tc = t->data_container;
tc->data_len = 1;
td = tc->data = MEM_callocN<TransData>("TransTexspace");
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
td_ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
}
td->flag = TD_SELECTED;
@@ -152,31 +152,31 @@ static void createTransCursor_view3d(bContext * /*C*/, TransInfo *t)
copy_v3_v3(td->iloc, cursor->location);
if (cursor->rotation_mode > 0) {
td->ext->rot = cursor->rotation_euler;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = nullptr;
td_ext->rot = cursor->rotation_euler;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = nullptr;
copy_v3_v3(td->ext->irot, cursor->rotation_euler);
copy_v3_v3(td_ext->irot, cursor->rotation_euler);
}
else if (cursor->rotation_mode == ROT_MODE_AXISANGLE) {
td->ext->rot = nullptr;
td->ext->rotAxis = cursor->rotation_axis;
td->ext->rotAngle = &cursor->rotation_angle;
td->ext->quat = nullptr;
td_ext->rot = nullptr;
td_ext->rotAxis = cursor->rotation_axis;
td_ext->rotAngle = &cursor->rotation_angle;
td_ext->quat = nullptr;
td->ext->irotAngle = cursor->rotation_angle;
copy_v3_v3(td->ext->irotAxis, cursor->rotation_axis);
td_ext->irotAngle = cursor->rotation_angle;
copy_v3_v3(td_ext->irotAxis, cursor->rotation_axis);
}
else {
td->ext->rot = nullptr;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = cursor->rotation_quaternion;
td_ext->rot = nullptr;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = cursor->rotation_quaternion;
copy_qt_qt(td->ext->iquat, cursor->rotation_quaternion);
copy_qt_qt(td_ext->iquat, cursor->rotation_quaternion);
}
td->ext->rotOrder = cursor->rotation_mode;
td_ext->rotOrder = cursor->rotation_mode;
}
static void recalcData_cursor_view3d(TransInfo *t)

View File

@@ -227,7 +227,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
td->flag = 0;
}
}
td->ext = nullptr;
td->val = nullptr;
hdata = initTransDataCurveHandles(td, bezt);
@@ -253,7 +252,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
else {
td->flag = 0;
}
td->ext = nullptr;
/* TODO: make points scale. */
if (t->mode == TFM_CURVE_SHRINKFATTEN /* `|| t->mode == TFM_RESIZE` */) {
@@ -309,7 +307,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
td->flag = 0;
}
}
td->ext = nullptr;
td->val = nullptr;
if (hdata == nullptr) {
@@ -345,7 +342,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
else {
td->flag = 0;
}
td->ext = nullptr;
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_RESIZE)) {
td->val = &(bp->radius);

View File

@@ -629,7 +629,6 @@ void curve_populate_trans_data_structs(const TransInfo &t,
td.val = value;
td.ival = *value;
}
td.ext = nullptr;
if (deformation.deform_mats.is_empty()) {
copy_m3_m3(td.smtx, smtx_base.ptr());

View File

@@ -110,7 +110,6 @@ static void bezt_to_transdata(TransData *td,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
/* Store AnimData info in td->extra, for applying mapping when flushing.

View File

@@ -98,7 +98,6 @@ static void createTransLatticeVerts(bContext * /*C*/, TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
td->ext = nullptr;
td->val = nullptr;
td++;

View File

@@ -90,7 +90,6 @@ static void MaskHandleToTransData(MaskSplinePoint *point,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
if (is_sel_any) {
@@ -156,8 +155,6 @@ static void MaskPointToTransData(Scene *scene,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
if (i == 1) {
/* Scaling weights. */
td->val = &bezt->weight;

View File

@@ -88,8 +88,6 @@ static void createTransMBallVerts(bContext * /*C*/, TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
td->ext = tx;
/* Radius of MetaElem (mass of MetaElem influence). */
if (ml->flag & MB_SCALE_RAD) {
td->val = &ml->rad;

View File

@@ -1474,11 +1474,9 @@ static void VertsToTransData(TransInfo *t,
td->axismtx[1][1] = td->axismtx[1][2] = 0.0f;
}
td->ext = nullptr;
td->val = nullptr;
td->extra = eve;
if (t->mode == TFM_SHRINKFATTEN) {
td->ext = tx;
tx->iscale[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT);
}
}

View File

@@ -104,8 +104,6 @@ static void createTransEdge(bContext * /*C*/, TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
td->ext = nullptr;
fl_ptr = static_cast<float *>(BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset));
td->val = fl_ptr;
td->ival = *fl_ptr;

View File

@@ -61,7 +61,6 @@ static void UVsToTransData(const float aspect[2],
memset(r_td->axismtx, 0, sizeof(r_td->axismtx));
r_td->axismtx[2][2] = 1.0f;
r_td->ext = nullptr;
r_td->val = nullptr;
if (selected) {

View File

@@ -74,7 +74,6 @@ static void create_transform_data_for_node(TransData &td,
memset(td.axismtx, 0, sizeof(td.axismtx));
td.axismtx[2][2] = 1.0f;
td.ext = nullptr;
td.val = nullptr;
td.flag = TD_SELECTED;

View File

@@ -139,7 +139,7 @@ static void trans_obchild_in_obmode_update_all(TransInfo *t)
/**
* Transcribe given object into TransData for Transforming.
*/
static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
static void ObjectToTransData(TransInfo *t, TransData *td, TransDataExtension *td_ext, Object *ob)
{
Scene *scene = t->scene;
bool constinv;
@@ -154,17 +154,17 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
if (BKE_rigidbody_check_sim_running(scene->rigidbody_world, ctime)) {
/* Save original object transform. */
copy_v3_v3(td->ext->oloc, ob->loc);
copy_v3_v3(td_ext->oloc, ob->loc);
if (ob->rotmode > 0) {
copy_v3_v3(td->ext->orot, ob->rot);
copy_v3_v3(td_ext->orot, ob->rot);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
td->ext->orotAngle = ob->rotAngle;
copy_v3_v3(td->ext->orotAxis, ob->rotAxis);
td_ext->orotAngle = ob->rotAngle;
copy_v3_v3(td_ext->orotAxis, ob->rotAxis);
}
else {
copy_qt_qt(td->ext->oquat, ob->quat);
copy_qt_qt(td_ext->oquat, ob->quat);
}
/* Update object's loc/rot to get current rigid body transform. */
mat4_to_loc_rot_size(ob->loc, rot, scale, ob->object_to_world().ptr());
@@ -176,8 +176,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
/* `axismtx` has the real orientation. */
transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->object_to_world().ptr()));
if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) {
if (!gimbal_axis_object(ob, td->ext->axismtx_gimbal)) {
copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx);
if (!gimbal_axis_object(ob, td_ext->axismtx_gimbal)) {
copy_m3_m3(td_ext->axismtx_gimbal, td->axismtx);
}
}
@@ -228,46 +228,46 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
copy_v3_v3(td->iloc, td->loc);
if (ob->rotmode > 0) {
td->ext->rot = ob->rot;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = nullptr;
td_ext->rot = ob->rot;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = nullptr;
copy_v3_v3(td->ext->irot, ob->rot);
copy_v3_v3(td->ext->drot, ob->drot);
copy_v3_v3(td_ext->irot, ob->rot);
copy_v3_v3(td_ext->drot, ob->drot);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
td->ext->rot = nullptr;
td->ext->rotAxis = ob->rotAxis;
td->ext->rotAngle = &ob->rotAngle;
td->ext->quat = nullptr;
td_ext->rot = nullptr;
td_ext->rotAxis = ob->rotAxis;
td_ext->rotAngle = &ob->rotAngle;
td_ext->quat = nullptr;
td->ext->irotAngle = ob->rotAngle;
copy_v3_v3(td->ext->irotAxis, ob->rotAxis);
td_ext->irotAngle = ob->rotAngle;
copy_v3_v3(td_ext->irotAxis, ob->rotAxis);
/* XXX, not implemented. */
#if 0
td->ext->drotAngle = ob->drotAngle;
copy_v3_v3(td->ext->drotAxis, ob->drotAxis);
td_ext->drotAngle = ob->drotAngle;
copy_v3_v3(td_ext->drotAxis, ob->drotAxis);
#endif
}
else {
td->ext->rot = nullptr;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = ob->quat;
td_ext->rot = nullptr;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = ob->quat;
copy_qt_qt(td->ext->iquat, ob->quat);
copy_qt_qt(td->ext->dquat, ob->dquat);
copy_qt_qt(td_ext->iquat, ob->quat);
copy_qt_qt(td_ext->dquat, ob->dquat);
}
td->ext->rotOrder = ob->rotmode;
td_ext->rotOrder = ob->rotmode;
td->ext->scale = ob->scale;
copy_v3_v3(td->ext->iscale, ob->scale);
copy_v3_v3(td->ext->dscale, ob->dscale);
td_ext->scale = ob->scale;
copy_v3_v3(td_ext->iscale, ob->scale);
copy_v3_v3(td_ext->dscale, ob->dscale);
copy_v3_v3(td->center, ob->object_to_world().location());
copy_m4_m4(td->ext->obmat, ob->object_to_world().ptr());
copy_m4_m4(td_ext->obmat, ob->object_to_world().ptr());
/* Is there a need to set the global<->data space conversion matrices? */
if (ob->parent || constinv) {
@@ -534,8 +534,7 @@ static void createTransObject(bContext *C, TransInfo *t)
td->flag = TD_SELECTED;
td->protectflag = ob->protectflag;
td->ext = tx;
td->ext->rotOrder = ob->rotmode;
tx->rotOrder = ob->rotmode;
if (base->flag & BA_TRANSFORM_CHILD) {
td->flag |= TD_NOCENTER;
@@ -565,7 +564,7 @@ static void createTransObject(bContext *C, TransInfo *t)
}
}
ObjectToTransData(t, td, ob);
ObjectToTransData(t, td, tx, ob);
td->val = nullptr;
td++;
tx++;
@@ -588,10 +587,9 @@ static void createTransObject(bContext *C, TransInfo *t)
BASE_SELECTABLE(v3d, base))
{
td->protectflag = ob->protectflag;
td->ext = tx;
td->ext->rotOrder = ob->rotmode;
tx->rotOrder = ob->rotmode;
ObjectToTransData(t, td, ob);
ObjectToTransData(t, td, tx, ob);
td->val = nullptr;
td++;
tx++;
@@ -906,6 +904,7 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t)
for (int i = 0; i < tc->data_len; i++) {
TransData *td = tc->data + i;
TransDataExtension *td_ext = tc->data_ext + i;
ListBase pidlist;
ob = static_cast<Object *>(td->extra);
@@ -945,12 +944,8 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t)
if (ob->rigidbody_object && canceled) {
float ctime = BKE_scene_ctime_get(t->scene);
if (BKE_rigidbody_check_sim_running(t->scene->rigidbody_world, ctime)) {
BKE_rigidbody_aftertrans_update(ob,
td->ext->oloc,
td->ext->orot,
td->ext->oquat,
td->ext->orotAxis,
td->ext->orotAngle);
BKE_rigidbody_aftertrans_update(
ob, td_ext->oloc, td_ext->orot, td_ext->oquat, td_ext->orotAxis, td_ext->orotAngle);
}
}
}

View File

@@ -36,6 +36,7 @@ static void createTransTexspace(bContext * /*C*/, TransInfo *t)
{
ViewLayer *view_layer = t->view_layer;
TransData *td;
TransDataExtension *td_ext;
Object *ob;
ID *id;
char *texspace_flag;
@@ -63,7 +64,7 @@ static void createTransTexspace(bContext * /*C*/, TransInfo *t)
TransDataContainer *tc = t->data_container;
tc->data_len = 1;
td = tc->data = MEM_callocN<TransData>("TransTexspace");
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
td_ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
}
td->flag = TD_SELECTED;
@@ -74,14 +75,14 @@ static void createTransTexspace(bContext * /*C*/, TransInfo *t)
normalize_m3(td->axismtx);
pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &td->loc, &td->ext->scale)) {
if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &td->loc, &td_ext->scale)) {
ob->dtx |= OB_TEXSPACE;
*texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO;
}
copy_v3_v3(td->iloc, td->loc);
copy_v3_v3(td->center, td->loc);
copy_v3_v3(td->ext->iscale, td->ext->scale);
copy_v3_v3(td_ext->iscale, td_ext->scale);
}
/** \} */

View File

@@ -48,7 +48,6 @@ static void PaintCurveConvertHandle(
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
td->flag |= TD_SELECTED;
td->dist = 0.0;
@@ -82,7 +81,6 @@ static void PaintCurvePointToTransData(PaintCurvePoint *pcp,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
td->flag |= TD_SELECTED;
td->dist = 0.0;

View File

@@ -143,7 +143,6 @@ static void createTransParticleVerts(bContext * /*C*/, TransInfo *t)
td->protectflag |= OB_LOCK_LOC;
}
td->ext = tx;
if (t->mode == TFM_BAKE_TIME) {
td->val = key->time;
td->ival = *(key->time);

View File

@@ -116,7 +116,6 @@ static void createTransPointCloudVerts(bContext * /*C*/, TransInfo *t)
td.val = value;
td.ival = *value;
}
td.ext = nullptr;
copy_m3_m3(td.smtx, smtx_base.ptr());
copy_m3_m3(td.mtx, mtx_base.ptr());

View File

@@ -32,6 +32,7 @@ namespace blender::ed::transform {
static void createTransSculpt(bContext *C, TransInfo *t)
{
TransData *td;
TransDataExtension *td_ext;
Scene *scene = t->scene;
if (!BKE_id_is_editable(CTX_data_main(C), &scene->id)) {
@@ -54,7 +55,7 @@ static void createTransSculpt(bContext *C, TransInfo *t)
tc->data_len = 1;
tc->is_active = true;
td = tc->data = MEM_callocN<TransData>(__func__);
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>(__func__);
td_ext = tc->data_ext = MEM_callocN<TransDataExtension>(__func__);
}
td->flag = TD_SELECTED;
@@ -72,24 +73,24 @@ static void createTransSculpt(bContext *C, TransInfo *t)
copy_m3_m4(obmat_inv, ob.object_to_world().ptr());
invert_m3(obmat_inv);
td->ext->rot = nullptr;
td->ext->rotAxis = nullptr;
td->ext->rotAngle = nullptr;
td->ext->quat = ss.pivot_rot;
copy_m4_m4(td->ext->obmat, ob.object_to_world().ptr());
copy_m3_m3(td->ext->l_smtx, obmat_inv);
copy_m3_m4(td->ext->r_mtx, ob.object_to_world().ptr());
copy_m3_m3(td->ext->r_smtx, obmat_inv);
td_ext->rot = nullptr;
td_ext->rotAxis = nullptr;
td_ext->rotAngle = nullptr;
td_ext->quat = ss.pivot_rot;
copy_m4_m4(td_ext->obmat, ob.object_to_world().ptr());
copy_m3_m3(td_ext->l_smtx, obmat_inv);
copy_m3_m4(td_ext->r_mtx, ob.object_to_world().ptr());
copy_m3_m3(td_ext->r_smtx, obmat_inv);
copy_qt_qt(td->ext->iquat, ss.pivot_rot);
td->ext->rotOrder = ROT_MODE_QUAT;
copy_qt_qt(td_ext->iquat, ss.pivot_rot);
td_ext->rotOrder = ROT_MODE_QUAT;
ss.pivot_scale[0] = 1.0f;
ss.pivot_scale[1] = 1.0f;
ss.pivot_scale[2] = 1.0f;
td->ext->scale = ss.pivot_scale;
td_ext->scale = ss.pivot_scale;
copy_v3_v3(ss.init_pivot_scale, ss.pivot_scale);
copy_v3_v3(td->ext->iscale, ss.init_pivot_scale);
copy_v3_v3(td_ext->iscale, ss.init_pivot_scale);
copy_m3_m3(td->smtx, obmat_inv);
copy_m3_m4(td->mtx, ob.object_to_world().ptr());

View File

@@ -213,7 +213,6 @@ static TransData *SeqToTransData(Scene *scene,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
td->flag |= TD_SELECTED;

View File

@@ -121,7 +121,6 @@ static TransData *SeqToTransData(
store_transform_properties(scene, strip, origin, td);
}
td->ext = nullptr;
td->flag |= TD_SELECTED;
td->dist = 0.0;

View File

@@ -59,7 +59,6 @@ static TransData *SeqToTransData(const Scene *scene,
tdseq->key_index = seq::retiming_key_index_get(strip, key);
td->extra = static_cast<void *>(tdseq);
td->ext = nullptr;
td->flag |= TD_SELECTED;
td->dist = 0.0;

View File

@@ -145,7 +145,6 @@ static void markerToTransDataInit(TransformInitContext *init_context,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
td->flag |= TD_SELECTED;
@@ -268,7 +267,6 @@ static void planeMarkerToTransDataInit(TransformInitContext *init_context,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
td->flag |= TD_SELECTED;

View File

@@ -77,7 +77,6 @@ static void markerToTransCurveDataInit(TransData *td,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
td->ext = nullptr;
td->val = nullptr;
td->flag |= TD_SELECTED;

View File

@@ -824,24 +824,6 @@ void postTrans(bContext *C, TransInfo *t)
}
}
void applyTransObjects(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
TransData *td;
for (td = tc->data; td < tc->data + tc->data_len; td++) {
copy_v3_v3(td->iloc, td->loc);
if (td->ext->rot) {
copy_v3_v3(td->ext->irot, td->ext->rot);
}
if (td->ext->scale) {
copy_v3_v3(td->ext->iscale, td->ext->scale);
}
}
recalc_data(t);
}
static void transdata_restore_basic(TransDataBasic *td_basic)
{
if (td_basic->loc) {
@@ -860,25 +842,6 @@ static void restoreElement(TransData *td)
{
transdata_restore_basic((TransDataBasic *)td);
if (td->ext && (td->flag & TD_NO_EXT) == 0) {
if (td->ext->rot) {
copy_v3_v3(td->ext->rot, td->ext->irot);
}
if (td->ext->rotAngle) {
*td->ext->rotAngle = td->ext->irotAngle;
}
if (td->ext->rotAxis) {
copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis);
}
/* XXX, `drotAngle` & `drotAxis` not used yet. */
if (td->ext->scale) {
copy_v3_v3(td->ext->scale, td->ext->iscale);
}
if (td->ext->quat) {
copy_qt_qt(td->ext->quat, td->ext->iquat);
}
}
if (td->flag & TD_BEZTRIPLE) {
*(td->hdata->h1) = td->hdata->ih1;
*(td->hdata->h2) = td->hdata->ih2;
@@ -901,6 +864,32 @@ void restoreTransObjects(TransInfo *t)
transdata_restore_basic((TransDataBasic *)tdm);
}
if (tc->data_ext) {
for (int i = 0; i < tc->data_len; i++) {
if (tc->data[i].flag & TD_NO_EXT) {
continue;
}
TransDataExtension *td_ext = &tc->data_ext[i];
if (td_ext->rot) {
copy_v3_v3(td_ext->rot, td_ext->irot);
}
if (td_ext->rotAngle) {
*td_ext->rotAngle = td_ext->irotAngle;
}
if (td_ext->rotAxis) {
copy_v3_v3(td_ext->rotAxis, td_ext->irotAxis);
}
/* XXX, `drotAngle` & `drotAxis` not used yet. */
if (td_ext->scale) {
copy_v3_v3(td_ext->scale, td_ext->iscale);
}
if (td_ext->quat) {
copy_qt_qt(td_ext->quat, td_ext->iquat);
}
}
}
for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) {
if (td2d->h1) {
td2d->h1[0] = td2d->ih1[0];
@@ -1392,7 +1381,10 @@ void calculatePropRatio(TransInfo *t)
}
}
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
void transform_data_ext_rotate(TransData *td,
TransDataExtension *td_ext,
float mat[3][3],
bool use_drot)
{
float totmat[3][3];
float smat[3][3];
@@ -1407,30 +1399,30 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
/* Logic from #BKE_object_rot_to_mat3. */
if (use_drot) {
if (td->ext->rotOrder > 0) {
eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder);
if (td_ext->rotOrder > 0) {
eulO_to_mat3(dmat, td_ext->drot, td_ext->rotOrder);
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
#if 0
axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle);
axis_angle_to_mat3(dmat, td_ext->drotAxis, td_ext->drotAngle);
#else
unit_m3(dmat);
#endif
}
else {
float tquat[4];
normalize_qt_qt(tquat, td->ext->dquat);
normalize_qt_qt(tquat, td_ext->dquat);
quat_to_mat3(dmat, tquat);
}
invert_m3_m3(dmat_inv, dmat);
}
if (td->ext->rotOrder == ROT_MODE_QUAT) {
if (td_ext->rotOrder == ROT_MODE_QUAT) {
float quat[4];
/* Calculate the total rotation. */
quat_to_mat3(obmat, td->ext->iquat);
quat_to_mat3(obmat, td_ext->iquat);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
}
@@ -1445,13 +1437,13 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
mat3_to_quat(quat, fmat);
/* Apply. */
copy_qt_qt(td->ext->quat, quat);
copy_qt_qt(td_ext->quat, quat);
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
float axis[3], angle;
/* Calculate the total rotation. */
axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
axis_angle_to_mat3(obmat, td_ext->irotAxis, td_ext->irotAngle);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
}
@@ -1466,14 +1458,14 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
mat3_to_axis_angle(axis, &angle, fmat);
/* Apply. */
copy_v3_v3(td->ext->rotAxis, axis);
*td->ext->rotAngle = angle;
copy_v3_v3(td_ext->rotAxis, axis);
*td_ext->rotAngle = angle;
}
else {
float eul[3];
/* Calculate the total rotation. */
eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
eulO_to_mat3(obmat, td_ext->irot, td_ext->rotOrder);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
}
@@ -1485,10 +1477,10 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
mul_m3_m3m3(fmat, dmat_inv, fmat);
}
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
mat3_to_compatible_eulO(eul, td_ext->rot, td_ext->rotOrder, fmat);
/* Apply. */
copy_v3_v3(td->ext->rot, eul);
copy_v3_v3(td_ext->rot, eul);
}
}

View File

@@ -347,35 +347,36 @@ void constraintTransLim(const TransInfo *t, const TransDataContainer *tc, TransD
}
}
static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
static void constraintob_from_transdata(bConstraintOb *cob, TransDataExtension *td_ext)
{
/* Make a temporary bConstraintOb for use by limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(cob, 0, sizeof(bConstraintOb));
if (td->ext) {
if (td->ext->rotOrder == ROT_MODE_QUAT) {
/* Quaternion. */
/* Objects and bones do normalization first too, otherwise
* we don't necessarily end up with a rotation matrix, and
* then conversion back to quat gives a different result. */
float quat[4];
normalize_qt_qt(quat, td->ext->quat);
quat_to_mat4(cob->matrix, quat);
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
/* Axis angle. */
axis_angle_to_mat4(cob->matrix, td->ext->rotAxis, *td->ext->rotAngle);
}
else {
/* Eulers. */
eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder);
}
if (!td_ext) {
return;
}
if (td_ext->rotOrder == ROT_MODE_QUAT) {
/* Quaternion. */
/* Objects and bones do normalization first too, otherwise
* we don't necessarily end up with a rotation matrix, and
* then conversion back to quat gives a different result. */
float quat[4];
normalize_qt_qt(quat, td_ext->quat);
quat_to_mat4(cob->matrix, quat);
}
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
/* Axis angle. */
axis_angle_to_mat4(cob->matrix, td_ext->rotAxis, *td_ext->rotAngle);
}
else {
/* Eulers. */
eulO_to_mat4(cob->matrix, td_ext->rot, td_ext->rotOrder);
}
}
static void constraintRotLim(const TransInfo * /*t*/, TransData *td)
static void constraintRotLim(const TransInfo * /*t*/, TransData *td, TransDataExtension *td_ext)
{
if (td->con) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
@@ -409,7 +410,7 @@ static void constraintRotLim(const TransInfo * /*t*/, TransData *td)
/* Only do conversion if necessary, to preserve quaternion and euler rotations. */
if (do_limit == false) {
constraintob_from_transdata(&cob, td);
constraintob_from_transdata(&cob, td_ext);
do_limit = true;
}
@@ -432,117 +433,126 @@ static void constraintRotLim(const TransInfo * /*t*/, TransData *td)
if (do_limit) {
/* Copy results from `cob->matrix`. */
if (td->ext->rotOrder == ROT_MODE_QUAT) {
if (td_ext->rotOrder == ROT_MODE_QUAT) {
/* Quaternion. */
mat4_to_quat(td->ext->quat, cob.matrix);
mat4_to_quat(td_ext->quat, cob.matrix);
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
/* Axis angle. */
mat4_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, cob.matrix);
mat4_to_axis_angle(td_ext->rotAxis, td_ext->rotAngle, cob.matrix);
}
else {
/* Eulers. */
mat4_to_eulO(td->ext->rot, td->ext->rotOrder, cob.matrix);
mat4_to_eulO(td_ext->rot, td_ext->rotOrder, cob.matrix);
}
}
}
}
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, TransData *td)
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, int td_index)
{
if (td->con && td->ext) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {nullptr};
bConstraint *con;
float scale_sign[3], scale_abs[3];
int i;
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
/* Scale val and reset the "scale". */
return; /* TODO: fix this case. */
}
/* Reset val if SINGLESIZE but using a constraint. */
if (td->flag & TD_SINGLE_SCALE) {
return;
}
/* Separate out sign to apply back later. */
for (i = 0; i < 3; i++) {
scale_sign[i] = signf(td->ext->scale[i]);
scale_abs[i] = fabsf(td->ext->scale[i]);
}
size_to_mat4(cob.matrix, scale_abs);
/* Evaluate valid constraints. */
for (con = td->con; con; con = con->next) {
/* Only consider constraint if enabled. */
if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
continue;
}
if (con->enforce == 0.0f) {
continue;
}
/* We're only interested in Limit-Scale constraints. */
if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
bSizeLimitConstraint *data = static_cast<bSizeLimitConstraint *>(con->data);
/* Only use it if it's tagged for this purpose. */
if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
continue;
}
/* Do space conversions. */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* Just multiply by `td->mtx` (this should be ok). */
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
}
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
/* Bone space without considering object transformations. */
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
mul_m4_m3m4(cob.matrix, tc->imat3, cob.matrix);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* Skip... incompatible `spacetype`. */
continue;
}
/* Do constraint. */
cti->evaluate_constraint(con, &cob, nullptr);
/* Convert spaces again. */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* Just multiply by `td->smtx` (this should be ok). */
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
}
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
mul_m4_m3m4(cob.matrix, tc->mat3, cob.matrix);
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
}
}
}
/* Copy results from `cob->matrix`. */
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
/* Scale val and reset the "scale". */
return; /* TODO: fix this case. */
}
/* Reset val if SINGLESIZE but using a constraint. */
if (td->flag & TD_SINGLE_SCALE) {
return;
}
/* Extract scale from matrix and apply back sign. */
mat4_to_size(td->ext->scale, cob.matrix);
mul_v3_v3(td->ext->scale, scale_sign);
if (!tc->data_ext) {
return;
}
TransData *td = &tc->data[td_index];
if (!td->con) {
return;
}
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
/* Scale val and reset the "scale". */
return; /* TODO: fix this case. */
}
/* Reset val if SINGLESIZE but using a constraint. */
if (td->flag & TD_SINGLE_SCALE) {
return;
}
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {nullptr};
bConstraint *con;
float scale_sign[3], scale_abs[3];
int i;
TransDataExtension *td_ext = &tc->data_ext[td_index];
/* Separate out sign to apply back later. */
for (i = 0; i < 3; i++) {
scale_sign[i] = signf(td_ext->scale[i]);
scale_abs[i] = fabsf(td_ext->scale[i]);
}
size_to_mat4(cob.matrix, scale_abs);
/* Evaluate valid constraints. */
for (con = td->con; con; con = con->next) {
/* Only consider constraint if enabled. */
if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
continue;
}
if (con->enforce == 0.0f) {
continue;
}
/* We're only interested in Limit-Scale constraints. */
if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
bSizeLimitConstraint *data = static_cast<bSizeLimitConstraint *>(con->data);
/* Only use it if it's tagged for this purpose. */
if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
continue;
}
/* Do space conversions. */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* Just multiply by `td->mtx` (this should be ok). */
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
}
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
/* Bone space without considering object transformations. */
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
mul_m4_m3m4(cob.matrix, tc->imat3, cob.matrix);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* Skip... incompatible `spacetype`. */
continue;
}
/* Do constraint. */
cti->evaluate_constraint(con, &cob, nullptr);
/* Convert spaces again. */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* Just multiply by `td->smtx` (this should be ok). */
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
}
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
mul_m4_m3m4(cob.matrix, tc->mat3, cob.matrix);
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
}
}
}
/* Copy results from `cob->matrix`. */
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
/* Scale val and reset the "scale". */
return; /* TODO: fix this case. */
}
/* Reset val if SINGLESIZE but using a constraint. */
if (td->flag & TD_SINGLE_SCALE) {
return;
}
/* Extract scale from matrix and apply back sign. */
mat4_to_size(td_ext->scale, cob.matrix);
mul_v3_v3(td_ext->scale, scale_sign);
}
/** \} */
@@ -581,6 +591,7 @@ void headerRotation(TransInfo *t, char *str, const int str_size, float final)
void ElementRotation_ex(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float mat[3][3],
const float *center)
{
@@ -616,11 +627,11 @@ void ElementRotation_ex(const TransInfo *t,
mul_m3_series(fmat, td->smtx, mat, td->mtx);
mat3_to_quat(quat, fmat); /* Actual transform. */
if (td->ext->quat) {
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
if (td_ext->quat) {
mul_qt_qtqt(td_ext->quat, quat, td_ext->iquat);
/* Is there a reason not to have this here? -jahka. */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
protectedQuaternionBits(td->protectflag, td_ext->quat, td_ext->iquat);
}
}
}
@@ -656,8 +667,8 @@ void ElementRotation_ex(const TransInfo *t,
/* Do nothing. */
}
else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
mul_m3_v3(tc->mat3, vec); /* To Global space. */
mul_m3_v3(td->ext->l_smtx, vec); /* To Pose space (Local Location). */
mul_m3_v3(tc->mat3, vec); /* To Global space. */
mul_m3_v3(td_ext->l_smtx, vec); /* To Pose space (Local Location). */
}
else {
mul_m3_v3(tc->mat3, vec); /* To Global space. */
@@ -675,58 +686,58 @@ void ElementRotation_ex(const TransInfo *t,
/* MORE HACK: as in some cases the matrix to apply location and rot/scale is not the same,
* and ElementRotation() might be called in Translation context (with align snapping),
* we need to be sure to actually use the *rotation* matrix here...
* So no other way than storing it in some dedicated members of `td->ext`! */
* So no other way than storing it in some dedicated members of `td_ext`! */
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't rotate objects itself. */
/* Euler or quaternion/axis-angle? */
if (td->ext->rotOrder == ROT_MODE_QUAT) {
mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
if (td_ext->rotOrder == ROT_MODE_QUAT) {
mul_m3_series(fmat, td_ext->r_smtx, mat, td_ext->r_mtx);
mat3_to_quat(quat, fmat); /* Actual transform. */
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
mul_qt_qtqt(td_ext->quat, quat, td_ext->iquat);
/* This function works on end result. */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
protectedQuaternionBits(td->protectflag, td_ext->quat, td_ext->iquat);
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
/* Calculate effect based on quaternions. */
float iquat[4], tquat[4];
axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
axis_angle_to_quat(iquat, td_ext->irotAxis, td_ext->irotAngle);
mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
mul_m3_series(fmat, td_ext->r_smtx, mat, td_ext->r_mtx);
mat3_to_quat(quat, fmat); /* Actual transform. */
mul_qt_qtqt(tquat, quat, iquat);
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
quat_to_axis_angle(td_ext->rotAxis, td_ext->rotAngle, tquat);
/* This function works on end result. */
protectedAxisAngleBits(td->protectflag,
td->ext->rotAxis,
td->ext->rotAngle,
td->ext->irotAxis,
td->ext->irotAngle);
td_ext->rotAxis,
td_ext->rotAngle,
td_ext->irotAxis,
td_ext->irotAngle);
}
else {
float eulmat[3][3];
mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
mul_m3_m3m3(totmat, mat, td_ext->r_mtx);
mul_m3_m3m3(smat, td_ext->r_smtx, totmat);
/* Calculate the total rotation in eulers. */
copy_v3_v3(eul, td->ext->irot);
eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
copy_v3_v3(eul, td_ext->irot);
eulO_to_mat3(eulmat, eul, td_ext->rotOrder);
/* `mat = transform`, `obmat = bone rotation`. */
mul_m3_m3m3(fmat, smat, eulmat);
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
mat3_to_compatible_eulO(eul, td_ext->rot, td_ext->rotOrder, fmat);
/* And apply (to end result only). */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
copy_v3_v3(td->ext->rot, eul);
protectedRotateBits(td->protectflag, eul, td_ext->irot);
copy_v3_v3(td_ext->rot, eul);
}
constraintRotLim(t, td);
constraintRotLim(t, td, td_ext);
}
}
else {
@@ -749,51 +760,51 @@ void ElementRotation_ex(const TransInfo *t,
/* Rotation. */
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't rotate objects itself. */
/* Euler or quaternion? */
if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
if ((td_ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
/* Can be called for texture space translate for example, then opt out. */
if (td->ext->quat) {
if (td_ext->quat) {
mul_m3_series(fmat, td->smtx, mat, td->mtx);
if (!is_zero_v3(td->ext->dquat)) {
if (!is_zero_v3(td_ext->dquat)) {
/* Correct for delta quat. */
float tmp_mat[3][3];
quat_to_mat3(tmp_mat, td->ext->dquat);
quat_to_mat3(tmp_mat, td_ext->dquat);
mul_m3_m3m3(fmat, fmat, tmp_mat);
}
mat3_to_quat(quat, fmat); /* Actual transform. */
if (!is_zero_v4(td->ext->dquat)) {
if (!is_zero_v4(td_ext->dquat)) {
/* Correct back for delta quaternion. */
float idquat[4];
invert_qt_qt_normalized(idquat, td->ext->dquat);
invert_qt_qt_normalized(idquat, td_ext->dquat);
mul_qt_qtqt(quat, idquat, quat);
}
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
mul_qt_qtqt(td_ext->quat, quat, td_ext->iquat);
/* This function works on end result. */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
protectedQuaternionBits(td->protectflag, td_ext->quat, td_ext->iquat);
}
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
/* Calculate effect based on quaternions. */
float iquat[4], tquat[4];
axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
axis_angle_to_quat(iquat, td_ext->irotAxis, td_ext->irotAngle);
mul_m3_series(fmat, td->smtx, mat, td->mtx);
mat3_to_quat(quat, fmat); /* Actual transform. */
mul_qt_qtqt(tquat, quat, iquat);
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
quat_to_axis_angle(td_ext->rotAxis, td_ext->rotAngle, tquat);
/* This function works on end result. */
protectedAxisAngleBits(td->protectflag,
td->ext->rotAxis,
td->ext->rotAngle,
td->ext->irotAxis,
td->ext->irotAngle);
td_ext->rotAxis,
td_ext->rotAngle,
td_ext->irotAxis,
td_ext->irotAngle);
}
else {
/* Calculate the total rotation in eulers. */
@@ -802,29 +813,29 @@ void ElementRotation_ex(const TransInfo *t,
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
if (!is_zero_v3(td->ext->drot)) {
if (!is_zero_v3(td_ext->drot)) {
/* Correct for delta rot. */
add_eul_euleul(eul, td->ext->irot, td->ext->drot, td->ext->rotOrder);
add_eul_euleul(eul, td_ext->irot, td_ext->drot, td_ext->rotOrder);
}
else {
copy_v3_v3(eul, td->ext->irot);
copy_v3_v3(eul, td_ext->irot);
}
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
eulO_to_mat3(obmat, eul, td_ext->rotOrder);
mul_m3_m3m3(fmat, smat, obmat);
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
mat3_to_compatible_eulO(eul, td_ext->rot, td_ext->rotOrder, fmat);
if (!is_zero_v3(td->ext->drot)) {
if (!is_zero_v3(td_ext->drot)) {
/* Correct back for delta rot. */
sub_eul_euleul(eul, eul, td->ext->drot, td->ext->rotOrder);
sub_eul_euleul(eul, eul, td_ext->drot, td_ext->rotOrder);
}
/* And apply. */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
copy_v3_v3(td->ext->rot, eul);
protectedRotateBits(td->protectflag, eul, td_ext->irot);
copy_v3_v3(td_ext->rot, eul);
}
constraintRotLim(t, td);
constraintRotLim(t, td, td_ext);
}
}
}
@@ -832,6 +843,7 @@ void ElementRotation_ex(const TransInfo *t,
void ElementRotation(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float mat[3][3],
const short around)
{
@@ -845,7 +857,7 @@ void ElementRotation(const TransInfo *t,
center = tc->center_local;
}
ElementRotation_ex(t, tc, td, mat, center);
ElementRotation_ex(t, tc, td, td_ext, mat, center);
}
/** \} */
@@ -951,9 +963,11 @@ static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float
void ElementResize(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
int td_index,
const float mat[3][3])
{
TransData *td = &tc->data[td_index];
float tmat[3][3], smat[3][3], center[3];
float vec[3];
@@ -985,51 +999,55 @@ void ElementResize(const TransInfo *t,
copy_v3_v3(center, tc->center_local);
}
/* Size checked needed since the 3D cursor only uses rotation fields. */
if (td->ext && td->ext->scale) {
float fscale[3];
if (tc->data_ext) {
TransDataExtension *td_ext = &tc->data_ext[td_index];
if (ELEM(t->data_type,
&TransConvertType_Sculpt,
&TransConvertType_Object,
&TransConvertType_ObjectTexSpace,
&TransConvertType_Pose))
{
float ob_scale_mat[3][3];
/* Reorient the size mat to fit the oriented object. */
mul_m3_m3m3(ob_scale_mat, tmat, td->axismtx);
// print_m3("ob_scale_mat", ob_scale_mat);
TransMat3ToSize(ob_scale_mat, td->axismtx, fscale);
// print_v3("fscale", fscale);
}
else {
mat3_to_size(fscale, tmat);
}
/* Size checked needed since the 3D cursor only uses rotation fields. */
if (td_ext->scale) {
float fscale[3];
protectedScaleBits(td->protectflag, fscale);
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't resize objects itself. */
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
/* Scale val and reset scale. */
*td->val = td->ival * (1 + (fscale[0] - 1) * td->factor);
td->ext->scale[0] = td->ext->iscale[0];
td->ext->scale[1] = td->ext->iscale[1];
td->ext->scale[2] = td->ext->iscale[2];
if (ELEM(t->data_type,
&TransConvertType_Sculpt,
&TransConvertType_Object,
&TransConvertType_ObjectTexSpace,
&TransConvertType_Pose))
{
float ob_scale_mat[3][3];
/* Reorient the size mat to fit the oriented object. */
mul_m3_m3m3(ob_scale_mat, tmat, td->axismtx);
// print_m3("ob_scale_mat", ob_scale_mat);
TransMat3ToSize(ob_scale_mat, td->axismtx, fscale);
// print_v3("fscale", fscale);
}
else {
/* Reset val if #TD_SINGLE_SCALE but using a constraint. */
if (td->flag & TD_SINGLE_SCALE) {
*td->val = td->ival;
}
td->ext->scale[0] = td->ext->iscale[0] * (1 + (fscale[0] - 1) * td->factor);
td->ext->scale[1] = td->ext->iscale[1] * (1 + (fscale[1] - 1) * td->factor);
td->ext->scale[2] = td->ext->iscale[2] * (1 + (fscale[2] - 1) * td->factor);
mat3_to_size(fscale, tmat);
}
}
constraintScaleLim(t, tc, td);
protectedScaleBits(td->protectflag, fscale);
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't resize objects itself. */
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
/* Scale val and reset scale. */
*td->val = td->ival * (1 + (fscale[0] - 1) * td->factor);
td_ext->scale[0] = td_ext->iscale[0];
td_ext->scale[1] = td_ext->iscale[1];
td_ext->scale[2] = td_ext->iscale[2];
}
else {
/* Reset val if #TD_SINGLE_SCALE but using a constraint. */
if (td->flag & TD_SINGLE_SCALE) {
*td->val = td->ival;
}
td_ext->scale[0] = td_ext->iscale[0] * (1 + (fscale[0] - 1) * td->factor);
td_ext->scale[1] = td_ext->iscale[1] * (1 + (fscale[1] - 1) * td->factor);
td_ext->scale[2] = td_ext->iscale[2] * (1 + (fscale[2] - 1) * td->factor);
}
}
constraintScaleLim(t, tc, td_index);
}
}
/* For individual element center, Editmode need to use iloc. */

View File

@@ -74,7 +74,7 @@ bool transform_mode_affect_only_locations(const TransInfo *t);
void protectedTransBits(short protectflag, float vec[3]);
void protectedScaleBits(short protectflag, float scale[3]);
void constraintTransLim(const TransInfo *t, const TransDataContainer *tc, TransData *td);
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, TransData *td);
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, int td_index);
/**
* Used by Transform Rotation and Transform Normal Rotation.
*/
@@ -88,17 +88,19 @@ void headerRotation(TransInfo *t, char *str, int str_size, float final);
void ElementRotation_ex(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float mat[3][3],
const float *center);
void ElementRotation(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float mat[3][3],
short around);
void headerResize(TransInfo *t, const float vec[3], char *str, int str_size);
void ElementResize(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
int td_index,
const float mat[3][3]);
void transform_mode_init(TransInfo *t, wmOperator *op, int mode);
/**

View File

@@ -56,7 +56,8 @@ static void applyAlign(TransInfo *t)
mul_m3_m3m3(mat, t->spacemtx, invmat);
ElementRotation(t, tc, td, mat, t->around);
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
ElementRotation(t, tc, td, td_ext, mat, t->around);
}
/* Restoring original center. */
copy_v3_v3(tc->center_local, center);

View File

@@ -82,7 +82,8 @@ static void applyBakeTime(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
TransDataExtension *td_ext = tc->data_ext;
for (i = 0; i < tc->data_len; i++, td++, td_ext++) {
if (td->flag & TD_SKIP) {
continue;
}
@@ -98,11 +99,11 @@ static void applyBakeTime(TransInfo *t)
}
*dst = ival + time * td->factor;
if (td->ext->scale && *dst < *td->ext->scale) {
*dst = *td->ext->scale;
if (td_ext->scale && *dst < *td_ext->scale) {
*dst = *td_ext->scale;
}
if (td->ext->quat && *dst > *td->ext->quat) {
*dst = *td->ext->quat;
if (td_ext->quat && *dst > *td_ext->quat) {
*dst = *td_ext->quat;
}
}
}

View File

@@ -64,6 +64,7 @@ struct BendCustomData {
static void transdata_elem_bend(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
float angle,
const BendCustomData *bend_data,
const float warp_sta_local[3],
@@ -120,7 +121,7 @@ static void transdata_elem_bend(const TransInfo *t,
/* Rotation. */
if ((t->flag & T_POINTS) == 0) {
ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
ElementRotation(t, tc, td, td_ext, mat, V3D_AROUND_LOCAL_ORIGINS);
}
/* Location. */
@@ -248,12 +249,14 @@ static void Bend(TransInfo *t)
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
for (const int i : range) {
TransData *td = &tc->data[i];
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
if (td->flag & TD_SKIP) {
continue;
}
transdata_elem_bend(t,
tc,
td,
td_ext,
values.angle,
bend_data,
warp_sta_local,

View File

@@ -39,11 +39,15 @@ namespace blender::ed::transform {
* \param flip: If true, a mirror on all axis will be performed additionally (point
* reflection).
*/
static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, int axis, bool flip)
static void ElementMirror(TransInfo *t, TransDataContainer *tc, int td_index, int axis, bool flip)
{
if ((t->flag & T_V3D_ALIGN) == 0 && td->ext) {
TransData *td = &tc->data[td_index];
if ((t->flag & T_V3D_ALIGN) == 0 && tc->data_ext) {
TransDataExtension *td_ext = &tc->data_ext[td_index];
/* Size checked needed since the 3D cursor only uses rotation fields. */
if (td->ext->scale) {
if (td_ext->scale) {
float fscale[] = {1.0, 1.0, 1.0};
if (axis >= 0) {
@@ -55,9 +59,9 @@ static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, i
protectedScaleBits(td->protectflag, fscale);
mul_v3_v3v3(td->ext->scale, td->ext->iscale, fscale);
mul_v3_v3v3(td_ext->scale, td_ext->iscale, fscale);
constraintScaleLim(t, tc, td);
constraintScaleLim(t, tc, td_index);
}
float rmat[3][3];
@@ -74,18 +78,18 @@ static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, i
mul_m3_m3m3(rmat, rmat, imat);
mul_m3_m3m3(rmat, t->spacemtx, rmat);
ElementRotation_ex(t, tc, td, rmat, td->center);
ElementRotation_ex(t, tc, td, td_ext, rmat, td->center);
if (td->ext->rotAngle) {
*td->ext->rotAngle = -td->ext->irotAngle;
if (td_ext->rotAngle) {
*td_ext->rotAngle = -td_ext->irotAngle;
}
}
else {
unit_m3(rmat);
ElementRotation_ex(t, tc, td, rmat, td->center);
ElementRotation_ex(t, tc, td, td_ext, rmat, td->center);
if (td->ext->rotAngle) {
*td->ext->rotAngle = td->ext->irotAngle;
if (td_ext->rotAngle) {
*td_ext->rotAngle = td_ext->irotAngle;
}
}
}
@@ -196,7 +200,7 @@ static void applyMirror(TransInfo *t)
continue;
}
ElementMirror(t, tc, td, special_axis, bitmap_len >= 2);
ElementMirror(t, tc, i, special_axis, bitmap_len >= 2);
}
}
@@ -216,7 +220,7 @@ static void applyMirror(TransInfo *t)
continue;
}
ElementMirror(t, tc, td, -1, false);
ElementMirror(t, tc, i, -1, false);
}
}

View File

@@ -220,7 +220,7 @@ static void applyResize(TransInfo *t)
if (td->flag & TD_SKIP) {
continue;
}
ElementResize(t, tc, td, mat);
ElementResize(t, tc, i, mat);
}
});
}
@@ -234,9 +234,8 @@ static void applyResize(TransInfo *t)
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
ElementResize(t, tc, td, mat);
for (i = 0; i < tc->data_len; i++) {
ElementResize(t, tc, i, mat);
}
/* Not ideal, see #clipUVData code-comment. */

View File

@@ -73,6 +73,7 @@ static void rmat_cache_update(RotateMatrixCache *rmc, const float axis[3], const
static void transdata_elem_rotate(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float axis[3],
const float angle,
const float angle_step,
@@ -106,13 +107,13 @@ static void transdata_elem_rotate(const TransInfo *t,
* Otherwise, just assume it's useless (e.g. in case of mesh/UV/etc. editing).
* Also need to be in Euler rotation mode, the others never allow more than one turn anyway.
*/
if (is_large_rotation && td->ext != nullptr && td->ext->rotOrder == ROT_MODE_EUL) {
copy_v3_v3(td->ext->rot, td->ext->irot);
if (is_large_rotation && td_ext != nullptr && td_ext->rotOrder == ROT_MODE_EUL) {
copy_v3_v3(td_ext->rot, td_ext->irot);
for (float angle_progress = angle_step; fabsf(angle_progress) < fabsf(angle_final);
angle_progress += angle_step)
{
axis_angle_normalized_to_mat3(rmc->mat, axis_final, angle_progress);
ElementRotation(t, tc, td, rmc->mat, t->around);
ElementRotation(t, tc, td, td_ext, rmc->mat, t->around);
}
rmat_cache_reset(rmc);
}
@@ -122,7 +123,7 @@ static void transdata_elem_rotate(const TransInfo *t,
rmat_cache_update(rmc, axis_final, angle_final);
ElementRotation(t, tc, td, rmc->mat, t->around);
ElementRotation(t, tc, td, td_ext, rmc->mat, t->around);
}
/** \} */
@@ -210,10 +211,11 @@ static void applyRotationValue(TransInfo *t,
rmat_cache_init(&rmc, angle, axis);
for (const int i : range) {
TransData *td = &tc->data[i];
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
if (td->flag & TD_SKIP) {
continue;
}
transdata_elem_rotate(t, tc, td, axis, angle, angle_step, is_large_rotation, &rmc);
transdata_elem_rotate(t, tc, td, td_ext, axis, angle, angle_step, is_large_rotation, &rmc);
}
});
}

View File

@@ -37,12 +37,13 @@ namespace blender::ed::transform {
static void transdata_elem_shrink_fatten(const TransInfo *t,
const TransDataContainer * /*tc*/,
TransData *td,
TransDataExtension *td_ext,
const float distance)
{
/* Get the final offset. */
float tdistance = distance * td->factor;
if (td->ext && (t->flag & T_ALT_TRANSFORM) != 0) {
tdistance *= td->ext->iscale[0]; /* Shell factor. */
if (td_ext && (t->flag & T_ALT_TRANSFORM) != 0) {
tdistance *= td_ext->iscale[0]; /* Shell factor. */
}
madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
@@ -118,10 +119,11 @@ static void applyShrinkFatten(TransInfo *t)
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
for (const int i : range) {
TransData *td = &tc->data[i];
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
if (td->flag & TD_SKIP) {
continue;
}
transdata_elem_shrink_fatten(t, tc, td, distance);
transdata_elem_shrink_fatten(t, tc, td, td_ext, distance);
}
});
}

View File

@@ -37,6 +37,7 @@ namespace blender::ed::transform {
static void transdata_elem_trackball(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float axis[3],
const float angle,
const float mat_final[3][3])
@@ -47,7 +48,7 @@ static void transdata_elem_trackball(const TransInfo *t,
axis_angle_normalized_to_mat3(mat_buf, axis, td->factor * angle);
mat = mat_buf;
}
ElementRotation(t, tc, td, mat, t->around);
ElementRotation(t, tc, td, td_ext, mat, t->around);
}
static void applyTrackballValue_calc_axis_angle(const TransInfo *t,
@@ -74,10 +75,11 @@ static void applyTrackballValue(TransInfo *t, const float axis[3], const float a
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
for (const int i : range) {
TransData *td = &tc->data[i];
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
if (td->flag & TD_SKIP) {
continue;
}
transdata_elem_trackball(t, tc, td, axis, angle, mat_final);
transdata_elem_trackball(t, tc, td, td_ext, axis, angle, mat_final);
}
});
}

View File

@@ -68,6 +68,7 @@ struct TranslateCustomData {
static void transdata_elem_translate(const TransInfo *t,
const TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext,
const float3 &snap_source_local,
const float3 &vec,
enum eTranslateRotateMode rotate_mode)
@@ -104,7 +105,7 @@ static void transdata_elem_translate(const TransInfo *t,
rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
}
ElementRotation_ex(t, tc, td, mat, snap_source_local);
ElementRotation_ex(t, tc, td, td_ext, mat, snap_source_local);
if (td->loc) {
use_rotate_offset = true;
@@ -436,10 +437,11 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
for (const int i : range) {
TransData *td = &tc->data[i];
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
if (td->flag & TD_SKIP) {
continue;
}
transdata_elem_translate(t, tc, td, snap_source_local, vec, rotate_mode);
transdata_elem_translate(t, tc, td, td_ext, snap_source_local, vec, rotate_mode);
}
});
}

View File

@@ -374,7 +374,10 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
return status;
}
static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td)
static bool applyFaceProject(TransInfo *t,
TransDataContainer *tc,
TransData *td,
TransDataExtension *td_ext)
{
float iloc[3], loc[3], no[3];
float mval_fl[2];
@@ -435,7 +438,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
rotation_between_vecs_to_mat3(mat, original_normal, no);
transform_data_ext_rotate(td, mat, true);
transform_data_ext_rotate(td, td_ext, mat, true);
/* TODO: support constraints for rotation too? see #ElementRotation. */
}
@@ -512,6 +515,7 @@ void transform_snap_project_individual_apply(TransInfo *t)
/* XXX: flickers in object mode. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
TransDataExtension *td_ext = tc->data_ext;
for (int i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_SKIP) {
continue;
@@ -525,7 +529,10 @@ void transform_snap_project_individual_apply(TransInfo *t)
* fall back to face nearest ray-cast does not hit. */
bool hit = false;
if (t->tsnap.mode & SCE_SNAP_INDIVIDUAL_PROJECT) {
hit = applyFaceProject(t, tc, td);
hit = applyFaceProject(t, tc, td, td_ext);
if (td_ext) {
td_ext++;
}
}
if (!hit && t->tsnap.mode & SCE_SNAP_INDIVIDUAL_NEAREST) {
@@ -1490,6 +1497,7 @@ static void snap_source_closest_fn(TransInfo *t)
/* Use bound-box if possible. */
if (bounds) {
TransDataExtension *td_ext = &tc->data_ext[i];
const std::array<float3, 8> bounds_corners = bounds::corners(*bounds);
int j;
@@ -1498,7 +1506,7 @@ static void snap_source_closest_fn(TransInfo *t)
float dist;
copy_v3_v3(loc, bounds_corners[j]);
mul_m4_v3(td->ext->obmat, loc);
mul_m4_v3(td_ext->obmat, loc);
dist = t->mode_info->snap_distance_fn(t, loc, t->tsnap.snap_target);