== Sculpt ==
[blender.git] / source / blender / src / sculptmode.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software  Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2006 by Nicholas Bishop
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  * Implements the Sculpt Mode tools
30  *
31  * BDR_sculptmode.h
32  *
33  */
34
35 #include "GHOST_Types.h"
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_arithb.h"
40 #include "BLI_blenlib.h"
41 #include "BLI_dynstr.h"
42
43 #include "DNA_armature_types.h"
44 #include "DNA_brush_types.h"
45 #include "DNA_image_types.h"
46 #include "DNA_key_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_modifier_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_texture_types.h"
54 #include "DNA_view3d_types.h"
55 #include "DNA_userdef_types.h"
56 #include "DNA_color_types.h"
57
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_sculpt.h"
69 #include "BKE_texture.h"
70 #include "BKE_utildefines.h"
71 #include "BKE_colortools.h"
72
73 #include "BIF_editkey.h"
74 #include "BIF_editview.h"
75 #include "BIF_glutil.h"
76 #include "BIF_gl.h"
77 #include "BIF_interface.h"
78 #include "BIF_mywindow.h"
79 #include "BIF_radialcontrol.h"
80 #include "BIF_resources.h"
81 #include "BIF_screen.h"
82 #include "BIF_space.h"
83 #include "BIF_toolbox.h"
84
85 #include "BDR_drawobject.h"
86 #include "BDR_sculptmode.h"
87
88 #include "BSE_drawview.h"
89 #include "BSE_edit.h"
90 #include "BSE_view.h"
91
92 #include "IMB_imbuf_types.h"
93
94 #include "blendef.h"
95 #include "multires.h"
96 #include "mydevice.h"
97
98 #include "RE_render_ext.h"
99 #include "RE_shader_ext.h" /*for multitex_ext*/
100
101 #include <math.h>
102 #include <stdlib.h>
103 #include <string.h>
104
105 /* Number of vertices to average in order to determine the flatten distance */
106 #define FLATTEN_SAMPLE_SIZE 10
107
108 /* ===== STRUCTS =====
109  *
110  */
111
112 /* Used by vertex_users to store face indices in a list */
113 typedef struct IndexNode {
114         struct IndexNode* next,* prev;
115         int Index;
116 } IndexNode;
117
118
119 /* ActiveData stores an Index into the mvert array of Mesh, plus Fade, which
120    stores how far the vertex is from the brush center, scaled to the range [0,1]. */
121 typedef struct ActiveData {
122         struct ActiveData *next, *prev;
123         unsigned int Index;
124         float Fade;
125         float dist;
126 } ActiveData;
127
128 typedef struct BrushActionSymm {
129         float center_3d[3];
130         char index;
131
132         float up[3], right[3], out[3];
133
134         // Grab brush
135         float grab_delta[3];
136 } BrushActionSymm;
137
138 typedef struct BrushAction {
139         BrushActionSymm symm;
140
141         char firsttime;
142
143         short mouse[2];
144         float size_3d;
145
146         float *layer_disps;
147         vec3f *layer_store;
148         char flip;
149
150         char clip[3];
151         float cliptol[3];
152
153         // Grab brush
154         ListBase grab_active_verts[8];
155         float depth;
156
157         /* Adjust brush strength along each axis
158            to adjust for object scaling */
159         float scale[3];
160 } BrushAction;
161
162 typedef struct RectNode {
163         struct RectNode *next, *prev;
164         rcti r;
165 } RectNode;
166
167 /* Used to store to 2D screen coordinates of each vertex in the mesh. */
168 typedef struct ProjVert {
169         short co[2];
170         
171         /* Used to mark whether a vertex is inside a rough bounding box
172            containing the brush. */
173         char inside;
174 } ProjVert;
175
176 static Object *active_ob= NULL;
177
178 SculptData *sculpt_data(void)
179 {
180         return &G.scene->sculptdata;
181 }
182
183 void sculpt_init_session(void);
184 void init_brushaction(BrushAction *a, short *, short *);
185 void sculpt_undo_push(const short);
186
187 SculptSession *sculpt_session(void)
188 {
189         if(!sculpt_data()->session)
190                 sculpt_init_session();
191         return sculpt_data()->session;
192 }
193
194 /* ===== MEMORY =====
195  * 
196  * Allocate/initialize/free data
197  */
198
199 void sculpt_init_session(void)
200 {
201         if(sculpt_data()->session)
202                 sculptsession_free(G.scene);
203         sculpt_data()->session= MEM_callocN(sizeof(SculptSession), "SculptSession");
204 }
205
206 /* vertex_users is an array of Lists that store all the faces that use a
207    particular vertex. vertex_users is in the same order as mesh.mvert */
208 void calc_vertex_users()
209 {
210         SculptSession *ss= sculpt_session();
211         int i,j;
212         IndexNode *node= NULL;
213         Mesh *me= get_mesh(OBACT);
214
215         sculpt_vertexusers_free(ss);
216         
217         /* For efficiency, use vertex_users_mem as a memory pool (may be larger
218            than necessary if mesh has triangles, but only one alloc is needed.) */
219         ss->vertex_users= MEM_callocN(sizeof(ListBase) * me->totvert, "vertex_users");
220         ss->vertex_users_size= me->totvert;
221         ss->vertex_users_mem= MEM_callocN(sizeof(IndexNode)*me->totface*4, "vertex_users_mem");
222         node= ss->vertex_users_mem;
223
224         /* Find the users */
225         for(i=0; i<me->totface; ++i){
226                 for(j=0; j<(me->mface[i].v4?4:3); ++j, ++node) {
227                         node->Index=i;
228                         BLI_addtail(&ss->vertex_users[((unsigned int*)(&me->mface[i]))[j]], node);
229                 }
230         }
231 }
232
233 /* ===== INTERFACE =====
234  */
235
236 void sculptmode_rem_tex(void *junk0,void *junk1)
237 {
238         MTex *mtex= G.scene->sculptdata.mtex[G.scene->sculptdata.texact];
239         if(mtex) {
240                 SculptSession *ss= sculpt_session();
241                 if(mtex->tex) mtex->tex->id.us--;
242                 MEM_freeN(mtex);
243                 G.scene->sculptdata.mtex[G.scene->sculptdata.texact]= NULL;
244                 /* Clear brush preview */
245                 if(ss->texcache) {
246                         MEM_freeN(ss->texcache);
247                         ss->texcache= NULL;
248                 }
249                 BIF_undo_push("Unlink brush texture");
250                 allqueue(REDRAWBUTSEDIT, 0);
251                 allqueue(REDRAWOOPS, 0);
252         }
253 }
254
255 /* ===== OPENGL =====
256  *
257  * Simple functions to get data from the GL
258  */
259
260 /* Store the modelview and projection matrices and viewport. */
261 void init_sculptmatrices()
262 {
263         SculptSession *ss= sculpt_session();
264
265         glMatrixMode(GL_MODELVIEW);
266         glPushMatrix();
267         glMultMatrixf(OBACT->obmat);
268
269         if(!ss->mats)
270                 ss->mats = MEM_callocN(sizeof(bglMats), "sculpt bglmats");
271         bgl_get_mats(ss->mats);
272         
273         glPopMatrix();
274
275 }
276
277 /* Uses window coordinates (x,y) to find the depth in the GL depth buffer. If
278    available, G.vd->depths is used so that the brush doesn't sculpt on top of
279    itself (G.vd->depths is only updated at the end of a brush stroke.) */
280 float get_depth(short x, short y)
281 {
282         float depth;
283
284         if(x<0 || y<0) return 1;
285         if(x>=curarea->winx || y>=curarea->winy) return 1;
286
287         if(G.vd->depths && x<G.vd->depths->w && y<G.vd->depths->h)
288                 return G.vd->depths->depths[y*G.vd->depths->w+x];
289         
290         x+= curarea->winrct.xmin;
291         y+= curarea->winrct.ymin;
292         
293         glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
294
295         return depth;
296 }
297
298 /* Uses window coordinates (x,y) and depth component z to find a point in
299    modelspace */
300 void unproject(float out[3], const short x, const short y, const float z)
301 {
302         SculptSession *ss= sculpt_session();
303         double ux, uy, uz;
304
305         gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection,
306                      (GLint *)ss->mats->viewport, &ux, &uy, &uz );
307         out[0] = ux;
308         out[1] = uy;
309         out[2] = uz;
310 }
311
312 /* Convert a point in model coordinates to 2D screen coordinates. */
313 void project(const float v[3], short p[2])
314 {
315         SculptSession *ss= sculpt_session();
316         double ux, uy, uz;
317
318         gluProject(v[0],v[1],v[2], ss->mats->modelview, ss->mats->projection,
319                    (GLint *)ss->mats->viewport, &ux, &uy, &uz);
320         p[0]= ux;
321         p[1]= uy;
322 }
323
324 /* ===== Sculpting =====
325  *
326  */
327
328 /* Return modified brush size. Uses current tablet pressure (if available) to
329    shrink the brush. Skipped for grab brush because only the first mouse down
330    size is used, which is small if the user has just touched the pen to the
331    tablet */
332 char brush_size()
333 {
334         const BrushData *b= sculptmode_brush();
335         float size= b->size;
336         float pressure= get_pressure();
337         short activedevice= get_activedevice();
338         
339         if(sculpt_data()->brush_type!=GRAB_BRUSH) {
340                 const float size_factor= G.scene->sculptdata.tablet_size / 10.0f;
341                 if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER))
342                         size*= G.scene->sculptdata.tablet_size==0?1:
343                                (1-size_factor) + pressure*size_factor;
344         }
345         
346         return size;
347 }
348
349 /* Return modified brush strength. Includes the direction of the brush, positive
350    values pull vertices, negative values push. Uses tablet pressure and a
351    special multiplier found experimentally to scale the strength factor. */
352 float brush_strength(BrushAction *a)
353 {
354         const BrushData* b= sculptmode_brush();
355         float dir= b->dir==1 ? 1 : -1;
356         float pressure= 1;
357         short activedevice= get_activedevice();
358         float flip= a->flip ? -1:1;
359
360         const float strength_factor= G.scene->sculptdata.tablet_strength / 10.0f;
361         if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER))
362                 pressure= G.scene->sculptdata.tablet_strength==0?1:
363                                   (1-strength_factor) + get_pressure()*strength_factor;
364         
365         /* Flip direction for eraser */
366         if(activedevice==DEV_ERASER)
367                 dir= -dir;
368
369         switch(G.scene->sculptdata.brush_type){
370         case DRAW_BRUSH:
371         case LAYER_BRUSH:
372                 return b->strength / 5000.0f * dir * pressure * flip;
373         case SMOOTH_BRUSH:
374                 return b->strength / 50.0f * pressure;
375         case PINCH_BRUSH:
376                 return b->strength / 1000.0f * dir * pressure * flip;
377         case GRAB_BRUSH:
378                 return 1;
379         case INFLATE_BRUSH:
380                 return b->strength / 5000.0f * dir * pressure * flip;
381         case FLATTEN_BRUSH:
382                 return b->strength / 500.0f * pressure;
383         default:
384                 return 0;
385         }
386 }
387
388 /* For clipping against a mirror modifier */
389 void sculpt_clip(const BrushAction *a, float *co, const float val[3])
390 {
391         char i;
392         for(i=0; i<3; ++i) {
393                 if(a->clip[i] && (fabs(co[i]) <= a->cliptol[i]))
394                         co[i]= 0.0f;
395                 else
396                         co[i]= val[i];
397         }               
398 }
399
400 /* Currently only for the draw brush; finds average normal for all active
401    vertices */
402 vec3f calc_area_normal(const float *outdir, const ListBase* active_verts)
403 {
404         Mesh *me= get_mesh(OBACT);
405         vec3f area_normal= {0,0,0};
406         ActiveData *node= active_verts->first;
407         const int view= sculpt_data()->brush_type==DRAW_BRUSH ? sculptmode_brush()->view : 0;
408
409         while(node){
410                 area_normal.x+= me->mvert[node->Index].no[0];
411                 area_normal.y+= me->mvert[node->Index].no[1];
412                 area_normal.z+= me->mvert[node->Index].no[2];
413                 node= node->next;
414         }
415         Normalize(&area_normal.x);
416
417         if(outdir) {
418                 area_normal.x= outdir[0] * view + area_normal.x * (10-view);
419                 area_normal.y= outdir[1] * view + area_normal.y * (10-view);
420                 area_normal.z= outdir[2] * view + area_normal.z * (10-view);
421         }
422
423         Normalize(&area_normal.x);
424         return area_normal;
425 }
426 void do_draw_brush(const BrushAction *a, const ListBase* active_verts)
427 {
428         Mesh *me= get_mesh(OBACT);
429         const vec3f area_normal= calc_area_normal(a->symm.out, active_verts);
430         ActiveData *node= active_verts->first;
431
432         while(node){
433                 float *co= me->mvert[node->Index].co;
434                 
435                 const float val[3]= {co[0]+area_normal.x*node->Fade*a->scale[0],
436                                      co[1]+area_normal.y*node->Fade*a->scale[1],
437                                      co[2]+area_normal.z*node->Fade*a->scale[2]};
438                                      
439                 sculpt_clip(a, 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 vec3f neighbor_average(const int vert)
449 {
450         SculptSession *ss= sculpt_session();
451         Mesh *me= get_mesh(OBACT);
452         int i, skip= -1, total=0;
453         IndexNode *node= ss->vertex_users[vert].first;
454         vec3f avg= {0,0,0};
455         char ncount= BLI_countlist(&ss->vertex_users[vert]);
456         MFace *f;
457                 
458         /* Don't modify corner vertices */
459         if(ncount==1) {
460                 VecCopyf(&avg.x, me->mvert[vert].co);
461                 return avg;
462         }
463
464         while(node){
465                 f= &me->mface[node->Index];
466                 
467                 if(f->v4) {
468                         skip= (f->v1==vert?2:
469                                f->v2==vert?3:
470                                f->v3==vert?0:
471                                f->v4==vert?1:-1);
472                 }
473
474                 for(i=0; i<(f->v4?4:3); ++i) {
475                         if(i != skip && (ncount!=2 || BLI_countlist(&ss->vertex_users[(&f->v1)[i]]) <= 2)) {
476                                 VecAddf(&avg.x,&avg.x,me->mvert[(&f->v1)[i]].co);
477                                 ++total;
478                         }
479                 }
480
481                 node= node->next;
482         }
483
484         if(total>0) {
485                 avg.x/= total;
486                 avg.y/= total;
487                 avg.z/= total;
488         }
489         else
490                 VecCopyf(&avg.x, me->mvert[vert].co);
491
492         return avg;
493 }
494
495 void do_smooth_brush(const BrushAction *a, const ListBase* active_verts)
496 {
497         ActiveData *node= active_verts->first;
498         Mesh *me= get_mesh(OBACT);
499
500         while(node){
501                 float *co= me->mvert[node->Index].co;
502                 const vec3f avg= neighbor_average(node->Index);
503                 const float val[3]= {co[0]+(avg.x-co[0])*node->Fade,
504                                      co[1]+(avg.y-co[1])*node->Fade,
505                                      co[2]+(avg.z-co[2])*node->Fade};
506                 sculpt_clip(a, co, val);
507                 node= node->next;
508         }
509 }
510
511 void do_pinch_brush(const BrushAction *a, const ListBase* active_verts)
512 {
513         Mesh *me= get_mesh(OBACT);
514         ActiveData *node= active_verts->first;
515
516         while(node) {
517                 float *co= me->mvert[node->Index].co;
518                 const float val[3]= {co[0]+(a->symm.center_3d[0]-co[0])*node->Fade,
519                                      co[1]+(a->symm.center_3d[1]-co[1])*node->Fade,
520                                      co[2]+(a->symm.center_3d[2]-co[2])*node->Fade};
521                 sculpt_clip(a, co, val);
522                 node= node->next;
523         }
524 }
525
526 void do_grab_brush(BrushAction *a)
527 {
528         Mesh *me= get_mesh(OBACT);
529         ActiveData *node= a->grab_active_verts[a->symm.index].first;
530         float add[3];
531
532         while(node) {
533                 float *co= me->mvert[node->Index].co;
534                 
535                 VecCopyf(add, a->symm.grab_delta);
536                 VecMulf(add, node->Fade);
537                 VecAddf(add, add, co);
538                 sculpt_clip(a, co, add);
539
540                 node= node->next;
541         }
542 }
543
544 void do_layer_brush(BrushAction *a, const ListBase *active_verts)
545 {
546         Mesh *me= get_mesh(OBACT);
547         vec3f area_normal= calc_area_normal(NULL, active_verts);
548         ActiveData *node= active_verts->first;
549         const float bstr= brush_strength(a);
550
551         while(node){
552                 float *disp= &a->layer_disps[node->Index];
553                 
554                 if((bstr > 0 && *disp < bstr) ||
555                   (bstr < 0 && *disp > bstr)) {
556                         float *co= me->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]= {a->layer_store[node->Index].x+area_normal.x * *disp*a->scale[0],
570                                                      a->layer_store[node->Index].y+area_normal.y * *disp*a->scale[1],
571                                                      a->layer_store[node->Index].z+area_normal.z * *disp*a->scale[2]};
572                                 sculpt_clip(a, co, val);
573                         }
574                 }
575
576                 node= node->next;
577         }
578 }
579
580 void do_inflate_brush(const BrushAction *a, const ListBase *active_verts)
581 {
582         ActiveData *node= active_verts->first;
583         float add[3];
584         Mesh *me= get_mesh(OBACT);
585         
586         while(node) {
587                 float *co= me->mvert[node->Index].co;
588                 short *no= me->mvert[node->Index].no;
589
590                 add[0]= no[0]/ 32767.0f;
591                 add[1]= no[1]/ 32767.0f;
592                 add[2]= no[2]/ 32767.0f;
593                 VecMulf(add, node->Fade);
594                 add[0]*= a->scale[0];
595                 add[1]*= a->scale[1];
596                 add[2]*= a->scale[2];
597                 VecAddf(add, add, co);
598                 
599                 sculpt_clip(a, co, add);
600
601                 node= node->next;
602         }
603 }
604
605 void calc_flatten_center(Mesh *me, ActiveData *node, float co[3])
606 {
607         ActiveData *outer[FLATTEN_SAMPLE_SIZE];
608         int i;
609         
610         for(i = 0; i < FLATTEN_SAMPLE_SIZE; ++i)
611                 outer[i] = node;
612                 
613         for(; node; node = node->next) {
614                 for(i = 0; i < FLATTEN_SAMPLE_SIZE; ++i) {
615                         if(node->dist > outer[i]->dist) {
616                                 outer[i] = node;
617                                 break;
618                         }
619                 }
620         }
621         
622         co[0] = co[1] = co[2] = 0.0f;
623         for(i = 0; i < FLATTEN_SAMPLE_SIZE; ++i)
624                 VecAddf(co, co, me->mvert[outer[i]->Index].co);
625         VecMulf(co, 1.0f / FLATTEN_SAMPLE_SIZE);
626 }
627
628 void do_flatten_brush(const BrushAction *a, const ListBase *active_verts)
629 {
630         Mesh *me= get_mesh(OBACT);
631         ActiveData *node= active_verts->first;
632         /* area_normal and cntr define the plane towards which vertices are squashed */
633         vec3f area_normal= calc_area_normal(a->symm.out, active_verts);
634         float cntr[3];
635         
636         calc_flatten_center(me, node, cntr);
637
638         while(node){
639                 float *co= me->mvert[node->Index].co;
640                 float p1[3], sub1[3], sub2[3], intr[3], val[3];
641                 
642                 /* Find the intersection between squash-plane and vertex (along the area normal) */
643                 VecSubf(p1, co, &area_normal.x);
644                 VecSubf(sub1, cntr, p1);
645                 VecSubf(sub2, co, p1);
646                 VecSubf(intr, co, p1);
647                 VecMulf(intr, Inpf(&area_normal.x, sub1) / Inpf(&area_normal.x, sub2));
648                 VecAddf(intr, intr, p1);
649                 
650                 VecSubf(val, intr, co);
651                 VecMulf(val, node->Fade);
652                 VecAddf(val, val, co);
653                                      
654                 sculpt_clip(a, co, val);
655                 
656                 node= node->next;
657         }
658 }
659
660 /* Uses the brush curve control to find a strength value between 0 and 1 */
661 float curve_strength(float p, const float len)
662 {
663         if(p > len) p= len;
664         return curvemapping_evaluateF(G.scene->sculptdata.cumap, 0, p/len);
665 }
666
667 /* Uses symm to selectively flip any axis of a coordinate. */
668 void flip_coord(float co[3], const char symm)
669 {
670         if(symm & SYMM_X)
671                 co[0]= -co[0];
672         if(symm & SYMM_Y)
673                 co[1]= -co[1];
674         if(symm & SYMM_Z)
675                 co[2]= -co[2];
676 }
677
678 /* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */
679 float sculpt_tex_angle(void)
680 {
681         SculptData *sd= sculpt_data();
682         if(sd->texact!=-1 && sd->mtex[sd->texact])
683                 return sd->mtex[sd->texact]->warpfac;
684         return 0;
685 }
686
687 void set_tex_angle(const float f)
688 {
689         SculptData *sd = sculpt_data();
690         if(sd->texact != -1 && sd->mtex[sd->texact])
691                 sd->mtex[sd->texact]->warpfac = f;
692 }
693         
694 float to_rad(const float deg)
695 {
696         return deg * (M_PI/180.0f);
697 }
698
699 float to_deg(const float rad)
700 {
701         return rad * (180.0f/M_PI);
702 }
703
704 /* Get a pixel from the texcache at (px, py) */
705 unsigned *get_texcache_pixel(const SculptSession *ss, int px, int py)
706 {
707         if(px < 0) px= 0;
708         if(py < 0) py= 0;
709         if(px > ss->texcache_w - 1) px= ss->texcache_w - 1;
710         if(py > ss->texcache_h - 1) py= ss->texcache_h - 1;
711         return ss->texcache + py * ss->texcache_w + px;
712 }
713
714 /* Return a multiplier for brush strength on a particular vertex. */
715 float tex_strength(BrushAction *a, float *point, const float len,const unsigned vindex)
716 {
717         SculptData *sd= sculpt_data();
718         SculptSession *ss= sculpt_session();
719         float avg= 1;
720
721         if(sd->texact==-1 || !sd->mtex[sd->texact])
722                 avg= 1;
723         else if(sd->texrept==SCULPTREPT_3D) {
724                 /* Get strength by feeding the vertex location directly
725                    into a texture */
726                 float jnk;
727                 const float factor= 0.01;
728                 MTex mtex;
729                 memset(&mtex,0,sizeof(MTex));
730                 mtex.tex= sd->mtex[sd->texact]->tex;
731                 mtex.projx= 1;
732                 mtex.projy= 2;
733                 mtex.projz= 3;
734                 VecCopyf(mtex.size, sd->mtex[sd->texact]->size);
735                 VecMulf(mtex.size, factor);
736                 if(!sd->texsep)
737                         mtex.size[1]= mtex.size[2]= mtex.size[0];
738                 
739                 externtex(&mtex,point,&avg,&jnk,&jnk,&jnk,&jnk);
740         }
741         else if(ss->texcache) {
742                 const short bsize= sculptmode_brush()->size * 2;
743                 const short half= sculptmode_brush()->size;
744                 const float rot= to_rad(sculpt_tex_angle());
745                 const unsigned tcw = ss->texcache_w, tch = ss->texcache_h;
746                 int px, py;
747                 unsigned i, *p;
748                 ProjVert pv;
749                 
750                 /* If the active area is being applied for symmetry, flip it
751                    across the symmetry axis in order to project it. This insures
752                    that the brush texture will be oriented correctly. */
753                 if(!a->symm.index)
754                         pv= ss->projverts[vindex];
755                 else {
756                         float co[3];
757                         VecCopyf(co, point);
758                         flip_coord(co, a->symm.index);
759                         project(co, pv.co);
760                 }
761
762                 /* For Tile and Drag modes, get the 2D screen coordinates of the
763                    and scale them up or down to the texture size. */
764                 if(sd->texrept==SCULPTREPT_TILE) {
765                         const int sx= (const int)sd->mtex[sd->texact]->size[0];
766                         const int sy= (const int)sd->texsep ? sd->mtex[sd->texact]->size[1] : sx;
767                         
768                         float fx= pv.co[0];
769                         float fy= pv.co[1];
770                         
771                         float angle= atan2(fy, fx) - rot;
772                         float len= sqrtf(fx*fx + fy*fy);
773                         
774                         if(rot<0.001 && rot>-0.001) {
775                                 px= pv.co[0];
776                                 py= pv.co[1];
777                         } else {
778                                 px= len * cos(angle) + 2000;
779                                 py= len * sin(angle) + 2000;
780                         }
781                         if(sx != 1)
782                                 px %= sx-1;
783                         if(sy != 1)
784                                 py %= sy-1;
785                         p= get_texcache_pixel(ss, tcw*px/sx, tch*py/sy);
786                 } else {
787                         float fx= (pv.co[0] - a->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2;
788                         float fy= (pv.co[1] - a->mouse[1] + half) * (tch*1.0f/bsize) - tch/2;
789
790                         float angle= atan2(fy, fx) - rot;
791                         float len= sqrtf(fx*fx + fy*fy);
792                         
793                         px= tcw/2 + len * cos(angle);
794                         py= tch/2 + len * sin(angle);
795
796                         p= get_texcache_pixel(ss, px, py);
797                 }
798                 
799                 avg= 0;
800                 for(i=0; i<3; ++i)
801                         avg+= ((unsigned char*)(p))[i] / 255.0f;
802
803                 avg/= 3;
804         }
805
806         if(sd->texfade)
807                 avg*= curve_strength(len, a->size_3d); /* Smooth curve */
808
809         return avg;
810 }
811
812 /* Mark area around the brush as damaged. projverts are marked if they are
813    inside the area and the damaged rectangle in 2D screen coordinates is 
814    added to damaged_rects. */
815 void sculpt_add_damaged_rect(BrushAction *a)
816 {
817         short p[2];
818         const float radius= brush_size();
819         RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode");
820         Mesh *me= get_mesh(OBACT);
821         SculptSession *ss = sculpt_session();
822         unsigned i;
823
824         /* Find center */
825         project(a->symm.center_3d, p);
826         rn->r.xmin= p[0]-radius;
827         rn->r.ymin= p[1]-radius;
828         rn->r.xmax= p[0]+radius;
829         rn->r.ymax= p[1]+radius;
830
831         BLI_addtail(&sculpt_session()->damaged_rects, rn);
832
833         /* Update insides */
834         for(i=0; i<me->totvert; ++i) {
835                 if(!ss->projverts[i].inside) {
836                         if(ss->projverts[i].co[0] > rn->r.xmin && ss->projverts[i].co[1] > rn->r.ymin &&
837                            ss->projverts[i].co[0] < rn->r.xmax && ss->projverts[i].co[1] < rn->r.ymax) {
838                                 ss->projverts[i].inside= 1;
839                         }
840                 }
841         }
842 }
843
844 /* Clears the depth buffer in each modified area. */
845 void sculpt_clear_damaged_areas(SculptSession *ss)
846 {
847         RectNode *rn= NULL;
848
849         for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
850                 rcti clp = rn->r;
851                 rcti *win = &curarea->winrct;
852                 
853                 clp.xmin += win->xmin;
854                 clp.xmax += win->xmin;
855                 clp.ymin += win->ymin;
856                 clp.ymax += win->ymin;
857                 
858                 if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
859                    clp.ymin < win->ymax && clp.ymax > win->ymin) {
860                         if(clp.xmin < win->xmin) clp.xmin = win->xmin;
861                         if(clp.ymin < win->ymin) clp.ymin = win->ymin;
862                         if(clp.xmax > win->xmax) clp.xmax = win->xmax;
863                         if(clp.ymax > win->ymax) clp.ymax = win->ymax;
864
865                         glScissor(clp.xmin + 1, clp.ymin + 1,
866                                   clp.xmax - clp.xmin - 2,
867                                   clp.ymax - clp.ymin - 2);
868                 }
869                 
870                 glClear(GL_DEPTH_BUFFER_BIT);
871         }
872 }
873
874 void do_brush_action(BrushAction *a)
875 {
876         int i;
877         float av_dist;
878         ListBase active_verts={0,0};
879         ActiveData *adata= 0;
880         float *vert;
881         Mesh *me= get_mesh(OBACT);
882         const float bstrength= brush_strength(a);
883         KeyBlock *keyblock= ob_get_keyblock(OBACT);
884         SculptData *sd = sculpt_data();
885         SculptSession *ss = sculpt_session();
886
887         sculpt_add_damaged_rect(a);
888
889         /* Build a list of all vertices that are potentially within the brush's
890            area of influence. Only do this once for the grab brush. */
891         if((sd->brush_type != GRAB_BRUSH) || a->firsttime) {
892                 for(i=0; i<me->totvert; ++i) {
893                         /* Projverts.inside provides a rough bounding box */
894                         if(ss->projverts[i].inside) {
895                                 vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : me->mvert[i].co;
896                                 av_dist= VecLenf(a->symm.center_3d, vert);
897                                 if(av_dist < a->size_3d) {
898                                         adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
899
900                                         adata->Index = i;
901                                         /* Fade is used to store the final strength at which the brush
902                                            should modify a particular vertex. */
903                                         adata->Fade= tex_strength(a, vert, av_dist, i) * bstrength;
904                                         adata->dist = av_dist;
905
906                                         if(sd->brush_type == GRAB_BRUSH && a->firsttime)
907                                                 BLI_addtail(&a->grab_active_verts[a->symm.index], adata);
908                                         else
909                                                 BLI_addtail(&active_verts, adata);
910                                 }
911                         }
912                 }
913         }
914
915         /* Only act if some verts are inside the brush area */
916         if(active_verts.first || (sd->brush_type == GRAB_BRUSH && a->grab_active_verts[a->symm.index].first)) {
917                 /* Apply one type of brush action */
918                 switch(G.scene->sculptdata.brush_type){
919                 case DRAW_BRUSH:
920                         do_draw_brush(a, &active_verts);
921                         break;
922                 case SMOOTH_BRUSH:
923                         do_smooth_brush(a, &active_verts);
924                         break;
925                 case PINCH_BRUSH:
926                         do_pinch_brush(a, &active_verts);
927                         break;
928                 case INFLATE_BRUSH:
929                         do_inflate_brush(a, &active_verts);
930                         break;
931                 case GRAB_BRUSH:
932                         do_grab_brush(a);
933                         break;
934                 case LAYER_BRUSH:
935                         do_layer_brush(a, &active_verts);
936                         break;
937                 case FLATTEN_BRUSH:
938                         do_flatten_brush(a, &active_verts);
939                         break;
940                 }
941         
942                 /* Copy the modified vertices from mesh to the active key */
943                 if(keyblock) {
944                         float *co= keyblock->data;
945                         if(co) {
946                                 if(sd->brush_type == GRAB_BRUSH)
947                                         adata = a->grab_active_verts[a->symm.index].first;
948                                 else
949                                         adata = active_verts.first;
950
951                                 for(; adata; adata= adata->next)
952                                         if(adata->Index < keyblock->totelem)
953                                                 VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
954                         }
955                 }
956
957                 if(ss->vertexcosnos)
958                         BLI_freelistN(&active_verts);
959                 else {
960                         if(sd->brush_type != GRAB_BRUSH)
961                                 addlisttolist(&ss->damaged_verts, &active_verts);
962                 }
963         }
964 }
965
966 /* Flip all the editdata across the axis/axes specified by symm. Used to
967    calculate multiple modifications to the mesh when symmetry is enabled. */
968 void calc_brushdata_symm(BrushAction *a, const char symm)
969 {
970         flip_coord(a->symm.center_3d, symm);
971         flip_coord(a->symm.up, symm);
972         flip_coord(a->symm.right, symm);
973         flip_coord(a->symm.out, symm);
974         
975         a->symm.index= symm;
976
977         flip_coord(a->symm.grab_delta, symm);
978 }
979
980 void do_symmetrical_brush_actions(BrushAction *a, short co[2], short pr_co[2])
981 {
982         const char symm = sculpt_data()->symm;
983         BrushActionSymm orig;
984         int i;
985
986         init_brushaction(a, co, pr_co);
987         orig = a->symm;
988         do_brush_action(a);
989         
990         for(i = 1; i <= symm; ++i) {
991                 if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
992                         // Restore the original symmetry data
993                         a->symm = orig;
994
995                         calc_brushdata_symm(a, i);
996                         do_brush_action(a);
997                 }
998         }
999 }
1000
1001 void add_face_normal(vec3f *norm, const MFace* face)
1002 {
1003         Mesh *me= get_mesh(OBACT);
1004
1005         vec3f c= {me->mvert[face->v1].co[0],me->mvert[face->v1].co[1],me->mvert[face->v1].co[2]};
1006         vec3f b= {me->mvert[face->v2].co[0],me->mvert[face->v2].co[1],me->mvert[face->v2].co[2]};
1007         vec3f a= {me->mvert[face->v3].co[0],me->mvert[face->v3].co[1],me->mvert[face->v3].co[2]};
1008         vec3f s1, s2;
1009
1010         VecSubf(&s1.x,&a.x,&b.x);
1011         VecSubf(&s2.x,&c.x,&b.x);
1012
1013         norm->x+= s1.y * s2.z - s1.z * s2.y;
1014         norm->y+= s1.z * s2.x - s1.x * s2.z;
1015         norm->z+= s1.x * s2.y - s1.y * s2.x;
1016 }
1017
1018 void update_damaged_vert(Mesh *me, ListBase *lb)
1019 {
1020         ActiveData *vert;
1021        
1022         for(vert= lb->first; vert; vert= vert->next) {
1023                 vec3f norm= {0,0,0};            
1024                 IndexNode *face= sculpt_session()->vertex_users[vert->Index].first;
1025
1026                 while(face){
1027                         add_face_normal(&norm,&me->mface[face->Index]);
1028                         face= face->next;
1029                 }
1030                 Normalize(&norm.x);
1031                 
1032                 me->mvert[vert->Index].no[0]=norm.x*32767;
1033                 me->mvert[vert->Index].no[1]=norm.y*32767;
1034                 me->mvert[vert->Index].no[2]=norm.z*32767;
1035         }
1036 }
1037
1038 void calc_damaged_verts(ListBase *damaged_verts, BrushAction *a)
1039 {
1040         Mesh *me= get_mesh(OBACT);
1041         int i;
1042         
1043         for(i=0; i<8; ++i)
1044                 update_damaged_vert(me, &a->grab_active_verts[i]);
1045
1046         update_damaged_vert(me, damaged_verts);
1047         BLI_freelistN(damaged_verts);
1048         damaged_verts->first = damaged_verts->last = NULL;
1049 }
1050
1051 void projverts_clear_inside(SculptSession *ss)
1052 {
1053         Mesh *me = get_mesh(OBACT);
1054         if(me) {
1055                 int i;
1056                 for(i = 0; i < me->totvert; ++i)
1057                         ss->projverts[i].inside = 0;
1058         }
1059 }
1060
1061 BrushData *sculptmode_brush(void)
1062 {
1063         SculptData *sd= &G.scene->sculptdata;
1064
1065         BrushData *bd = 
1066                 (sd->brush_type==DRAW_BRUSH ? &sd->drawbrush :
1067                  sd->brush_type==SMOOTH_BRUSH ? &sd->smoothbrush :
1068                  sd->brush_type==PINCH_BRUSH ? &sd->pinchbrush :
1069                  sd->brush_type==INFLATE_BRUSH ? &sd->inflatebrush :
1070                  sd->brush_type==GRAB_BRUSH ? &sd->grabbrush :
1071                  sd->brush_type==LAYER_BRUSH ? &sd->layerbrush :
1072                  sd->brush_type==FLATTEN_BRUSH ? &sd->flattenbrush : NULL);
1073
1074         if(!bd) {
1075                 sculptdata_init(G.scene);
1076                 bd = &sd->drawbrush;
1077         }
1078
1079         return bd;
1080 }
1081
1082 void sculptmode_update_tex()
1083 {
1084         SculptData *sd= sculpt_data();
1085         SculptSession *ss= sculpt_session();
1086         MTex *mtex = sd->mtex[sd->texact];
1087         TexResult texres = {0};
1088         float x, y, step=2.0/128.0, co[3];
1089         int hasrgb, ix, iy;
1090         
1091         /* Skip Default brush shape and non-textures */
1092         if(sd->texact == -1 || !sd->mtex[sd->texact]) return;
1093
1094         if(ss->texcache) {
1095                 MEM_freeN(ss->texcache);
1096                 ss->texcache= NULL;
1097         }
1098         
1099         ss->texcache_w = ss->texcache_h = 128;
1100         ss->texcache = MEM_callocN(sizeof(int) * ss->texcache_w * ss->texcache_h, "Sculpt Texture cache");
1101         
1102         if(mtex && mtex->tex) {
1103                 BKE_image_get_ibuf(sd->mtex[sd->texact]->tex->ima, NULL);
1104                 
1105                 /*do normalized cannonical view coords for texture*/
1106                 for (y=-1.0, iy=0; iy<128; iy++, y += step) {
1107                         for (x=-1.0, ix=0; ix<128; ix++, x += step) {
1108                                 co[0]= x;
1109                                 co[1]= y;
1110                                 co[2]= 0.0f;
1111                                 
1112                                 /* This is copied from displace modifier code */
1113                                 hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 1, &texres);
1114                         
1115                                 /* if the texture gave an RGB value, we assume it didn't give a valid
1116                                  * intensity, so calculate one (formula from do_material_tex).
1117                                  * if the texture didn't give an RGB value, copy the intensity across
1118                                  */
1119                                 if(hasrgb & TEX_RGB)
1120                                         texres.tin = (0.35 * texres.tr + 0.45 *
1121                                                       texres.tg + 0.2 * texres.tb);
1122
1123                                 texres.tin = texres.tin * 255.0;
1124                                 ((char*)ss->texcache)[(iy*128+ix)*4] = (char)texres.tin;
1125                                 ((char*)ss->texcache)[(iy*128+ix)*4+1] = (char)texres.tin;
1126                                 ((char*)ss->texcache)[(iy*128+ix)*4+2] = (char)texres.tin;
1127                                 ((char*)ss->texcache)[(iy*128+ix)*4+3] = (char)texres.tin;
1128                         }
1129                 }
1130         }
1131 }
1132
1133 /* pr_mouse is only used for the grab brush, can be NULL otherwise */
1134 void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse)
1135 {
1136         SculptData *sd = sculpt_data();
1137         const float mouse_depth = get_depth(mouse[0], mouse[1]);
1138         float brush_edge_loc[3], zero_loc[3], oldloc[3];
1139         ModifierData *md;
1140         int i;
1141         const char flip = (get_qual() == LR_SHIFTKEY);
1142
1143         a->flip = flip;
1144         a->symm.index = 0;
1145         a->mouse[0] = mouse[0];
1146         a->mouse[1] = mouse[1];
1147         
1148         /* Convert the location and size of the brush to
1149            modelspace coords */
1150         unproject(a->symm.center_3d, mouse[0], mouse[1], mouse_depth);
1151         unproject(brush_edge_loc, mouse[0] + brush_size(), mouse[1], mouse_depth);
1152         a->size_3d = VecLenf(a->symm.center_3d, brush_edge_loc);
1153
1154         /* Set the pivot to allow the model to rotate around the center of the brush */
1155         if(get_depth(mouse[0],mouse[1]) < 1.0)
1156                 VecCopyf(&sculpt_session()->pivot.x, a->symm.center_3d);
1157
1158         /* Now project the Up, Right, and Out normals from view to model coords */
1159         unproject(zero_loc, 0, 0, 0);
1160         unproject(a->symm.up, 0, -1, 0);
1161         unproject(a->symm.right, 1, 0, 0);
1162         unproject(a->symm.out, 0, 0, -1);
1163         VecSubf(a->symm.up, a->symm.up, zero_loc);
1164         VecSubf(a->symm.right, a->symm.right, zero_loc);
1165         VecSubf(a->symm.out, a->symm.out, zero_loc);
1166         Normalize(a->symm.up);
1167         Normalize(a->symm.right);
1168         Normalize(a->symm.out);
1169         
1170         /* Initialize mirror modifier clipping */
1171         for(i=0; i<3; ++i) {
1172                 a->clip[i]= 0;
1173                 a->cliptol[i]= 0;
1174         }
1175         for(md= OBACT->modifiers.first; md; md= md->next) {
1176                 if(md->type==eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
1177                         const MirrorModifierData *mmd = (MirrorModifierData*) md;
1178                         
1179                         if(mmd->flag & MOD_MIR_CLIPPING) {
1180                                 a->clip[mmd->axis]= 1;
1181                                 if(mmd->tolerance > a->cliptol[mmd->axis])
1182                                         a->cliptol[mmd->axis] = mmd->tolerance;
1183                         }
1184                 }
1185         }
1186
1187         if(sd->brush_type == GRAB_BRUSH) {
1188                 float gcenter[3];
1189
1190                 if(a->firsttime) 
1191                         a->depth = mouse_depth;
1192
1193                 /* Find the delta */
1194                 unproject(gcenter, mouse[0], mouse[1], a->depth);
1195                 unproject(oldloc, pr_mouse[0], pr_mouse[1], a->depth);
1196                 VecSubf(a->symm.grab_delta, gcenter, oldloc);
1197         }
1198         else if(sd->brush_type == LAYER_BRUSH) {
1199                 Mesh *me= get_mesh(OBACT);
1200
1201                 if(!a->layer_disps)
1202                         a->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
1203                 if(!a->layer_store) {
1204                         unsigned i;
1205                         a->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
1206                         for(i=0; i<me->totvert; ++i)
1207                                 VecCopyf(&a->layer_store[i].x, me->mvert[i].co);
1208                 }
1209         }
1210 }
1211 void sculptmode_set_strength(const int delta)
1212 {
1213         int val = sculptmode_brush()->strength + delta;
1214         if(val < 1) val = 1;
1215         if(val > 100) val = 100;
1216         sculptmode_brush()->strength= val;
1217 }
1218
1219 static void sculpt_radialcontrol_callback(const int mode, const int val)
1220 {
1221         SculptSession *ss = sculpt_session();
1222         BrushData *br = sculptmode_brush();
1223
1224         if(mode == RADIALCONTROL_SIZE)
1225                 br->size = val;
1226         else if(mode == RADIALCONTROL_STRENGTH)
1227                 br->strength = val;
1228         else if(mode == RADIALCONTROL_ROTATION)
1229                 set_tex_angle(val);
1230
1231         ss->radialcontrol = NULL;
1232 }
1233
1234 /* Returns GL handle to brush texture */
1235 static GLuint sculpt_radialcontrol_calctex()
1236 {
1237         SculptData *sd= sculpt_data();
1238         SculptSession *ss= sculpt_session();
1239         int i, j;
1240         const int tsz = 128;
1241         float *texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
1242         GLuint tex;
1243
1244         if(sd->texrept!=SCULPTREPT_3D)
1245                 sculptmode_update_tex();
1246         for(i=0; i<tsz; ++i)
1247                 for(j=0; j<tsz; ++j) {
1248                         float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
1249                         if(sd->texfade)
1250                                 texdata[i*tsz+j]= curve_strength(magn,tsz/2);
1251                         else
1252                                 texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
1253                 }
1254         if(sd->texact != -1 && ss->texcache) {
1255                 for(i=0; i<tsz; ++i)
1256                         for(j=0; j<tsz; ++j) {
1257                                 const int col= ss->texcache[i*tsz+j];
1258                                 texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
1259                         }
1260         }
1261                 
1262         glGenTextures(1, &tex);
1263         glBindTexture(GL_TEXTURE_2D, tex);
1264         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, texdata);
1265         MEM_freeN(texdata);
1266
1267         return tex;
1268 }
1269
1270 void sculpt_radialcontrol_start(int mode)
1271 {
1272         SculptData *sd = sculpt_data();
1273         SculptSession *ss = sculpt_session();
1274         BrushData *br = sculptmode_brush();
1275         int orig=1, max=100;
1276
1277         if(mode == RADIALCONTROL_SIZE) {
1278                 orig = br->size;
1279                 max = 200;
1280         }
1281         else if(mode == RADIALCONTROL_STRENGTH) {
1282                 orig = br->strength;
1283                 max = 100;
1284         }
1285         else if(mode == RADIALCONTROL_ROTATION) {
1286                 if(sd->texact!=-1 && sd->mtex[sd->texact]) {
1287                         orig = sculpt_tex_angle();
1288                         max = 360;
1289                 }
1290                 else
1291                         mode = RADIALCONTROL_NONE;
1292         }
1293
1294         if(mode != RADIALCONTROL_NONE) {
1295                 ss->radialcontrol= radialcontrol_start(mode, sculpt_radialcontrol_callback, orig, max,
1296                                                        sculpt_radialcontrol_calctex());
1297         }
1298 }
1299
1300 void sculpt_paint_brush(char clear)
1301 {
1302         if(sculpt_data()->flags & SCULPT_DRAW_BRUSH) {
1303                 static short mvalo[2];
1304                 short mval[2];
1305                 const short rad= sculptmode_brush()->size;
1306
1307                 getmouseco_areawin(mval);
1308                 
1309                 persp(PERSP_WIN);
1310                 if(clear)
1311                         fdrawXORcirc(mval[0], mval[1], rad);
1312                 else
1313                         draw_sel_circle(mval, mvalo, rad, rad, 0);
1314                 
1315                 mvalo[0]= mval[0];
1316                 mvalo[1]= mval[1];
1317         }
1318 }
1319
1320 void sculptmode_selectbrush_menu(void)
1321 {
1322         SculptData *sd= sculpt_data();
1323         int val;
1324         
1325         pupmenu_set_active(sd->brush_type);
1326         
1327         val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
1328
1329         if(val>0) {
1330                 sd->brush_type= val;
1331
1332                 BIF_undo_push("Brush type");
1333                 
1334                 allqueue(REDRAWVIEW3D, 1);
1335                 allqueue(REDRAWBUTSEDIT, 1);
1336         }
1337 }
1338
1339 void sculptmode_update_all_projverts(float *vertcosnos)
1340 {
1341         SculptSession *ss = sculpt_session();
1342         Mesh *me= get_mesh(OBACT);
1343         unsigned i;
1344
1345         if(!ss->projverts)
1346                 ss->projverts = MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts");
1347
1348         for(i=0; i<me->totvert; ++i) {
1349                 project(vertcosnos ? &vertcosnos[i * 6] : me->mvert[i].co, ss->projverts[i].co);
1350                 ss->projverts[i].inside= 0;
1351         }
1352 }
1353
1354 void sculptmode_draw_wires(SculptSession *ss, int only_damaged, Mesh *me)
1355 {
1356         int i;
1357
1358         bglPolygonOffset(1.0);
1359         glDepthMask(0);
1360         BIF_ThemeColor((OBACT==OBACT)?TH_ACTIVE:TH_SELECT);
1361
1362         for(i=0; i<me->totedge; i++) {
1363                 MEdge *med= &me->medge[i];
1364
1365                 if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
1366                    (med->flag & ME_EDGEDRAW)) {
1367                         glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
1368                 }
1369         }
1370
1371         glDepthMask(1);
1372         bglPolygonOffset(0.0);
1373 }
1374
1375 void sculptmode_draw_mesh(int only_damaged) 
1376 {
1377         Mesh *me= get_mesh(OBACT);
1378         int i, j, dt, drawCurrentMat = 1, matnr= -1;
1379         SculptSession *ss = sculpt_session();
1380
1381         persp(PERSP_VIEW);
1382         mymultmatrix(OBACT->obmat);
1383         glEnable(GL_DEPTH_TEST);
1384         glEnable(GL_LIGHTING);
1385         init_gl_materials(OBACT, 0);
1386         glEnable(GL_CULL_FACE);
1387
1388         glShadeModel(GL_SMOOTH);
1389
1390         glVertexPointer(3, GL_FLOAT, sizeof(MVert), &me->mvert[0].co);
1391         glNormalPointer(GL_SHORT, sizeof(MVert), &me->mvert[0].no);
1392
1393         dt= MIN2(G.vd->drawtype, OBACT->dt);
1394         if(dt==OB_WIRE)
1395                 glColorMask(0,0,0,0);
1396
1397         for(i=0; i<me->totface; ++i) {
1398                 MFace *f= &me->mface[i];
1399                 char inside= 0;
1400                 int new_matnr= f->mat_nr + 1;
1401                 
1402                 if(new_matnr != matnr)
1403                         drawCurrentMat= set_gl_material(matnr = new_matnr);
1404                 
1405                 /* If only_damaged!=0, only draw faces that are partially
1406                    inside the area(s) modified by the brush */
1407                 if(only_damaged) {
1408                         for(j=0; j<(f->v4?4:3); ++j) {
1409                                 if(ss->projverts[*((&f->v1)+j)].inside) {
1410                                         inside= 1;
1411                                         break;
1412                                 }
1413                         }
1414                 }
1415                 else
1416                         inside= 1;
1417                         
1418                 if(inside && drawCurrentMat)
1419                         glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
1420         }
1421
1422         glDisable(GL_CULL_FACE);
1423         glDisable(GL_LIGHTING);
1424         glColorMask(1,1,1,1);
1425
1426         if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
1427                 sculptmode_draw_wires(ss, only_damaged, me);
1428
1429         glDisable(GL_DEPTH_TEST);
1430 }
1431
1432 void sculptmode_correct_state(void)
1433 {
1434         if(!sculpt_session())
1435                 sculpt_init_session();
1436
1437         glEnableClientState(GL_VERTEX_ARRAY);
1438         glEnableClientState(GL_NORMAL_ARRAY);
1439         
1440         if(!sculpt_session()->vertex_users) calc_vertex_users();
1441 }
1442
1443 /* Checks whether full update mode (slower) needs to be used to work with modifiers */
1444 char sculpt_modifiers_active(Object *ob)
1445 {
1446         ModifierData *md;
1447         
1448         for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) {
1449                 if(md->mode & eModifierMode_Realtime)
1450                         return 1;
1451         }
1452         
1453         return 0;
1454 }
1455
1456 void sculpt(void)
1457 {
1458         SculptData *sd= sculpt_data();
1459         SculptSession *ss= sculpt_session();
1460         Object *ob= OBACT;
1461         /* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
1462         short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
1463         short modifier_calculations= 0;
1464         BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
1465         short spacing= 32000;
1466         int scissor_box[4];
1467         float offsetRot;
1468         int smooth_stroke = 0, i;
1469
1470         if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
1471                 return;
1472         if(!(ob->lay & G.vd->lay))
1473                 error("Active object is not in this layer");
1474         if(ob_get_keyblock(ob)) {
1475                 if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
1476                         error("Cannot sculpt on unlocked shape key");
1477                         return;
1478                 }
1479         }
1480         
1481         if(!ss) {
1482                 sculpt_init_session();
1483                 ss= sd->session;
1484         }
1485
1486         smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush_type != GRAB_BRUSH);
1487
1488         if(smooth_stroke)
1489                 sculpt_stroke_new(256);
1490
1491         ss->damaged_rects.first = ss->damaged_rects.last = NULL;
1492         ss->damaged_verts.first = ss->damaged_verts.last = NULL;
1493         ss->vertexcosnos = NULL;
1494
1495         /* Check that vertex users are up-to-date */
1496         if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != get_mesh(ob)->totvert) {
1497                 sculpt_vertexusers_free(ss);
1498                 calc_vertex_users();
1499                 if(ss->projverts)
1500                         MEM_freeN(ss->projverts);
1501                 ss->projverts = NULL;
1502                 active_ob= ob;
1503         }
1504                 
1505         glEnableClientState(GL_VERTEX_ARRAY);
1506         glEnableClientState(GL_NORMAL_ARRAY);
1507
1508         persp(PERSP_VIEW);
1509         
1510         getmouseco_areawin(mvalo);
1511
1512         /* Init texture
1513            FIXME: Shouldn't be doing this every time! */
1514         if(sd->texrept!=SCULPTREPT_3D)
1515                 sculptmode_update_tex();
1516
1517         getmouseco_areawin(mouse);
1518         mvalo[0]= mouse[0];
1519         mvalo[1]= mouse[1];
1520         lastSigMouse[0]=mouse[0];
1521         lastSigMouse[1]=mouse[1];
1522         mousebut = L_MOUSE;
1523
1524         /* If modifier_calculations is true, then extra time must be spent
1525            updating the mesh. This takes a *lot* longer, so it's worth
1526            skipping if the modifier stack is empty. */
1527         modifier_calculations= sculpt_modifiers_active(ob);
1528
1529         init_sculptmatrices();
1530
1531         if(modifier_calculations)
1532                 ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
1533         sculptmode_update_all_projverts(ss->vertexcosnos);
1534
1535         a->layer_disps= NULL;
1536         a->layer_store= NULL;
1537
1538         /* Set scaling adjustment */
1539         a->scale[0]= 1.0f / ob->size[0];
1540         a->scale[1]= 1.0f / ob->size[1];
1541         a->scale[2]= 1.0f / ob->size[2];
1542
1543         /* Capture original copy */
1544         if(sd->flags & SCULPT_DRAW_FAST)
1545                 glAccum(GL_LOAD, 1);
1546
1547         /* Get original scissor box */
1548         glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
1549         
1550         /* For raking, get the original angle*/
1551         offsetRot=sculpt_tex_angle();
1552         
1553         while (get_mbut() & mousebut) {
1554                 getmouseco_areawin(mouse);
1555                 /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
1556                 if (sd->rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
1557                         /*Nasty looking, but just orig + new angle really*/
1558                         set_tex_angle(offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
1559                         lastSigMouse[0]=mouse[0];
1560                         lastSigMouse[1]=mouse[1];
1561                 }
1562                 
1563                 if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
1564                         a->firsttime = firsttime;
1565                         firsttime= 0;
1566
1567                         if(smooth_stroke)
1568                                 sculpt_stroke_add_point(mouse[0], mouse[1]);
1569
1570                         spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
1571
1572                         if(modifier_calculations && !ss->vertexcosnos)
1573                                 ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
1574
1575                         if(G.scene->sculptdata.brush_type != GRAB_BRUSH) {
1576                                 if(smooth_stroke) {
1577                                         sculpt_stroke_apply(a);
1578                                 }
1579                                 else if(sd->spacing==0 || spacing>sd->spacing) {
1580                                         do_symmetrical_brush_actions(a, mouse, NULL);
1581                                         spacing= 0;
1582                                 }
1583                         }
1584                         else {
1585                                 do_symmetrical_brush_actions(a, mouse, mvalo);
1586                                 unproject(&ss->pivot.x, mouse[0], mouse[1], a->depth);
1587                         }
1588
1589                         if(modifier_calculations || ob_get_keyblock(ob))
1590                                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1591
1592                         if(modifier_calculations || sd->brush_type == GRAB_BRUSH || !(sd->flags & SCULPT_DRAW_FAST)) {
1593                                 calc_damaged_verts(&ss->damaged_verts, a);
1594                                 scrarea_do_windraw(curarea);
1595                                 screen_swapbuffers();
1596                         } else { /* Optimized drawing */
1597                                 calc_damaged_verts(&ss->damaged_verts, a);
1598
1599                                 /* Draw the stored image to the screen */
1600                                 glAccum(GL_RETURN, 1);
1601
1602                                 sculpt_clear_damaged_areas(ss);
1603                                 
1604                                 /* Draw all the polygons that are inside the modified area(s) */
1605                                 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
1606                                 sculptmode_draw_mesh(1);
1607                                 glAccum(GL_LOAD, 1);
1608
1609                                 projverts_clear_inside(ss);
1610
1611                                 persp(PERSP_WIN);
1612                                 glDisable(GL_DEPTH_TEST);
1613                                 
1614                                 /* Draw cursor */
1615                                 if(sculpt_data()->flags & SCULPT_DRAW_BRUSH)
1616                                         fdrawXORcirc((float)mouse[0],(float)mouse[1],sculptmode_brush()->size);
1617                                 if(smooth_stroke)
1618                                         sculpt_stroke_draw();
1619                                 
1620                                 myswapbuffers();
1621                         }
1622
1623                         BLI_freelistN(&ss->damaged_rects);
1624                         ss->damaged_rects.first = ss->damaged_rects.last = NULL;
1625         
1626                         mvalo[0]= mouse[0];
1627                         mvalo[1]= mouse[1];
1628
1629                         if(ss->vertexcosnos) {
1630                                 MEM_freeN(ss->vertexcosnos);
1631                                 ss->vertexcosnos= NULL;
1632                         }
1633
1634                 }
1635                 else BIF_wait_for_statechange();
1636         }
1637
1638         /* Set the rotation of the brush back to what it was before any rake */
1639         set_tex_angle(offsetRot);
1640         
1641         if(smooth_stroke) {
1642                 sculpt_stroke_apply_all(a);
1643                 calc_damaged_verts(&ss->damaged_verts, a);
1644                 BLI_freelistN(&ss->damaged_rects);
1645         }
1646
1647         if(a->layer_disps) MEM_freeN(a->layer_disps);
1648         if(a->layer_store) MEM_freeN(a->layer_store);
1649         for(i=0; i<8; ++i)
1650                 BLI_freelistN(&a->grab_active_verts[i]);
1651         MEM_freeN(a);
1652         sculpt_stroke_free();
1653
1654         sculpt_undo_push(G.scene->sculptdata.brush_type);
1655
1656         if(G.vd->depths) G.vd->depths->damaged= 1;
1657         
1658         allqueue(REDRAWVIEW3D, 0);
1659 }
1660
1661 void sculpt_undo_push(const short brush_type)
1662 {
1663         switch(brush_type) {
1664         case DRAW_BRUSH:
1665                 BIF_undo_push("Draw Brush"); break;
1666         case SMOOTH_BRUSH:
1667                 BIF_undo_push("Smooth Brush"); break;
1668         case PINCH_BRUSH:
1669                 BIF_undo_push("Pinch Brush"); break;
1670         case INFLATE_BRUSH:
1671                 BIF_undo_push("Inflate Brush"); break;
1672         case GRAB_BRUSH:
1673                 BIF_undo_push("Grab Brush"); break;
1674         case LAYER_BRUSH:
1675                 BIF_undo_push("Layer Brush"); break;
1676         case FLATTEN_BRUSH:
1677                 BIF_undo_push("Flatten Brush"); break;
1678         default:
1679                 BIF_undo_push("Sculpting"); break;
1680         }
1681 }
1682
1683 void set_sculptmode(void)
1684 {
1685         if(G.f & G_SCULPTMODE) {
1686                 Mesh *me= get_mesh(OBACT);
1687                 
1688                 G.f &= ~G_SCULPTMODE;
1689
1690                 sculptsession_free(G.scene);
1691                 if(me && me->pv) 
1692                         mesh_pmv_off(OBACT, me);
1693         } 
1694         else {
1695                 G.f |= G_SCULPTMODE;
1696
1697                 /* Called here to sanity-check the brush */
1698                 sculptmode_brush();
1699
1700                 sculpt_init_session();
1701                 
1702                 glEnableClientState(GL_VERTEX_ARRAY);
1703                 glEnableClientState(GL_NORMAL_ARRAY);
1704         }
1705         
1706         active_ob= NULL;
1707
1708         allqueue(REDRAWVIEW3D, 1);
1709         allqueue(REDRAWBUTSEDIT, 0);
1710 }
1711
1712 /* Partial Mesh Visibility */
1713
1714 /* mode: 0=hide outside selection, 1=hide inside selection */
1715 static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
1716 {
1717         Mesh *me= get_mesh(ob);
1718         float hidebox[6][3];
1719         vec3f plane_normals[4];
1720         float plane_ds[4];
1721         unsigned i, j;
1722         unsigned ndx_show, ndx_hide;
1723         MVert *nve;
1724         unsigned face_cnt_show= 0, face_ndx_show= 0;
1725         unsigned edge_cnt_show= 0, edge_ndx_show= 0;
1726         unsigned *old_map= NULL;
1727         const unsigned SHOW= 0, HIDE=1;
1728
1729         /* Convert hide box from 2D to 3D */
1730         unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
1731         unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
1732         unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
1733         unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
1734         unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
1735         unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
1736         
1737         /* Calculate normals for each side of hide box */
1738         CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
1739         CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
1740         CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
1741         CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
1742         
1743         /* Calculate D for each side of hide box */
1744         for(i= 0; i<4; ++i)
1745                 plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
1746                         hidebox[i][2]*plane_normals[i].z;
1747         
1748         /* Add partial visibility to mesh */
1749         if(!me->pv) {
1750                 me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
1751         } else {
1752                 old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
1753                 for(i=0; i<me->pv->totvert; ++i) {
1754                         old_map[i]= me->pv->vert_map[i]<me->totvert?0:1;
1755                 }
1756                 mesh_pmv_revert(ob, me);
1757         }
1758         
1759         /* Kill sculpt data */
1760         active_ob= NULL;
1761         
1762         /* Initalize map with which verts are to be hidden */
1763         me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
1764         me->pv->totvert= me->totvert;
1765         me->totvert= 0;
1766         for(i=0; i<me->pv->totvert; ++i) {
1767                 me->pv->vert_map[i]= mode ? HIDE:SHOW;
1768                 for(j=0; j<4; ++j) {
1769                         if(me->mvert[i].co[0] * plane_normals[j].x +
1770                            me->mvert[i].co[1] * plane_normals[j].y +
1771                            me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
1772                                 me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
1773                                 break;
1774                         }
1775                 }
1776                 if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
1777                 if(!me->pv->vert_map[i]) ++me->totvert;
1778
1779         }
1780         if(old_map) MEM_freeN(old_map);
1781
1782         /* Find out how many faces to show */
1783         for(i=0; i<me->totface; ++i) {
1784                 if(!me->pv->vert_map[me->mface[i].v1] &&
1785                    !me->pv->vert_map[me->mface[i].v2] &&
1786                    !me->pv->vert_map[me->mface[i].v3]) {
1787                         if(me->mface[i].v4) {
1788                                 if(!me->pv->vert_map[me->mface[i].v4])
1789                                         ++face_cnt_show;
1790                         }
1791                         else ++face_cnt_show;
1792                 }
1793         }
1794         /* Find out how many edges to show */
1795         for(i=0; i<me->totedge; ++i) {
1796                 if(!me->pv->vert_map[me->medge[i].v1] &&
1797                    !me->pv->vert_map[me->medge[i].v2])
1798                         ++edge_cnt_show;
1799         }
1800
1801         /* Create new vert array and reset each vert's map with map[old]=new index */
1802         nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
1803         ndx_show= 0; ndx_hide= me->totvert;
1804         for(i=0; i<me->pv->totvert; ++i) {
1805                 if(me->pv->vert_map[i]) {
1806                         me->pv->vert_map[i]= ndx_hide;
1807                         nve[me->pv->vert_map[i]]= me->mvert[i];
1808                         ++ndx_hide;
1809                 } else {
1810                         me->pv->vert_map[i]= ndx_show;
1811                         nve[me->pv->vert_map[i]]= me->mvert[i];
1812                         ++ndx_show;
1813                 }
1814         }
1815         CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
1816         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
1817
1818         /* Create new face array */
1819         me->pv->old_faces= me->mface;
1820         me->pv->totface= me->totface;
1821         me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
1822         for(i=0; i<me->totface; ++i) {
1823                 MFace *pr_f= &me->pv->old_faces[i];
1824                 char show= 0;
1825
1826                 if(me->pv->vert_map[pr_f->v1] < me->totvert &&
1827                    me->pv->vert_map[pr_f->v2] < me->totvert &&
1828                    me->pv->vert_map[pr_f->v3] < me->totvert) {
1829                         if(pr_f->v4) {
1830                                 if(me->pv->vert_map[pr_f->v4] < me->totvert)
1831                                         show= 1;
1832                         }
1833                         else show= 1;
1834                 }
1835
1836                 if(show) {
1837                         MFace *cr_f= &me->mface[face_ndx_show];
1838                         *cr_f= *pr_f;
1839                         cr_f->v1= me->pv->vert_map[pr_f->v1];
1840                         cr_f->v2= me->pv->vert_map[pr_f->v2];
1841                         cr_f->v3= me->pv->vert_map[pr_f->v3];
1842                         cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
1843                         test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
1844                         ++face_ndx_show;
1845                 }
1846         }
1847         me->totface= face_cnt_show;
1848         CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
1849
1850         /* Create new edge array */
1851         me->pv->old_edges= me->medge;
1852         me->pv->totedge= me->totedge;
1853         me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
1854         me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
1855         for(i=0; i<me->totedge; ++i) {
1856                 if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
1857                    me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
1858                         MEdge *cr_e= &me->medge[edge_ndx_show];
1859                         me->pv->edge_map[i]= edge_ndx_show;
1860                         *cr_e= me->pv->old_edges[i];
1861                         cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
1862                         cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
1863                         ++edge_ndx_show;
1864                 }
1865                 else me->pv->edge_map[i]= -1;
1866         }
1867         me->totedge= edge_cnt_show;
1868         CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
1869
1870         DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1871 }
1872
1873 static rcti sculptmode_pmv_box()
1874 {
1875         short down[2], mouse[2];
1876         rcti ret;
1877
1878         getmouseco_areawin(down);
1879
1880         while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
1881                 getmouseco_areawin(mouse);
1882
1883                 scrarea_do_windraw(curarea);
1884
1885                 persp(PERSP_WIN);
1886                 glLineWidth(2);
1887                 setlinestyle(2);
1888                 sdrawXORline(down[0],down[1],mouse[0],down[1]);
1889                 sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
1890                 sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
1891                 sdrawXORline(down[0],mouse[1],down[0],down[1]);
1892                 setlinestyle(0);
1893                 glLineWidth(1);
1894                 persp(PERSP_VIEW);
1895
1896                 screen_swapbuffers();
1897                 backdrawview3d(0);
1898         }
1899
1900         ret.xmin= down[0]<mouse[0]?down[0]:mouse[0];
1901         ret.ymin= down[1]<mouse[1]?down[1]:mouse[1];
1902         ret.xmax= down[0]>mouse[0]?down[0]:mouse[0];
1903         ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
1904         return ret;
1905 }
1906
1907 void sculptmode_pmv(int mode)
1908 {
1909         Object *ob= OBACT;
1910         rcti hb_2d;
1911         
1912         if(ob_get_key(ob)) {
1913                 error("Cannot hide mesh with shape keys enabled");
1914                 return;
1915         }
1916         
1917         hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
1918         
1919         sculptmode_correct_state();
1920
1921         waitcursor(1);
1922
1923         if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
1924                 init_sculptmatrices();
1925
1926                 sculptmode_do_pmv(ob,&hb_2d,mode);
1927         }
1928         else mesh_pmv_off(ob, get_mesh(ob));
1929
1930         scrarea_do_windraw(curarea);
1931
1932         BIF_undo_push("Partial mesh hide");
1933
1934         waitcursor(0);
1935 }