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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2008-01-13 21:24:09 +0300
committerMartin Poirier <theeth@yahoo.com>2008-01-13 21:24:09 +0300
commitd660e293650d88e00009ad315fb00ade71239621 (patch)
treea146ca02bf7424ce8857265273b5d2b69a23978f /source
parent67de673496a056c1f807717865a0f73c4e1aca9f (diff)
=== Custom Transform Orientation ===
Custom Orientations can be added with Ctrl-Shift-C (hotkey suggestions are welcomed), this adds and select the new alignment. Custom Orientations can also be added, deleted, selected from the Transform Orientations panel (View -> Transform Orientations). Standard orientations (global, local, normal, view) can also be selected from this panel. If you plan on using only a single custom orientation and don't really need a list, I suggest you use the hotkey as it adds and selects at the same time. Custom Orientations are save in the scene and are selected per 3D view (like normal orientation). Adding from an object, the orientation is a normalized version of the object's orientation. Adding from mesh data, a single element (vertex, edge, face) must be selected in its respective selection mode. Vertex orientation Z-axis is based on the normal, edge Z-axis on the edge itself (X-axis is on the XoY plane when possible, Y-axis is perpendicular to the rest). Face orientation Z-axis is the face normal, X-axis is perpendicular to the first edge, Y-axis is perpendicular to the rest. (More logical orientations can be suggested). I plan to add: 2 vertice (connected or not) => edge orientation , 3 vertice = face orientation Differences from the patch: - orientations no longer link back to the object they came from, everything is copy on creation. - orientations are overwritten based on name (if you add an orientation with the same name as one that already exists, it overwrites the old one)
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/writefile.c5
-rw-r--r--source/blender/include/BIF_space.h1
-rw-r--r--source/blender/include/BIF_transform.h14
-rw-r--r--source/blender/include/blendef.h1
-rw-r--r--source/blender/include/butspace.h2
-rw-r--r--source/blender/include/transform.h9
-rw-r--r--source/blender/makesdna/DNA_scene_types.h9
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h1
-rw-r--r--source/blender/src/drawview.c77
-rw-r--r--source/blender/src/header_info.c1
-rw-r--r--source/blender/src/header_view3d.c15
-rw-r--r--source/blender/src/space.c4
-rw-r--r--source/blender/src/transform.c313
-rw-r--r--source/blender/src/transform_constraints.c4
-rw-r--r--source/blender/src/transform_manipulator.c3
17 files changed, 451 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index cfec0e3b439..357b3c1bf54 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -153,6 +153,7 @@ void free_scene(Scene *sce)
}
BLI_freelistN(&sce->markers);
+ BLI_freelistN(&sce->transform_spaces);
BLI_freelistN(&sce->r.layers);
if(sce->toolsettings){
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 78d0bb8b90c..4812d7e3904 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3457,6 +3457,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
link_list(fd, &(sce->markers));
+ link_list(fd, &(sce->transform_spaces));
link_list(fd, &(sce->r.layers));
sce->nodetree= newdataadr(fd, sce->nodetree);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 87462ad78f6..9c013fbc1d0 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1401,6 +1401,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
MetaStack *ms;
Strip *strip;
TimeMarker *marker;
+ TransformOrientation *ts;
SceneRenderLayer *srl;
int a;
@@ -1505,6 +1506,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
for(marker= sce->markers.first; marker; marker= marker->next)
writestruct(wd, DATA, "TimeMarker", 1, marker);
+ /* writing dynamic list of TransformOrientations to the blend file */
+ for(ts = sce->transform_spaces.first; ts; ts = ts->next)
+ writestruct(wd, DATA, "TransformOrientation", 1, ts);
+
for(srl= sce->r.layers.first; srl; srl= srl->next)
writestruct(wd, DATA, "SceneRenderLayer", 1, srl);
diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h
index 78f5ff90a4e..43f0629f935 100644
--- a/source/blender/include/BIF_space.h
+++ b/source/blender/include/BIF_space.h
@@ -55,6 +55,7 @@ struct SpaceOops;
#define VIEW3D_HANDLER_OBJECT 3
#define VIEW3D_HANDLER_PREVIEW 4
#define VIEW3D_HANDLER_MULTIRES 5
+#define VIEW3D_HANDLER_TRANSFORM 6
/* ipo handler codes */
#define IPO_HANDLER_PROPERTIES 20
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index 6d4095f0d40..98af3b84770 100644
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -81,6 +81,8 @@ int calculateTransformCenter(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);
@@ -88,6 +90,18 @@ 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);
+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(); /* 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);
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h
index 8f9de747c2a..36ae384467d 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -237,6 +237,7 @@
#define B_SEL_PATH 166
#define B_SEL_POINT 167
#define B_SEL_END 168
+#define B_MAN_MODE 169
/* IPO: 200 */
#define B_IPOHOME 201
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 31a61972ea3..e296a71bc70 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -170,6 +170,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_ARMATUREPANEL3 1013
#define B_OBJECTPANELSCALE 1014
#define B_OBJECTPANELDIMS 1015
+#define B_TRANSFORMSPACEADD 1016
+#define B_TRANSFORMSPACECLEAR 1017
/* *********************** */
#define B_LAMPBUTS 1200
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index d52de12ed17..ae8997a28ee 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -463,6 +463,15 @@ short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);
char handleNumInput(NumInput *n, unsigned short event);
+/*********************** TransSpace ******************************/
+
+int manageObjectSpace(int confirm, int set);
+int manageMeshSpace(int confirm, int set);
+
+int addMatrixSpace(float mat[3][3], char name[]);
+int addObjectSpace(struct Object *ob);
+void applyTransformOrientation(void);
+
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index c82a1f9e510..282093f39be 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -333,6 +333,12 @@ typedef struct ParticleEditSettings {
int draw_timed;
} ParticleEditSettings;
+typedef struct TransformOrientation {
+ struct TransformOrientation *next, *prev;
+ char name[36];
+ float mat[3][3];
+} TransformOrientation;
+
typedef struct ToolSettings {
/* Subdivide Settings */
short cornertype;
@@ -366,7 +372,7 @@ typedef struct ToolSettings {
/* Auto-IK */
short autoik_chainlen;
- /* Image Paint (8 byte aligned please!) */
+ /* Image Paint (8 byttse aligned please!) */
struct ImagePaintSettings imapaint;
/* Particle Editing */
@@ -494,6 +500,7 @@ typedef struct Scene {
ScriptLink scriptlink;
ListBase markers;
+ ListBase transform_spaces;
short jumpframe, pad1;
short snap_flag, snap_target;
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index ee75d7b8f0f..78605464268 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -200,6 +200,7 @@ typedef struct View3D {
#define V3D_MANIP_LOCAL 1
#define V3D_MANIP_NORMAL 2
#define V3D_MANIP_VIEW 3
+#define V3D_MANIP_CUSTOM 4 /* anything of value 4 or higher is custom */
/* View3d->twflag */
/* USE = user setting, DRAW = based on selection */
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 1016de5c603..b637118e38a 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -2228,9 +2228,83 @@ void do_viewbuts(unsigned short event)
allqueue(REDRAWVIEW3D, 1);
}
break;
+ case B_TRANSFORMSPACEADD:
+ BIF_manageTransformOrientation(1, 0);
+ allqueue(REDRAWVIEW3D, 1);
+ break;
+ case B_TRANSFORMSPACECLEAR:
+ BIF_clearTransformOrientation();
+ allqueue(REDRAWVIEW3D, 1);
}
}
+void removeTransformOrientation_func(void *target, void *unused)
+{
+ BIF_removeTransformOrientation((TransformOrientation *) target);
+}
+
+void selectTransformOrientation_func(void *target, void *unused)
+{
+ BIF_selectTransformOrientation((TransformOrientation *) target);
+}
+
+static void view3d_panel_transform_spaces(short cntrl)
+{
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ TransformOrientation *ts = transform_spaces->first;
+ uiBlock *block;
+ uiBut *but;
+ int xco = 20, yco = 70, height = 140;
+ int index;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_panel_transform", UI_EMBOSS, UI_HELV, curarea->win);
+ uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+ uiSetPanelHandler(VIEW3D_HANDLER_TRANSFORM); // for close and esc
+
+ if(uiNewPanel(curarea, block, "Transform Orientations", "View3d", 10, 230, 318, height)==0) return;
+
+ uiNewPanelHeight(block, height);
+
+ uiBlockBeginAlign(block);
+
+ if (G.obedit)
+ uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
+ else
+ uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
+
+ uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
+
+ uiBlockEndAlign(block);
+
+ uiPanelPush(block);
+
+ uiBlockBeginAlign(block);
+
+ uiDefButS(block, ROW, REDRAWHEADERS, "Global", xco, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
+ uiDefButS(block, ROW, REDRAWHEADERS, "Local", xco + 40, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
+ uiDefButS(block, ROW, REDRAWHEADERS, "Normal", xco + 80, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
+ uiDefButS(block, ROW, REDRAWHEADERS, "View", xco + 120, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_VIEW, 0, 0, "View Transform Orientation");
+
+ for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
+
+ BIF_ThemeColor(TH_BUT_ACTION);
+ but = uiDefIconButS(block,ROW, REDRAWHEADERS, ICON_RIGHTARROW_THIN, xco,yco,XIC,YIC, &G.vd->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
+ uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
+ uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
+ but = uiDefIconBut(block, BUT, REDRAWVIEW3D, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
+ uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
+
+ xco = 20;
+ yco -= 25;
+ }
+ uiBlockEndAlign(block);
+
+ uiPanelPop(block);
+
+ if(yco < 0) uiNewPanelHeight(block, height-yco);
+}
+
+
static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
{
uiBlock *block;
@@ -2565,6 +2639,9 @@ static void view3d_blockhandlers(ScrArea *sa)
case VIEW3D_HANDLER_PREVIEW:
view3d_panel_preview(sa, v3d->blockhandler[a+1]);
break;
+ case VIEW3D_HANDLER_TRANSFORM:
+ view3d_panel_transform_spaces(v3d->blockhandler[a+1]);
+ break;
}
/* clear action value for event */
v3d->blockhandler[a+1]= 0;
diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c
index 62450d686a1..8200a9c0c76 100644
--- a/source/blender/src/header_info.c
+++ b/source/blender/src/header_info.c
@@ -304,6 +304,7 @@ Scene *copy_scene(Scene *sce, int level)
scen->toolsettings= MEM_dupallocN(sce->toolsettings);
duplicatelist(&(scen->markers), &(sce->markers));
+ duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
duplicatelist(&(scen->r.layers), &(sce->r.layers));
scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 2f6225bb8e0..dbfbaf9d30b 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -601,6 +601,9 @@ static void do_view3d_viewmenu(void *arg, int event)
case 19: /* zoom within border */
view3d_border_zoom();
break;
+ case 20: /* Transform Space Panel */
+ add_blockhandler(curarea, VIEW3D_HANDLER_TRANSFORM, UI_PNL_UNSTOW);
+ break;
}
allqueue(REDRAWVIEW3D, 1);
}
@@ -614,6 +617,7 @@ static uiBlock *view3d_viewmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_view3d_viewmenu, NULL);
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Orientations...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 20, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Render Preview...|Shift P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 16, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Background Image...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
@@ -5108,7 +5112,9 @@ void do_view3d_buttons(short event)
G.vd->twtype= V3D_MANIP_SCALE;
allqueue(REDRAWVIEW3D, 1);
break;
-
+ case B_MAN_MODE:
+ allqueue(REDRAWVIEW3D, 1);
+ break;
default:
if(event>=B_LAY && event<B_LAY+31) {
@@ -5395,6 +5401,7 @@ void view3d_buttons(void)
xco+= XIC+10;
} else {
/* Manipulators arnt used in weight paint mode */
+ char *str_menu;
uiDefIconTextButS(block, ICONTEXTROW,B_AROUND, ICON_ROTATE, around_pup(), xco,0,XIC+10,YIC, &(G.vd->around), 0, 3.0, 0, 0, "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period, Ctrl Period, Alt Period)");
xco+= XIC+10;
@@ -5419,7 +5426,11 @@ void view3d_buttons(void)
uiDefIconButBitS(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode (Ctrl Alt S)");
xco+= XIC;
}
- uiDefButS(block, MENU, B_NOP, "Orientation%t|Global%x0|Local%x1|Normal%x2|View%x3",xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (Alt Space)");
+
+ str_menu = BIF_menustringTransformOrientation();
+ uiDefButS(block, MENU, B_MAN_MODE, str_menu,xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (ALT+Space)");
+ MEM_freeN(str_menu);
+
xco+= 70;
uiBlockEndAlign(block);
xco+= 8;
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index dee87f2380c..775148582a8 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1798,6 +1798,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
add_constraint(0); /* editconstraint.c, generic for objects and posemode */
+ else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY)) {
+ BIF_manageTransformOrientation(0, 1);
+ allqueue(REDRAWVIEW3D, 0);
+ }
else if((G.qual==LR_SHIFTKEY)) {
view3d_home(1);
curs= give_cursor();
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 1b9f8752103..5950eef6703 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -157,6 +157,305 @@ static void helpline(TransInfo *t, float *vec)
glDrawBuffer(GL_BACK);
}
}
+
+/* *********************** TransSpace ************************** */
+
+void BIF_clearTransformOrientation(void)
+{
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ BLI_freelistN(transform_spaces);
+
+ if (G.vd->twmode >= V3D_MANIP_CUSTOM)
+ G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+}
+
+void BIF_manageTransformOrientation(int confirm, int set) {
+ int index = -1;
+
+ if (G.obedit) {
+ if (G.obedit->type == OB_MESH)
+ index = manageMeshSpace(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("Custome Space %t|Add and Use Active Object%x1") != 1) {
+ return -1;
+ }
+ else if (set == 0 && pupmenu("Custome Space %t|Add Active Object%x1") != 1) {
+ return -1;
+ }
+ }
+
+ return addObjectSpace(base->object);
+}
+
+int manageMeshSpace(int confirm, int set) {
+ EditMesh *em = G.editMesh;
+ float mat[3][3], vec[3] = {0.0f, 0.0f, 1.0f};
+ int index;
+ char name[36] = "";
+
+ if (G.scene->selectmode & SCE_SELECT_VERTEX && G.totvertsel == 1) {
+ EditVert *eve;
+
+ if (confirm == 0) {
+ if (set && pupmenu("Custome Space %t|Add and Use Vertex%x1") != 1) {
+ return -1;
+ }
+ else if (set == 0 && pupmenu("Custome Space %t|Add Vertex%x1") != 1) {
+ return -1;
+ }
+ }
+
+ for(eve = em->verts.first; eve; eve= eve->next) {
+ if(eve->h == 0 && (eve->f & SELECT))
+ break;
+ }
+
+ if (eve == NULL)
+ return -1;
+
+ VECCOPY(mat[2], eve->no);
+ if (Normalize(mat[2]) == 0.0f) {
+ error("Cannot use vertex with zero-length normal");
+ return -1;
+ }
+
+ strcpy(name, "Vertex");
+ }
+ else if(G.scene->selectmode & SCE_SELECT_EDGE && G.totedgesel == 1) {
+ EditEdge *eed;
+
+ if (confirm == 0) {
+ if (set && pupmenu("Custome Space %t|Add and Use Edge%x1") != 1) {
+ return -1;
+ }
+ else if (set == 0 && pupmenu("Custome Space %t|Add Edge%x1") != 1) {
+ return -1;
+ }
+ }
+
+ for(eed = em->edges.first; eed; eed= eed->next) {
+ if(eed->h == 0 && (eed->f & SELECT))
+ break;
+ }
+
+ if (eed == NULL)
+ return -1;
+
+ VecSubf(mat[2], eed->v2->co, eed->v1->co);
+ if (Normalize(mat[2]) == 0.0f) {
+ error("Cannot use zero-length edges");
+ return -1;
+ }
+
+ strcpy(name, "Edge");
+ }
+ else if(G.scene->selectmode & SCE_SELECT_FACE && G.totfacesel == 1) {
+ EditFace *efa;
+
+ if (confirm == 0) {
+ if (set && pupmenu("Custome Space %t|Add and Use Face%x1") != 1) {
+ return -1;
+ }
+ else if (set == 0 && pupmenu("Custome Space %t|Add Face%x1") != 1) {
+ return -1;
+ }
+ }
+
+ for(efa = em->faces.first; efa; efa= efa->next) {
+ if(efa->h == 0 && (efa->f & SELECT))
+ break;
+ }
+
+ if (efa == NULL)
+ return -1;
+
+ VECCOPY(mat[2], efa->n);
+ if (Normalize(mat[2]) == 0.0f) {
+ error("Cannot use face with zero-length normal");
+ return -1;
+ }
+
+ VecSubf(vec, efa->v2->co, efa->v1->co);
+
+ strcpy(name, "Face");
+ }
+ else {
+ notice("You need to select only one vertex, edge or face");
+ return -1;
+ }
+
+ /* Applying matrix for global space */
+ Mat4Mul3Vecfl(G.obedit->obmat, mat[2]);
+ Mat4Mul3Vecfl(G.obedit->obmat, vec);
+
+ /* Calculating the other axis */
+
+ Crossf(mat[0], mat[2], vec);
+ if (Normalize(mat[0]) == 0.0f) {
+ vec[0] = 1.0f;
+ vec[1] = vec[2] = 0.0f;
+ Crossf(mat[0], vec, mat[2]);
+ }
+
+ Crossf(mat[1], mat[2], mat[0]);
+
+ Mat3Ortho(mat);
+
+ /* Input name */
+ sbutton(name, 1, 35, "name: ");
+
+ index = addMatrixSpace(mat, name);
+ return index;
+}
+
+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 BIF_countTransformOrientation() - 1;
+}
+
+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 menu[] = "Orientation%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) + 40 * BIF_countTransformOrientation(), "UserTransSpace from matrix");
+ p = str_menu;
+
+ p += sprintf(str_menu, "%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;
+ }
+ }
+ }
+}
+
/* ************************** INPUT FROM MOUSE *************************** */
float InputScaleRatio(TransInfo *t, short mval[2]) {
@@ -465,12 +764,12 @@ static void viewRedrawPost(TransInfo *t)
void BIF_selectOrientation() {
short val;
- val= pupmenu("Orientation%t|Global|Local|Normal|View");
- if(val>0) {
- if(val==1) G.vd->twmode= V3D_MANIP_GLOBAL;
- else if(val==2) G.vd->twmode= V3D_MANIP_LOCAL;
- else if(val==3) G.vd->twmode= V3D_MANIP_NORMAL;
- else if(val==4) G.vd->twmode= V3D_MANIP_VIEW;
+ char *str_menu = BIF_menustringTransformOrientation();
+ val= pupmenu(str_menu);
+ MEM_freeN(str_menu);
+
+ if(val >= 0) {
+ G.vd->twmode = val;
}
}
@@ -2341,7 +2640,7 @@ int Rotation(TransInfo *t, short mval[2])
outputNumInput(&(t->num), c);
- sprintf(str, "Rot: %s %s", &c[0], t->proptext);
+ sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
/* Clamp between -180 and 180 */
while (final >= 180.0)
diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c
index 99e5123a953..33311210ec5 100644
--- a/source/blender/src/transform_constraints.c
+++ b/source/blender/src/transform_constraints.c
@@ -539,6 +539,10 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[]) {
sprintf(text, ftext, "view");
setConstraint(t, t->spacemtx, mode, text);
break;
+ default: /* V3D_MANIP_CUSTOM */
+ sprintf(text, ftext, t->spacename);
+ setConstraint(t, t->spacemtx, mode, text);
+ break;
}
t->con.mode |= CON_USER;
diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c
index 7a6d4c69442..13a8552b844 100644
--- a/source/blender/src/transform_manipulator.c
+++ b/source/blender/src/transform_manipulator.c
@@ -531,6 +531,9 @@ int calc_manipulator_stats(ScrArea *sa)
Mat4CpyMat3(v3d->twmat, mat);
}
break;
+ default: /* V3D_MANIP_CUSTOM */
+ applyTransformOrientation();
+ break;
}
}