#include "ED_markers.h"
#include "ED_util.h"
#include "ED_view3d.h"
+#include "ED_mesh.h"
#include "UI_view2d.h"
#include "WM_types.h"
#include "WM_api.h"
-#include "BLI_arithb.h"
+#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
+#include "BLI_ghash.h"
+#include "BLI_linklist.h"
#include "PIL_time.h" /* sleep */
if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = t->ar->regiondata;
- Mat4CpyMat4(t->viewmat, rv3d->viewmat);
- Mat4CpyMat4(t->viewinv, rv3d->viewinv);
- Mat4CpyMat4(t->persmat, rv3d->persmat);
- Mat4CpyMat4(t->persinv, rv3d->persinv);
+ copy_m4_m4(t->viewmat, rv3d->viewmat);
+ copy_m4_m4(t->viewinv, rv3d->viewinv);
+ copy_m4_m4(t->persmat, rv3d->persmat);
+ copy_m4_m4(t->persinv, rv3d->persinv);
t->persp = rv3d->persp;
}
else {
- Mat4One(t->viewmat);
- Mat4One(t->viewinv);
- Mat4One(t->persmat);
- Mat4One(t->persinv);
- t->persp = V3D_ORTHO;
+ unit_m4(t->viewmat);
+ unit_m4(t->viewinv);
+ unit_m4(t->persmat);
+ unit_m4(t->persinv);
+ t->persp = RV3D_ORTHO;
}
calculateCenter2D(t);
else if(t->spacetype == SPACE_NODE)
{
//ED_area_tag_redraw(t->sa);
- WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE_VIEW, NULL);
}
else if(t->spacetype == SPACE_SEQ)
{
}
else if (t->spacetype==SPACE_IMAGE) {
// XXX how to deal with lock?
-#if 0
SpaceImage *sima= (SpaceImage*)t->sa->spacedata.first;
- if(sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
- else force_draw(0);
-#endif
-
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data);
+ if(sima->lock) WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data);
+ else ED_area_tag_redraw(t->sa);
}
}
#define TFM_MODAL_RESIZE 5
#define TFM_MODAL_SNAP_GEARS 6
#define TFM_MODAL_SNAP_GEARS_OFF 7
+#define TFM_MODAL_SNAP_GEARS_TOGGLE 8
/* called in transform_ops.c, on each regeneration of keymaps */
-void transform_modal_keymap(wmWindowManager *wm)
+void transform_modal_keymap(wmKeyConfig *keyconf)
{
static EnumPropertyItem modal_items[] = {
{TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
{TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
{TFM_MODAL_SNAP_GEARS, "SNAP_GEARS", 0, "Snap On", ""},
{TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""},
+ {TFM_MODAL_SNAP_GEARS_TOGGLE, "SNAP_GEARS_TOGGLE", 0, "Snap Toggle", ""},
{0, NULL, 0, NULL, NULL}};
- wmKeyMap *keymap= WM_modalkeymap_get(wm, "Transform Modal Map");
+ wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map");
/* this function is called for each spacetype, only needs to add map once */
if(keymap) return;
- keymap= WM_modalkeymap_add(wm, "Transform Modal Map", modal_items);
+ 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_ANY, KM_ANY, 0, TFM_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
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, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_GEARS);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, TFM_MODAL_SNAP_GEARS_OFF);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_GEARS_TOGGLE);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "TFM_OT_transform");
WM_modalkeymap_assign(keymap, "TFM_OT_shrink_fatten");
WM_modalkeymap_assign(keymap, "TFM_OT_tilt");
WM_modalkeymap_assign(keymap, "TFM_OT_trackball");
-
+ WM_modalkeymap_assign(keymap, "TFM_OT_mirror");
+ WM_modalkeymap_assign(keymap, "TFM_OT_edge_slide");
}
t->redraw = 1;
+ if (t->state == TRANS_STARTING) {
+ t->state = TRANS_RUNNING;
+ }
+
applyMouseInput(t, &t->mouse, t->mval, t->values);
}
case TFM_MODAL_CONFIRM:
t->state = TRANS_CONFIRM;
break;
-
case TFM_MODAL_TRANSLATE:
/* only switch when... */
if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
t->modifiers &= ~MOD_SNAP_GEARS;
t->redraw = 1;
break;
+ case TFM_MODAL_SNAP_GEARS_TOGGLE:
+ t->modifiers ^= MOD_SNAP_GEARS;
+ t->redraw = 1;
+ break;
}
}
/* else do non-mapped events */
t->state = TRANS_CANCEL;
break;
/* enforce redraw of transform when modifiers are used */
- case LEFTCTRLKEY:
- case RIGHTCTRLKEY:
- t->modifiers |= MOD_SNAP_GEARS;
- t->redraw = 1;
- break;
-
case LEFTSHIFTKEY:
case RIGHTSHIFTKEY:
t->modifiers |= MOD_CONSTRAINT_PLANE;
getmouseco_sc(mval);
BIF_selectOrientation();
calc_manipulator_stats(curarea);
- Mat3CpyMat4(t->spacemtx, G.vd->twmat);
+ copy_m3_m4(t->spacemtx, G.vd->twmat);
warp_pointer(mval[0], mval[1]);
#endif
}
stopConstraint(t);
}
else {
+ short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, (CON_AXIS0), "along %s X");
+ setUserConstraint(t, orientation, (CON_AXIS0), "along %s X");
else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, (CON_AXIS1|CON_AXIS2), "locking %s X");
+ setUserConstraint(t, orientation, (CON_AXIS1|CON_AXIS2), "locking %s X");
}
}
}
stopConstraint(t);
}
else {
+ short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, (CON_AXIS1), "along %s Y");
+ setUserConstraint(t, orientation, (CON_AXIS1), "along %s Y");
else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, (CON_AXIS0|CON_AXIS2), "locking %s Y");
+ setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y");
}
}
}
stopConstraint(t);
}
else {
+ short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, (CON_AXIS2), "along %s Z");
+ setUserConstraint(t, orientation, (CON_AXIS2), "along %s Z");
else if ((t->modifiers & MOD_CONSTRAINT_PLANE) && ((t->flag & T_2D_EDIT)==0))
- setUserConstraint(t, (CON_AXIS0|CON_AXIS1), "locking %s Z");
+ setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z");
}
}
else if ((t->flag & T_2D_EDIT)==0) {
//arrows_move_cursor(event->type);
}
- else {
+ else if (event->val==KM_RELEASE) {
switch (event->type){
- case LEFTMOUSE:
- t->state = TRANS_CONFIRM;
- break;
case LEFTSHIFTKEY:
case RIGHTSHIFTKEY:
t->modifiers &= ~MOD_CONSTRAINT_PLANE;
t->redraw = 1;
break;
- case LEFTCTRLKEY:
- case RIGHTCTRLKEY:
- t->modifiers &= ~MOD_SNAP_GEARS;
- /* no redraw on release modifier keys! this makes sure you can assign the 'grid' still
- after releasing modifer key */
- //t->redraw = 1;
- break;
case MIDDLEMOUSE:
if ((t->flag & T_NO_CONSTRAINT)==0) {
t->modifiers &= ~MOD_CONSTRAINT_SELECT;
// t->state = TRANS_CONFIRM;
// break;
}
+
+ /* confirm transform if launch key is released after mouse move */
+ /* XXX Keyrepeat bug in Xorg fucks this up, will test when fixed */
+ if (event->type == LEFTMOUSE /*t->launch_event*/ && t->state != TRANS_STARTING)
+ {
+ t->state = TRANS_CONFIRM;
+ }
}
// Per transform event, if present
VECCOPY(vec, t->con.center);
}
- postTrans(t);
/* aftertrans does insert ipos and action channels, and clears base flags, doesnt read transdata */
special_aftertrans_update(t);
+ postTrans(t);
+
MEM_freeN(t);
return success;
VECCOPY(vecrot, t->center);
if(t->flag & T_EDIT) {
Object *ob= t->obedit;
- if(ob) Mat4MulVecfl(ob->obmat, vecrot);
+ if(ob) mul_m4_v3(ob->obmat, vecrot);
}
else if(t->flag & T_POSE) {
Object *ob=t->poseobj;
- if(ob) Mat4MulVecfl(ob->obmat, vecrot);
+ if(ob) mul_m4_v3(ob->obmat, vecrot);
}
projectFloatView(t, vecrot, cent); // no overflow in extreme cases
- glDisable(GL_DEPTH_TEST);
-
- glMatrixMode(GL_PROJECTION);
glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
- ED_region_pixelspace(t->ar);
switch(t->helpline)
{
}
}
- glMatrixMode(GL_PROJECTION);
glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- glEnable(GL_DEPTH_TEST);
}
}
-void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg)
+void drawTransformView(const struct bContext *C, struct ARegion *ar, void *arg)
{
TransInfo *t = arg;
drawConstraint(C, t);
drawPropCircle(C, t);
drawSnapping(C, t);
+}
+
+void drawTransformPixel(const struct bContext *C, struct ARegion *ar, void *arg)
+{
+ TransInfo *t = arg;
+
drawHelpline(C, t);
}
proportional = 0;
}
+ // If modal, save settings back in scene if not set as operator argument
+ if (t->flag & T_MODAL)
+ {
+ /* save settings if not set in operator */
+ if (RNA_struct_find_property(op->ptr, "proportional") && !RNA_property_is_set(op->ptr, "proportional"))
+ {
+ ts->proportional = proportional;
+ }
+
+ if (RNA_struct_find_property(op->ptr, "proportional_size") && !RNA_property_is_set(op->ptr, "proportional_size"))
+ {
+ ts->proportional_size = t->prop_size;
+ }
+
+ if (RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && !RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
+ {
+ ts->prop_mode = t->prop_mode;
+ }
+
+ if(t->spacetype == SPACE_VIEW3D)
+ {
+ if (RNA_struct_find_property(op->ptr, "constraint_orientation") && !RNA_property_is_set(op->ptr, "constraint_orientation"))
+ {
+ View3D *v3d = t->view;
+
+ v3d->twmode = t->current_orientation;
+ }
+ }
+ }
+
if (RNA_struct_find_property(op->ptr, "proportional"))
{
RNA_enum_set(op->ptr, "proportional", proportional);
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
}
-
- // XXX If modal, save settings back in scene
- if (t->flag & T_MODAL)
- {
- ts->prop_mode = t->prop_mode;
- ts->proportional = proportional;
-
- if(t->spacetype == SPACE_VIEW3D)
- {
- View3D *v3d = t->view;
-
- v3d->twmode = t->current_orientation;
- }
- }
}
int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode)
/* added initialize, for external calls to set stuff in TransInfo, like undo string */
- t->state = TRANS_RUNNING;
+ t->state = TRANS_STARTING;
t->options = options;
t->mode = mode;
+ t->launch_event = event ? event->type : -1;
+
if (!initTransInfo(C, t, op, event)) // internal data, mouse, vectors
{
return 0;
//calc_manipulator_stats(curarea);
initTransformOrientation(C, t);
- t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
}
else if(t->spacetype == SPACE_IMAGE) {
- Mat3One(t->spacemtx);
- t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
+ unit_m3(t->spacemtx);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
}
else
- Mat3One(t->spacemtx);
+ unit_m3(t->spacemtx);
createTransData(C, t); // make TransData structs from selection
case TFM_BONE_ENVELOPE:
initBoneEnvelope(t);
break;
+ case TFM_EDGE_SLIDE:
+ initEdgeSlide(t);
+ break;
case TFM_BONE_ROLL:
initBoneRoll(t);
break;
t->con.mode |= CON_AXIS2;
}
- setUserConstraint(t, t->con.mode, "%s");
+ setUserConstraint(t, t->current_orientation, t->con.mode, "%s");
}
}
{
int exit_code = OPERATOR_RUNNING_MODAL;
- if (t->state != TRANS_RUNNING)
+ if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING)
{
/* handle restoring objects */
if(t->state == TRANS_CANCEL)
exit_code = OPERATOR_FINISHED;
}
- /* free data */
- postTrans(t);
-
/* aftertrans does insert keyframes, and clears base flags, doesnt read transdata */
special_aftertrans_update(t);
+ /* free data */
+ postTrans(t);
+
/* send events out for redraws */
viewRedrawPost(t);
eul[2]= oldeul[2];
}
-static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
+
+/* this function only does the delta rotation */
+/* axis-angle is usually internally stored as quats... */
+static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
{
- /* quaternions get limited with euler... */
- /* this function only does the delta rotation */
+ /* 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)
+ *angle= oldAngle;
+ if (protectflag & OB_LOCK_ROTX)
+ axis[0]= oldAxis[0];
+ if (protectflag & OB_LOCK_ROTY)
+ axis[1]= oldAxis[1];
+ if (protectflag & OB_LOCK_ROTZ)
+ axis[2]= oldAxis[2];
+ }
+ 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_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) {
+ /* for now, rotate around y-axis then (so that it simply becomes the roll) */
+ axis[1]= 1.0f;
+ }
+ }
+}
- if(protectflag) {
+/* this function only does the delta rotation */
+static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
+{
+ /* 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)
+ quat[0]= oldquat[0];
+ if (protectflag & OB_LOCK_ROTX)
+ quat[1]= oldquat[1];
+ if (protectflag & OB_LOCK_ROTY)
+ quat[2]= oldquat[2];
+ if (protectflag & OB_LOCK_ROTZ)
+ quat[3]= oldquat[3];
+ }
+ else {
+ /* quaternions get limited with euler... (compatability mode) */
float eul[3], oldeul[3], quat1[4];
-
+
QUATCOPY(quat1, quat);
- QuatToEul(quat, eul);
- QuatToEul(oldquat, oldeul);
-
- if(protectflag & OB_LOCK_ROTX)
+ quat_to_eul( eul,quat);
+ quat_to_eul( oldeul,oldquat);
+
+ if (protectflag & OB_LOCK_ROTX)
eul[0]= oldeul[0];
- if(protectflag & OB_LOCK_ROTY)
+ if (protectflag & OB_LOCK_ROTY)
eul[1]= oldeul[1];
- if(protectflag & OB_LOCK_ROTZ)
+ if (protectflag & OB_LOCK_ROTZ)
eul[2]= oldeul[2];
-
- EulToQuat(eul, quat);
+
+ eul_to_quat( quat,eul);
+
/* quaternions flip w sign to accumulate rotations correctly */
- if( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
- QuatMulf(quat, -1.0f);
+ if ( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
+ mul_qt_fl(quat, -1.0f);
}
}
}
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
bConstraintOb cob;
bConstraint *con;
-
+
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
- Mat4One(cob.matrix);
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- cob.matrix[3][0]= tdi->locx[0];
- cob.matrix[3][1]= tdi->locy[0];
- cob.matrix[3][2]= tdi->locz[0];
- }
- else {
- VECCOPY(cob.matrix[3], td->loc);
- }
-
+ unit_m4(cob.matrix);
+ VECCOPY(cob.matrix[3], td->loc);
+
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
float tmat[4][4];
-
+
/* only consider constraint if enabled */
if (con->flag & CONSTRAINT_DISABLE) 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;
-
+
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
- Mat4CpyMat4(tmat, cob.matrix);
- Mat4MulMat34(cob.matrix, td->mtx, tmat);
+ copy_m4_m4(tmat, cob.matrix);
+ mul_m4_m3m4(cob.matrix, td->mtx, tmat);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
- Mat4CpyMat4(tmat, cob.matrix);
- Mat4MulMat34(cob.matrix, td->smtx, tmat);
+ copy_m4_m4(tmat, cob.matrix);
+ mul_m4_m3m4(cob.matrix, td->smtx, tmat);
}
}
}
-
+
/* copy results from cob->matrix */
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- tdi->locx[0]= cob.matrix[3][0];
- tdi->locy[0]= cob.matrix[3][1];
- tdi->locz[0]= cob.matrix[3][2];
- }
- else {
- VECCOPY(td->loc, cob.matrix[3]);
- }
+ VECCOPY(td->loc, cob.matrix[3]);
}
}
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */
if (td->ext)
- QuatToMat4(td->ext->quat, cob.matrix);
+ quat_to_mat4( cob.matrix,td->ext->quat);
else
return;
}
- else if (td->tdi) {
- /* ipo-keys eulers */
- TransDataIpokey *tdi= td->tdi;
- float eul[3];
-
- eul[0]= tdi->rotx[0];
- eul[1]= tdi->roty[0];
- eul[2]= tdi->rotz[0];
-
- EulOToMat4(eul, td->rotOrder, cob.matrix);
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+ /* axis angle */
+ if (td->ext)
+ axis_angle_to_mat4( cob.matrix,&td->ext->quat[1], td->ext->quat[0]);
+ else
+ return;
}
else {
/* eulers */
if (td->ext)
- EulOToMat4(td->ext->rot, td->rotOrder, cob.matrix);
+ eulO_to_mat4( cob.matrix,td->ext->rot, td->rotOrder);
else
return;
}
-
+
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
/* only consider constraint if enabled */
if (con->flag & CONSTRAINT_DISABLE) continue;
if (con->enforce == 0.0f) continue;
-
+
/* we're only interested in Limit-Rotation constraints */
if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
bRotLimitConstraint *data= con->data;
float tmat[4][4];
-
+
/* 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) */
- Mat4CpyMat4(tmat, cob.matrix);
- Mat4MulMat34(cob.matrix, td->mtx, tmat);
+ copy_m4_m4(tmat, cob.matrix);
+ mul_m4_m3m4(cob.matrix, td->mtx, tmat);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
- Mat4CpyMat4(tmat, cob.matrix);
- Mat4MulMat34(cob.matrix, td->smtx, tmat);
+ copy_m4_m4(tmat, cob.matrix);
+ mul_m4_m3m4(cob.matrix, td->smtx, tmat);
}
}
}
-
+
/* copy results from cob->matrix */
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */
- Mat4ToQuat(cob.matrix, td->ext->quat);
+ mat4_to_quat( td->ext->quat,cob.matrix);
}
- else if (td->tdi) {
- /* ipo-keys eulers */
- TransDataIpokey *tdi= td->tdi;
- float eul[3];
-
- Mat4ToEulO(cob.matrix, eul, td->rotOrder);
-
- tdi->rotx[0]= eul[0];
- tdi->roty[0]= eul[1];
- tdi->rotz[0]= eul[2];
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+ /* axis angle */
+ mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix);
}
else {
/* eulers */
- Mat4ToEulO(cob.matrix, td->ext->rot, td->rotOrder);
+ mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
}
}
}
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob;
bConstraint *con;
-
+
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- float size[3];
-
- size[0]= tdi->sizex[0];
- size[1]= tdi->sizey[0];
- size[2]= tdi->sizez[0];
- SizeToMat4(size, cob.matrix);
- }
- else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
return; // TODO: fix this case
}
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
-
- SizeToMat4(td->ext->size, cob.matrix);
+
+ size_to_mat4( cob.matrix,td->ext->size);
}
-
+
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
/* only consider constraint if enabled */
if (con->flag & CONSTRAINT_DISABLE) 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;
float tmat[4][4];
-
+
/* 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) */
- Mat4CpyMat4(tmat, cob.matrix);
- Mat4MulMat34(cob.matrix, td->mtx, tmat);
+ copy_m4_m4(tmat, cob.matrix);
+ mul_m4_m3m4(cob.matrix, td->mtx, tmat);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
- Mat4CpyMat4(tmat, cob.matrix);
- Mat4MulMat34(cob.matrix, td->smtx, tmat);
+ copy_m4_m4(tmat, cob.matrix);
+ mul_m4_m3m4(cob.matrix, td->smtx, tmat);
}
}
}
-
+
/* copy results from cob->matrix */
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- float size[3];
-
- Mat4ToSize(cob.matrix, size);
-
- tdi->sizex[0]= size[0];
- tdi->sizey[0]= size[1];
- tdi->sizez[0]= size[2];
- }
- else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
return; // TODO: fix this case
}
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
-
- Mat4ToSize(cob.matrix, td->ext->size);
+
+ mat4_to_size( td->ext->size,cob.matrix);
}
}
}
{
float max[3], min[3];
int i;
-
+
t->mode = TFM_WARP;
t->transform = Warp;
t->handleEvent = handleEventWarp;
-
+
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 5.0f;
t->snap[2] = 1.0f;
-
+
t->flag |= T_NO_CONSTRAINT;
-
+
/* we need min/max in view space */
for(i = 0; i < t->total; i++) {
float center[3];
VECCOPY(center, t->data[i].center);
- Mat3MulVecfl(t->data[i].mtx, center);
- Mat4MulVecfl(t->viewmat, center);
- VecSubf(center, center, t->viewmat[3]);
+ mul_m3_v3(t->data[i].mtx, center);
+ mul_m4_v3(t->viewmat, center);
+ sub_v3_v3v3(center, center, t->viewmat[3]);
if (i)
- MinMax3(min, max, center);
+ minmax_v3_v3v3(min, max, center);
else {
VECCOPY(max, center);
VECCOPY(min, center);
}
}
-
+
t->center[0]= (min[0]+max[0])/2.0f;
t->center[1]= (min[1]+max[1])/2.0f;
t->center[2]= (min[2]+max[2])/2.0f;
int handleEventWarp(TransInfo *t, wmEvent *event)
{
int status = 0;
-
+
if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
{
// Use customData pointer to signal warp direction
t->customData = (void*)1;
else
t->customData = 0;
-
+
status = 1;
}
-
+
return status;
}
float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3];
int i;
char str[50];
-
+
curs= give_cursor(t->scene, t->view);
/*
* gcursor is the one used for helpline.
VECCOPY(cursor, curs);
VECCOPY(gcursor, cursor);
if (t->flag & T_EDIT) {
- VecSubf(cursor, cursor, t->obedit->obmat[3]);
- VecSubf(gcursor, gcursor, t->obedit->obmat[3]);
- Mat3MulVecfl(t->data->smtx, gcursor);
+ sub_v3_v3v3(cursor, cursor, t->obedit->obmat[3]);
+ sub_v3_v3v3(gcursor, gcursor, t->obedit->obmat[3]);
+ mul_m3_v3(t->data->smtx, gcursor);
}
- Mat4MulVecfl(t->viewmat, cursor);
- VecSubf(cursor, cursor, t->viewmat[3]);
-
+ mul_m4_v3(t->viewmat, cursor);
+ sub_v3_v3v3(cursor, cursor, t->viewmat[3]);
+
/* amount of degrees for warp */
circumfac = 360.0f * t->values[0];
-
+
if (t->customData) /* non-null value indicates reversed input */
{
circumfac *= -1;
}
-
+
snapGrid(t, &circumfac);
applyNumInput(&t->num, &circumfac);
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "Warp: %s", c);
}
else {
/* default header print */
sprintf(str, "Warp: %.3f", circumfac);
}
-
+
circumfac*= (float)(-M_PI/360.0);
-
+
for(i = 0; i < t->total; i++, td++) {
float loc[3];
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
/* translate point to center, rotate in such a way that outline==distance */
VECCOPY(vec, td->iloc);
- Mat3MulVecfl(td->mtx, vec);
- Mat4MulVecfl(t->viewmat, vec);
- VecSubf(vec, vec, t->viewmat[3]);
-
+ mul_m3_v3(td->mtx, vec);
+ mul_m4_v3(t->viewmat, vec);
+ sub_v3_v3v3(vec, vec, t->viewmat[3]);
+
dist= vec[0]-cursor[0];
-
+
/* t->val is X dimension projected boundbox */
phi0= (circumfac*dist/t->val);
-
+
vec[1]= (vec[1]-cursor[1]);
-
+
co= (float)cos(phi0);
si= (float)sin(phi0);
loc[0]= -si*vec[1]+cursor[0];
loc[1]= co*vec[1]+cursor[1];
loc[2]= vec[2];
-
- Mat4MulVecfl(t->viewinv, loc);
- VecSubf(loc, loc, t->viewinv[3]);
- Mat3MulVecfl(td->smtx, loc);
-
- VecSubf(loc, loc, td->iloc);
- VecMulf(loc, td->factor);
- VecAddf(td->loc, td->iloc, loc);
+
+ mul_m4_v3(t->viewinv, loc);
+ sub_v3_v3v3(loc, loc, t->viewinv[3]);
+ mul_m3_v3(td->smtx, loc);
+
+ sub_v3_v3v3(loc, loc, td->iloc);
+ mul_v3_fl(loc, td->factor);
+ add_v3_v3v3(td->loc, td->iloc, loc);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
t->mode = TFM_SHEAR;
t->transform = Shear;
t->handleEvent = handleEventShear;
-
+
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
-
+
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;
-
+
t->flag |= T_NO_CONSTRAINT;
}
int handleEventShear(TransInfo *t, wmEvent *event)
{
int status = 0;
-
+
if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
{
// Use customData pointer to signal Shear direction
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
t->customData = 0;
}
-
+
status = 1;
}
-
+
return status;
}
float value;
int i;
char str[50];
-
- Mat3CpyMat4(persmat, t->viewmat);
- Mat3Inv(persinv, persmat);
-
+
+ copy_m3_m4(persmat, t->viewmat);
+ invert_m3_m3(persinv, persmat);
+
value = 0.05f * t->values[0];
-
+
snapGrid(t, &value);
-
+
applyNumInput(&t->num, &value);
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "Shear: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "Shear: %.3f %s", value, t->proptext);
}
-
- Mat3One(smat);
-
+
+ unit_m3(smat);
+
// Custom data signals shear direction
if (t->customData == 0)
smat[1][0] = value;
else
smat[0][1] = value;
-
- Mat3MulMat3(tmat, smat, persmat);
- Mat3MulMat3(totmat, persinv, tmat);
-
+
+ mul_m3_m3m3(tmat, smat, persmat);
+ mul_m3_m3m3(totmat, persinv, tmat);
+
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (t->obedit) {
float mat3[3][3];
- Mat3MulMat3(mat3, totmat, td->mtx);
- Mat3MulMat3(tmat, td->smtx, mat3);
+ mul_m3_m3m3(mat3, totmat, td->mtx);
+ mul_m3_m3m3(tmat, td->smtx, mat3);
}
else {
- Mat3CpyMat3(tmat, totmat);
+ copy_m3_m3(tmat, totmat);
}
- VecSubf(vec, td->center, t->center);
-
- Mat3MulVecfl(tmat, vec);
-
- VecAddf(vec, vec, t->center);
- VecSubf(vec, vec, td->center);
-
- VecMulf(vec, td->factor);
-
- VecAddf(td->loc, td->iloc, vec);
+ sub_v3_v3v3(vec, td->center, t->center);
+
+ mul_m3_v3(tmat, vec);
+
+ add_v3_v3v3(vec, vec, t->center);
+ sub_v3_v3v3(vec, vec, td->center);
+
+ mul_v3_fl(vec, td->factor);
+
+ add_v3_v3v3(td->loc, td->iloc, vec);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
return 1;
{
t->mode = TFM_RESIZE;
t->transform = Resize;
-
+
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
-
+
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
t->flag |= T_NO_ZERO;
t->num.flag |= NUM_NO_ZERO;
}
-
+
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
sprintf(&tvec[20], "%.4f", vec[1]);
sprintf(&tvec[40], "%.4f", vec[2]);
}
-
+
if (t->con.mode & CON_APPLY) {
switch(t->num.idx_max) {
case 0:
static void TransMat3ToSize( float mat[][3], float smat[][3], float *size)
{
float vec[3];
-
- VecCopyf(vec, mat[0]);
- size[0]= Normalize(vec);
- VecCopyf(vec, mat[1]);
- size[1]= Normalize(vec);
- VecCopyf(vec, mat[2]);
- size[2]= Normalize(vec);
-
+
+ copy_v3_v3(vec, mat[0]);
+ size[0]= normalize_v3(vec);
+ copy_v3_v3(vec, mat[1]);
+ size[1]= normalize_v3(vec);
+ copy_v3_v3(vec, mat[2]);
+ size[2]= normalize_v3(vec);
+
/* first tried with dotproduct... but the sign flip is crucial */
if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0];
if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1];
static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
float tmat[3][3], smat[3][3], center[3];
float vec[3];
-
+
if (t->flag & T_EDIT) {
- Mat3MulMat3(smat, mat, td->mtx);
- Mat3MulMat3(tmat, td->smtx, smat);
+ mul_m3_m3m3(smat, mat, td->mtx);
+ mul_m3_m3m3(tmat, td->smtx, smat);
}
else {
- Mat3CpyMat3(tmat, mat);
+ copy_m3_m3(tmat, mat);
}
-
+
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
-
+
/* local constraint shouldn't alter center */
if (t->around == V3D_LOCAL) {
if (t->flag & T_OBJECT) {
VECCOPY(center, td->center);
}
else if (t->flag & T_EDIT) {
-
+
if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
VECCOPY(center, td->center);
}
else {
VECCOPY(center, t->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.
- Mat3MulMat3(obsizemat, tmat, td->axismtx);
- //printmatrix3("obsizemat", obsizemat);
+ mul_m3_m3m3(obsizemat, tmat, td->axismtx);
+ //print_m3("obsizemat", obsizemat);
TransMat3ToSize(obsizemat, td->axismtx, fsize);
- //printvecf("fsize", fsize);
+ //print_v3("fsize", fsize);
}
else {
- Mat3ToSize(tmat, fsize);
+ mat3_to_size( fsize,tmat);
}
-
+
protectedSizeBits(td->protectflag, fsize);
-
+
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself
- /* handle ipokeys? */
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- /* calculate delta size (equal for size and dsize) */
-
- vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor;
- vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor;
- vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor;
-
- add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]);
- add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]);
- add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]);
-
- }
- else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
+ if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
/* scale val and reset size */
- *td->val = td->ival * fsize[0] * td->factor;
-
+ *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] * (fsize[0]) * td->factor;
- td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor;
- td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor;
+
+ 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);
}
-
+
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_POINTS)
- VecSubf(vec, td->iloc, center);
+ sub_v3_v3v3(vec, td->iloc, center);
else
- VecSubf(vec, td->center, center);
-
- Mat3MulVecfl(tmat, vec);
-
- VecAddf(vec, vec, center);
+ sub_v3_v3v3(vec, td->center, center);
+
+ mul_m3_v3(tmat, vec);
+
+ add_v3_v3v3(vec, vec, center);
if (t->flag & T_POINTS)
- VecSubf(vec, vec, td->iloc);
+ sub_v3_v3v3(vec, vec, td->iloc);
else
- VecSubf(vec, vec, td->center);
-
- VecMulf(vec, td->factor);
-
+ sub_v3_v3v3(vec, vec, td->center);
+
+ mul_v3_fl(vec, td->factor);
+
if (t->flag & (T_OBJECT|T_POSE)) {
- Mat3MulVecfl(td->smtx, vec);
+ mul_m3_v3(td->smtx, vec);
}
-
+
protectedTransBits(td->protectflag, vec);
-
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
- }
- else VecAddf(td->loc, td->iloc, vec);
-
+ add_v3_v3v3(td->loc, td->iloc, vec);
+
constraintTransLim(t, td);
}
float ratio;
int i;
char str[200];
-
+
/* for manipulator, center handle, the scaling can't be done relative to center */
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0)
{
{
ratio = t->values[0];
}
-
+
size[0] = size[1] = size[2] = ratio;
-
+
snapGrid(t, size);
-
+
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
-
+
applySnapping(t, size);
-
+
if (t->flag & T_AUTOVALUES)
{
VECCOPY(size, t->auto_values);
}
-
+
VECCOPY(t->values, size);
-
- SizeToMat3(size, mat);
-
+
+ size_to_mat3( mat,size);
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
- Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+
+ copy_m3_m3(t->mat, mat); // used in manipulator
+
headerResize(t, size, 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, size, 1)) {
- SizeToMat3(size, mat);
-
+ size_to_mat3( mat,size);
+
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);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
{
TransData *td = t->data;
int i;
-
+
t->mode = TFM_TOSPHERE;
t->transform = ToSphere;
-
+
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;
-
+
t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
-
+
// Calculate average radius
for(i = 0 ; i < t->total; i++, td++) {
- t->val += VecLenf(t->center, td->iloc);
+ t->val += len_v3v3(t->center, td->iloc);
}
-
+
t->val /= (float)t->total;
}
int i;
char str[64];
TransData *td = t->data;
-
+
ratio = t->values[0];
-
+
snapGrid(t, &ratio);
-
+
applyNumInput(&t->num, &ratio);
-
+
if (ratio < 0)
ratio = 0.0f;
else if (ratio > 1)
ratio = 1.0f;
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "To Sphere: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "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;
-
- VecSubf(vec, td->iloc, t->center);
-
- radius = Normalize(vec);
-
+
+ sub_v3_v3v3(vec, td->iloc, t->center);
+
+ radius = normalize_v3(vec);
+
tratio = ratio * td->factor;
-
- VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio);
-
- VecAddf(td->loc, t->center, vec);
+
+ 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);
-
+
return 1;
}
{
t->mode = TFM_ROTATION;
t->transform = Rotation;
-
+
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
-
+
t->ndof.axis = 16;
/* Scale down and flip input for rotation */
t->ndof.factor[0] = -0.2f;
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
-
+
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
}
float vec[3], totmat[3][3], smat[3][3];
float eul[3], fmat[3][3], quat[4];
float *center = t->center;
-
+
/* local constraint shouldn't alter center */
if (around == V3D_LOCAL) {
if (t->flag & (T_OBJECT|T_POSE)) {
center = td->center;
}
else {
- /* !TODO! Make this if not rely on G */
if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
center = td->center;
}
}
}
-
+
if (t->flag & T_POINTS) {
- Mat3MulMat3(totmat, mat, td->mtx);
- Mat3MulMat3(smat, td->smtx, totmat);
-
- VecSubf(vec, td->iloc, center);
- Mat3MulVecfl(smat, vec);
-
- VecAddf(td->loc, vec, center);
-
- VecSubf(vec,td->loc,td->iloc);
+ 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);
- VecAddf(td->loc, td->iloc, vec);
-
+ add_v3_v3v3(td->loc, td->iloc, vec);
+
+
if(td->flag & TD_USEQUAT) {
- Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
- Mat3ToQuat(fmat, quat); // Actual transform
-
+ mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ mat3_to_quat( quat,fmat); // Actual transform
+
if(td->ext->quat){
- QuatMul(td->ext->quat, quat, td->ext->iquat);
-
+ 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
- Mat3CpyMat4(pmtx, t->poseobj->obmat);
- Mat3Inv(imtx, pmtx);
-
+ copy_m3_m4(pmtx, t->poseobj->obmat);
+ invert_m3_m3(imtx, pmtx);
+
if ((td->flag & TD_NO_LOC) == 0)
{
- VecSubf(vec, td->center, center);
-
- Mat3MulVecfl(pmtx, vec); // To Global space
- Mat3MulVecfl(mat, vec); // Applying rotation
- Mat3MulVecfl(imtx, vec); // To Local space
-
- VecAddf(vec, vec, center);
+ 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_v3v3(vec, vec, center);
/* vec now is the location where the object has to be */
-
- VecSubf(vec, vec, td->center); // Translation needed from the initial location
-
- Mat3MulVecfl(pmtx, vec); // To Global space
- Mat3MulVecfl(td->smtx, vec);// To Pose space
-
+
+ sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location
+
+ mul_m3_v3(pmtx, vec); // To Global space
+ mul_m3_v3(td->smtx, vec);// To Pose space
+
protectedTransBits(td->protectflag, vec);
-
- VecAddf(td->loc, td->iloc, 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->flag & TD_USEQUAT) {
- Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
-
- Mat3ToQuat(fmat, quat); // Actual transform
-
- QuatMul(td->ext->quat, quat, td->ext->iquat);
+ /* euler or quaternion/axis-angle? */
+ if (td->rotOrder == ROT_MODE_QUAT) {
+ mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+
+ 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->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_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ 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];
- Mat3MulMat3(totmat, mat, td->mtx);
- Mat3MulMat3(smat, td->smtx, totmat);
+ mul_m3_m3m3(totmat, mat, td->mtx);
+ mul_m3_m3m3(smat, td->smtx, totmat);
/* calculate the total rotatation in eulers */
VECCOPY(eul, td->ext->irot);
- EulOToMat3(eul, td->rotOrder, eulmat);
+ eulO_to_mat3( eulmat,eul, td->rotOrder);
/* mat = transform, obmat = bone rotation */
- Mat3MulMat3(fmat, smat, eulmat);
+ mul_m3_m3m3(fmat, smat, eulmat);
- Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder);
+ mat3_to_compatible_eulO( eul, td->ext->rot, td->rotOrder,fmat);
/* and apply (to end result only) */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
VECCOPY(td->ext->rot, eul);
}
-
+
constraintRotLim(t, td);
}
}
if ((td->flag & TD_NO_LOC) == 0)
{
/* translation */
- VecSubf(vec, td->center, center);
- Mat3MulVecfl(mat, vec);
- VecAddf(vec, vec, center);
+ sub_v3_v3v3(vec, td->center, center);
+ mul_m3_v3(mat, vec);
+ add_v3_v3v3(vec, vec, center);
/* vec now is the location where the object has to be */
- VecSubf(vec, vec, td->center);
- Mat3MulVecfl(td->smtx, vec);
-
+ sub_v3_v3v3(vec, vec, td->center);
+ mul_m3_v3(td->smtx, vec);
+
protectedTransBits(td->protectflag, vec);
-
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
- }
- else VecAddf(td->loc, td->iloc, 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->flag & TD_USEQUAT) {
- Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
- Mat3ToQuat(fmat, quat); // Actual transform
-
- QuatMul(td->ext->quat, quat, td->ext->iquat);
+ if ((td->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
+ mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ 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->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_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ mat3_to_quat( quat,fmat); // Actual transform
+ mul_qt_qtqt(tquat, quat, iquat);
+
+ quat_to_axis_angle( td->ext->rotAxis, td->ext->rotAngle,quat);
+
+ /* 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];
-
- /* are there ipo keys? */
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- float current_rot[3];
- float rot[3];
-
- /* current IPO value for compatible euler */
- current_rot[0] = (tdi->rotx) ? tdi->rotx[0] : 0.0f;
- current_rot[1] = (tdi->roty) ? tdi->roty[0] : 0.0f;
- current_rot[2] = (tdi->rotz) ? tdi->rotz[0] : 0.0f;
- VecMulf(current_rot, (float)(M_PI_2 / 9.0));
-
- /* calculate the total rotatation in eulers */
- VecAddf(eul, td->ext->irot, td->ext->drot);
- EulToMat3(eul, obmat);
- /* mat = transform, obmat = object rotation */
- Mat3MulMat3(fmat, mat, obmat);
-
- Mat3ToCompatibleEul(fmat, eul, current_rot);
-
- /* correct back for delta rot */
- if(tdi->flag & TOB_IPODROT) {
- VecSubf(rot, eul, td->ext->irot);
- }
- else {
- VecSubf(rot, eul, td->ext->drot);
- }
-
- VecMulf(rot, (float)(9.0/M_PI_2));
- VecSubf(rot, rot, tdi->oldrot);
-
- protectedRotateBits(td->protectflag, rot, tdi->oldrot);
-
- add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]);
- add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]);
- add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]);
- }
- else {
- Mat3MulMat3(totmat, mat, td->mtx);
- Mat3MulMat3(smat, td->smtx, totmat);
-
- /* calculate the total rotatation in eulers */
- VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
- EulToMat3(eul, obmat);
- /* mat = transform, obmat = object rotation */
- Mat3MulMat3(fmat, smat, obmat);
-
- Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
-
- /* correct back for delta rot */
- VecSubf(eul, eul, td->ext->drot);
-
- /* and apply */
- protectedRotateBits(td->protectflag, eul, td->ext->irot);
- VECCOPY(td->ext->rot, eul);
- }
+
+ 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->rotOrder);
+ /* mat = transform, obmat = object rotation */
+ mul_m3_m3m3(fmat, smat, obmat);
+
+ mat3_to_compatible_eulO( eul, td->ext->rot, td->rotOrder,fmat);
+
+ /* correct back for delta rot */
+ sub_v3_v3v3(eul, eul, td->ext->drot);
+
+ /* and apply */
+ protectedRotateBits(td->protectflag, eul, td->ext->irot);
+ VECCOPY(td->ext->rot, eul);
}
-
+
constraintRotLim(t, td);
}
}
TransData *td = t->data;
float mat[3][3];
int i;
-
- VecRotToMat3(axis, angle, mat);
-
+
+ vec_rot_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);
- VecRotToMat3(axis, angle * td->factor, mat);
+ vec_rot_to_mat3( mat,axis, angle * td->factor);
}
else if (t->flag & T_PROP_EDIT) {
- VecRotToMat3(axis, angle * td->factor, mat);
+ vec_rot_to_mat3( mat,axis, angle * td->factor);
}
-
+
ElementRotation(t, td, mat, t->around);
}
}
int Rotation(TransInfo *t, short mval[2])
{
char str[64];
-
+
float final;
-
+
float axis[3];
float mat[3][3];
-
+
VECCOPY(axis, t->viewinv[2]);
- VecMulf(axis, -1.0f);
- Normalize(axis);
-
+ mul_v3_fl(axis, -1.0f);
+ normalize_v3(axis);
+
final = t->values[0];
-
+
applyNDofInput(&t->ndof, &final);
-
+
snapGrid(t, &final);
-
+
if (t->con.applyRot) {
t->con.applyRot(t, NULL, axis, &final);
}
-
+
applySnapping(t, &final);
-
+
if (hasNumInput(&t->num)) {
char c[20];
-
+
applyNumInput(&t->num, &final);
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
-
+
/* Clamp between -180 and 180 */
while (final >= 180.0)
final -= 360.0;
-
+
while (final <= -180.0)
final += 360.0;
-
+
final *= (float)(M_PI / 180.0);
}
else {
sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext);
}
-
- VecRotToMat3(axis, final, mat);
-
+
+ vec_rot_to_mat3( mat,axis, final);
+
// TRANSFORM_FIX_ME
// t->values[0] = final; // used in manipulator
-// Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+// copy_m3_m3(t->mat, mat); // used in manipulator
+
applyRotation(t, final, axis);
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
float mat[3][3], smat[3][3], totmat[3][3];
int i;
- VecRotToMat3(axis1, angles[0], smat);
- VecRotToMat3(axis2, angles[1], totmat);
+ vec_rot_to_mat3( smat,axis1, angles[0]);
+ vec_rot_to_mat3( totmat,axis2, angles[1]);
- Mat3MulMat3(mat, smat, totmat);
+ mul_m3_m3m3(mat, smat, totmat);
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
continue;
if (t->flag & T_PROP_EDIT) {
- VecRotToMat3(axis1, td->factor * angles[0], smat);
- VecRotToMat3(axis2, td->factor * angles[1], totmat);
+ vec_rot_to_mat3( smat,axis1, td->factor * angles[0]);
+ vec_rot_to_mat3( totmat,axis2, td->factor * angles[1]);
- Mat3MulMat3(mat, smat, totmat);
+ mul_m3_m3m3(mat, smat, totmat);
}
ElementRotation(t, td, mat, t->around);
VECCOPY(axis1, t->persinv[0]);
VECCOPY(axis2, t->persinv[1]);
- Normalize(axis1);
- Normalize(axis2);
+ normalize_v3(axis1);
+ normalize_v3(axis2);
phi[0] = t->values[0];
phi[1] = t->values[1];
sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
}
- VecRotToMat3(axis1, phi[0], smat);
- VecRotToMat3(axis2, phi[1], totmat);
+ vec_rot_to_mat3( smat,axis1, phi[0]);
+ vec_rot_to_mat3( totmat,axis2, phi[1]);
- Mat3MulMat3(mat, smat, totmat);
+ mul_m3_m3m3(mat, smat, totmat);
// TRANSFORM_FIX_ME
- //Mat3CpyMat3(t->mat, mat); // used in manipulator
+ //copy_m3_m3(t->mat, mat); // used in manipulator
applyTrackball(t, axis1, axis2, phi);
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
- dist = VecLength(t->num.val);
+ dist = len_v3(t->num.val);
}
else {
float dvec[3];
VECCOPY(dvec, vec);
applyAspectRatio(t, dvec);
- dist = VecLength(vec);
+ dist = len_v3(vec);
if(t->scene->unit.system) {
int i, do_split= t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1:0;
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
/* handle snapping rotation before doing the translation */
if (usingSnappingNormal(t))
{
float quat[4];
float mat[3][3];
float angle;
-
- Crossf(axis, original_normal, t->tsnap.snapNormal);
- angle = saacos(Inpf(original_normal, t->tsnap.snapNormal));
-
- AxisAngleToQuat(quat, axis, angle);
-
- QuatToMat3(quat, mat);
-
+
+ cross_v3_v3v3(axis, original_normal, t->tsnap.snapNormal);
+ angle = saacos(dot_v3v3(original_normal, t->tsnap.snapNormal));
+
+ axis_angle_to_quat(quat, axis, angle);
+
+ quat_to_mat3( mat,quat);
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
else
{
float mat[3][3];
-
- Mat3One(mat);
-
+
+ unit_m3(mat);
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
}
-
+
if (t->con.applyVec) {
float pvec[3];
t->con.applyVec(t, td, vec, tvec, pvec);
else {
VECCOPY(tvec, vec);
}
-
- Mat3MulVecfl(td->smtx, tvec);
- VecMulf(tvec, td->factor);
-
+
+ mul_m3_v3(td->smtx, tvec);
+ mul_v3_fl(tvec, td->factor);
+
protectedTransBits(td->protectflag, tvec);
-
- /* transdata ipokey */
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, tvec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, tvec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]);
- }
- else VecAddf(td->loc, td->iloc, tvec);
-
+
+ add_v3_v3v3(td->loc, td->iloc, tvec);
+
constraintTransLim(t, td);
}
}
continue;
VECCOPY(vec, td->axismtx[2]);
- VecMulf(vec, distance);
- VecMulf(vec, td->factor);
+ mul_v3_fl(vec, distance);
+ mul_v3_fl(vec, td->factor);
- VecAddf(td->loc, td->iloc, vec);
+ add_v3_v3v3(td->loc, td->iloc, vec);
}
recalcData(t);
if (td->flag & TD_SKIP)
continue;
- VecSubf(vec, t->center, td->center);
+ sub_v3_v3v3(vec, t->center, td->center);
if (t->con.applyRot && t->con.mode & CON_APPLY) {
t->con.applyRot(t, td, axis, NULL);
if (isLockConstraint(t)) {
float dvec[3];
- Projf(dvec, vec, axis);
- VecSubf(vec, vec, dvec);
+ project_v3_v3v3(dvec, vec, axis);
+ sub_v3_v3v3(vec, vec, dvec);
}
else {
- Projf(vec, vec, axis);
+ project_v3_v3v3(vec, vec, axis);
}
}
- Normalize(vec);
- VecMulf(vec, distance);
- VecMulf(vec, td->factor);
+ normalize_v3(vec);
+ mul_v3_fl(vec, distance);
+ mul_v3_fl(vec, td->factor);
- VecAddf(td->loc, td->iloc, vec);
+ add_v3_v3v3(td->loc, td->iloc, vec);
}
recalcData(t);
float tmat[3][3], smat[3][3], oldy;
float sizemat[3][3];
- Mat3MulMat3(smat, mat, td->mtx);
- Mat3MulMat3(tmat, td->smtx, smat);
+ mul_m3_m3m3(smat, mat, td->mtx);
+ mul_m3_m3m3(tmat, td->smtx, smat);
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
/* we've tucked the scale in loc */
oldy= td->iloc[1];
- SizeToMat3(td->iloc, sizemat);
- Mat3MulMat3(tmat, tmat, sizemat);
- Mat3ToSize(tmat, td->loc);
+ size_to_mat3( sizemat,td->iloc);
+ mul_m3_m3m3(tmat, tmat, sizemat);
+ mat3_to_size( td->loc,tmat);
td->loc[1]= oldy;
}
float ratio;
int i;
char str[60];
-
+
// 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)
{
ratio = t->values[0];
}
-
+
size[0] = size[1] = size[2] = ratio;
-
+
snapGrid(t, size);
-
+
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
-
- SizeToMat3(size, mat);
-
+
+ size_to_mat3( mat,size);
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
- Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+
+ 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);
-
+
return 1;
}
{
t->mode = TFM_BONE_ENVELOPE;
t->transform = BoneEnvelope;
-
+
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;
-
+
t->flag |= T_NO_CONSTRAINT;
}
float ratio;
int i;
char str[50];
-
+
ratio = t->values[0];
-
+
snapGrid(t, &ratio);
-
+
applyNumInput(&t->num, &ratio);
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
sprintf(str, "Envelope: %s", c);
}
else {
sprintf(str, "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);
+
+ return 1;
+}
+
+/* ******************** Edge Slide *************** */
+#if 1
+static int createSlideVerts(TransInfo *t) {
+#else
+static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e)
+{
+ BMIter iter;
+ BMEdge *e2;
+
+ BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
+ if (BM_TestHFlag(e2, BM_SELECT) && e2 != e)
+ return e;
+ }
+
+ return NULL;
+}
+
+static BMLoop *get_next_loop(BMesh *bm, BMVert *v, BMFace *f,
+ BMEdge *olde, BMEdge *nexte)
+{
+ BMIter iter;
+ BMLoop *l, firstl;
+
+ BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
+ if (l->e == olde)
+ break;
+ }
+
+ firstl = l;
+ do {
+ l = BM_OtherFaceLoop(l->e, l->f, v);
+ if (l->radial.next->data == l)
+ return NULL;
+
+ if (BM_OtherFaceLoop(l->e, l->f, v)->e == nexte)
+ return BM_OtherFaceLoop(l->e, l->f, v);
+
+ if (l->e == nexte)
+ return l;
+
+ l = l->radial.next->data;
+ } while (l != firstl);
+
+ return NULL;
+}
+
+static int createSlideVerts(TransInfo *t)
+{
+ Mesh *me = t->obedit->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter, iter2;
+ BMEdge *e, *e1, *e2;
+ BMVert *v, *first;
+ BMLoop *l, *l1, *l2;
+ TransDataSlideVert *tempsv;
+ GHash **uvarray= NULL;
+ SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ int uvlay_idx;
+ TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
+ RegionView3D *v3d = t->ar->regiondata;
+ float projectMat[4][4];
+ float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
+ float vec[3], i, j;
+ float totvec=0.0;
+
+ if (!v3d) {
+ /*ok, let's try to survive this*/
+ unit_m4(projectMat);
+ } else {
+ view3d_get_object_project_mat(v3d, t->obedit, projectMat);
+ }
+
+ /*ensure valid selection*/
+ BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if (BM_TestHFlag(v, BM_SELECT)) {
+ numsel = 0;
+ BM_ITER(e, &iter2, em->bm, BM_EDGES_OF_VERT, v) {
+ if (BM_TestHFlag(e, BM_SELECT)) {
+ /*BMESH_TODO: this is probably very evil,
+ set v->edge to a selected edge*/
+ v->edge = e;
+
+ numsel++;
+ }
+ }
+
+ if (numsel > 2) {
+ return 0; //invalid edge selection
+ }
+ }
+ }
+
+ BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+ if (BM_TestHFlag(e, BM_SELECT)) {
+ if (BM_Edge_FaceCount(e) > 2)
+ return 0; //can't handle more then 2 faces around an edge
+ }
+ }
+
+ j = 0;
+ BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if (BM_TestHFlag(v, BM_SELECT)) {
+ BMINDEX_SET(v, 1);
+ j += 1;
+ } else BMINDEX_SET(v, 0);
+ }
+
+ if (!j)
+ return 0;
+
+ tempsv = MEM_callocN(sizeof(TransDataSlideVert)*j, "tempsv");
+
+ j = 0;
+ while (1) {
+ v = NULL;
+ BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if (BMINDEX_GET(v))
+ break;
+
+ }
+
+ if (!v)
+ break;
+
+ BMINDX_SET(v, 0);
+
+ if (!v->edge)
+ continue
+
+ first = v;
+
+ /*walk along the edge loop*/
+ e = v->edge;
+
+ /*first, rewind*/
+ numsel = 0;
+ do {
+ e = get_other_edge(bm, v, e);
+ if (!e) {
+ e = v->edge;
+ break;
+ }
+
+ v = BM_OtherEdgeVert(e, v);
+ numsel += 1;
+ } while (e != v->edge);
+
+ l1 = l2 = l = NULL;
+
+ /*iterate over the loop*/
+ first = v;
+ do {
+ TransDataSlideVert *sv = tempsv + j;
+
+ sv->v = v;
+ sv->origvert = *v;
+
+ e = get_other_edge(bm, v, e);
+ if (!e) {
+ e = v->edge;
+ break;
+ }
+
+ v = BM_OtherEdgeVert(e, v);
+ j += 1
+ } while (e != v->edge);
+ }
+
+ MEM_freeN(tempsv);
+#endif
+#if 0
+ Mesh *me = t->obedit->data;
+ BMEditMesh *em = me->edit_btmesh;
+ EditFace *efa;
+ EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
+ EditVert *ev, *nearest = NULL;
+ LinkNode *edgelist = NULL, *vertlist=NULL, *look;
+ GHash *vertgh;
+ TransDataSlideVert *tempsv;
+ float vertdist; // XXX, projectMat[4][4];
+ int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0;
+ /* UV correction vars */
+ GHash **uvarray= NULL;
+ SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ int uvlay_idx;
+ TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
+ RegionView3D *v3d = t->ar->regiondata;
+ float projectMat[4][4];
+ float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
+ float vec[3];
+ float totvec=0.0;
+
+ if (!v3d) {
+ /*ok, let's try to survive this*/
+ unit_m4(projectMat);
+ } else {
+ view3d_get_object_project_mat(v3d, t->obedit, projectMat);
+ }
+
+ numsel =0;
+
+ // Get number of selected edges and clear some flags
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ eed->f1 = 0;
+ eed->f2 = 0;
+ if(eed->f & SELECT) numsel++;
+ }
+
+ for(ev=em->verts.first;ev;ev=ev->next) {
+ ev->f1 = 0;
+ }
+
+ //Make sure each edge only has 2 faces
+ // make sure loop doesn't cross face
+ for(efa=em->faces.first;efa;efa=efa->next) {
+ int ct = 0;
+ if(efa->e1->f & SELECT) {
+ ct++;
+ efa->e1->f1++;
+ if(efa->e1->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ if(efa->e2->f & SELECT) {
+ ct++;
+ efa->e2->f1++;
+ if(efa->e2->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ if(efa->e3->f & SELECT) {
+ ct++;
+ efa->e3->f1++;
+ if(efa->e3->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ if(efa->e4 && efa->e4->f & SELECT) {
+ ct++;
+ efa->e4->f1++;
+ if(efa->e4->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ // Make sure loop is not 2 edges of same face
+ if(ct > 1) {
+ //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
+ return 0;
+ }
+ }
+
+ // Get # of selected verts
+ for(ev=em->verts.first;ev;ev=ev->next) {
+ if(ev->f & SELECT) vertsel++;
+ }
+
+ // Test for multiple segments
+ if(vertsel > numsel+1) {
+ //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop");
+ return 0;
+ }
+
+ // Get the edgeloop in order - mark f1 with SELECT once added
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if((eed->f & SELECT) && !(eed->f1 & SELECT)) {
+ // If this is the first edge added, just put it in
+ if(!edgelist) {
+ BLI_linklist_prepend(&edgelist,eed);
+ numadded++;
+ first = eed;
+ last = eed;
+ eed->f1 = SELECT;
+ } else {
+ if(editedge_getSharedVert(eed, last)) {
+ BLI_linklist_append(&edgelist,eed);
+ eed->f1 = SELECT;
+ numadded++;
+ last = eed;
+ } else if(editedge_getSharedVert(eed, first)) {
+ BLI_linklist_prepend(&edgelist,eed);
+ eed->f1 = SELECT;
+ numadded++;
+ first = eed;
+ }
+ }
+ }
+ if(eed->next == NULL && numadded != numsel) {
+ eed=em->edges.first;
+ timesthrough++;
+ }
+
+ // It looks like there was an unexpected case - Hopefully should not happen
+ if(timesthrough >= numsel*2) {
+ BLI_linklist_free(edgelist,NULL);
+ //BKE_report(op->reports, RPT_ERROR, "Could not order loop");
+ return 0;
+ }
+ }
+
+ // Put the verts in order in a linklist
+ look = edgelist;
+ while(look) {
+ eed = look->link;
+ if(!vertlist) {
+ if(look->next) {
+ temp = look->next->link;
+
+ //This is the first entry takes care of extra vert
+ if(eed->v1 != temp->v1 && eed->v1 != temp->v2) {
+ BLI_linklist_append(&vertlist,eed->v1);
+ eed->v1->f1 = 1;
+ } else {
+ BLI_linklist_append(&vertlist,eed->v2);
+ eed->v2->f1 = 1;
+ }
+ } else {
+ //This is the case that we only have 1 edge
+ BLI_linklist_append(&vertlist,eed->v1);
+ eed->v1->f1 = 1;
+ }
+ }
+ // for all the entries
+ if(eed->v1->f1 != 1) {
+ BLI_linklist_append(&vertlist,eed->v1);
+ eed->v1->f1 = 1;
+ } else if(eed->v2->f1 != 1) {
+ BLI_linklist_append(&vertlist,eed->v2);
+ eed->v2->f1 = 1;
+ }
+ look = look->next;
+ }
+
+ // populate the SlideVerts
+
+ vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ look = vertlist;
+ while(look) {
+ i=0;
+ j=0;
+ ev = look->link;
+ tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert");
+ tempsv->up = NULL;
+ tempsv->down = NULL;
+ tempsv->origvert.co[0] = ev->co[0];
+ tempsv->origvert.co[1] = ev->co[1];
+ tempsv->origvert.co[2] = ev->co[2];
+ tempsv->origvert.no[0] = ev->no[0];
+ tempsv->origvert.no[1] = ev->no[1];
+ tempsv->origvert.no[2] = ev->no[2];
+ // i is total edges that vert is on
+ // j is total selected edges that vert is on
+
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if(eed->v1 == ev || eed->v2 == ev) {
+ i++;
+ if(eed->f & SELECT) {
+ j++;
+ }
+ }
+ }
+ // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges
+ if(i == 4 && j == 2) {
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if(editedge_containsVert(eed, ev)) {
+ if(!(eed->f & SELECT)) {
+ if(!tempsv->up) {
+ tempsv->up = eed;
+ } else if (!(tempsv->down)) {
+ tempsv->down = eed;
+ }
+ }
+ }
+ }
+ }
+ // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected
+ if(i >= 3 && j == 1) {
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if(editedge_containsVert(eed, ev) && eed->f & SELECT) {
+ for(efa = em->faces.first;efa;efa=efa->next) {
+ if(editface_containsEdge(efa, eed)) {
+ if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e1;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e1;
+ }
+ }
+ if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e2;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e2;
+ }
+ }
+ if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e3;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e3;
+ }
+ }
+ if(efa->e4) {
+ if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e4;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e4;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ if(i > 4 && j == 2) {
+ BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(vertlist,NULL);
+ BLI_linklist_free(edgelist,NULL);
+ return 0;
+ }
+ BLI_ghash_insert(vertgh,ev,tempsv);
+
+ look = look->next;
+ }
+
+ // make sure the UPs nad DOWNs are 'faceloops'
+ // Also find the nearest slidevert to the cursor
+
+ look = vertlist;
+ nearest = NULL;
+ vertdist = -1;
+ while(look) {
+ tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+
+ if(!tempsv->up || !tempsv->down) {
+ //BKE_report(op->reports, RPT_ERROR, "Missing rails");
+ BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(vertlist,NULL);
+ BLI_linklist_free(edgelist,NULL);
+ return 0;
+ }
+
+ if(me->drawflag & ME_DRAW_EDGELEN) {
+ if(!(tempsv->up->f & SELECT)) {
+ tempsv->up->f |= SELECT;
+ tempsv->up->f2 |= 16;
+ } else {
+ tempsv->up->f2 |= ~16;
+ }
+ if(!(tempsv->down->f & SELECT)) {
+ tempsv->down->f |= SELECT;
+ tempsv->down->f2 |= 16;
+ } else {
+ tempsv->down->f2 |= ~16;
+ }
+ }
+
+ if(look->next != NULL) {
+ TransDataSlideVert *sv;
+
+ ev = (EditVert*)look->next->link;
+ sv = BLI_ghash_lookup(vertgh, ev);
+
+ if(sv) {
+ float co[3], co2[3], vec[3];
+
+ ev = (EditVert*)look->link;
+
+ if(!sharesFace(em, tempsv->up,sv->up)) {
+ EditEdge *swap;
+ swap = sv->up;
+ sv->up = sv->down;
+ sv->down = swap;
+ }
+
+ if (v3d) {
+ view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat);
+ view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat);
+ }
+
+ if (ev == tempsv->up->v1) {
+ sub_v3_v3v3(vec, co, co2);
+ } else {
+ sub_v3_v3v3(vec, co2, co);
+ }
+
+ add_v3_v3v3(start, start, vec);
+
+ if (v3d) {
+ view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat);
+ view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat);
+ }
+
+ if (ev == tempsv->down->v1) {
+ sub_v3_v3v3(vec, co2, co);
+ } else {
+ sub_v3_v3v3(vec, co, co2);
+ }
+
+ add_v3_v3v3(end, end, vec);
+
+ totvec += 1.0f;
+ nearest = (EditVert*)look->link;
+ }
+ }
+
+
+
+ look = look->next;
+ }
+
+ add_v3_v3v3(start, start, end);
+ mul_v3_fl(start, 0.5*(1.0/totvec));
+ VECCOPY(vec, start);
+ start[0] = t->mval[0];
+ start[1] = t->mval[1];
+ add_v3_v3v3(end, start, vec);
+
+ sld->start[0] = (short) start[0];
+ sld->start[1] = (short) start[1];
+ sld->end[0] = (short) end[0];
+ sld->end[1] = (short) end[1];
+
+ if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+ int maxnum = 0;
+
+ uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
+ sld->totuv = uvlay_tot;
+ suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */
+ suv = NULL;
+
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+
+ uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ for(ev=em->verts.first;ev;ev=ev->next) {
+ ev->tmp.l = 0;
+ }
+ look = vertlist;
+ while(look) {
+ float *uv_new;
+ tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+
+ ev = look->link;
+ suv = NULL;
+ for(efa = em->faces.first;efa;efa=efa->next) {
+ if (ev->tmp.l != -1) { /* test for self, in this case its invalid */
+ int k=-1; /* face corner */
+
+ /* Is this vert in the faces corner? */
+ if (efa->v1==ev) k=0;
+ else if (efa->v2==ev) k=1;
+ else if (efa->v3==ev) k=2;
+ else if (efa->v4 && efa->v4==ev) k=3;
+
+ if (k != -1) {
+ MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx);
+ EditVert *ev_up, *ev_down;
+
+ uv_new = tf->uv[k];
+
+ if (ev->tmp.l) {
+ if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) {
+ ev->tmp.l = -1; /* Tag as invalid */
+ BLI_linklist_free(suv->fuv_list,NULL);
+ suv->fuv_list = NULL;
+ BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
+ suv = NULL;
+ break;
+ }
+ } else {
+ ev->tmp.l = 1;
+ suv = suv_last;
+
+ suv->fuv_list = NULL;
+ suv->uv_up = suv->uv_down = NULL;
+ suv->origuv[0] = uv_new[0];
+ suv->origuv[1] = uv_new[1];
+
+ BLI_linklist_prepend(&suv->fuv_list, uv_new);
+ BLI_ghash_insert(uvarray[uvlay_idx],ev,suv);
+
+ suv_last++; /* advance to next slide UV */
+ maxnum++;
+ }
+
+ /* Now get the uvs along the up or down edge if we can */
+ if (suv) {
+ if (!suv->uv_up) {
+ ev_up = editedge_getOtherVert(tempsv->up,ev);
+ if (efa->v1==ev_up) suv->uv_up = tf->uv[0];
+ else if (efa->v2==ev_up) suv->uv_up = tf->uv[1];
+ else if (efa->v3==ev_up) suv->uv_up = tf->uv[2];
+ else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3];
+ }
+ if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */
+ ev_down = editedge_getOtherVert(tempsv->down,ev);
+ if (efa->v1==ev_down) suv->uv_down = tf->uv[0];
+ else if (efa->v2==ev_down) suv->uv_down = tf->uv[1];
+ else if (efa->v3==ev_down) suv->uv_down = tf->uv[2];
+ else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3];
+ }
+
+ /* Copy the pointers to the face UV's */
+ BLI_linklist_prepend(&suv->fuv_list, uv_new);
+ }
+ }
+ }
+ }
+ look = look->next;
+ }
+ } /* end uv layer loop */
+ } /* end uvlay_tot */
+
+ sld->uvhash = uvarray;
+ sld->slideuv = slideuvs;
+ sld->vhash = vertgh;
+ sld->nearest = nearest;
+ sld->vertlist = vertlist;
+ sld->edgelist = edgelist;
+ sld->suv_last = suv_last;
+ sld->uvlay_tot = uvlay_tot;
+
+ // we should have enough info now to slide
+
+ t->customData = sld;
+
+ return 1;
+#endif
+}
+
+void freeSlideVerts(TransInfo *t)
+{
+#if 0
+ TransDataSlideUv *suv;
+ SlideData *sld = t->customData;
+ int uvlay_idx;
+
+ //BLI_ghash_free(edgesgh, freeGHash, NULL);
+ BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(sld->vertlist, NULL);
+ BLI_linklist_free(sld->edgelist, NULL);
+
+ if (sld->uvlay_tot) {
+ for (uvlay_idx=0; uvlay_idx<sld->uvlay_tot; uvlay_idx++) {
+ BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL);
+ }
+
+ suv = sld->suv_last-1;
+ while (suv >= sld->slideuv) {
+ if (suv->fuv_list) {
+ BLI_linklist_free(suv->fuv_list,NULL);
+ }
+ suv--;
+ }
+
+ MEM_freeN(sld->slideuv);
+ MEM_freeN(sld->uvhash);
+ }
+
+ MEM_freeN(sld);
+ t->customData = NULL;
+#endif
+}
+
+void initEdgeSlide(TransInfo *t)
+{
+ SlideData *sld;
+
+ t->mode = TFM_EDGE_SLIDE;
+ t->transform = EdgeSlide;
+
+ createSlideVerts(t);
+ sld = t->customData;
+
+ if (!sld)
+ return;
+
+ t->customFree = freeSlideVerts;
+
+ /* set custom point first if you want value to be initialized by init */
+ setCustomPoints(t, &t->mouse, sld->end, sld->start);
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = (float)((5.0/180)*M_PI);
+ t->snap[2] = t->snap[1] * 0.2f;
+
+ t->flag |= T_NO_CONSTRAINT;
+}
+
+int doEdgeSlide(TransInfo *t, float perc)
+{
+#if 0
+ Mesh *me= t->obedit->data;
+ EditMesh *em = me->edit_mesh;
+ SlideData *sld = t->customData;
+ EditVert *ev, *nearest = sld->nearest;
+ EditVert *centerVert, *upVert, *downVert;
+ LinkNode *vertlist=sld->vertlist, *look;
+ GHash *vertgh = sld->vhash;
+ TransDataSlideVert *tempsv;
+ float len = 0.0f;
+ int prop=1, flip=0;
+ /* UV correction vars */
+ GHash **uvarray= sld->uvhash;
+ int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ int uvlay_idx;
+ TransDataSlideUv *suv=sld->slideuv;
+ float uv_tmp[2];
+ LinkNode *fuv_link;
+
+ len = 0.0f;
+
+ tempsv = BLI_ghash_lookup(vertgh,nearest);
+
+ centerVert = editedge_getSharedVert(tempsv->up, tempsv->down);
+ upVert = editedge_getOtherVert(tempsv->up, centerVert);
+ downVert = editedge_getOtherVert(tempsv->down, centerVert);
+
+ len = MIN2(perc, len_v3v3(upVert->co,downVert->co));
+ len = MAX2(len, 0);
+
+ //Adjust Edgeloop
+ if(prop) {
+ look = vertlist;
+ while(look) {
+ EditVert *tempev;
+ ev = look->link;
+ tempsv = BLI_ghash_lookup(vertgh,ev);
+
+ tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
+ interp_v3_v3v3(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
+
+ if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+ suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+ if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+ interp_v2_v2v2(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc));
+ fuv_link = suv->fuv_list;
+ while (fuv_link) {
+ VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+ fuv_link = fuv_link->next;
+ }
+ }
+ }
+ }
+
+ look = look->next;
+ }
+ }
+ else {
+ //Non prop code
+ look = vertlist;
+ while(look) {
+ float newlen;
+ ev = look->link;
+ tempsv = BLI_ghash_lookup(vertgh,ev);
+ newlen = (len / len_v3v3(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co));
+ if(newlen > 1.0) {newlen = 1.0;}
+ if(newlen < 0.0) {newlen = 0.0;}
+ if(flip == 0) {
+ interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
+ if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ /* dont do anything if no UVs */
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+ suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+ if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+ interp_v2_v2v2(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen));
+ fuv_link = suv->fuv_list;
+ while (fuv_link) {
+ VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+ fuv_link = fuv_link->next;
+ }
+ }
+ }
+ }
+ } else{
+ interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
+
+ if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ /* dont do anything if no UVs */
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+ suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+ if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+ interp_v2_v2v2(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen));
+ fuv_link = suv->fuv_list;
+ while (fuv_link) {
+ VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+ fuv_link = fuv_link->next;
+ }
+ }
+ }
+ }
+ }
+ look = look->next;
+ }
+
+ }
+#endif
+ return 1;
+}
+
+int EdgeSlide(TransInfo *t, short mval[2])
+{
+ char str[50];
+ float final;
+
+ final = t->values[0];
+
+ snapGrid(t, &final);
+
+ if (hasNumInput(&t->num)) {
+ char c[20];
+
+ applyNumInput(&t->num, &final);
+
+ outputNumInput(&(t->num), c);
+
+ sprintf(str, "Edge Slide Percent: %s", &c[0]);
+ }
+ else {
+ sprintf(str, "Edge Slide Percent: %.2f", final);
+ }
+
+ CLAMP(final, -1.0f, 1.0f);
+
+ /*do stuff here*/
+ if (t->customData)
+ doEdgeSlide(t, final);
+ else {
+ strcpy(str, "Invalid Edge Selection");
+ t->state = TRANS_CANCEL;
+ }
recalcData(t);
return 1;
}
-
/* ******************** EditBone roll *************** */
void initBoneRoll(TransInfo *t)
if (t->con.mode & CON_APPLY) {
size[0] = size[1] = size[2] = -1;
- SizeToMat3(size, mat);
+ size_to_mat3( mat,size);
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
{
size[0] = size[1] = size[2] = 1;
- SizeToMat3(size, mat);
+ size_to_mat3( mat,size);
for(i = 0, td=t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
}
}
- Mat3Inv(invmat, td->axismtx);
+ invert_m3_m3(invmat, td->axismtx);
- Mat3MulMat3(mat, t->spacemtx, invmat);
+ mul_m3_m3m3(mat, t->spacemtx, invmat);
ElementRotation(t, td, mat, t->around);
}