some small optimizations
[blender.git] / source / blender / blenkernel / intern / mesh.c
1
2 /*  mesh.c      MIXED MODEL
3  * 
4  *  jan/maart 95
5  *  
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version. The Blender
15  * Foundation also sells licenses for use in proprietary software under
16  * the Blender License.  See http://www.blender.org/BL/ for information
17  * about this.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37
38 #ifdef WIN32
39 #include "BLI_winstuff.h"
40 #endif
41
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <math.h>
46
47 #include "MEM_guardedalloc.h"
48
49 #include "DNA_ID.h"
50 #include "DNA_curve_types.h"
51 #include "DNA_material_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_image_types.h"
54 #include "DNA_key_types.h"
55 #include "DNA_mesh_types.h"
56
57 #include "BKE_main.h"
58 #include "BKE_global.h"
59 #include "BKE_mesh.h"
60 #include "BKE_subsurf.h"
61 #include "BKE_displist.h"
62 #include "BKE_library.h"
63 #include "BKE_material.h"
64 #include "BKE_key.h"
65 /* these 2 are only used by conversion functions */
66 #include "BKE_curve.h"
67 /* -- */
68 #include "BKE_object.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_bad_level_calls.h"
71
72 #include "BLI_blenlib.h"
73 #include "BLI_editVert.h"
74 #include "BLI_arithb.h"
75
76
77
78 int update_realtime_texture(TFace *tface, double time)
79 {
80         Image *ima;
81         int     inc = 0;
82         float   diff;
83         int     newframe;
84
85         ima = tface->tpage;
86
87         if (!ima)
88                 return 0;
89
90         if (ima->lastupdate<0)
91                 ima->lastupdate = 0;
92
93         if (ima->lastupdate>time)
94                 ima->lastupdate=(float)time;
95
96         if(ima->tpageflag & IMA_TWINANIM) {
97                 if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1;
98                 
99                 /* check: zit de bindcode niet het array? Vrijgeven. (nog doen) */
100                 
101                 diff = (float)(time-ima->lastupdate);
102
103                 inc = (int)(diff*(float)ima->animspeed);
104
105                 ima->lastupdate+=((float)inc/(float)ima->animspeed);
106
107                 newframe = ima->lastframe+inc;
108
109                 if (newframe > (int)ima->twend)
110                         newframe = (int)ima->twsta-1 + (newframe-ima->twend)%(ima->twend-ima->twsta);
111
112                 ima->lastframe = newframe;
113         }
114         return inc;
115 }
116
117 float get_mvert_weight (Object *ob, int vert, int defgroup)
118 {
119         int     i;
120         Mesh *me;
121         float   result;
122
123         me=ob->data;
124
125         if (!me->dvert)
126                 return 0.0F;
127
128         result=0.0F;
129
130         for (i=0; i<me->dvert[vert].totweight; i++){
131                 if (me->dvert[vert].dw[i].def_nr==defgroup)
132                         result+=me->dvert[vert].dw[i].weight;           
133         }
134
135         return result;
136 }
137
138 void unlink_mesh(Mesh *me)
139 {
140         int a;
141         
142         if(me==0) return;
143         
144         for(a=0; a<me->totcol; a++) {
145                 if(me->mat[a]) me->mat[a]->id.us--;
146                 me->mat[a]= 0;
147         }
148         if(me->key) me->key->id.us--;
149         me->key= 0;
150         
151         if(me->texcomesh) me->texcomesh= 0;
152 }
153
154
155 /* niet mesh zelf vrijgeven */
156 void free_mesh(Mesh *me)
157 {
158
159         unlink_mesh(me);
160
161         if(me->mat) MEM_freeN(me->mat);
162         if(me->orco) MEM_freeN(me->orco);
163         if(me->mface) MEM_freeN(me->mface);
164         if(me->tface) MEM_freeN(me->tface);
165         if(me->mvert) MEM_freeN(me->mvert);
166         if(me->dvert) free_dverts(me->dvert, me->totvert);
167         if(me->mcol) MEM_freeN(me->mcol);
168         if(me->msticky) MEM_freeN(me->msticky);
169         if(me->bb) MEM_freeN(me->bb);
170         if(me->disp.first) freedisplist(&me->disp);
171 }
172
173 void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
174 {
175         /* Assumes dst is already set up */
176         int i;
177
178         if (!src || !dst)
179                 return;
180
181         memcpy (dst, src, copycount * sizeof(MDeformVert));
182         
183         for (i=0; i<copycount; i++){
184                 if (src[i].dw){
185                         dst[i].dw = MEM_callocN (sizeof(MDeformWeight)*src[i].totweight, "copy_deformWeight");
186                         memcpy (dst[i].dw, src[i].dw, sizeof (MDeformWeight)*src[i].totweight);
187                 }
188         }
189
190 }
191 void free_dverts(MDeformVert *dvert, int totvert)
192 {
193         /* Instead of freeing the verts directly,
194         call this function to delete any special
195         vert data */
196         int     i;
197
198         if (!dvert)
199                 return;
200
201         /* Free any special data from the verts */
202         for (i=0; i<totvert; i++){
203                 if (dvert[i].dw) MEM_freeN (dvert[i].dw);
204         }
205         MEM_freeN (dvert);
206 }
207
208 Mesh *add_mesh()
209 {
210         Mesh *me;
211         
212         me= alloc_libblock(&G.main->mesh, ID_ME, "Mesh");
213         
214         me->size[0]= me->size[1]= me->size[2]= 1.0;
215         me->smoothresh= 30;
216         me->texflag= AUTOSPACE;
217         me->flag= ME_TWOSIDED;
218         me->subdiv= 1;
219         me->subdivr = 1;
220         me->bb= unit_boundbox();
221         
222         return me;
223 }
224
225 Mesh *copy_mesh(Mesh *me)
226 {
227         Mesh *men;
228         int a;
229         
230         men= copy_libblock(me);
231         
232         men->mat= MEM_dupallocN(me->mat);
233         for(a=0; a<men->totcol; a++) {
234                 id_us_plus((ID *)men->mat[a]);
235         }
236         id_us_plus((ID *)men->texcomesh);
237         men->mface= MEM_dupallocN(me->mface);
238
239         men->tface= MEM_dupallocN(me->tface);
240
241         men->dface= 0;
242         men->mvert= MEM_dupallocN(me->mvert);
243         memcpy (men->mvert, me->mvert, sizeof (MVert)*me->totvert);
244         if (me->dvert){
245                 men->dvert = MEM_mallocN (sizeof (MDeformVert)*me->totvert, "MDeformVert");
246                 copy_dverts(men->dvert, me->dvert, me->totvert);
247         }
248
249         men->mcol= MEM_dupallocN(me->mcol);
250         men->msticky= MEM_dupallocN(me->msticky);
251         men->texcomesh= 0;
252         men->orco= 0;
253         men->bb= MEM_dupallocN(men->bb);
254         
255         copy_displist(&men->disp, &me->disp);
256         
257         men->key= copy_key(me->key);
258         if(men->key) men->key->from= (ID *)men;
259         
260         return men;
261 }
262
263 void make_local_tface(Mesh *me)
264 {
265         TFace *tface;
266         Image *ima;
267         int a;
268         
269         if(me->tface==0) return;
270         
271         a= me->totface;
272         tface= me->tface;
273         while(a--) {
274                 
275                 /* speciaal geval: ima altijd meteen lokaal */
276                 if(tface->tpage) {
277                         ima= tface->tpage;
278                         if(ima->id.lib) {
279                                 ima->id.lib= 0;
280                                 ima->id.flag= LIB_LOCAL;
281                                 new_id(0, (ID *)ima, 0);
282                         }
283                 }
284                 tface++;
285         }
286         
287 }
288
289 void make_local_mesh(Mesh *me)
290 {
291         Object *ob;
292         Mesh *men;
293         int local=0, lib=0;
294         
295         /* - zijn er alleen lib users: niet doen
296          * - zijn er alleen locale users: flag zetten
297          * - mixed: copy
298          */
299         
300         if(me->id.lib==0) return;
301         if(me->id.us==1) {
302                 me->id.lib= 0;
303                 me->id.flag= LIB_LOCAL;
304                 new_id(0, (ID *)me, 0);
305                 
306                 if(me->tface) make_local_tface(me);
307                 
308                 return;
309         }
310         
311         ob= G.main->object.first;
312         while(ob) {
313                 if( me==get_mesh(ob) ) {
314                         if(ob->id.lib) lib= 1;
315                         else local= 1;
316                 }
317                 ob= ob->id.next;
318         }
319         
320         if(local && lib==0) {
321                 me->id.lib= 0;
322                 me->id.flag= LIB_LOCAL;
323                 new_id(0, (ID *)me, 0);
324                 
325                 if(me->tface) make_local_tface(me);
326                 
327         }
328         else if(local && lib) {
329                 men= copy_mesh(me);
330                 men->id.us= 0;
331                 
332                 ob= G.main->object.first;
333                 while(ob) {
334                         if( me==get_mesh(ob) ) {                                
335                                 if(ob->id.lib==0) {
336                                         set_mesh(ob, men);
337                                 }
338                         }
339                         ob= ob->id.next;
340                 }
341         }
342 }
343
344 void boundbox_mesh(Mesh *me, float *loc, float *size)
345 {
346         MVert *mvert;
347         BoundBox *bb;
348         float min[3], max[3];
349         float mloc[3], msize[3];
350         int a;
351         
352         if(me->bb==0) me->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
353         bb= me->bb;
354         
355         INIT_MINMAX(min, max);
356
357         if (!loc) loc= mloc;
358         if (!size) size= msize;
359         
360         mvert= me->mvert;
361         for(a=0; a<me->totvert; a++, mvert++) {
362                 DO_MINMAX(mvert->co, min, max);
363         }
364
365         if(me->totvert) {
366                 loc[0]= (min[0]+max[0])/2.0f;
367                 loc[1]= (min[1]+max[1])/2.0f;
368                 loc[2]= (min[2]+max[2])/2.0f;
369                 
370                 size[0]= (max[0]-min[0])/2.0f;
371                 size[1]= (max[1]-min[1])/2.0f;
372                 size[2]= (max[2]-min[2])/2.0f;
373         }
374         else {
375                 loc[0]= loc[1]= loc[2]= 0.0;
376                 size[0]= size[1]= size[2]= 0.0;
377         }
378         
379         bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
380         bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
381         
382         bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
383         bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
384
385         bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
386         bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
387 }
388
389 void tex_space_mesh(Mesh *me)
390 {
391         KeyBlock *kb;
392         float *fp, loc[3], size[3], min[3], max[3];
393         int a;
394
395         boundbox_mesh(me, loc, size);
396
397         if(me->texflag & AUTOSPACE) {
398                 if(me->key) {
399                         kb= me->key->refkey;
400                         if (kb) {
401                                 
402                                 INIT_MINMAX(min, max);
403                                 
404                                 fp= kb->data;
405                                 for(a=0; a<kb->totelem; a++, fp+=3) {   
406                                         DO_MINMAX(fp, min, max);
407                                 }
408                                 if(kb->totelem) {
409                                         loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f;
410                                         size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f;
411                                 }
412                                 else {
413                                         loc[0]= loc[1]= loc[2]= 0.0;
414                                         size[0]= size[1]= size[2]= 0.0;
415                                 }
416                                 
417                         }
418                 }
419
420                 VECCOPY(me->loc, loc);
421                 VECCOPY(me->size, size);
422                 me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
423
424                 if(me->size[0]==0.0) me->size[0]= 1.0;
425                 else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
426                 else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
427         
428                 if(me->size[1]==0.0) me->size[1]= 1.0;
429                 else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
430                 else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
431         
432                 if(me->size[2]==0.0) me->size[2]= 1.0;
433                 else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
434                 else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
435         }
436         
437 }
438
439 void make_orco_displist_mesh(Object *ob, int subdivlvl)
440 {
441         Mesh *me;
442         DispList *dl;
443         DispListMesh *dlm;
444         int i;
445         
446         me= ob->data;
447
448                 /* if there's a key, set the first one */
449         if(me->key && me->texcomesh==0) {
450                 cp_key(0, me->totvert, me->totvert, (char*) me->mvert->co, me->key, me->key->refkey, 0);
451         }
452
453                 /* Rebuild the displist */
454         dl= subsurf_mesh_to_displist(me, NULL, (short)subdivlvl);
455         
456                 /* Restore correct key */
457         do_ob_key(ob);
458
459                 /* XXX Assume dl is a DL_MESH (it is), 
460                  * should be explicit -zr 
461                  */
462         dlm= dl->mesh;
463         
464         me->orco= MEM_mallocN(dlm->totvert*3*sizeof(float), "mesh displist orco");
465                 
466         for(i=0; i<dlm->totvert; i++) {
467                 float *fp= &me->orco[i*3];
468
469                 VECCOPY(fp, dlm->mvert[i].co);
470
471                 fp[0]= (fp[0]-me->loc[0])/me->size[0];
472                 fp[1]= (fp[1]-me->loc[1])/me->size[1];
473                 fp[2]= (fp[2]-me->loc[2])/me->size[2];
474         }
475         
476         free_disp_elem(dl);
477 }
478
479 void make_orco_mesh(Mesh *me)
480 {
481         MVert *mvert;
482         KeyBlock *kb;
483         float *orco, *fp;
484         int a, totvert;
485         
486         totvert= me->totvert;
487         if(totvert==0) return;
488         orco= me->orco= MEM_mallocN(sizeof(float)*3*totvert, "orco mesh");
489
490         if(me->key && me->texcomesh==0) {
491                 kb= me->key->refkey;
492                 if (kb) {               /***** BUG *****/
493                         fp= kb->data;
494                         
495                         for(a=0; a<totvert; a++, orco+=3) {
496                                 orco[0]= (fp[0]-me->loc[0])/me->size[0];
497                                 orco[1]= (fp[1]-me->loc[1])/me->size[1];
498                                 orco[2]= (fp[2]-me->loc[2])/me->size[2];
499                                 
500                                 /* mvert alleen ophogen als totvert <= kb->totelem */
501                                 if(a<kb->totelem) fp+=3;
502                         }
503                 }
504         }
505         else {
506                 if(me->texcomesh) {
507                         me= me->texcomesh;
508                 }       
509         
510                 mvert= me->mvert;
511                 for(a=0; a<totvert; a++, orco+=3) {
512                         orco[0]= (mvert->co[0]-me->loc[0])/me->size[0];
513                         orco[1]= (mvert->co[1]-me->loc[1])/me->size[1];
514                         orco[2]= (mvert->co[2]-me->loc[2])/me->size[2];
515                         
516                         /* mvert alleen ophogen als totvert <= me->totvert */
517                         if(a<me->totvert) mvert++;
518                 }
519         }
520 }
521
522 /** rotates the vertices of a face in case v[2] or v[3] (vertex index)
523   * is = 0.
524   * Helaas, the MFace structure has no pointer to its
525   * texture face, therefore, texture can not be fixed inside
526   * this function. 
527   * 
528   * see also blender/src/editmesh.c, fix_faceindices()
529
530   * THIS FUNCTION WILL BE DINOSOURCE. For the moment, another hack
531         is added to fix texture coordinates / vertex colors:
532
533         void test_index_face(MFace *mface, TFace *tface, int nr)
534   */
535
536 void test_index_mface(MFace *mface, int nr)
537 {
538         int a;
539
540         
541         /* first test if the face is legal */
542
543         if(mface->v3 && mface->v3==mface->v4) {
544                 mface->v4= 0;
545                 nr--;
546         }
547         if(mface->v2 && mface->v2==mface->v3) {
548                 mface->v3= mface->v4;
549                 mface->v4= 0;
550                 nr--;
551         }
552         if(mface->v1==mface->v2) {
553                 mface->v2= mface->v3;
554                 mface->v3= mface->v4;
555                 mface->v4= 0;
556                 nr--;
557         }
558
559         /* voorkom dat een nul op de verkeerde plek staat */
560         if(nr==2) {
561                 if(mface->v2==0) SWAP(int, mface->v1, mface->v2);
562         }
563         else if(nr==3) {
564                 if(mface->v3==0) {
565                         SWAP(int, mface->v1, mface->v2);
566                         SWAP(int, mface->v2, mface->v3);
567                         
568                         a= mface->edcode;
569                         mface->edcode= 0;
570                         if(a & ME_V1V2) mface->edcode |= ME_V3V1;
571                         if(a & ME_V2V3) mface->edcode |= ME_V1V2;
572                         if(a & ME_V3V1) mface->edcode |= ME_V2V3;
573                         
574                         a= mface->puno;
575                         mface->puno &= ~15;
576                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2;
577                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3;
578                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
579                 }
580         }
581         else if(nr==4) {
582                 if(mface->v3==0 || mface->v4==0) {
583                         SWAP(int, mface->v1, mface->v3);
584                         SWAP(int, mface->v2, mface->v4);
585                         a= mface->edcode;
586                         mface->edcode= 0;
587                         if(a & ME_V1V2) mface->edcode |= ME_V3V4;
588                         if(a & ME_V2V3) mface->edcode |= ME_V2V3;
589                         if(a & ME_V3V4) mface->edcode |= ME_V1V2;
590                         if(a & ME_V4V1) mface->edcode |= ME_V4V1;
591
592                         a= mface->puno;
593                         mface->puno &= ~15;
594                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3;
595                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4;
596                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
597                         if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2;
598                 }
599         }
600 }
601
602 /**     This function should die as soon as there is another mesh
603         structure. Functionality is the same as
604
605                 void test_index_mface()
606
607         but it fixes texture coordinates as well.
608 */
609
610 #define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
611 void test_index_face(MFace *mface, TFace *tface, int nr)
612 {
613         int a;
614         float tmpuv[2];
615         unsigned int tmpcol;
616
617
618         /* first test if the face is legal */
619
620         if(mface->v3 && mface->v3==mface->v4) {
621                 mface->v4= 0;
622                 nr--;
623         }
624         if(mface->v2 && mface->v2==mface->v3) {
625                 mface->v3= mface->v4;
626                 mface->v4= 0;
627                 nr--;
628         }
629         if(mface->v1==mface->v2) {
630                 mface->v2= mface->v3;
631                 mface->v3= mface->v4;
632                 mface->v4= 0;
633                 nr--;
634         }
635
636         /* voorkom dat een nul op de verkeerde plek staat */
637         if(nr==2) {
638                 if(mface->v2==0) SWAP(int, mface->v1, mface->v2);
639         }
640         else if(nr==3) {
641                 if(mface->v3==0) {
642                         SWAP(int, mface->v1, mface->v2);
643                         SWAP(int, mface->v2, mface->v3);
644                         /* rotate face UV coordinates, too */
645                         UVCOPY(tmpuv, tface->uv[0]);
646                         UVCOPY(tface->uv[0], tface->uv[1]);
647                         UVCOPY(tface->uv[1], tface->uv[2]);
648                         UVCOPY(tface->uv[2], tmpuv);
649                         /* same with vertex colours */
650                         tmpcol = tface->col[0];
651                         tface->col[0] = tface->col[1];
652                         tface->col[1] = tface->col[2];
653                         tface->col[2] = tmpcol;
654
655                         
656                         a= mface->edcode;
657                         mface->edcode= 0;
658                         if(a & ME_V1V2) mface->edcode |= ME_V3V1;
659                         if(a & ME_V2V3) mface->edcode |= ME_V1V2;
660                         if(a & ME_V3V1) mface->edcode |= ME_V2V3;
661                         
662                         a= mface->puno;
663                         mface->puno &= ~15;
664                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2;
665                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3;
666                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
667                 }
668         }
669         else if(nr==4) {
670                 if(mface->v3==0 || mface->v4==0) {
671                         SWAP(int, mface->v1, mface->v3);
672                         SWAP(int, mface->v2, mface->v4);
673                         /* swap UV coordinates */
674                         UVCOPY(tmpuv, tface->uv[0]);
675                         UVCOPY(tface->uv[0], tface->uv[2]);
676                         UVCOPY(tface->uv[2], tmpuv);
677                         UVCOPY(tmpuv, tface->uv[1]);
678                         UVCOPY(tface->uv[1], tface->uv[3]);
679                         UVCOPY(tface->uv[3], tmpuv);
680                         /* swap vertex colours */
681                         tmpcol = tface->col[0];
682                         tface->col[0] = tface->col[2];
683                         tface->col[2] = tmpcol;
684                         tmpcol = tface->col[1];
685                         tface->col[1] = tface->col[3];
686                         tface->col[3] = tmpcol;
687
688                         a= mface->edcode;
689                         mface->edcode= 0;
690                         if(a & ME_V1V2) mface->edcode |= ME_V3V4;
691                         if(a & ME_V2V3) mface->edcode |= ME_V2V3;
692                         if(a & ME_V3V4) mface->edcode |= ME_V1V2;
693                         if(a & ME_V4V1) mface->edcode |= ME_V4V1;
694
695                         a= mface->puno;
696                         mface->puno &= ~15;
697                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3;
698                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4;
699                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
700                         if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2;
701                 }
702         }
703 }
704
705 void flipnorm_mesh(Mesh *me)
706 {
707         MFace *mface;
708         MVert *mvert;
709         DispList *dl;
710         float *fp;
711         int a, temp;
712         
713         mvert= me->mvert;
714         a= me->totvert;
715         while(a--) {
716                 mvert->no[0]= -mvert->no[0];
717                 mvert->no[1]= -mvert->no[1];
718                 mvert->no[2]= -mvert->no[2];
719                 mvert++;
720         }
721         
722         mface= me->mface;
723         a= me->totface;
724         while(a--) {
725                 if(mface->v3) {
726                         if(mface->v4) {
727                                 SWAP(int, mface->v4, mface->v1);
728                                 SWAP(int, mface->v3, mface->v2);
729                                 test_index_mface(mface, 4);
730                                 temp= mface->puno;
731                                 mface->puno &= ~15;
732                                 if(temp & ME_FLIPV1) mface->puno |= ME_FLIPV4;
733                                 if(temp & ME_FLIPV2) mface->puno |= ME_FLIPV3;
734                                 if(temp & ME_FLIPV3) mface->puno |= ME_FLIPV2;
735                                 if(temp & ME_FLIPV4) mface->puno |= ME_FLIPV1;
736                         }
737                         else {
738                                 SWAP(int, mface->v3, mface->v1);
739                                 test_index_mface(mface, 3);
740                                 temp= mface->puno;
741                                 mface->puno &= ~15;
742                                 if(temp & ME_FLIPV1) mface->puno |= ME_FLIPV3;
743                                 if(temp & ME_FLIPV2) mface->puno |= ME_FLIPV2;
744                                 if(temp & ME_FLIPV3) mface->puno |= ME_FLIPV1;
745                         }
746                 }
747                 mface++;
748         }
749
750         if(me->disp.first) {
751                 dl= me->disp.first;
752                 fp= dl->nors;
753                 if(fp) {
754                         a= dl->nr;
755                         while(a--) {
756                                 fp[0]= -fp[0];
757                                 fp[1]= -fp[1];
758                                 fp[2]= -fp[2];
759                                 fp+= 3;
760                         }
761                 }
762         }
763 }
764
765 Mesh *get_mesh(Object *ob)
766 {
767         
768         if(ob==0) return 0;
769         if(ob->type==OB_MESH) return ob->data;
770         else return 0;
771 }
772
773 void set_mesh(Object *ob, Mesh *me)
774 {
775         Mesh *old=0;
776         
777         if(ob==0) return;
778         
779         if(ob->type==OB_MESH) {
780                 old= ob->data;
781                 old->id.us--;
782                 ob->data= me;
783                 id_us_plus((ID *)me);
784         }
785         
786         test_object_materials((ID *)me);
787 }
788
789 void mball_to_mesh(ListBase *lb, Mesh *me)
790 {
791         DispList *dl;
792         MVert *mvert;
793         MFace *mface;
794         float *nors, *verts;
795         int a, *index;
796         
797         dl= lb->first;
798         if(dl==0) return;
799
800         if(dl->type==DL_INDEX4) {
801                 me->flag= ME_NOPUNOFLIP;
802                 me->totvert= dl->nr;
803                 me->totface= dl->parts;
804                 
805                 me->mvert=mvert= MEM_callocN(dl->nr*sizeof(MVert), "mverts");
806                 a= dl->nr;
807                 nors= dl->nors;
808                 verts= dl->verts;
809                 while(a--) {
810                         VECCOPY(mvert->co, verts);
811                         mvert->no[0]= (short int)(nors[0]*32767.0);
812                         mvert->no[1]= (short int)(nors[1]*32767.0);
813                         mvert->no[2]= (short int)(nors[2]*32767.0);
814                         mvert++;
815                         nors+= 3;
816                         verts+= 3;
817                 }
818                 
819                 me->mface=mface= MEM_callocN(dl->parts*sizeof(MFace), "mface");
820                 a= dl->parts;
821                 index= dl->index;
822                 while(a--) {
823                         mface->v1= index[0];
824                         mface->v2= index[1];
825                         mface->v3= index[2];
826                         mface->v4= index[3];
827
828                         mface->puno= 0;
829                         mface->edcode= ME_V1V2+ME_V2V3;
830                         mface->flag = ME_SMOOTH;
831                         
832                         mface++;
833                         index+= 4;
834                 }
835         }       
836 }
837
838 void nurbs_to_mesh(Object *ob)
839 {
840         Object *ob1;
841         DispList *dl;
842         Mesh *me;
843         Curve *cu;
844         MVert *mvert;
845         MFace *mface;
846         float *data;
847         int a, b, ofs, vertcount, startvert, totvert=0, totvlak=0;
848         int p1, p2, p3, p4, *index;
849
850         cu= ob->data;
851
852         if(ob->type==OB_CURVE) {
853                 /* regel: dl->type INDEX3 altijd vooraan in lijst */
854                 dl= cu->disp.first;
855                 if(dl->type!=DL_INDEX3) {
856                         curve_to_filledpoly(ob->data, &cu->disp);
857                 }
858         }
859
860         /* tellen */
861         dl= cu->disp.first;
862         while(dl) {
863                 if(dl->type==DL_SEGM) {
864                         totvert+= dl->parts*dl->nr;
865                         totvlak+= dl->parts*(dl->nr-1);
866                 }
867                 else if(dl->type==DL_POLY) {
868                         /* cyclic polys are filled. except when 3D */
869                         if(cu->flag & CU_3D) {
870                                 totvert+= dl->parts*dl->nr;
871                                 totvlak+= dl->parts*dl->nr;
872                         }
873                 }
874                 else if(dl->type==DL_SURF) {
875                         totvert+= dl->parts*dl->nr;
876                         totvlak+= (dl->parts-1+((dl->flag & 2)==2))*(dl->nr-1+(dl->flag & 1));
877                 }
878                 else if(dl->type==DL_INDEX3) {
879                         totvert+= dl->nr;
880                         totvlak+= dl->parts;
881                 }
882                 dl= dl->next;
883         }
884         if(totvert==0) {
885                 error("can't convert");
886                 return;
887         }
888
889         /* mesh maken */
890         me= add_mesh();
891         me->totvert= totvert;
892         me->totface= totvlak;
893
894         me->totcol= cu->totcol;
895         me->mat= cu->mat;
896         cu->mat= 0;
897         cu->totcol= 0;
898
899         mvert=me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "cumesh1");
900         mface=me->mface= MEM_callocN(me->totface*sizeof(MFace), "cumesh2");
901
902         /* verts en vlakken */
903         vertcount= 0;
904
905         dl= cu->disp.first;
906         while(dl) {
907                 if(dl->type==DL_SEGM) {
908                         startvert= vertcount;
909                         a= dl->parts*dl->nr;
910                         data= dl->verts;
911                         while(a--) {
912                                 VECCOPY(mvert->co, data);
913                                 data+=3;
914                                 vertcount++;
915                                 mvert++;
916                         }
917
918                         for(a=0; a<dl->parts; a++) {
919                                 ofs= a*dl->nr;
920                                 for(b=1; b<dl->nr; b++) {
921                                         mface->v1= startvert+ofs+b-1;
922                                         mface->v2= startvert+ofs+b;
923                                         mface->edcode= ME_V1V2;
924                                         test_index_mface(mface, 2);
925                                         mface++;
926                                 }
927                         }
928
929                 }
930                 else if(dl->type==DL_POLY) {
931                         /* cyclic polys are filled */
932                         /* startvert= vertcount;
933                         a= dl->parts*dl->nr;
934                         data= dl->verts;
935                         while(a--) {
936                                 VECCOPY(mvert->co, data);
937                                 data+=3;
938                                 vertcount++;
939                                 mvert++;
940                         }
941
942                         for(a=0; a<dl->parts; a++) {
943                                 ofs= a*dl->nr;
944                                 for(b=0; b<dl->nr; b++) {
945                                         mface->v1= startvert+ofs+b;
946                                         if(b==dl->nr-1) mface->v2= startvert+ofs;
947                                         else mface->v2= startvert+ofs+b+1;
948                                         mface->edcode= ME_V1V2;
949                                         test_index_mface(mface, 2);
950                                         mface++;
951                                 }
952                         }
953                         */
954                 }
955                 else if(dl->type==DL_INDEX3) {
956                         startvert= vertcount;
957                         a= dl->nr;
958                         data= dl->verts;
959                         while(a--) {
960                                 VECCOPY(mvert->co, data);
961                                 data+=3;
962                                 vertcount++;
963                                 mvert++;
964                         }
965
966                         a= dl->parts;
967                         index= dl->index;
968                         while(a--) {
969                                 mface->v1= startvert+index[0];
970                                 mface->v2= startvert+index[1];
971                                 mface->v3= startvert+index[2];
972                                 mface->v4= 0;
973         
974                                 mface->puno= 7;
975                                 mface->edcode= ME_V1V2+ME_V2V3;
976                                 test_index_mface(mface, 3);
977                                 
978                                 mface++;
979                                 index+= 3;
980                         }
981         
982         
983                 }
984                 else if(dl->type==DL_SURF) {
985                         startvert= vertcount;
986                         a= dl->parts*dl->nr;
987                         data= dl->verts;
988                         while(a--) {
989                                 VECCOPY(mvert->co, data);
990                                 data+=3;
991                                 vertcount++;
992                                 mvert++;
993                         }
994
995                         for(a=0; a<dl->parts; a++) {
996
997                                 if( (dl->flag & 2)==0 && a==dl->parts-1) break;
998
999                                 if(dl->flag & 1) {                              /* p2 -> p1 -> */
1000                                         p1= startvert+ dl->nr*a;        /* p4 -> p3 -> */
1001                                         p2= p1+ dl->nr-1;                       /* -----> volgende rij */
1002                                         p3= p1+ dl->nr;
1003                                         p4= p2+ dl->nr;
1004                                         b= 0;
1005                                 }
1006                                 else {
1007                                         p2= startvert+ dl->nr*a;
1008                                         p1= p2+1;
1009                                         p4= p2+ dl->nr;
1010                                         p3= p1+ dl->nr;
1011                                         b= 1;
1012                                 }
1013                                 if( (dl->flag & 2) && a==dl->parts-1) {
1014                                         p3-= dl->parts*dl->nr;
1015                                         p4-= dl->parts*dl->nr;
1016                                 }
1017
1018                                 for(; b<dl->nr; b++) {
1019                                         mface->v1= p1;
1020                                         mface->v2= p3;
1021                                         mface->v3= p4;
1022                                         mface->v4= p2;
1023                                         mface->mat_nr= (unsigned char)dl->col;
1024                                         mface->edcode= ME_V1V2+ME_V2V3;
1025                                         test_index_mface(mface, 4);
1026                                         mface++;
1027
1028                                         p4= p3; 
1029                                         p3++;
1030                                         p2= p1; 
1031                                         p1++;
1032                                 }
1033                         }
1034
1035                 }
1036
1037                 dl= dl->next;
1038         }
1039
1040         if(ob->data) {
1041                 free_libblock(&G.main->curve, ob->data);
1042         }
1043         ob->data= me;
1044         ob->type= OB_MESH;
1045         
1046         tex_space_mesh(me);
1047         
1048         /* andere users */
1049         ob1= G.main->object.first;
1050         while(ob1) {
1051                 if(ob1->data==cu) {
1052                         ob1->type= OB_MESH;
1053                 
1054                         ob1->data= ob->data;
1055                         id_us_plus((ID *)ob->data);
1056                 }
1057                 ob1= ob1->id.next;
1058         }
1059
1060 }
1061
1062 void edge_drawflags_mesh(Mesh *me)
1063 {
1064         MFace *mface;
1065         int a;
1066         
1067         mface= me->mface;
1068         for(a=0; a<me->totface; a++, mface++) {
1069                 mface->edcode= ME_V1V2|ME_V2V3|ME_V3V4|ME_V4V1;
1070         }
1071 }
1072
1073 void tface_to_mcol(Mesh *me)
1074 {
1075         TFace *tface;
1076         unsigned int *mcol;
1077         int a;
1078         
1079         me->mcol= MEM_mallocN(4*sizeof(int)*me->totface, "nepmcol");
1080         mcol= (unsigned int *)me->mcol;
1081         
1082         a= me->totface;
1083         tface= me->tface;
1084         while(a--) {
1085                 memcpy(mcol, tface->col, 16);
1086                 mcol+= 4;
1087                 tface++;
1088         }
1089 }
1090
1091 void mcol_to_tface(Mesh *me, int freedata)
1092 {
1093         TFace *tface;
1094         unsigned int *mcol;
1095         int a;
1096         
1097         a= me->totface;
1098         tface= me->tface;
1099         mcol= (unsigned int *)me->mcol;
1100         while(a--) {
1101                 memcpy(tface->col, mcol, 16);
1102                 mcol+= 4;
1103                 tface++;
1104         }
1105         
1106         if(freedata) {
1107                 MEM_freeN(me->mcol);
1108                 me->mcol= 0;
1109         }
1110 }
1111
1112 int mesh_uses_displist(Mesh *me) {
1113         return (me->flag&ME_SUBSURF && (me->subdiv>0));
1114 }
1115
1116 int rendermesh_uses_displist(Mesh *me) {
1117         return (me->flag&ME_SUBSURF);
1118 }