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