== Radial Control ==
authorNicholas Bishop <nicholasbishop@gmail.com>
Wed, 16 Jan 2008 07:19:21 +0000 (07:19 +0000)
committerNicholas Bishop <nicholasbishop@gmail.com>
Wed, 16 Jan 2008 07:19:21 +0000 (07:19 +0000)
* 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...

source/blender/blenkernel/BKE_sculpt.h
source/blender/blenkernel/intern/scene.c
source/blender/include/BDR_sculptmode.h
source/blender/include/BIF_editparticle.h
source/blender/include/BIF_radialcontrol.h [new file with mode: 0644]
source/blender/src/drawview.c
source/blender/src/editparticle.c
source/blender/src/header_view3d.c
source/blender/src/radialcontrol.c [new file with mode: 0644]
source/blender/src/sculptmode.c
source/blender/src/space.c

index d539bcf5e8c6df501dcc42d31ad449e724da324b..e03e38bab75017fe393a9e90e7a3e2c805bd7f4f 100644 (file)
 #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;
index 357b3c1bf5415dcf39e880ac9684a4c7454b102e..94dfa705dc2dc550a6e307e461a699f4ed89e8b3 100644 (file)
@@ -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)
index e15c1fb706340f2b68e776a5d58a3ce38e73c6bc..8b0b65be4dea655121eba318efac778c6bec9b47 100644 (file)
@@ -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);
index 77fb091de3798369d088e87a615e16e6b6f2bd76..6074dcd4fecc55ae94ae9c017ea70a61256469a1 100644 (file)
@@ -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 (file)
index 0000000..81181a3
--- /dev/null
@@ -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
index fd23761c82c155bb054b8962b4ab93e8e8fc2320..e3d73f4cda351f013a0ced615aafc75feaf8031e 100644 (file)
 #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);
                }
index 0a2158faf33f2da6a550d00e9e1d9f25a53a0085..ea93ba7a090bf1470617ec6367facfc6003e2578 100644 (file)
@@ -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                                            */
 /************************************************/
index 8102e60c7fb2681fdb7a97f9af81a7eebfee19e3..b476bb6c9447ee4a3a011201e52f9ef4ca5009c1 100644 (file)
 #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 (file)
index 0000000..9911062
--- /dev/null
@@ -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);
+               }
+       }
+}
index a1341fd60c3370b2b3f351a126718899e8919f87..79a40fdb60700168ff1eaf6a687e4d460fdbdc83 100644 (file)
@@ -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);
index 9f3754f32da0f326d58911277f32deba6a5d8a48..e09da2b4a3b4e523aee3883bed28a6ba5e894ed7 100644 (file)
 #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;