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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@gmail.com>2008-01-16 10:19:21 +0300
committerNicholas Bishop <nicholasbishop@gmail.com>2008-01-16 10:19:21 +0300
commitc6118036bc044bd5f25106dfb0b422ee2310d5ba (patch)
treeb7d3105398c881d155043dc6579bf6e7652f179e
parentf41c3340be9fbd5126a09a514f48cf88af2ec951 (diff)
== Radial Control ==
* Generalized the interactive brush property control from sculpt mode into a simple API * Modified sculpt mode to take advantage of this (even fixes some minor bugs!) * Added shortcuts in particle edit to set brush size/strength (FKEY/shift+FKEY) Still todo are the other modes that have brushes...
-rw-r--r--source/blender/blenkernel/BKE_sculpt.h23
-rw-r--r--source/blender/blenkernel/intern/scene.c9
-rw-r--r--source/blender/include/BDR_sculptmode.h5
-rw-r--r--source/blender/include/BIF_editparticle.h3
-rw-r--r--source/blender/include/BIF_radialcontrol.h62
-rw-r--r--source/blender/src/drawview.c66
-rw-r--r--source/blender/src/editparticle.c41
-rw-r--r--source/blender/src/header_view3d.c8
-rw-r--r--source/blender/src/radialcontrol.c266
-rw-r--r--source/blender/src/sculptmode.c281
-rw-r--r--source/blender/src/space.c27
11 files changed, 475 insertions, 316 deletions
diff --git a/source/blender/blenkernel/BKE_sculpt.h b/source/blender/blenkernel/BKE_sculpt.h
index d539bcf5e8c..e03e38bab75 100644
--- a/source/blender/blenkernel/BKE_sculpt.h
+++ b/source/blender/blenkernel/BKE_sculpt.h
@@ -31,30 +31,11 @@
#define BKE_SCULPT_H
struct NumInput;
+struct RadialControl;
struct Scene;
struct SculptData;
struct SculptSession;
-typedef enum PropsetMode {
- PropsetNone = 0,
- PropsetSize,
- PropsetStrength,
- PropsetTexRot
-} PropsetMode;
-
-typedef struct PropsetData {
- PropsetMode mode;
- unsigned int tex;
- short origloc[2];
- float *texdata;
-
- short origsize;
- char origstrength;
- float origtexrot;
-
- struct NumInput *num;
-} PropsetData;
-
typedef struct SculptSession {
struct ProjVert *projverts;
@@ -76,7 +57,7 @@ typedef struct SculptSession {
/* Used to cache the render of the active texture */
unsigned int texcache_w, texcache_h, *texcache;
- struct PropsetData *propset;
+ struct RadialControl *radialcontrol;
/* For rotating around a pivot point */
vec3f pivot;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 357b3c1bf54..94dfa705dc2 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -661,13 +661,8 @@ void sculptsession_free(Scene *sce)
if(ss->mats)
MEM_freeN(ss->mats);
- if(ss->propset) {
- if(ss->propset->texdata)
- MEM_freeN(ss->propset->texdata);
- if(ss->propset->num)
- MEM_freeN(ss->propset->num);
- MEM_freeN(ss->propset);
- }
+ if(ss->radialcontrol)
+ MEM_freeN(ss->radialcontrol);
sculpt_vertexusers_free(ss);
if(ss->texcache)
diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h
index e15c1fb7063..8b0b65be4de 100644
--- a/source/blender/include/BDR_sculptmode.h
+++ b/source/blender/include/BDR_sculptmode.h
@@ -33,7 +33,6 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
#include "BKE_sculpt.h"
-#include "transform.h"
struct uiBlock;
struct BrushData;
@@ -59,15 +58,13 @@ void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, un
void sculptmode_draw_interface_brush(struct uiBlock *block,unsigned short cx, unsigned short cy);
void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy);
void sculptmode_rem_tex(void*,void*);
-void sculptmode_propset_init(PropsetMode mode);
-void sculptmode_propset(const unsigned short event);
void sculptmode_selectbrush_menu(void);
void sculptmode_draw_mesh(int);
void sculpt_paint_brush(char clear);
void sculpt_stroke_draw();
+void sculpt_radialcontrol_start(int mode);
struct BrushData *sculptmode_brush(void);
-float tex_angle(void);
void do_symmetrical_brush_actions(struct EditData *e, short *, short *);
void sculptmode_update_tex(void);
diff --git a/source/blender/include/BIF_editparticle.h b/source/blender/include/BIF_editparticle.h
index 77fb091de37..6074dcd4fec 100644
--- a/source/blender/include/BIF_editparticle.h
+++ b/source/blender/include/BIF_editparticle.h
@@ -38,6 +38,7 @@
struct Object;
struct ParticleSystem;
struct ParticleEditSettings;
+struct RadialControl;
/* particle edit mode */
void PE_set_particle_edit(void);
@@ -53,6 +54,7 @@ short PE_get_current_num(struct Object *ob);
int PE_minmax(float *min, float *max);
void PE_get_colors(char sel[4], char nosel[4]);
struct ParticleEditSettings *PE_settings(void);
+struct RadialControl **PE_radialcontrol();
/* update calls */
void PE_hide_keys_time(struct ParticleSystem *psys, float cfra);
@@ -83,6 +85,7 @@ void PE_remove_doubles(void);
void PE_mirror_x(int tagged);
void PE_selectbrush_menu(void);
void PE_remove_doubles(void);
+void PE_radialcontrol_start(const int mode);
/* undo */
void PE_undo_push(char *str);
diff --git a/source/blender/include/BIF_radialcontrol.h b/source/blender/include/BIF_radialcontrol.h
new file mode 100644
index 00000000000..81181a3a91e
--- /dev/null
+++ b/source/blender/include/BIF_radialcontrol.h
@@ -0,0 +1,62 @@
+/*
+ * $Id: multires.h 13015 2007-12-27 07:27:03Z nicholasbishop $
+ *
+ * ***** 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) 2008 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef RADIALCONTROL_H
+#define RADIALCONTROL_H
+
+struct NumInput;
+
+#define RADIALCONTROL_NONE 0
+#define RADIALCONTROL_SIZE 1
+#define RADIALCONTROL_STRENGTH 2
+#define RADIALCONTROL_ROTATION 3
+
+typedef void (*RadialControlCallback)(const int, const int);
+
+typedef struct RadialControl {
+ int mode;
+ short origloc[2];
+
+ unsigned int tex;
+
+ int new_value;
+ int original_value;
+ int max_value;
+ RadialControlCallback callback;
+
+ struct NumInput *num;
+} RadialControl;
+
+RadialControl *radialcontrol_start(const int mode, RadialControlCallback callback,
+ const int original_value, const int max_value,
+ const unsigned int tex);
+void radialcontrol_do_events(RadialControl *rc, const unsigned short event);
+void radialcontrol_draw(RadialControl *rc);
+
+#endif
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index fd23761c82c..e3d73f4cda3 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -125,6 +125,7 @@
#include "BIF_mywindow.h"
#include "BIF_poseobject.h"
#include "BIF_previewrender.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
@@ -3061,68 +3062,13 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
/* Draw Sculpt Mode brush */
if(!G.obedit && (G.f & G_SCULPTMODE) && area_is_active_area(v3d->area) && sculpt_session()) {
- PropsetData *pd= sculpt_session()->propset;
- short r1=100, r2=100, r3=100;
- short mouse[2];
+ RadialControl *rc= sculpt_session()->radialcontrol;
if(sculpt_data()->flags & SCULPT_INPUT_SMOOTH)
sculpt_stroke_draw();
- if(pd) {
- if(pd->mode == PropsetSize) {
- r1= sculptmode_brush()->size;
- r2= pd->origsize;
- r3= r1;
- } else if(pd->mode == PropsetStrength) {
- r1= 200 - sculptmode_brush()->strength * 2;
- r2= 200;
- r3= 200;
- } else if(pd->mode == PropsetTexRot) {
- r1= r2= 200;
- r3= 200;
- }
-
- /* Draw brush with texture */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glBindTexture(GL_TEXTURE_2D, pd->tex);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glPushMatrix();
- glTranslatef(pd->origloc[0], pd->origloc[1], 0);
- glRotatef(tex_angle(), 0, 0, 1);
-
- glEnable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
- glColor4f(0,0,0,1);
- glTexCoord2f(0,0);
- glVertex2f(-r3, -r3);
- glTexCoord2f(1,0);
- glVertex2f(r3, -r3);
- glTexCoord2f(1,1);
- glVertex2f(r3, r3);
- glTexCoord2f(0,1);
- glVertex2f(-r3, r3);
- glEnd();
- glDisable(GL_TEXTURE_2D);
-
- glPopMatrix();
-
- if(r1 != r2)
- fdrawXORcirc(pd->origloc[0], pd->origloc[1], r1);
- fdrawXORcirc(pd->origloc[0], pd->origloc[1], r2);
-
- if(pd->mode == PropsetTexRot) {
- const float ang= pd->origtexrot * (M_PI/180.0f);
- getmouseco_areawin(mouse);
- sdrawXORline(pd->origloc[0], pd->origloc[1],
- pd->origloc[0]+200*cos(ang), pd->origloc[1]+200*sin(ang));
- sdrawXORline(pd->origloc[0], pd->origloc[1], mouse[0], mouse[1]);
- }
- }
+ if(rc)
+ radialcontrol_draw(rc);
else if(sculpt_data()->flags & SCULPT_DRAW_BRUSH) {
short csc[2], car[2];
getmouseco_sc(csc);
@@ -3143,7 +3089,9 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
ParticleEditSettings *pset = PE_settings();
short c[2];
- if(psys && psys->edit && pset->brushtype>=0){
+ if(*PE_radialcontrol())
+ radialcontrol_draw(*PE_radialcontrol());
+ else if(psys && psys->edit && pset->brushtype>=0) {
getmouseco_areawin(c);
fdrawXORcirc((float)c[0], (float)c[1], (float)pset->brush[pset->brushtype].size);
}
diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c
index 0a2158faf33..ea93ba7a090 100644
--- a/source/blender/src/editparticle.c
+++ b/source/blender/src/editparticle.c
@@ -80,6 +80,7 @@
#include "BIF_interface.h"
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h"
@@ -1989,6 +1990,46 @@ void PE_remove_doubles(void)
BIF_undo_push("Remove double particles");
}
+static void PE_radialcontrol_callback(const int mode, const int val)
+{
+ ParticleEditSettings *pset = PE_settings();
+
+ if(pset->brushtype>=0) {
+ ParticleBrushData *brush= &pset->brush[pset->brushtype];
+
+ if(mode == RADIALCONTROL_SIZE)
+ brush->size = val;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ brush->strength = val;
+ }
+
+ (*PE_radialcontrol()) = NULL;
+}
+
+RadialControl **PE_radialcontrol()
+{
+ static RadialControl *rc = NULL;
+ return &rc;
+}
+
+void PE_radialcontrol_start(const int mode)
+{
+ ParticleEditSettings *pset = PE_settings();
+ int orig;
+
+ if(pset->brushtype>=0) {
+ ParticleBrushData *brush= &pset->brush[pset->brushtype];
+
+ if(mode == RADIALCONTROL_SIZE)
+ orig = brush->size;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ orig = brush->strength;
+
+ if(mode != RADIALCONTROL_NONE)
+ (*PE_radialcontrol())= radialcontrol_start(mode, PE_radialcontrol_callback, orig, 100, 0);
+ }
+}
+
/************************************************/
/* Edit Brushes */
/************************************************/
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 8102e60c7fb..b476bb6c944 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -113,6 +113,7 @@
#include "BIF_meshtools.h"
#include "BIF_poselib.h"
#include "BIF_poseobject.h"
+#include "BIF_radialcontrol.h"
#include "BIF_renderwin.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
@@ -4402,6 +4403,7 @@ void do_view3d_sculptmenu(void *arg, int event)
{
SculptData *sd= &G.scene->sculptdata;
BrushData *br= sculptmode_brush();
+
switch(event) {
case 0:
case 1:
@@ -4445,13 +4447,13 @@ void do_view3d_sculptmenu(void *arg, int event)
add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
break;
case 15:
- sculptmode_propset_init(PropsetTexRot);
+ sculpt_radialcontrol_start(RADIALCONTROL_ROTATION);
break;
case 16:
- sculptmode_propset_init(PropsetStrength);
+ sculpt_radialcontrol_start(RADIALCONTROL_STRENGTH);
break;
case 17:
- sculptmode_propset_init(PropsetSize);
+ sculpt_radialcontrol_start(RADIALCONTROL_SIZE);
break;
case 18:
br->dir= br->dir==1 ? 2 : 1;
diff --git a/source/blender/src/radialcontrol.c b/source/blender/src/radialcontrol.c
new file mode 100644
index 00000000000..9911062f3df
--- /dev/null
+++ b/source/blender/src/radialcontrol.c
@@ -0,0 +1,266 @@
+/*
+ * $Id: multires.c 13015 2007-12-27 07:27:03Z nicholasbishop $
+ *
+ * ***** 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) 2006 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Implements the multiresolution modeling tools.
+ *
+ * multires.h
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+#include "BIF_mywindow.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "BIF_radialcontrol.h"
+
+#include "BKE_global.h"
+
+#include "mydevice.h"
+#include "transform.h"
+
+#include "math.h"
+
+/* Prints the value being edited in the view header */
+static void radialcontrol_header(const RadialControl *rc)
+{
+ if(rc) {
+ char str[512];
+ const char *name= "";
+
+ if(rc->mode == RADIALCONTROL_SIZE)
+ name= "Size";
+ else if(rc->mode == RADIALCONTROL_STRENGTH)
+ name= "Strength";
+ else if(rc->mode == RADIALCONTROL_ROTATION)
+ name= "Angle";
+
+ sprintf(str, "%s: %d", name, (int)(rc->new_value));
+ headerprint(str);
+ }
+}
+
+/* Creates, initializes, and returns the control */
+RadialControl *radialcontrol_start(const int mode, RadialControlCallback callback,
+ const int original_value, const int max_value,
+ const unsigned int tex)
+{
+ RadialControl *rc= MEM_callocN(sizeof(RadialControl), "radial control");
+ short mouse[2];
+
+ getmouseco_areawin(mouse);
+ rc->origloc[0]= mouse[0];
+ rc->origloc[1]= mouse[1];
+
+ if(mode == RADIALCONTROL_SIZE)
+ rc->origloc[0]-= original_value;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ rc->origloc[0]-= 200 - 2*original_value;
+ else if(mode == RADIALCONTROL_ROTATION) {
+ rc->origloc[0]-= 200 * cos(original_value * M_PI / 180.0);
+ rc->origloc[1]-= 200 * sin(original_value * M_PI / 180.0);
+ }
+
+ rc->callback = callback;
+ rc->original_value = original_value;
+ rc->max_value = max_value;
+
+ rc->tex = tex;
+
+ /* NumInput is used for keyboard input */
+ rc->num = MEM_callocN(sizeof(NumInput), "radialcontrol numinput");
+ rc->num->idx_max= 0;
+
+ rc->mode= mode;
+ radialcontrol_header(rc);
+
+ allqueue(REDRAWVIEW3D, 0);
+
+ return rc;
+}
+
+
+static void radialcontrol_end(RadialControl *rc)
+{
+ if(rc) {
+ rc->callback(rc->mode, rc->new_value);
+ BIF_undo_push("Brush property set");
+
+ /* Free everything */
+ glDeleteTextures(1, (GLuint*)(&rc->tex));
+ MEM_freeN(rc->num);
+ MEM_freeN(rc);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWHEADERS, 0);
+ }
+}
+
+void radialcontrol_do_events(RadialControl *rc, unsigned short event)
+{
+ short mouse[2];
+ short tmp[2];
+ float dist;
+ char valset= 0;
+
+ if(!rc)
+ return;
+
+ handleNumInput(rc->num, event);
+
+ if(hasNumInput(rc->num)) {
+ float val;
+ applyNumInput(rc->num, &val);
+ rc->new_value = val;
+ valset= 1;
+ allqueue(REDRAWVIEW3D, 0);
+ }
+
+ switch(event) {
+ case MOUSEX:
+ case MOUSEY:
+ if(!hasNumInput(rc->num)) {
+ char ctrl= G.qual & LR_CTRLKEY;
+ getmouseco_areawin(mouse);
+ tmp[0]= rc->origloc[0]-mouse[0];
+ tmp[1]= rc->origloc[1]-mouse[1];
+ dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
+ if(rc->mode == RADIALCONTROL_SIZE)
+ rc->new_value = dist;
+ else if(rc->mode == RADIALCONTROL_STRENGTH) {
+ float fin= (200.0f - dist) * 0.5f;
+ rc->new_value= fin>=0 ? fin : 0;
+ } else if(rc->mode == RADIALCONTROL_ROTATION)
+ rc->new_value= ((int)(atan2(tmp[1], tmp[0]) * (180.0 / M_PI)) + 180);
+
+ if(ctrl)
+ rc->new_value= (rc->new_value + 5) / 10*10;
+
+ valset= 1;
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ break;
+ case ESCKEY:
+ case RIGHTMOUSE:
+ rc->new_value = rc->original_value;
+ case LEFTMOUSE:
+ while(get_mbut()==L_MOUSE);
+ case RETKEY:
+ case PADENTER:
+ radialcontrol_end(rc);
+ return;
+ default:
+ break;
+ };
+
+ if(valset) {
+ if(rc->new_value > rc->max_value)
+ rc->new_value = rc->max_value;
+ }
+
+ radialcontrol_header(rc);
+}
+
+static void rot_line(const short o[2], const float ang)
+{
+ sdrawXORline(o[0], o[1], o[0] + 200*cos(ang), o[1] + 200*sin(ang));
+}
+
+void radialcontrol_draw(RadialControl *rc)
+{
+ short r1, r2, r3;
+ float angle = 0;
+
+ if(rc && rc->mode) {
+ if(rc->mode == RADIALCONTROL_SIZE) {
+ r1= rc->new_value;
+ r2= rc->original_value;
+ r3= r1;
+ } else if(rc->mode == RADIALCONTROL_STRENGTH) {
+ r1= 200 - rc->new_value * 2;
+ r2= 200;
+ r3= 200;
+ } else if(rc->mode == RADIALCONTROL_ROTATION) {
+ r1= r2= 200;
+ r3= 200;
+ angle = rc->new_value;
+ }
+
+ /* Draw brush with texture */
+ glPushMatrix();
+ glTranslatef(rc->origloc[0], rc->origloc[1], 0);
+ glRotatef(angle, 0, 0, 1);
+
+ if(rc->tex) {
+ const float str = rc->mode == RADIALCONTROL_STRENGTH ? (rc->new_value / 200.0 + 0.5) : 1;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glBindTexture(GL_TEXTURE_2D, rc->tex);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glEnable(GL_TEXTURE_2D);
+ glBegin(GL_QUADS);
+ glColor4f(0,0,0, str);
+ glTexCoord2f(0,0);
+ glVertex2f(-r3, -r3);
+ glTexCoord2f(1,0);
+ glVertex2f(r3, -r3);
+ glTexCoord2f(1,1);
+ glVertex2f(r3, r3);
+ glTexCoord2f(0,1);
+ glVertex2f(-r3, r3);
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+ }
+
+ glPopMatrix();
+
+ if(r1 != r2)
+ fdrawXORcirc(rc->origloc[0], rc->origloc[1], r1);
+ fdrawXORcirc(rc->origloc[0], rc->origloc[1], r2);
+
+ if(rc->mode == RADIALCONTROL_ROTATION) {
+ float ang1= rc->original_value * (M_PI/180.0f);
+ float ang2= rc->new_value * (M_PI/180.0f);
+
+ if(rc->new_value > 359)
+ ang2 = 0;
+
+ rot_line(rc->origloc, ang1);
+ if(ang1 != ang2)
+ rot_line(rc->origloc, ang2);
+ }
+ }
+}
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index a1341fd60c3..79a40fdb607 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -76,6 +76,7 @@
#include "BIF_gl.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h"
@@ -672,7 +673,7 @@ void flip_coord(float co[3], const char symm)
}
/* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */
-float tex_angle(void)
+float sculpt_tex_angle(void)
{
SculptData *sd= sculpt_data();
if(sd->texact!=-1 && sd->mtex[sd->texact])
@@ -737,7 +738,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
else if(ss->texcache) {
const short bsize= sculptmode_brush()->size * 2;
const short half= sculptmode_brush()->size;
- const float rot= to_rad(tex_angle());
+ const float rot= to_rad(sculpt_tex_angle());
const unsigned tcw = ss->texcache_w, tch = ss->texcache_h;
int px, py;
unsigned i, *p;
@@ -1224,147 +1225,85 @@ void sculptmode_set_strength(const int delta)
sculptmode_brush()->strength= val;
}
-void sculptmode_propset_calctex()
+static void sculpt_radialcontrol_callback(const int mode, const int val)
{
- SculptData *sd= sculpt_data();
- SculptSession *ss= sculpt_session();
- PropsetData *pd= sculpt_session()->propset;
- if(pd) {
- int i, j;
- const int tsz = 128;
- float *d;
- if(!pd->texdata) {
- pd->texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
- if(sd->texrept!=SCULPTREPT_3D)
- sculptmode_update_tex();
- for(i=0; i<tsz; ++i)
- for(j=0; j<tsz; ++j) {
- float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
- if(sd->texfade)
- pd->texdata[i*tsz+j]= curve_strength(magn,tsz/2);
- else
- pd->texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
- }
- if(sd->texact != -1 && ss->texcache) {
- for(i=0; i<tsz; ++i)
- for(j=0; j<tsz; ++j) {
- const int col= ss->texcache[i*tsz+j];
- pd->texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
- }
- }
- }
-
- /* Adjust alpha with brush strength */
- d= MEM_dupallocN(pd->texdata);
- for(i=0; i<tsz; ++i)
- for(j=0; j<tsz; ++j)
- d[i*tsz+j]*= sculptmode_brush()->strength/200.0f+0.5f;
-
-
- if(!pd->tex)
- glGenTextures(1, (GLuint *)&pd->tex);
- glBindTexture(GL_TEXTURE_2D, pd->tex);
+ SculptSession *ss = sculpt_session();
+ BrushData *br = sculptmode_brush();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, d);
- MEM_freeN(d);
- }
+ if(mode == RADIALCONTROL_SIZE)
+ br->size = val;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ br->strength = val;
+ else if(mode == RADIALCONTROL_ROTATION)
+ set_tex_angle(val);
+
+ ss->radialcontrol = NULL;
}
-void sculptmode_propset_header()
+/* Returns GL handle to brush texture */
+static GLuint sculpt_radialcontrol_calctex()
{
+ SculptData *sd= sculpt_data();
SculptSession *ss= sculpt_session();
- PropsetData *pd= ss ? ss->propset : NULL;
- if(pd) {
- char str[512];
- const char *name= "";
- int val= 0;
- if(pd->mode == PropsetSize) {
- name= "Size";
- val= sculptmode_brush()->size;
- }
- else if(pd->mode == PropsetStrength) {
- name= "Strength";
- val= sculptmode_brush()->strength;
- }
- else if(pd->mode == PropsetTexRot) {
- name= "Texture Angle";
- val= tex_angle();
- }
- sprintf(str, "Brush %s: %d", name, val);
- headerprint(str);
- }
-}
+ int i, j;
+ const int tsz = 128;
+ float *texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
+ GLuint tex;
-void sculptmode_propset_end(SculptSession *ss, int cancel)
-{
- if(ss && ss->propset) {
- PropsetData *pd= ss->propset;
-
- if(cancel) {
- sculptmode_brush()->size= pd->origsize;
- sculptmode_brush()->strength= pd->origstrength;
- set_tex_angle(pd->origtexrot);
- } else {
- if(pd->mode != PropsetSize)
- sculptmode_brush()->size= pd->origsize;
- if(pd->mode != PropsetStrength)
- sculptmode_brush()->strength= pd->origstrength;
- if(pd->mode != PropsetTexRot)
- set_tex_angle(pd->origtexrot);
-
- BIF_undo_push("Brush property set");
+ if(sd->texrept!=SCULPTREPT_3D)
+ sculptmode_update_tex();
+ for(i=0; i<tsz; ++i)
+ for(j=0; j<tsz; ++j) {
+ float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
+ if(sd->texfade)
+ texdata[i*tsz+j]= curve_strength(magn,tsz/2);
+ else
+ texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
}
- glDeleteTextures(1, &pd->tex);
- MEM_freeN(pd->num);
- MEM_freeN(pd->texdata);
- MEM_freeN(pd);
- ss->propset= NULL;
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- allqueue(REDRAWHEADERS, 0);
+ if(sd->texact != -1 && ss->texcache) {
+ for(i=0; i<tsz; ++i)
+ for(j=0; j<tsz; ++j) {
+ const int col= ss->texcache[i*tsz+j];
+ texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
+ }
}
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, texdata);
+ MEM_freeN(texdata);
+
+ return tex;
}
-void sculptmode_propset_init(PropsetMode mode)
+void sculpt_radialcontrol_start(int mode)
{
- SculptSession *ss= sculpt_session();
- PropsetData *pd= ss->propset;
- const float ang= tex_angle();
-
- if(!pd) {
- short mouse[2];
-
- pd= MEM_callocN(sizeof(PropsetData),"PropsetSize");
- ss->propset= pd;
-
- getmouseco_areawin(mouse);
- pd->origloc[0]= mouse[0];
- pd->origloc[1]= mouse[1];
-
- if(mode == PropsetSize)
- pd->origloc[0]-= sculptmode_brush()->size;
- else if(mode == PropsetStrength)
- pd->origloc[0]-= 200 - 2*sculptmode_brush()->strength;
- else if(mode == PropsetTexRot) {
- pd->origloc[0]-= 200 * cos(to_rad(ang));
- pd->origloc[1]-= 200 * sin(to_rad(ang));
+ SculptData *sd = sculpt_data();
+ SculptSession *ss = sculpt_session();
+ BrushData *br = sculptmode_brush();
+ int orig, max;
+
+ if(mode == RADIALCONTROL_SIZE) {
+ orig = br->size;
+ max = 200;
+ }
+ else if(mode == RADIALCONTROL_STRENGTH) {
+ orig = br->strength;
+ max = 100;
+ }
+ else if(mode == RADIALCONTROL_ROTATION) {
+ if(sd->texact!=-1 && sd->mtex[sd->texact]) {
+ orig = sculpt_tex_angle();
+ max = 360;
}
-
- pd->origsize= sculptmode_brush()->size;
- pd->origstrength= sculptmode_brush()->strength;
- pd->origtexrot= ang;
-
- sculptmode_propset_calctex();
-
- if(!pd->num)
- pd->num = MEM_callocN(sizeof(NumInput), "propset numinput");
- pd->num->idx_max= 0;
+ else
+ mode = RADIALCONTROL_NONE;
}
- pd->mode= mode;
- sculptmode_propset_header();
-
- allqueue(REDRAWVIEW3D, 0);
+ if(mode != RADIALCONTROL_NONE) {
+ ss->radialcontrol= radialcontrol_start(mode, sculpt_radialcontrol_callback, orig, max,
+ sculpt_radialcontrol_calctex());
+ }
}
void sculpt_paint_brush(char clear)
@@ -1387,90 +1326,6 @@ void sculpt_paint_brush(char clear)
}
}
-void sculptmode_propset(unsigned short event)
-{
- PropsetData *pd= sculpt_session()->propset;
- short mouse[2];
- short tmp[2];
- float dist;
- BrushData *brush= sculptmode_brush();
- char valset= 0;
-
- handleNumInput(pd->num, event);
-
- if(hasNumInput(pd->num)) {
- float val;
- applyNumInput(pd->num, &val);
- if(pd->mode==PropsetSize)
- brush->size= val;
- else if(pd->mode==PropsetStrength)
- brush->strength= val;
- else if(pd->mode==PropsetTexRot)
- set_tex_angle(val);
- valset= 1;
- allqueue(REDRAWVIEW3D, 0);
- }
-
- switch(event) {
- case MOUSEX:
- case MOUSEY:
- if(!hasNumInput(pd->num)) {
- char ctrl= G.qual & LR_CTRLKEY;
- getmouseco_areawin(mouse);
- tmp[0]= pd->origloc[0]-mouse[0];
- tmp[1]= pd->origloc[1]-mouse[1];
- dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
- if(pd->mode == PropsetSize) {
- brush->size= dist;
- if(ctrl) brush->size= (brush->size+5)/10*10;
- } else if(pd->mode == PropsetStrength) {
- float fin= (200.0f - dist) * 0.5f;
- brush->strength= fin>=0 ? fin : 0;
- if(ctrl) brush->strength= (brush->strength+5)/10*10;
- } else if(pd->mode == PropsetTexRot) {
- set_tex_angle((int)to_deg(atan2(tmp[1], tmp[0])) + 180);
- if(ctrl)
- set_tex_angle(((int)(tex_angle())+5)/10*10);
- }
- valset= 1;
- allqueue(REDRAWVIEW3D, 0);
- }
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- brush->size= pd->origsize;
- brush->strength= pd->origstrength;
- set_tex_angle(pd->origtexrot);
- case LEFTMOUSE:
- while(get_mbut()==L_MOUSE);
- case RETKEY:
- case PADENTER:
- sculptmode_propset_end(sculpt_session(), 0);
- break;
- default:
- break;
- };
-
- if(valset) {
- if(pd->mode == PropsetSize) {
- if(brush->size<1) brush->size= 1;
- if(brush->size>200) brush->size= 200;
- }
- else if(pd->mode == PropsetStrength) {
- if(brush->strength > 100) brush->strength= 100;
- sculptmode_propset_calctex();
- }
- else if(pd->mode == PropsetTexRot) {
- if(tex_angle() < 0)
- set_tex_angle(0);
- else if(tex_angle() > 360)
- set_tex_angle(360);
- }
- }
-
- sculptmode_propset_header();
-}
-
void sculptmode_selectbrush_menu(void)
{
SculptData *sd= sculpt_data();
@@ -1699,7 +1554,7 @@ void sculpt(void)
glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
/* For raking, get the original angle*/
- offsetRot=tex_angle();
+ offsetRot=sculpt_tex_angle();
while (get_mbut() & mousebut) {
getmouseco_areawin(mouse);
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 9f3754f32da..e09da2b4a3b 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -129,6 +129,7 @@
#include "BIF_poselib.h"
#include "BIF_poseobject.h"
#include "BIF_outliner.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
@@ -1199,8 +1200,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(!mouse_in_header(sa)) {
if(!G.obedit && (G.f & G_SCULPTMODE)) {
SculptSession *ss= sculpt_session();
- if(ss && ss->propset) {
- sculptmode_propset(event);
+ if(ss && ss->radialcontrol) {
+ radialcontrol_do_events(ss->radialcontrol, event);
return;
}
else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
@@ -1211,6 +1212,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT){
ParticleSystem *psys=PE_get_current(OBACT);
ParticleEditSettings *pset=PE_settings();
+ if(*PE_radialcontrol()) {
+ radialcontrol_do_events(*PE_radialcontrol(), event);
+ return;
+ }
if(psys && psys->edit){
if(pset->brushtype>=0 &&
event!=LEFTMOUSE && event!=RIGHTMOUSE && event!=MIDDLEMOUSE &&
@@ -1366,7 +1371,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case LEFTMOUSE:
if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
sculptmode_pmv(0);
- else if(!(ss && ss->propset))
+ else if(!(ss && ss->radialcontrol))
sculpt();
break;
/* View */
@@ -1444,12 +1449,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
br->airbrush= !br->airbrush;
update_prop= 1; break;
case FKEY:
- if(G.qual==0)
- sculptmode_propset_init(PropsetSize);
- if(G.qual==LR_SHIFTKEY)
- sculptmode_propset_init(PropsetStrength);
- if(G.qual==LR_CTRLKEY)
- sculptmode_propset_init(PropsetTexRot);
+ if(ss) {
+ sculpt_radialcontrol_start(G.qual == 0 ? RADIALCONTROL_SIZE :
+ G.qual == LR_SHIFTKEY ? RADIALCONTROL_STRENGTH :
+ G.qual == LR_CTRLKEY ? RADIALCONTROL_ROTATION :
+ RADIALCONTROL_NONE);
+ }
break;
case VKEY:
br->dir= br->dir==1 ? 2 : 1;
@@ -1914,6 +1919,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
pose_activate_flipped_bone();
else if(G.f & G_WEIGHTPAINT)
pose_activate_flipped_bone();
+ else if(G.f & G_PARTICLEEDIT)
+ PE_radialcontrol_start(RADIALCONTROL_STRENGTH);
else
fly();
}
@@ -1922,6 +1929,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
G.f ^= G_FACESELECT;
allqueue(REDRAWVIEW3D, 1);
}
+ else if(G.f & G_PARTICLEEDIT)
+ PE_radialcontrol_start(RADIALCONTROL_SIZE);
}
break;