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