SVN maintenance.
[blender-staging.git] / source / blender / editors / sculpt_paint / sculpt.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software  Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2006 by Nicholas Bishop
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  * Implements the Sculpt Mode tools
30  *
31  */
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_arithb.h"
36 #include "BLI_blenlib.h"
37 #include "BLI_dynstr.h"
38
39 #include "DNA_armature_types.h"
40 #include "DNA_brush_types.h"
41 #include "DNA_image_types.h"
42 #include "DNA_key_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_modifier_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_texture_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_userdef_types.h"
52 #include "DNA_color_types.h"
53
54 #include "BKE_brush.h"
55 #include "BKE_context.h"
56 #include "BKE_customdata.h"
57 #include "BKE_DerivedMesh.h"
58 #include "BKE_depsgraph.h"
59 #include "BKE_global.h"
60 #include "BKE_image.h"
61 #include "BKE_key.h"
62 #include "BKE_library.h"
63 #include "BKE_main.h"
64 #include "BKE_mesh.h"
65 #include "BKE_modifier.h"
66 #include "BKE_multires.h"
67 #include "BKE_sculpt.h"
68 #include "BKE_texture.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_colortools.h"
71
72 #include "BIF_gl.h"
73 #include "BIF_glutil.h"
74
75 #include "WM_api.h"
76 #include "WM_types.h"
77 #include "ED_screen.h"
78 #include "ED_sculpt.h"
79 #include "ED_space_api.h"
80 #include "ED_util.h"
81 #include "ED_view3d.h"
82 #include "sculpt_intern.h"
83
84 #include "RNA_access.h"
85 #include "RNA_define.h"
86
87 #include "IMB_imbuf_types.h"
88
89 #include "RE_render_ext.h"
90 #include "RE_shader_ext.h" /*for multitex_ext*/
91
92 #include "GPU_draw.h"
93
94 #include <math.h>
95 #include <stdlib.h>
96 #include <string.h>
97
98 /* Number of vertices to average in order to determine the flatten distance */
99 #define FLATTEN_SAMPLE_SIZE 10
100
101 /* ===== STRUCTS =====
102  *
103  */
104
105 /* ActiveData stores an Index into the mvert array of Mesh, plus Fade, which
106    stores how far the vertex is from the brush center, scaled to the range [0,1]. */
107 typedef struct ActiveData {
108         struct ActiveData *next, *prev;
109         unsigned int Index;
110         float Fade;
111         float dist;
112 } ActiveData;
113
114 typedef enum StrokeFlags {
115         CLIP_X = 1,
116         CLIP_Y = 2,
117         CLIP_Z = 4
118 } StrokeFlags;
119
120 /* Cache stroke properties. Used because
121    RNA property lookup isn't particularly fast.
122
123    For descriptions of these settings, check the operator properties.
124 */
125 typedef struct StrokeCache {
126         /* Invariants */
127         float radius;
128         float scale[3];
129         int flag;
130         float clip_tolerance[3];
131         int initial_mouse[2];
132         float depth;
133
134         /* Variants */
135         float true_location[3];
136         float location[3];
137         float flip;
138         float pressure;
139         int mouse[2];
140
141         /* The rest is temporary storage that isn't saved as a property */
142
143         int first_time; /* Beginning of stroke may do some things special */
144
145         ViewContext vc;
146         bglMats *mats;
147
148         float *layer_disps; /* Displacements for each vertex */
149         float (*mesh_store)[3]; /* Copy of the mesh vertices' locations */
150         short (*orig_norms)[3]; /* Copy of the mesh vertices' normals */
151         float (*face_norms)[3]; /* Copy of the mesh faces' normals */
152         float rotation; /* Texture rotation (radians) for anchored and rake modes */
153         int pixel_radius, previous_pixel_radius;
154         ListBase grab_active_verts[8]; /* The same list of verts is used throught grab stroke */
155         float grab_delta[3], grab_delta_symmetry[3];
156         float old_grab_location[3];
157         int symmetry; /* Symmetry index between 0 and 7 */
158         float view_normal[3], view_normal_symmetry[3];
159         int last_dot[2]; /* Last location of stroke application */
160         int last_rake[2]; /* Last location of updating rake rotation */
161 } StrokeCache;
162
163 typedef struct RectNode {
164         struct RectNode *next, *prev;
165         rcti r;
166 } RectNode;
167
168 /* Used to store to 2D screen coordinates of each vertex in the mesh. */
169 typedef struct ProjVert {
170         short co[2];
171         
172         /* Used to mark whether a vertex is inside a rough bounding box
173            containing the brush. */
174         char inside;
175 } ProjVert;
176
177 /* ===== OPENGL =====
178  *
179  * Simple functions to get data from the GL
180  */
181
182 /* Uses window coordinates (x,y) and depth component z to find a point in
183    modelspace */
184 static void unproject(bglMats *mats, float out[3], const short x, const short y, const float z)
185 {
186         double ux, uy, uz;
187
188         gluUnProject(x,y,z, mats->modelview, mats->projection,
189                      (GLint *)mats->viewport, &ux, &uy, &uz );
190         out[0] = ux;
191         out[1] = uy;
192         out[2] = uz;
193 }
194
195 /* Convert a point in model coordinates to 2D screen coordinates. */
196 static void projectf(bglMats *mats, const float v[3], float p[2])
197 {
198         double ux, uy, uz;
199
200         gluProject(v[0],v[1],v[2], mats->modelview, mats->projection,
201                    (GLint *)mats->viewport, &ux, &uy, &uz);
202         p[0]= ux;
203         p[1]= uy;
204 }
205
206 static void project(bglMats *mats, const float v[3], short p[2])
207 {
208         float f[2];
209         projectf(mats, v, f);
210
211         p[0]= f[0];
212         p[1]= f[1];
213 }
214
215 /* ===== Sculpting =====
216  *
217  */
218
219 /* Return modified brush size. Uses current tablet pressure (if available) to
220    shrink the brush. Skipped for grab brush because only the first mouse down
221    size is used, which is small if the user has just touched the pen to the
222    tablet */
223 static char brush_size(Sculpt *sd)
224 {
225         float size= sd->brush->size;
226         
227         if((sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && (sd->brush->flag & BRUSH_SIZE_PRESSURE))
228                 size *= sd->session->cache->pressure;
229
230         return size;
231 }
232
233 /* Return modified brush strength. Includes the direction of the brush, positive
234    values pull vertices, negative values push. Uses tablet pressure and a
235    special multiplier found experimentally to scale the strength factor. */
236 static float brush_strength(Sculpt *sd, StrokeCache *cache)
237 {
238         /* Primary strength input; square it to make lower values more sensitive */
239         float alpha = sd->brush->alpha * sd->brush->alpha;
240
241         float dir= sd->brush->flag & BRUSH_DIR_IN ? -1 : 1;
242         float pressure= 1;
243         float flip= cache->flip ? -1:1;
244
245         if(sd->brush->flag & BRUSH_ALPHA_PRESSURE)
246                 pressure *= cache->pressure;
247         
248         switch(sd->brush->sculpt_tool){
249         case SCULPT_TOOL_DRAW:
250         case SCULPT_TOOL_INFLATE:
251         case SCULPT_TOOL_CLAY:
252         case SCULPT_TOOL_FLATTEN:
253         case SCULPT_TOOL_LAYER:
254                 return alpha * dir * pressure * flip; /*XXX: not sure why? was multiplied by G.vd->grid */;
255         case SCULPT_TOOL_SMOOTH:
256                 return alpha * 4 * pressure;
257         case SCULPT_TOOL_PINCH:
258                 return alpha / 2 * dir * pressure * flip;
259         case SCULPT_TOOL_GRAB:
260                 return 1;
261         default:
262                 return 0;
263         }
264 }
265
266 /* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */
267 static void sculpt_clip(Sculpt *sd, float *co, const float val[3])
268 {
269         int i;
270
271         for(i=0; i<3; ++i) {
272                 if(sd->flags & (SCULPT_LOCK_X << i))
273                         continue;
274
275                 if((sd->session->cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= sd->session->cache->clip_tolerance[i]))
276                         co[i]= 0.0f;
277                 else
278                         co[i]= val[i];
279         }               
280 }
281
282 static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], const short no[3])
283 {
284         float fno[3] = {no[0], no[1], no[2]};
285
286         Normalize(fno);
287
288         if((Inpf(view_vec, fno)) > 0) {
289                 VecAddf(out, out, fno);
290         } else {
291                 VecAddf(out_flip, out_flip, fno); /* out_flip is used when out is {0,0,0} */
292         }
293 }
294
295 /* Currently only for the draw brush; finds average normal for all active
296    vertices */
297 static void calc_area_normal(Sculpt *sd, float out[3], const ListBase* active_verts)
298 {
299         StrokeCache *cache = sd->session->cache;
300         ActiveData *node = active_verts->first;
301         const int view = 0; /* XXX: should probably be a flag, not number: sd->brush_type==SCULPT_TOOL_DRAW ? sculptmode_brush()->view : 0; */
302         float out_flip[3];
303         float *out_dir = cache->view_normal_symmetry;
304         
305         out[0]=out[1]=out[2] = out_flip[0]=out_flip[1]=out_flip[2] = 0;
306
307         if(sd->brush->flag & BRUSH_ANCHORED) {
308                 for(; node; node = node->next)
309                         add_norm_if(out_dir, out, out_flip, cache->orig_norms[node->Index]);
310         }
311         else {
312                 for(; node; node = node->next)
313                         add_norm_if(out_dir, out, out_flip, sd->session->mvert[node->Index].no);
314         }
315
316         if (out[0]==0.0 && out[1]==0.0 && out[2]==0.0) {
317                 VECCOPY(out, out_flip);
318         }
319         
320         Normalize(out);
321
322         if(out_dir) {
323                 out[0] = out_dir[0] * view + out[0] * (10-view);
324                 out[1] = out_dir[1] * view + out[1] * (10-view);
325                 out[2] = out_dir[2] * view + out[2] * (10-view);
326         }
327         
328         Normalize(out);
329 }
330
331 static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_verts)
332 {
333         float area_normal[3];
334         ActiveData *node= active_verts->first;
335
336         calc_area_normal(sd, area_normal, active_verts);
337         
338         while(node){
339                 float *co= ss->mvert[node->Index].co;
340
341                 const float val[3]= {co[0]+area_normal[0]*ss->cache->radius*node->Fade*ss->cache->scale[0],
342                                      co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1],
343                                      co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]};
344                                      
345                 sculpt_clip(sd, co, val);
346                 
347                 node= node->next;
348         }
349 }
350
351 /* For the smooth brush, uses the neighboring vertices around vert to calculate
352    a smoothed location for vert. Skips corner vertices (used by only one
353    polygon.) */
354 static void neighbor_average(SculptSession *ss, float avg[3], const int vert)
355 {
356         int i, skip= -1, total=0;
357         IndexNode *node= ss->fmap[vert].first;
358         char ncount= BLI_countlist(&ss->fmap[vert]);
359         MFace *f;
360
361         avg[0] = avg[1] = avg[2] = 0;
362                 
363         /* Don't modify corner vertices */
364         if(ncount==1) {
365                 VecCopyf(avg, ss->mvert[vert].co);
366                 return;
367         }
368
369         while(node){
370                 f= &ss->mface[node->index];
371                 
372                 if(f->v4) {
373                         skip= (f->v1==vert?2:
374                                f->v2==vert?3:
375                                f->v3==vert?0:
376                                f->v4==vert?1:-1);
377                 }
378
379                 for(i=0; i<(f->v4?4:3); ++i) {
380                         if(i != skip && (ncount!=2 || BLI_countlist(&ss->fmap[(&f->v1)[i]]) <= 2)) {
381                                 VecAddf(avg, avg, ss->mvert[(&f->v1)[i]].co);
382                                 ++total;
383                         }
384                 }
385
386                 node= node->next;
387         }
388
389         if(total>0)
390                 VecMulf(avg, 1.0f / total);
391         else
392                 VecCopyf(avg, ss->mvert[vert].co);
393 }
394
395 static void do_smooth_brush(Sculpt *s, const ListBase* active_verts)
396 {
397         ActiveData *node= active_verts->first;
398         int i;
399         
400         for(i = 0; i < 2; ++i) {
401                 while(node){
402                         float *co= s->session->mvert[node->Index].co;
403                         float avg[3], val[3];
404                         
405                         neighbor_average(s->session, avg, node->Index);
406                         val[0] = co[0]+(avg[0]-co[0])*node->Fade;
407                         val[1] = co[1]+(avg[1]-co[1])*node->Fade;
408                         val[2] = co[2]+(avg[2]-co[2])*node->Fade;
409                         
410                         sculpt_clip(s, co, val);
411                         node= node->next;
412                 }
413         }
414 }
415
416 static void do_pinch_brush(Sculpt *s, const ListBase* active_verts)
417 {
418         ActiveData *node= active_verts->first;
419
420         while(node) {
421                 float *co= s->session->mvert[node->Index].co;
422                 const float val[3]= {co[0]+(s->session->cache->location[0]-co[0])*node->Fade,
423                                      co[1]+(s->session->cache->location[1]-co[1])*node->Fade,
424                                      co[2]+(s->session->cache->location[2]-co[2])*node->Fade};
425                 sculpt_clip(s, co, val);
426                 node= node->next;
427         }
428 }
429
430 static void do_grab_brush(Sculpt *sd, SculptSession *ss)
431 {
432         ActiveData *node= ss->cache->grab_active_verts[ss->cache->symmetry].first;
433         float add[3];
434         float grab_delta[3];
435         
436         VecCopyf(grab_delta, ss->cache->grab_delta_symmetry);
437         
438         while(node) {
439                 float *co= ss->mvert[node->Index].co;
440                 
441                 VecCopyf(add, grab_delta);
442                 VecMulf(add, node->Fade);
443                 VecAddf(add, add, co);
444                 sculpt_clip(sd, co, add);
445
446                 node= node->next;
447         }
448         
449 }
450
451 static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active_verts)
452 {
453         float area_normal[3];
454         ActiveData *node= active_verts->first;
455         float lim= ss->cache->radius / 4;
456
457         if(ss->cache->flip)
458                 lim = -lim;
459
460         calc_area_normal(sd, area_normal, active_verts);
461
462         while(node){
463                 float *disp= &ss->cache->layer_disps[node->Index];
464                 float *co= ss->mvert[node->Index].co;
465                 float val[3];
466                 
467                 *disp+= node->Fade;
468                 
469                 /* Don't let the displacement go past the limit */
470                 if((lim < 0 && *disp < lim) || (lim > 0 && *disp > lim))
471                         *disp = lim;
472                 
473                 val[0] = ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0];
474                 val[1] = ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
475                 val[2] = ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
476
477                 sculpt_clip(sd, co, val);
478
479                 node= node->next;
480         }
481 }
482
483 static void do_inflate_brush(Sculpt *s, const ListBase *active_verts)
484 {
485         ActiveData *node= active_verts->first;
486         SculptSession *ss = s->session;
487         float add[3];
488         
489         while(node) {
490                 float *co= ss->mvert[node->Index].co;
491                 short *no= ss->mvert[node->Index].no;
492
493                 add[0]= no[0]/ 32767.0f;
494                 add[1]= no[1]/ 32767.0f;
495                 add[2]= no[2]/ 32767.0f;
496                 VecMulf(add, node->Fade * ss->cache->radius);
497                 add[0]*= ss->cache->scale[0];
498                 add[1]*= ss->cache->scale[1];
499                 add[2]*= ss->cache->scale[2];
500                 VecAddf(add, add, co);
501                 
502                 sculpt_clip(s, co, add);
503
504                 node= node->next;
505         }
506 }
507
508 static void calc_flatten_center(SculptSession *ss, ActiveData *node, float co[3])
509 {
510         ActiveData *outer[FLATTEN_SAMPLE_SIZE];
511         int i;
512         
513         for(i = 0; i < FLATTEN_SAMPLE_SIZE; ++i)
514                 outer[i] = node;
515                 
516         for(; node; node = node->next) {
517                 for(i = 0; i < FLATTEN_SAMPLE_SIZE; ++i) {
518                         if(node->dist > outer[i]->dist) {
519                                 outer[i] = node;
520                                 break;
521                         }
522                 }
523         }
524         
525         co[0] = co[1] = co[2] = 0.0f;
526         for(i = 0; i < FLATTEN_SAMPLE_SIZE; ++i)
527                 VecAddf(co, co, ss->mvert[outer[i]->Index].co);
528         VecMulf(co, 1.0f / FLATTEN_SAMPLE_SIZE);
529 }
530
531 static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase *active_verts, int clay)
532 {
533         ActiveData *node= active_verts->first;
534         /* area_normal and cntr define the plane towards which vertices are squashed */
535         float area_normal[3];
536         float cntr[3];
537
538         calc_area_normal(sd, area_normal, active_verts);
539         calc_flatten_center(ss, node, cntr);
540
541         while(node){
542                 float *co= ss->mvert[node->Index].co;
543                 float p1[3], sub1[3], sub2[3], intr[3], val[3];
544                 
545                 /* Find the intersection between squash-plane and vertex (along the area normal) */
546                 VecSubf(p1, co, area_normal);
547                 VecSubf(sub1, cntr, p1);
548                 VecSubf(sub2, co, p1);
549                 VecSubf(intr, co, p1);
550                 VecMulf(intr, Inpf(area_normal, sub1) / Inpf(area_normal, sub2));
551                 VecAddf(intr, intr, p1);
552                 
553                 VecSubf(val, intr, co);
554                 VecMulf(val, fabs(node->Fade));
555                 VecAddf(val, val, co);
556                 
557                 if(clay) {
558                         /* Clay brush displaces after flattening */
559                         float tmp[3];
560                         VecCopyf(tmp, area_normal);
561                         VecMulf(tmp, ss->cache->radius * node->Fade * 0.1);
562                         VecAddf(val, val, tmp);
563                 }
564
565                 sculpt_clip(sd, co, val);
566                 
567                 node= node->next;
568         }
569 }
570  
571 /* Uses symm to selectively flip any axis of a coordinate. */
572 static void flip_coord(float out[3], float in[3], const char symm)
573 {
574         if(symm & SCULPT_SYMM_X)
575                 out[0]= -in[0];
576         else
577                 out[0]= in[0];
578         if(symm & SCULPT_SYMM_Y)
579                 out[1]= -in[1];
580         else
581                 out[1]= in[1];
582         if(symm & SCULPT_SYMM_Z)
583                 out[2]= -in[2];
584         else
585                 out[2]= in[2];
586 }
587
588 /* Get a pixel from the texcache at (px, py) */
589 static unsigned char get_texcache_pixel(const SculptSession *ss, int px, int py)
590 {
591         unsigned *p;
592         p = ss->texcache + py * ss->texcache_side + px;
593         return ((unsigned char*)(p))[0];
594 }
595
596 static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float v)
597 {
598         int x, y, x2, y2;
599         const int tc_max = ss->texcache_side - 1;
600         float urat, vrat, uopp;
601
602         if(u < 0) u = 0;
603         else if(u >= ss->texcache_side) u = tc_max;
604         if(v < 0) v = 0;
605         else if(v >= ss->texcache_side) v = tc_max;
606
607         x = floor(u);
608         y = floor(v);
609         x2 = x + 1;
610         y2 = y + 1;
611
612         if(x2 > ss->texcache_side) x2 = tc_max;
613         if(y2 > ss->texcache_side) y2 = tc_max;
614         
615         urat = u - x;
616         vrat = v - y;
617         uopp = 1 - urat;
618                 
619         return ((get_texcache_pixel(ss, x, y) * uopp +
620                  get_texcache_pixel(ss, x2, y) * urat) * (1 - vrat) + 
621                 (get_texcache_pixel(ss, x, y2) * uopp +
622                  get_texcache_pixel(ss, x2, y2) * urat) * vrat) / 255.0;
623 }
624
625 /* Return a multiplier for brush strength on a particular vertex. */
626 static float tex_strength(Sculpt *sd, float *point, const float len)
627 {
628         SculptSession *ss= sd->session;
629         Brush *br = sd->brush;
630         float avg= 1;
631
632         if(br->texact==-1 || !br->mtex[br->texact])
633                 avg= 1;
634         else if(br->tex_mode==BRUSH_TEX_3D) {
635                 /* Get strength by feeding the vertex location directly
636                    into a texture */
637                 float jnk;
638                 const float factor= 0.01;
639                 MTex mtex;
640                 memset(&mtex,0,sizeof(MTex));
641                 mtex.tex= br->mtex[br->texact]->tex;
642                 mtex.projx= 1;
643                 mtex.projy= 2;
644                 mtex.projz= 3;
645                 VecCopyf(mtex.size, br->mtex[br->texact]->size);
646                 VecMulf(mtex.size, factor);
647                 if(!sd->texsep)
648                         mtex.size[1]= mtex.size[2]= mtex.size[0];
649                 
650                 externtex(&mtex,point,&avg,&jnk,&jnk,&jnk,&jnk);
651         }
652         else if(ss->texcache) {
653                 const float bsize= ss->cache->pixel_radius * 2;
654                 const float rot= sd->brush->rot + ss->cache->rotation;
655                 int px, py;
656                 float flip[3], point_2d[2];
657
658                 /* If the active area is being applied for symmetry, flip it
659                    across the symmetry axis in order to project it. This insures
660                    that the brush texture will be oriented correctly. */
661                 VecCopyf(flip, point);
662                 flip_coord(flip, flip, ss->cache->symmetry);
663                 projectf(ss->cache->mats, flip, point_2d);
664
665                 /* For Tile and Drag modes, get the 2D screen coordinates of the
666                    and scale them up or down to the texture size. */
667                 if(br->tex_mode==BRUSH_TEX_TILE) {
668                         const int sx= (const int)br->mtex[br->texact]->size[0];
669                         const int sy= (const int)sd->texsep ? br->mtex[br->texact]->size[1] : sx;
670                         
671                         float fx= point_2d[0];
672                         float fy= point_2d[1];
673                         
674                         float angle= atan2(fy, fx) - rot;
675                         float flen= sqrtf(fx*fx + fy*fy);
676                         
677                         if(rot<0.001 && rot>-0.001) {
678                                 px= point_2d[0];
679                                 py= point_2d[1];
680                         } else {
681                                 px= flen * cos(angle) + 2000;
682                                 py= flen * sin(angle) + 2000;
683                         }
684                         if(sx != 1)
685                                 px %= sx-1;
686                         if(sy != 1)
687                                 py %= sy-1;
688                         avg= get_texcache_pixel_bilinear(ss, ss->texcache_side*px/sx, ss->texcache_side*py/sy);
689                 } else {
690                         float fx= (point_2d[0] - ss->cache->mouse[0]) / bsize;
691                         float fy= (point_2d[1] - ss->cache->mouse[1]) / bsize;
692
693                         float angle= atan2(fy, fx) - rot;
694                         float flen= sqrtf(fx*fx + fy*fy);
695                         
696                         fx = flen * cos(angle) + 0.5;
697                         fy = flen * sin(angle) + 0.5;
698
699                         avg= get_texcache_pixel_bilinear(ss, fx * ss->texcache_side, fy * ss->texcache_side);
700                 }
701         }
702
703         avg*= brush_curve_strength(sd->brush, len, ss->cache->radius); /* Falloff curve */
704
705         return avg;
706 }
707
708 /* Mark area around the brush as damaged. projverts are marked if they are
709    inside the area and the damaged rectangle in 2D screen coordinates is 
710    added to damaged_rects. */
711 static void sculpt_add_damaged_rect(SculptSession *ss)
712 {
713         short p[2];
714         RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode");
715         const float radius = MAX2(ss->cache->pixel_radius, ss->cache->previous_pixel_radius);
716         unsigned i;
717
718         /* Find center */
719         project(ss->cache->mats, ss->cache->location, p);
720         rn->r.xmin= p[0] - radius;
721         rn->r.ymin= p[1] - radius;
722         rn->r.xmax= p[0] + radius;
723         rn->r.ymax= p[1] + radius;
724
725         BLI_addtail(&ss->damaged_rects, rn);
726
727         /* Update insides */
728         for(i=0; i<ss->totvert; ++i) {
729                 if(!ss->projverts[i].inside) {
730                         if(ss->projverts[i].co[0] > rn->r.xmin && ss->projverts[i].co[1] > rn->r.ymin &&
731                            ss->projverts[i].co[0] < rn->r.xmax && ss->projverts[i].co[1] < rn->r.ymax) {
732                                 ss->projverts[i].inside= 1;
733                         }
734                 }
735                 // XXX: remember to fix this!
736                 // temporary pass
737                 ss->projverts[i].inside = 1;
738         }
739 }
740
741 /* Clears the depth buffer in each modified area. */
742 #if 0
743 static void sculpt_clear_damaged_areas(SculptSession *ss)
744 {
745         RectNode *rn= NULL;
746
747         for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
748                 rcti clp = rn->r;
749                 rcti *win = NULL; /*XXX: &curarea->winrct; */
750                 
751                 clp.xmin += win->xmin;
752                 clp.xmax += win->xmin;
753                 clp.ymin += win->ymin;
754                 clp.ymax += win->ymin;
755                 
756                 if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
757                    clp.ymin < win->ymax && clp.ymax > win->ymin) {
758                         if(clp.xmin < win->xmin) clp.xmin = win->xmin;
759                         if(clp.ymin < win->ymin) clp.ymin = win->ymin;
760                         if(clp.xmax > win->xmax) clp.xmax = win->xmax;
761                         if(clp.ymax > win->ymax) clp.ymax = win->ymax;
762
763                         glScissor(clp.xmin + 1, clp.ymin + 1,
764                                   clp.xmax - clp.xmin - 2,
765                                   clp.ymax - clp.ymin - 2);
766                 }
767                 
768                 glClear(GL_DEPTH_BUFFER_BIT);
769         }
770 }
771 #endif
772 static void do_brush_action(Sculpt *sd, StrokeCache *cache)
773 {
774         SculptSession *ss = sd->session;
775         float av_dist;
776         ListBase active_verts={0,0};
777         ListBase *grab_active_verts = &ss->cache->grab_active_verts[ss->cache->symmetry];
778         ActiveData *adata= 0;
779         float *vert;
780         Mesh *me= NULL; /*XXX: get_mesh(OBACT); */
781         const float bstrength= brush_strength(sd, cache);
782         KeyBlock *keyblock= NULL; /*XXX: ob_get_keyblock(OBACT); */
783         Brush *b = sd->brush;
784         int i;
785
786         sculpt_add_damaged_rect(ss);
787
788         /* Build a list of all vertices that are potentially within the brush's
789            area of influence. Only do this once for the grab brush. */
790         if((b->sculpt_tool != SCULPT_TOOL_GRAB) || cache->first_time) {
791                 for(i=0; i<ss->totvert; ++i) {
792                         /* Projverts.inside provides a rough bounding box */
793                         if(ss->multires || ss->projverts[i].inside) {
794                                 //vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : a->verts[i].co;
795                                 vert= ss->mvert[i].co;
796                                 av_dist= VecLenf(ss->cache->location, vert);
797                                 if(av_dist < cache->radius) {
798                                         adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
799
800                                         adata->Index = i;
801                                         /* Fade is used to store the final strength at which the brush
802                                            should modify a particular vertex. */
803                                         adata->Fade= tex_strength(sd, vert, av_dist) * bstrength;
804                                         adata->dist = av_dist;
805
806                                         if(b->sculpt_tool == SCULPT_TOOL_GRAB && cache->first_time)
807                                                 BLI_addtail(grab_active_verts, adata);
808                                         else
809                                                 BLI_addtail(&active_verts, adata);
810                                 }
811                         }
812                 }
813         }
814
815         /* Only act if some verts are inside the brush area */
816         if(active_verts.first || (b->sculpt_tool == SCULPT_TOOL_GRAB && grab_active_verts->first)) {
817                 /* Apply one type of brush action */
818                 switch(b->sculpt_tool){
819                 case SCULPT_TOOL_DRAW:
820                         do_draw_brush(sd, ss, &active_verts);
821                         break;
822                 case SCULPT_TOOL_SMOOTH:
823                         do_smooth_brush(sd, &active_verts);
824                         break;
825                 case SCULPT_TOOL_PINCH:
826                         do_pinch_brush(sd, &active_verts);
827                         break;
828                 case SCULPT_TOOL_INFLATE:
829                         do_inflate_brush(sd, &active_verts);
830                         break;
831                 case SCULPT_TOOL_GRAB:
832                         do_grab_brush(sd, ss);
833                         break;
834                 case SCULPT_TOOL_LAYER:
835                         do_layer_brush(sd, ss, &active_verts);
836                         break;
837                 case SCULPT_TOOL_FLATTEN:
838                         do_flatten_clay_brush(sd, ss, &active_verts, 0);
839                         break;
840                 case SCULPT_TOOL_CLAY:
841                         do_flatten_clay_brush(sd, ss, &active_verts, 1);
842                 }
843         
844                 /* Copy the modified vertices from mesh to the active key */
845                 if(keyblock && !ss->multires) {
846                         float *co= keyblock->data;
847                         if(co) {
848                                 if(b->sculpt_tool == SCULPT_TOOL_GRAB)
849                                         adata = grab_active_verts->first;
850                                 else
851                                         adata = active_verts.first;
852
853                                 for(; adata; adata= adata->next)
854                                         if(adata->Index < keyblock->totelem)
855                                                 VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
856                         }
857                 }
858
859                 if(ss->vertexcosnos && !ss->multires)
860                         BLI_freelistN(&active_verts);
861                 else {
862                         if(b->sculpt_tool != SCULPT_TOOL_GRAB)
863                                 addlisttolist(&ss->damaged_verts, &active_verts);
864                 }
865         }
866 }
867
868 /* Flip all the editdata across the axis/axes specified by symm. Used to
869    calculate multiple modifications to the mesh when symmetry is enabled. */
870 static void calc_brushdata_symm(StrokeCache *cache, const char symm)
871 {
872         flip_coord(cache->location, cache->true_location, symm);
873         flip_coord(cache->view_normal_symmetry, cache->view_normal, symm);
874         flip_coord(cache->grab_delta_symmetry, cache->grab_delta, symm);
875         cache->symmetry= symm;
876 }
877
878 static void do_symmetrical_brush_actions(Sculpt *sd, StrokeCache *cache)
879 {
880         const char symm = sd->flags & 7;
881         int i;
882
883         /* Brush spacing: only apply dot if next dot is far enough away */
884         if((sd->brush->flag & BRUSH_SPACE) && !(sd->brush->flag & BRUSH_ANCHORED) && !cache->first_time) {
885                 int dx = cache->last_dot[0] - cache->mouse[0];
886                 int dy = cache->last_dot[1] - cache->mouse[1];
887                 if(sqrt(dx*dx+dy*dy) < sd->brush->spacing)
888                         return;
889         }
890         memcpy(cache->last_dot, cache->mouse, sizeof(int) * 2);
891
892         VecCopyf(cache->location, cache->true_location);
893         VecCopyf(cache->grab_delta_symmetry, cache->grab_delta);
894         cache->symmetry = 0;
895         do_brush_action(sd, cache);
896
897         for(i = 1; i <= symm; ++i) {
898                 if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
899                         calc_brushdata_symm(cache, i);
900                         do_brush_action(sd, cache);
901                 }
902         }
903
904         cache->first_time = 0;
905 }
906
907 static void add_face_normal(vec3f *norm, MVert *mvert, const MFace* face, float *fn)
908 {
909         vec3f c= {mvert[face->v1].co[0],mvert[face->v1].co[1],mvert[face->v1].co[2]};
910         vec3f b= {mvert[face->v2].co[0],mvert[face->v2].co[1],mvert[face->v2].co[2]};
911         vec3f a= {mvert[face->v3].co[0],mvert[face->v3].co[1],mvert[face->v3].co[2]};
912         vec3f s1, s2;
913         float final[3];
914
915         VecSubf(&s1.x,&a.x,&b.x);
916         VecSubf(&s2.x,&c.x,&b.x);
917
918         final[0] = s1.y * s2.z - s1.z * s2.y;
919         final[1] = s1.z * s2.x - s1.x * s2.z;
920         final[2] = s1.x * s2.y - s1.y * s2.x;
921
922         if(fn)
923                 VecCopyf(fn, final);
924
925         norm->x+= final[0];
926         norm->y+= final[1];
927         norm->z+= final[2];
928 }
929
930 static void update_damaged_vert(SculptSession *ss, ListBase *lb)
931 {
932         ActiveData *vert;
933        
934         for(vert= lb->first; vert; vert= vert->next) {
935                 vec3f norm= {0,0,0};            
936                 IndexNode *face= ss->fmap[vert->Index].first;
937
938                 while(face){
939                         float *fn = NULL;
940                         if(ss->face_normals)
941                                 fn = &ss->face_normals[face->index*3];
942                         add_face_normal(&norm, ss->mvert, &ss->mface[face->index], fn);
943                         face= face->next;
944                 }
945                 Normalize(&norm.x);
946                 
947                 ss->mvert[vert->Index].no[0]=norm.x*32767;
948                 ss->mvert[vert->Index].no[1]=norm.y*32767;
949                 ss->mvert[vert->Index].no[2]=norm.z*32767;
950         }
951 }
952
953 static void calc_damaged_verts(SculptSession *ss)
954 {
955         int i;
956         
957         for(i=0; i<8; ++i)
958                 update_damaged_vert(ss, &ss->cache->grab_active_verts[i]);
959         update_damaged_vert(ss, &ss->damaged_verts);
960         BLI_freelistN(&ss->damaged_verts);
961         ss->damaged_verts.first = ss->damaged_verts.last = NULL;
962 }
963
964 #if 0
965 static void projverts_clear_inside(SculptSession *ss)
966 {
967         int i;
968         for(i = 0; i < ss->totvert; ++i)
969                 ss->projverts[i].inside = 0;
970 }
971 #endif
972
973 static void sculpt_update_tex(Sculpt *sd)
974 {
975         SculptSession *ss= sd->session;
976
977         if(ss->texcache) {
978                 MEM_freeN(ss->texcache);
979                 ss->texcache= NULL;
980         }
981
982         /* Need to allocate a bigger buffer for bigger brush size */
983         ss->texcache_side = sd->brush->size * 2;
984         if(!ss->texcache || ss->texcache_side > ss->texcache_actual) {
985                 ss->texcache = brush_gen_texture_cache(sd->brush, sd->brush->size);
986                 ss->texcache_actual = ss->texcache_side;
987         }
988 }
989
990 void sculptmode_selectbrush_menu(void)
991 {
992         /* XXX: I guess menus belong elsewhere too?
993
994         Sculpt *sd= sculpt_data();
995         int val;
996         
997         pupmenu_set_active(sd->brush_type);
998         
999         val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
1000
1001         if(val>0) {
1002                 sd->brush_type= val;
1003
1004                 allqueue(REDRAWVIEW3D, 1);
1005                 allqueue(REDRAWBUTSEDIT, 1);
1006         }*/
1007 }
1008
1009 static void sculptmode_update_all_projverts(SculptSession *ss)
1010 {
1011         unsigned i;
1012
1013         if(!ss->projverts)
1014                 ss->projverts = MEM_mallocN(sizeof(ProjVert)*ss->totvert,"ProjVerts");
1015
1016         for(i=0; i<ss->totvert; ++i) {
1017                 project(ss->cache->mats, ss->vertexcosnos ? &ss->vertexcosnos[i * 6] : ss->mvert[i].co,
1018                         ss->projverts[i].co);
1019                 ss->projverts[i].inside= 0;
1020         }
1021 }
1022
1023 /* Checks whether full update mode (slower) needs to be used to work with modifiers */
1024 char sculpt_modifiers_active(Object *ob)
1025 {
1026         ModifierData *md;
1027         
1028         for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) {
1029                 if(md->mode & eModifierMode_Realtime && md->type != eModifierType_Multires)
1030                         return 1;
1031         }
1032         
1033         return 0;
1034 }
1035
1036 /* Sculpt mode handles multires differently from regular meshes, but only if
1037    it's the last modifier on the stack and it is not on the first level */
1038 static struct MultiresModifierData *sculpt_multires_active(Object *ob)
1039 {
1040         ModifierData *md;
1041         
1042         for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) {
1043                 if(md->type == eModifierType_Multires && !md->next) {
1044                         MultiresModifierData *mmd = (MultiresModifierData*)md;
1045                         if(mmd->lvl != 1)
1046                                 return mmd;
1047                 }
1048         }
1049
1050         return NULL;
1051 }
1052
1053 static void sculpt_update_mesh_elements(bContext *C)
1054 {
1055         SculptSession *ss = CTX_data_tool_settings(C)->sculpt->session;
1056         Object *ob = CTX_data_active_object(C);
1057         int oldtotvert = ss->totvert;
1058
1059         if((ss->multires = sculpt_multires_active(ob))) {
1060                 DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH);
1061                 ss->totvert = dm->getNumVerts(dm);
1062                 ss->totface = dm->getNumFaces(dm);
1063                 ss->mvert = dm->getVertDataArray(dm, CD_MVERT);
1064                 ss->mface = dm->getFaceDataArray(dm, CD_MFACE);
1065                 ss->face_normals = dm->getFaceDataArray(dm, CD_NORMAL);
1066         }
1067         else {
1068                 Mesh *me = get_mesh(ob);
1069                 ss->totvert = me->totvert;
1070                 ss->totface = me->totface;
1071                 ss->mvert = me->mvert;
1072                 ss->mface = me->mface;
1073                 ss->face_normals = NULL;
1074         }
1075
1076         if(ss->totvert != oldtotvert) {
1077                 if(ss->projverts) MEM_freeN(ss->projverts);
1078                 ss->projverts = NULL;
1079
1080                 if(ss->fmap) MEM_freeN(ss->fmap);
1081                 if(ss->fmap_mem) MEM_freeN(ss->fmap_mem);
1082                 create_vert_face_map(&ss->fmap, &ss->fmap_mem, ss->mface, ss->totvert, ss->totface);
1083                 ss->fmap_size = ss->totvert;
1084         }
1085 }
1086
1087 /* XXX: lots of drawing code (partial redraw), has to go elsewhere */
1088 #if 0
1089 void sculptmode_draw_wires(SculptSession *ss, int only_damaged)
1090 {
1091         Mesh *me = get_mesh(OBACT);
1092         int i;
1093
1094         bglPolygonOffset(1.0);
1095         glDepthMask(0);
1096         BIF_ThemeColor((OBACT==OBACT)?TH_ACTIVE:TH_SELECT);
1097
1098         for(i=0; i<me->totedge; i++) {
1099                 MEdge *med= &me->medge[i];
1100
1101                 if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
1102                    (med->flag & ME_EDGEDRAW)) {
1103                         glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
1104                 }
1105         }
1106
1107         glDepthMask(1);
1108         bglPolygonOffset(0.0);
1109 }
1110
1111 void sculptmode_draw_mesh(int only_damaged) 
1112 {
1113         int i, j, dt, drawCurrentMat = 1, matnr= -1;
1114         SculptSession *ss = sculpt_session();
1115
1116         sculpt_update_mesh_elements(ss, OBACT);
1117
1118         persp(PERSP_VIEW);
1119         mymultmatrix(OBACT->obmat);
1120         glEnable(GL_DEPTH_TEST);
1121         glEnable(GL_LIGHTING);
1122         /* XXX: GPU_set_object_materials(G.scene, OBACT, 0, NULL); */
1123         glEnable(GL_CULL_FACE);
1124
1125         glShadeModel(GL_SMOOTH);
1126
1127         glVertexPointer(3, GL_FLOAT, sizeof(MVert), &cache->mvert[0].co);
1128         glNormalPointer(GL_SHORT, sizeof(MVert), &cache->mvert[0].no);
1129
1130         dt= MIN2(G.vd->drawtype, OBACT->dt);
1131         if(dt==OB_WIRE)
1132                 glColorMask(0,0,0,0);
1133
1134         for(i=0; i<ss->totface; ++i) {
1135                 MFace *f= &ss->mface[i];
1136                 char inside= 0;
1137                 int new_matnr= f->mat_nr + 1;
1138                 
1139                 if(new_matnr != matnr)
1140                         drawCurrentMat= GPU_enable_material(matnr = new_matnr, NULL);
1141                 
1142                 /* If only_damaged!=0, only draw faces that are partially
1143                    inside the area(s) modified by the brush */
1144                 if(only_damaged) {
1145                         for(j=0; j<(f->v4?4:3); ++j) {
1146                                 if(ss->projverts[*((&f->v1)+j)].inside) {
1147                                         inside= 1;
1148                                         break;
1149                                 }
1150                         }
1151                 }
1152                 else
1153                         inside= 1;
1154                         
1155                 if(inside && drawCurrentMat)
1156                         glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
1157         }
1158
1159         glDisable(GL_CULL_FACE);
1160         glDisable(GL_LIGHTING);
1161         glColorMask(1,1,1,1);
1162
1163         if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
1164                 sculptmode_draw_wires(ss, only_damaged);
1165
1166         glDisable(GL_DEPTH_TEST);
1167 }
1168 #endif
1169
1170 static int sculpt_mode_poll(bContext *C)
1171 {
1172         return G.f & G_SCULPTMODE;
1173 }
1174
1175 static int sculpt_poll(bContext *C)
1176 {
1177         return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
1178                 CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW;
1179 }
1180
1181 /*** Sculpt Cursor ***/
1182 static void draw_paint_cursor(bContext *C, int x, int y, void *customdata)
1183 {
1184         Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
1185         
1186         glTranslatef((float)x, (float)y, 0.0f);
1187         
1188         glColor4ub(255, 100, 100, 128);
1189         glEnable( GL_LINE_SMOOTH );
1190         glEnable(GL_BLEND);
1191         glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40);
1192         glDisable(GL_BLEND);
1193         glDisable( GL_LINE_SMOOTH );
1194         
1195         glTranslatef((float)-x, (float)-y, 0.0f);
1196 }
1197
1198 static void toggle_paint_cursor(bContext *C)
1199 {
1200         Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt;
1201
1202         if(s->session->cursor) {
1203                 WM_paint_cursor_end(CTX_wm_manager(C), s->session->cursor);
1204                 s->session->cursor = NULL;
1205         }
1206         else {
1207                 s->session->cursor =
1208                         WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL);
1209         }
1210 }
1211
1212 static void sculpt_undo_push(bContext *C, Sculpt *sd)
1213 {
1214         switch(sd->brush->sculpt_tool) {
1215         case SCULPT_TOOL_DRAW:
1216                 ED_undo_push(C, "Draw Brush"); break;
1217         case SCULPT_TOOL_SMOOTH:
1218                 ED_undo_push(C, "Smooth Brush"); break;
1219         case SCULPT_TOOL_PINCH:
1220                 ED_undo_push(C, "Pinch Brush"); break;
1221         case SCULPT_TOOL_INFLATE:
1222                 ED_undo_push(C, "Inflate Brush"); break;
1223         case SCULPT_TOOL_GRAB:
1224                 ED_undo_push(C, "Grab Brush"); break;
1225         case SCULPT_TOOL_LAYER:
1226                 ED_undo_push(C, "Layer Brush"); break;
1227         case SCULPT_TOOL_FLATTEN:
1228                 ED_undo_push(C, "Flatten Brush"); break;
1229         default:
1230                 ED_undo_push(C, "Sculpting"); break;
1231         }
1232 }
1233
1234 static int sculpt_brush_curve_preset_exec(bContext *C, wmOperator *op)
1235 {
1236         brush_curve_preset(CTX_data_scene(C)->toolsettings->sculpt->brush, RNA_enum_get(op->ptr, "mode"));
1237         return OPERATOR_FINISHED;
1238 }
1239
1240 static void SCULPT_OT_brush_curve_preset(wmOperatorType *ot)
1241 {
1242         static EnumPropertyItem prop_mode_items[] = {
1243                 {BRUSH_PRESET_SHARP, "SHARP", 0, "Sharp Curve", ""},
1244                 {BRUSH_PRESET_SMOOTH, "SMOOTH", 0, "Smooth Curve", ""},
1245                 {BRUSH_PRESET_MAX, "MAX", 0, "Max Curve", ""},
1246                 {0, NULL, 0, NULL, NULL}};
1247
1248         ot->name= "Preset";
1249         ot->idname= "SCULPT_OT_brush_curve_preset";
1250
1251         ot->exec= sculpt_brush_curve_preset_exec;
1252         ot->poll= sculpt_mode_poll;
1253
1254         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1255
1256         RNA_def_enum(ot->srna, "mode", prop_mode_items, BRUSH_PRESET_SHARP, "Mode", "");
1257 }
1258
1259 /**** Radial control ****/
1260 static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
1261 {
1262         toggle_paint_cursor(C);
1263         brush_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->sculpt->brush, 1);
1264         return WM_radial_control_invoke(C, op, event);
1265 }
1266
1267 static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
1268 {
1269         int ret = WM_radial_control_modal(C, op, event);
1270         if(ret != OPERATOR_RUNNING_MODAL)
1271                 toggle_paint_cursor(C);
1272         return ret;
1273 }
1274
1275 static int sculpt_radial_control_exec(bContext *C, wmOperator *op)
1276 {
1277         return brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->sculpt->brush, 1);
1278 }
1279
1280 static void SCULPT_OT_radial_control(wmOperatorType *ot)
1281 {
1282         WM_OT_radial_control_partial(ot);
1283
1284         ot->name= "Sculpt Radial Control";
1285         ot->idname= "SCULPT_OT_radial_control";
1286
1287         ot->invoke= sculpt_radial_control_invoke;
1288         ot->modal= sculpt_radial_control_modal;
1289         ot->exec= sculpt_radial_control_exec;
1290         ot->poll= sculpt_poll;
1291
1292         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1293 }
1294
1295 /**** Operator for applying a stroke (various attributes including mouse path)
1296       using the current brush. ****/
1297
1298 static float unproject_brush_radius(SculptSession *ss, float offset)
1299 {
1300         float brush_edge[3];
1301
1302         /* In anchored mode, brush size changes with mouse loc, otherwise it's fixed using the brush radius */
1303         unproject(ss->cache->mats, brush_edge, ss->cache->initial_mouse[0] + offset,
1304                   ss->cache->initial_mouse[1], ss->cache->depth);
1305
1306         return VecLenf(ss->cache->true_location, brush_edge);
1307 }
1308
1309 static void sculpt_cache_free(StrokeCache *cache)
1310 {
1311         if(cache->layer_disps)
1312                 MEM_freeN(cache->layer_disps);
1313         if(cache->mesh_store)
1314                 MEM_freeN(cache->mesh_store);
1315         if(cache->orig_norms)
1316                 MEM_freeN(cache->orig_norms);
1317         if(cache->face_norms)
1318                 MEM_freeN(cache->face_norms);
1319         if(cache->mats)
1320                 MEM_freeN(cache->mats);
1321         MEM_freeN(cache);
1322 }
1323
1324 /* Initialize the stroke cache invariants from operator properties */
1325 static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *op)
1326 {
1327         StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
1328         int i;
1329
1330         sd->session->cache = cache;
1331
1332         RNA_float_get_array(op->ptr, "scale", cache->scale);
1333         cache->flag = RNA_int_get(op->ptr, "flag");
1334         RNA_float_get_array(op->ptr, "clip_tolerance", cache->clip_tolerance);
1335         RNA_int_get_array(op->ptr, "initial_mouse", cache->initial_mouse);
1336         cache->depth = RNA_float_get(op->ptr, "depth");
1337
1338         /* Truly temporary data that isn't stored in properties */
1339
1340         view3d_set_viewcontext(C, &cache->vc);
1341
1342         cache->mats = MEM_callocN(sizeof(bglMats), "sculpt bglMats");
1343         view3d_get_transformation(&cache->vc, cache->vc.obact, cache->mats);
1344
1345         sculpt_update_mesh_elements(C);
1346
1347         if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
1348                 cache->layer_disps = MEM_callocN(sizeof(float) * sd->session->totvert, "layer brush displacements");
1349
1350         /* Make copies of the mesh vertex locations and normals for some tools */
1351         if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER || (sd->brush->flag & BRUSH_ANCHORED)) {
1352                 cache->mesh_store= MEM_mallocN(sizeof(float) * 3 * sd->session->totvert, "sculpt mesh vertices copy");
1353                 for(i = 0; i < sd->session->totvert; ++i)
1354                         VecCopyf(cache->mesh_store[i], sd->session->mvert[i].co);
1355
1356                 if(sd->brush->flag & BRUSH_ANCHORED) {
1357                         cache->orig_norms= MEM_mallocN(sizeof(short) * 3 * sd->session->totvert, "Sculpt orig norm");
1358                         for(i = 0; i < sd->session->totvert; ++i) {
1359                                 cache->orig_norms[i][0] = sd->session->mvert[i].no[0];
1360                                 cache->orig_norms[i][1] = sd->session->mvert[i].no[1];
1361                                 cache->orig_norms[i][2] = sd->session->mvert[i].no[2];
1362                         }
1363
1364                         if(sd->session->face_normals) {
1365                                 float *fn = sd->session->face_normals;
1366                                 cache->face_norms= MEM_mallocN(sizeof(float) * 3 * sd->session->totface, "Sculpt face norms");
1367                                 for(i = 0; i < sd->session->totface; ++i, fn += 3)
1368                                         VecCopyf(cache->face_norms[i], fn);
1369                         }
1370                 }
1371         }
1372
1373         unproject(cache->mats, cache->true_location, cache->initial_mouse[0], cache->initial_mouse[1], cache->depth);
1374         cache->radius = unproject_brush_radius(sd->session, brush_size(sd));
1375         cache->rotation = 0;
1376         cache->first_time = 1;
1377 }
1378
1379 /* Initialize the stroke cache variants from operator properties */
1380 static void sculpt_update_cache_variants(Sculpt *sd, PointerRNA *ptr)
1381 {
1382         StrokeCache *cache = sd->session->cache;
1383         float grab_location[3];
1384         int dx, dy;
1385
1386         if(!(sd->brush->flag & BRUSH_ANCHORED))
1387                 RNA_float_get_array(ptr, "location", cache->true_location);
1388         cache->flip = RNA_boolean_get(ptr, "flip");
1389         RNA_int_get_array(ptr, "mouse", cache->mouse);
1390         
1391         /* Truly temporary data that isn't stored in properties */
1392
1393         cache->previous_pixel_radius = cache->pixel_radius;
1394         cache->pixel_radius = brush_size(sd);
1395
1396         if(sd->brush->flag & BRUSH_ANCHORED) {
1397                 dx = cache->mouse[0] - cache->initial_mouse[0];
1398                 dy = cache->mouse[1] - cache->initial_mouse[1];
1399                 cache->pixel_radius = sqrt(dx*dx + dy*dy);
1400                 cache->radius = unproject_brush_radius(sd->session, cache->pixel_radius);
1401                 cache->rotation = atan2(dy, dx);
1402         }
1403         else if(sd->brush->flag & BRUSH_RAKE) {
1404                 int update;
1405
1406                 dx = cache->last_rake[0] - cache->mouse[0];
1407                 dy = cache->last_rake[1] - cache->mouse[1];
1408
1409                 update = dx*dx + dy*dy > 100;
1410
1411                 /* To prevent jitter, only update the angle if the mouse has moved over 10 pixels */
1412                 if(update && !cache->first_time)
1413                         cache->rotation = M_PI_2 + atan2(dy, dx);
1414
1415                 if(update || cache->first_time) {
1416                         cache->last_rake[0] = cache->mouse[0];
1417                         cache->last_rake[1] = cache->mouse[1];
1418                 }
1419         }
1420
1421         /* Find the grab delta */
1422         if(sd->brush->sculpt_tool == SCULPT_TOOL_GRAB) {
1423                 unproject(cache->mats, grab_location, cache->mouse[0], cache->mouse[1], cache->depth);
1424                 if(!cache->first_time)
1425                         VecSubf(cache->grab_delta, grab_location, cache->old_grab_location);
1426                 VecCopyf(cache->old_grab_location, grab_location);
1427         }
1428 }
1429
1430 /* Initialize stroke operator properties */
1431 static void sculpt_brush_stroke_init_properties(bContext *C, wmOperator *op, wmEvent *event, SculptSession *ss)
1432 {
1433         Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
1434         Object *ob= CTX_data_active_object(C);
1435         ModifierData *md;
1436         ViewContext vc;
1437         float scale[3], clip_tolerance[3] = {0,0,0};
1438         int mouse[2], flag = 0;
1439
1440         /* Set scaling adjustment */
1441         scale[0] = 1.0f / ob->size[0];
1442         scale[1] = 1.0f / ob->size[1];
1443         scale[2] = 1.0f / ob->size[2];
1444         RNA_float_set_array(op->ptr, "scale", scale);
1445
1446         /* Initialize mirror modifier clipping */
1447         for(md= ob->modifiers.first; md; md= md->next) {
1448                 if(md->type==eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
1449                         const MirrorModifierData *mmd = (MirrorModifierData*) md;
1450                         
1451                         /* Mark each axis that needs clipping along with its tolerance */
1452                         if(mmd->flag & MOD_MIR_CLIPPING) {
1453                                 flag |= CLIP_X << mmd->axis;
1454                                 if(mmd->tolerance > clip_tolerance[mmd->axis])
1455                                         clip_tolerance[mmd->axis] = mmd->tolerance;
1456                         }
1457                 }
1458         }
1459         RNA_int_set(op->ptr, "flag", flag);
1460         RNA_float_set_array(op->ptr, "clip_tolerance", clip_tolerance);
1461
1462         /* Initial mouse location */
1463         mouse[0] = event->x;
1464         mouse[1] = event->y;
1465         RNA_int_set_array(op->ptr, "initial_mouse", mouse);
1466
1467         /* Initial screen depth under the mouse */
1468         view3d_set_viewcontext(C, &vc);
1469         RNA_float_set(op->ptr, "depth", read_cached_depth(&vc, event->x, event->y));
1470
1471         sculpt_update_cache_invariants(sd, C, op);
1472 }
1473
1474 static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
1475 {
1476         Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
1477
1478         view3d_operator_needs_opengl(C);
1479         sculpt_brush_stroke_init_properties(C, op, event, sd->session);
1480
1481         sculptmode_update_all_projverts(sd->session);
1482
1483         /* TODO: Shouldn't really have to do this at the start of every
1484            stroke, but sculpt would need some sort of notification when
1485            changes are made to the texture. */
1486         sculpt_update_tex(sd);
1487
1488         /* add modal handler */
1489         WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
1490         
1491         return OPERATOR_RUNNING_MODAL;
1492 }
1493
1494 static void sculpt_restore_mesh(Sculpt *sd)
1495 {
1496         SculptSession *ss = sd->session;
1497         StrokeCache *cache = ss->cache;
1498         int i;
1499         
1500         /* Restore the mesh before continuing with anchored stroke */
1501         if((sd->brush->flag & BRUSH_ANCHORED) && cache->mesh_store) {
1502                 for(i = 0; i < ss->totvert; ++i) {
1503                         VecCopyf(ss->mvert[i].co, cache->mesh_store[i]);
1504                         ss->mvert[i].no[0] = cache->orig_norms[i][0];
1505                         ss->mvert[i].no[1] = cache->orig_norms[i][1];
1506                         ss->mvert[i].no[2] = cache->orig_norms[i][2];
1507                 }
1508
1509                 if(ss->face_normals) {
1510                         float *fn = ss->face_normals;
1511                         for(i = 0; i < ss->totface; ++i, fn += 3)
1512                                 VecCopyf(fn, cache->face_norms[i]);
1513                 }
1514
1515                 if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
1516                         memset(cache->layer_disps, 0, sizeof(float) * ss->totvert);
1517         }
1518 }
1519
1520 static void sculpt_post_stroke_free(SculptSession *ss)
1521 {
1522         BLI_freelistN(&ss->damaged_rects);
1523         BLI_freelistN(&ss->damaged_verts);
1524 }
1525
1526 static void sculpt_flush_update(bContext *C)
1527 {
1528         Sculpt *s = CTX_data_tool_settings(C)->sculpt;
1529         ARegion *ar = CTX_wm_region(C);
1530         MultiresModifierData *mmd = s->session->multires;
1531
1532         calc_damaged_verts(s->session);
1533
1534         if(mmd) {
1535                 if(mmd->undo_verts && mmd->undo_verts != s->session->mvert)
1536                         MEM_freeN(mmd->undo_verts);
1537                 
1538                 mmd->undo_verts = s->session->mvert;
1539                 mmd->undo_verts_tot = s->session->totvert;
1540                 multires_mark_as_modified(CTX_data_active_object(C));
1541         }
1542
1543         ED_region_tag_redraw(ar);
1544 }
1545
1546 static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
1547 {
1548         PointerRNA itemptr;
1549         Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
1550         float center[3];
1551         int mouse[2] = {event->x, event->y};
1552
1553         sculpt_update_mesh_elements(C);
1554
1555         unproject(sd->session->cache->mats, center, event->x, event->y,
1556                   read_cached_depth(&sd->session->cache->vc, event->x, event->y));
1557
1558         /* Add to stroke */
1559         RNA_collection_add(op->ptr, "stroke", &itemptr);
1560         RNA_float_set_array(&itemptr, "location", center);
1561         RNA_int_set_array(&itemptr, "mouse", mouse);
1562         RNA_boolean_set(&itemptr, "flip", event->shift);
1563         sculpt_update_cache_variants(sd, &itemptr);
1564
1565         sculpt_restore_mesh(sd);
1566         do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
1567
1568         sculpt_flush_update(C);
1569         sculpt_post_stroke_free(sd->session);
1570
1571         /* Finished */
1572         if(event->type == LEFTMOUSE && event->val == 0) {
1573                 request_depth_update(sd->session->cache->vc.rv3d);
1574
1575                 sculpt_cache_free(sd->session->cache);
1576
1577                 sculpt_undo_push(C, sd);
1578
1579                 return OPERATOR_FINISHED;
1580         }
1581
1582         return OPERATOR_RUNNING_MODAL;
1583 }
1584
1585 static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
1586 {
1587         Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
1588
1589         view3d_operator_needs_opengl(C);
1590         sculpt_update_cache_invariants(sd, C, op);
1591         sculptmode_update_all_projverts(sd->session);
1592         sculpt_update_tex(sd);
1593
1594         RNA_BEGIN(op->ptr, itemptr, "stroke") {
1595                 sculpt_update_cache_variants(sd, &itemptr);
1596
1597                 sculpt_restore_mesh(sd);
1598                 do_symmetrical_brush_actions(sd, sd->session->cache);
1599
1600                 sculpt_post_stroke_free(sd->session);
1601         }
1602         RNA_END;
1603
1604         sculpt_flush_update(C);
1605         sculpt_cache_free(sd->session->cache);
1606
1607         sculpt_undo_push(C, sd);
1608
1609         return OPERATOR_FINISHED;
1610 }
1611
1612 static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
1613 {
1614         ot->flag |= OPTYPE_REGISTER;
1615
1616         /* identifiers */
1617         ot->name= "Sculpt Mode";
1618         ot->idname= "SCULPT_OT_brush_stroke";
1619         
1620         /* api callbacks */
1621         ot->invoke= sculpt_brush_stroke_invoke;
1622         ot->modal= sculpt_brush_stroke_modal;
1623         ot->exec= sculpt_brush_stroke_exec;
1624         ot->poll= sculpt_poll;
1625         
1626         /* flags (sculpt does own undo? (ton) */
1627         ot->flag= OPTYPE_REGISTER;
1628
1629         /* properties */
1630         RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
1631
1632         /* If the object has a scaling factor, brushes also need to be scaled
1633            to work as expected. */
1634         RNA_def_float_vector(ot->srna, "scale", 3, NULL, 0.0f, FLT_MAX, "Scale", "", 0.0f, 1000.0f);
1635
1636         RNA_def_int(ot->srna, "flag", 0, 0, INT_MAX, "flag", "", 0, INT_MAX);
1637
1638         /* For mirror modifiers */
1639         RNA_def_float_vector(ot->srna, "clip_tolerance", 3, NULL, 0.0f, FLT_MAX, "clip_tolerance", "", 0.0f, 1000.0f);
1640
1641         /* The initial 2D location of the mouse */
1642         RNA_def_int_vector(ot->srna, "initial_mouse", 2, NULL, INT_MIN, INT_MAX, "initial_mouse", "", INT_MIN, INT_MAX);
1643
1644         /* The initial screen depth of the mouse */
1645         RNA_def_float(ot->srna, "depth", 0.0f, 0.0f, FLT_MAX, "depth", "", 0.0f, FLT_MAX);
1646 }
1647
1648 /**** Toggle operator for turning sculpt mode on or off ****/
1649
1650 static int sculpt_toggle_mode(bContext *C, wmOperator *op)
1651 {
1652         ToolSettings *ts = CTX_data_tool_settings(C);
1653
1654         if(G.f & G_SCULPTMODE) {
1655                 multires_force_update(CTX_data_active_object(C));
1656
1657                 /* Leave sculptmode */
1658                 G.f &= ~G_SCULPTMODE;
1659
1660                 toggle_paint_cursor(C);
1661
1662                 sculptsession_free(ts->sculpt);
1663         }
1664         else {
1665                 MTex *mtex; // XXX: temporary
1666
1667                 /* Enter sculptmode */
1668
1669                 G.f |= G_SCULPTMODE;
1670                 
1671                 /* Create persistent sculpt mode data */
1672                 if(!ts->sculpt)
1673                         ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data");
1674
1675                 /* Create sculpt mode session data */
1676                 if(ts->sculpt->session)
1677                         MEM_freeN(ts->sculpt->session);
1678                 ts->sculpt->session = MEM_callocN(sizeof(SculptSession), "sculpt session");
1679
1680                 toggle_paint_cursor(C);
1681
1682                 /* If there's no brush, create one */
1683                 brush_check_exists(&ts->sculpt->brush);
1684
1685                 /* XXX: testing: set the brush texture to the first available one */
1686                 if(G.main->tex.first) {
1687                         Tex *tex = G.main->tex.first;
1688                         if(tex->type) {
1689                                 mtex = MEM_callocN(sizeof(MTex), "test mtex");
1690                                 ts->sculpt->brush->texact = 0;
1691                                 ts->sculpt->brush->mtex[0] = mtex;
1692                                 mtex->tex = tex;
1693                                 mtex->size[0] = mtex->size[1] = mtex->size[2] = 50;
1694                         }
1695                 }
1696         }
1697
1698         return OPERATOR_FINISHED;
1699 }
1700
1701 static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
1702 {
1703         /* identifiers */
1704         ot->name= "Sculpt Mode";
1705         ot->idname= "SCULPT_OT_sculptmode_toggle";
1706         
1707         /* api callbacks */
1708         ot->exec= sculpt_toggle_mode;
1709         ot->poll= ED_operator_object_active;
1710         
1711         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1712 }
1713
1714 void ED_operatortypes_sculpt()
1715 {
1716         WM_operatortype_append(SCULPT_OT_radial_control);
1717         WM_operatortype_append(SCULPT_OT_brush_stroke);
1718         WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
1719         WM_operatortype_append(SCULPT_OT_brush_curve_preset);
1720 }
1721
1722 void sculpt(Sculpt *sd)
1723 {
1724 #if 0
1725         SculptSession *ss= sd->session;
1726         Object *ob= NULL; /*XXX */
1727         Mesh *me;
1728         MultiresModifierData *mmd = NULL;
1729         /* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
1730         short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
1731         short modifier_calculations= 0;
1732         BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
1733         short spacing= 32000;
1734         int scissor_box[4];
1735         float offsetRot;
1736         int smooth_stroke = 0, i;
1737         int anchored, rake = 0 /* XXX: rake = ? */;
1738
1739         /* XXX: checking that sculpting is allowed
1740         if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
1741                 return;
1742         if(!(ob->lay & G.vd->lay))
1743                 error("Active object is not in this layer");
1744         if(ob_get_keyblock(ob)) {
1745                 if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
1746                         error("Cannot sculpt on unlocked shape key");
1747                         return;
1748                 }
1749         }*/
1750         
1751         anchored = sd->brush->flag & BRUSH_ANCHORED;
1752         smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && !anchored;
1753
1754         if(smooth_stroke)
1755                 sculpt_stroke_new(256);
1756
1757         ss->damaged_rects.first = ss->damaged_rects.last = NULL;
1758         ss->damaged_verts.first = ss->damaged_verts.last = NULL;
1759         ss->vertexcosnos = NULL;
1760
1761         mmd = sculpt_multires_active(ob);
1762
1763         /* Check that vertex users are up-to-date */
1764         if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != cache->totvert) {
1765                 sculpt_vertexusers_free(ss);
1766                 calc_vertex_users(ss);
1767                 if(ss->projverts)
1768                         MEM_freeN(ss->projverts);
1769                 ss->projverts = NULL;
1770                 active_ob= ob;
1771         }
1772                 
1773         glEnableClientState(GL_VERTEX_ARRAY);
1774         glEnableClientState(GL_NORMAL_ARRAY);
1775
1776         /*XXX:
1777         persp(PERSP_VIEW);
1778         getmouseco_areawin(mvalo);*/
1779
1780         /* Init texture
1781            FIXME: Shouldn't be doing this every time! */
1782         if(sd->tex_mode!=SCULPTREPT_3D)
1783                 sculptmode_update_tex(sd);
1784
1785         /*XXX: getmouseco_areawin(mouse); */
1786         mvalo[0]= mouse[0];
1787         mvalo[1]= mouse[1];
1788         lastSigMouse[0]=mouse[0];
1789         lastSigMouse[1]=mouse[1];
1790         mousebut = 0; /* XXX: L_MOUSE; */
1791
1792         /* If modifier_calculations is true, then extra time must be spent
1793            updating the mesh. This takes a *lot* longer, so it's worth
1794            skipping if the modifier stack is empty. */
1795         modifier_calculations= sculpt_modifiers_active(ob);
1796
1797         if(modifier_calculations)
1798                 ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /* XXX: scene = ? */
1799         sculptmode_update_all_projverts(ss);
1800
1801         /* Capture original copy */
1802         if(sd->flags & SCULPT_DRAW_FAST)
1803                 glAccum(GL_LOAD, 1);
1804
1805         /* Get original scissor box */
1806         glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
1807         
1808         /* For raking, get the original angle*/
1809         offsetRot=sculpt_tex_angle(sd);
1810
1811         me = get_mesh(ob);
1812
1813         while (/*XXX:get_mbut() & mousebut*/0) {
1814                 /* XXX: getmouseco_areawin(mouse); */
1815                 /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
1816                 if (rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
1817                         /*Nasty looking, but just orig + new angle really*/
1818                         set_tex_angle(sd, offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
1819                         lastSigMouse[0]=mouse[0];
1820                         lastSigMouse[1]=mouse[1];
1821                 }
1822                 
1823                 if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] ||
1824                    sd->brush->flag & BRUSH_AIRBRUSH) {
1825                         a->firsttime = firsttime;
1826                         firsttime= 0;
1827
1828                         if(smooth_stroke)
1829                                 sculpt_stroke_add_point(ss->stroke, mouse[0], mouse[1]);
1830
1831                         spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
1832
1833                         if(modifier_calculations && !ss->vertexcosnos)
1834                                 ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /*XXX scene = ? */
1835
1836                         if(sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
1837                                 if(anchored) {
1838                                         /* Restore the mesh before continuing with anchored stroke */
1839                                         /*if(a->mesh_store) {
1840                                                 for(i = 0; i < cache->totvert; ++i) {
1841                                                         VecCopyf(cache->mvert[i].co, &a->mesh_store[i].x);
1842                                                         cache->mvert[i].no[0] = a->orig_norms[i][0];
1843                                                         cache->mvert[i].no[1] = a->orig_norms[i][1];
1844                                                         cache->mvert[i].no[2] = a->orig_norms[i][2];
1845                                                 }
1846                                                 }*/
1847                                         
1848                                         //do_symmetrical_brush_actions(sd, a, mouse, NULL);
1849                                 }
1850                                 else {
1851                                         if(smooth_stroke) {
1852                                                 sculpt_stroke_apply(sd, ss->stroke);
1853                                         }
1854                                         else if(sd->spacing==0 || spacing>sd->spacing) {
1855                                                 //do_symmetrical_brush_actions(sd, a, mouse, NULL);
1856                                                 spacing= 0;
1857                                         }
1858                                 }
1859                         }
1860                         else {
1861                                 //do_symmetrical_brush_actions(sd, a, mouse, mvalo);
1862                                 //unproject(ss, sd->pivot, mouse[0], mouse[1], a->depth);
1863                         }
1864
1865                         if((!ss->multires && modifier_calculations) || ob_get_keyblock(ob)) {
1866                                 /* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); */ }
1867
1868                         if(modifier_calculations || sd->brush->sculpt_tool == SCULPT_TOOL_GRAB || !(sd->flags & SCULPT_DRAW_FAST)) {
1869                                 calc_damaged_verts(ss, a);
1870                                 /*XXX: scrarea_do_windraw(curarea);
1871                                 screen_swapbuffers(); */
1872                         } else { /* Optimized drawing */
1873                                 calc_damaged_verts(ss, a);
1874
1875                                 /* Draw the stored image to the screen */
1876                                 glAccum(GL_RETURN, 1);
1877
1878                                 sculpt_clear_damaged_areas(ss);
1879                                 
1880                                 /* Draw all the polygons that are inside the modified area(s) */
1881                                 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
1882                                 /* XXX: sculptmode_draw_mesh(1); */
1883                                 glAccum(GL_LOAD, 1);
1884
1885                                 projverts_clear_inside(ss);
1886
1887                                 /* XXX: persp(PERSP_WIN); */
1888                                 glDisable(GL_DEPTH_TEST);
1889                                 
1890                                 /* Draw cursor */
1891                                 if(sd->flags & SCULPT_TOOL_DRAW)
1892                                         fdrawXORcirc((float)mouse[0],(float)mouse[1],sd->brush->size);
1893                                 /* XXX: if(smooth_stroke)
1894                                    sculpt_stroke_draw();
1895                                 
1896                                 myswapbuffers(); */
1897                         }
1898
1899                         BLI_freelistN(&ss->damaged_rects);
1900                         ss->damaged_rects.first = ss->damaged_rects.last = NULL;
1901         
1902                         mvalo[0]= mouse[0];
1903                         mvalo[1]= mouse[1];
1904
1905                         if(ss->vertexcosnos) {
1906                                 MEM_freeN(ss->vertexcosnos);
1907                                 ss->vertexcosnos= NULL;
1908                         }
1909
1910                 }
1911                 else { /*XXX:BIF_wait_for_statechange();*/ }
1912         }
1913
1914         /* Set the rotation of the brush back to what it was before any rake */
1915         set_tex_angle(sd, offsetRot);
1916         
1917         if(smooth_stroke) {
1918                 sculpt_stroke_apply_all(sd, ss->stroke);
1919                 calc_damaged_verts(ss, a);
1920                 BLI_freelistN(&ss->damaged_rects);
1921         }
1922
1923         //if(a->layer_disps) MEM_freeN(a->layer_disps);
1924         //if(a->mesh_store) MEM_freeN(a->mesh_store);
1925         //if(a->orig_norms) MEM_freeN(a->orig_norms);
1926         for(i=0; i<8; ++i)
1927                 BLI_freelistN(&a->grab_active_verts[i]);
1928         MEM_freeN(a);
1929         sculpt_stroke_free(ss->stroke);
1930         ss->stroke = NULL;
1931
1932         if(mmd) {
1933                 if(mmd->undo_verts && mmd->undo_verts != cache->mvert)
1934                         MEM_freeN(mmd->undo_verts);
1935                 
1936                 mmd->undo_verts = cache->mvert;
1937                 mmd->undo_verts_tot = cache->totvert;
1938         }
1939
1940         //sculpt_undo_push(sd);
1941
1942         /* XXX: if(G.vd->depths) G.vd->depths->damaged= 1;
1943            allqueue(REDRAWVIEW3D, 0); */
1944 #endif
1945 }
1946
1947 /* Partial Mesh Visibility */
1948
1949 /* XXX: Partial vis. always was a mess, have to figure something out */
1950 #if 0
1951 /* mode: 0=hide outside selection, 1=hide inside selection */
1952 static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
1953 {
1954         Mesh *me= get_mesh(ob);
1955         float hidebox[6][3];
1956         vec3f plane_normals[4];
1957         float plane_ds[4];
1958         unsigned i, j;
1959         unsigned ndx_show, ndx_hide;
1960         MVert *nve;
1961         unsigned face_cnt_show= 0, face_ndx_show= 0;
1962         unsigned edge_cnt_show= 0, edge_ndx_show= 0;
1963         unsigned *old_map= NULL;
1964         const unsigned SHOW= 0, HIDE=1;
1965
1966         /* Convert hide box from 2D to 3D */
1967         unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
1968         unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
1969         unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
1970         unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
1971         unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
1972         unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
1973         
1974         /* Calculate normals for each side of hide box */
1975         CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
1976         CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
1977         CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
1978         CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
1979         
1980         /* Calculate D for each side of hide box */
1981         for(i= 0; i<4; ++i)
1982                 plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
1983                         hidebox[i][2]*plane_normals[i].z;
1984         
1985         /* Add partial visibility to mesh */
1986         if(!me->pv) {
1987                 me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
1988         } else {
1989                 old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
1990                 for(i=0; i<me->pv->totvert; ++i) {
1991                         old_map[i]= me->pv->vert_map[i]<me->totvert?0:1;
1992                 }
1993                 mesh_pmv_revert(ob, me);
1994         }
1995         
1996         /* Kill sculpt data */
1997         active_ob= NULL;
1998         
1999         /* Initalize map with which verts are to be hidden */
2000         me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
2001         me->pv->totvert= me->totvert;
2002         me->totvert= 0;
2003         for(i=0; i<me->pv->totvert; ++i) {
2004                 me->pv->vert_map[i]= mode ? HIDE:SHOW;
2005                 for(j=0; j<4; ++j) {
2006                         if(me->mvert[i].co[0] * plane_normals[j].x +
2007                            me->mvert[i].co[1] * plane_normals[j].y +
2008                            me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
2009                                 me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
2010                                 break;
2011                         }
2012                 }
2013                 if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
2014                 if(!me->pv->vert_map[i]) ++me->totvert;
2015
2016         }
2017         if(old_map) MEM_freeN(old_map);
2018
2019         /* Find out how many faces to show */
2020         for(i=0; i<me->totface; ++i) {
2021                 if(!me->pv->vert_map[me->mface[i].v1] &&
2022                    !me->pv->vert_map[me->mface[i].v2] &&
2023                    !me->pv->vert_map[me->mface[i].v3]) {
2024                         if(me->mface[i].v4) {
2025                                 if(!me->pv->vert_map[me->mface[i].v4])
2026                                         ++face_cnt_show;
2027                         }
2028                         else ++face_cnt_show;
2029                 }
2030         }
2031         /* Find out how many edges to show */
2032         for(i=0; i<me->totedge; ++i) {
2033                 if(!me->pv->vert_map[me->medge[i].v1] &&
2034                    !me->pv->vert_map[me->medge[i].v2])
2035                         ++edge_cnt_show;
2036         }
2037
2038         /* Create new vert array and reset each vert's map with map[old]=new index */
2039         nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
2040         ndx_show= 0; ndx_hide= me->totvert;
2041         for(i=0; i<me->pv->totvert; ++i) {
2042                 if(me->pv->vert_map[i]) {
2043                         me->pv->vert_map[i]= ndx_hide;
2044                         nve[me->pv->vert_map[i]]= me->mvert[i];
2045                         ++ndx_hide;
2046                 } else {
2047                         me->pv->vert_map[i]= ndx_show;
2048                         nve[me->pv->vert_map[i]]= me->mvert[i];
2049                         ++ndx_show;
2050                 }
2051         }
2052         CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
2053         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
2054
2055         /* Create new face array */
2056         me->pv->old_faces= me->mface;
2057         me->pv->totface= me->totface;
2058         me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
2059         for(i=0; i<me->totface; ++i) {
2060                 MFace *pr_f= &me->pv->old_faces[i];
2061                 char show= 0;
2062
2063                 if(me->pv->vert_map[pr_f->v1] < me->totvert &&
2064                    me->pv->vert_map[pr_f->v2] < me->totvert &&
2065                    me->pv->vert_map[pr_f->v3] < me->totvert) {
2066                         if(pr_f->v4) {
2067                                 if(me->pv->vert_map[pr_f->v4] < me->totvert)
2068                                         show= 1;
2069                         }
2070                         else show= 1;
2071                 }
2072
2073                 if(show) {
2074                         MFace *cr_f= &me->mface[face_ndx_show];
2075                         *cr_f= *pr_f;
2076                         cr_f->v1= me->pv->vert_map[pr_f->v1];
2077                         cr_f->v2= me->pv->vert_map[pr_f->v2];
2078                         cr_f->v3= me->pv->vert_map[pr_f->v3];
2079                         cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
2080                         test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
2081                         ++face_ndx_show;
2082                 }
2083         }
2084         me->totface= face_cnt_show;
2085         CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
2086
2087         /* Create new edge array */
2088         me->pv->old_edges= me->medge;
2089         me->pv->totedge= me->totedge;
2090         me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
2091         me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
2092         for(i=0; i<me->totedge; ++i) {
2093                 if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
2094                    me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
2095                         MEdge *cr_e= &me->medge[edge_ndx_show];
2096                         me->pv->edge_map[i]= edge_ndx_show;
2097                         *cr_e= me->pv->old_edges[i];
2098                         cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
2099                         cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
2100                         ++edge_ndx_show;
2101                 }
2102                 else me->pv->edge_map[i]= -1;
2103         }
2104         me->totedge= edge_cnt_show;
2105         CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
2106
2107         /* XXX: DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); */
2108 }
2109
2110 static rcti sculptmode_pmv_box()
2111 {
2112         /*XXX:  short down[2], mouse[2];
2113         rcti ret;
2114
2115         getmouseco_areawin(down);
2116
2117         while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
2118                 getmouseco_areawin(mouse);
2119
2120                 scrarea_do_windraw(curarea);
2121
2122                 persp(PERSP_WIN);
2123                 glLineWidth(2);
2124                 setlinestyle(2);
2125                 sdrawXORline(down[0],down[1],mouse[0],down[1]);
2126                 sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
2127                 sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
2128                 sdrawXORline(down[0],mouse[1],down[0],down[1]);
2129                 setlinestyle(0);
2130                 glLineWidth(1);
2131                 persp(PERSP_VIEW);
2132
2133                 screen_swapbuffers();
2134                 backdrawview3d(0);
2135         }
2136
2137         ret.xmin= down[0]<mouse[0]?down[0]:mouse[0];
2138         ret.ymin= down[1]<mouse[1]?down[1]:mouse[1];
2139         ret.xmax= down[0]>mouse[0]?down[0]:mouse[0];
2140         ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
2141         return ret;*/
2142 }
2143
2144 void sculptmode_pmv(int mode)
2145 {
2146         Object *ob= NULL; /*XXX: OBACT; */
2147         rcti hb_2d;
2148         
2149         if(ob_get_key(ob)) {
2150                 error("Cannot hide mesh with shape keys enabled");
2151                 return;
2152         }
2153         
2154         hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
2155         
2156         sculptmode_correct_state();
2157
2158         waitcursor(1);
2159
2160         if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
2161                 init_sculptmatrices();
2162
2163                 sculptmode_do_pmv(ob,&hb_2d,mode);
2164         }
2165         else mesh_pmv_off(ob, get_mesh(ob));
2166
2167         /*XXX: scrarea_do_windraw(curarea); */
2168
2169         waitcursor(0);
2170 }
2171 #endif