Fix for bug #5345, sculpt tool doesn't seems to use correctly the undo setting on...
[blender-staging.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_mesh_types.h"
47 #include "DNA_meshdata_types.h"
48 #include "DNA_modifier_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_screen_types.h"
51 #include "DNA_scene_types.h"
52 #include "DNA_texture_types.h"
53 #include "DNA_view3d_types.h"
54 #include "DNA_userdef_types.h"
55
56 #include "BKE_customdata.h"
57 #include "BKE_DerivedMesh.h"
58 #include "BKE_depsgraph.h"
59 #include "BKE_global.h"
60 #include "BKE_image.h"
61 #include "BKE_library.h"
62 #include "BKE_main.h"
63 #include "BKE_mesh.h"
64 #include "BKE_modifier.h"
65 #include "BKE_texture.h"
66 #include "BKE_utildefines.h"
67
68 #include "BIF_glutil.h"
69 #include "BIF_gl.h"
70 #include "BIF_interface.h"
71 #include "BIF_mywindow.h"
72 #include "BIF_previewrender.h"
73 #include "BIF_resources.h"
74 #include "BIF_screen.h"
75 #include "BIF_space.h"
76 #include "BIF_toolbox.h"
77
78 #include "BDR_drawobject.h"
79 #include "BDR_sculptmode.h"
80
81 #include "BSE_drawview.h"
82 #include "BSE_edit.h"
83 #include "BSE_view.h"
84
85 #include "IMB_imbuf_types.h"
86
87 #include "blendef.h"
88 #include "mydevice.h"
89
90 #include "RE_render_ext.h"
91
92 #include <math.h>
93 #include <stdlib.h>
94 #include <string.h>
95
96 /* ===== STRUCTS =====
97  *
98  */
99
100 /* Used by vertex_users to store face indices in a list */
101 typedef struct IndexNode {
102         struct IndexNode* next,* prev;
103         int Index;
104 } IndexNode;
105
106
107 /* ActiveData stores an Index into the mvert array of Mesh, plus Fade, which
108    stores how far the vertex is from the brush center, scaled to the range [0,1]. */
109 typedef struct ActiveData {
110         struct ActiveData *next, *prev;
111         unsigned int Index;
112         float Fade;
113 } ActiveData;
114
115 typedef struct GrabData {
116         char firsttime;
117         ListBase active_verts[8];
118         unsigned char index;
119         vec3f delta, delta_symm;
120         float depth;
121 } GrabData;
122
123 typedef struct ProjVert {
124         short co[2];
125         char inside;
126 } ProjVert;
127
128 typedef struct EditData {
129         vec3f center;
130         float size;
131         char flip;
132         short mouse[2];
133
134         /* Normals */
135         vec3f up, right;
136
137         GrabData *grabdata;
138         float *layer_disps;
139         vec3f *layer_store;
140 } EditData;
141
142 typedef struct RectNode {
143         struct RectNode *next, *prev;
144         rcti r;
145 } RectNode;
146
147 static ProjVert *projverts= NULL;
148
149
150 /* ===== MEMORY =====
151  * 
152  * Allocate/initialize/free data
153  */
154
155 void sculptmode_init(Scene *sce)
156 {
157         SculptData *sd;
158
159         if(!sce) {
160                 error("Unable to initialize sculptmode: bad scene");
161                 return;
162         }
163
164         sd= &sce->sculptdata;
165
166         memset(sd, 0, sizeof(SculptData));
167
168         sd->drawbrush.size=sd->smoothbrush.size=sd->pinchbrush.size=sd->inflatebrush.size=sd->grabbrush.size=sd->layerbrush.size= 50;
169         sd->drawbrush.strength=sd->smoothbrush.strength=sd->pinchbrush.strength=sd->inflatebrush.strength=sd->grabbrush.strength=sd->layerbrush.strength= 25;
170         sd->drawbrush.dir=sd->pinchbrush.dir=sd->inflatebrush.dir=sd->layerbrush.dir= 1;
171         sd->drawbrush.airbrush=sd->smoothbrush.airbrush=sd->pinchbrush.airbrush=sd->inflatebrush.airbrush=sd->layerbrush.airbrush= 0;
172         sd->brush_type= DRAW_BRUSH;
173         sd->texact= -1;
174         sd->texfade= 1;
175         sd->averaging= 1;
176         sd->texscale= 100;
177         sd->texrept= SCULPTREPT_DRAG;
178 }
179
180 /* Free G.sculptdata->vertexusers */
181 void sculptmode_free_vertexusers(struct Scene *sce)
182 {
183         SculptData *sd;
184
185         if(!sce) return;
186
187         sd= &sce->sculptdata;
188         if(sd->vertex_users){
189                 int i;
190                 for(i=0; i<sd->vertex_users_size; ++i){
191                         BLI_freelistN(&sd->vertex_users[i]);
192                 }
193                 MEM_freeN(sd->vertex_users);
194                 sd->vertex_users= NULL;
195                 sd->vertex_users_size= 0;
196         }
197 }
198
199 typedef struct SculptUndoStep {
200         struct SculptUndoStep *next, *prev;
201         
202         SculptUndoType type;
203         char *str;
204
205         MVert *verts;
206         
207         MEdge *edges;
208         MFace *faces;
209         int totvert, totedge, totface;
210         
211         PartialVisibility *pv;
212 } SculptUndoStep;
213 typedef struct SculptUndo {
214         ListBase steps;
215         SculptUndoStep *cur;
216 } SculptUndo;
217
218 void sculptmode_undo_debug_print_type(SculptUndoType t)
219 {
220         if(t & SUNDO_VERT) printf("VERT,");
221         if(t & SUNDO_TOPO) printf("TOPO,");
222         if(t & SUNDO_PVIS) printf("PVIS,");
223 }
224
225 void sculptmode_undo_push_debug_print()
226 {
227         SculptUndo *su= G.scene->sculptdata.undo;
228         
229         if(su) {
230                 int i;
231                 SculptUndoStep *sus;
232                 
233                 for(i=1, sus= su->steps.first; sus; ++i, sus= sus->next) {
234                         printf("%d(%p): ",i,sus);
235                         if(sus == su->cur) printf("A");
236                         else printf("-");
237                         printf(" type(");
238                         sculptmode_undo_debug_print_type(sus->type);
239                         printf(") v(%p) f/e/vc/fc/ec(%p,%p,%d,%d,%d) pv(%p) name(%s)\n",sus->verts,sus->faces,sus->edges,sus->totvert,sus->totface,sus->totedge,sus->pv,sus->str);
240                 }
241         }
242         else
243                 printf("No undo data");
244         printf("\n");
245 }
246
247 void sculptmode_undo_init()
248 {
249         G.scene->sculptdata.undo= MEM_callocN(sizeof(SculptUndo), "Sculpt Undo");
250         sculptmode_undo_push("Original", SUNDO_VERT|SUNDO_TOPO|SUNDO_PVIS);
251 }
252
253 void sculptmode_undo_free_link(SculptUndoStep *sus)
254 {
255         if(sus->verts)
256                 MEM_freeN(sus->verts);
257         if(sus->edges)
258                 MEM_freeN(sus->edges);
259         if(sus->faces)
260                 MEM_freeN(sus->faces);
261         if(sus->pv)
262                 sculptmode_pmv_free(sus->pv);
263 }
264
265 void sculptmode_undo_pull_chopped(SculptUndoStep *sus)
266 {
267         SculptUndoStep *f;
268         
269         for(f= sus; f && !(sus->type & SUNDO_TOPO); f= f->prev)
270                 if(f->type & SUNDO_TOPO) {
271                         sus->edges= f->edges;
272                         f->edges= NULL;
273                         sus->faces= f->faces;
274                         f->faces= NULL;
275                         sus->totvert= f->totvert;
276                         sus->totedge= f->totedge;
277                         sus->totface= f->totface;
278                         sus->type |= SUNDO_TOPO;
279                         break;
280                 }
281         
282         for(f= sus; f && !(sus->type & SUNDO_PVIS); f= f->prev)
283                 if(f->type & SUNDO_PVIS) {
284                         sus->pv= f->pv;
285                         f->pv= NULL;
286                         sus->type |= SUNDO_PVIS;
287                         break;
288                 }
289 }
290
291 void sculptmode_undo_free(Scene *sce)
292 {
293         SculptUndoStep *sus;
294         if(!sce->sculptdata.undo) return;
295         for(sus= sce->sculptdata.undo->steps.first; sus; sus= sus->next)
296                 sculptmode_undo_free_link(sus);
297         BLI_freelistN(&sce->sculptdata.undo->steps);
298         MEM_freeN(sce->sculptdata.undo);
299         sce->sculptdata.undo= NULL;
300 }
301
302 void sculptmode_undo_push(char *str, SculptUndoType type)
303 {
304         int cnt= U.undosteps-1;
305         SculptUndo *su= G.scene->sculptdata.undo;
306         SculptUndoStep *n, *sus, *chop, *path;
307         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
308         
309         if(U.undosteps==0) {
310                 sculptmode_undo_free(G.scene);
311                 return;
312         }
313         
314         n= MEM_callocN(sizeof(SculptUndoStep), "SculptUndo");
315
316         /* Chop off undo data after cur */
317         for(sus= su->steps.last; sus && sus != su->cur; sus= path) {
318                 path= sus->prev;
319                 sculptmode_undo_free_link(sus);
320                 BLI_freelinkN(&su->steps, sus);
321         }
322
323         /* Initialize undo data */
324         n->type= type;
325         n->str= str;
326         if(type & SUNDO_VERT)
327                 n->verts= MEM_dupallocN(me->mvert);
328         if(type & SUNDO_TOPO) {
329                 n->edges= MEM_dupallocN(me->medge);
330                 n->faces= MEM_dupallocN(me->mface);
331                 n->totvert= me->totvert;
332                 n->totedge= me->totedge;
333                 n->totface= me->totface;
334         }
335         if(type & SUNDO_PVIS) {
336                 if(me->pv)
337                         n->pv= sculptmode_copy_pmv(me->pv);
338         }
339
340         /* Add new undo step */
341         BLI_addtail(&su->steps, n);
342
343         /* Chop off undo steps pass MAXSZ */
344         for(chop= su->steps.last; chop && cnt; chop= chop->prev, --cnt);
345         if(!cnt && chop) {
346                 /* Make sure that non-vert data isn't lost */
347                 sculptmode_undo_pull_chopped(chop);
348         
349                 for(sus= su->steps.first; sus && sus != chop; sus= path) {
350                         path= sus->next;
351                         sculptmode_undo_free_link(sus);
352                         BLI_freelinkN(&su->steps, sus);
353                 }
354         }
355
356         su->cur= n;
357 }
358
359 void sculptmode_undo_update(SculptUndoStep *newcur)
360 {
361         SculptData *sd= &G.scene->sculptdata;
362         Mesh *me= get_mesh(sd->active_ob);
363         SculptUndoStep *oldcur= sd->undo->cur, *sus;
364         Object *ob= sd->active_ob;
365         int forward= 0;
366         SculptUndoType type= SUNDO_VERT;
367         
368         /* No update if undo step hasn't changed */
369         if(newcur == oldcur) return;
370         /* Discover direction of undo */
371         for(sus= oldcur; sus && sus != newcur; sus= sus->next);
372         if(sus == newcur) forward= 1;
373         
374         set_sculpt_object(NULL);
375
376         /* Verts */
377         if(newcur->verts) {
378                 CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
379                 me->mvert= MEM_dupallocN(newcur->verts);
380                 CustomData_add_layer(&me->vdata, CD_MVERT, 0, me->mvert, newcur->totvert);
381         }
382         
383         /* Check if faces/edges have been modified between oldcur and newcur */
384         for(sus= forward?oldcur->next:newcur->next;
385             sus && sus != (forward?newcur->next:oldcur->next); sus= sus->next)
386                 if(sus->type & SUNDO_TOPO) {
387                         type |= SUNDO_TOPO;
388                         break;
389                 }
390                 
391         for(sus= forward?oldcur->next:newcur->next;
392             sus && sus != (forward?newcur->next:oldcur->next); sus= sus->next)
393                 if(sus->type & SUNDO_PVIS) {
394                         type |= SUNDO_PVIS;
395                         break;
396                 }
397         
398         if(type & SUNDO_TOPO)
399                 for(sus= newcur; sus; sus= sus->prev) {
400                         if(sus->type & SUNDO_TOPO) {
401                                 CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
402                                 CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
403
404                                 me->medge= MEM_dupallocN(sus->edges);
405                                 me->mface= MEM_dupallocN(sus->faces);
406                                 CustomData_add_layer(&me->edata, CD_MEDGE, 0, me->medge, sus->totedge);
407                                 CustomData_add_layer(&me->fdata, CD_MFACE, 0, me->mface, sus->totface);
408
409                                 me->totvert= sus->totvert;
410                                 me->totedge= sus->totedge;
411                                 me->totface= sus->totface;
412                                 break;
413                         }
414                 }
415         
416         if(type & SUNDO_PVIS)
417                 for(sus= newcur; sus; sus= sus->prev)
418                         if(sus->type & SUNDO_PVIS) {
419                                 if(me->pv)
420                                         sculptmode_pmv_free(me->pv);
421                                 me->pv= NULL;
422                                 if(sus->pv)
423                                         me->pv= sculptmode_copy_pmv(sus->pv);
424                                 break;
425                         }
426
427         sd->undo->cur= newcur;
428         
429         set_sculpt_object(ob);
430         
431         if(modifiers_getVirtualModifierList(ob))
432                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
433
434         if(G.vd->depths) G.vd->depths->damaged= 1;
435         allqueue(REDRAWVIEW3D, 0);
436 }
437
438 void sculptmode_undo()
439 {
440         SculptUndo *su= G.scene->sculptdata.undo;
441
442         if(su && su->cur->prev)
443                 sculptmode_undo_update(su->cur->prev);
444 }
445
446 void sculptmode_redo()
447 {
448         SculptUndo *su= G.scene->sculptdata.undo;
449
450         if(su && su->cur->next)
451                 sculptmode_undo_update(su->cur->next);
452 }
453
454 void sculptmode_undo_menu()
455 {
456         SculptUndo *su= G.scene->sculptdata.undo;
457         SculptUndoStep *sus;
458         DynStr *ds= BLI_dynstr_new();
459         char *menu;
460         
461         if(!su) return;
462         
463         BLI_dynstr_append(ds, "Sculpt Mode Undo History %t");
464         for(sus= su->steps.first; sus; sus= sus->next) {
465                 BLI_dynstr_append(ds, "|");
466                 BLI_dynstr_append(ds, sus->str);
467         }
468         menu= BLI_dynstr_get_cstring(ds);
469         BLI_dynstr_free(ds);
470         
471         if(menu) {
472                 short event= pupmenu_col(menu, 20);
473                 MEM_freeN(menu);
474
475                 if(event>0) {
476                         int a= 1;
477                         for(sus= su->steps.first; sus; sus= sus->next, a++)
478                                 if(a==event) break;
479                         sculptmode_undo_update(sus);
480                 }
481         }
482 }
483
484 void sculptmode_free_all(Scene *sce)
485 {
486         SculptData *sd= &sce->sculptdata;
487         int a;
488
489         sculptmode_free_vertexusers(sce);
490         if(sd->texrndr) {
491                 if(sd->texrndr->rect) MEM_freeN(sd->texrndr->rect);
492                 MEM_freeN(sd->texrndr);
493         }
494         
495         for(a=0; a<MAX_MTEX; a++) {
496                 MTex *mtex= sd->mtex[a];
497                 if(mtex) {
498                         if(mtex->tex) mtex->tex->id.us--;
499                         MEM_freeN(mtex);
500                 }
501         }
502
503         sculptmode_undo_free(sce);
504 }
505
506 void calc_vertex_users()
507 {
508         int i,j;
509         IndexNode *node= 0;
510         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
511
512         sculptmode_free_vertexusers(G.scene);
513
514         /* Allocate an array of ListBases, one per vertex */
515         G.scene->sculptdata.vertex_users= (ListBase*)MEM_mallocN(sizeof(ListBase) * me->totvert, "vertex_users");
516         G.scene->sculptdata.vertex_users_size= me->totvert;
517
518         /* Initialize */
519         for(i=0; i<me->totvert; ++i){
520                 G.scene->sculptdata.vertex_users[i].first=G.scene->sculptdata.vertex_users[i].last= 0;
521         }
522
523         /* Find the users */
524         for(i=0; i<me->totface; ++i){
525                 for(j=0; j<(me->mface[i].v4?4:3); ++j){
526                         node= (IndexNode*)MEM_mallocN(sizeof(IndexNode), "faceindex");
527                         node->Index=i;
528                         BLI_addtail(&G.scene->sculptdata.vertex_users[((unsigned int*)(&me->mface[i]))[j]], node);
529                 }
530         }
531 }
532
533 void set_sculpt_object(struct Object *ob)
534 {
535         G.scene->sculptdata.active_ob= ob;
536
537         if(ob)
538                 calc_vertex_users();
539 }
540
541 /* ===== INTERFACE =====
542  */
543
544 void sculptmode_rem_tex(void *junk0,void *junk1)
545 {
546         MTex *mtex= G.scene->sculptdata.mtex[G.scene->sculptdata.texact];
547         if(mtex) {
548                 if(mtex->tex) mtex->tex->id.us--;
549                 MEM_freeN(mtex);
550                 G.scene->sculptdata.mtex[G.scene->sculptdata.texact]= NULL;
551                 BIF_undo_push("Unlink brush texture");
552                 allqueue(REDRAWBUTSEDIT, 0);
553                 allqueue(REDRAWOOPS, 0);
554         }
555 }
556
557 /* ===== OPENGL =====
558  *
559  * Simple functions to get data from the GL
560  */
561
562 void init_sculptmatrices()
563 {
564         const double badvalue= 1.0e-6;
565
566         glMatrixMode(GL_MODELVIEW);
567         glPushMatrix();
568         glMultMatrixf(OBACT->obmat);
569
570         glGetDoublev(GL_MODELVIEW_MATRIX, G.scene->sculptdata.modelviewmat);
571         glGetDoublev(GL_PROJECTION_MATRIX, G.scene->sculptdata.projectionmat);
572         glGetIntegerv(GL_VIEWPORT, (GLint *)G.scene->sculptdata.viewport);
573         
574         /* Very strange code here - it seems that certain bad values in the
575            modelview matrix can cause gluUnProject to give bad results. */
576         if(G.scene->sculptdata.modelviewmat[0] < badvalue &&
577            G.scene->sculptdata.modelviewmat[0] > -badvalue)
578                 G.scene->sculptdata.modelviewmat[0]= 0;
579         if(G.scene->sculptdata.modelviewmat[5] < badvalue &&
580            G.scene->sculptdata.modelviewmat[5] > -badvalue)
581                 G.scene->sculptdata.modelviewmat[5]= 0;
582         
583         /* Set up viewport so that gluUnProject will give correct values */
584         G.scene->sculptdata.viewport[0] = 0;
585         G.scene->sculptdata.viewport[1] = 0;
586
587         glPopMatrix();
588
589 }
590
591 /* Uses window coordinates (x,y) to find the depth in the GL depth buffer */
592 float get_depth(short x, short y)
593 {
594         float depth;
595
596         if(x<0 || y<0) return 1;
597         if(x>=curarea->winx || y>=curarea->winy) return 1;
598
599         if(G.vd->depths && x<G.vd->depths->w && y<G.vd->depths->h)
600                 return G.vd->depths->depths[y*G.vd->depths->w+x];
601         
602         x+= curarea->winrct.xmin;
603         y+= curarea->winrct.ymin;
604         
605         glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
606
607         return depth;
608 }
609
610 /* Uses window coordinates (x,y) and depth component z to find a point in
611    modelspace */
612 vec3f unproject(const short x, const short y, const float z)
613 {
614         double ux, uy, uz;
615         vec3f p;
616
617         gluUnProject(x,y,z, G.scene->sculptdata.modelviewmat,
618                      G.scene->sculptdata.projectionmat,
619                      (GLint *)G.scene->sculptdata.viewport, &ux, &uy, &uz );
620         p.x= ux;
621         p.y= uy;
622         p.z= uz;
623         return p;
624 }
625
626 void project(const float v[3], short p[2])
627 {
628         double ux, uy, uz;
629
630         gluProject(v[0],v[1],v[2], G.scene->sculptdata.modelviewmat,
631                    G.scene->sculptdata.projectionmat,
632                    (GLint *)G.scene->sculptdata.viewport, &ux, &uy, &uz);
633         p[0]= ux;
634         p[1]= uy;
635 }
636
637 /* ===== Sculpting =====
638  *
639  */
640
641 float brush_strength(EditData *e)
642 {
643         const BrushData* b= sculptmode_brush();
644         float dir= b->dir==1 ? 1 : -1;
645         float pressure= 1;
646         const GHOST_TabletData *td= get_tablet_data();
647         float flip= e->flip ? -1:1;
648
649         if(td) {
650                 switch(td->Active) {
651                 case 1:
652                         pressure= td->Pressure;
653                         break;
654                 case 2:
655                         pressure= td->Pressure;
656                         dir = -dir;
657                         break;
658                 default:
659                         break;
660                 }
661         }
662
663         switch(G.scene->sculptdata.brush_type){
664         case DRAW_BRUSH:
665         case LAYER_BRUSH:
666                 return b->strength / 5000.0f * dir * pressure * flip;
667         case SMOOTH_BRUSH:
668                 return b->strength / 50.0f * pressure;
669         case PINCH_BRUSH:
670                 return b->strength / 1000.0f * dir * pressure * flip;
671         case GRAB_BRUSH:
672                 return 1;
673         case INFLATE_BRUSH:
674                 return b->strength / 5000.0f * dir * pressure * flip;
675         default:
676                 return 0;
677         }
678 }
679
680 /* Currently only for the draw brush; finds average normal for all active
681    vertices */
682 vec3f calc_area_normal(const ListBase* active_verts)
683 {
684         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
685         vec3f area_normal= {0,0,0};
686         ActiveData *node= active_verts->first;
687
688         while(node){
689                 area_normal.x+= me->mvert[node->Index].no[0];
690                 area_normal.y+= me->mvert[node->Index].no[1];
691                 area_normal.z+= me->mvert[node->Index].no[2];
692                 node= node->next;
693         }
694         Normalise(&area_normal.x);
695         return area_normal;
696 }
697 void do_draw_brush(const ListBase* active_verts)
698 {
699         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
700         const vec3f area_normal= calc_area_normal(active_verts);
701         ActiveData *node= active_verts->first;
702
703         while(node){
704                 me->mvert[node->Index].co[0] += area_normal.x * node->Fade;
705                 me->mvert[node->Index].co[1] += area_normal.y * node->Fade;
706                 me->mvert[node->Index].co[2] += area_normal.z * node->Fade;
707                 node= node->next;
708         }
709 }
710
711 vec3f neighbor_average(const int vert)
712 {
713         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
714         int i, skip= -1, total=0;
715         IndexNode *node= G.scene->sculptdata.vertex_users[vert].first;
716         vec3f avg= {0,0,0};
717         MFace *f;
718
719         while(node){
720                 f= &me->mface[node->Index];
721                 if(f->v4) {
722                         skip= (f->v1==vert?2:
723                                f->v2==vert?3:
724                                f->v3==vert?0:
725                                f->v4==vert?1:-1);
726                 }
727
728                 for(i=0; i<(f->v4?4:3); ++i) {
729                         if(i != skip) {
730                                 VecAddf(&avg.x,&avg.x,me->mvert[(&f->v1)[i]].co);
731                                 ++total;
732                         }
733                 }
734
735                 node= node->next;
736         }
737
738         avg.x/= total;
739         avg.y/= total;
740         avg.z/= total;
741
742         return avg;
743 }
744
745 void do_smooth_brush(const ListBase* active_verts)
746 {
747         int cur;
748         ActiveData *node= active_verts->first;
749         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
750         vec3f avg;
751
752         while(node){
753                 cur= node->Index;
754
755                 if(BLI_countlist(&G.scene->sculptdata.vertex_users[cur]) > 2) {
756                         avg.x=avg.y=avg.z= 0;
757                         
758                         avg= neighbor_average(cur);
759                         
760                         me->mvert[cur].co[0]+= (avg.x - me->mvert[cur].co[0])*node->Fade;
761                         me->mvert[cur].co[1]+= (avg.y - me->mvert[cur].co[1])*node->Fade;
762                         me->mvert[cur].co[2]+= (avg.z - me->mvert[cur].co[2])*node->Fade;
763                 }
764
765                 node= node->next;
766         }
767 }
768
769 void do_pinch_brush(const ListBase* active_verts, const vec3f* center)
770 {
771         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
772         ActiveData *node= active_verts->first;
773         float* co;
774
775         while(node) {
776                 co= me->mvert[node->Index].co;
777                 co[0] += (center->x - co[0]) * node->Fade;
778                 co[1] += (center->y - co[1]) * node->Fade;
779                 co[2] += (center->z - co[2]) * node->Fade;
780                 node= node->next;
781         }
782 }
783
784 void do_grab_brush(EditData *e)
785 {
786         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
787         ActiveData *node= e->grabdata->active_verts[e->grabdata->index].first;
788         float add[3];
789
790         while(node) {
791                 VecCopyf(add,&e->grabdata->delta_symm.x);
792                 VecMulf(add,node->Fade);
793                 VecAddf(me->mvert[node->Index].co,me->mvert[node->Index].co,add);
794
795                 node= node->next;
796         }
797 }
798
799 void do_layer_brush(EditData *e, const ListBase *active_verts)
800 {
801         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
802         vec3f area_normal= calc_area_normal(active_verts);
803         ActiveData *node= active_verts->first;
804         const float bstr= brush_strength(e);
805
806         while(node){
807                 float *disp= &e->layer_disps[node->Index];
808                 
809                 if((bstr > 0 && *disp < bstr) ||
810                   (bstr < 0 && *disp > bstr)) {
811                         *disp+= node->Fade;
812
813                         if(bstr < 0) {
814                                 if(*disp < bstr)
815                                         *disp = bstr;
816                         } else {
817                                 if(*disp > bstr)
818                                         *disp = bstr;
819                         }
820
821                         me->mvert[node->Index].co[0]= e->layer_store[node->Index].x + area_normal.x * *disp;
822                         me->mvert[node->Index].co[1]= e->layer_store[node->Index].y + area_normal.y * *disp;
823                         me->mvert[node->Index].co[2]= e->layer_store[node->Index].z + area_normal.z * *disp;
824                 }
825
826                 node= node->next;
827         }
828 }
829
830 void do_inflate_brush(const ListBase *active_verts)
831 {
832         ActiveData *node= active_verts->first;
833         int cur;
834         float add[3];
835         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
836         
837         while(node) {
838                 cur= node->Index;
839
840                 add[0]= me->mvert[cur].no[0]/ 32767.0f;
841                 add[1]= me->mvert[cur].no[1]/ 32767.0f;
842                 add[2]= me->mvert[cur].no[2]/ 32767.0f;
843                 VecMulf(add,node->Fade);
844                 VecAddf(me->mvert[cur].co,me->mvert[cur].co,add);
845
846                 node= node->next;
847         }
848 }
849
850 float simple_strength(float p, const float len)
851 {
852         if(p > len) p= len;
853         return 0.5f * (cos(3*p/len) + 1);
854 }
855
856 float tex_strength(EditData *e, float *point, const float len,const unsigned vindex)
857 {
858         float avg= 0;
859
860         if(G.scene->sculptdata.texact==-1)
861                 avg= 1;
862         else if(G.scene->sculptdata.texrept==SCULPTREPT_3D) {
863                 float jnk;
864                 const float factor= 0.01;
865                 MTex mtex;
866                 memset(&mtex,0,sizeof(MTex));
867                 mtex.tex= G.scene->sculptdata.mtex[G.scene->sculptdata.texact]->tex;
868                 mtex.projx= 1;
869                 mtex.projy= 2;
870                 mtex.projz= 3;
871                 mtex.size[0]= G.scene->sculptdata.texscale * factor;
872                 mtex.size[1]= G.scene->sculptdata.texscale * factor;
873                 mtex.size[2]= G.scene->sculptdata.texscale * factor;
874                 
875                 externtex(&mtex,point,&avg,&jnk,&jnk,&jnk,&jnk);
876         } else {
877                 vec3f t2;
878                 float theta, magn;
879                 float cx;
880                 int px, py;
881                 unsigned i;
882                 unsigned int *p;
883                 RenderInfo *ri= G.scene->sculptdata.texrndr;
884
885                 /* If no texture or Default, use smooth curve */
886                 if(G.scene->sculptdata.texact == -1 || !G.scene->sculptdata.mtex[G.scene->sculptdata.texact] ||
887                    !G.scene->sculptdata.mtex[G.scene->sculptdata.texact]->tex->type)
888                         return simple_strength(len,e->size);
889
890                 /* Find direction from center to point */
891                 VecSubf(&t2.x,point,&e->center.x);
892                 Normalise(&t2.x);
893
894                 theta= e->right.x*t2.x+e->right.y*t2.y+e->right.z*t2.z;
895
896                 /* Avoid NaN errors */
897                 if( theta < -1 )
898                         theta = -1;
899                 else if( theta > 1 )
900                         theta = 1;
901
902                 theta = acos( theta );
903
904                 /* Checks whether theta should be in the III/IV quadrants using the
905                    dot product with the Up vector */
906                 if(e->up.x*t2.x+e->up.y*t2.y+e->up.z*t2.z > 0)
907                         theta = 2 * M_PI - theta;
908
909                 magn= len/e->size;
910
911                 /* XXX: This code assumes that the texture can be treated as a square */
912
913                 /* Find alpha's center, we assume a square */
914                 cx= ri->pr_rectx/2.0f;
915
916                 /* Scale the magnitude to match the size of the tex */
917                 magn*= cx;
918         
919                 /* XXX: not sure if this +c business is correct....
920            
921                 Find the pixel in the tex */
922                 px= magn * cos(theta) + cx;
923                 py= magn * sin(theta) + cx;
924
925                 if(G.scene->sculptdata.texrept==SCULPTREPT_TILE) {
926                         const float scale= G.scene->sculptdata.texscale;
927                         px+= e->mouse[0];
928                         py+= e->mouse[1];
929                         px%= (int)scale;
930                         py%= (int)scale;
931                         p= ri->rect + (int)(ri->pr_recty*py/scale) * ri->pr_rectx + (int)(ri->pr_rectx*px/scale);
932                 }
933                 else p= ri->rect + py * ri->pr_rectx + px;
934                 
935                 for(i=0; i<3; ++i)
936                         avg+= ((unsigned char*)(p))[i] / 255.0f;
937
938                 avg/= 3;
939         }
940
941         if(G.scene->sculptdata.texfade)
942                 avg*= simple_strength(len,e->size); /* Smooth curve */
943
944         return avg;
945 }
946
947 void sculptmode_add_damaged_rect(EditData *e, ListBase *damaged_rects)
948 {
949         short p[2];
950         const float radius= sculptmode_brush()->size;
951         RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode");
952         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
953         unsigned i;
954
955         /* Find center */
956         project(&e->center.x, p);
957         rn->r.xmin= p[0]-radius;
958         rn->r.ymin= p[1]-radius;
959         rn->r.xmax= p[0]+radius;
960         rn->r.ymax= p[1]+radius;
961
962         BLI_addtail(damaged_rects,rn);
963
964         /* Update insides */
965         for(i=0; i<me->totvert; ++i) {
966                 if(!projverts[i].inside) {
967                         if(projverts[i].co[0] > rn->r.xmin && projverts[i].co[1] > rn->r.ymin &&
968                            projverts[i].co[0] < rn->r.xmax && projverts[i].co[1] < rn->r.ymax) {
969                                 projverts[i].inside= 1;
970                         }
971                 }
972         }
973 }
974
975 void do_brush_action(float *vertexcosnos, EditData e,
976                      ListBase *damaged_verts, ListBase *damaged_rects)
977 {
978         int i;
979         float av_dist;
980         ListBase active_verts={0,0};
981         ActiveData *adata= 0;
982         float *vert;
983         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
984         const float bstrength= brush_strength(&e);
985
986         sculptmode_add_damaged_rect(&e,damaged_rects);
987
988         if(!e.grabdata || (e.grabdata && e.grabdata->firsttime)) {
989                 /* Find active vertices */
990                 for(i=0; i<me->totvert; ++i)
991                 {
992                         if(projverts[i].inside) {
993                                 vert= vertexcosnos ? &vertexcosnos[i*6] : me->mvert[i].co;
994                                 av_dist= VecLenf(&e.center.x,vert);
995                                 if( av_dist < e.size )
996                                 {
997                                         adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
998                                         adata->Index = i;
999                                         adata->Fade= tex_strength(&e,vert,av_dist,i) * bstrength;
1000                                         if(e.grabdata && e.grabdata->firsttime)
1001                                                 BLI_addtail(&e.grabdata->active_verts[e.grabdata->index], adata);
1002                                         else
1003                                                 BLI_addtail(&active_verts, adata);
1004                                 }
1005                         }
1006                 }
1007         }
1008
1009         switch(G.scene->sculptdata.brush_type){
1010         case DRAW_BRUSH:
1011                 do_draw_brush(&active_verts);
1012                 break;
1013         case SMOOTH_BRUSH:
1014                 do_smooth_brush(&active_verts);
1015                 break;
1016         case PINCH_BRUSH:
1017                 do_pinch_brush(&active_verts, &e.center);
1018                 break;
1019         case INFLATE_BRUSH:
1020                 do_inflate_brush(&active_verts);
1021                 break;
1022         case GRAB_BRUSH:
1023                 do_grab_brush(&e);
1024                 break;
1025         case LAYER_BRUSH:
1026                 do_layer_brush(&e, &active_verts);
1027                 break;
1028         }
1029
1030         if(vertexcosnos)
1031                 BLI_freelistN(&active_verts);
1032         else {
1033                 if(!e.grabdata)
1034                         addlisttolist(damaged_verts, &active_verts);
1035         }
1036 }
1037
1038 EditData flip_editdata(EditData *e, short x, short y, short z)
1039 {
1040         EditData fe= *e;
1041         GrabData *gd= fe.grabdata;
1042         if(x) {
1043                 fe.center.x= -fe.center.x;
1044                 fe.up.x= -fe.up.x;
1045                 fe.right.x= -fe.right.x;
1046         }
1047
1048         if(y) {
1049                 fe.center.y= -fe.center.y;
1050                 fe.up.y= -fe.up.y;
1051                 fe.right.y= -fe.right.y;
1052         }
1053
1054         if(z) {
1055                 fe.center.z= -fe.center.z;
1056                 fe.up.z= -fe.up.z;
1057                 fe.right.z= -fe.right.z;
1058         }
1059
1060         project(&fe.center.x,fe.mouse);
1061
1062         if(gd) {
1063                 gd->index= x + y*2 + z*4;
1064                 gd->delta_symm= gd->delta;
1065                 if(x) gd->delta_symm.x= -gd->delta_symm.x;
1066                 if(y) gd->delta_symm.y= -gd->delta_symm.y;
1067                 if(z) gd->delta_symm.z= -gd->delta_symm.z;
1068         }
1069
1070         return fe;
1071 }
1072
1073 void do_symmetrical_brush_actions(float *vertexcosnos, EditData *e,
1074                                   ListBase *damaged_verts, ListBase *damaged_rects)
1075 {
1076         const SculptData *sd= &G.scene->sculptdata;
1077
1078         do_brush_action(vertexcosnos,flip_editdata(e,0,0,0),damaged_verts,damaged_rects);
1079
1080         if(sd->symm_x)
1081                 do_brush_action(vertexcosnos,flip_editdata(e,1,0,0),damaged_verts,damaged_rects);
1082         if(sd->symm_y)
1083                 do_brush_action(vertexcosnos,flip_editdata(e,0,1,0),damaged_verts,damaged_rects);
1084         if(sd->symm_z)
1085                 do_brush_action(vertexcosnos,flip_editdata(e,0,0,1),damaged_verts,damaged_rects);
1086         if(sd->symm_x && sd->symm_y)
1087                 do_brush_action(vertexcosnos,flip_editdata(e,1,1,0),damaged_verts,damaged_rects);
1088         if(sd->symm_x && sd->symm_z)
1089                 do_brush_action(vertexcosnos,flip_editdata(e,1,0,1),damaged_verts,damaged_rects);
1090         if(sd->symm_y && sd->symm_z)
1091                 do_brush_action(vertexcosnos,flip_editdata(e,0,1,1),damaged_verts,damaged_rects);
1092         if(sd->symm_x && sd->symm_y && sd->symm_z)
1093                 do_brush_action(vertexcosnos,flip_editdata(e,1,1,1),damaged_verts,damaged_rects);
1094 }
1095
1096 void add_face_normal(vec3f *norm, const MFace* face)
1097 {
1098         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
1099
1100         vec3f c= {me->mvert[face->v1].co[0],me->mvert[face->v1].co[1],me->mvert[face->v1].co[2]};
1101         vec3f b= {me->mvert[face->v2].co[0],me->mvert[face->v2].co[1],me->mvert[face->v2].co[2]};
1102         vec3f a= {me->mvert[face->v3].co[0],me->mvert[face->v3].co[1],me->mvert[face->v3].co[2]};
1103         vec3f s1, s2;
1104
1105         VecSubf(&s1.x,&a.x,&b.x);
1106         VecSubf(&s2.x,&c.x,&b.x);
1107
1108         norm->x+= s1.y * s2.z - s1.z * s2.y;
1109         norm->y+= s1.z * s2.x - s1.x * s2.z;
1110         norm->z+= s1.x * s2.y - s1.y * s2.x;
1111 }
1112
1113 void update_damaged_vert(Mesh *me, ListBase *lb)
1114 {
1115         ActiveData *vert;
1116        
1117         for(vert= lb->first; vert; vert= vert->next) {
1118                 vec3f norm= {0,0,0};            
1119                 IndexNode *face= G.scene->sculptdata.vertex_users[vert->Index].first;
1120
1121                 while(face){
1122                         add_face_normal(&norm,&me->mface[face->Index]);
1123                         face= face->next;
1124                 }
1125                 Normalise(&norm.x);
1126                 
1127                 me->mvert[vert->Index].no[0]=norm.x*32767;
1128                 me->mvert[vert->Index].no[1]=norm.y*32767;
1129                 me->mvert[vert->Index].no[2]=norm.z*32767;
1130         }
1131 }
1132
1133 void calc_damaged_verts(ListBase *damaged_verts, GrabData *grabdata)
1134 {
1135         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
1136
1137         if(grabdata) {
1138                 int i;
1139                 for(i=0; i<8; ++i)
1140                         update_damaged_vert(me,&grabdata->active_verts[i]);
1141         } else {
1142                 update_damaged_vert(me,damaged_verts);
1143                 BLI_freelistN(damaged_verts);
1144         }
1145 }
1146
1147 BrushData *sculptmode_brush()
1148 {
1149         SculptData *sd= &G.scene->sculptdata;
1150         return (sd->brush_type==DRAW_BRUSH ? &sd->drawbrush :
1151                 sd->brush_type==SMOOTH_BRUSH ? &sd->smoothbrush :
1152                 sd->brush_type==PINCH_BRUSH ? &sd->pinchbrush :
1153                 sd->brush_type==INFLATE_BRUSH ? &sd->inflatebrush :
1154                 sd->brush_type==GRAB_BRUSH ? &sd->grabbrush :
1155                 sd->brush_type==LAYER_BRUSH ? &sd->layerbrush : NULL);
1156 }
1157
1158 void sculptmode_update_tex()
1159 {
1160         SculptData *sd= &G.scene->sculptdata;
1161         RenderInfo *ri= sd->texrndr;
1162
1163         /* Skip Default brush shape and non-textures */
1164         if(sd->texact == -1 || !sd->mtex[sd->texact]) return;
1165
1166         if(!ri) {
1167                 ri= MEM_callocN(sizeof(RenderInfo),"brush texture render");
1168                 sd->texrndr= ri;
1169         }
1170
1171         if(ri->rect) {
1172                 MEM_freeN(ri->rect);
1173                 ri->rect= NULL;
1174         }
1175
1176         ri->curtile= 0;
1177         ri->tottile= 0;
1178         if(ri->rect) MEM_freeN(ri->rect);
1179         ri->rect = NULL;
1180         ri->pr_rectx = 128; /* FIXME: might want to allow higher/lower sizes */
1181         ri->pr_recty = 128;
1182
1183         BIF_previewrender(&sd->mtex[sd->texact]->tex->id, ri, NULL, PR_ICON_RENDER);
1184 }
1185
1186 void init_editdata(SculptData *sd, EditData *e, short *mouse, short *pr_mouse, const char flip)
1187 {
1188         const float mouse_depth= get_depth(mouse[0],mouse[1]);
1189         vec3f brush_edge_loc, zero_loc, oldloc;
1190
1191         e->flip= flip;
1192         
1193         /* Convert the location and size of the brush to
1194            modelspace coords */
1195         e->center= unproject(mouse[0],mouse[1],mouse_depth);
1196         brush_edge_loc= unproject(mouse[0] +
1197                                   sculptmode_brush()->size,mouse[1],
1198                                   mouse_depth);
1199         e->size= VecLenf(&e->center.x,&brush_edge_loc.x);
1200
1201         /* Now project the Up and Right normals from view to model coords */
1202         zero_loc= unproject(0,0,0);
1203         e->up= unproject(0,-1,0);
1204         e->right= unproject(1,0,0);
1205         VecSubf(&e->up.x,&e->up.x,&zero_loc.x);
1206         VecSubf(&e->right.x,&e->right.x,&zero_loc.x);
1207         Normalise(&e->up.x);
1208         Normalise(&e->right.x);
1209
1210         if(sd->brush_type == GRAB_BRUSH) {
1211                 vec3f gcenter;
1212                 if(!e->grabdata) {
1213                         e->grabdata= MEM_callocN(sizeof(GrabData),"grab data");
1214                         e->grabdata->firsttime= 1;
1215                         e->grabdata->depth= mouse_depth;
1216                 }
1217                 else
1218                         e->grabdata->firsttime= 0;
1219                 
1220                 /* Find the delta */
1221                 gcenter= unproject(mouse[0],mouse[1],e->grabdata->depth);
1222                 oldloc= unproject(pr_mouse[0],pr_mouse[1],e->grabdata->depth);
1223                 VecSubf(&e->grabdata->delta.x,&gcenter.x,&oldloc.x);
1224         }
1225         else if(sd->brush_type == LAYER_BRUSH) {
1226                 Mesh *me= get_mesh(sd->active_ob);
1227
1228                 if(!e->layer_disps)
1229                         e->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
1230                 if(!e->layer_store) {
1231                         unsigned i;
1232                         e->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
1233                         for(i=0; i<me->totvert; ++i)
1234                                 VecCopyf(&e->layer_store[i].x,me->mvert[i].co);
1235                 }
1236         }
1237 }
1238
1239 void sculptmode_set_strength(const int delta)
1240 {
1241         int val = sculptmode_brush()->strength + delta;
1242         if(val < 1) val = 1;
1243         if(val > 100) val = 100;
1244         sculptmode_brush()->strength= val;
1245 }
1246
1247 void sculptmode_propset_calctex()
1248 {
1249         PropsetData *pd= G.scene->sculptdata.propset;
1250         if(pd) {
1251                 int i, j;
1252                 const int tsz = 128;
1253                 float *d;
1254                 if(!pd->texdata) {
1255                         pd->texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
1256                         if(G.scene->sculptdata.texrept!=SCULPTREPT_3D)
1257                                 sculptmode_update_tex();
1258                         for(i=0; i<tsz; ++i)
1259                                 for(j=0; j<tsz; ++j)
1260                                         pd->texdata[i*tsz+j]= simple_strength(sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2)),tsz/2);
1261                         if(G.scene->sculptdata.texact != -1 && G.scene->sculptdata.texrndr) {
1262                                 for(i=0; i<tsz; ++i)
1263                                         for(j=0; j<tsz; ++j) {
1264                                                 const int col= G.scene->sculptdata.texrndr->rect[i*tsz+j];
1265                                                 pd->texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
1266                                         }
1267                         }
1268                 }
1269                 
1270                 /* Adjust alpha with brush strength */
1271                 d= MEM_dupallocN(pd->texdata);
1272                 for(i=0; i<tsz; ++i)
1273                         for(j=0; j<tsz; ++j)
1274                                 d[i*tsz+j]*= sculptmode_brush()->strength/200.0f+0.5f;
1275                 
1276                         
1277                 if(!pd->tex)
1278                         glGenTextures(1, (GLuint *)&pd->tex);
1279                 glBindTexture(GL_TEXTURE_2D, pd->tex);
1280
1281                 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, d);
1282                 MEM_freeN(d);
1283         }
1284 }
1285
1286 void sculptmode_propset_end(int cancel)
1287 {
1288         PropsetData *pd= G.scene->sculptdata.propset;
1289         if(pd) {
1290                 if(cancel) {
1291                         sculptmode_brush()->size= pd->origsize;
1292                         sculptmode_brush()->strength= pd->origstrength;
1293                 } else {        
1294                         if(pd->mode != PropsetSize)
1295                                 sculptmode_brush()->size= pd->origsize;
1296                         if(pd->mode != PropsetStrength)
1297                                 sculptmode_brush()->strength= pd->origstrength;
1298                 }
1299                 glDeleteTextures(1, &pd->tex);
1300                 MEM_freeN(pd->texdata);
1301                 MEM_freeN(pd);
1302                 G.scene->sculptdata.propset= NULL;
1303                 allqueue(REDRAWVIEW3D, 0);
1304                 allqueue(REDRAWBUTSEDIT, 0);
1305         }
1306 }
1307
1308 void sculptmode_propset_init(PropsetMode mode)
1309 {
1310         PropsetData *pd= G.scene->sculptdata.propset;
1311         
1312         if(!pd) {
1313                 short mouse[2];
1314                 
1315                 pd= MEM_callocN(sizeof(PropsetData),"PropsetSize");
1316                 G.scene->sculptdata.propset= pd;
1317                 
1318                 getmouseco_areawin(mouse);
1319                 pd->origloc[0]= mouse[0];
1320                 pd->origloc[1]= mouse[1];
1321                 
1322                 pd->origsize= sculptmode_brush()->size;
1323                 pd->origstrength= sculptmode_brush()->strength;
1324                 
1325                 sculptmode_propset_calctex();
1326         }
1327
1328         pd->mode= mode;
1329 }
1330
1331 void sculptmode_propset(unsigned short event)
1332 {
1333         PropsetData *pd= G.scene->sculptdata.propset;
1334         short mouse[2];
1335         short tmp[2];
1336         float dist;
1337
1338         switch(event) {
1339         case MOUSEX:
1340         case MOUSEY:
1341                 getmouseco_areawin(mouse);
1342                 tmp[0]= pd->origloc[0]-mouse[0];
1343                 tmp[1]= pd->origloc[1]-mouse[1];
1344                 dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
1345                 if(pd->mode == PropsetSize) {
1346                         sculptmode_brush()->size= dist;
1347                         if(sculptmode_brush()->size>200) sculptmode_brush()->size= 200;
1348                 } else if(pd->mode == PropsetStrength) {
1349                         float fin= (200.0f - dist) * 0.5f;
1350                         sculptmode_brush()->strength= fin>=0 ? fin : 0;
1351                         sculptmode_propset_calctex();
1352                 }
1353                 allqueue(REDRAWVIEW3D, 0);
1354                 break;
1355         /*case WHEELUPMOUSE:
1356                 sculptmode_set_strength(5);
1357                 allqueue(REDRAWVIEW3D, 0);
1358                 break;
1359         case WHEELDOWNMOUSE:
1360                 sculptmode_set_strength(-5);
1361                 allqueue(REDRAWVIEW3D, 0);
1362                 break;*/
1363         case ESCKEY:
1364         case RIGHTMOUSE:
1365                 sculptmode_brush()->size= pd->origsize;
1366                 sculptmode_brush()->strength= pd->origstrength;
1367         case LEFTMOUSE:
1368                 while(get_mbut()==L_MOUSE);
1369         case RETKEY:
1370         case PADENTER:
1371                 sculptmode_propset_end(0);
1372                 break;
1373         default:
1374                 break;
1375         };
1376 }
1377
1378 void sculptmode_selectbrush_menu()
1379 {
1380         SculptData *sd= &G.scene->sculptdata;
1381         int val;
1382         
1383         pupmenu_set_active(sd->brush_type);
1384         
1385         val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer");
1386
1387         if(val>0) {
1388                 sd->brush_type= val;
1389                 
1390                 allqueue(REDRAWVIEW3D, 1);
1391                 allqueue(REDRAWBUTSEDIT, 1);
1392         }
1393 }
1394
1395 void sculptmode_update_all_projverts()
1396 {
1397         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
1398         unsigned i;
1399
1400         if(projverts) MEM_freeN(projverts);
1401         projverts= MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts");
1402         for(i=0; i<me->totvert; ++i) {
1403                 project(me->mvert[i].co, projverts[i].co);
1404                 projverts[i].inside= 0;
1405         }
1406 }
1407
1408 void sculptmode_draw_wires(int only_damaged, Mesh *me)
1409 {
1410         int i;
1411
1412         bglPolygonOffset(1.0);
1413         glDepthMask(0);
1414         BIF_ThemeColor((G.scene->sculptdata.active_ob==OBACT)?TH_ACTIVE:TH_SELECT);
1415
1416         for(i=0; i<me->totedge; i++) {
1417                 MEdge *med= &me->medge[i];
1418
1419                 if((!only_damaged || (projverts[med->v1].inside || projverts[med->v2].inside)) &&
1420                    (med->flag & ME_EDGEDRAW)) {
1421                         glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
1422                 }
1423         }
1424
1425         glDepthMask(1);
1426         bglPolygonOffset(0.0);
1427 }
1428
1429 void sculptmode_draw_mesh(int only_damaged) {
1430         Mesh *me= get_mesh(G.scene->sculptdata.active_ob);
1431         SculptData *sd= &G.scene->sculptdata;
1432         int i, j, dt, drawCurrentMat = 1, matnr= -1;
1433
1434         persp(PERSP_VIEW);
1435         mymultmatrix(sd->active_ob->obmat);
1436         glEnable(GL_DEPTH_TEST);
1437         glEnable(GL_LIGHTING);
1438         init_gl_materials(sd->active_ob, 0);
1439
1440         glShadeModel(GL_SMOOTH);
1441
1442         glVertexPointer(3, GL_FLOAT, sizeof(MVert), &me->mvert[0].co);
1443         glNormalPointer(GL_SHORT, sizeof(MVert), &me->mvert[0].no);
1444
1445         dt= MIN2(G.vd->drawtype, G.scene->sculptdata.active_ob->dt);
1446         if(dt==OB_WIRE)
1447                 glColorMask(0,0,0,0);
1448
1449         
1450         for(i=0; i<me->totface; ++i) {
1451                 MFace *f= &me->mface[i];
1452                 char inside= 0;
1453                 int new_matnr= f->mat_nr + 1;
1454                 
1455                 if(new_matnr != matnr)
1456                         drawCurrentMat= set_gl_material(matnr = new_matnr);
1457                 
1458                 /* If only_damaged!=0, only draw faces that are partially
1459                    inside the area(s) modified by the brush */
1460                 if(only_damaged) {
1461                         for(j=0; j<(f->v4?4:3); ++j) {
1462                                 if(projverts[*((&f->v1)+j)].inside) {
1463                                         inside= 1;
1464                                         break;
1465                                 }
1466                         }
1467                 }
1468                 else
1469                         inside= 1;
1470                         
1471                 if(inside && drawCurrentMat)
1472                         glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
1473         }
1474
1475         glDisable(GL_LIGHTING);
1476         glColorMask(1,1,1,1);
1477
1478         if(dt==OB_WIRE || (sd->active_ob->dtx & OB_DRAWWIRE))
1479                 sculptmode_draw_wires(only_damaged, me);
1480
1481         glDisable(GL_DEPTH_TEST);
1482 }
1483
1484 void sculptmode_correct_state()
1485 {
1486         if(get_mesh(G.scene->sculptdata.active_ob) != get_mesh(OBACT))
1487                 set_sculpt_object(OBACT);
1488
1489         glEnableClientState(GL_VERTEX_ARRAY);
1490         glEnableClientState(GL_NORMAL_ARRAY);
1491         
1492         if(!G.scene->sculptdata.vertex_users) calc_vertex_users();
1493         if(!G.scene->sculptdata.undo) sculptmode_undo_init();
1494 }
1495
1496 void sculpt()
1497 {
1498         Object *ob= 0;
1499         short mouse[2], mvalo[2], firsttime=1, mousebut;
1500         ListBase damaged_verts= {0,0};
1501         ListBase damaged_rects= {0,0};
1502         float *vertexcosnos= 0;
1503         short modifier_calculations= 0;
1504         EditData e;
1505         RectNode *rn= NULL;
1506         SculptData *sd= &G.scene->sculptdata;
1507         short spacing= 32000;
1508
1509         if((G.f & G_SCULPTMODE)==0) return;
1510         if(G.obedit) return;
1511         
1512         ob= OBACT;
1513         if(ob->id.lib) return;
1514
1515         /* Make sure that the active mesh is set correctly */
1516         if(get_mesh(G.scene->sculptdata.active_ob) != get_mesh(ob))
1517                 set_sculpt_object(ob);
1518                 
1519         glEnableClientState(GL_VERTEX_ARRAY);
1520         glEnableClientState(GL_NORMAL_ARRAY);
1521
1522         if(!G.scene->sculptdata.active_ob || !get_mesh(G.scene->sculptdata.active_ob) ||
1523            get_mesh(G.scene->sculptdata.active_ob)->totface==0) return;
1524
1525         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1526
1527         persp(PERSP_VIEW);
1528         
1529         getmouseco_areawin(mvalo);
1530
1531         /* Make sure sculptdata has been init'd properly */
1532         if(!G.scene->sculptdata.vertex_users) calc_vertex_users();
1533         if(!G.scene->sculptdata.undo) sculptmode_undo_init();
1534         
1535         /* Init texture
1536            FIXME: Shouldn't be doing this every time! */
1537         if(sd->texrept!=SCULPTREPT_3D)
1538                 sculptmode_update_tex();
1539
1540         getmouseco_areawin(mouse);
1541         mvalo[0]= mouse[0];
1542         mvalo[1]= mouse[1];
1543
1544         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1545         else mousebut = L_MOUSE;
1546
1547         /* If modifier_calculations is true, then extra time must be spent
1548            updating the mesh. This takes a *lot* longer, so it's worth
1549            skipping if the modifier stack is empty. */
1550         modifier_calculations= modifiers_getVirtualModifierList(ob) != NULL;
1551
1552         init_sculptmatrices();
1553
1554         sculptmode_update_all_projverts();
1555
1556         e.grabdata= NULL;
1557         e.layer_disps= NULL;
1558         e.layer_store= NULL;
1559
1560         /* Capture original copy */
1561         glAccum(GL_LOAD, 1);
1562
1563         while (get_mbut() & mousebut) {
1564                 getmouseco_areawin(mouse);
1565                 
1566                 if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
1567                         firsttime= 0;
1568
1569                         spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
1570
1571                         if(modifier_calculations)
1572                                 vertexcosnos= mesh_get_mapped_verts_nors(ob);
1573
1574                         if(G.scene->sculptdata.brush_type != GRAB_BRUSH && (sd->spacing==0 || spacing>sd->spacing)) {
1575                                 char i;
1576                                 float t= G.scene->sculptdata.averaging-1;
1577                                 const float sub= 1/(t+1);
1578                                 t/= (t+1);
1579                                 for(i=0; i<G.scene->sculptdata.averaging; ++i) {
1580                                         short avgco[2]= {mvalo[0]*t+mouse[0]*(1-t),
1581                                                          mvalo[1]*t+mouse[1]*(1-t)};
1582                                         
1583                                         init_editdata(&G.scene->sculptdata,&e,avgco,mvalo,get_qual()==LR_SHIFTKEY);
1584                                         
1585                                         if(get_depth(mouse[0],mouse[1]) < 1.0)
1586                                                 G.scene->sculptdata.pivot= e.center;
1587                                         
1588                                         /* The brush always has at least one area it affects,
1589                                            right beneath the mouse. It can have up to seven
1590                                            other areas that must also be modified, if all three
1591                                            axes of symmetry are on. */
1592                                         do_symmetrical_brush_actions(vertexcosnos,&e,&damaged_verts,&damaged_rects);
1593
1594                                         t-= sub;
1595                                 }
1596                                 spacing= 0;
1597                         }
1598                         else if(sd->brush_type==GRAB_BRUSH) {
1599                                 init_editdata(&G.scene->sculptdata,&e,mouse,mvalo,0);
1600                                 G.scene->sculptdata.pivot= unproject(mouse[0],mouse[1],e.grabdata->depth);
1601                                 do_symmetrical_brush_actions(vertexcosnos,&e,&damaged_verts,&damaged_rects);
1602                         }
1603                         
1604                         if(modifier_calculations)
1605                                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1606
1607                         if(modifier_calculations || sd->brush_type == GRAB_BRUSH) {
1608                                 calc_damaged_verts(&damaged_verts,e.grabdata);
1609
1610                                 scrarea_do_windraw(curarea);
1611                                 screen_swapbuffers();
1612                         } else {
1613                                 calc_damaged_verts(&damaged_verts,e.grabdata);
1614
1615                                 for(rn=damaged_rects.first; rn; rn= rn->next) {
1616                                         float col[3];
1617                                         rcti clp= rn->r;
1618                                         rcti *win= &curarea->winrct;
1619                                         
1620                                         clp.xmin+= win->xmin;
1621                                         clp.xmax+= win->xmin;
1622                                         clp.ymin+= win->ymin;
1623                                         clp.ymax+= win->ymin;
1624                                         
1625                                         if(clp.xmin<win->xmax && clp.xmax>win->xmin &&
1626                                            clp.ymin<win->ymax && clp.ymax>win->ymin) {
1627                                                 if(clp.xmin<win->xmin) clp.xmin= win->xmin;
1628                                                 if(clp.ymin<win->ymin) clp.ymin= win->ymin;
1629                                                 if(clp.xmax>win->xmax) clp.xmax= win->xmax;
1630                                                 if(clp.ymax>win->ymax) clp.ymax= win->ymax;
1631                                                 glScissor(clp.xmin+1, clp.ymin+1,
1632                                                           clp.xmax-clp.xmin-2,clp.ymax-clp.ymin-2);
1633                                         }
1634                                         
1635                                         BIF_GetThemeColor3fv(TH_BACK, col);
1636                                         glClearColor(col[0], col[1], col[2], 0.0);
1637                                         glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
1638                                 }
1639                                 glDisable(GL_SCISSOR_TEST);
1640                                 
1641                                 sculptmode_draw_mesh(1);
1642
1643                                 glAccum(GL_LOAD, 1);
1644                                 
1645                                 /* Draw cursor */
1646                                 persp(PERSP_WIN);
1647                                 glDisable(GL_DEPTH_TEST);
1648                                 fdrawXORcirc((float)mouse[0],(float)mouse[1],sculptmode_brush()->size);
1649                                 glRasterPos2i(0, 0);
1650                                 myswapbuffers();
1651                                 glAccum(GL_RETURN, 1);
1652                                 
1653                                 glEnable(GL_SCISSOR_TEST);
1654                         }
1655
1656                         BLI_freelistN(&damaged_rects);
1657         
1658                         mvalo[0]= mouse[0];
1659                         mvalo[1]= mouse[1];
1660
1661                         if(modifier_calculations)
1662                                 MEM_freeN(vertexcosnos);
1663                 }
1664                 else BIF_wait_for_statechange();
1665         }
1666
1667         if(projverts) MEM_freeN(projverts);
1668         projverts= NULL;
1669         if(e.layer_disps) MEM_freeN(e.layer_disps);
1670         if(e.layer_store) MEM_freeN(e.layer_store);
1671         /* Free GrabData */
1672         if(e.grabdata) {
1673                 int i;
1674                 for(i=0; i<8; ++i)
1675                         BLI_freelistN(&e.grabdata->active_verts[i]);
1676                 MEM_freeN(e.grabdata);
1677         }
1678
1679         switch(G.scene->sculptdata.brush_type) {
1680         case DRAW_BRUSH:
1681                 sculptmode_undo_push("Draw Brush", SUNDO_VERT); break;
1682         case SMOOTH_BRUSH:
1683                 sculptmode_undo_push("Smooth Brush", SUNDO_VERT); break;
1684         case PINCH_BRUSH:
1685                 sculptmode_undo_push("Pinch Brush", SUNDO_VERT); break;
1686         case INFLATE_BRUSH:
1687                 sculptmode_undo_push("Inflate Brush", SUNDO_VERT); break;
1688         case GRAB_BRUSH:
1689                 sculptmode_undo_push("Grab Brush", SUNDO_VERT); break;
1690         case LAYER_BRUSH:
1691                 sculptmode_undo_push("Layer Brush", SUNDO_VERT); break;
1692         default:
1693                 sculptmode_undo_push("Sculpting", SUNDO_VERT); break;
1694         }
1695
1696         if(G.vd->depths) G.vd->depths->damaged= 1;
1697         
1698         allqueue(REDRAWVIEW3D, 0);
1699 }
1700
1701 void set_sculptmode()
1702 {
1703         if(G.f & G_SCULPTMODE) {
1704                 G.f &= ~G_SCULPTMODE;
1705
1706                 set_sculpt_object(NULL);
1707
1708                 sculptmode_undo_free(G.scene);
1709
1710                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1711         } else {
1712                 G.f |= G_SCULPTMODE;
1713
1714                 if(!sculptmode_brush())
1715                         sculptmode_init(G.scene);
1716
1717                 if(G.vd->twflag) G.vd->twflag= 0;
1718
1719                 set_sculpt_object(OBACT);
1720
1721                 sculptmode_undo_init();
1722                 
1723                 glEnableClientState(GL_VERTEX_ARRAY);
1724                 glEnableClientState(GL_NORMAL_ARRAY);
1725
1726                 allqueue(REDRAWVIEW3D,0);
1727         }
1728
1729         allqueue(REDRAWBUTSEDIT, 0);
1730 }
1731
1732 /* Partial Mesh Visibility */
1733 PartialVisibility *sculptmode_copy_pmv(PartialVisibility *pmv)
1734 {
1735         PartialVisibility *n= MEM_dupallocN(pmv);
1736         n->vert_map= MEM_dupallocN(pmv->vert_map);
1737         n->edge_map= MEM_dupallocN(pmv->edge_map);
1738         n->old_edges= MEM_dupallocN(pmv->old_edges);
1739         n->old_faces= MEM_dupallocN(pmv->old_faces);
1740         return n;
1741 }
1742
1743 void sculptmode_pmv_free(PartialVisibility *pv)
1744 {
1745         MEM_freeN(pv->vert_map);
1746         MEM_freeN(pv->edge_map);
1747         MEM_freeN(pv->old_faces);
1748         MEM_freeN(pv->old_edges);
1749         MEM_freeN(pv);
1750 }
1751
1752 void sculptmode_revert_pmv(Mesh *me)
1753 {
1754         if(me->pv) {
1755                 unsigned i;
1756                 MVert *nve, *old_verts;
1757                 Object *ob= G.scene->sculptdata.active_ob;
1758
1759                 /* Temporarily exit sculptmode */
1760                 set_sculpt_object(NULL);
1761
1762                 /* Reorder vertices */
1763                 nve= me->mvert;
1764                 old_verts = MEM_mallocN(sizeof(MVert)*me->pv->totvert,"PMV revert verts");
1765                 for(i=0; i<me->pv->totvert; ++i)
1766                         old_verts[i]= nve[me->pv->vert_map[i]];
1767
1768                 /* Restore verts, edges and faces */
1769                 CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
1770                 CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
1771                 CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
1772
1773                 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, old_verts, me->pv->totvert);
1774                 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, 0, me->pv->old_edges, me->pv->totedge);
1775                 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, me->pv->old_faces, me->pv->totface);
1776
1777                 me->totvert= me->pv->totvert;
1778                 me->totedge= me->pv->totedge;
1779                 me->totface= me->pv->totface;
1780
1781                 me->pv->old_edges= NULL;
1782                 me->pv->old_faces= NULL;
1783
1784                 /* Free maps */
1785                 MEM_freeN(me->pv->edge_map);
1786                 me->pv->edge_map= NULL;
1787                 MEM_freeN(me->pv->vert_map);
1788                 me->pv->vert_map= NULL;
1789                 
1790                 set_sculpt_object(ob);
1791
1792                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1793         }
1794 }
1795
1796 void sculptmode_pmv_off(Mesh *me)
1797 {
1798         if(me->pv) {
1799                 sculptmode_revert_pmv(me);
1800                 MEM_freeN(me->pv);
1801                 me->pv= NULL;
1802         }
1803 }
1804
1805 /* mode: 0=hide outside selection, 1=hide inside selection */
1806 void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
1807 {
1808         Mesh *me= get_mesh(ob);
1809         vec3f hidebox[6];
1810         vec3f plane_normals[4];
1811         float plane_ds[4];
1812         unsigned i, j;
1813         unsigned ndx_show, ndx_hide;
1814         MVert *nve;
1815         unsigned face_cnt_show= 0, face_ndx_show= 0;
1816         unsigned edge_cnt_show= 0, edge_ndx_show= 0;
1817         unsigned *old_map= NULL;
1818         const unsigned SHOW= 0, HIDE=1;
1819
1820         /* Convert hide box from 2D to 3D */
1821         hidebox[0]= unproject(hb_2d->xmin, hb_2d->ymax, 1);
1822         hidebox[1]= unproject(hb_2d->xmax, hb_2d->ymax, 1);
1823         hidebox[2]= unproject(hb_2d->xmax, hb_2d->ymin, 1);
1824         hidebox[3]= unproject(hb_2d->xmin, hb_2d->ymin, 1);
1825         hidebox[4]= unproject(hb_2d->xmin, hb_2d->ymax, 0);
1826         hidebox[5]= unproject(hb_2d->xmax, hb_2d->ymin, 0);
1827         
1828         /* Calculate normals for each side of hide box */
1829         CalcNormFloat(&hidebox[0].x,&hidebox[1].x,&hidebox[4].x,&plane_normals[0].x);
1830         CalcNormFloat(&hidebox[1].x,&hidebox[2].x,&hidebox[5].x,&plane_normals[1].x);
1831         CalcNormFloat(&hidebox[2].x,&hidebox[3].x,&hidebox[5].x,&plane_normals[2].x);
1832         CalcNormFloat(&hidebox[3].x,&hidebox[0].x,&hidebox[4].x,&plane_normals[3].x);
1833         
1834         /* Calculate D for each side of hide box */
1835         for(i= 0; i<4; ++i)
1836                 plane_ds[i]= hidebox[i].x*plane_normals[i].x + hidebox[i].y*plane_normals[i].y +
1837                         hidebox[i].z*plane_normals[i].z;
1838         
1839         /* Add partial visibility to mesh */
1840         if(!me->pv) {
1841                 me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
1842         } else {
1843                 old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
1844                 for(i=0; i<me->pv->totvert; ++i) {
1845                         old_map[i]= me->pv->vert_map[i]<me->totvert?0:1;
1846                 }
1847                 sculptmode_revert_pmv(me);
1848         }
1849         
1850         /* Kill sculpt data */
1851         set_sculpt_object(NULL);
1852         
1853         /* Initalize map with which verts are to be hidden */
1854         me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
1855         me->pv->totvert= me->totvert;
1856         me->totvert= 0;
1857         for(i=0; i<me->pv->totvert; ++i) {
1858                 me->pv->vert_map[i]= mode ? HIDE:SHOW;
1859                 for(j=0; j<4; ++j) {
1860                         if(me->mvert[i].co[0] * plane_normals[j].x +
1861                            me->mvert[i].co[1] * plane_normals[j].y +
1862                            me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
1863                                 me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
1864                                 break;
1865                         }
1866                 }
1867                 if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
1868                 if(!me->pv->vert_map[i]) ++me->totvert;
1869
1870         }
1871         if(old_map) MEM_freeN(old_map);
1872
1873         /* Find out how many faces to show */
1874         for(i=0; i<me->totface; ++i) {
1875                 if(!me->pv->vert_map[me->mface[i].v1] &&
1876                    !me->pv->vert_map[me->mface[i].v2] &&
1877                    !me->pv->vert_map[me->mface[i].v3]) {
1878                         if(me->mface[i].v4) {
1879                                 if(!me->pv->vert_map[me->mface[i].v4])
1880                                         ++face_cnt_show;
1881                         }
1882                         else ++face_cnt_show;
1883                 }
1884         }
1885         /* Find out how many edges to show */
1886         for(i=0; i<me->totedge; ++i) {
1887                 if(!me->pv->vert_map[me->medge[i].v1] &&
1888                    !me->pv->vert_map[me->medge[i].v2])
1889                         ++edge_cnt_show;
1890         }
1891
1892         /* Create new vert array and reset each vert's map with map[old]=new index */
1893         nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
1894         ndx_show= 0; ndx_hide= me->totvert;
1895         for(i=0; i<me->pv->totvert; ++i) {
1896                 if(me->pv->vert_map[i]) {
1897                         me->pv->vert_map[i]= ndx_hide;
1898                         nve[me->pv->vert_map[i]]= me->mvert[i];
1899                         ++ndx_hide;
1900                 } else {
1901                         me->pv->vert_map[i]= ndx_show;
1902                         nve[me->pv->vert_map[i]]= me->mvert[i];
1903                         ++ndx_show;
1904                 }
1905         }
1906         CustomData_free_layer(&me->vdata, CD_MVERT, me->pv->totvert);
1907         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, nve, me->totvert);
1908
1909         /* Create new face array */
1910         me->pv->old_faces= me->mface;
1911         me->pv->totface= me->totface;
1912         me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
1913         for(i=0; i<me->totface; ++i) {
1914                 MFace *pr_f= &me->pv->old_faces[i];
1915                 char show= 0;
1916
1917                 if(me->pv->vert_map[pr_f->v1] < me->totvert &&
1918                    me->pv->vert_map[pr_f->v2] < me->totvert &&
1919                    me->pv->vert_map[pr_f->v3] < me->totvert) {
1920                         if(pr_f->v4) {
1921                                 if(me->pv->vert_map[pr_f->v4] < me->totvert)
1922                                         show= 1;
1923                         }
1924                         else show= 1;
1925                 }
1926
1927                 if(show) {
1928                         MFace *cr_f= &me->mface[face_ndx_show];
1929                         *cr_f= *pr_f;
1930                         cr_f->v1= me->pv->vert_map[pr_f->v1];
1931                         cr_f->v2= me->pv->vert_map[pr_f->v2];
1932                         cr_f->v3= me->pv->vert_map[pr_f->v3];
1933                         cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
1934                         test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
1935                         ++face_ndx_show;
1936                 }
1937         }
1938         me->totface= face_cnt_show;
1939         CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
1940
1941         /* Create new edge array */
1942         me->pv->old_edges= me->medge;
1943         me->pv->totedge= me->totedge;
1944         me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
1945         me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
1946         for(i=0; i<me->totedge; ++i) {
1947                 if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
1948                    me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
1949                         MEdge *cr_e= &me->medge[edge_ndx_show];
1950                         me->pv->edge_map[i]= edge_ndx_show;
1951                         *cr_e= me->pv->old_edges[i];
1952                         cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
1953                         cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
1954                         ++edge_ndx_show;
1955                 }
1956                 else me->pv->edge_map[i]= -1;
1957         }
1958         me->totedge= edge_cnt_show;
1959         CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
1960         
1961         set_sculpt_object(ob);
1962
1963         DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1964 }
1965
1966 rcti sculptmode_pmv_box()
1967 {
1968         short down[2], mouse[2];
1969         rcti ret;
1970
1971         getmouseco_areawin(down);
1972
1973         while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
1974                 getmouseco_areawin(mouse);
1975
1976                 scrarea_do_windraw(curarea);
1977
1978                 persp(PERSP_WIN);
1979                 glLineWidth(2);
1980                 setlinestyle(2);
1981                 sdrawXORline(down[0],down[1],mouse[0],down[1]);
1982                 sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
1983                 sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
1984                 sdrawXORline(down[0],mouse[1],down[0],down[1]);
1985                 setlinestyle(0);
1986                 glLineWidth(1);
1987                 persp(PERSP_VIEW);
1988
1989                 screen_swapbuffers();
1990                 backdrawview3d(0);
1991         }
1992
1993         ret.xmin= down[0]<mouse[0]?down[0]:mouse[0];
1994         ret.ymin= down[1]<mouse[1]?down[1]:mouse[1];
1995         ret.xmax= down[0]>mouse[0]?down[0]:mouse[0];
1996         ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
1997         return ret;
1998 }
1999
2000 void sculptmode_pmv(int mode)
2001 {
2002         Object *ob= OBACT;
2003         rcti hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
2004         
2005         sculptmode_correct_state();
2006
2007         waitcursor(1);
2008
2009         if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
2010                 init_sculptmatrices();
2011
2012                 sculptmode_do_pmv(ob,&hb_2d,mode);
2013         }
2014         else sculptmode_pmv_off(get_mesh(ob));
2015
2016         scrarea_do_windraw(curarea);
2017
2018         sculptmode_undo_push("Partial mesh hide", SUNDO_VERT|SUNDO_TOPO|SUNDO_PVIS);
2019
2020         waitcursor(0);
2021 }