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