2.5
Transform: First working port of the transform code: - Object mode only (other conversions need to be ported) - Contraints (global and local only) working - Snap (no edit mode, obviously) working - Numinput working - Gears (Ctrl and Shift) working - Only grap, rotate, scale, shear, warp and to sphere have been added as hotkey, but the rest should work too once accessible - No manipulator - No drawn feedback other than moving stuff and header print (no constraint line, snap circle, ...) - No NDOF support I've only tested Scons support, though Makefil *should* work, I *think*. Misc: -QuatIsNull function in arith -Exporting project_* and view[line|ray] functions from view3d
This commit is contained in:
parent
97a82102d4
commit
b6b61681ef
@ -123,6 +123,7 @@ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
|
||||
* @section Quaternion arithmetic routines
|
||||
*/
|
||||
|
||||
int QuatIsNul(float *q);
|
||||
void QuatToEul(float *quat, float *eul);
|
||||
void QuatOne(float *);
|
||||
void QuatMul(float *, float *, float *);
|
||||
|
@ -1087,6 +1087,10 @@ void printmatrix3( char *str, float m[][3])
|
||||
|
||||
/* **************** QUATERNIONS ********** */
|
||||
|
||||
int QuatIsNul(float *q)
|
||||
{
|
||||
return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0);
|
||||
}
|
||||
|
||||
void QuatMul(float *q, float *q1, float *q2)
|
||||
{
|
||||
|
135
source/blender/editors/include/BIF_transform.h
Normal file
135
source/blender/editors/include/BIF_transform.h
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BIF_TRANSFORM_H
|
||||
#define BIF_TRANSFORM_H
|
||||
|
||||
/* ******************* Registration Function ********************** */
|
||||
|
||||
struct wmWindowManager;
|
||||
struct ListBase;
|
||||
struct wmEvent;
|
||||
struct bContext;
|
||||
|
||||
void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid);
|
||||
void transform_operatortypes(void);
|
||||
|
||||
/* ******************** Macros & Prototypes *********************** */
|
||||
|
||||
/* MODE AND NUMINPUT FLAGS */
|
||||
#define TFM_INIT -1
|
||||
#define TFM_DUMMY 0
|
||||
#define TFM_TRANSLATION 1
|
||||
#define TFM_ROTATION 2
|
||||
#define TFM_RESIZE 3
|
||||
#define TFM_TOSPHERE 4
|
||||
#define TFM_SHEAR 5
|
||||
#define TFM_WARP 7
|
||||
#define TFM_SHRINKFATTEN 8
|
||||
#define TFM_TILT 9
|
||||
#define TFM_LAMP_ENERGY 10
|
||||
#define TFM_TRACKBALL 11
|
||||
#define TFM_PUSHPULL 12
|
||||
#define TFM_CREASE 13
|
||||
#define TFM_MIRROR 14
|
||||
#define TFM_BONESIZE 15
|
||||
#define TFM_BONE_ENVELOPE 16
|
||||
#define TFM_CURVE_SHRINKFATTEN 17
|
||||
#define TFM_BONE_ROLL 18
|
||||
#define TFM_TIME_TRANSLATE 19
|
||||
#define TFM_TIME_SLIDE 20
|
||||
#define TFM_TIME_SCALE 21
|
||||
#define TFM_TIME_EXTEND 22
|
||||
#define TFM_BAKE_TIME 23
|
||||
#define TFM_BEVEL 24
|
||||
#define TFM_BWEIGHT 25
|
||||
#define TFM_ALIGN 26
|
||||
|
||||
/* TRANSFORM CONTEXTS */
|
||||
#define CTX_NONE 0
|
||||
#define CTX_TEXTURE 1
|
||||
#define CTX_EDGE 2
|
||||
#define CTX_NO_PET 4
|
||||
#define CTX_TWEAK 8
|
||||
#define CTX_NO_MIRROR 16
|
||||
#define CTX_AUTOCONFIRM 32
|
||||
#define CTX_BMESH 64
|
||||
#define CTX_NDOF 128
|
||||
|
||||
/* Standalone call to get the transformation center corresponding to the current situation
|
||||
* returns 1 if successful, 0 otherwise (usually means there's no selection)
|
||||
* (if 0 is returns, *vec is unmodified)
|
||||
* */
|
||||
int calculateTransformCenter(struct bContext *C, struct wmEvent *event, int centerMode, float *vec);
|
||||
|
||||
struct TransInfo;
|
||||
struct ScrArea;
|
||||
struct Base;
|
||||
struct Scene;
|
||||
|
||||
struct TransInfo * BIF_GetTransInfo(void);
|
||||
void BIF_setSingleAxisConstraint(float vec[3], char *text);
|
||||
void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text);
|
||||
void BIF_setLocalAxisConstraint(char axis, char *text);
|
||||
void BIF_setLocalLockConstraint(char axis, char *text);
|
||||
|
||||
int BIF_snappingSupported(void);
|
||||
|
||||
struct TransformOrientation;
|
||||
|
||||
void BIF_clearTransformOrientation(void);
|
||||
void BIF_removeTransformOrientation(struct TransformOrientation *ts);
|
||||
void BIF_manageTransformOrientation(int confirm, int set);
|
||||
int BIF_menuselectTransformOrientation(void);
|
||||
void BIF_selectTransformOrientation(struct TransformOrientation *ts);
|
||||
void BIF_selectTransformOrientationFromIndex(int index);
|
||||
|
||||
char * BIF_menustringTransformOrientation(char *title); /* the returned value was allocated and needs to be freed after use */
|
||||
int BIF_countTransformOrientation();
|
||||
|
||||
/* Drawing callbacks */
|
||||
void BIF_drawConstraint(void);
|
||||
void BIF_drawPropCircle(void);
|
||||
void BIF_drawSnap(void);
|
||||
|
||||
void BIF_getPropCenter(float *center);
|
||||
|
||||
void BIF_TransformSetUndo(char *str);
|
||||
|
||||
void BIF_selectOrientation(void);
|
||||
|
||||
/* view3d manipulators */
|
||||
void initManipulator(int mode);
|
||||
void ManipulatorTransform();
|
||||
|
||||
//int BIF_do_manipulator(struct ScrArea *sa);
|
||||
//void BIF_draw_manipulator(struct ScrArea *sa);
|
||||
|
||||
#endif
|
||||
|
@ -29,8 +29,28 @@
|
||||
#define ED_VIEW3D_H
|
||||
|
||||
/* ********* exports for space_view3d/ module ********** */
|
||||
struct ARegion;
|
||||
struct View3D;
|
||||
|
||||
|
||||
float *give_cursor(Scene *scene, View3D *v3d);
|
||||
|
||||
void initgrabz(struct View3D *v3d, float x, float y, float z);
|
||||
void window_to_3d(struct ARegion *ar, struct View3D *v3d, float *vec, short mx, short my);
|
||||
|
||||
/* Projection */
|
||||
|
||||
void project_short(struct ARegion *ar, struct View3D *v3d, float *vec, short *adr);
|
||||
void project_short_noclip(struct ARegion *ar, struct View3D *v3d, float *vec, short *adr);
|
||||
|
||||
void project_int(struct ARegion *ar, struct View3D *v3d, float *vec, int *adr);
|
||||
void project_int_noclip(struct ARegion *ar, struct View3D *v3d, float *vec, int *adr);
|
||||
|
||||
void project_float(struct ARegion *ar, struct View3D *v3d, float *vec, float *adr);
|
||||
void project_float_noclip(struct ARegion *ar, struct View3D *v3d, float *vec, float *adr);
|
||||
|
||||
void viewline(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]);
|
||||
void viewray(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]);
|
||||
|
||||
#endif /* ED_VIEW3D_H */
|
||||
|
||||
|
@ -130,11 +130,7 @@ void VIEW3D_OT_circle_select(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
|
||||
|
||||
void view3d_operator_needs_opengl(const struct bContext *C);
|
||||
void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]);
|
||||
void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]);
|
||||
|
||||
void initgrabz(View3D *v3d, float x, float y, float z);
|
||||
void window_to_3d(ARegion *ar, View3D *v3d, float *vec, short mx, short my);
|
||||
int boundbox_clip(View3D *v3d, float obmat[][4], struct BoundBox *bb);
|
||||
|
||||
void view3d_project_short_clip(ARegion *ar, View3D *v3d, float *vec, short *adr, float projmat[4][4], float wmat[4][4]);
|
||||
@ -143,13 +139,6 @@ void view3d_project_float(ARegion *a, float *vec, float *adr, float mat[4][4]);
|
||||
void view3d_get_object_project_mat(View3D *v3d, struct Object *ob, float pmat[4][4], float vmat[4][4]);
|
||||
void view3d_project_float(ARegion *ar, float *vec, float *adr, float mat[4][4]);
|
||||
|
||||
void project_short(ARegion *ar, View3D *v3d, float *vec, short *adr);
|
||||
void project_int(ARegion *ar, View3D *v3d, float *vec, int *adr);
|
||||
void project_int_noclip(ARegion *ar, View3D *v3d, float *vec, int *adr);
|
||||
void project_short_noclip(ARegion *ar, View3D *v3d, float *vec, short *adr);
|
||||
void project_float(ARegion *ar, View3D *v3d, float *vec, float *adr);
|
||||
void project_float_noclip(ARegion *ar, View3D *v3d, float *vec, float *adr);
|
||||
|
||||
int get_view3d_viewplane(View3D *v3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
|
||||
void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, float *lens);
|
||||
void obmat_to_viewmat(View3D *v3d, Object *ob, short smooth);
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_transform.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
@ -79,6 +81,8 @@ void view3d_operatortypes(void)
|
||||
WM_operatortype_append(VIEW3D_OT_smoothview);
|
||||
WM_operatortype_append(VIEW3D_OT_render_border);
|
||||
WM_operatortype_append(VIEW3D_OT_cursor3d);
|
||||
|
||||
transform_operatortypes();
|
||||
}
|
||||
|
||||
void view3d_keymap(wmWindowManager *wm)
|
||||
@ -136,5 +140,7 @@ void view3d_keymap(wmWindowManager *wm)
|
||||
/* TODO - this is just while we have no way to load a text datablock */
|
||||
RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_run_pyfile", PKEY, KM_PRESS, 0, 0)->ptr, "filename", "test.py");
|
||||
|
||||
transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#
|
||||
# Makes module object directory and bounces make to subdirectories.
|
||||
|
||||
LIBNAME = ed_screen
|
||||
LIBNAME = ed_transform
|
||||
DIR = $(OCGDIR)/blender/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('*.c')
|
||||
|
||||
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
|
||||
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
|
||||
incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont'
|
||||
incs += ' ../../gpu ../../makesrna'
|
||||
|
||||
env.BlenderLib ( 'bf_editors_transform', sources, Split(incs), [], libtype=['core'], priority=[40] )
|
4827
source/blender/editors/transform/transform.c
Normal file
4827
source/blender/editors/transform/transform.c
Normal file
File diff suppressed because it is too large
Load Diff
569
source/blender/editors/transform/transform.h
Normal file
569
source/blender/editors/transform/transform.h
Normal file
@ -0,0 +1,569 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef TRANSFORM_H
|
||||
#define TRANSFORM_H
|
||||
|
||||
#include "BIF_transform.h"
|
||||
|
||||
/* ************************** Types ***************************** */
|
||||
|
||||
struct TransInfo;
|
||||
struct TransData;
|
||||
struct TransSnap;
|
||||
struct NumInput;
|
||||
struct Object;
|
||||
struct View3D;
|
||||
struct ScrArea;
|
||||
struct Scene;
|
||||
struct bPose;
|
||||
struct bConstraint;
|
||||
struct BezTriple;
|
||||
struct wmOperatorType;
|
||||
struct bContext;
|
||||
struct wmEvent;
|
||||
struct ARegion;
|
||||
|
||||
typedef struct NDofInput {
|
||||
int flag;
|
||||
int axis;
|
||||
float fval[7];
|
||||
float factor[3];
|
||||
} NDofInput;
|
||||
|
||||
typedef struct NumInput {
|
||||
short idx;
|
||||
short idx_max;
|
||||
short flag; /* Different flags to indicate different behaviors */
|
||||
float val[3]; /* Direct value of the input */
|
||||
int 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
|
||||
*/
|
||||
|
||||
typedef struct TransSnap {
|
||||
short modePoint;
|
||||
short modeTarget;
|
||||
int status;
|
||||
float snapPoint[3];
|
||||
float snapTarget[3];
|
||||
float snapNormal[3];
|
||||
float snapTangent[3];
|
||||
float dist; // Distance from snapPoint to snapTarget
|
||||
double last;
|
||||
void (*applySnap)(struct TransInfo *, float *);
|
||||
void (*calcSnap)(struct TransInfo *, float *);
|
||||
void (*targetSnap)(struct TransInfo *);
|
||||
float (*distance)(struct TransInfo *, float p1[3], float p2[3]); // Get the transform distance between two points (used by Closest snap)
|
||||
} TransSnap;
|
||||
|
||||
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 pmtx[3][3]; /* Projection Constraint Matrix (same as imtx with some axis == 0) */
|
||||
float center[3]; /* transformation center to define where to draw the view widget
|
||||
ALWAYS in global space. Unlike the transformation center */
|
||||
short imval[2]; /* initial mouse value for visual calculation */
|
||||
/* the one in TransInfo is not garanty to stay the same (Rotates change it) */
|
||||
int mode; /* Mode flags of the Constraint */
|
||||
void (*drawExtra)(struct TransInfo *);
|
||||
/* For constraints that needs to draw differently from the other
|
||||
uses this instead of the generic draw function */
|
||||
void (*applyVec)(struct TransInfo *, struct TransData *, float *, float *, float *);
|
||||
/* Apply function pointer for linear vectorial transformation */
|
||||
/* The last three parameters are pointers to the in/out/printable vectors */
|
||||
void (*applySize)(struct TransInfo *, struct TransData *, float [3][3]);
|
||||
/* Apply function pointer for size transformation */
|
||||
void (*applyRot)(struct TransInfo *, struct TransData *, float [3], float *);
|
||||
/* 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 dsize[3]; /* Initial object dsize */
|
||||
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 obmat[4][4]; /* Object matrix */
|
||||
} TransDataExtension;
|
||||
|
||||
typedef struct TransData2D {
|
||||
float loc[3]; /* Location of data used to transform (x,y,0) */
|
||||
float *loc2d; /* Pointer to real 2d location of data */
|
||||
} TransData2D;
|
||||
|
||||
/* we need to store 2 handles for each transdata incase the other handle wasnt selected */
|
||||
typedef struct TransDataCurveHandleFlags {
|
||||
char ih1, ih2;
|
||||
char *h1, *h2;
|
||||
} TransDataCurveHandleFlags;
|
||||
|
||||
|
||||
typedef struct TransData {
|
||||
float dist; /* Distance needed to affect element (for Proportionnal Editing) */
|
||||
float rdist; /* 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 *val; /* Value pointer for special transforms */
|
||||
float ival; /* Old value*/
|
||||
float center[3]; /* Individual data center */
|
||||
float mtx[3][3]; /* Transformation matrix from data space to global space */
|
||||
float smtx[3][3]; /* Transformation matrix from global space to data space */
|
||||
float axismtx[3][3];/* Axis orientation matrix of the data */
|
||||
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 */
|
||||
short protectflag; /* If set, copy of Object or PoseChannel protection */
|
||||
/*#ifdef WITH_VERSE*/
|
||||
void *verse; /* pointer at verse data struct (VerseVert, etc.) */
|
||||
/*#endif*/
|
||||
} TransData;
|
||||
|
||||
typedef struct TransInfo {
|
||||
int mode; /* current mode */
|
||||
int flag; /* generic flags for special behaviors */
|
||||
short state; /* current state (running, canceled,...)*/
|
||||
int context; /* current context */
|
||||
float val; /* init value for some transformations (and rotation angle) */
|
||||
float fac; /* factor for distance based transform */
|
||||
int (*transform)(struct TransInfo *, short *);
|
||||
/* transform function pointer */
|
||||
int (*handleEvent)(struct TransInfo *, struct wmEvent *event);
|
||||
/* event handler function pointer RETURN 1 if redraw is needed */
|
||||
int total; /* total number of transformed data */
|
||||
TransData *data; /* transformed data (array) */
|
||||
TransDataExtension *ext; /* transformed data extension (array) */
|
||||
TransData2D *data2d; /* transformed data for 2d (array) */
|
||||
TransCon con; /* transformed constraint */
|
||||
TransSnap tsnap;
|
||||
NumInput num; /* numerical input */
|
||||
NDofInput ndof; /* ndof input */
|
||||
char redraw; /* redraw flag */
|
||||
float propsize; /* proportional circle radius */
|
||||
char proptext[20]; /* proportional falloff text */
|
||||
float center[3]; /* center of transformation */
|
||||
int center2d[2]; /* center in screen coordinates */
|
||||
short imval[2]; /* initial mouse position */
|
||||
short shiftmval[2]; /* mouse position when shift was pressed */
|
||||
short idx_max; /* maximum index on the input vector */
|
||||
float snap[3]; /* Snapping Gears */
|
||||
|
||||
float viewmat[4][4]; /* copy from G.vd, prevents feedback, */
|
||||
float viewinv[4][4]; /* and to make sure we don't have to */
|
||||
float persmat[4][4]; /* access G.vd from other space types */
|
||||
float persinv[4][4];
|
||||
short persp;
|
||||
short around;
|
||||
char spacetype; /* spacetype where transforming is */
|
||||
|
||||
float vec[3]; /* translation, to show for widget */
|
||||
float mat[3][3]; /* rot/rescale, to show for widget */
|
||||
|
||||
char *undostr; /* if set, uses this string for undo */
|
||||
float spacemtx[3][3]; /* orientation matrix of the current space */
|
||||
char spacename[32]; /* name of the current space */
|
||||
|
||||
struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */
|
||||
|
||||
void *customData; /* Per Transform custom data */
|
||||
|
||||
/*************** NEW STUFF *********************/
|
||||
|
||||
float values[4];
|
||||
void *view;
|
||||
struct ScrArea *sa;
|
||||
struct ARegion *ar;
|
||||
struct Scene *scene;
|
||||
struct wmEvent *event; /* last event, reset at the start of each transformApply and nulled at the transformEnd */
|
||||
short mval[2]; /* current mouse position */
|
||||
} TransInfo;
|
||||
|
||||
|
||||
/* ******************** Macros & Prototypes *********************** */
|
||||
|
||||
/* NUMINPUT FLAGS */
|
||||
#define NUM_NULL_ONE 2
|
||||
#define NUM_NO_NEGATIVE 4
|
||||
#define NUM_NO_ZERO 8
|
||||
#define NUM_NO_FRACTION 16
|
||||
#define NUM_AFFECT_ALL 32
|
||||
|
||||
/* NDOFINPUT FLAGS */
|
||||
#define NDOF_INIT 1
|
||||
|
||||
/* transinfo->state */
|
||||
#define TRANS_RUNNING 0
|
||||
#define TRANS_CONFIRM 1
|
||||
#define TRANS_CANCEL 2
|
||||
|
||||
/* transinfo->flag */
|
||||
#define T_OBJECT (1 << 0)
|
||||
#define T_EDIT (1 << 1)
|
||||
#define T_POSE (1 << 2)
|
||||
#define T_TEXTURE (1 << 3)
|
||||
#define T_CAMERA (1 << 4)
|
||||
// when shift pressed, higher resolution transform. cannot rely on G.qual, need event!
|
||||
#define T_SHIFT_MOD (1 << 5)
|
||||
// trans on points, having no rotation/scale
|
||||
#define T_POINTS (1 << 6)
|
||||
// for manipulator exceptions, like scaling using center point, drawing help lines
|
||||
#define T_USES_MANIPULATOR (1 << 7)
|
||||
|
||||
/* restrictions flags */
|
||||
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
|
||||
#define T_NO_CONSTRAINT (1 << 8)
|
||||
#define T_NULL_ONE (1 << 9)
|
||||
#define T_NO_ZERO (1 << 10)
|
||||
|
||||
#define T_PROP_EDIT (1 << 11)
|
||||
#define T_PROP_CONNECTED (1 << 12)
|
||||
|
||||
/* if MMB is pressed or not */
|
||||
#define T_MMB_PRESSED (1 << 13)
|
||||
|
||||
#define T_V3D_ALIGN (1 << 14)
|
||||
/* for 2d views like uv or ipo */
|
||||
#define T_2D_EDIT (1 << 15)
|
||||
#define T_CLIP_UV (1 << 16)
|
||||
|
||||
#define T_FREE_CUSTOMDATA (1 << 17)
|
||||
/* auto-ik is on */
|
||||
#define T_AUTOIK (1 << 18)
|
||||
|
||||
/* ******************************************************************************** */
|
||||
|
||||
/* transinfo->con->mode */
|
||||
#define CON_APPLY 1
|
||||
#define CON_AXIS0 2
|
||||
#define CON_AXIS1 4
|
||||
#define CON_AXIS2 8
|
||||
#define CON_SELECT 16
|
||||
#define CON_NOFLIP 32 /* does not reorient vector to face viewport when on */
|
||||
#define CON_LOCAL 64
|
||||
#define CON_USER 128
|
||||
|
||||
/* transdata->flag */
|
||||
#define TD_SELECTED 1
|
||||
#define TD_ACTIVE (1 << 1)
|
||||
#define TD_NOACTION (1 << 2)
|
||||
#define TD_USEQUAT (1 << 3)
|
||||
#define TD_NOTCONNECTED (1 << 4)
|
||||
#define TD_SINGLESIZE (1 << 5) /* used for scaling of MetaElem->rad */
|
||||
#ifdef WITH_VERSE
|
||||
#define TD_VERSE_OBJECT (1 << 6)
|
||||
#define TD_VERSE_VERT (1 << 7)
|
||||
#endif
|
||||
#define TD_TIMEONLY (1 << 8)
|
||||
#define TD_NOCENTER (1 << 9)
|
||||
#define TD_NO_EXT (1 << 10) /* ext abused for particle key timing */
|
||||
#define TD_SKIP (1 << 11) /* don't transform this data */
|
||||
#define TD_BEZTRIPLE (1 << 12) /* if this is a bez triple, we need to restore the handles, if this is set transdata->misc.hdata needs freeing */
|
||||
#define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */
|
||||
|
||||
/* transsnap->status */
|
||||
#define SNAP_ON 1
|
||||
#define TARGET_INIT 2
|
||||
#define POINT_INIT 4
|
||||
|
||||
/* transsnap->modePoint */
|
||||
#define SNAP_GRID 0
|
||||
#define SNAP_GEO 1
|
||||
|
||||
/* transsnap->modeTarget */
|
||||
#define SNAP_CLOSEST 0
|
||||
#define SNAP_CENTER 1
|
||||
#define SNAP_MEDIAN 2
|
||||
#define SNAP_ACTIVE 3
|
||||
|
||||
|
||||
void TFM_OT_transform(struct wmOperatorType *ot);
|
||||
|
||||
void initTransform(struct bContext *C, struct TransInfo *t, int mode, int context, struct wmEvent *event);
|
||||
void transformEvent(TransInfo *t, struct wmEvent *event);
|
||||
void transformApply(TransInfo *t);
|
||||
int transformEnd(TransInfo *t);
|
||||
|
||||
void setTransformViewMatrices(TransInfo *t);
|
||||
void convertViewVec(TransInfo *t, float *vec, short dx, short dy);
|
||||
void projectIntView(TransInfo *t, float *vec, int *adr);
|
||||
void projectFloatView(TransInfo *t, float *vec, float *adr);
|
||||
|
||||
void convertVecToDisplayNum(float *vec, float *num);
|
||||
void convertDisplayNumToVec(float *num, float *vec);
|
||||
|
||||
void initWarp(TransInfo *t);
|
||||
int handleEventWarp(TransInfo *t, struct wmEvent *event);
|
||||
int Warp(TransInfo *t, short mval[2]);
|
||||
|
||||
void initShear(TransInfo *t);
|
||||
int handleEventShear(TransInfo *t, struct wmEvent *event);
|
||||
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]);
|
||||
|
||||
void initShrinkFatten(TransInfo *t);
|
||||
int ShrinkFatten(TransInfo *t, short mval[2]);
|
||||
|
||||
void initTilt(TransInfo *t);
|
||||
int Tilt(TransInfo *t, short mval[2]);
|
||||
|
||||
void initCurveShrinkFatten(TransInfo *t);
|
||||
int CurveShrinkFatten(TransInfo *t, short mval[2]);
|
||||
|
||||
void initTrackball(TransInfo *t);
|
||||
int Trackball(TransInfo *t, short mval[2]);
|
||||
|
||||
void initPushPull(TransInfo *t);
|
||||
int PushPull(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBevel(TransInfo *t);
|
||||
int handleEventBevel(TransInfo *t, struct wmEvent *event);
|
||||
int Bevel(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBevelWeight(TransInfo *t);
|
||||
int BevelWeight(TransInfo *t, short mval[2]);
|
||||
|
||||
void initCrease(TransInfo *t);
|
||||
int Crease(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBoneSize(TransInfo *t);
|
||||
int BoneSize(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBoneEnvelope(TransInfo *t);
|
||||
int BoneEnvelope(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBoneRoll(TransInfo *t);
|
||||
int BoneRoll(TransInfo *t, short mval[2]);
|
||||
|
||||
void initTimeTranslate(TransInfo *t);
|
||||
int TimeTranslate(TransInfo *t, short mval[2]);
|
||||
|
||||
void initTimeSlide(TransInfo *t);
|
||||
int TimeSlide(TransInfo *t, short mval[2]);
|
||||
|
||||
void initTimeScale(TransInfo *t);
|
||||
int TimeScale(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBakeTime(TransInfo *t);
|
||||
int BakeTime(TransInfo *t, short mval[2]);
|
||||
|
||||
void initMirror(TransInfo *t);
|
||||
int Mirror(TransInfo *t, short mval[2]);
|
||||
|
||||
void initAlign(TransInfo *t);
|
||||
int Align(TransInfo *t, short mval[2]);
|
||||
|
||||
/*********************** transform_conversions.c ********** */
|
||||
struct ListBase;
|
||||
void flushTransGPactionData(TransInfo *t);
|
||||
void flushTransIpoData(TransInfo *t);
|
||||
void flushTransUVs(TransInfo *t);
|
||||
void flushTransParticles(TransInfo *t);
|
||||
int clipUVTransform(TransInfo *t, float *vec, int resize);
|
||||
|
||||
/*********************** exported from transform_manipulator.c ********** */
|
||||
void draw_manipulator_ext(struct ScrArea *sa, int type, char axis, int col, float vec[3], float mat[][3]);
|
||||
int calc_manipulator_stats(struct ScrArea *sa);
|
||||
float get_drawsize(struct View3D *v3d, struct ScrArea *sa, float *co);
|
||||
|
||||
/*********************** TransData Creation and General Handling *********** */
|
||||
void createTransData(struct bContext *C, TransInfo *t);
|
||||
void sort_trans_data_dist(TransInfo *t);
|
||||
void add_tdi_poin(float *poin, float *old, float delta);
|
||||
void special_aftertrans_update(TransInfo *t);
|
||||
|
||||
void transform_autoik_update(TransInfo *t, short mode);
|
||||
|
||||
/* auto-keying stuff used by special_aftertrans_update */
|
||||
short autokeyframe_cfra_can_key(struct Object *ob);
|
||||
void autokeyframe_ob_cb_func(struct Object *ob, int tmode);
|
||||
void autokeyframe_pose_cb_func(struct Object *ob, int tmode, short targetless_ik);
|
||||
|
||||
/*********************** Constraints *****************************/
|
||||
|
||||
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 constraintNumInput(TransInfo *t, float vec[3]);
|
||||
|
||||
void getConstraintMatrix(TransInfo *t);
|
||||
int isLockConstraint(TransInfo *t);
|
||||
int getConstraintSpaceDimension(TransInfo *t);
|
||||
char constraintModeToChar(TransInfo *t);
|
||||
|
||||
void startConstraint(TransInfo *t);
|
||||
void stopConstraint(TransInfo *t);
|
||||
|
||||
void initSelectConstraint(TransInfo *t, float mtx[3][3]);
|
||||
void selectConstraint(TransInfo *t);
|
||||
void postSelectConstraint(TransInfo *t);
|
||||
|
||||
void setNearestAxis(TransInfo *t);
|
||||
|
||||
/*********************** Snapping ********************************/
|
||||
|
||||
typedef enum {
|
||||
NO_GEARS = 0,
|
||||
BIG_GEARS = 1,
|
||||
SMALL_GEARS = 2
|
||||
} GearsType;
|
||||
|
||||
void snapGrid(TransInfo *t, float *val);
|
||||
void snapGridAction(TransInfo *t, float *val, GearsType action);
|
||||
|
||||
void initSnapping(struct TransInfo *t);
|
||||
void applySnapping(TransInfo *t, float *vec);
|
||||
void resetSnapping(TransInfo *t);
|
||||
int handleSnapping(TransInfo *t, struct wmEvent *event);
|
||||
void drawSnapping(TransInfo *t);
|
||||
int usingSnappingNormal(TransInfo *t);
|
||||
int validSnappingNormal(TransInfo *t);
|
||||
|
||||
/*********************** Generics ********************************/
|
||||
|
||||
void initTransInfo(struct bContext *C, TransInfo *t, struct wmEvent *event);
|
||||
void postTrans (TransInfo *t);
|
||||
void resetTransRestrictions(TransInfo *t);
|
||||
|
||||
void drawLine(float *center, float *dir, char axis, short options);
|
||||
|
||||
TransDataCurveHandleFlags *initTransDataCurveHandes(TransData *td, struct BezTriple *bezt);
|
||||
|
||||
/* DRAWLINE options flags */
|
||||
#define DRAWLIGHT 1
|
||||
#define DRAWDASHED 2
|
||||
#define DRAWBOLD 4
|
||||
|
||||
void applyTransObjects(TransInfo *t);
|
||||
void restoreTransObjects(TransInfo *t);
|
||||
void recalcData(TransInfo *t);
|
||||
|
||||
void calculateCenter(TransInfo *t);
|
||||
void calculateCenter2D(TransInfo *t);
|
||||
void calculateCenterBound(TransInfo *t);
|
||||
void calculateCenterMedian(TransInfo *t);
|
||||
void calculateCenterCursor(TransInfo *t);
|
||||
|
||||
void calculateCenterCursor2D(TransInfo *t);
|
||||
void calculatePropRatio(TransInfo *t);
|
||||
|
||||
void getViewVector(TransInfo *t, float coord[3], float vec[3]);
|
||||
|
||||
TransInfo * BIF_GetTransInfo(void);
|
||||
|
||||
/*********************** NumInput ********************************/
|
||||
|
||||
void initNumInput(NumInput *n);
|
||||
void outputNumInput(NumInput *n, char *str);
|
||||
short hasNumInput(NumInput *n);
|
||||
void applyNumInput(NumInput *n, float *vec);
|
||||
char handleNumInput(NumInput *n, struct wmEvent *event);
|
||||
|
||||
/*********************** NDofInput ********************************/
|
||||
|
||||
void initNDofInput(NDofInput *n);
|
||||
int hasNDofInput(NDofInput *n);
|
||||
void applyNDofInput(NDofInput *n, float *vec);
|
||||
int handleNDofInput(NDofInput *n, struct wmEvent *event);
|
||||
|
||||
/* handleNDofInput return values */
|
||||
#define NDOF_REFRESH 1
|
||||
#define NDOF_NOMOVE 2
|
||||
#define NDOF_CONFIRM 3
|
||||
#define NDOF_CANCEL 4
|
||||
|
||||
|
||||
/*********************** TransSpace ******************************/
|
||||
|
||||
int manageObjectSpace(int confirm, int set);
|
||||
int manageMeshSpace(int confirm, int set);
|
||||
int manageBoneSpace(int confirm, int set);
|
||||
|
||||
/* 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(float mat[3][3], char name[]);
|
||||
int addObjectSpace(struct Object *ob);
|
||||
void applyTransformOrientation(void);
|
||||
|
||||
|
||||
#define ORIENTATION_NONE 0
|
||||
#define ORIENTATION_NORMAL 1
|
||||
#define ORIENTATION_VERT 2
|
||||
#define ORIENTATION_EDGE 3
|
||||
#define ORIENTATION_FACE 4
|
||||
|
||||
int getTransformOrientation(struct bContext *C, float normal[3], float plane[3], int activeOnly);
|
||||
int createSpaceNormal(float mat[3][3], float normal[3]);
|
||||
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
|
||||
|
||||
#endif
|
||||
|
||||
|
1070
source/blender/editors/transform/transform_constraints.c
Normal file
1070
source/blender/editors/transform/transform_constraints.c
Normal file
File diff suppressed because it is too large
Load Diff
4461
source/blender/editors/transform/transform_conversions.c
Normal file
4461
source/blender/editors/transform/transform_conversions.c
Normal file
File diff suppressed because it is too large
Load Diff
1235
source/blender/editors/transform/transform_generics.c
Normal file
1235
source/blender/editors/transform/transform_generics.c
Normal file
File diff suppressed because it is too large
Load Diff
1683
source/blender/editors/transform/transform_manipulator.c
Normal file
1683
source/blender/editors/transform/transform_manipulator.c
Normal file
File diff suppressed because it is too large
Load Diff
155
source/blender/editors/transform/transform_ndofinput.c
Normal file
155
source/blender/editors/transform/transform_ndofinput.c
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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: all of this file.
|
||||
*
|
||||
* Contributor(s): Martin Poirier
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <math.h> /* fabs */
|
||||
#include <stdio.h> /* for sprintf */
|
||||
|
||||
#include "BKE_global.h" /* for G */
|
||||
#include "BKE_utildefines.h" /* ABS */
|
||||
|
||||
#include "DNA_view3d_types.h" /* for G.vd (view3d) */
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "transform.h"
|
||||
|
||||
static int updateNDofMotion(NDofInput *n); // return 0 when motion is null
|
||||
static void resetNDofInput(NDofInput *n);
|
||||
|
||||
void initNDofInput(NDofInput *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
n->flag = 0;
|
||||
n->axis = 0;
|
||||
|
||||
resetNDofInput(n);
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
n->factor[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void resetNDofInput(NDofInput *n)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
n->fval[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int handleNDofInput(NDofInput *n, wmEvent *event)
|
||||
{
|
||||
int retval = 0;
|
||||
// TRANSFORM_FIX_ME
|
||||
#if 0
|
||||
switch(event)
|
||||
{
|
||||
case NDOFMOTION:
|
||||
if (updateNDofMotion(n) == 0)
|
||||
{
|
||||
retval = NDOF_NOMOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = NDOF_REFRESH;
|
||||
}
|
||||
break;
|
||||
case NDOFBUTTON:
|
||||
if (val == 1)
|
||||
{
|
||||
retval = NDOF_CONFIRM;
|
||||
}
|
||||
else if (val == 2)
|
||||
{
|
||||
retval = NDOF_CANCEL;
|
||||
resetNDofInput(n);
|
||||
n->flag &= ~NDOF_INIT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int hasNDofInput(NDofInput *n)
|
||||
{
|
||||
return (n->flag & NDOF_INIT) == NDOF_INIT;
|
||||
}
|
||||
|
||||
void applyNDofInput(NDofInput *n, float *vec)
|
||||
{
|
||||
if (hasNDofInput(n))
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < 6; i++)
|
||||
{
|
||||
if (n->axis & (1 << i))
|
||||
{
|
||||
vec[j] = n->fval[i] * n->factor[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int updateNDofMotion(NDofInput *n)
|
||||
{
|
||||
float fval[7];
|
||||
int i;
|
||||
int retval = 0;
|
||||
|
||||
// TRANSFORM_FIX_ME
|
||||
#if 0
|
||||
getndof(fval);
|
||||
|
||||
if (G.vd->ndoffilter)
|
||||
filterNDOFvalues(fval);
|
||||
#endif
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
if (!retval && fval[i] != 0.0f)
|
||||
{
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
n->fval[i] += fval[i] / 1024.0f;
|
||||
}
|
||||
|
||||
n->flag |= NDOF_INIT;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
258
source/blender/editors/transform/transform_numinput.c
Normal file
258
source/blender/editors/transform/transform_numinput.c
Normal file
@ -0,0 +1,258 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <math.h> /* fabs */
|
||||
#include <stdio.h> /* for sprintf */
|
||||
|
||||
#include "BKE_global.h" /* for G */
|
||||
#include "BKE_utildefines.h" /* ABS */
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "transform.h"
|
||||
|
||||
/* ************************** Functions *************************** */
|
||||
|
||||
/* ************************** NUMINPUT **************************** */
|
||||
|
||||
void initNumInput(NumInput *n)
|
||||
{
|
||||
n->flag =
|
||||
n->idx =
|
||||
n->idx_max =
|
||||
n->ctrl[0] =
|
||||
n->ctrl[1] =
|
||||
n->ctrl[2] = 0;
|
||||
|
||||
n->val[0] =
|
||||
n->val[1] =
|
||||
n->val[2] = 0.0f;
|
||||
}
|
||||
|
||||
void outputNumInput(NumInput *n, char *str)
|
||||
{
|
||||
char cur;
|
||||
short i, j;
|
||||
|
||||
for (j=0; j<=n->idx_max; j++) {
|
||||
/* if AFFECTALL and no number typed and cursor not on number, use first number */
|
||||
if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
|
||||
i = 0;
|
||||
else
|
||||
i = j;
|
||||
|
||||
if (n->idx != i)
|
||||
cur = ' ';
|
||||
else
|
||||
cur = '|';
|
||||
|
||||
if( n->val[i] > 1e10 || n->val[i] < -1e10 )
|
||||
sprintf(&str[j*20], "%.4e%c", n->val[i], cur);
|
||||
else
|
||||
switch (n->ctrl[i]) {
|
||||
case 0:
|
||||
sprintf(&str[j*20], "NONE%c", cur);
|
||||
break;
|
||||
case 1:
|
||||
case -1:
|
||||
sprintf(&str[j*20], "%.0f%c", n->val[i], cur);
|
||||
break;
|
||||
case 10:
|
||||
case -10:
|
||||
sprintf(&str[j*20], "%.f.%c", n->val[i], cur);
|
||||
break;
|
||||
case 100:
|
||||
case -100:
|
||||
sprintf(&str[j*20], "%.1f%c", n->val[i], cur);
|
||||
break;
|
||||
case 1000:
|
||||
case -1000:
|
||||
sprintf(&str[j*20], "%.2f%c", n->val[i], cur);
|
||||
break;
|
||||
case 10000:
|
||||
case -10000:
|
||||
sprintf(&str[j*20], "%.3f%c", n->val[i], cur);
|
||||
break;
|
||||
default:
|
||||
sprintf(&str[j*20], "%.4e%c", n->val[i], cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
short hasNumInput(NumInput *n)
|
||||
{
|
||||
short i;
|
||||
|
||||
for (i=0; i<=n->idx_max; i++) {
|
||||
if (n->ctrl[i])
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void applyNumInput(NumInput *n, float *vec)
|
||||
{
|
||||
short i, j;
|
||||
float val[3];
|
||||
|
||||
if (hasNumInput(n)) {
|
||||
convertDisplayNumToVec(n->val, val);
|
||||
|
||||
for (j=0; j<=n->idx_max; j++) {
|
||||
/* if AFFECTALL and no number typed and cursor not on number, use first number */
|
||||
if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
|
||||
i = 0;
|
||||
else
|
||||
i = j;
|
||||
|
||||
if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
|
||||
vec[j] = 1.0f;
|
||||
}
|
||||
else if (val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
|
||||
vec[j] = 0.0001f;
|
||||
}
|
||||
else {
|
||||
vec[j] = val[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char handleNumInput(NumInput *n, wmEvent *event)
|
||||
{
|
||||
float Val = 0;
|
||||
short idx = n->idx, idx_max = n->idx_max;
|
||||
|
||||
switch (event->type) {
|
||||
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->flag & NUM_NO_FRACTION)
|
||||
break;
|
||||
|
||||
switch (n->ctrl[idx])
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
n->ctrl[idx] = 10;
|
||||
break;
|
||||
case -1:
|
||||
n->ctrl[idx] = -10;
|
||||
}
|
||||
break;
|
||||
case PADMINUS:
|
||||
if(event->alt)
|
||||
break;
|
||||
case MINUSKEY:
|
||||
if (n->flag & NUM_NO_NEGATIVE)
|
||||
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 (fabs(n->val[idx]) > 9999999.0f);
|
||||
else 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 {
|
||||
/* float resolution breaks when over six digits after comma */
|
||||
if( ABS(n->ctrl[idx]) < 10000000) {
|
||||
n->val[idx] += Val / (float)n->ctrl[idx];
|
||||
n->ctrl[idx] *= 10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* REDRAW SINCE NUMBERS HAVE CHANGED */
|
||||
return 1;
|
||||
}
|
781
source/blender/editors/transform/transform_orientations.c
Normal file
781
source/blender/editors/transform/transform_orientations.c
Normal file
@ -0,0 +1,781 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s): Martin Poirier
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
//#include "BIF_editmesh.h"
|
||||
#include "BIF_editarmature.h"
|
||||
//#include "BIF_interface.h"
|
||||
//#include "BIF_space.h"
|
||||
//#include "BIF_toolbox.h"
|
||||
|
||||
#include "transform.h"
|
||||
|
||||
#if 0 // TRANSFORM_FIX_ME
|
||||
|
||||
/* *********************** TransSpace ************************** */
|
||||
|
||||
void BIF_clearTransformOrientation(void)
|
||||
{
|
||||
ListBase *transform_spaces = &G.scene->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 */
|
||||
}
|
||||
|
||||
void BIF_manageTransformOrientation(int confirm, int set) {
|
||||
Object *ob = OBACT;
|
||||
int index = -1;
|
||||
|
||||
if (G.obedit) {
|
||||
if (G.obedit->type == OB_MESH)
|
||||
index = manageMeshSpace(confirm, set);
|
||||
else if (G.obedit->type == OB_ARMATURE)
|
||||
index = manageBoneSpace(confirm, set);
|
||||
}
|
||||
else if (ob && (ob->flag & OB_POSEMODE)) {
|
||||
index = manageBoneSpace(confirm, set);
|
||||
}
|
||||
else {
|
||||
index = manageObjectSpace(confirm, set);
|
||||
}
|
||||
|
||||
if (set && index != -1)
|
||||
{
|
||||
BIF_selectTransformOrientationFromIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
int manageObjectSpace(int confirm, int set) {
|
||||
Base *base = BASACT;
|
||||
|
||||
if (base == NULL)
|
||||
return -1;
|
||||
|
||||
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(base->object);
|
||||
}
|
||||
|
||||
/* return 1 on confirm */
|
||||
int confirmSpace(int set, char text[])
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (pupmenu(menu) == 1) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int manageBoneSpace(int confirm, int set) {
|
||||
float mat[3][3];
|
||||
float normal[3], plane[3];
|
||||
char name[36] = "";
|
||||
int index;
|
||||
|
||||
getTransformOrientation(normal, plane, 0);
|
||||
|
||||
if (confirm == 0 && confirmSpace(set, "Bone") == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||
error("Cannot use zero-length bone");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(name, "Bone");
|
||||
|
||||
/* Input name */
|
||||
sbutton(name, 1, 35, "name: ");
|
||||
|
||||
index = addMatrixSpace(mat, name);
|
||||
return index;
|
||||
}
|
||||
|
||||
int manageMeshSpace(int confirm, int set) {
|
||||
float mat[3][3];
|
||||
float normal[3], plane[3];
|
||||
char name[36] = "";
|
||||
int index;
|
||||
int type;
|
||||
|
||||
type = getTransformOrientation(normal, plane, 0);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ORIENTATION_VERT:
|
||||
if (confirm == 0 && confirmSpace(set, "vertex") == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (createSpaceNormal(mat, normal) == 0) {
|
||||
error("Cannot use vertex with zero-length normal");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(name, "Vertex");
|
||||
break;
|
||||
case ORIENTATION_EDGE:
|
||||
if (confirm == 0 && confirmSpace(set, "Edge") == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||
error("Cannot use zero-length edge");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(name, "Edge");
|
||||
break;
|
||||
case ORIENTATION_FACE:
|
||||
if (confirm == 0 && confirmSpace(set, "Face") == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||
error("Cannot use zero-area face");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(name, "Face");
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Input name */
|
||||
sbutton(name, 1, 35, "name: ");
|
||||
|
||||
index = addMatrixSpace(mat, name);
|
||||
return index;
|
||||
}
|
||||
|
||||
int createSpaceNormal(float mat[3][3], float normal[3])
|
||||
{
|
||||
float tangent[3] = {0.0f, 0.0f, 1.0f};
|
||||
|
||||
VECCOPY(mat[2], normal);
|
||||
if (Normalize(mat[2]) == 0.0f) {
|
||||
return 0; /* error return */
|
||||
}
|
||||
|
||||
Crossf(mat[0], mat[2], tangent);
|
||||
if (Inpf(mat[0], mat[0]) == 0.0f) {
|
||||
tangent[0] = 1.0f;
|
||||
tangent[1] = tangent[2] = 0.0f;
|
||||
Crossf(mat[0], tangent, mat[2]);
|
||||
}
|
||||
|
||||
Crossf(mat[1], mat[2], mat[0]);
|
||||
|
||||
Mat3Ortho(mat);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3])
|
||||
{
|
||||
VECCOPY(mat[2], normal);
|
||||
if (Normalize(mat[2]) == 0.0f) {
|
||||
return 0; /* error return */
|
||||
}
|
||||
|
||||
/* preempt zero length tangent from causing trouble */
|
||||
if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0)
|
||||
{
|
||||
tangent[2] = 1;
|
||||
}
|
||||
|
||||
Crossf(mat[0], mat[2], tangent);
|
||||
if (Normalize(mat[0]) == 0.0f) {
|
||||
return 0; /* error return */
|
||||
}
|
||||
|
||||
Crossf(mat[1], mat[2], mat[0]);
|
||||
|
||||
Mat3Ortho(mat);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int addObjectSpace(Object *ob) {
|
||||
float mat[3][3];
|
||||
char name[36] = "";
|
||||
|
||||
Mat3CpyMat4(mat, ob->obmat);
|
||||
Mat3Ortho(mat);
|
||||
|
||||
strncpy(name, ob->id.name+2, 35);
|
||||
|
||||
/* Input name */
|
||||
sbutton(name, 1, 35, "name: ");
|
||||
|
||||
return addMatrixSpace(mat, name);
|
||||
}
|
||||
|
||||
int addMatrixSpace(float mat[3][3], char name[]) {
|
||||
ListBase *transform_spaces = &G.scene->transform_spaces;
|
||||
TransformOrientation *ts;
|
||||
int index = 0;
|
||||
|
||||
/* 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 not, create a new one */
|
||||
if (ts == NULL)
|
||||
{
|
||||
ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix");
|
||||
BLI_addtail(transform_spaces, ts);
|
||||
strncpy(ts->name, name, 35);
|
||||
}
|
||||
|
||||
/* copy matrix into transform space */
|
||||
Mat3CpyMat3(ts->mat, mat);
|
||||
|
||||
BIF_undo_push("Add/Update Transform Orientation");
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void BIF_removeTransformOrientation(TransformOrientation *target) {
|
||||
ListBase *transform_spaces = &G.scene->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) {
|
||||
if (selected_index == i) {
|
||||
G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
|
||||
}
|
||||
else if (selected_index > i)
|
||||
G.vd->twmode--;
|
||||
|
||||
BLI_freelinkN(transform_spaces, ts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BIF_undo_push("Remove Transform Orientation");
|
||||
}
|
||||
|
||||
void BIF_selectTransformOrientation(TransformOrientation *target) {
|
||||
ListBase *transform_spaces = &G.scene->transform_spaces;
|
||||
TransformOrientation *ts = transform_spaces->first;
|
||||
int i;
|
||||
|
||||
for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
|
||||
if (ts == target) {
|
||||
G.vd->twmode = V3D_MANIP_CUSTOM + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BIF_selectTransformOrientationFromIndex(int index) {
|
||||
G.vd->twmode = V3D_MANIP_CUSTOM + index;
|
||||
}
|
||||
|
||||
char * BIF_menustringTransformOrientation(char *title) {
|
||||
char menu[] = "%t|Global%x0|Local%x1|Normal%x2|View%x3";
|
||||
ListBase *transform_spaces = &G.scene->transform_spaces;
|
||||
TransformOrientation *ts;
|
||||
int i = V3D_MANIP_CUSTOM;
|
||||
char *str_menu, *p;
|
||||
|
||||
|
||||
str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + 40 * BIF_countTransformOrientation(), "UserTransSpace from matrix");
|
||||
p = str_menu;
|
||||
|
||||
p += sprintf(str_menu, "%s", title);
|
||||
p += sprintf(p, "%s", menu);
|
||||
|
||||
for (ts = transform_spaces->first; ts; ts = ts->next) {
|
||||
p += sprintf(p, "|%s%%x%d", ts->name, i++);
|
||||
}
|
||||
|
||||
return str_menu;
|
||||
}
|
||||
|
||||
int BIF_countTransformOrientation() {
|
||||
ListBase *transform_spaces = &G.scene->transform_spaces;
|
||||
TransformOrientation *ts;
|
||||
int count = 0;
|
||||
|
||||
for (ts = transform_spaces->first; ts; ts = ts->next) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void applyTransformOrientation() {
|
||||
TransInfo *t = BIF_GetTransInfo();
|
||||
TransformOrientation *ts;
|
||||
int selected_index = (G.vd->twmode - V3D_MANIP_CUSTOM);
|
||||
int i;
|
||||
|
||||
if (selected_index >= 0) {
|
||||
for (i = 0, ts = G.scene->transform_spaces.first; ts; ts = ts->next, i++) {
|
||||
if (selected_index == i) {
|
||||
strcpy(t->spacename, ts->name);
|
||||
Mat3CpyMat3(t->spacemtx, ts->mat);
|
||||
Mat4CpyMat3(G.vd->twmat, ts->mat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TRANSFORM_FIX_ME
|
||||
|
||||
static int count_bone_select(bArmature *arm, ListBase *lb, int do_it)
|
||||
{
|
||||
Bone *bone;
|
||||
int do_next;
|
||||
int total = 0;
|
||||
|
||||
for(bone= lb->first; bone; bone= bone->next) {
|
||||
bone->flag &= ~BONE_TRANSFORM;
|
||||
do_next = do_it;
|
||||
if(do_it) {
|
||||
if(bone->layer & arm->layer) {
|
||||
if (bone->flag & BONE_SELECTED) {
|
||||
bone->flag |= BONE_TRANSFORM;
|
||||
total++;
|
||||
do_next= 0; // no transform on children if one parent bone is selected
|
||||
}
|
||||
}
|
||||
}
|
||||
total += count_bone_select(arm, &bone->childbase, do_next);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int getTransformOrientation(bContext *C, float normal[3], float plane[3], int activeOnly)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
View3D *v3d = sa->spacedata.first;
|
||||
Base *base;
|
||||
Object *ob = OBACT;
|
||||
int result = ORIENTATION_NONE;
|
||||
|
||||
normal[0] = normal[1] = normal[2] = 0;
|
||||
plane[0] = plane[1] = plane[2] = 0;
|
||||
|
||||
if(G.obedit)
|
||||
{
|
||||
float imat[3][3], mat[3][3];
|
||||
|
||||
/* we need the transpose of the inverse for a normal... */
|
||||
Mat3CpyMat4(imat, ob->obmat);
|
||||
|
||||
Mat3Inv(mat, imat);
|
||||
Mat3Transp(mat);
|
||||
|
||||
ob= G.obedit;
|
||||
|
||||
if(G.obedit->type==OB_MESH)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve;
|
||||
EditSelection ese;
|
||||
float vec[3]= {0,0,0};
|
||||
|
||||
/* USE LAST SELECTED WITH ACTIVE */
|
||||
if (activeOnly && EM_get_actSelection(&ese))
|
||||
{
|
||||
EM_editselection_normal(normal, &ese);
|
||||
EM_editselection_plane(plane, &ese);
|
||||
|
||||
switch (ese.type)
|
||||
{
|
||||
case EDITVERT:
|
||||
result = ORIENTATION_VERT;
|
||||
break;
|
||||
case EDITEDGE:
|
||||
result = ORIENTATION_EDGE;
|
||||
break;
|
||||
case EDITFACE:
|
||||
result = ORIENTATION_FACE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (G.totfacesel >= 1)
|
||||
{
|
||||
EditFace *efa;
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next)
|
||||
{
|
||||
if(efa->f & SELECT)
|
||||
{
|
||||
VECADD(normal, normal, efa->n);
|
||||
VecSubf(vec, efa->v2->co, efa->v1->co);
|
||||
VECADD(plane, plane, vec);
|
||||
}
|
||||
}
|
||||
|
||||
result = ORIENTATION_FACE;
|
||||
}
|
||||
else if (G.totvertsel == 3)
|
||||
{
|
||||
EditVert *v1 = NULL, *v2 = NULL, *v3 = NULL;
|
||||
float cotangent[3];
|
||||
|
||||
for (eve = em->verts.first; eve; eve = eve->next)
|
||||
{
|
||||
if ( eve->f & SELECT ) {
|
||||
if (v1 == NULL) {
|
||||
v1 = eve;
|
||||
}
|
||||
else if (v2 == NULL) {
|
||||
v2 = eve;
|
||||
}
|
||||
else {
|
||||
v3 = eve;
|
||||
|
||||
VecSubf(plane, v2->co, v1->co);
|
||||
VecSubf(cotangent, v3->co, v2->co);
|
||||
Crossf(normal, cotangent, plane);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if there's an edge available, use that for the tangent */
|
||||
if (G.totedgesel >= 1)
|
||||
{
|
||||
EditEdge *eed = NULL;
|
||||
|
||||
for(eed= em->edges.first; eed; eed= eed->next) {
|
||||
if(eed->f & SELECT) {
|
||||
VecSubf(plane, eed->v2->co, eed->v1->co);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = ORIENTATION_FACE;
|
||||
}
|
||||
else if (G.totedgesel == 1)
|
||||
{
|
||||
EditEdge *eed;
|
||||
|
||||
for(eed= em->edges.first; eed; eed= eed->next) {
|
||||
if(eed->f & SELECT) {
|
||||
/* use average vert normals as plane and edge vector as normal */
|
||||
VECCOPY(plane, eed->v1->no);
|
||||
VECADD(plane, plane, eed->v2->no);
|
||||
VecSubf(normal, eed->v2->co, eed->v1->co);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = ORIENTATION_EDGE;
|
||||
}
|
||||
else if (G.totvertsel == 2)
|
||||
{
|
||||
EditVert *v1 = NULL, *v2 = NULL;
|
||||
|
||||
for (eve = em->verts.first; eve; eve = eve->next)
|
||||
{
|
||||
if ( eve->f & SELECT ) {
|
||||
if (v1 == NULL) {
|
||||
v1 = eve;
|
||||
}
|
||||
else {
|
||||
v2 = eve;
|
||||
|
||||
VECCOPY(plane, v1->no);
|
||||
VECADD(plane, plane, v2->no);
|
||||
VecSubf(normal, v2->co, v1->co);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = ORIENTATION_EDGE;
|
||||
}
|
||||
else if (G.totvertsel == 1)
|
||||
{
|
||||
for (eve = em->verts.first; eve; eve = eve->next)
|
||||
{
|
||||
if ( eve->f & SELECT ) {
|
||||
VECCOPY(normal, eve->no);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = ORIENTATION_VERT;
|
||||
}
|
||||
else if (G.totvertsel > 3)
|
||||
{
|
||||
normal[0] = normal[1] = normal[2] = 0;
|
||||
|
||||
for (eve = em->verts.first; eve; eve = eve->next)
|
||||
{
|
||||
if ( eve->f & SELECT ) {
|
||||
VecAddf(normal, normal, eve->no);
|
||||
}
|
||||
}
|
||||
Normalize(normal);
|
||||
result = ORIENTATION_VERT;
|
||||
}
|
||||
}
|
||||
} /* end editmesh */
|
||||
else if ELEM3(G.obedit->type, OB_CURVE, OB_SURF, OB_FONT)
|
||||
{
|
||||
extern ListBase editNurb; /* BOOO! go away stupid extern */
|
||||
Nurb *nu;
|
||||
BezTriple *bezt;
|
||||
int a;
|
||||
|
||||
for (nu = editNurb.first; nu; nu = nu->next)
|
||||
{
|
||||
/* only bezier has a normal */
|
||||
if((nu->type & 7) == CU_BEZIER)
|
||||
{
|
||||
bezt= nu->bezt;
|
||||
a= nu->pntsu;
|
||||
while(a--)
|
||||
{
|
||||
/* exception */
|
||||
if ( (bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT )
|
||||
{
|
||||
VecSubf(normal, bezt->vec[0], bezt->vec[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bezt->f1)
|
||||
{
|
||||
VecSubf(normal, bezt->vec[0], bezt->vec[1]);
|
||||
}
|
||||
if(bezt->f2)
|
||||
{
|
||||
VecSubf(normal, bezt->vec[0], bezt->vec[2]);
|
||||
}
|
||||
if(bezt->f3)
|
||||
{
|
||||
VecSubf(normal, bezt->vec[1], bezt->vec[2]);
|
||||
}
|
||||
}
|
||||
bezt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0)
|
||||
{
|
||||
result = ORIENTATION_NORMAL;
|
||||
}
|
||||
}
|
||||
else if(G.obedit->type==OB_MBALL)
|
||||
{
|
||||
/* editmball.c */
|
||||
extern ListBase editelems; /* go away ! */
|
||||
MetaElem *ml, *ml_sel = NULL;
|
||||
|
||||
/* loop and check that only one element is selected */
|
||||
for (ml = editelems.first; ml; ml = ml->next)
|
||||
{
|
||||
if (ml->flag & SELECT) {
|
||||
if (ml_sel == NULL)
|
||||
{
|
||||
ml_sel = ml;
|
||||
}
|
||||
else
|
||||
{
|
||||
ml_sel = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ml_sel)
|
||||
{
|
||||
float mat[4][4];
|
||||
|
||||
/* Rotation of MetaElem is stored in quat */
|
||||
QuatToMat4(ml_sel->quat, mat);
|
||||
|
||||
VECCOPY(normal, mat[2]);
|
||||
VECCOPY(plane, mat[1]);
|
||||
|
||||
VecMulf(plane, -1.0);
|
||||
|
||||
result = ORIENTATION_NORMAL;
|
||||
}
|
||||
}
|
||||
else if (G.obedit->type == OB_ARMATURE)
|
||||
{
|
||||
bArmature *arm = G.obedit->data;
|
||||
EditBone *ebone;
|
||||
|
||||
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
|
||||
if (arm->layer & ebone->layer)
|
||||
{
|
||||
if (ebone->flag & BONE_SELECTED)
|
||||
{
|
||||
float mat[3][3];
|
||||
float vec[3];
|
||||
VecSubf(vec, ebone->tail, ebone->head);
|
||||
Normalize(vec);
|
||||
VecAddf(normal, normal, vec);
|
||||
|
||||
vec_roll_to_mat3(vec, ebone->roll, mat);
|
||||
VecAddf(plane, plane, mat[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Normalize(normal);
|
||||
Normalize(plane);
|
||||
|
||||
if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0)
|
||||
{
|
||||
result = ORIENTATION_EDGE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Vectors from edges don't need the special transpose inverse multiplication */
|
||||
if (result == ORIENTATION_EDGE)
|
||||
{
|
||||
Mat4Mul3Vecfl(ob->obmat, normal);
|
||||
Mat4Mul3Vecfl(ob->obmat, plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mat3MulVecfl(mat, normal);
|
||||
Mat3MulVecfl(mat, plane);
|
||||
}
|
||||
}
|
||||
else if(ob && (ob->flag & OB_POSEMODE))
|
||||
{
|
||||
bArmature *arm= ob->data;
|
||||
bPoseChannel *pchan;
|
||||
int totsel;
|
||||
|
||||
totsel = count_bone_select(arm, &arm->bonebase, 1);
|
||||
if(totsel) {
|
||||
float imat[3][3], mat[3][3];
|
||||
|
||||
/* use channels to get stats */
|
||||
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
|
||||
VecAddf(normal, normal, pchan->pose_mat[2]);
|
||||
VecAddf(plane, plane, pchan->pose_mat[1]);
|
||||
}
|
||||
}
|
||||
VecMulf(plane, -1.0);
|
||||
|
||||
/* we need the transpose of the inverse for a normal... */
|
||||
Mat3CpyMat4(imat, ob->obmat);
|
||||
|
||||
Mat3Inv(mat, imat);
|
||||
Mat3Transp(mat);
|
||||
Mat3MulVecfl(mat, normal);
|
||||
Mat3MulVecfl(mat, plane);
|
||||
|
||||
result = ORIENTATION_EDGE;
|
||||
}
|
||||
}
|
||||
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE))
|
||||
{
|
||||
}
|
||||
else if(G.f & G_PARTICLEEDIT)
|
||||
{
|
||||
}
|
||||
else {
|
||||
/* we need the one selected object, if its not active */
|
||||
ob = OBACT;
|
||||
if(ob && !(ob->flag & SELECT)) ob = NULL;
|
||||
|
||||
for(base= G.scene->base.first; base; base= base->next) {
|
||||
if TESTBASELIB(v3d, base) {
|
||||
if(ob == NULL) {
|
||||
ob= base->object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VECCOPY(normal, ob->obmat[2]);
|
||||
VECCOPY(plane, ob->obmat[1]);
|
||||
result = ORIENTATION_NORMAL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
1306
source/blender/editors/transform/transform_snap.c
Normal file
1306
source/blender/editors/transform/transform_snap.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user