Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c1463
-rw-r--r--source/blender/editors/transform/transform.h79
-rw-r--r--source/blender/editors/transform/transform_constraints.c5
-rw-r--r--source/blender/editors/transform/transform_conversions.c447
-rw-r--r--source/blender/editors/transform/transform_generics.c170
-rw-r--r--source/blender/editors/transform/transform_input.c48
-rw-r--r--source/blender/editors/transform/transform_manipulator.c19
-rw-r--r--source/blender/editors/transform/transform_ops.c191
-rw-r--r--source/blender/editors/transform/transform_orientations.c273
-rw-r--r--source/blender/editors/transform/transform_snap.c127
10 files changed, 1751 insertions, 1071 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index e877f1fecae..7128bd9c6a9 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -100,6 +100,7 @@
#include "ED_markers.h"
#include "ED_util.h"
#include "ED_view3d.h"
+#include "ED_mesh.h"
#include "UI_view2d.h"
#include "WM_types.h"
@@ -108,6 +109,8 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
+#include "BLI_ghash.h"
+#include "BLI_linklist.h"
#include "PIL_time.h" /* sleep */
@@ -319,7 +322,7 @@ static void viewRedrawForce(bContext *C, TransInfo *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, NULL);
}
else if(t->spacetype == SPACE_SEQ)
{
@@ -512,7 +515,7 @@ static char *transform_to_undostr(TransInfo *t)
#define TFM_MODAL_SNAP_GEARS_OFF 7
/* 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", ""},
@@ -524,12 +527,12 @@ void transform_modal_keymap(wmWindowManager *wm)
{TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""},
{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);
@@ -770,10 +773,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
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");
}
}
}
@@ -802,10 +806,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
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");
}
}
}
@@ -830,10 +835,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
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) {
@@ -1282,6 +1288,36 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
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);
@@ -1313,20 +1349,6 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
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)
@@ -1428,6 +1450,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
case TFM_BONE_ENVELOPE:
initBoneEnvelope(t);
break;
+ case TFM_EDGE_SLIDE:
+ initEdgeSlide(t);
+ break;
case TFM_BONE_ROLL:
initBoneRoll(t);
break;
@@ -1499,7 +1524,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
t->con.mode |= CON_AXIS2;
}
- setUserConstraint(t, t->con.mode, "%s");
+ setUserConstraint(t, t->current_orientation, t->con.mode, "%s");
}
}
@@ -1705,38 +1730,30 @@ static void constraintTransLim(TransInfo *t, TransData *td)
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);
- }
-
+ 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) */
@@ -1747,10 +1764,10 @@ static void constraintTransLim(TransInfo *t, TransData *td)
/* 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) */
@@ -1759,17 +1776,9 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
}
}
-
+
/* 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]);
}
}
@@ -1785,25 +1794,14 @@ static void constraintRotLim(TransInfo *t, TransData *td)
* - 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);
else
return;
}
- else if (td->tdi) { // XXX depreceated
- /* 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 == PCHAN_ROT_AXISANGLE) {
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* axis angle */
if (td->ext)
AxisAngleToMat4(&td->ext->quat[1], td->ext->quat[0], cob.matrix);
@@ -1857,22 +1855,11 @@ static void constraintRotLim(TransInfo *t, TransData *td)
}
/* copy results from cob->matrix */
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */
Mat4ToQuat(cob.matrix, td->ext->quat);
}
- 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 == PCHAN_ROT_AXISANGLE) {
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* axis angle */
Mat4ToAxisAngle(cob.matrix, &td->ext->quat[1], &td->ext->quat[0]);
}
@@ -1889,22 +1876,13 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
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
}
@@ -1912,25 +1890,25 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
-
+
SizeToMat4(td->ext->size, cob.matrix);
}
-
+
/* 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) */
@@ -1941,10 +1919,10 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* 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) */
@@ -1953,19 +1931,9 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
}
}
}
-
+
/* 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
}
@@ -1973,7 +1941,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
-
+
Mat4ToSize(cob.matrix, td->ext->size);
}
}
@@ -1985,21 +1953,21 @@ void initWarp(TransInfo *t)
{
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];
@@ -2014,7 +1982,7 @@ void initWarp(TransInfo *t)
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;
@@ -2026,7 +1994,7 @@ void initWarp(TransInfo *t)
int handleEventWarp(TransInfo *t, wmEvent *event)
{
int status = 0;
-
+
if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
{
// Use customData pointer to signal warp direction
@@ -2034,10 +2002,10 @@ int handleEventWarp(TransInfo *t, wmEvent *event)
t->customData = (void*)1;
else
t->customData = 0;
-
+
status = 1;
}
-
+
return status;
}
@@ -2047,7 +2015,7 @@ int Warp(TransInfo *t, short mval[2])
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.
@@ -2068,73 +2036,73 @@ int Warp(TransInfo *t, short mval[2])
}
Mat4MulVecfl(t->viewmat, cursor);
VecSubf(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]);
-
+
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);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -2145,22 +2113,22 @@ void initShear(TransInfo *t)
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
@@ -2174,10 +2142,10 @@ int handleEventShear(TransInfo *t, wmEvent *event)
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
t->customData = 0;
}
-
+
status = 1;
}
-
+
return status;
}
@@ -2190,47 +2158,47 @@ int Shear(TransInfo *t, short mval[2])
float value;
int i;
char str[50];
-
+
Mat3CpyMat4(persmat, t->viewmat);
Mat3Inv(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);
-
+
// 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);
-
+
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);
@@ -2240,19 +2208,19 @@ int Shear(TransInfo *t, short mval[2])
Mat3CpyMat3(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);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
return 1;
@@ -2264,9 +2232,9 @@ void initResize(TransInfo *t)
{
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;
@@ -2274,7 +2242,7 @@ void initResize(TransInfo *t)
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;
@@ -2292,7 +2260,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
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:
@@ -2320,14 +2288,14 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
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);
-
+
/* 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];
@@ -2338,7 +2306,7 @@ static void TransMat3ToSize( float mat[][3], float smat[][3], float *size)
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);
@@ -2346,18 +2314,18 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
else {
Mat3CpyMat3(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);
}
@@ -2372,14 +2340,14 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
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);
+ Mat3MulMat3(obsizemat, td->axismtx, tmat);
//printmatrix3("obsizemat", obsizemat);
TransMat3ToSize(obsizemat, td->axismtx, fsize);
//printvecf("fsize", fsize);
@@ -2387,28 +2355,14 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
else {
Mat3ToSize(tmat, fsize);
}
-
+
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->ext->size[0] = td->ext->isize[0];
td->ext->size[1] = td->ext->isize[1];
td->ext->size[2] = td->ext->isize[2];
@@ -2417,46 +2371,39 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
/* 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;
}
}
-
+
constraintSizeLim(t, td);
}
-
+
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_POINTS)
VecSubf(vec, td->iloc, center);
else
VecSubf(vec, td->center, center);
-
+
Mat3MulVecfl(tmat, vec);
-
+
VecAddf(vec, vec, center);
if (t->flag & T_POINTS)
VecSubf(vec, vec, td->iloc);
else
VecSubf(vec, vec, td->center);
-
+
VecMulf(vec, td->factor);
-
+
if (t->flag & (T_OBJECT|T_POSE)) {
Mat3MulVecfl(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);
-
+ VecAddf(td->loc, td->iloc, vec);
+
constraintTransLim(t, td);
}
@@ -2467,7 +2414,7 @@ int Resize(TransInfo *t, short mval[2])
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)
{
@@ -2477,60 +2424,60 @@ int Resize(TransInfo *t, short mval[2])
{
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);
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
+
Mat3CpyMat3(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);
-
+
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;
}
@@ -2540,26 +2487,26 @@ void initToSphere(TransInfo *t)
{
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 /= (float)t->total;
}
@@ -2570,56 +2517,56 @@ int ToSphere(TransInfo *t, short mval[2])
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);
-
+
tratio = ratio * td->factor;
-
+
VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio);
-
+
VecAddf(td->loc, t->center, vec);
}
-
-
+
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -2630,19 +2577,19 @@ void initRotation(TransInfo *t)
{
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;
}
@@ -2651,40 +2598,40 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
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);
protectedTransBits(td->protectflag, vec);
VecAddf(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
-
+
if(td->ext->quat){
QuatMul(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);
}
@@ -2704,48 +2651,48 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
*/
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);
-
+
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);
/* 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
-
+
protectedTransBits(td->protectflag, vec);
-
+
VecAddf(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/axis-angle? */
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
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);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
- else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
float iquat[4];
@@ -2797,93 +2744,67 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
/* vec now is the location where the object has to be */
VecSubf(vec, vec, td->center);
Mat3MulVecfl(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);
+
+ VecAddf(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) {
+ if ((td->rotOrder == ROT_MODE_QUAT) || (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);
/* 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];
+
+ /* td->ext->(i)quat is in axis-angle form, not quats! */
+ AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+
+ Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ Mat3ToQuat(fmat, quat); // Actual transform
+
+ QuatMul(td->ext->quat, quat, iquat);
+
+ /* make temp copy (since stored in same place) */
+ QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro
+ QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]);
+
+ /* this function works on end result */
+ protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
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);
- }
+
+ 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 */
+ EulOToMat3(eul, td->rotOrder, obmat);
+ /* mat = transform, obmat = object rotation */
+ Mat3MulMat3(fmat, smat, obmat);
+
+ Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder);
+
+ /* 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);
}
-
+
constraintRotLim(t, td);
}
}
@@ -2894,17 +2815,17 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
TransData *td = t->data;
float mat[3][3];
int i;
-
+
VecRotToMat3(axis, angle, mat);
-
+
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);
@@ -2912,7 +2833,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
else if (t->flag & T_PROP_EDIT) {
VecRotToMat3(axis, angle * td->factor, mat);
}
-
+
ElementRotation(t, td, mat, t->around);
}
}
@@ -2920,62 +2841,62 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
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);
-
+
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);
-
+
// TRANSFORM_FIX_ME
// t->values[0] = final; // used in manipulator
// Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+
applyRotation(t, final, axis);
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -3193,10 +3114,10 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
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))
{
@@ -3207,26 +3128,26 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
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);
-
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
else
{
float mat[3][3];
-
+
Mat3One(mat);
-
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
}
-
+
if (t->con.applyVec) {
float pvec[3];
t->con.applyVec(t, td, vec, tvec, pvec);
@@ -3234,21 +3155,14 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
else {
VECCOPY(tvec, vec);
}
-
+
Mat3MulVecfl(td->smtx, tvec);
VecMulf(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);
-
+
+ VecAddf(td->loc, td->iloc, tvec);
+
constraintTransLim(t, td);
}
}
@@ -3915,7 +3829,7 @@ int BoneSize(TransInfo *t, short mval[2])
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)
@@ -3926,40 +3840,40 @@ int BoneSize(TransInfo *t, short mval[2])
{
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);
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
+
Mat3CpyMat3(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;
}
@@ -3970,15 +3884,15 @@ void initBoneEnvelope(TransInfo *t)
{
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;
}
@@ -3988,31 +3902,31 @@ int BoneEnvelope(TransInfo *t, short mval[2])
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)
@@ -4021,6 +3935,698 @@ int BoneEnvelope(TransInfo *t, short mval[2])
*td->val= ratio;
}
}
+
+ recalcData(t);
+
+ ED_area_headerprint(t->sa, str);
+
+ return 1;
+}
+
+/* ******************** Edge Slide *************** */
+
+static int createSlideVerts(TransInfo *t)
+{
+#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 perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4];
+ float shiftlabda= 0.0f,len = 0.0f;
+ int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
+ int wasshift = 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];
+ //short mval[2], mvalo[2];
+ float labda = 0.0f, totvec=0.0;
+
+ if (!v3d) {
+ /*ok, let's try to survive this*/
+ Mat4One(projectMat);
+ } else {
+ view3d_get_object_project_mat(v3d, t->obedit, projectMat);
+ }
+
+ //mvalo[0] = -1; mvalo[1] = -1;
+ 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) {
+ VecSubf(vec, co, co2);
+ } else {
+ VecSubf(vec, co2, co);
+ }
+
+ VecAddf(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) {
+ VecSubf(vec, co2, co);
+ } else {
+ VecSubf(vec, co, co2);
+ }
+
+ VecAddf(end, end, vec);
+
+ totvec += 1.0f;
+ nearest = (EditVert*)look->link;
+ }
+ }
+
+
+
+ look = look->next;
+ }
+
+ VecAddf(start, start, end);
+ VecMulf(start, 0.5*(1.0/totvec));
+ VECCOPY(vec, start);
+ start[0] = t->mval[0];
+ start[1] = t->mval[1];
+ VecAddf(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;
+
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+ setCustomPoints(t, &t->mouse, sld->end, sld->start);
+
+ 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;
+ EditEdge *first=NULL,*last=NULL, *temp = NULL;
+ EditVert *ev, *nearest = sld->nearest;
+ EditVert *centerVert, *upVert, *downVert;
+ LinkNode *edgelist = sld->edgelist, *vertlist=sld->vertlist, *look;
+ GHash *vertgh = sld->vhash;
+ TransDataSlideVert *tempsv;
+ float shiftlabda= 0.0f,len = 0.0f;
+ int i = 0, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
+ int wasshift = 0;
+ /* UV correction vars */
+ GHash **uvarray= sld->uvhash;
+ int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ int uvlay_idx;
+ TransDataSlideUv *slideuvs=sld->slideuv, *suv=sld->slideuv, *suv_last=NULL;
+ float uv_tmp[2];
+ LinkNode *fuv_link;
+ float labda = 0.0f;
+
+ 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, VecLenf(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);
+ VecLerpf(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) {
+ Vec2Lerpf(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 / VecLenf(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) {
+ VecLerpf(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) {
+ Vec2Lerpf(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{
+ VecLerpf(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) {
+ Vec2Lerpf(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])
+{
+ TransData *td = t->data;
+ 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);
@@ -4029,7 +4635,6 @@ int BoneEnvelope(TransInfo *t, short mval[2])
return 1;
}
-
/* ******************** EditBone roll *************** */
void initBoneRoll(TransInfo *t)
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index e5bd405c0cd..fc31fad622a 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -32,10 +32,13 @@
#include "ED_transform.h"
+#include "BLI_editVert.h"
+
/* ************************** Types ***************************** */
struct TransInfo;
struct TransData;
+struct TransformOrientation;
struct TransSnap;
struct NumInput;
struct Object;
@@ -52,6 +55,7 @@ struct bContext;
struct wmEvent;
struct wmTimer;
struct ARegion;
+struct ReportList;
typedef struct NDofInput {
int flag;
@@ -83,6 +87,7 @@ typedef struct TransSnap {
short modeTarget;
short mode;
short align;
+ short project;
short status;
float snapPoint[3]; /* snapping from this point */
float snapTarget[3]; /* to this point */
@@ -118,20 +123,9 @@ typedef struct TransCon {
/* Apply function pointer for rotation transformation */
} TransCon;
-typedef struct TransDataIpokey {
- int flag; /* which keys */
- float *locx, *locy, *locz; /* channel pointers */
- float *rotx, *roty, *rotz;
- float *quatx, *quaty, *quatz, *quatw;
- float *sizex, *sizey, *sizez;
- float oldloc[9]; /* storage old values */
- float oldrot[9];
- float oldsize[9];
- float oldquat[12];
-} TransDataIpokey;
-
typedef struct TransDataExtension {
float drot[3]; /* Initial object drot */
+ float dquat[4]; /* Initial object dquat */
float dsize[3]; /* Initial object dsize */
float *rot; /* Rotation of the data to transform (Faculative) */
float irot[3]; /* Initial rotation */
@@ -179,6 +173,31 @@ typedef struct TransDataNla {
int handle; /* handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends */
} TransDataNla;
+struct LinkNode;
+struct EditEdge;
+struct EditVert;
+struct GHash;
+typedef struct TransDataSlideUv {
+ float origuv[2];
+ float *uv_up, *uv_down;
+ //float *fuv[4];
+ struct LinkNode *fuv_list;
+} TransDataSlideUv;
+
+typedef struct TransDataSlideVert {
+ struct EditEdge *up, *down;
+ struct EditVert origvert;
+} TransDataSlideVert;
+
+typedef struct SlideData {
+ TransDataSlideUv *slideuv, *suv_last;
+ int totuv, uvlay_tot;
+ struct GHash *vhash, **uvhash;
+ struct EditVert *nearest;
+ struct LinkNode *edgelist, *vertlist;
+ short start[2], end[2];
+} SlideData;
+
typedef struct TransData {
float dist; /* Distance needed to affect element (for Proportionnal Editing) */
float rdist; /* Distance to the nearest element (for Proportionnal Editing) */
@@ -194,12 +213,11 @@ typedef struct TransData {
struct Object *ob;
struct bConstraint *con; /* for objects/bones, the first constraint in its constraint stack */
TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */
- TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */
TransDataCurveHandleFlags *hdata; /* for curves, stores handle flags for modification/cancel */
void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */
- short flag; /* Various flags */
+ int flag; /* Various flags */
short protectflag; /* If set, copy of Object or PoseChannel protection */
- int rotOrder; /* rotation order (for eulers), as defined in BLI_arithb.h */
+ int rotOrder; /* rotation mode, as defined in eRotationModes (DNA_action_types.h) */
} TransData;
typedef struct MouseInput {
@@ -210,6 +228,7 @@ typedef struct MouseInput {
short precision_mval[2]; /* mouse position when precision key was pressed */
int center[2];
float factor;
+ void *data; /* additional data, if needed by the particular function */
} MouseInput;
typedef struct TransInfo {
@@ -263,12 +282,15 @@ typedef struct TransInfo {
struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */
void *customData; /* Per Transform custom data */
+ void (*customFree)(struct TransInfo *); /* if a special free function is needed */
/*************** NEW STUFF *********************/
short current_orientation;
short prop_mode;
+
+ short mirror;
float values[4];
float auto_values[4];
@@ -378,6 +400,7 @@ typedef struct TransInfo {
#define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */
#define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */
#define TD_INTVALUES (1 << 15) /* for Graph Editor - curves that can only have int-values need their keyframes tagged with this */
+#define TD_MIRROR_EDGE (1 << 16) /* For editmode mirror, clamp to x = 0 */
/* transsnap->status */
#define SNAP_ON 1
@@ -466,6 +489,9 @@ int BoneEnvelope(TransInfo *t, short mval[2]);
void initBoneRoll(TransInfo *t);
int BoneRoll(TransInfo *t, short mval[2]);
+void initEdgeSlide(TransInfo *t);
+int EdgeSlide(TransInfo *t, short mval[2]);
+
void initTimeTranslate(TransInfo *t);
int TimeTranslate(TransInfo *t, short mval[2]);
@@ -486,7 +512,7 @@ int Align(TransInfo *t, short mval[2]);
void drawPropCircle(const struct bContext *C, TransInfo *t);
-void transform_modal_keymap(struct wmWindowManager *wm);
+void transform_modal_keymap(struct wmKeyConfig *keyconf);
/*********************** transform_conversions.c ********** */
@@ -526,7 +552,7 @@ void drawConstraint(const struct bContext *C, TransInfo *t);
void getConstraintMatrix(TransInfo *t);
void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]);
void setLocalConstraint(TransInfo *t, int mode, const char text[]);
-void setUserConstraint(TransInfo *t, int mode, const char text[]);
+void setUserConstraint(TransInfo *t, short orientation, int mode, const char text[]);
void constraintNumInput(TransInfo *t, float vec[3]);
@@ -556,6 +582,7 @@ void snapGrid(TransInfo *t, float *val);
void snapGridAction(TransInfo *t, float *val, GearsType action);
void initSnapping(struct TransInfo *t, struct wmOperator *op);
+void applyProject(TransInfo *t);
void applySnapping(TransInfo *t, float *vec);
void resetSnapping(TransInfo *t);
int handleSnapping(TransInfo *t, struct wmEvent *event);
@@ -575,7 +602,8 @@ typedef enum {
INPUT_HORIZONTAL_RATIO,
INPUT_HORIZONTAL_ABSOLUTE,
INPUT_VERTICAL_RATIO,
- INPUT_VERTICAL_ABSOLUTE
+ INPUT_VERTICAL_ABSOLUTE,
+ INPUT_CUSTOM_RATIO
} MouseInputMode;
void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], short mval[2]);
@@ -583,6 +611,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event);
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, short mval[2], float output[3]);
+void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2]);
+
/*********************** Generics ********************************/
int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event);
@@ -640,18 +670,17 @@ int handleNDofInput(NDofInput *n, struct wmEvent *event);
void initTransformOrientation(struct bContext *C, TransInfo *t);
-int manageObjectSpace(struct bContext *C, int confirm, int set);
-int manageMeshSpace(struct bContext *C, int confirm, int set);
-int manageBoneSpace(struct bContext *C, int confirm, int set);
+struct TransformOrientation *createObjectSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite);
+struct TransformOrientation *createMeshSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite);
+struct TransformOrientation *createBoneSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite);
/* Those two fill in mat and return non-zero on success */
int createSpaceNormal(float mat[3][3], float normal[3]);
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
-int addMatrixSpace(struct bContext *C, float mat[3][3], char name[]);
+struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite);
int addObjectSpace(struct bContext *C, struct Object *ob);
-void applyTransformOrientation(const struct bContext *C, TransInfo *t);
-
+void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name);
#define ORIENTATION_NONE 0
#define ORIENTATION_NORMAL 1
@@ -663,6 +692,8 @@ int getTransformOrientation(const struct bContext *C, float normal[3], float pla
int createSpaceNormal(float mat[3][3], float normal[3]);
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
+void freeSlideVerts(TransInfo *t);
+
#endif
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 158ea98c090..1143203217b 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -551,11 +551,10 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) {
ftext is a format string passed to sprintf. It will add the name of
the orientation where %s is (logically).
*/
-void setUserConstraint(TransInfo *t, int mode, const char ftext[]) {
+void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) {
char text[40];
- //short twmode= (t->spacetype==SPACE_VIEW3D)? ((View3D*)t->view)->twmode: V3D_MANIP_GLOBAL;
- switch(t->current_orientation) {
+ switch(orientation) {
case V3D_MANIP_GLOBAL:
{
float mtx[3][3];
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 4267bd39d5e..764256c476d 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -126,7 +126,6 @@
#include "ED_object.h"
#include "ED_markers.h"
#include "ED_mesh.h"
-#include "ED_retopo.h"
#include "ED_types.h"
#include "ED_uvedit.h"
#include "ED_view3d.h"
@@ -296,7 +295,7 @@ static void createTransTexspace(bContext *C, TransInfo *t)
TransData *td;
Object *ob;
ID *id;
- int *texflag;
+ short *texflag;
ob = OBACT;
@@ -382,7 +381,6 @@ static void createTransEdge(bContext *C, TransInfo *t) {
Mat3CpyMat3(td->mtx, mtx);
td->ext = NULL;
- td->tdi = NULL;
if (t->mode == TFM_BWEIGHT) {
td->val = &(eed->bweight);
td->ival = eed->bweight;
@@ -512,8 +510,8 @@ static short apply_targetless_ik(Object *ob)
/* rotation */
if (parchan->rotmode > 0)
Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode);
- else if (parchan->rotmode == PCHAN_ROT_AXISANGLE)
- Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]);
+ else if (parchan->rotmode == ROT_MODE_AXISANGLE)
+ Mat3ToAxisAngle(rmat3, parchan->rotAxis, &pchan->rotAngle);
else
Mat3ToQuat(rmat3, parchan->quat);
@@ -522,8 +520,8 @@ static short apply_targetless_ik(Object *ob)
if (data->flag & CONSTRAINT_IK_STRETCH) {
if (parchan->rotmode > 0)
EulOToMat3(parchan->eul, parchan->rotmode, qrmat);
- else if (parchan->rotmode == PCHAN_ROT_AXISANGLE)
- AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat);
+ else if (parchan->rotmode == ROT_MODE_AXISANGLE)
+ AxisAngleToMat3(parchan->rotAxis, parchan->rotAngle, qrmat);
else
QuatToMat3(parchan->quat, qrmat);
@@ -559,10 +557,6 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ob = ob;
td->flag = TD_SELECTED;
- if (pchan->rotmode == PCHAN_ROT_QUAT)
- {
- td->flag |= TD_USEQUAT;
- }
if (bone->flag & BONE_HINGE_CHILD_TRANSFORM)
{
td->flag |= TD_NOCENTER;
@@ -587,15 +581,14 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ext->quat= NULL;
VECCOPY(td->ext->irot, pchan->eul);
- td->rotOrder= pchan->rotmode;
}
else {
td->ext->rot= NULL;
td->ext->quat= pchan->quat;
QUATCOPY(td->ext->iquat, pchan->quat);
- td->rotOrder= pchan->rotmode;
}
+ td->rotOrder= pchan->rotmode;
/* proper way to get parent transform + own transform + constraints transform */
@@ -1019,7 +1012,6 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob)
tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt");
for(i=0; i<t->total; i++, td++, tdx++) {
td->ext= tdx;
- td->tdi = NULL;
td->val = NULL;
}
@@ -1103,7 +1095,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1119,7 +1110,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1154,7 +1144,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
Mat3Ortho(td->axismtx);
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1171,7 +1160,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->flag= TD_SELECTED;
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1199,7 +1187,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
}
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td++;
@@ -1222,7 +1209,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->extra = ebo; /* to fix roll */
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td++;
@@ -1275,7 +1261,6 @@ static void createTransMBallVerts(bContext *C, TransInfo *t)
Mat3CpyMat3(td->mtx, mtx);
td->ext = tx;
- td->tdi = NULL;
/* Radius of MetaElem (mass of MetaElem influence) */
if(ml->flag & MB_SCALE_RAD){
@@ -1440,7 +1425,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
else td->flag= 0;
}
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
hdata = initTransDataCurveHandes(td, bezt);
@@ -1461,7 +1445,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
td->ext = NULL;
- td->tdi = NULL;
if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
td->val = &(bezt->radius);
@@ -1501,7 +1484,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
else td->flag= 0;
}
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
if (hdata==NULL) { /* if the handle was not saved by the previous handle */
@@ -1541,7 +1523,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
if(bp->f1 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
td->ext = NULL;
- td->tdi = NULL;
if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) {
td->val = &(bp->radius);
@@ -1617,7 +1598,6 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t)
Mat3CpyMat3(td->mtx, mtx);
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td++;
@@ -1728,7 +1708,6 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
td->ob = ob;
td->ext = tx;
- td->tdi = NULL;
if(t->mode == TFM_BAKE_TIME) {
td->val = key->time;
td->ival = *(key->time);
@@ -1951,7 +1930,6 @@ static void editmesh_set_connectivity_distance(EditMesh *em, int total, float *v
td->axismtx[1][1] =\
td->axismtx[1][2] = 0.0f;\
td->ext = NULL;\
- td->tdi = NULL;\
td->val = NULL;\
td->extra = NULL;\
if (t->mode == TFM_BWEIGHT) {\
@@ -1985,7 +1963,6 @@ inline void VertsToTransData(TransInfo *t, TransData *td, BMesh *em, BMVert *eve
td->axismtx[1][2] = 0.0f;
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td->extra = NULL;
if (t->mode == TFM_BWEIGHT) {
@@ -2298,7 +2275,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
for(a=0; eve; eve=BMIter_Step(&iter), a++) {
if(!BM_TestHFlag(eve, BM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) {
if(eve->co[0]<0.0f)
+ {
+ t->mirror = -1;
mirror = -1;
+ }
break;
}
}
@@ -2374,6 +2354,19 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
}
}
}
+
+ if (mirror != 0)
+ {
+ tob = t->data;
+ for( a = 0; a < t->total; a++, tob++ )
+ {
+ if (ABS(tob->loc[0]) <= 0.00001f)
+ {
+ tob->flag |= TD_MIRROR_EDGE;
+ }
+ }
+ }
+
if (propmode) {
MEM_freeN(vectors);
MEM_freeN(nears);
@@ -2504,7 +2497,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
if(selected) {
td->flag |= TD_SELECTED;
@@ -2804,7 +2797,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0f;
@@ -2835,7 +2828,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0f;
@@ -2987,7 +2980,7 @@ static void posttrans_fcurve_clean (FCurve *fcu)
/* Loop 1: find selected keyframes */
for (i = 0; i < fcu->totvert; i++) {
BezTriple *bezt= &fcu->bezt[i];
-
+
if (BEZSELECTED(bezt)) {
selcache[index]= bezt->vec[1][0];
index++;
@@ -2995,16 +2988,18 @@ static void posttrans_fcurve_clean (FCurve *fcu)
}
}
- /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */
- if (len) {
+ /* Loop 2: delete unselected keyframes on the same frames
+ * (if any keyframes were found, or the whole curve wasn't affected)
+ */
+ if ((len) && (len != fcu->totvert)) {
for (i = 0; i < fcu->totvert; i++) {
BezTriple *bezt= &fcu->bezt[i];
-
+
if (BEZSELECTED(bezt) == 0) {
/* check beztriple should be removed according to cache */
for (index= 0; index < len; index++) {
if (IS_EQ(bezt->vec[1][0], selcache[index])) {
- //delete_icu_key(icu, i, 0);
+ delete_fcurve_key(fcu, i, 0);
break;
}
else if (bezt->vec[1][0] > selcache[index])
@@ -3012,7 +3007,7 @@ static void posttrans_fcurve_clean (FCurve *fcu)
}
}
}
-
+
testhandles_fcurve(fcu);
}
@@ -3386,7 +3381,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
/* store AnimData info in td->extra, for applying mapping when flushing */
td->extra= adt;
@@ -3819,98 +3814,6 @@ void flushTransGraphData(TransInfo *t)
}
}
-/* **************** IpoKey stuff, for Object TransData ********** */
-
-/* while transforming */
-void add_tdi_poin(float *poin, float *old, float delta)
-{
- if(poin) {
- poin[0]= old[0]+delta;
- poin[-3]= old[3]+delta;
- poin[3]= old[6]+delta;
- }
-}
-
-#if 0 // TRANSFORM_FIX_ME
-/* storage of bezier triple. thats why -3 and +3! */
-static void set_tdi_old(float *old, float *poin)
-{
- old[0]= *(poin);
- old[3]= *(poin-3);
- old[6]= *(poin+3);
-}
-
-/* fill ipokey transdata with old vals and pointers */
-static void ipokey_to_transdata(IpoKey *ik, TransData *td)
-{
- extern int ob_ar[]; // blenkernel ipo.c
- TransDataIpokey *tdi= td->tdi;
- BezTriple *bezt;
- int a, delta= 0;
-
- td->val= NULL; // is read on ESC
-
- for(a=0; a<OB_TOTIPO; a++) {
- if(ik->data[a]) {
- bezt= ik->data[a];
-
- switch( ob_ar[a] ) {
- case OB_LOC_X:
- case OB_DLOC_X:
- tdi->locx= &(bezt->vec[1][1]); break;
- case OB_LOC_Y:
- case OB_DLOC_Y:
- tdi->locy= &(bezt->vec[1][1]); break;
- case OB_LOC_Z:
- case OB_DLOC_Z:
- tdi->locz= &(bezt->vec[1][1]); break;
-
- case OB_DROT_X:
- delta= 1;
- case OB_ROT_X:
- tdi->rotx= &(bezt->vec[1][1]); break;
- case OB_DROT_Y:
- delta= 1;
- case OB_ROT_Y:
- tdi->roty= &(bezt->vec[1][1]); break;
- case OB_DROT_Z:
- delta= 1;
- case OB_ROT_Z:
- tdi->rotz= &(bezt->vec[1][1]); break;
-
- case OB_SIZE_X:
- case OB_DSIZE_X:
- tdi->sizex= &(bezt->vec[1][1]); break;
- case OB_SIZE_Y:
- case OB_DSIZE_Y:
- tdi->sizey= &(bezt->vec[1][1]); break;
- case OB_SIZE_Z:
- case OB_DSIZE_Z:
- tdi->sizez= &(bezt->vec[1][1]); break;
- }
- }
- }
-
- /* oldvals for e.g. undo */
- if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
- if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
- if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
-
- /* remember, for mapping curves ('1'=10 degrees) */
- if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
- if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
- if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
-
- /* this is not allowed to be dsize! */
- if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
- if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
- if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
-
- tdi->flag= TOB_IPO;
- if(delta) tdi->flag |= TOB_IPODROT;
-}
-#endif
-
/* *************************** Object Transform data ******************* */
/* Little helper function for ObjectToTransData used to give certain
@@ -4128,7 +4031,7 @@ static TransData *SeqToTransData(TransInfo *t, TransData *td, TransData2D *td2d,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0;
@@ -4269,20 +4172,20 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
if (skip_invert == 0 && (ob->track || constinv==0)) {
track= ob->track;
ob->track= NULL;
-
+
if (constinv == 0) {
fakecons.first = ob->constraints.first;
fakecons.last = ob->constraints.last;
ob->constraints.first = ob->constraints.last = NULL;
}
-
+
where_is_object(t->scene, ob);
-
+
if (constinv == 0) {
ob->constraints.first = fakecons.first;
ob->constraints.last = fakecons.last;
}
-
+
ob->track= track;
}
else
@@ -4296,6 +4199,10 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
td->ext->rot = ob->rot;
VECCOPY(td->ext->irot, ob->rot);
VECCOPY(td->ext->drot, ob->drot);
+
+ td->ext->quat = ob->quat;
+ QUATCOPY(td->ext->iquat, ob->quat);
+ QUATCOPY(td->ext->dquat, ob->dquat);
td->ext->size = ob->size;
VECCOPY(td->ext->isize, ob->size);
@@ -4337,7 +4244,7 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
/* it deselects Bases, so we have to call the clear function always after */
static void set_trans_object_base_flags(bContext *C, TransInfo *t)
{
- Scene *sce = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
View3D *v3d = t->view;
/*
@@ -4354,15 +4261,15 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t)
copy_baseflags(t->scene);
/* handle pending update events, otherwise they got copied below */
- for (base= sce->base.first; base; base= base->next) {
+ for (base= scene->base.first; base; base= base->next) {
if(base->object->recalc)
object_handle_update(t->scene, base->object);
}
- for (base= sce->base.first; base; base= base->next) {
+ for (base= scene->base.first; base; base= base->next) {
base->flag &= ~BA_WAS_SEL;
- if(TESTBASELIB(v3d, base)) {
+ if(TESTBASELIB_BGMODE(v3d, base)) {
Object *ob= base->object;
Object *parsel= ob->parent;
@@ -4394,7 +4301,7 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t)
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
- for (base= sce->base.first; base; base= base->next) {
+ for (base= scene->base.first; base; base= base->next) {
if(base->object->recalc & OB_RECALC_OB)
base->flag |= BA_HAS_RECALC_OB;
if(base->object->recalc & OB_RECALC_DATA)
@@ -4426,10 +4333,16 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
// TODO: this should probably be done per channel instead...
if (autokeyframe_cfra_can_key(scene, id)) {
- AnimData *adt= ob->adt;
+ KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
+ bCommonKeySrc cks;
+ ListBase dsources = {&cks, &cks};
float cfra= (float)CFRA; // xxx this will do for now
short flag = 0;
+ /* init common-key-source for use by KeyingSets */
+ memset(&cks, 0, sizeof(bCommonKeySrc));
+ cks.id= &ob->id;
+
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
@@ -4437,7 +4350,14 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
- if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+
+ if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) {
+ /* only insert into active keyingset */
+ modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+ else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+ AnimData *adt= ob->adt;
+
/* only key on available channels */
if (adt && adt->action) {
for (fcu= adt->action->curves.first; fcu; fcu= fcu->next) {
@@ -4476,41 +4396,25 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
doScale = 1;
}
- // TODO: the group names here are temporary...
- // TODO: should this be made to use the builtin KeyingSets instead?
+ /* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
if (doLoc) {
- insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag);
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doRot) {
- insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag);
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doScale) {
- insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag);
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale");
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
}
+ /* insert keyframe in all (transform) channels */
else {
- // TODO: the group names here are temporary...
- // TODO: should this be made to use the builtin KeyingSets instead?
- insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag);
-
- insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag);
-
- insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag);
- insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag);
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
-
- // XXX todo... find a way to send notifiers from here...
}
}
@@ -4530,9 +4434,15 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
// TODO: this should probably be done per channel instead...
if (autokeyframe_cfra_can_key(scene, id)) {
+ KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
+ bCommonKeySrc cks;
+ ListBase dsources = {&cks, &cks};
float cfra= (float)CFRA;
short flag= 0;
- char buf[512];
+
+ /* init common-key-source for use by KeyingSets */
+ memset(&cks, 0, sizeof(bCommonKeySrc));
+ cks.id= &ob->id;
/* flag is initialised from UserPref keyframing settings
* - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
@@ -4551,8 +4461,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
/* clear any 'unkeyed' flag it may have */
pchan->bone->flag &= ~BONE_UNKEYED;
+ /* only insert into active keyingset? */
+ if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) {
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+ modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
/* only insert into available channels? */
- if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+ else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
if (act) {
for (fcu= act->curves.first; fcu; fcu= fcu->next)
insert_keyframe(id, act, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
@@ -4585,58 +4501,34 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
}
if (doLoc) {
- sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
+
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doRot) {
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
- sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag);
- }
- else {
- sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
- }
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
+
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doScale) {
- sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale");
+
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
}
- /* insert keyframe in any channel that's appropriate */
+ /* insert keyframe in all (transform) channels */
else {
- sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
-
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
- sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag);
- }
- else {
- sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
- }
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
- sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name);
- insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
- insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+ modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
}
}
@@ -4676,13 +4568,7 @@ void special_aftertrans_update(TransInfo *t)
if (t->spacetype==SPACE_VIEW3D) {
if (t->obedit) {
if (cancelled==0) {
-#if 0 // TRANSFORM_FIX_ME
- EM_automerge(1);
- /* when snapping, delay retopo until after automerge */
- if (G.qual & LR_CTRLKEY) {
- retopo_do_all();
- }
-#endif
+ EM_automerge(t->scene, t->obedit, 1);
}
}
}
@@ -5007,7 +4893,7 @@ void special_aftertrans_update(TransInfo *t)
// allqueue(REDRAWBUTSEDIT, 0);
}
- else if(t->scene->basact && (ob = t->scene->basact->object) && ob->mode & OB_MODE_PARTICLE_EDIT) {
+ else if(t->scene->basact && (ob = t->scene->basact->object) && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, ob)) {
;
}
else {
@@ -5030,6 +4916,7 @@ void special_aftertrans_update(TransInfo *t)
if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
pid->cache->flag |= PTCACHE_OUTDATED;
}
+ BLI_freelistN(&pidlist);
/* pointcache refresh */
if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
@@ -5076,30 +4963,7 @@ static void createTransObject(bContext *C, TransInfo *t)
set_trans_object_base_flags(C, t);
/* count */
-#if 0 // TRANSFORM_FIX_ME
- CTX_DATA_BEGIN(C, Object*, ob, selected_objects)
- {
- /* store ipo keys? */
- if ((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) {
- elems.first= elems.last= NULL;
- make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */
-
- pushdata(&elems, sizeof(ListBase));
-
- for(ik= elems.first; ik; ik= ik->next)
- t->total++;
-
- if(elems.first==NULL)
- t->total++;
- }
-// else {
- t->total++;
-// }
- }
- CTX_DATA_END;
-#else
t->total= CTX_DATA_COUNT(C, selected_objects);
-#endif
if(!t->total) {
/* clear here, main transform function escapes too */
@@ -5113,92 +4977,27 @@ static void createTransObject(bContext *C, TransInfo *t)
CTX_DATA_BEGIN(C, Base*, base, selected_bases)
{
Object *ob= base->object;
-
+
td->flag = TD_SELECTED;
td->protectflag= ob->protectflag;
td->ext = tx;
-
+ td->rotOrder= ob->rotmode;
+
if (base->flag & BA_TRANSFORM_CHILD)
{
td->flag |= TD_NOCENTER;
td->flag |= TD_NO_LOC;
}
-
+
/* select linked objects, but skip them later */
if (ob->id.lib != 0) {
td->flag |= TD_SKIP;
}
-
- /* store ipo keys? */
- // TRANSFORM_FIX_ME
-#if 0
- if((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) {
-
- popfirst(&elems); // bring back pushed listbase
-
- if(elems.first) {
- int cfraont;
- int ipoflag;
-
- base->flag |= BA_DO_IPO+BA_WAS_SEL;
- base->flag &= ~SELECT;
-
- cfraont= CFRA;
- set_no_parent_ipo(1);
- ipoflag= ob->ipoflag;
- ob->ipoflag &= ~OB_OFFS_OB;
-
- /*
- * This is really EVIL code that pushes down Object values
- * (loc, dloc, orig, size, dsize, rot, drot)
- * */
-
- pushdata((void*)ob->loc, 7 * 3 * sizeof(float)); // tsk! tsk!
-
- for(ik= elems.first; ik; ik= ik->next) {
-
- /* weak... this doesn't correct for floating values, giving small errors */
- CFRA= (int)(ik->val/t->scene->r.framelen);
-
- do_ob_ipo(ob);
- ObjectToTransData(C, t, td, ob); // does where_is_object()
-
- td->flag= TD_SELECTED;
-
- td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey");
- /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */
- ipokey_to_transdata(ik, td);
-
- td++;
- tx++;
- if(ik->next) td->ext= tx; // prevent corrupting mem!
- }
- free_ipokey(&elems);
-
- poplast(ob->loc);
- set_no_parent_ipo(0);
-
- CFRA= cfraont;
- ob->ipoflag= ipoflag;
-
- where_is_object(t->scene, ob); // restore
- }
- else {
- ObjectToTransData(C, t, td, ob);
- td->tdi = NULL;
- td->val = NULL;
- td++;
- tx++;
- }
- }
-#endif
-// else {
- ObjectToTransData(C, t, td, ob);
- td->tdi = NULL;
- td->val = NULL;
- td++;
- tx++;
-// }
+
+ ObjectToTransData(C, t, td, ob);
+ td->val = NULL;
+ td++;
+ tx++;
}
CTX_DATA_END;
}
@@ -5220,7 +5019,7 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0;
@@ -5364,7 +5163,7 @@ void createTransData(bContext *C, TransInfo *t)
{
if(ob_armature->type==OB_ARMATURE)
{
- if(ob_armature->mode & OB_MODE_POSE)
+ if((ob_armature->mode & OB_MODE_POSE) && ob_armature == modifiers_isDeformedByArmature(ob))
{
createTransPose(C, t, ob_armature);
break;
@@ -5387,6 +5186,8 @@ void createTransData(bContext *C, TransInfo *t)
}
else {
t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */
+ t->options |= CTX_NO_PET;
+
createTransObject(C, t);
t->flag |= T_OBJECT;
@@ -5394,7 +5195,7 @@ void createTransData(bContext *C, TransInfo *t)
{
View3D *v3d = t->view;
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
+ if(rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
{
t->flag |= T_CAMERA;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 36ee9b81623..66b46ab5b96 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -59,6 +59,7 @@
//#include "BIF_screen.h"
//#include "BIF_mywindow.h"
#include "BIF_gl.h"
+#include "BIF_glutil.h"
//#include "BIF_editmesh.h"
//#include "BIF_editsima.h"
//#include "BIF_editparticle.h"
@@ -92,7 +93,7 @@
#include "ED_keyframing.h"
#include "ED_markers.h"
#include "ED_mesh.h"
-#include "ED_retopo.h"
+#include "ED_particle.h"
#include "ED_screen_types.h"
#include "ED_space_api.h"
#include "ED_uvedit.h"
@@ -265,8 +266,13 @@ static void editbmesh_apply_to_mirror(TransInfo *t)
eve->co[1]= td->loc[1];
eve->co[2]= td->loc[2];
}
+
+ if (td->flag & TD_MIRROR_EDGE)
+ {
+ td->loc[0] = 0;
}
}
+}
/* tags the given ID block for refreshes (if applicable) due to
* Animation Editor editing
@@ -348,7 +354,7 @@ void recalcData(TransInfo *t)
if (t->obedit) {
}
- else if(base && base->object->mode & OB_MODE_PARTICLE_EDIT) {
+ else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(scene, base->object)) {
flushTransParticles(t);
}
if (t->spacetype==SPACE_NODE) {
@@ -618,13 +624,31 @@ void recalcData(TransInfo *t)
}
}
}
- else if (t->obedit) {
+ else if (t->spacetype == SPACE_IMAGE) {
+ if (t->obedit && t->obedit->type == OB_MESH) {
+ SpaceImage *sima= t->sa->spacedata.first;
+
+ flushTransUVs(t);
+ if(sima->flag & SI_LIVE_UNWRAP)
+ ED_uvedit_live_unwrap_re_solve();
+
+ DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
+ }
+ }
+ else if (t->spacetype == SPACE_VIEW3D) {
+
+ /* project */
+ if(t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+
+ if (t->obedit) {
if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
Curve *cu= t->obedit->data;
Nurb *nu= cu->editnurb->first;
-
+
DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
-
+
if (t->state == TRANS_CANCEL) {
while(nu) {
calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
@@ -637,8 +661,6 @@ void recalcData(TransInfo *t)
calchandlesNurb(nu);
nu= nu->next;
}
- /* TRANSFORM_FIX_ME */
- // retopo_do_all();
}
}
else if(t->obedit->type==OB_LATTICE) {
@@ -648,23 +670,9 @@ void recalcData(TransInfo *t)
if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt);
}
else if (t->obedit->type == OB_MESH) {
- if(t->spacetype==SPACE_IMAGE) {
- SpaceImage *sima= t->sa->spacedata.first;
-
- flushTransUVs(t);
- if(sima->flag & SI_LIVE_UNWRAP)
- ED_uvedit_live_unwrap_re_solve();
-
- DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
- } else {
BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh;
/* mirror modifier clipping? */
if(t->state != TRANS_CANCEL) {
- /* TRANSFORM_FIX_ME */
-// if ((G.qual & LR_CTRLKEY)==0) {
-// /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */
-// retopo_do_all();
-// }
clipMirrorModifier(t, t->obedit);
}
if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
@@ -675,17 +683,16 @@ void recalcData(TransInfo *t)
EDBM_RecalcNormals(em);
BMEdit_RecalcTesselation(em);
}
- }
else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */
bArmature *arm= t->obedit->data;
ListBase *edbo = arm->edbo;
EditBone *ebo;
TransData *td = t->data;
int i;
-
+
/* Ensure all bones are correctly adjusted */
for (ebo = edbo->first; ebo; ebo = ebo->next){
-
+
if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
/* If this bone has a parent tip that has been moved */
if (ebo->parent->flag & BONE_TIPSEL){
@@ -698,7 +705,7 @@ void recalcData(TransInfo *t)
if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head;
}
}
-
+
/* on extrude bones, oldlength==0.0f, so we scale radius of points */
ebo->length= VecLenf(ebo->head, ebo->tail);
if(ebo->oldlength==0.0f) {
@@ -718,8 +725,8 @@ void recalcData(TransInfo *t)
ebo->oldlength= ebo->length;
}
}
-
-
+
+
if (t->mode != TFM_BONE_ROLL)
{
/* fix roll */
@@ -729,10 +736,10 @@ void recalcData(TransInfo *t)
{
float vec[3], up_axis[3];
float qrot[4];
-
+
ebo = td->extra;
VECCOPY(up_axis, td->axismtx[2]);
-
+
if (t->mode != TFM_ROTATION)
{
VecSubf(vec, ebo->tail, ebo->head);
@@ -744,15 +751,15 @@ void recalcData(TransInfo *t)
{
Mat3MulVecfl(t->mat, up_axis);
}
-
+
ebo->roll = ED_rollBoneToVector(ebo, up_axis);
}
}
}
-
+
if(arm->flag & ARM_MIRROR_EDIT)
transform_armature_mirror_update(t->obedit);
-
+
}
else
DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
@@ -760,7 +767,7 @@ void recalcData(TransInfo *t)
else if( (t->flag & T_POSE) && t->poseobj) {
Object *ob= t->poseobj;
bArmature *arm= ob->data;
-
+
/* if animtimer is running, and the object already has animation data,
* check if the auto-record feature means that we should record 'samples'
* (i.e. uneditable animation values)
@@ -772,7 +779,7 @@ void recalcData(TransInfo *t)
animrecord_check_state(t->scene, &ob->id, t->animtimer);
autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
}
-
+
/* old optimize trick... this enforces to bypass the depgraph */
if (!(arm->flag & ARM_DELAYDEFORM)) {
DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
@@ -783,13 +790,13 @@ void recalcData(TransInfo *t)
else {
for(base= FIRSTBASE; base; base= base->next) {
Object *ob= base->object;
-
+
/* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
if(base->flag & BA_HAS_RECALC_OB)
ob->recalc |= OB_RECALC_OB;
if(base->flag & BA_HAS_RECALC_DATA)
ob->recalc |= OB_RECALC_DATA;
-
+
/* if object/base is selected */
if ((base->flag & SELECT) || (ob->flag & SELECT)) {
/* if animtimer is running, and the object already has animation data,
@@ -802,7 +809,7 @@ void recalcData(TransInfo *t)
autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode);
}
}
-
+
/* proxy exception */
if(ob->proxy)
ob->proxy->recalc |= ob->recalc;
@@ -810,11 +817,11 @@ void recalcData(TransInfo *t)
group_tag_recalc(ob->proxy_group->dup_group);
}
}
-
- /* update shaded drawmode while transform */
- if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED)
+
+ if(((View3D*)t->view)->drawtype == OB_SHADED)
reshadeall_displist(t->scene);
}
+}
void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
{
@@ -936,7 +943,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
t->around = v3d->around;
- if (op && RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_orientation"))
+ if (op && RNA_struct_find_property(op->ptr, "constraint_orientation") && RNA_property_is_set(op->ptr, "constraint_orientation"))
{
t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation");
@@ -970,20 +977,24 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
if (RNA_boolean_get(op->ptr, "mirror"))
{
t->flag |= T_MIRROR;
+ t->mirror = 1;
}
}
// Need stuff to take it from edit mesh or whatnot here
else
{
- if (t->obedit && t->obedit->type == OB_MESH && ts->editbutflag & B_MESH_X_MIRROR)
+ if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X))
{
t->flag |= T_MIRROR;
+ t->mirror = 1;
}
}
- /* setting PET flag */
- if (op && RNA_struct_find_property(op->ptr, "proportional") && RNA_property_is_set(op->ptr, "proportional"))
+ /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
+ if (op && RNA_struct_find_property(op->ptr, "proportional"))
{
+ if (RNA_property_is_set(op->ptr, "proportional"))
+ {
switch(RNA_enum_get(op->ptr, "proportional"))
{
case 2: /* XXX connected constant */
@@ -995,10 +1006,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
}
else
{
- if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) {
+ if ((t->options & CTX_NO_PET) == 0 && (ts->proportional != PROP_EDIT_OFF)) {
t->flag |= T_PROP_EDIT;
- if(ts->proportional == 2)
+ if(ts->proportional == PROP_EDIT_CONNECTED)
t->flag |= T_PROP_CONNECTED; // yes i know, has to become define
}
}
@@ -1012,6 +1023,13 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->prop_size = ts->proportional_size;
}
+
+ /* TRANSFORM_FIX_ME rna restrictions */
+ if (t->prop_size <= 0)
+ {
+ t->prop_size = 1.0f;
+ }
+
if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
{
t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff");
@@ -1020,13 +1038,13 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
{
t->prop_mode = ts->prop_mode;
}
-
- /* TRANSFORM_FIX_ME rna restrictions */
- if (t->prop_size <= 0)
+ }
+ else /* add not pet option to context when not available */
{
- t->prop_size = 1.0f;
+ t->options |= CTX_NO_PET;
}
+
setTransformViewMatrices(t);
initNumInput(&t->num);
initNDofInput(&t->ndof);
@@ -1050,8 +1068,8 @@ void postTrans (TransInfo *t)
/* since ipokeys are optional on objects, we mallocced them per trans-data */
for(a=0, td= t->data; a<t->total; a++, td++) {
- if(td->tdi) MEM_freeN(td->tdi);
- if (td->flag & TD_BEZTRIPLE) MEM_freeN(td->hdata);
+ if (td->flag & TD_BEZTRIPLE)
+ MEM_freeN(td->hdata);
}
MEM_freeN(t->data);
}
@@ -1067,8 +1085,16 @@ void postTrans (TransInfo *t)
if(sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
}
- else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) {
- if (t->customData)
+
+ if (t->mouse.data)
+ {
+ MEM_freeN(t->mouse.data);
+ }
+
+ if (t->customFree) {
+ t->customFree(t);
+ }
+ else if (t->customData) {
MEM_freeN(t->customData);
}}
@@ -1088,16 +1114,6 @@ void applyTransObjects(TransInfo *t)
recalcData(t);
}
-/* helper for below */
-static void restore_ipokey(float *poin, float *old)
-{
- if(poin) {
- poin[0]= old[0];
- poin[-3]= old[3];
- poin[3]= old[6];
- }
-}
-
static void restoreElement(TransData *td) {
/* TransData for crease has no loc */
if (td->loc) {
@@ -1113,34 +1129,16 @@ static void restoreElement(TransData *td) {
if (td->ext->size) {
VECCOPY(td->ext->size, td->ext->isize);
}
- if(td->flag & TD_USEQUAT) {
if (td->ext->quat) {
QUATCOPY(td->ext->quat, td->ext->iquat);
}
}
- }
if (td->flag & TD_BEZTRIPLE) {
*(td->hdata->h1) = td->hdata->ih1;
*(td->hdata->h2) = td->hdata->ih2;
}
-
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
-
- restore_ipokey(tdi->locx, tdi->oldloc);
- restore_ipokey(tdi->locy, tdi->oldloc+1);
- restore_ipokey(tdi->locz, tdi->oldloc+2);
-
- restore_ipokey(tdi->rotx, tdi->oldrot);
- restore_ipokey(tdi->roty, tdi->oldrot+1);
- restore_ipokey(tdi->rotz, tdi->oldrot+2);
-
- restore_ipokey(tdi->sizex, tdi->oldsize);
- restore_ipokey(tdi->sizey, tdi->oldsize+1);
- restore_ipokey(tdi->sizez, tdi->oldsize+2);
}
-}
void restoreTransObjects(TransInfo *t)
{
@@ -1322,7 +1320,7 @@ void calculateCenter(TransInfo *t)
Mat4MulVecfl(ob->obmat, t->con.center);
}
- /* voor panning from cameraview */
+ /* for panning from cameraview */
if(t->flag & T_OBJECT)
{
if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW)
@@ -1384,6 +1382,12 @@ void calculatePropRatio(TransInfo *t)
if (td->flag & TD_SELECTED) {
td->factor = 1.0f;
}
+ else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f)
+ {
+ td->flag |= TD_SKIP;
+ td->factor = 0.0f;
+ restoreElement(td);
+ }
else if ((connected &&
(td->flag & TD_NOTCONNECTED || td->dist > t->prop_size))
||
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 6bd0a8c8d42..83d4a314057 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -34,7 +34,7 @@
#include "transform.h"
-
+#include "MEM_guardedalloc.h"
/* ************************** INPUT FROM MOUSE *************************** */
@@ -163,6 +163,47 @@ void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float ou
output[0] = Inpf(t->viewinv[1], vec) * 2.0f;
}
+void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2])
+{
+ short *data = mi->data;
+
+ data[0] = start[0];
+ data[1] = start[1];
+ data[2] = end[0];
+ data[3] = end[1];
+}
+
+void InputCustomRatio(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ float length;
+ float distance;
+ short *data = mi->data;
+ short dx, dy;
+
+ dx = data[2] - data[0];
+ dy = data[3] - data[1];
+
+ length = (float)sqrtf(dx*dx + dy*dy);
+
+ if (mi->precision) {
+ /* deal with Shift key by adding motion / 10 to motion before shift press */
+ short mdx, mdy;
+ mdx = (mi->precision_mval[0] + (float)(mval[0] - mi->precision_mval[0]) / 10.0f) - data[2];
+ mdy = (mi->precision_mval[1] + (float)(mval[1] - mi->precision_mval[1]) / 10.0f) - data[3];
+
+ distance = (mdx*dx + mdy*dy) / length;
+ }
+ else {
+ short mdx, mdy;
+ mdx = mval[0] - data[2];
+ mdy = mval[1] - data[3];
+
+ distance = (mdx*dx + mdy*dy) / length;
+ }
+
+ output[0] = distance / length;
+}
+
void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
{
double dx2 = mval[0] - mi->center[0];
@@ -291,6 +332,11 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
mi->apply = InputVerticalAbsolute;
t->helpline = HLP_VARROW;
break;
+ case INPUT_CUSTOM_RATIO:
+ mi->apply = InputCustomRatio;
+ t->helpline = HLP_NONE;
+ mi->data = MEM_callocN(sizeof(short) * 4, "custom points");
+ break;
case INPUT_NONE:
default:
mi->apply = NULL;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 664627f1e15..19881c7bc5b 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -415,6 +415,9 @@ int calc_manipulator_stats(const bContext *C)
if(ob && totsel) {
switch(v3d->twmode) {
+
+ case V3D_MANIP_GLOBAL:
+ break; /* nothing to do */
case V3D_MANIP_NORMAL:
if(obedit || ob->mode & OB_MODE_POSE) {
@@ -476,8 +479,12 @@ int calc_manipulator_stats(const bContext *C)
}
break;
default: /* V3D_MANIP_CUSTOM */
- // XXX applyTransformOrientation(C, t);
- break;
+ {
+ float mat[3][3];
+ applyTransformOrientation(C, mat, NULL);
+ Mat4CpyMat3(rv3d->twmat, mat);
+ break;
+ }
}
}
@@ -1605,7 +1612,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
break;
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr);
}
else if (drawflags & MAN_SCALE_C) {
switch(drawflags) {
@@ -1635,10 +1642,10 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
break;
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_resize", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr);
}
else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */
- WM_operator_name_call(C, "TFM_OT_trackball", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_trackball", WM_OP_INVOKE_DEFAULT, op->ptr);
}
else if (drawflags & MAN_ROT_C) {
switch(drawflags) {
@@ -1653,7 +1660,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
break;
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_rotate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr);
}
}
/* after transform, restore drawflags */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 758b89d2e92..fe8e5b34b54 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -55,40 +55,6 @@ typedef struct TransformModeItem
static float VecOne[3] = {1, 1, 1};
-/* need constants for this */
-EnumPropertyItem proportional_mode_types[] = {
- {0, "OFF", 0, "Off", ""},
- {1, "ON", 0, "On", ""},
- {2, "CONNECTED", 0, "Connected", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
-EnumPropertyItem snap_mode_types[] = {
- {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", ""},
- {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", ""},
- {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", ""},
- {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
-EnumPropertyItem proportional_falloff_types[] = {
- {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""},
- {PROP_SPHERE, "SPHERE", 0, "Sphere", ""},
- {PROP_ROOT, "ROOT", 0, "Root", ""},
- {PROP_SHARP, "SHARP", 0, "Sharp", ""},
- {PROP_LIN, "LINEAR", 0, "Linear", ""},
- {PROP_CONST, "CONSTANT", 0, "Constant", ""},
- {PROP_RANDOM, "RANDOM", 0, "Random", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
-EnumPropertyItem orientation_items[]= {
- {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""},
- {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""},
- {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""},
- {V3D_MANIP_VIEW, "VIEW", 0, "View", ""},
- {0, NULL, 0, NULL, NULL}};
-
char OP_TRANSLATION[] = "TFM_OT_translate";
char OP_ROTATION[] = "TFM_OT_rotate";
char OP_TOSPHERE[] = "TFM_OT_tosphere";
@@ -99,6 +65,7 @@ char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten";
char OP_TILT[] = "TFM_OT_tilt";
char OP_TRACKBALL[] = "TFM_OT_trackball";
char OP_MIRROR[] = "TFM_OT_mirror";
+char OP_EDGE_SLIDE[] = "TFM_OT_edge_slide";
TransformModeItem transform_modes[] =
@@ -113,6 +80,7 @@ TransformModeItem transform_modes[] =
{OP_TILT, TFM_TILT},
{OP_TRACKBALL, TFM_TRACKBALL},
{OP_MIRROR, TFM_MIRROR},
+ {OP_EDGE_SLIDE, TFM_EDGE_SLIDE},
{NULL, 0}
};
@@ -121,6 +89,8 @@ static int select_orientation_exec(bContext *C, wmOperator *op)
int orientation = RNA_enum_get(op->ptr, "orientation");
BIF_selectTransformOrientationValue(C, orientation);
+
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
return OPERATOR_FINISHED;
}
@@ -138,28 +108,111 @@ static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event
return OPERATOR_CANCELLED;
}
-static EnumPropertyItem *select_orientation_itemf(bContext *C, PointerRNA *ptr, int *free)
-{
- *free= 1;
- return BIF_enumTransformOrientation(C);
-}
-
void TFM_OT_select_orientation(struct wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Select Orientation";
- ot->description= "Select orientation type.";
+ ot->description= "Select transformation orientation.";
ot->idname = "TFM_OT_select_orientation";
+ ot->flag = OPTYPE_UNDO;
/* api callbacks */
ot->invoke = select_orientation_invoke;
ot->exec = select_orientation_exec;
ot->poll = ED_operator_areaactive;
- prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN");
- RNA_def_enum_funcs(prop, select_orientation_itemf);
+ prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation.");
+ RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
+}
+
+
+static int delete_orientation_exec(bContext *C, wmOperator *op)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+
+ BIF_removeTransformOrientationIndex(C, selected_index);
+
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return delete_orientation_exec(C, op);
+}
+
+static int delete_orientation_poll(bContext *C)
+{
+ int selected_index = -1;
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (ED_operator_areaactive(C) == 0)
+ return 0;
+
+
+ if(v3d) {
+ selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+ }
+
+ return selected_index >= 0;
+}
+
+void TFM_OT_delete_orientation(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Delete Orientation";
+ ot->description= "Delete transformation orientation.";
+ ot->idname = "TFM_OT_delete_orientation";
+ ot->flag = OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = delete_orientation_invoke;
+ ot->exec = delete_orientation_exec;
+ ot->poll = delete_orientation_poll;
+}
+
+static int create_orientation_exec(bContext *C, wmOperator *op)
+{
+ char name[36];
+ int use = RNA_boolean_get(op->ptr, "use");
+ int overwrite = RNA_boolean_get(op->ptr, "overwrite");
+
+ RNA_string_get(op->ptr, "name", name);
+
+ BIF_createTransformOrientation(C, op->reports, name, use, overwrite);
+
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return create_orientation_exec(C, op);
+}
+
+void TFM_OT_create_orientation(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Create Orientation";
+ ot->description= "Create transformation orientation from selection.";
+ ot->idname = "TFM_OT_create_orientation";
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = create_orientation_invoke;
+ ot->exec = create_orientation_exec;
+ ot->poll = ED_operator_areaactive;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_string(ot->srna, "name", "", 35, "Name", "Text to insert at the cursor position.");
+ RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation");
+ RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name");
}
static void transformops_exit(bContext *C, wmOperator *op)
@@ -270,7 +323,7 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
TransInfo *t = op->customdata;
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
t->flag |= T_MODAL; // XXX meh maybe somewhere else
@@ -280,15 +333,15 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
void Properties_Proportional(struct wmOperatorType *ot)
{
- RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Editing", "");
- RNA_def_enum(ot->srna, "proportional_editing_falloff", prop_mode_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
+ RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", "");
+ RNA_def_enum(ot->srna, "proportional_editing_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
}
void Properties_Snapping(struct wmOperatorType *ot, short align)
{
RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", "");
- RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", "");
+ RNA_def_enum(ot->srna, "snap_mode", snap_mode_items, 0, "Mode", "");
RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
if (align)
@@ -303,8 +356,9 @@ void Properties_Constraints(struct wmOperatorType *ot)
PropertyRNA *prop;
RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
- prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN");
- RNA_def_enum_funcs(prop, select_orientation_itemf);
+ prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation.");
+ RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
}
void TFM_OT_translate(struct wmOperatorType *ot)
@@ -523,7 +577,7 @@ void TFM_OT_tosphere(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_areaactive;
- RNA_def_float_percentage(ot->srna, "value", 0, 0, 1, "Percentage", "", 0, 1);
+ RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
Properties_Proportional(ot);
@@ -549,6 +603,26 @@ void TFM_OT_mirror(struct wmOperatorType *ot)
Properties_Constraints(ot);
}
+void TFM_OT_edge_slide(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edge Slide";
+ ot->description= "Slide an edge loop along a mesh.";
+ ot->idname = OP_EDGE_SLIDE;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh;
+
+ RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
+}
+
void TFM_OT_transform(struct wmOperatorType *ot)
{
static EnumPropertyItem transform_mode_types[] = {
@@ -578,6 +652,7 @@ void TFM_OT_transform(struct wmOperatorType *ot)
{TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
{TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
{TFM_ALIGN, "ALIGN", 0, "Align", ""},
+ {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -617,16 +692,19 @@ void transform_operatortypes(void)
WM_operatortype_append(TFM_OT_tilt);
WM_operatortype_append(TFM_OT_trackball);
WM_operatortype_append(TFM_OT_mirror);
+ WM_operatortype_append(TFM_OT_edge_slide);
WM_operatortype_append(TFM_OT_select_orientation);
+ WM_operatortype_append(TFM_OT_create_orientation);
+ WM_operatortype_append(TFM_OT_delete_orientation);
}
-void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid)
+void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int spaceid)
{
- wmKeymapItem *km;
+ wmKeyMapItem *km;
/* transform.c, only adds modal map once, checks if it's there */
- transform_modal_keymap(wm);
+ transform_modal_keymap(keyconf);
switch(spaceid)
{
@@ -651,6 +729,11 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
+ km = WM_keymap_add_item(keymap, "TFM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ RNA_boolean_set(km->ptr, "use", 1);
+
+ km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
+
break;
case SPACE_ACTION:
km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
@@ -721,7 +804,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, 0, 0);
+ km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
break;
default:
break;
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index e73afa919b3..bad744d101b 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -23,6 +23,7 @@
*/
#include <string.h>
+#include <ctype.h>
#include "MEM_guardedalloc.h"
@@ -44,6 +45,7 @@
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_tessmesh.h"
+#include "BKE_report.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -68,108 +70,131 @@
void BIF_clearTransformOrientation(bContext *C)
{
+ View3D *v3d = CTX_wm_view3d(C);
+
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
BLI_freelistN(transform_spaces);
- // TRANSFORM_FIX_ME
// Need to loop over all view3d
-// if (G.vd->twmode >= V3D_MANIP_CUSTOM)
-// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ if(v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
+ v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+}
}
-void BIF_manageTransformOrientation(bContext *C, int confirm, int set) {
+TransformOrientation* findOrientationName(bContext *C, char *name)
+{
+ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
+ TransformOrientation *ts= NULL;
+
+ for (ts = transform_spaces->first; ts; ts = ts->next) {
+ if (strncmp(ts->name, name, 35) == 0) {
+ return ts;
+ }
+ }
+
+ return NULL;
+}
+
+void uniqueOrientationName(bContext *C, char *name)
+{
+ if (findOrientationName(C, name) != NULL)
+ {
+ char tempname[64];
+ int number;
+ char *dot;
+
+
+ number = strlen(name);
+
+ if (number && isdigit(name[number-1]))
+ {
+ dot = strrchr(name, '.'); // last occurrence
+ if (dot)
+ *dot=0;
+ }
+
+ for (number = 1; number <= 999; number++)
+ {
+ sprintf(tempname, "%s.%03d", name, number);
+ if (findOrientationName(C, tempname) == NULL)
+ {
+ BLI_strncpy(name, tempname, 32);
+ break;
+ }
+ }
+ }
+}
+
+void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use, int overwrite)
+{
Object *obedit = CTX_data_edit_object(C);
Object *ob = CTX_data_active_object(C);
- int index = -1;
+ TransformOrientation *ts = NULL;
if (obedit) {
if (obedit->type == OB_MESH)
- index = manageMeshSpace(C, confirm, set);
+ ts = createMeshSpace(C, reports, name, overwrite);
else if (obedit->type == OB_ARMATURE)
- index = manageBoneSpace(C, confirm, set);
+ ts = createBoneSpace(C, reports, name, overwrite);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- index = manageBoneSpace(C, confirm, set);
+ ts = createBoneSpace(C, reports, name, overwrite);
}
else {
- index = manageObjectSpace(C, confirm, set);
+ ts = createObjectSpace(C, reports, name, overwrite);
}
- if (set && index != -1)
+ if (use && ts != NULL)
{
- BIF_selectTransformOrientationValue(C, V3D_MANIP_CUSTOM + index);
+ BIF_selectTransformOrientation(C, ts);
}
}
-int manageObjectSpace(bContext *C, int confirm, int set) {
+TransformOrientation *createObjectSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
Base *base = CTX_data_active_base(C);
+ Object *ob;
+ float mat[3][3];
if (base == NULL)
- return -1;
-
-//XXX if (confirm == 0) {
-// if (set && pupmenu("Custom Orientation %t|Add and Use Active Object%x1") != 1) {
-// return -1;
-// }
-// else if (set == 0 && pupmenu("Custom Orientation %t|Add Active Object%x1") != 1) {
-// return -1;
-// }
-// }
-
- return addObjectSpace(C, base->object);
-}
+ return NULL;
+
+
+ ob = base->object;
+
+ Mat3CpyMat4(mat, ob->obmat);
+ Mat3Ortho(mat);
-/* return 1 on confirm */
-int confirmSpace(int set, char text[])
+ /* use object name if no name is given */
+ if (name[0] == 0)
{
- char menu[64];
-
- if (set) {
- sprintf(menu, "Custom Orientation %%t|Add and Use %s%%x1", text);
- }
- else {
- sprintf(menu, "Custom Orientation %%t|Add %s%%x1", text);
+ strncpy(name, ob->id.name+2, 35);
}
-//XXX if (pupmenu(menu) == 1) {
- return 1;
-// }
-// else {
-// return 0;
-// }
+ return addMatrixSpace(C, mat, name, overwrite);
}
-int manageBoneSpace(bContext *C, int confirm, int set) {
+TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
float mat[3][3];
float normal[3], plane[3];
- char name[36] = "";
- int index;
getTransformOrientation(C, normal, plane, 0);
- if (confirm == 0 && confirmSpace(set, "Bone") == 0) {
- return -1;
- }
-
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
-//XXX error("Cannot use zero-length bone");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use zero-length bone");
+ return NULL;
}
+ if (name[0] == 0)
+ {
strcpy(name, "Bone");
+ }
- /* Input name */
-//XXX sbutton(name, 1, 35, "name: ");
-
- index = addMatrixSpace(C, mat, name);
- return index;
+ return addMatrixSpace(C, mat, name, overwrite);
}
-int manageMeshSpace(bContext *C, int confirm, int set) {
+TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
float mat[3][3];
float normal[3], plane[3];
- char name[36] = "";
- int index;
int type;
type = getTransformOrientation(C, normal, plane, 0);
@@ -177,51 +202,44 @@ int manageMeshSpace(bContext *C, int confirm, int set) {
switch (type)
{
case ORIENTATION_VERT:
- if (confirm == 0 && confirmSpace(set, "vertex") == 0) {
- return -1;
- }
-
if (createSpaceNormal(mat, normal) == 0) {
-// XXX error("Cannot use vertex with zero-length normal");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use vertex with zero-length normal");
+ return NULL;
}
+ if (name[0] == 0)
+ {
strcpy(name, "Vertex");
+ }
break;
case ORIENTATION_EDGE:
- if (confirm == 0 && confirmSpace(set, "Edge") == 0) {
- return -1;
- }
-
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
-// XXX error("Cannot use zero-length edge");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use zero-length edge");
+ return NULL;
}
+ if (name[0] == 0)
+ {
strcpy(name, "Edge");
+ }
break;
case ORIENTATION_FACE:
- if (confirm == 0 && confirmSpace(set, "Face") == 0) {
- return -1;
- }
-
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
-// XXX error("Cannot use zero-area face");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use zero-area face");
+ return NULL;
}
+ if (name[0] == 0)
+ {
strcpy(name, "Face");
+ }
break;
default:
- return -1;
+ return NULL;
break;
}
- /* Input name */
-//XXX sbutton(name, 1, 35, "name: ");
-
- index = addMatrixSpace(C, mat, name);
- return index;
+ return addMatrixSpace(C, mat, name, overwrite);
}
int createSpaceNormal(float mat[3][3], float normal[3])
@@ -272,32 +290,17 @@ int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3])
return 1;
}
-
-int addObjectSpace(bContext *C, Object *ob) {
- float mat[3][3];
- char name[36] = "";
-
- Mat3CpyMat4(mat, ob->obmat);
- Mat3Ortho(mat);
-
- strncpy(name, ob->id.name+2, 35);
-
- /* Input name */
-//XXX sbutton(name, 1, 35, "name: ");
-
- return addMatrixSpace(C, mat, name);
-}
-
-int addMatrixSpace(bContext *C, float mat[3][3], char name[]) {
+TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) {
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
- TransformOrientation *ts;
- int index = 0;
+ TransformOrientation *ts = NULL;
- /* if name is found in list, reuse that transform space */
- for (index = 0, ts = transform_spaces->first; ts; ts = ts->next, index++) {
- if (strncmp(ts->name, name, 35) == 0) {
- break;
+ if (overwrite)
+ {
+ ts = findOrientationName(C, name);
}
+ else
+ {
+ uniqueOrientationName(C, name);
}
/* if not, create a new one */
@@ -311,31 +314,61 @@ int addMatrixSpace(bContext *C, float mat[3][3], char name[]) {
/* copy matrix into transform space */
Mat3CpyMat3(ts->mat, mat);
- ED_undo_push(C, "Add/Update Transform Orientation");
-
- return index;
+ return ts;
}
void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) {
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
TransformOrientation *ts = transform_spaces->first;
- //int selected_index = (G.vd->twmode - V3D_MANIP_CUSTOM);
int i;
for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
if (ts == target) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if(v3d) {
+ int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+
// Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
-// if (selected_index == i) {
-// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
-// }
-// else if (selected_index > i)
-// G.vd->twmode--;
+ if (selected_index == i) {
+ v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ }
+ else if (selected_index > i) {
+ v3d->twmode--;
+ }
+
+ }
+
+ BLI_freelinkN(transform_spaces, ts);
+ break;
+ }
+ }
+}
+
+void BIF_removeTransformOrientationIndex(bContext *C, int index) {
+ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
+ TransformOrientation *ts = transform_spaces->first;
+ int i;
+
+ for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
+ if (i == index) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if(v3d) {
+ int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+
+ // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
+ if (selected_index == i) {
+ v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ }
+ else if (selected_index > i) {
+ v3d->twmode--;
+ }
+
+ }
BLI_freelinkN(transform_spaces, ts);
break;
}
}
- ED_undo_push(C, "Remove Transform Orientation");
}
void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) {
@@ -354,6 +387,7 @@ void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) {
void BIF_selectTransformOrientationValue(bContext *C, int orientation) {
View3D *v3d = CTX_wm_view3d(C);
+ if(v3d) /* currently using generic poll */
v3d->twmode = orientation;
}
@@ -433,7 +467,7 @@ int BIF_countTransformOrientation(const bContext *C) {
return count;
}
-void applyTransformOrientation(const bContext *C, TransInfo *t) {
+void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) {
TransformOrientation *ts;
View3D *v3d = CTX_wm_view3d(C);
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
@@ -442,8 +476,11 @@ void applyTransformOrientation(const bContext *C, TransInfo *t) {
if (selected_index >= 0) {
for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) {
if (selected_index == i) {
- strcpy(t->spacename, ts->name);
- Mat3CpyMat3(t->spacemtx, ts->mat);
+
+ if (name)
+ strcpy(name, ts->name);
+
+ Mat3CpyMat3(mat, ts->mat);
break;
}
}
@@ -558,7 +595,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
}
break;
default: /* V3D_MANIP_CUSTOM */
- applyTransformOrientation(C, t);
+ applyTransformOrientation(C, t->spacemtx, t->spacename);
break;
}
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 575e8f2150a..a2a7577c8d6 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -117,7 +117,7 @@ int BIF_snappingSupported(Object *obedit)
{
int status = 0;
- if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE)) /* only support object mesh or armature */
+ if (obedit == NULL || ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) /* only support object mesh, armature, curves */
{
status = 1;
}
@@ -219,8 +219,69 @@ int handleSnapping(TransInfo *t, wmEvent *event)
return status;
}
+void applyProject(TransInfo *t)
+{
+ /* XXX FLICKER IN OBJECT MODE */
+ if ((t->tsnap.project) && (t->tsnap.status & SNAP_ON) && (t->modifiers & MOD_SNAP_GEARS))
+ {
+ TransData *td = t->data;
+ float tvec[3];
+ float imat[4][4];
+ int i;
+
+ if(t->flag & (T_EDIT|T_POSE)) {
+ Object *ob = t->obedit?t->obedit:t->poseobj;
+ Mat4Invert(imat, ob->obmat);
+ }
+
+ for(i = 0 ; i < t->total; i++, td++) {
+ float iloc[3], loc[3], no[3];
+ float mval[2];
+ int dist = 1000;
+
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ VECCOPY(iloc, td->loc);
+ if (t->flag & (T_EDIT|T_POSE))
+ {
+ Object *ob = t->obedit?t->obedit:t->poseobj;
+ Mat4MulVecfl(ob->obmat, iloc);
+ }
+ else if (t->flag & T_OBJECT)
+ {
+ VECCOPY(iloc, td->ob->obmat[3]);
+ }
+
+ project_float(t->ar, iloc, mval);
+
+ if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode))
+ {
+// if(t->flag & (T_EDIT|T_POSE)) {
+// Mat4MulVecfl(imat, loc);
+// }
+//
+ VecSubf(tvec, loc, iloc);
+
+ Mat3MulVecfl(td->smtx, tvec);
+
+ VecAddf(td->loc, td->loc, tvec);
+ }
+
+ //XXX constraintTransLim(t, td);
+ }
+ }
+}
+
void applySnapping(TransInfo *t, float *vec)
{
+ /* project is not applied this way */
+ if (t->tsnap.project)
+ return;
+
if (t->tsnap.status & SNAP_FORCED)
{
t->tsnap.targetSnap(t);
@@ -307,12 +368,24 @@ void initSnapping(TransInfo *t, wmOperator *op)
RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal);
Normalize(t->tsnap.snapNormal);
}
+
+ if (RNA_struct_find_property(op->ptr, "snap_project"))
+ {
+ t->tsnap.project = RNA_boolean_get(op->ptr, "snap_project");
}
}
+ }
else
{
snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP);
t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+ t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+ }
+
+ /* force project off when not supported */
+ if (ts->snap_mode != SCE_SNAP_MODE_FACE)
+ {
+ t->tsnap.project = 0;
}
if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
@@ -322,7 +395,7 @@ void initSnapping(TransInfo *t, wmOperator *op)
/* Edit mode */
if (t->tsnap.applySnap != NULL && // A snapping function actually exist
(snapping) && // Only if the snap flag is on
- (obedit != NULL && ELEM(obedit->type, OB_MESH, OB_ARMATURE)) ) // Temporary limited to edit mode meshes or armature
+ (obedit != NULL && ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) ) // Temporary limited to edit mode meshes, armature, curves
{
t->tsnap.status |= SNAP_ON;
t->tsnap.modePoint = SNAP_GEO;
@@ -539,9 +612,12 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
{
float loc[3];
float no[3];
+ float mval[2];
int found = 0;
int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
- SnapMode mode;
+
+ mval[0] = t->mval[0];
+ mval[1] = t->mval[1];
if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME)
{
@@ -553,7 +629,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
depth_peels.first = depth_peels.last = NULL;
- peelObjectsTransForm(t, &depth_peels, t->mval);
+ peelObjectsTransForm(t, &depth_peels, mval);
// if (LAST_SNAP_POINT_VALID)
// {
@@ -636,18 +712,9 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
}
else
{
- if (t->obedit == NULL)
- {
- mode = SNAP_NOT_SELECTED;
- }
- else
- {
- mode = SNAP_NOT_OBEDIT;
+ found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode);
}
- found = snapObjectsTransform(t, t->mval, &dist, loc, no, mode);
- }
-
if (found == 1)
{
float tangent[3];
@@ -866,7 +933,7 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
-int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
{
float lambda;
int result;
@@ -897,7 +964,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
new_depth = VecLenf(location, ray_start);
project_int(ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+ new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
if (new_dist <= *dist && new_depth < *depth)
{
@@ -917,7 +984,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
return retval;
}
-int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
{
float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
int result;
@@ -965,7 +1032,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
new_depth = VecLenf(location, ray_start);
project_int(ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+ new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
/* 10% threshold if edge is closer but a bit further
* this takes care of series of connected edges a bit slanted w.r.t the viewport
@@ -1002,7 +1069,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
return retval;
}
-int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
{
int retval = 0;
float dvec[3];
@@ -1023,7 +1090,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray
new_depth = VecLenf(location, ray_start);
project_int(ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+ new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
if (new_dist <= *dist && new_depth < *depth)
{
@@ -1046,7 +1113,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray
return retval;
}
-int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth)
{
float imat[4][4];
float ray_start_local[3], ray_normal_local[3];
@@ -1358,7 +1425,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, B
return retval;
}
-int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth)
{
ToolSettings *ts= scene->toolsettings;
int retval = 0;
@@ -1390,7 +1457,7 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma
return retval;
}
-int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mval[2], int *dist, float *loc, float *no, SnapMode mode) {
+int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mval[2], int *dist, float *loc, float *no, SnapMode mode) {
Base *base;
float depth = FLT_MAX;
int retval = 0;
@@ -1407,7 +1474,7 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv
base= FIRSTBASE;
for ( base = FIRSTBASE; base != NULL; base = base->next ) {
- if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (mode == SNAP_NOT_OBEDIT && base != BASACT)) ) {
+ if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) {
Object *ob = base->object;
if (ob->transflag & OB_DUPLI)
@@ -1432,12 +1499,12 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv
return retval;
}
-int snapObjectsTransform(TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode)
+int snapObjectsTransform(TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode)
{
return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, dist, loc, no, mode);
}
-int snapObjectsContext(bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode)
+int snapObjectsContext(bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1502,7 +1569,7 @@ void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], O
peel->flag = 0;
}
-int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels)
+int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], ListBase *depth_peels)
{
int retval = 0;
int totvert = dm->getNumVerts(dm);
@@ -1610,7 +1677,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
return retval;
}
-int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, short mval[2])
+int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, float mval[2])
{
Base *base;
int retval = 0;
@@ -1693,12 +1760,12 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase
return retval;
}
-int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, short mval[2])
+int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, float mval[2])
{
return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval);
}
-int peelObjectsContext(bContext *C, ListBase *depth_peels, short mval[2])
+int peelObjectsContext(bContext *C, ListBase *depth_peels, float mval[2])
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;