static void viewRedrawPost(bContext *C, TransInfo *t)
{
ED_area_headerprint(t->sa, NULL);
-
+
if (t->spacetype == SPACE_VIEW3D) {
/* if autokeying is enabled, send notifiers that keyframes were added */
if (IS_AUTOKEY_ON(t->scene))
{
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
-
+
/* XXX temp, first hack to get auto-render in compositor work (ton) */
WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C));
}
-
+
#if 0 // TRANSFORM_FIX_ME
if (t->spacetype == SPACE_VIEW3D) {
allqueue(REDRAWBUTSOBJECT, 0);
{TFM_MODAL_INSERTOFS_TOGGLE_DIR, "INSERTOFS_TOGGLE_DIR", 0, "Toggle Direction for Node Auto-offset", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Transform Modal Map");
-
+
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) return NULL;
-
+
keymap = WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items);
-
+
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, TFM_MODAL_TRANSLATE);
WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, TFM_MODAL_ROTATE);
WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, TFM_MODAL_RESIZE);
-
+
WM_modalkeymap_add_item(keymap, TABKEY, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_SNAP_TOGGLE);
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_INV_ON);
WM_modalkeymap_add_item(keymap, RIGHTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_INV_ON);
WM_modalkeymap_add_item(keymap, RIGHTCTRLKEY, KM_RELEASE, KM_ANY, 0, TFM_MODAL_SNAP_INV_OFF);
-
+
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, TFM_MODAL_ADD_SNAP);
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_ALT, 0, TFM_MODAL_REMOVE_SNAP);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0, TFM_MODAL_EDGESLIDE_UP);
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ALT, 0, TFM_MODAL_EDGESLIDE_DOWN);
-
+
WM_modalkeymap_add_item(keymap, PAGEUPKEY, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_INC);
WM_modalkeymap_add_item(keymap, PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_DEC);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_INC);
const bool edit_2d = (t->flag & T_2D_EDIT) != 0;
const char *msg1 = "", *msg2 = "", *msg3 = "";
char axis;
-
+
/* Initialize */
switch (key_type) {
case XKEY:
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
-
+
if (t->mode == TFM_ROTATION) {
initTrackball(t);
}
}
}
break;
-
+
case TFM_MODAL_SNAP_INV_ON:
t->modifiers |= MOD_SNAP_INVERT;
t->redraw |= TREDRAW_HARD;
static int helpline_poll(bContext *C)
{
ARegion *ar = CTX_wm_region(C);
-
+
if (ar && ar->regiontype == RGN_TYPE_WINDOW)
return 1;
return 0;
static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), void *arg)
{
TransInfo *t = arg;
-
+
glLineWidth(1.0);
drawConstraint(t);
int xco, yco;
ED_region_visible_rect(ar, &rect);
-
+
BLF_width_and_height_default(printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
-
+
xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
yco = (rect.ymax - U.widget_unit);
-
+
/* warning text (to clarify meaning of overlays)
* - original color was red to match the icon, but that clashes badly with a less nasty border
*/
#else
BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
#endif
-
+
/* autokey recording icon... */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
xco -= U.widget_unit;
yco -= (int)printable_size[1] / 2;
UI_icon_draw(xco, yco, ICON_REC);
-
+
glDisable(GL_BLEND);
}
static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg)
-{
+{
TransInfo *t = arg;
Scene *scene = t->scene;
Object *ob = OBACT;
-
- /* draw autokeyframing hint in the corner
- * - only draw if enabled (advanced users may be distracted/annoyed),
+
+ /* draw autokeyframing hint in the corner
+ * - only draw if enabled (advanced users may be distracted/annoyed),
* for objects that will be autokeyframed (no point ohterwise),
* AND only for the active region (as showing all is too overwhelming)
*/
ts->prop_mode = t->prop_mode;
}
}
-
+
/* do we check for parameter? */
if (t->modifiers & MOD_SNAP) {
ts->snap_flag |= SCE_SNAP;
}
}
}
-
+
if ((prop = RNA_struct_find_property(op->ptr, "proportional"))) {
RNA_property_enum_set(op->ptr, prop, proportional);
RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
options |= CTX_TEXTURE;
}
}
-
+
if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) && RNA_property_is_set(op->ptr, prop)) {
if (RNA_property_boolean_get(op->ptr, prop)) {
options |= CTX_GPENCIL_STROKES;
else if (t->mode == TFM_VERT_SLIDE) {
doVertSlide(t, 0.0f);
}
-
+
exit_code = OPERATOR_CANCELLED;
restoreTransObjects(t); // calls recalcData()
}
/* check that protection flags are set */
if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0)
return;
-
+
if (protectflag & OB_LOCK_ROT4D) {
/* axis-angle getting limited as 4D entities that they are... */
if (protectflag & OB_LOCK_ROTW)
else {
/* axis-angle get limited with euler... */
float eul[3], oldeul[3];
-
+
axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, axis, *angle);
axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, oldAxis, oldAngle);
-
+
if (protectflag & OB_LOCK_ROTX)
eul[0] = oldeul[0];
if (protectflag & OB_LOCK_ROTY)
eul[1] = oldeul[1];
if (protectflag & OB_LOCK_ROTZ)
eul[2] = oldeul[2];
-
+
eulO_to_axis_angle(axis, angle, eul, EULER_ORDER_DEFAULT);
-
+
/* when converting to axis-angle, we need a special exception for the case when there is no axis */
if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
/* for now, rotate around y-axis then (so that it simply becomes the roll) */
/* check that protection flags are set */
if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0)
return;
-
+
if (protectflag & OB_LOCK_ROT4D) {
/* quaternions getting limited as 4D entities that they are... */
if (protectflag & OB_LOCK_ROTW)
/* restore original quat size */
mul_qt_fl(quat, qlen);
-
+
/* quaternions flip w sign to accumulate rotations correctly */
if ((nquat[0] < 0.0f && quat[0] > 0.0f) ||
(nquat[0] > 0.0f && quat[0] < 0.0f))
if (td->con) {
const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
-
+
bConstraintOb cob = {NULL};
bConstraint *con;
float ctime = (float)(t->scene->r.cfra);
-
+
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
unit_m4(cob.matrix);
copy_v3_v3(cob.matrix[3], td->loc);
-
+
/* Evaluate valid constraints */
for (con = td->con; con; con = con->next) {
const bConstraintTypeInfo *cti = NULL;
ListBase targets = {NULL, NULL};
-
+
/* only consider constraint if enabled */
if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
if (con->enforce == 0.0f) continue;
-
+
/* only use it if it's tagged for this purpose (and the right type) */
if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
bLocLimitConstraint *data = con->data;
-
+
if ((data->flag2 & LIMIT_TRANSFORM) == 0)
continue;
cti = ctiLoc;
}
else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) {
bDistLimitConstraint *data = con->data;
-
+
if ((data->flag & LIMITDIST_TRANSFORM) == 0)
continue;
cti = ctiDist;
}
-
+
if (cti) {
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* skip... incompatable spacetype */
continue;
}
-
+
/* get constraint targets if needed */
BKE_constraint_targets_for_solving_get(con, &cob, &targets, ctime);
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, &targets);
-
+
/* 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);
}
-
+
/* free targets list */
BLI_freelistN(&targets);
}
}
-
+
/* copy results from cob->matrix */
copy_v3_v3(td->loc, cob.matrix[3]);
}
/* just multiply by td->mtx (this should be ok) */
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->smtx (this should be ok) */
}
}
}
-
+
if (do_limit) {
/* copy results from cob->matrix */
if (td->ext->rotOrder == ROT_MODE_QUAT) {
bConstraint *con;
float size_sign[3], size_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
size_sign[i] = signf(td->ext->size[i]);
size_abs[i] = fabsf(td->ext->size[i]);
}
-
+
size_to_mat4(cob.matrix, size_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 = 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) */
/* skip... incompatible spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->smtx (this should be ok) */
const float *curs;
float tvec[3];
struct BendCustomData *data;
-
+
t->mode = TFM_BEND;
t->transform = Bend;
t->handleEvent = handleEventBend;
-
+
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE_SPRING);
-
+
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = 0.0f;
static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event)
{
eRedrawFlag status = TREDRAW_NOTHING;
-
+
if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
status = TREDRAW_HARD;
}
-
+
return status;
}
char c[NUM_STR_REP_LEN * 2];
outputNumInput(&(t->num), c, &t->scene->unit);
-
+
BLI_snprintf(str, sizeof(str), IFACE_("Bend Angle: %s Radius: %s Alt, Clamp %s"),
&c[0], &c[NUM_STR_REP_LEN],
WM_bool_as_string(is_clamp));
RAD2DEGF(values.angle), values.scale * data->warp_init_dist,
WM_bool_as_string(is_clamp));
}
-
+
values.angle *= -1.0f;
values.scale *= data->warp_init_dist;
-
+
/* calc 'data->warp_end' from 'data->warp_end_init' */
copy_v3_v3(warp_end_radius, data->warp_end);
dist_ensure_v3_v3fl(warp_end_radius, data->warp_sta, values.scale);
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
/* location */
copy_v3_v3(td->loc, vec);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
t->handleEvent = handleEventShear;
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
{
eRedrawFlag status = TREDRAW_NOTHING;
-
+
if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
/* Use custom.mode.data pointer to signal Shear direction */
if (t->custom.mode.data == NULL) {
else if (event->type == XKEY && event->val == KM_PRESS) {
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->custom.mode.data = NULL;
-
+
status = TREDRAW_HARD;
}
else if (event->type == YKEY && event->val == KM_PRESS) {
initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO);
t->custom.mode.data = (void *)1;
-
+
status = TREDRAW_HARD;
}
-
+
return status;
}
int i;
char str[UI_MAX_DRAW_STR];
const bool is_local_center = transdata_check_local_center(t, t->around);
-
+
copy_m3_m4(persmat, t->viewmat);
invert_m3_m3(persinv, persmat);
-
+
value = t->values[0];
-
+
snapGridIncrement(t, &value);
-
+
applyNumInput(&t->num, &value);
-
+
t->values[0] = value;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
-
+
outputNumInput(&(t->num), c, &t->scene->unit);
-
+
BLI_snprintf(str, sizeof(str), IFACE_("Shear: %s %s"), c, t->proptext);
}
else {
/* default header print */
BLI_snprintf(str, sizeof(str), IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
}
-
+
unit_m3(smat);
-
+
// Custom data signals shear direction
if (t->custom.mode.data == NULL)
smat[1][0] = value;
else
smat[0][1] = value;
-
+
mul_m3_m3m3(tmat, smat, persmat);
mul_m3_m3m3(totmat, persinv, tmat);
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (t->obedit) {
float mat3[3][3];
mul_m3_m3m3(mat3, totmat, td->mtx);
}
sub_v3_v3v3(vec, co, center);
-
+
mul_m3_v3(tmat, vec);
-
+
add_v3_v3(vec, center);
sub_v3_v3(vec, co);
-
+
mul_v3_fl(vec, td->factor);
-
+
add_v3_v3v3(td->loc, td->iloc, vec);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
{
t->mode = TFM_RESIZE;
t->transform = applyResize;
-
+
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
-
+
t->flag |= T_NULL_ONE;
t->num.val_flag[0] |= NUM_NULL_ONE;
t->num.val_flag[1] |= NUM_NULL_ONE;
t->num.val_flag[2] |= NUM_NO_ZERO;
#endif
}
-
+
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
{
float tmat[3][3], smat[3][3], center[3];
float vec[3];
-
+
if (t->flag & T_EDIT) {
mul_m3_m3m3(smat, mat, td->mtx);
mul_m3_m3m3(tmat, td->smtx, smat);
else {
copy_m3_m3(tmat, mat);
}
-
+
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
-
+
/* local constraint shouldn't alter center */
if (transdata_check_local_center(t, t->around)) {
copy_v3_v3(center, td->center);
if (td->ext) {
float fsize[3];
-
+
if (t->flag & (T_OBJECT | T_TEXTURE | T_POSE)) {
float obsizemat[3][3];
/* Reorient the size mat to fit the oriented object. */
else {
mat3_to_size(fsize, tmat);
}
-
+
protectedSizeBits(td->protectflag, fsize);
-
+
if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't resize objects itself */
if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
*td->val = td->ival * (1 + (fsize[0] - 1) * td->factor);
-
+
td->ext->size[0] = td->ext->isize[0];
td->ext->size[1] = td->ext->isize[1];
td->ext->size[2] = td->ext->isize[2];
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
*td->val = td->ival;
-
+
td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
td->ext->size[2] = td->ext->isize[2] * (1 + (fsize[2] - 1) * td->factor);
}
}
-
+
constraintSizeLim(t, td);
}
sub_v3_v3v3(vec, td->iloc, center);
else
sub_v3_v3v3(vec, td->center, center);
-
+
mul_m3_v3(tmat, vec);
-
+
add_v3_v3(vec, center);
if (t->flag & T_POINTS)
sub_v3_v3(vec, td->iloc);
else
sub_v3_v3(vec, td->center);
-
+
mul_v3_fl(vec, td->factor);
-
+
if (t->flag & (T_OBJECT | T_POSE)) {
mul_m3_v3(td->smtx, vec);
}
-
+
protectedTransBits(td->protectflag, vec);
if (td->loc) {
add_v3_v3v3(td->loc, td->iloc, vec);
}
-
+
constraintTransLim(t, td);
}
applySnapping(t, t->values);
}
-
+
size_to_mat3(mat, t->values);
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
+
copy_m3_m3(t->mat, mat); // used in manipulator
-
+
headerResize(t, t->values, str);
-
+
for (i = 0, td = t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
ElementResize(t, td, mat);
}
-
+
/* evil hack - redo resize if cliping needed */
if (t->flag & T_CLIP_UV && clipUVTransform(t, t->values, 1)) {
size_to_mat3(mat, t->values);
-
+
if (t->con.applySize)
t->con.applySize(t, NULL, mat);
-
+
for (i = 0, td = t->data; i < t->total; i++, td++)
ElementResize(t, td, mat);
clipUVData(t);
}
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
{
t->mode = TFM_SKIN_RESIZE;
t->transform = applySkinResize;
-
+
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
-
+
t->flag |= T_NULL_ONE;
t->num.val_flag[0] |= NUM_NULL_ONE;
t->num.val_flag[1] |= NUM_NULL_ONE;
t->num.val_flag[2] |= NUM_NO_ZERO;
#endif
}
-
+
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
float size[3], mat[3][3];
int i;
char str[UI_MAX_DRAW_STR];
-
+
copy_v3_fl(size, t->values[0]);
-
+
snapGridIncrement(t, size);
-
+
if (applyNumInput(&t->num, size)) {
constraintNumInput(t, size);
}
-
+
applySnapping(t, size);
-
+
if (t->flag & T_AUTOVALUES) {
copy_v3_v3(size, t->auto_values);
}
-
+
copy_v3_v3(t->values, size);
-
+
size_to_mat3(mat, size);
-
+
headerResize(t, size, str);
-
+
for (i = 0, td = t->data; i < t->total; i++, td++) {
float tmat[3][3], smat[3][3];
float fsize[3];
-
+
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
else {
copy_m3_m3(tmat, mat);
}
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, tmat);
}
td->val[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
td->val[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
{
TransData *td = t->data;
int i;
-
+
t->mode = TFM_TOSPHERE;
t->transform = applyToSphere;
-
+
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
+
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
t->num.val_flag[0] |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
-
+
// Calculate average radius
for (i = 0; i < t->total; i++, td++) {
t->val += len_v3v3(t->center, td->iloc);
}
-
+
t->val /= (float)t->total;
}
int i;
char str[UI_MAX_DRAW_STR];
TransData *td = t->data;
-
+
ratio = t->values[0];
-
+
snapGridIncrement(t, &ratio);
-
+
applyNumInput(&t->num, &ratio);
-
+
CLAMP(ratio, 0.0f, 1.0f);
-
+
t->values[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
-
+
outputNumInput(&(t->num), c, &t->scene->unit);
-
+
BLI_snprintf(str, sizeof(str), IFACE_("To Sphere: %s %s"), c, t->proptext);
}
else {
/* default header print */
BLI_snprintf(str, sizeof(str), IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
}
-
-
+
+
for (i = 0; i < t->total; i++, td++) {
float tratio;
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
sub_v3_v3v3(vec, td->iloc, t->center);
-
+
radius = normalize_v3(vec);
-
+
tratio = ratio * td->factor;
-
+
mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
-
+
add_v3_v3v3(td->loc, t->center, vec);
}
-
-
+
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
{
t->mode = TFM_ROTATION;
t->transform = applyRotation;
-
+
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = DEG2RAD(5.0);
t->snap[2] = DEG2RAD(1.0);
-
+
copy_v3_fl(t->num.val_inc, t->snap[2]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS);
if (t->flag & T_POINTS) {
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
-
+
sub_v3_v3v3(vec, td->iloc, center);
mul_m3_v3(smat, vec);
-
+
add_v3_v3v3(td->loc, vec, center);
-
+
sub_v3_v3v3(vec, td->loc, td->iloc);
protectedTransBits(td->protectflag, vec);
add_v3_v3v3(td->loc, td->iloc, vec);
-
-
+
+
if (td->flag & TD_USEQUAT) {
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);
-
+
/* is there a reason not to have this here? -jahka */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
*/
else if (t->flag & T_POSE) {
float pmtx[3][3], imtx[3][3];
-
+
// Extract and invert armature object matrix
copy_m3_m4(pmtx, t->poseobj->obmat);
invert_m3_m3(imtx, pmtx);
-
+
if ((td->flag & TD_NO_LOC) == 0) {
sub_v3_v3v3(vec, td->center, center);
-
+
mul_m3_v3(pmtx, vec); // To Global space
mul_m3_v3(mat, vec); // Applying rotation
mul_m3_v3(imtx, vec); // To Local space
-
+
add_v3_v3(vec, center);
/* vec now is the location where the object has to be */
-
+
sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location
-
+
/* special exception, see TD_PBONE_LOCAL_MTX definition comments */
if (td->flag & TD_PBONE_LOCAL_MTX_P) {
/* do nothing */
}
protectedTransBits(td->protectflag, vec);
-
+
add_v3_v3v3(td->loc, td->iloc, vec);
-
+
constraintTransLim(t, td);
}
-
+
/* rotation */
/* 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),
/* 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);
-
+
mat3_to_quat(quat, fmat); /* Actual transform */
-
+
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);
-
+
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
float iquat[4], tquat[4];
-
+
axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
-
+
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);
-
+
/* this function works on end result */
protectedAxisAngleBits(td->protectflag, 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);
-
+
/* calculate the total rotatation in eulers */
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);
-
+
/* and apply (to end result only) */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
copy_v3_v3(td->ext->rot, eul);
}
-
+
constraintRotLim(t, td);
}
}
/* vec now is the location where the object has to be */
sub_v3_v3(vec, td->center);
mul_m3_v3(td->smtx, vec);
-
+
protectedTransBits(td->protectflag, vec);
-
+
add_v3_v3v3(td->loc, td->iloc, vec);
}
-
-
+
+
constraintTransLim(t, td);
-
+
/* rotation */
if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't rotate objects itself
/* euler or quaternion? */
if (td->ext->quat) {
mul_m3_series(fmat, td->smtx, mat, td->mtx);
mat3_to_quat(quat, fmat); // Actual transform
-
+
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);
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
float iquat[4], tquat[4];
-
+
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);
-
+
/* this function works on end result */
protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
td->ext->irotAngle);
}
else {
float obmat[3][3];
-
+
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
-
+
/* calculate the total rotatation in eulers */
add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
/* mat = transform, obmat = object rotation */
mul_m3_m3m3(fmat, smat, obmat);
-
+
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
-
+
/* correct back for delta rot */
sub_v3_v3v3(eul, eul, td->ext->drot);
-
+
/* and apply */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
copy_v3_v3(td->ext->rot, eul);
}
-
+
constraintRotLim(t, td);
}
}
TransData *td = t->data;
float mat[3][3];
int i;
-
+
axis_angle_normalized_to_mat3(mat, axis, angle);
-
+
for (i = 0; i < t->total; i++, td++) {
-
+
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (t->con.applyRot) {
t->con.applyRot(t, td, axis, NULL);
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
else if (t->flag & T_PROP_EDIT) {
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
}
-
+
ElementRotation(t, td, mat, t->around);
}
}
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
-
+
outputNumInput(&(t->num), c, &t->scene->unit);
-
+
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
}
else {
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Rot: %.2f%s %s"),
RAD2DEGF(final), t->con.text, t->proptext);
}
-
+
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
applyRotationValue(t, final, t->axis);
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
{
if (t->spacetype == SPACE_ACTION) {
/* this space uses time translate */
- BKE_report(t->reports, RPT_ERROR,
+ BKE_report(t->reports, RPT_ERROR,
"Use 'Time_Translate' transform mode instead of 'Translation' mode "
"for translating keyframes in Dope Sheet Editor");
t->state = TRANS_CANCEL;
for (int i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
if (use_rotate_offset) {
add_v3_v3(tvec, rotate_offset);
}
-
+
mul_m3_v3(td->smtx, tvec);
mul_v3_fl(tvec, td->factor);
-
+
protectedTransBits(td->protectflag, tvec);
-
+
if (td->loc)
add_v3_v3v3(td->loc, td->iloc, tvec);
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
-
+
// TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
/* for manipulator, center handle, the scaling can't be done relative to center */
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
else {
ratio = t->values[0];
}
-
+
copy_v3_fl(size, ratio);
-
+
snapGridIncrement(t, size);
-
+
if (applyNumInput(&t->num, size)) {
constraintNumInput(t, size);
}
-
+
copy_v3_v3(t->values, size);
size_to_mat3(mat, size);
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
+
copy_m3_m3(t->mat, mat); // used in manipulator
-
+
headerBoneSize(t, size, str);
-
+
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
ElementBoneSize(t, td, mat);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
{
t->mode = TFM_BONE_ENVELOPE;
t->transform = applyBoneEnvelope;
-
+
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
+
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
-
+
ratio = t->values[0];
-
+
snapGridIncrement(t, &ratio);
-
+
applyNumInput(&t->num, &ratio);
-
+
t->values[0] = ratio;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
-
+
outputNumInput(&(t->num), c, &t->scene->unit);
BLI_snprintf(str, sizeof(str), IFACE_("Envelope: %s"), c);
}
else {
BLI_snprintf(str, sizeof(str), IFACE_("Envelope: %3f"), ratio);
}
-
+
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (td->val) {
/* if the old/original value was 0.0f, then just use ratio */
if (td->ival)
*td->val = ratio;
}
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
}
/** \} */
l_first = l;
do {
l = BM_loop_other_edge_loop(l, v);
-
+
if (l->e == e_next) {
if (i) {
normalize_v3_length(vec_accum, vec_accum_len / (float)i);
if (i) {
normalize_v3_length(vec_accum, vec_accum_len / (float)i);
}
-
+
copy_v3_v3(r_slide_vec, vec_accum);
-
+
return NULL;
}
if (!v->e)
continue;
-
+
v_first = v;
/*walk along the edge loop*/
}
sld->em = em;
-
+
sld->perc = 0.0f;
-
+
t->custom.mode.data = sld;
-
+
MEM_freeN(sv_table);
return true;
void freeEdgeSlideVerts(TransInfo *UNUSED(t), TransCustomData *custom_data)
{
EdgeSlideData *sld = custom_data->data;
-
+
if (!sld)
return;
freeEdgeSlideTempFaces(sld);
bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
-
+
MEM_freeN(sld->sv);
MEM_freeN(sld);
-
+
custom_data->data = NULL;
}
t->state = TRANS_CANCEL;
return;
}
-
+
sld = t->custom.mode.data;
if (!sld)
/* set custom point first if you want value to be initialized by init */
calcEdgeSlideCustomPoints(t);
initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
static short getAnimEdit_SnapMode(TransInfo *t)
{
short autosnap = SACTSNAP_OFF;
-
+
if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
-
+
if (saction)
autosnap = saction->autosnap;
}
else if (t->spacetype == SPACE_IPO) {
SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first;
-
+
if (sipo)
autosnap = sipo->autosnap;
}
else if (t->spacetype == SPACE_NLA) {
SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
-
+
if (snla)
autosnap = snla->autosnap;
}
else {
autosnap = SACTSNAP_OFF;
}
-
- /* toggle autosnap on/off
+
+ /* toggle autosnap on/off
* - when toggling on, prefer nearest frame over 1.0 frame increments
*/
if (t->modifiers & MOD_SNAP_INVERT) {
const Scene *scene = t->scene;
const double secf = FPS;
double val;
-
+
/* convert frame to nla-action time (if needed) */
if (adt)
val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
else
val = *(td->val);
-
+
/* do the snapping to nearest frame/second */
if (autosnap == SACTSNAP_FRAME) {
val = floorf(val + 0.5);
else if (autosnap == SACTSNAP_SECOND) {
val = (float)(floor((val / secf) + 0.5) * secf);
}
-
+
/* convert frame out of nla-action time */
if (adt)
*(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
/* snap key to nearest marker? */
else if (autosnap == SACTSNAP_MARKER) {
float val;
-
+
/* convert frame to nla-action time (if needed) */
if (adt)
val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
else
val = *(td->val);
-
+
/* snap to nearest marker */
// TODO: need some more careful checks for where data comes from
val = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val);
-
+
/* convert frame out of nla-action time */
if (adt)
*(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
else
*(td->val) = val;
}
-
- /* if the handles are to be moved too (as side-effect of keyframes moving, to keep the general effect)
- * offset them by the same amount so that the general angles are maintained (i.e. won't change while
+
+ /* if the handles are to be moved too (as side-effect of keyframes moving, to keep the general effect)
+ * offset them by the same amount so that the general angles are maintained (i.e. won't change while
* handles are free-to-roam and keyframes are snap-locked)
*/
if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
const short autosnap = getAnimEdit_SnapMode(t);
const double secf = FPS;
float val = t->values[0];
-
+
/* apply snapping + frame->seconds conversions */
if (autosnap == SACTSNAP_STEP) {
/* frame step */
/* nearest second */
val = (float)((double)val / secf);
}
-
+
if (autosnap == SACTSNAP_FRAME)
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 (%.4f)", (int)val, val);
else if (autosnap == SACTSNAP_SECOND)
TransData2D *td2d = t->data2d;
Scene *scene = t->scene;
int i;
-
+
const short autosnap = getAnimEdit_SnapMode(t);
const double secf = FPS;
for (i = 0; i < t->total; i++, td++) {
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
float val = *(td->val);
-
+
/* strip/action time to global (mapped) time */
if (adt)
val = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_MAP);
-
+
if (min > val) min = val;
if (max < val) max = val;
}
*/
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
float cval = t->values[0];
-
+
/* only apply to data if in range */
if ((sval > minx) && (sval < maxx)) {
float cvalc = CLAMPIS(cval, minx, maxx);
float ival = td->ival;
float timefac;
-
+
/* NLA mapping magic here works as follows:
* - "ival" goes from strip time to global time
* - calculation is performed into td->val in global time
/* strip to global */
ival = BKE_nla_tweakedit_remap(adt, ival, NLATIME_CONVERT_MAP);
}
-
+
/* left half? */
if (ival < sval) {
timefac = (sval - ival) / (sval - minx);
timefac = (ival - sval) / (maxx - sval);
*(td->val) = cvalc + timefac * (maxx - cvalc);
}
-
+
if (adt) {
/* global to strip */
*(td->val) = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_UNMAP);
static void applyTimeScale(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
-
+
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);