Initial new transform commit.

Disabled behind defines. Uncomment //#define NEWTRANSFORM in transform.h to enable.

Use at your own risk

For more info, see Wiki: http://wiki.blender.org/bin/view.pl/Blenderdev/TransformRefactoring
And tuhopuu mailing list: http://projects.blender.org/pipermail/tuhopuu-devel/

Notes for Ton (things that could need bulldozing:
- TransData conversions. Objects is ok, but others could be rechecked. (some still use totsel). Need to add pose mode support.
- Need more icons in the PET mode dropdown (in the 3D view header) for the new modes
- Add new transform calls to Toolbox and Menus and the one right after Extrude.

That's pretty much all I can think of now.
This commit is contained in:
Martin Poirier 2005-02-14 02:53:36 +00:00
parent 923a9a0b03
commit d2f4ba4549
12 changed files with 2963 additions and 34 deletions

@ -85,6 +85,7 @@ source_files = ['B.blend.c',
'header_sound.c',
'header_text.c',
'header_view3d.c',
'imagepaint.c',
'imasel.c',
'interface.c',
'interface_panel.c',
@ -110,6 +111,10 @@ source_files = ['B.blend.c',
'swapbuffers.c',
'toets.c',
'toolbox.c',
'transform.c',
'transform_generics.c',
'transform_numinput.c',
'transform_constraints.c',
'unwrapper.c',
'usiblender.c',
'view.c',

@ -126,6 +126,8 @@
#include "mydevice.h"
#include "butspace.h" // event codes
#include "transform_constraints.h"
/* Modules used */
#include "render.h" // for ogl render
#include "radio.h"
@ -1908,7 +1910,13 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
base= base->next;
}
if(G.moving) constline_callback();
if(G.moving) {
constline_callback();
#ifdef NEWTRANSFORM
drawConstraint();
drawPropCircle();
#endif
}
/* duplis, draw as last to make sure the displists are ok */
base= G.scene->base.first;

@ -160,6 +160,8 @@
#include "blendef.h"
#include "transform.h"
#include "BIF_poseobject.h"
/* extern Lattice *copy_lattice(Lattice *lt); */
@ -760,7 +762,7 @@ void make_track(void)
allqueue(REDRAWOOPS, 0);
sort_baselist(G.scene);
}
BIF_undo_push("make Track");
BIF_undo_push("Make Track");
}
void apply_obmat(Object *ob)
@ -886,8 +888,6 @@ void clear_object(char mode)
else if(mode=='o') str= "Clear origin";
else return;
if(okee(str)==0) return;
if (G.obpose){
switch (G.obpose->type){
@ -4142,16 +4142,18 @@ void make_trans_verts(float *min, float *max, int mode)
void draw_prop_circle()
{
float tmat[4][4], imat[4][4];
if(G.moving) {
if (G.f & G_PROPORTIONAL) {
float tmat[4][4], imat[4][4];
BIF_ThemeColor(TH_GRID);
if(G.moving) {
mygetmatrix(tmat);
Mat4Invert(imat, tmat);
BIF_ThemeColor(TH_GRID);
drawcircball(prop_cent, prop_size, imat);
mygetmatrix(tmat);
Mat4Invert(imat, tmat);
drawcircball(prop_cent, prop_size, imat);
}
}
}
@ -6080,7 +6082,7 @@ void transform(int mode)
dist= vec[0]-centre[0];
if ((typemode) && (addvec[0]))
phi0= (Dist1*addvec[0]*M_PI/(360.0*dist)) - 0.5*M_PI;
phi0= (dist*addvec[0]*M_PI/(360.0*Dist1)) - 0.5*M_PI;
else
phi0= (circumfac*dist/rad) - 0.5*M_PI;
@ -6685,6 +6687,7 @@ void transform(int mode)
special_aftertrans_update(mode, a & 1, canceled, keyflags);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
scrarea_queue_headredraw(curarea);
clearbaseflags_for_editing();
@ -6722,7 +6725,11 @@ void std_rmouse_transform(void (*xf_func)(int))
while(get_mbut() & mousebut) {
getmouseco_areawin(mval);
if(abs(mval[0]-xo)+abs(mval[1]-yo) > 10) {
#ifdef NEWTRANSFORM
Transform(TRANSLATION);
#else
xf_func('g');
#endif
while(get_mbut() & mousebut) BIF_wait_for_statechange();
return;
}
@ -7827,7 +7834,7 @@ void select_select_keys(void)
allspace(REMAKEIPO, 0);
allqueue(REDRAWIPO, 0);
BIF_undo_push("Selet keys");
BIF_undo_push("Select keys");
}

@ -145,6 +145,8 @@
#include "blendef.h"
#include "datatoc.h"
#include "transform.h"
#include "TPT_DependKludge.h"
#ifdef NAN_TPT
#include "BSE_trans_types.h"
@ -1208,10 +1210,16 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.qual & LR_ALTKEY) rem_selected_from_group(); */
if((G.qual==LR_SHIFTKEY))
select_group_menu();
else if(G.qual==LR_ALTKEY)
clear_object('g');
else if((G.qual==0))
else if(G.qual==LR_ALTKEY) {
if(okee("Clear location")) {
clear_object('g');
}
} else if((G.qual==0))
#ifdef NEWTRANSFORM
Transform(TRANSLATION);
#else
transform('g');
#endif
break;
case HKEY:
if(G.obedit) {
@ -1402,24 +1410,29 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case OKEY:
ob= OBACT;
if(G.obedit) {
if (G.qual==LR_SHIFTKEY) {
extern int prop_mode;
if (G.qual==LR_SHIFTKEY) {
prop_mode= !prop_mode;
allqueue(REDRAWHEADERS, 0);
}
else if((G.qual==0)) {
G.f ^= G_PROPORTIONAL;
allqueue(REDRAWHEADERS, 0);
}
#ifdef NEWTRANSFORM
prop_mode = (prop_mode+1)%5;
#else
prop_mode= !prop_mode;
#endif
allqueue(REDRAWHEADERS, 0);
}
else if((G.qual==LR_SHIFTKEY)) {
else if((G.qual==0)) {
G.f ^= G_PROPORTIONAL;
allqueue(REDRAWHEADERS, 0);
}
else if((G.qual==LR_CTRLKEY)) {
if(ob && ob->type == OB_MESH) {
flip_subdivison(ob, -1);
}
}
else if(G.qual==LR_ALTKEY) clear_object('o');
else if(G.qual==LR_ALTKEY) {
if(okee("Clear origin")) {
clear_object('o');
}
}
break;
case PKEY:
@ -1443,9 +1456,11 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case RKEY:
if((G.obedit==0) && (G.f & G_FACESELECT) && (G.qual==0))
rotate_uv_tface();
else if(G.qual==LR_ALTKEY)
clear_object('r');
else if (G.obedit) {
else if(G.qual==LR_ALTKEY) {
if(okee("Clear rotation")) {
clear_object('r');
}
} else if (G.obedit) {
if((G.qual==LR_SHIFTKEY)) {
if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
selectrow_nurb();
@ -1457,29 +1472,60 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
loopoperations(LOOP_CUT);
}
else if((G.qual==0))
#ifdef NEWTRANSFORM
Transform(ROTATION);
#else
transform('r');
#endif
}
else if((G.qual==0))
#ifdef NEWTRANSFORM
Transform(ROTATION);
#else
transform('r');
#endif
break;
case SKEY:
if(G.obedit) {
if(G.qual==LR_ALTKEY)
transform('N'); /* scale along normal */
else if(G.qual==LR_CTRLKEY)
#ifdef NEWTRANSFORM
Transform(SHEAR);
else if(G.qual==(LR_CTRLKEY|LR_ALTKEY))
Transform(SHEAR);
#else
transform('S');
#endif
else if(G.qual==LR_SHIFTKEY)
snapmenu();
else if((G.qual==0))
else if(G.qual==0)
#ifdef NEWTRANSFORM
Transform(RESIZE);
else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
Transform(TOSPHERE);
#else
transform('s');
#endif
}
else if(G.qual==LR_ALTKEY) {
clear_object('s');
if(okee("Clear size")) {
clear_object('s');
}
}
else if((G.qual==LR_SHIFTKEY))
else if(G.qual==LR_SHIFTKEY) {
snapmenu();
}
else if((G.qual==0))
#ifdef NEWTRANSFORM
Transform(RESIZE);
else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
Transform(TOSPHERE);
else if(G.qual==(LR_CTRLKEY|LR_ALTKEY))
Transform(SHEAR);
#else
transform('s');
#endif
break;
case TKEY:
if(G.obedit){

1375
source/blender/src/transform.c Executable file

File diff suppressed because it is too large Load Diff

147
source/blender/src/transform.h Executable file

@ -0,0 +1,147 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef TRANSFORM_H
#define TRANSFORM_H
#include "transform_numinput.h"
/* ************************** Types ***************************** */
typedef struct TransCon {
char text[50]; /* Description of the Constraint for header_print */
float mtx[3][3]; /* Matrix of the Constraint space */
float imtx[3][3]; /* Inverse Matrix of the Constraint space */
float center[3]; /* transformation centre to define where to draw the view widget
ALWAYS in global space. Unlike the transformation center */
int mode; /* Mode flags of the Constraint */
void (*applyVec)(struct TransInfo *, struct TransData *, float *, float *);
/* Apply function pointer for linear vectorial transformation */
/* The last two parameters are pointers to the in/out vectors */
void (*applyRot)(struct TransInfo *, struct TransData *, float [3]);
/* Apply function pointer for rotation transformation (prototype will change */
} TransCon;
typedef struct TransData {
float dist; /* Distance to the nearest element (for Proportionnal Editing) */
float factor; /* Factor of the transformation (for Proportionnal Editing) */
float *loc; /* Location of the data to transform */
float iloc[3]; /* Initial location */
float *rot; /* Rotation of the data to transform (Faculative) */
float irot[3]; /* Initial rotation */
float *quat; /* Rotation quaternion of the data to transform (Faculative) */
float iquat[4]; /* Initial rotation quaternion */
float *size; /* Size of the data to transform (Faculative) */
float isize[3]; /* Initial size */
float center[3];
float mtx[3][3]; /* Matrix of the data to transform */
float smtx[3][3]; /* Matrix needed to apply the changes (in most case, the inverse of the parent) */
struct Object *ob;
int flag; /* Various flags */
} TransData;
typedef struct TransInfo {
int mode; /* current mode */
int (*transform)(struct TransInfo *, short *);
/* transform function pointer */
char redraw; /* redraw flag */
int flags; /* generic flags for special behaviors */
int total; /* total number of transformed data */
float propsize; /* proportional circle radius */
char proptext[20]; /* proportional falloff text */
float center[3]; /* center of transformation */
short center2d[2]; /* center in screen coordinates */
short imval[2]; /* initial mouse position */
TransData *data; /* transformed data (array) */
TransCon con; /* transformed constraint */
NumInput num; /* numerical input */
float val; /* init value for some transformations */
float fac; /* factor for distance based transform */
} TransInfo;
/* ******************** Macros & Prototypes *********************** */
//#define NEWTRANSFORM
/* MODE AND NUMINPUT FLAGS */
#define NOCONSTRAINT 1
#define NULLONE 2
#define NONEGATIVE 4
#define NOZERO 8
#define NOFRACTION 16
#define REPEAT 0
#define TRANSLATION 1
#define ROTATION 2
#define RESIZE 3
#define TOSPHERE 4
#define SHEAR 5
#define APPLYCON 1
#define CONAXIS0 2
#define CONAXIS1 4
#define CONAXIS2 8
#define PROP_SHARP 0
#define PROP_SMOOTH 1
#define PROP_ROOT 2
#define PROP_LIN 3
#define PROP_CONST 4
/* TRANSDATA FLAGS */
#define TD_SELECTED 1
#define TD_NOACTION 2
void Transform(int mode);
void initWrap(TransInfo *t);
int Wrap(TransInfo *t, short mval[2]);
void initShear(TransInfo *t);
int Shear(TransInfo *t, short mval[2]);
void initResize(TransInfo *t);
int Resize(TransInfo *t, short mval[2]);
void initTranslation(TransInfo *t);
int Translation(TransInfo *t, short mval[2]);
void initToSphere(TransInfo *t);
int ToSphere(TransInfo *t, short mval[2]);
void initRotation(TransInfo *t);
int Rotation(TransInfo *t, short mval[2]);
#endif

@ -0,0 +1,421 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#include "BLI_winstuff.h"
#endif
#include "MEM_guardedalloc.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_ika_types.h"
#include "DNA_image_types.h"
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "DNA_userdef_types.h"
#include "DNA_property_types.h"
#include "DNA_vfont_types.h"
#include "DNA_constraint_types.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_editview.h"
#include "BIF_resources.h"
#include "BIF_mywindow.h"
#include "BIF_gl.h"
#include "BIF_editlattice.h"
#include "BIF_editarmature.h"
#include "BIF_editmesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BKE_lattice.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BSE_view.h"
#include "BSE_edit.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BDR_drawobject.h"
#include "blendef.h"
#include "mydevice.h"
#include "transform.h"
#include "transform_constraints.h"
#include "transform_generics.h"
extern ListBase editNurb;
extern ListBase editelems;
void recalcData();
extern TransInfo trans;
/* ************************** CONSTRAINTS ************************* */
void getConstraintMatrix(TransInfo *t);
void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3])
{
VECCOPY(out, in);
if (!td && t->con.mode & APPLYCON) {
Mat3MulVecfl(t->con.imtx, out);
if (!(out[0] == out[1] == out[2] == 0.0f)) {
if (getConstraintSpaceDimension(t) == 2) {
float vec[3], factor, angle;
VecSubf(vec, out, in);
factor = Normalise(vec);
angle = Inpf(vec, G.vd->viewinv[2]);
if (angle * angle >= 0.000001f) {
factor /= angle;
VECCOPY(vec, G.vd->viewinv[2]);
VecMulf(vec, factor);
VecAddf(out, in, vec);
}
}
else if (getConstraintSpaceDimension(t) == 1) {
float c[3], n[3], vec[3], factor;
if (t->con.mode & CONAXIS0) {
VECCOPY(c, t->con.mtx[0]);
}
else if (t->con.mode & CONAXIS1) {
VECCOPY(c, t->con.mtx[1]);
}
else if (t->con.mode & CONAXIS2) {
VECCOPY(c, t->con.mtx[2]);
}
Normalise(c);
VECCOPY(n, c);
Mat4MulVecfl(G.vd->viewmat, n);
n[2] = G.vd->viewmat[3][2];
Mat4MulVecfl(G.vd->viewinv, n);
if (Inpf(c, G.vd->viewinv[2]) != 1.0f) {
Projf(vec, in, n);
factor = Normalise(vec);
factor /= Inpf(c, vec);
VecMulf(c, factor);
VECCOPY(out, c);
}
else {
out[0] = out[1] = out[2] = 0.0f;
}
}
}
if (t->num.flags & NULLONE && !(t->con.mode & CONAXIS0))
out[0] = 1.0f;
if (t->num.flags & NULLONE && !(t->con.mode & CONAXIS1))
out[1] = 1.0f;
if (t->num.flags & NULLONE && !(t->con.mode & CONAXIS2))
out[2] = 1.0f;
}
}
/*
* Generic callback for constant spacial constraints applied to rotations
*
* The rotation axis is copied into VEC.
*
* In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane.
*
* The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
*/
void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3])
{
if (!td && t->con.mode & APPLYCON) {
int mode = t->con.mode & (CONAXIS0|CONAXIS1|CONAXIS2);
switch(mode) {
case CONAXIS0:
case (CONAXIS1|CONAXIS2):
VECCOPY(vec, t->con.mtx[0]);
break;
case CONAXIS1:
case (CONAXIS0|CONAXIS2):
VECCOPY(vec, t->con.mtx[1]);
break;
case CONAXIS2:
case (CONAXIS0|CONAXIS1):
VECCOPY(vec, t->con.mtx[2]);
break;
}
if (Inpf(vec, G.vd->viewinv[2]) > 0.0f) {
VecMulf(vec, -1.0f);
}
}
}
/*
* Returns the dimension of the constraint space.
*
* For that reason, the flags always needs to be set to properly evaluate here,
* even if they aren't actually used in the callback function. (Which could happen
* for weird constraints not yet designed. Along a path for example.)
*/
int getConstraintSpaceDimension(TransInfo *t)
{
int n = 0;
if (t->con.mode & CONAXIS0)
n++;
if (t->con.mode & CONAXIS1)
n++;
if (t->con.mode & CONAXIS2)
n++;
return n;
}
void setConstraint(TransInfo *t, float space[3][3], int mode) {
Mat3CpyMat3(t->con.mtx, space);
t->con.mode = mode;
getConstraintMatrix(t);
VECCOPY(t->con.center, t->center);
if (G.obedit) {
Mat4MulVecfl(G.obedit->obmat, t->con.center);
}
t->con.applyVec = applyAxisConstraintVec;
t->con.applyRot = applyAxisConstraintRot;
t->redraw = 1;
}
//void drawConstraint(TransCon *t) {
void drawConstraint() {
int i = -1;
TransCon *t = &(trans.con);
if (t->mode == 0)
return;
if (!(t->mode & APPLYCON)) {
i = nearestAxisIndex(&trans);
}
if (t->mode & CONAXIS0) {
if (i == 0)
drawLine(t->center, t->mtx[0], 255 - 'x');
else
drawLine(t->center, t->mtx[0], 'x');
}
if (t->mode & CONAXIS1) {
if (i == 1)
drawLine(t->center, t->mtx[1], 255 - 'y');
else
drawLine(t->center, t->mtx[1], 'y');
}
if (t->mode & CONAXIS2) {
if (i == 2)
drawLine(t->center, t->mtx[2], 255 - 'z');
else
drawLine(t->center, t->mtx[2], 'z');
}
}
void drawPropCircle()
//void drawPropCircle(TransInfo *t)
{
TransInfo *t = &trans;
if (G.f & G_PROPORTIONAL) {
float tmat[4][4], imat[4][4];
BIF_ThemeColor(TH_GRID);
mygetmatrix(tmat);
Mat4Invert(imat, tmat);
drawcircball(t->center, t->propsize, imat);
}
}
void getConstraintMatrix(TransInfo *t)
{
Mat3Inv(t->con.imtx, t->con.mtx);
if (!(t->con.mode & CONAXIS0)) {
t->con.imtx[0][0] =
t->con.imtx[0][1] =
t->con.imtx[0][2] = 0.0f;
}
if (!(t->con.mode & CONAXIS1)) {
t->con.imtx[1][0] =
t->con.imtx[1][1] =
t->con.imtx[1][2] = 0.0f;
}
if (!(t->con.mode & CONAXIS2)) {
t->con.imtx[2][0] =
t->con.imtx[2][1] =
t->con.imtx[2][2] = 0.0f;
}
}
void selectConstraint(TransInfo *t)
{
Mat3One(t->con.mtx);
Mat3One(t->con.imtx);
t->con.mode |= CONAXIS0;
t->con.mode |= CONAXIS1;
t->con.mode |= CONAXIS2;
t->con.mode &= ~APPLYCON;
VECCOPY(t->con.center, t->center);
if (G.obedit) {
Mat4MulVecfl(G.obedit->obmat, t->con.center);
}
}
int nearestAxisIndex(TransInfo *t)
{
short coord[2];
float mvec[3], axis[3], center[3], proj[3];
float len[3];
int i;
VECCOPY(center, t->center);
if (G.obedit) {
Mat4MulVecfl(G.obedit->obmat, center);
}
getmouseco_areawin(coord);
mvec[0] = (float)(coord[0] - t->center2d[0]);
mvec[1] = (float)(coord[1] - t->center2d[1]);
mvec[2] = 0.0f;
for (i = 0; i<3; i++) {
VECCOPY(axis, t->con.mtx[i]);
VecAddf(axis, axis, center);
project_short_noclip(axis, coord);
axis[0] = (float)(coord[0] - t->center2d[0]);
axis[1] = (float)(coord[1] - t->center2d[1]);
axis[2] = 0.0f;
if (Normalise(axis) != 0.0f) {
Projf(proj, mvec, axis);
VecSubf(axis, mvec, proj);
len[i] = Normalise(axis);
}
else {
len[i] = 10000000000.0f;
}
}
if (len[0] < len[1] && len[0] < len[2]) {
return 0;
}
else if (len[1] < len[0] && len[1] < len[2]) {
return 1;
}
else if (len[2] < len[1] && len[2] < len[0]) {
return 2;
}
return -1;
}
void chooseConstraint(TransInfo *t)
{
t->con.mode &= ~CONAXIS0;
t->con.mode &= ~CONAXIS1;
t->con.mode &= ~CONAXIS2;
switch(nearestAxisIndex(t)) {
case 0:
t->con.mode |= CONAXIS0;
break;
case 1:
t->con.mode |= CONAXIS1;
break;
case 2:
t->con.mode |= CONAXIS2;
break;
}
t->con.mode |= APPLYCON;
VECCOPY(t->con.center, t->center);
getConstraintMatrix(t);
t->con.applyVec = applyAxisConstraintVec;
t->con.applyRot = applyAxisConstraintRot;
t->redraw = 1;
}

@ -0,0 +1,58 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef TRANSFORM_CONSTRAINTS_H
#define TRANSFORM_CONSTRAINTS_H
#include "transform.h"
void getConstraintMatrix(TransInfo *t);
void setConstraint(TransInfo *t, float space[3][3], int mode);
//void drawConstraint(TransCon *t);
void drawConstraint();
//void drawPropCircle(TransInfo *t);
void drawPropCircle();
void getConstraintMatrix(TransInfo *t);
void selectConstraint(TransInfo *t);
void chooseConstraint(TransInfo *t);
int getConstraintSpaceDimension(TransInfo *t);
int nearestAxisIndex(TransInfo *t);
#endif

@ -0,0 +1,499 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#include "BLI_winstuff.h"
#endif
#include "MEM_guardedalloc.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_ika_types.h"
#include "DNA_image_types.h"
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "DNA_userdef_types.h"
#include "DNA_property_types.h"
#include "DNA_vfont_types.h"
#include "DNA_constraint_types.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_editview.h"
#include "BIF_resources.h"
#include "BIF_mywindow.h"
#include "BIF_gl.h"
#include "BIF_editlattice.h"
#include "BIF_editarmature.h"
#include "BIF_editmesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BKE_lattice.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BSE_view.h"
#include "BSE_edit.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "blendef.h"
#include "mydevice.h"
#include "transform.h"
#include "transform_generics.h"
extern ListBase editNurb;
extern ListBase editelems;
/* GLOBAL VARIABLE THAT SHOULD MOVED TO SCREEN MEMBER OR SOMETHING */
extern TransInfo trans;
/* ************************** Functions *************************** */
/* ************************** GENERICS **************************** */
void recalcData(TransInfo *t)
{
if (G.obedit) {
if (G.obedit->type == OB_MESH) {
recalc_editnormals();
makeDispList(G.obedit);
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
Nurb *nu= editNurb.first;
while(nu) {
test2DNurb(nu);
testhandlesNurb(nu); /* test for bezier too */
nu= nu->next;
}
makeDispList(G.obedit);
makeBevelList(G.obedit); // might be needed for deform
calc_curvepath(G.obedit);
}
else if (G.obedit->type == OB_MBALL) {
makeDispList(G.obedit);
}
}
else {
TransData *tob;
int i;
tob = t->data;
for (i = 0; i < t->total; i++, tob++) {
if (tob->ob->type == OB_MBALL) {
makeDispList(tob->ob);
}
}
}
}
void initTransModeFlags(TransInfo *t, int mode) {
t->flags = 0;
t->num.flags = 0;
switch (mode) {
case TRANSLATION:
break;
case ROTATION:
break;
case RESIZE:
t->num.flags |= NULLONE;
if (!G.obedit) {
t->flags |= NOZERO;
t->num.flags |= NOZERO;
}
break;
case TOSPHERE:
t->num.flags |= NULLONE;
t->num.flags |= NONEGATIVE;
t->flags |= NOCONSTRAINT;
break;
case SHEAR:
t->flags |= NOCONSTRAINT;
break;
}
}
void drawLine(float *center, float *dir, char axis)
{
extern void make_axis_color(char *col, char *col2, char axis); // drawview.c
float v1[3], v2[3], v3[3];
char col[3], col2[3];
//if(G.obedit) mymultmatrix(G.obedit->obmat); // sets opengl viewing
VecCopyf(v3, dir);
VecMulf(v3, G.vd->far);
VecSubf(v2, center, v3);
VecAddf(v1, center, v3);
if (axis > 127) {
axis = -1 * (axis - 255);
col[0] = col[1] = col[2] = 200;
}
else {
BIF_GetThemeColor3ubv(TH_GRID, col);
}
make_axis_color(col, col2, axis);
glColor3ubv(col2);
setlinestyle(0);
glBegin(GL_LINE_STRIP);
glVertex3fv(v1);
glVertex3fv(v2);
glEnd();
myloadmatrix(G.vd->viewmat);
}
void postTrans (TransInfo *t) {
MEM_freeN(t->data);
t->data = NULL;
G.moving = 0; // Set moving flag off (display as usual)
scrarea_do_windraw(curarea);
screen_swapbuffers();
}
void apply_grid3(float *val, int max_index, float fac1, float fac2, float fac3)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
int invert = U.flag & USER_AUTOGRABGRID;
int ctrl;
int i;
for (i=0; i<=max_index; i++) {
if(invert) {
if(G.qual & LR_CTRLKEY) ctrl= 0;
else ctrl= 1;
}
else ctrl= (G.qual & LR_CTRLKEY);
if(ctrl && (G.qual & LR_SHIFTKEY)) {
if(fac3!= 0.0) {
for (i=0; i<=max_index; i++) {
val[i]= fac3*(float)floor(val[i]/fac3 +.5);
}
}
}
else if(ctrl) {
if(fac2!= 0.0) {
for (i=0; i<=max_index; i++) {
val[i]= fac2*(float)floor(val[i]/fac2 +.5);
}
}
}
else {
if(fac1!= 0.0) {
for (i=0; i<=max_index; i++) {
val[i]= fac1*(float)floor(val[i]/fac1 +.5);
}
}
}
}
}
void apply_grid1(float *val, int max_index, float factor)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
float fac1 = 0.0;
float fac2 = G.vd->grid * factor;
float fac3 = 0.1f * fac2;
apply_grid3(val, max_index, fac1, fac2, fac3);
}
void apply_grid2(float *val, int max_index, float factor, float factor2)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
float fac1 = 0.0;
float fac2 = G.vd->grid * factor;
float fac3 = factor2 * fac2;
apply_grid3(val, max_index, fac1, fac2, fac3);
}
void applyTransObjects(TransInfo *t)
{
TransData *tob;
for (tob = t->data; tob < t->data + t->total; tob++) {
VECCOPY(tob->iloc, tob->loc);
if (tob->rot) {
VECCOPY(tob->irot, tob->rot);
}
if (tob->size) {
VECCOPY(tob->isize, tob->size);
}
}
recalcData(t);
}
void restoreTransObjects(TransInfo *t)
{
TransData *tob;
for (tob = t->data; tob < t->data + t->total; tob++) {
VECCOPY(tob->loc, tob->iloc);
if (tob->rot) {
VECCOPY(tob->rot, tob->irot);
}
if (tob->size) {
VECCOPY(tob->size, tob->isize);
}
}
recalcData(t);
}
void initTrans (TransInfo *t)
{
G.moving = 1; // Set moving flag on (display object in white)
t->data = NULL;
getmouseco_areawin(t->imval);
t->transform = NULL;
t->con.applyVec = NULL;
t->con.applyRot = NULL;
t->mode =
t->con.mode =
t->total =
t->num.idx =
t->num.idx_max =
t->num.ctrl[0] =
t->num.ctrl[1] =
t->num.ctrl[2] = 0;
t->val = 0.0f;
t->num.val[0] =
t->num.val[1] =
t->num.val[2] = 0.0f;
}
void calculateCenterCursor(TransInfo *t)
{
float *cursor;
cursor = give_cursor();
VECCOPY(t->center, cursor);
if(G.obedit) {
float mat[3][3], imat[3][3];
VecSubf(t->center, t->center, G.obedit->obmat[3]);
Mat3CpyMat4(mat, G.obedit->obmat);
Mat3Inv(imat, mat);
Mat3MulVecfl(imat, t->center);
}
if (G.obedit) {
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(G.obedit->obmat, vec);
project_short_noclip(vec, t->center2d);
}
else {
project_short_noclip(t->center, t->center2d);
}
}
void calculateCenterMedian(TransInfo *t)
{
float partial[3] = {0.0f, 0.0f, 0.0f};
int i;
for(i = 0; i < t->total; i++) {
if (t->data[i].flag & TD_SELECTED) {
VecAddf(partial, partial, t->data[i].center);
}
}
VecMulf(partial, 1.0f / t->total);
VECCOPY(t->center, partial);
if (G.obedit) {
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(G.obedit->obmat, vec);
project_short_noclip(vec, t->center2d);
}
else {
project_short_noclip(t->center, t->center2d);
}
}
void calculateCenterBound(TransInfo *t)
{
float max[3];
float min[3];
int i;
for(i = 0; i < t->total; i++) {
if (i) {
if (t->data[i].flag & TD_SELECTED) {
MinMax3(min, max, t->data[i].center);
}
}
else {
VECCOPY(max, t->data[i].center);
VECCOPY(min, t->data[i].center);
}
}
VecAddf(t->center, min, max);
VecMulf(t->center, 0.5);
if (G.obedit) {
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(G.obedit->obmat, vec);
project_short_noclip(vec, t->center2d);
}
else {
project_short_noclip(t->center, t->center2d);
}
}
void calculateCenter(TransInfo *t) {
switch(G.vd->around) {
case V3D_CENTRE:
calculateCenterBound(t);
break;
case V3D_CENTROID:
calculateCenterMedian(t);
break;
case V3D_CURSOR:
calculateCenterCursor(t);
break;
case V3D_LOCAL:
// NEED TO REPLACE THIS
calculateCenterMedian(t);
printf("local\n");
break;
}
initgrabz(t->center[0], t->center[1], t->center[2]);
}
void calculatePropRatio(TransInfo *t)
{
TransData *td = t->data;
int i;
float dist;
extern int prop_mode;
if (G.f & G_PROPORTIONAL) {
for(i = 0 ; i < t->total; i++, td++) {
if (td->dist == 0.0f) {
td->factor = 1.0f;
}
else if (td->dist > t->propsize) {
td->factor = 0.0f;
}
else {
dist= (t->propsize-td->dist)/t->propsize;
switch(prop_mode) {
case PROP_SHARP:
td->factor= dist*dist;
break;
case PROP_SMOOTH:
td->factor= 3.0f*dist*dist - 2.0f*dist*dist*dist;
break;
case PROP_ROOT:
td->factor = (float)sqrt(dist);
break;
case PROP_LIN:
td->factor = dist;
break;
case PROP_CONST:
td->factor = 1;
break;
default:
td->factor = 1;
}
}
}
switch(prop_mode) {
case PROP_SHARP:
strcpy(t->proptext, "(Quad)");
break;
case PROP_SMOOTH:
strcpy(t->proptext, "(Smooth)");
break;
case PROP_ROOT:
strcpy(t->proptext, "(Root)");
break;
case PROP_LIN:
strcpy(t->proptext, "(Linear)");
break;
case PROP_CONST:
strcpy(t->proptext, "(Constant)");
break;
default:
strcpy(t->proptext, "");
}
}
else {
for(i = 0 ; i < t->total; i++, td++) {
td->factor = 1.0;
}
strcpy(t->proptext, "");
}
}

@ -0,0 +1,63 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef TRANSFORM_GENERICS_H
#define TRANSFORM_GENERICS_H
void recalcData(TransInfo *t);
void initTransModeFlags(TransInfo *t, int mode);
void drawLine(float *center, float *dir, char axis);
void postTrans (TransInfo *t);
void apply_grid1(float *val, int max_index, float factor);
void apply_grid2(float *val, int max_index, float factor, float factor2);
void apply_grid3(float *val, int max_index, float fac1, float fac2, float fac3);
void applyTransObjects(TransInfo *t);
void restoreTransObjects(TransInfo *t);
void initTrans(TransInfo *t);
void calculateCenterBound(TransInfo *t);
void calculateCenterMedian(TransInfo *t);
void calculateCenterCursor(TransInfo *t);
void calculateCenter(TransInfo *t);
void calculatePropRatio(TransInfo *t);
#endif

@ -0,0 +1,238 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#include "BLI_winstuff.h"
#endif
#include "MEM_guardedalloc.h"
#include "blendef.h"
#include "mydevice.h"
#include "BLI_arithb.h"
#include "transform_numinput.h"
#include "transform.h"
/* ************************** Functions *************************** */
/* ************************** NUMINPUT **************************** */
void outputNumInput(NumInput *n, char *str)
{
char Cur;
short i;
for (i=0; i<=n->idx_max; i++) {
if (n->idx != i)
Cur = ' ';
else
Cur = '|';
switch (n->ctrl[i]) {
case 0:
sprintf(&str[i*20], "NONE%c", Cur);
break;
case 1:
case -1:
sprintf(&str[i*20], "%.0f%c", n->val[i], Cur);
break;
case 10:
case -10:
sprintf(&str[i*20], "%.f.%c", n->val[i], Cur);
break;
case 100:
case -100:
sprintf(&str[i*20], "%.1f%c", n->val[i], Cur);
break;
case 1000:
case -1000:
sprintf(&str[i*20], "%.2f%c", n->val[i], Cur);
case 10000:
case -10000:
sprintf(&str[i*20], "%.3f%c", n->val[i], Cur);
break;
default:
sprintf(&str[i*20], "%.4f%c", n->val[i], Cur);
}
}
}
short hasNumInput(NumInput *n)
{
short doit = 0;
short i;
for (i=0; i<=n->idx_max; i++) {
if (n->ctrl[i])
doit = 1;
}
return doit;
}
void applyNumInput(NumInput *n, float *vec)
{
short i;
if (hasNumInput(n)) {
for (i=0; i<=n->idx_max; i++) {
if (n->ctrl[i] == 0 && n->flags & NULLONE) {
vec[i] = 1.0f;
}
else if (n->val[i] == 0.0f && n->flags & NOZERO) {
vec[i] = 0.0001f;
}
else {
vec[i] = n->val[i];
}
}
}
}
char handleNumInput(NumInput *n, unsigned short event)
{
float Val = 0;
short idx = n->idx, idx_max = n->idx_max;
switch (event) {
case BACKSPACEKEY:
if (n->ctrl[idx] == 0) {
n->val[0] =
n->val[1] =
n->val[2] = 0.0f;
n->ctrl[0] =
n->ctrl[1] =
n->ctrl[2] = 0;
}
else {
n->val[idx] = 0.0f;
n->ctrl[idx] = 0;
}
break;
case PERIODKEY:
case PADPERIOD:
if (n->flags & NOFRACTION)
break;
switch (n->ctrl[idx])
{
case 0:
case 1:
n->ctrl[idx] = 10;
break;
case -1:
n->ctrl[idx] = -10;
}
break;
case MINUSKEY:
if (n->flags & NONEGATIVE)
break;
if (n->ctrl[idx]) {
n->ctrl[idx] *= -1;
n->val[idx] *= -1;
}
else
n->ctrl[idx] = -1;
break;
case TABKEY:
idx++;
if (idx > idx_max)
idx = 0;
n->idx = idx;
break;
case PAD9:
case NINEKEY:
Val += 1.0f;
case PAD8:
case EIGHTKEY:
Val += 1.0f;
case PAD7:
case SEVENKEY:
Val += 1.0f;
case PAD6:
case SIXKEY:
Val += 1.0f;
case PAD5:
case FIVEKEY:
Val += 1.0f;
case PAD4:
case FOURKEY:
Val += 1.0f;
case PAD3:
case THREEKEY:
Val += 1.0f;
case PAD2:
case TWOKEY:
Val += 1.0f;
case PAD1:
case ONEKEY:
Val += 1.0f;
case PAD0:
case ZEROKEY:
if (!n->ctrl[idx])
n->ctrl[idx] = 1;
if (n->ctrl[idx] == 1) {
n->val[idx] *= 10;
n->val[idx] += Val;
}
else if (n->ctrl[idx] == -1) {
n->val[idx] *= 10;
n->val[idx] -= Val;
}
else {
n->val[idx] += Val / (float)n->ctrl[idx];
n->ctrl[idx] *= 10;
}
break;
default:
return 0;
}
/* REDRAW SINCE NUMBERS HAVE CHANGED */
return 1;
}

@ -0,0 +1,62 @@
/**
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef TRANSFORM_NUMINPUT_H
#define TRANSFORM_NUMINPUT_H
typedef struct NumInput {
short idx;
short idx_max;
short flags; /* Different flags to indicate different behaviors */
float val[3]; /* Direct value of the input */
short ctrl[3]; /* Control to indicate what to do with the numbers that are typed */
} NumInput ;
/*
The ctrl value has different meaning:
0 : No value has been typed
otherwise, |value| - 1 is where the cursor is located after the period
Positive : number is positive
Negative : number is negative
*/
void outputNumInput(NumInput *n, char *str);
short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);
char handleNumInput(NumInput *n, unsigned short event);
#endif