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