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