d901644c19f9077ef7c146f6ba7043a68591cac9
[blender.git] / source / blender / src / meshtools.c
1 /**
2  * $Id: 
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2004 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 /*
34
35 meshtools.c: no editmode, tools operating on meshes
36
37 int join_mesh(void);
38
39 void fasterdraw(void);
40 void slowerdraw(void);
41
42 void sort_faces(void);
43
44 */
45
46 #include <stdlib.h>
47 #include <string.h>
48 #include <math.h>
49
50 #ifdef HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53
54 #include "MEM_guardedalloc.h"
55
56 #include "DNA_image_types.h"
57 #include "DNA_mesh_types.h"
58 #include "DNA_meshdata_types.h"
59 #include "DNA_object_types.h"
60 #include "DNA_material_types.h"
61 #include "DNA_scene_types.h"
62 #include "DNA_screen_types.h"
63 #include "DNA_space_types.h"
64 #include "DNA_view3d_types.h"
65 #include "DNA_world_types.h"
66
67 #include "BLI_blenlib.h"
68 #include "BLI_arithb.h"
69
70 #include "BKE_depsgraph.h"
71 #include "BKE_customdata.h"
72 #include "BKE_global.h"
73 #include "BKE_image.h"
74 #include "BKE_library.h"
75 #include "BKE_main.h"
76 #include "BKE_mesh.h"
77 #include "BKE_material.h"
78 #include "BKE_object.h"
79 #include "BKE_utildefines.h"
80
81 #include "BIF_editmesh.h"
82 #include "BIF_graphics.h"
83 #include "BIF_interface.h"
84 #include "BIF_mywindow.h"
85 #include "BIF_screen.h"
86 #include "BIF_space.h"
87 #include "BIF_toolbox.h"
88 #include "BIF_editconstraint.h"
89
90 #include "BDR_drawmesh.h" 
91 #include "BDR_editobject.h" 
92 #include "BDR_editface.h" 
93 #include "BDR_sculptmode.h"
94
95 #include "BLI_editVert.h"
96 #include "BLI_ghash.h"
97 #include "BLI_threads.h"
98 #include "BLI_rand.h" /* for randome face sorting */
99
100 #include "mydevice.h"
101 #include "blendef.h"
102
103 #include "BIF_meshtools.h" /* include ourself for prototypes */
104
105 #include "RE_pipeline.h"
106 #include "RE_shader_ext.h"
107
108 #include "PIL_time.h"
109
110 #include "IMB_imbuf_types.h"
111
112 /* from rendercode.c */
113 #define VECMUL(dest, f)                  dest[0]*= f; dest[1]*= f; dest[2]*= f
114
115 /* * ********************** no editmode!!! *********** */
116
117 /* join selected meshes into the active mesh, context sensitive
118 return 0 if no join is made (error) and 1 of the join is done */
119 int join_mesh(void)
120 {
121         Base *base, *nextb;
122         Object *ob;
123         Material **matar, *ma;
124         Mesh *me;
125         MVert *mvert, *mvertmain;
126         MEdge *medge = NULL, *medgemain;
127         MFace *mface = NULL, *mfacemain;
128         float imat[4][4], cmat[4][4];
129         int a, b, totcol, totedge=0, totvert=0, totface=0, ok=0, vertofs, map[MAXMAT];
130         int     i, j, index, haskey=0, hasmulti=0, edgeofs, faceofs;
131         bDeformGroup *dg, *odg;
132         MDeformVert *dvert;
133         CustomData vdata, edata, fdata;
134
135         if(G.obedit) return 0;
136         
137         ob= OBACT;
138         if(!ob || ob->type!=OB_MESH) return 0;
139         
140         if (object_data_is_libdata(ob)) {
141                 error_libdata();
142                 return 0;
143         }
144
145 #ifdef WITH_VERSE
146         /* it isn't allowed to join shared object at verse server
147          * this function will be implemented as soon as possible */
148         base= FIRSTBASE;
149         while(base) {
150                 if TESTBASELIB(base) {
151                         if(base->object->type==OB_MESH) {
152                                 if(base->object->vnode) {
153                                         haskey= 1;
154                                         break;
155                                 }
156                         }
157                 }
158                 base= base->next;
159         }
160         if(haskey) {
161                 error("Can't join meshes shared at verse server");
162                 return 0;
163         }
164 #endif
165
166         /* count & check */
167         base= FIRSTBASE;
168         while(base) {
169                 if TESTBASELIB(base) {
170                         if(base->object->type==OB_MESH) {
171                                 me= base->object->data;
172                                 totvert+= me->totvert;
173                                 totface+= me->totface;
174
175                                 if(base->object == ob) ok= 1;
176
177                                 if(me->key) {
178                                         haskey= 1;
179                                         break;
180                                 }
181                                 if(me->mr) {
182                                         hasmulti= 1;
183                                         break;
184                                 }
185                         }
186                 }
187                 base= base->next;
188         }
189         
190         if(haskey) {
191                 error("Can't join meshes with vertex keys");
192                 return 0;
193         }
194         if(hasmulti) {
195                 error("Can't join meshes with Multires");
196                 return 0;
197         }
198         /* that way the active object is always selected */ 
199         if(ok==0) return 0;
200         
201         if(totvert==0 || totvert>MESH_MAX_VERTS) return 0;
202
203         /* if needed add edges to other meshes */
204         for(base= FIRSTBASE; base; base= base->next) {
205                 if TESTBASELIB(base) {
206                         if(base->object->type==OB_MESH) {
207                                 me= base->object->data;
208                                 totedge += me->totedge;
209                         }
210                 }
211         }
212         
213         /* new material indices and material array */
214         matar= MEM_callocN(sizeof(void *)*MAXMAT, "join_mesh");
215         totcol= ob->totcol;
216         
217         /* obact materials in new main array, is nicer start! */
218         for(a=1; a<=ob->totcol; a++) {
219                 matar[a-1]= give_current_material(ob, a);
220                 id_us_plus((ID *)matar[a-1]);
221                 /* increase id->us : will be lowered later */
222         }
223         
224         base= FIRSTBASE;
225         while(base) {
226                 if TESTBASELIB(base) {
227                         if(ob!=base->object && base->object->type==OB_MESH) {
228                                 me= base->object->data;
229
230                                 // Join this object's vertex groups to the base one's
231                                 for (dg=base->object->defbase.first; dg; dg=dg->next){
232                                         /* See if this group exists in the object */
233                                         for (odg=ob->defbase.first; odg; odg=odg->next){
234                                                 if (!strcmp(odg->name, dg->name)){
235                                                         break;
236                                                 }
237                                         }
238                                         if (!odg){
239                                                 odg = MEM_callocN (sizeof(bDeformGroup), "join deformGroup");
240                                                 memcpy (odg, dg, sizeof(bDeformGroup));
241                                                 BLI_addtail(&ob->defbase, odg);
242                                         }
243
244                                 }
245                                 if (ob->defbase.first && ob->actdef==0)
246                                         ob->actdef=1;
247
248                                 if(me->totvert) {
249                                         for(a=1; a<=base->object->totcol; a++) {
250                                                 ma= give_current_material(base->object, a);
251                                                 if(ma) {
252                                                         for(b=0; b<totcol; b++) {
253                                                                 if(ma == matar[b]) break;
254                                                         }
255                                                         if(b==totcol) {
256                                                                 matar[b]= ma;
257                                                                 ma->id.us++;
258                                                                 totcol++;
259                                                         }
260                                                         if(totcol>=MAXMAT-1) break;
261                                                 }
262                                         }
263                                 }
264                         }
265                         if(totcol>=MAXMAT-1) break;
266                 }
267                 base= base->next;
268         }
269
270         me= ob->data;
271
272         memset(&vdata, 0, sizeof(vdata));
273         memset(&edata, 0, sizeof(edata));
274         memset(&fdata, 0, sizeof(fdata));
275         
276         mvert= CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
277         medge= CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
278         mface= CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
279
280         mvertmain= mvert;
281         medgemain= medge;
282         mfacemain= mface;
283
284         /* inverse transorm all selected meshes in this object */
285         Mat4Invert(imat, ob->obmat);
286
287         vertofs= 0;
288         edgeofs= 0;
289         faceofs= 0;
290         base= FIRSTBASE;
291         while(base) {
292                 nextb= base->next;
293                 if TESTBASELIB(base) {
294                         if(base->object->type==OB_MESH) {
295                                 
296                                 me= base->object->data;
297                                 
298                                 if(me->totvert) {
299                                         CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
300                                         CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert);
301                                         
302                                         dvert= CustomData_get(&vdata, vertofs, CD_MDEFORMVERT);
303
304                                         /* NEW VERSION */
305                                         if (dvert){
306                                                 for (i=0; i<me->totvert; i++){
307                                                         for (j=0; j<dvert[i].totweight; j++){
308                                                                 //      Find the old vertex group
309                                                                 odg = BLI_findlink (&base->object->defbase, dvert[i].dw[j].def_nr);
310                                                                 if(odg) {
311                                                                         //      Search for a match in the new object
312                                                                         for (dg=ob->defbase.first, index=0; dg; dg=dg->next, index++){
313                                                                                 if (!strcmp(dg->name, odg->name)){
314                                                                                         dvert[i].dw[j].def_nr = index;
315                                                                                         break;
316                                                                                 }
317                                                                         }
318                                                                 }
319                                                         }
320                                                 }
321                                         }
322
323                                         if(base->object != ob) {
324                                                 /* watch this: switch matmul order really goes wrong */
325                                                 Mat4MulMat4(cmat, base->object->obmat, imat);
326                                                 
327                                                 a= me->totvert;
328                                                 while(a--) {
329                                                         Mat4MulVecfl(cmat, mvert->co);
330                                                         mvert++;
331                                                 }
332                                         }
333                                         else mvert+= me->totvert;
334                                 }
335                                 if(me->totface) {
336                                 
337                                         /* make mapping for materials */
338                                         memset(map, 0, 4*MAXMAT);
339                                         for(a=1; a<=base->object->totcol; a++) {
340                                                 ma= give_current_material(base->object, a);
341                                                 if(ma) {
342                                                         for(b=0; b<totcol; b++) {
343                                                                 if(ma == matar[b]) {
344                                                                         map[a-1]= b;
345                                                                         break;
346                                                                 }
347                                                         }
348                                                 }
349                                         }
350
351                                         CustomData_merge(&me->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
352                                         CustomData_copy_data(&me->fdata, &fdata, 0, faceofs, me->totface);
353
354                                         for(a=0; a<me->totface; a++, mface++) {
355                                                 mface->v1+= vertofs;
356                                                 mface->v2+= vertofs;
357                                                 mface->v3+= vertofs;
358                                                 if(mface->v4) mface->v4+= vertofs;
359                                                 
360                                                 mface->mat_nr= map[(int)mface->mat_nr];
361                                         }
362
363                                         faceofs += me->totface;
364                                 }
365                                 
366                                 if(me->totedge) {
367                                         CustomData_merge(&me->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
368                                         CustomData_copy_data(&me->edata, &edata, 0, edgeofs, me->totedge);
369
370                                         for(a=0; a<me->totedge; a++, medge++) {
371                                                 medge->v1+= vertofs;
372                                                 medge->v2+= vertofs;
373                                         }
374
375                                         edgeofs += me->totedge;
376                                 }
377                                 
378                                 vertofs += me->totvert;
379                                 
380                                 if(base->object!=ob)
381                                         free_and_unlink_base(base);
382                         }
383                 }
384                 base= nextb;
385         }
386         
387         me= ob->data;
388         
389         CustomData_free(&me->vdata, me->totvert);
390         CustomData_free(&me->edata, me->totedge);
391         CustomData_free(&me->fdata, me->totface);
392
393         me->totvert= totvert;
394         me->totedge= totedge;
395         me->totface= totface;
396         
397         me->vdata= vdata;
398         me->edata= edata;
399         me->fdata= fdata;
400
401         mesh_update_customdata_pointers(me);
402         
403         /* old material array */
404         for(a=1; a<=ob->totcol; a++) {
405                 ma= ob->mat[a-1];
406                 if(ma) ma->id.us--;
407         }
408         for(a=1; a<=me->totcol; a++) {
409                 ma= me->mat[a-1];
410                 if(ma) ma->id.us--;
411         }
412         if(ob->mat) MEM_freeN(ob->mat);
413         if(me->mat) MEM_freeN(me->mat);
414         ob->mat= me->mat= 0;
415         
416         if(totcol) {
417                 me->mat= matar;
418                 ob->mat= MEM_callocN(sizeof(void *)*totcol, "join obmatar");
419         }
420         else MEM_freeN(matar);
421         
422         ob->totcol= me->totcol= totcol;
423         ob->colbits= 0;
424         
425         /* other mesh users */
426         test_object_materials((ID *)me);
427         
428         DAG_scene_sort(G.scene);        // removed objects, need to rebuild dag before editmode call
429         
430         enter_editmode(EM_WAITCURSOR);
431         exit_editmode(EM_FREEDATA|EM_WAITCURSOR);       // freedata, but no undo
432         
433         allqueue(REDRAWVIEW3D, 0);
434         allqueue(REDRAWBUTSSHADING, 0);
435
436         BIF_undo_push("Join Mesh");
437         return 1;
438 }
439
440
441 /* ********************** SORT FACES ******************* */
442
443 static void permutate(void *list, int num, int size, int *index)
444 {
445         void *buf;
446         int len;
447         int i;
448
449         len = num * size;
450
451         buf = MEM_mallocN(len, "permutate");
452         memcpy(buf, list, len);
453         
454         for (i = 0; i < num; i++) {
455                 memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
456         }
457         MEM_freeN(buf);
458 }
459
460 /* sort faces on view axis */
461 static float *face_sort_floats;
462 static int float_sort(const void *v1, const void *v2)
463 {
464         float x1, x2;
465         
466         x1 = face_sort_floats[((int *) v1)[0]];
467         x2 = face_sort_floats[((int *) v2)[0]];
468         
469         if( x1 > x2 ) return 1;
470         else if( x1 < x2 ) return -1;
471         return 0;
472 }
473
474
475 void sort_faces(void)
476 {
477         Object *ob= OBACT;
478         Mesh *me;
479         CustomDataLayer *layer;
480         int i, *index;
481         short event;
482         float reverse = 1;
483         
484         if(!ob) return;
485         if(G.obedit) return;
486         if(ob->type!=OB_MESH) return;
487         if (!G.vd) return;
488         
489         me= ob->data;
490         if(me->totface==0) return;
491         
492         event = pupmenu(
493         "Sort Faces (Ctrl to reverse)%t|"
494         "View Axis%x1|"
495         "Cursor Distance%x2|"
496         "Material%x3|"
497         "Selection%x4|"
498         "Randomize%x5");
499         
500         if (event==-1) return;
501         
502         if(G.qual & LR_CTRLKEY)
503                 reverse = -1;
504         
505 /*      create index list */
506         index = (int *) MEM_mallocN(sizeof(int) * me->totface, "sort faces");
507         for (i = 0; i < me->totface; i++) {
508                 index[i] = i;
509         }
510         
511         face_sort_floats = (float *) MEM_mallocN(sizeof(float) * me->totface, "sort faces float");
512         
513 /* sort index list instead of faces itself 
514    and apply this permutation to all face layers */
515    
516         if (event == 5) {
517                 /* Random */
518                 for(i=0; i<me->totface; i++) {
519                         face_sort_floats[i] = BLI_frand();
520                 }
521                 qsort(index, me->totface, sizeof(int), float_sort);             
522         } else {
523                 MFace *mf;
524                 float vec[3];
525                 float mat[4][4];
526                 float cur[3];
527                 
528                 if (event == 1)
529                         Mat4MulMat4(mat, OBACT->obmat, G.vd->viewmat); /* apply the view matrix to the object matrix */
530                 else if (event == 2) { /* sort from cursor */
531                         if( G.vd && G.vd->localview ) {
532                                 VECCOPY(cur, G.vd->cursor);
533                         } else {
534                                 VECCOPY(cur, G.scene->cursor);
535                         }
536                         Mat4Invert(mat, OBACT->obmat);
537                         Mat4MulVecfl(mat, cur);
538                 }
539                 
540                 mf= me->mface;
541                 for(i=0; i<me->totface; i++, mf++) {
542                         
543                         if (event==3) {
544                                 face_sort_floats[i] = ((float)mf->mat_nr)*reverse;
545                         } else if (event==4) {
546                                 /*selected first*/
547                                 if (mf->flag & ME_FACE_SEL)     face_sort_floats[i] = 0.0;
548                                 else                                            face_sort_floats[i] = reverse;
549                         } else {
550                                 /* find the faces center */
551                                 VECADD(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co);
552                                 if (mf->v4) {
553                                         VECADD(vec, vec, (me->mvert+mf->v3)->co);
554                                         VECADD(vec, vec, (me->mvert+mf->v4)->co);
555                                         VECMUL(vec, 0.25f);
556                                 } else {
557                                         VECADD(vec, vec, (me->mvert+mf->v3)->co);
558                                         VECMUL(vec, 1.0f/3.0f);
559                                 } /* done */
560                                 
561                                 if (event == 1) { /* sort on view axis */
562                                         Mat4MulVecfl(mat, vec);
563                                         face_sort_floats[i] = vec[2] * reverse;
564                                 } else { /* distance from cursor*/
565                                         face_sort_floats[i] = VecLenf(cur, vec) * reverse; /* back to front */
566                                 }
567                         }
568                 }
569                 qsort(index, me->totface, sizeof(int), float_sort);
570         }
571         
572         MEM_freeN(face_sort_floats);
573         
574         for(i = 0; i < me->fdata.totlayer; i++) {
575                 layer = &me->fdata.layers[i];
576                 permutate(layer->data, me->totface, CustomData_sizeof(layer->type), index);
577         }
578
579         MEM_freeN(index);
580
581         allqueue(REDRAWVIEW3D, 0);
582         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
583 }
584
585
586
587 /* ********************* MESH VERTEX OCTREE LOOKUP ************* */
588
589 /* important note; this is unfinished, needs better API for editmode, and custom threshold */
590
591 #define MOC_RES                 8
592 #define MOC_NODE_RES    8
593 #define MOC_THRESH              0.0002f
594
595 typedef struct MocNode {
596         struct MocNode *next;
597         long index[MOC_NODE_RES];
598 } MocNode;
599
600 static int mesh_octree_get_base_offs(float *co, float *offs, float *div)
601 {
602         int vx, vy, vz;
603         
604         vx= floor( (co[0]-offs[0])/div[0] );
605         vy= floor( (co[1]-offs[1])/div[1] );
606         vz= floor( (co[2]-offs[2])/div[2] );
607         
608         CLAMP(vx, 0, MOC_RES-1);
609         CLAMP(vy, 0, MOC_RES-1);
610         CLAMP(vz, 0, MOC_RES-1);
611
612         return (vx*MOC_RES*MOC_RES) + vy*MOC_RES + vz;
613 }
614
615 static void mesh_octree_add_node(MocNode **bt, long index)
616 {
617         if(*bt==NULL) {
618                 *bt= MEM_callocN(sizeof(MocNode), "MocNode");
619                 (*bt)->index[0]= index;
620         }
621         else {
622                 int a;
623                 for(a=0; a<MOC_NODE_RES; a++) {
624                         if((*bt)->index[a]==index)
625                                 return;
626                         else if((*bt)->index[a]==0) {
627                                 (*bt)->index[a]= index;
628                                 return;
629                         }
630                 }
631                 mesh_octree_add_node(&(*bt)->next, index);
632         }
633 }
634
635 static void mesh_octree_free_node(MocNode **bt)
636 {
637         if( (*bt)->next ) {
638                 mesh_octree_free_node(&(*bt)->next);
639         }
640         MEM_freeN(*bt);
641 }
642
643
644 /* temporal define, just to make nicer code below */
645 #define MOC_ADDNODE(vx, vy, vz) mesh_octree_add_node(basetable + ((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz), index)
646
647 static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, long index)
648 {
649         float fx, fy, fz;
650         int vx, vy, vz;
651         
652         fx= (co[0]-offs[0])/div[0];
653         fy= (co[1]-offs[1])/div[1];
654         fz= (co[2]-offs[2])/div[2];
655         CLAMP(fx, 0.0f, MOC_RES-MOC_THRESH);
656         CLAMP(fy, 0.0f, MOC_RES-MOC_THRESH);
657         CLAMP(fz, 0.0f, MOC_RES-MOC_THRESH);
658         
659         vx= floor(fx);
660         vy= floor(fy);
661         vz= floor(fz);
662         
663         MOC_ADDNODE(vx, vy, vz);
664         
665         if( vx>0 )
666                 if( fx-((float)vx)-MOC_THRESH < 0.0f)
667                         MOC_ADDNODE(vx-1, vy, vz);
668         if( vx<MOC_RES-2 )
669                 if( fx-((float)vx)+MOC_THRESH > 1.0f)
670                         MOC_ADDNODE(vx+1, vy, vz);
671
672         if( vy>0 )
673                 if( fy-((float)vy)-MOC_THRESH < 0.0f) 
674                         MOC_ADDNODE(vx, vy-1, vz);
675         if( vy<MOC_RES-2 )
676                 if( fy-((float)vy)+MOC_THRESH > 1.0f) 
677                         MOC_ADDNODE(vx, vy+1, vz);
678
679         if( vz>0 )
680                 if( fz-((float)vz)-MOC_THRESH < 0.0f) 
681                         MOC_ADDNODE(vx, vy, vz-1);
682         if( vz<MOC_RES-2 )
683                 if( fz-((float)vz)+MOC_THRESH > 1.0f) 
684                         MOC_ADDNODE(vx, vy, vz+1);
685         
686 }
687
688 static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
689 {
690         float *vec;
691         int a;
692         
693         if(*bt==NULL)
694                 return -1;
695         
696         for(a=0; a<MOC_NODE_RES; a++) {
697                 if((*bt)->index[a]) {
698                         /* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
699                         if(mvert) {
700                                 vec= (mvert+(*bt)->index[a]-1)->co;
701                                 if(FloatCompare(vec, co, MOC_THRESH))
702                                         return (*bt)->index[a]-1;
703                         }
704                         else {
705                                 EditVert *eve= (EditVert *)((*bt)->index[a]);
706                                 if(FloatCompare(eve->co, co, MOC_THRESH))
707                                         return (*bt)->index[a];
708                         }
709                 }
710                 else return -1;
711         }
712         if( (*bt)->next)
713                 return mesh_octree_find_index(&(*bt)->next, mvert, co);
714         
715         return -1;
716 }
717
718
719 /* mode is 's' start, or 'e' end, or 'u' use */
720 /* if end, ob can be NULL */
721 long mesh_octree_table(Object *ob, float *co, char mode)
722 {
723         MocNode **bt;
724         static MocNode **basetable= NULL;
725         static float offs[3], div[3];
726         
727         if(mode=='u') {         /* use table */
728                 if(basetable==NULL)
729                         mesh_octree_table(ob, NULL, 's');
730            
731                 if(basetable) {
732                         Mesh *me= ob->data;
733                         bt= basetable + mesh_octree_get_base_offs(co, offs, div);
734                         if(ob==G.obedit)
735                                 return mesh_octree_find_index(bt, NULL, co);
736                         else
737                                 return mesh_octree_find_index(bt, me->mvert, co);
738                 }
739                 return -1;
740         }
741         else if(mode=='s') {    /* start table */
742                 Mesh *me= ob->data;
743                 BoundBox *bb = mesh_get_bb(me);
744                 
745                 /* for quick unit coordinate calculus */
746                 VECCOPY(offs, bb->vec[0]);
747                 offs[0]-= MOC_THRESH;           /* we offset it 1 threshold unit extra */
748                 offs[1]-= MOC_THRESH;
749                 offs[2]-= MOC_THRESH;
750                         
751                 VecSubf(div, bb->vec[6], bb->vec[0]);
752                 div[0]+= 2*MOC_THRESH;          /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
753                 div[1]+= 2*MOC_THRESH;
754                 div[2]+= 2*MOC_THRESH;
755                 
756                 VecMulf(div, 1.0f/MOC_RES);
757                 if(div[0]==0.0f) div[0]= 1.0f;
758                 if(div[1]==0.0f) div[1]= 1.0f;
759                 if(div[2]==0.0f) div[2]= 1.0f;
760                         
761                 if(basetable) /* happens when entering this call without ending it */
762                         mesh_octree_table(ob, co, 'e');
763                 
764                 basetable= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
765                 
766                 if(ob==G.obedit) {
767                         EditVert *eve;
768                         
769                         for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
770                                 mesh_octree_add_nodes(basetable, eve->co, offs, div, (long)(eve));
771                         }
772                 }
773                 else {          
774                         MVert *mvert;
775                         long a;
776                         
777                         for(a=1, mvert= me->mvert; a<=me->totvert; a++, mvert++) {
778                                 mesh_octree_add_nodes(basetable, mvert->co, offs, div, a);
779                         }
780                 }
781         }
782         else if(mode=='e') { /* end table */
783                 if(basetable) {
784                         int a;
785                         
786                         for(a=0, bt=basetable; a<MOC_RES*MOC_RES*MOC_RES; a++, bt++) {
787                                 if(*bt) mesh_octree_free_node(bt);
788                         }
789                         MEM_freeN(basetable);
790                         basetable= NULL;
791                 }
792         }
793         return 0;
794 }
795
796 int mesh_get_x_mirror_vert(Object *ob, int index)
797 {
798         Mesh *me= ob->data;
799         MVert *mvert= me->mvert+index;
800         float vec[3];
801         
802         vec[0]= -mvert->co[0];
803         vec[1]= mvert->co[1];
804         vec[2]= mvert->co[2];
805         
806         return mesh_octree_table(ob, vec, 'u');
807 }
808
809 EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co)
810 {
811         float vec[3];
812         long poinval;
813         
814         vec[0]= -co[0];
815         vec[1]= co[1];
816         vec[2]= co[2];
817         
818         poinval= mesh_octree_table(ob, vec, 'u');
819         if(poinval != -1)
820                 return (EditVert *)(poinval);
821         return NULL;
822 }
823
824 static unsigned int mirror_facehash(void *ptr)
825 {
826         MFace *mf= ptr;
827         int v0, v1;
828
829         if(mf->v4) {
830                 v0= MIN4(mf->v1, mf->v2, mf->v3, mf->v4);
831                 v1= MAX4(mf->v1, mf->v2, mf->v3, mf->v4);
832         }
833         else {
834                 v0= MIN3(mf->v1, mf->v2, mf->v3);
835                 v1= MAX3(mf->v1, mf->v2, mf->v3);
836         }
837
838         return ((v0*39)^(v1*31));
839 }
840
841 static int mirror_facerotation(MFace *a, MFace *b)
842 {
843         if(b->v4) {
844                 if(a->v1==b->v1 && a->v2==b->v2 && a->v3==b->v3 && a->v4==b->v4)
845                         return 0;
846                 else if(a->v4==b->v1 && a->v1==b->v2 && a->v2==b->v3 && a->v3==b->v4)
847                         return 1;
848                 else if(a->v3==b->v1 && a->v4==b->v2 && a->v1==b->v3 && a->v2==b->v4)
849                         return 2;
850                 else if(a->v2==b->v1 && a->v3==b->v2 && a->v4==b->v3 && a->v1==b->v4)
851                         return 3;
852         }
853         else {
854                 if(a->v1==b->v1 && a->v2==b->v2 && a->v3==b->v3)
855                         return 0;
856                 else if(a->v3==b->v1 && a->v1==b->v2 && a->v2==b->v3)
857                         return 1;
858                 else if(a->v2==b->v1 && a->v3==b->v2 && a->v1==b->v3)
859                         return 2;
860         }
861         
862         return -1;
863 }
864
865 static int mirror_facecmp(void *a, void *b)
866 {
867         return (mirror_facerotation((MFace*)a, (MFace*)b) == -1);
868 }
869
870 int *mesh_get_x_mirror_faces(Object *ob)
871 {
872         Mesh *me= ob->data;
873         MVert *mv, *mvert= me->mvert;
874         MFace mirrormf, *mf, *hashmf, *mface= me->mface;
875         GHash *fhash;
876         int *mirrorverts, *mirrorfaces;
877         float vec[3];
878         int a;
879
880         mirrorverts= MEM_callocN(sizeof(int)*me->totvert, "MirrorVerts");
881         mirrorfaces= MEM_callocN(sizeof(int)*2*me->totface, "MirrorFaces");
882
883         mesh_octree_table(ob, NULL, 's');
884
885         for(a=0, mv=mvert; a<me->totvert; a++, mv++) {
886                 vec[0]= -mv->co[0];
887                 vec[1]= mv->co[1];
888                 vec[2]= mv->co[2];
889                 mirrorverts[a]= mesh_octree_table(ob, vec, 'u');
890         }
891
892         mesh_octree_table(ob, NULL, 'e');
893
894         fhash= BLI_ghash_new(mirror_facehash, mirror_facecmp);
895         for(a=0, mf=mface; a<me->totface; a++, mf++)
896                 BLI_ghash_insert(fhash, mf, mf);
897
898         for(a=0, mf=mface; a<me->totface; a++, mf++) {
899                 mirrormf.v1= mirrorverts[mf->v3];
900                 mirrormf.v2= mirrorverts[mf->v2];
901                 mirrormf.v3= mirrorverts[mf->v1];
902                 mirrormf.v4= (mf->v4)? mirrorverts[mf->v4]: 0;
903
904                 hashmf= BLI_ghash_lookup(fhash, &mirrormf);
905                 if(hashmf) {
906                         mirrorfaces[a*2]= hashmf - mface;
907                         mirrorfaces[a*2+1]= mirror_facerotation(&mirrormf, hashmf);
908                 }
909                 else
910                         mirrorfaces[a*2]= -1;
911         }
912
913         BLI_ghash_free(fhash, NULL, NULL);
914         MEM_freeN(mirrorverts);
915         
916         return mirrorfaces;
917 }
918
919 /* ****************** render BAKING ********************** */
920
921 /* threaded break test */
922 static volatile int g_break= 0;
923 static int thread_break(void)
924 {
925         return g_break;
926 }
927
928 static ScrArea *biggest_image_area(void)
929 {
930         ScrArea *sa, *big= NULL;
931         int size, maxsize= 0;
932         
933         for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
934                 if(sa->spacetype==SPACE_IMAGE) {
935                         size= sa->winx*sa->winy;
936                         if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
937                                 maxsize= size;
938                                 big= sa;
939                         }
940                 }
941         }
942         return big;
943 }
944
945
946 typedef struct BakeRender {
947         Render *re;
948         int event, tot, ready;
949 } BakeRender;
950
951 static void *do_bake_render(void *bake_v)
952 {
953         BakeRender *bkr= bake_v;
954         
955         bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event);
956         bkr->ready= 1;
957         
958         return NULL;
959 }
960
961
962 void objects_bake_render_menu(void)
963 {
964         short event;
965
966         event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4");
967         
968         objects_bake_render(event);
969 }
970
971 /* all selected meshes with UV maps are rendered for current scene visibility */
972 void objects_bake_render(short event)
973 {
974         short prev_r_raytrace= 0, prev_wo_amb_occ= 0;
975         
976         if(event==0) event= G.scene->r.bake_mode;
977         
978         if(G.scene->r.renderer!=R_INTERN) {      
979                 error("Bake only supported for Internal Renderer");      
980                 return;  
981         }        
982         
983         if(event>0) {
984                 Render *re= RE_NewRender("_Bake View_");
985                 ScrArea *area= biggest_image_area();
986                 ListBase threads;
987                 BakeRender bkr;
988                 int timer=0, tot, sculptmode= G.f & G_SCULPTMODE;
989                 
990                 if(sculptmode) set_sculptmode();
991                 
992                 if(event==1) event= RE_BAKE_ALL;
993                 else if(event==2) event= RE_BAKE_AO;
994                 else if(event==3) event= RE_BAKE_NORMALS;
995                 else event= RE_BAKE_TEXTURE;
996
997                 if(event==RE_BAKE_AO) {
998                         if(G.scene->world==NULL) {
999                                 error("No world set up");
1000                                 return;
1001                         }
1002
1003                         /* If raytracing or AO is disabled, switch it on temporarily for baking. */
1004                         prev_r_raytrace = (G.scene->r.mode & R_RAYTRACE) != 0;
1005                         prev_wo_amb_occ = (G.scene->world->mode & WO_AMB_OCC) != 0;
1006
1007                         G.scene->r.mode |= R_RAYTRACE;
1008                         G.scene->world->mode |= WO_AMB_OCC;
1009                 }
1010                 
1011                 waitcursor(1);
1012                 RE_test_break_cb(re, thread_break);
1013                 g_break= 0;
1014                 G.afbreek= 0;   /* blender_test_break uses this global */
1015                 
1016                 RE_Database_Baking(re, G.scene, event);
1017                 
1018                 /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
1019         
1020                 BLI_init_threads(&threads, do_bake_render, 1);
1021                 bkr.re= re;
1022                 bkr.event= event;
1023                 bkr.ready= 0;
1024                 BLI_insert_thread(&threads, &bkr);
1025                 
1026                 while(bkr.ready==0) {
1027                         PIL_sleep_ms(50);
1028                         if(bkr.ready)
1029                                 break;
1030                         
1031                         g_break= blender_test_break();
1032                         
1033                         timer++;
1034                         if(area && timer==20) {
1035                                 Image *ima= RE_bake_shade_get_image();
1036                                 if(ima) ((SpaceImage *)area->spacedata.first)->image= ima;
1037                                 scrarea_do_windraw(area);
1038                                 myswapbuffers();        
1039                                 timer= 0;
1040                         }
1041                 }
1042                 BLI_end_threads(&threads);
1043                 tot= bkr.tot;
1044                 
1045                 RE_Database_Free(re);
1046                 waitcursor(0);
1047                 
1048                 if(tot==0) error("No Images found to bake to");
1049                 else {
1050                         Image *ima;
1051                         /* force OpenGL reload */
1052                         for(ima= G.main->image.first; ima; ima= ima->id.next) {
1053                                 if(ima->ok==IMA_OK_LOADED) {
1054                                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1055                                         if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
1056                                                 free_realtime_image(ima); 
1057                                 }
1058                         }
1059                 }
1060                 
1061                         /* restore raytrace and AO */
1062                 if(event==RE_BAKE_AO) {
1063                         if( prev_wo_amb_occ == 0) G.scene->world->mode &= ~WO_AMB_OCC;
1064                         if( prev_r_raytrace == 0) G.scene->r.mode &= ~R_RAYTRACE;
1065                 }
1066                 
1067                 allqueue(REDRAWIMAGE, 0);
1068                 allqueue(REDRAWVIEW3D, 0);
1069                 
1070                 if(sculptmode) set_sculptmode();
1071                 
1072         }
1073 }
1074
1075