edits ontop of Alex's patch from r41292.
[blender.git] / source / blender / blenkernel / intern / mesh.c
index 7302abe..5c7d927 100644 (file)
@@ -1,10 +1,4 @@
-
-/*  mesh.c
- *
- *  
- * 
- * $Id$
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -236,6 +230,8 @@ Mesh *copy_mesh(Mesh *me)
        }
        
        men->mselect= NULL;
+       men->edit_mesh= NULL;
+       men->pv= NULL; /* looks like this is no-longer supported but NULL just incase */
 
        men->bb= MEM_dupallocN(men->bb);
        
@@ -245,83 +241,71 @@ Mesh *copy_mesh(Mesh *me)
        return men;
 }
 
-void make_local_tface(Mesh *me)
+static void expand_local_mesh(Mesh *me)
 {
-       MTFace *tface;
-       Image *ima;
-       int a, i;
-       
-       for(i=0; i<me->fdata.totlayer; i++) {
-               if(me->fdata.layers[i].type == CD_MTFACE) {
-                       tface= (MTFace*)me->fdata.layers[i].data;
-                       
-                       for(a=0; a<me->totface; a++, tface++) {
-                               /* special case: ima always local immediately */
-                               if(tface->tpage) {
-                                       ima= tface->tpage;
-                                       if(ima->id.lib) {
-                                               ima->id.lib= NULL;
-                                               ima->id.flag= LIB_LOCAL;
-                                               new_id(NULL, (ID *)ima, NULL);
+       id_lib_extern((ID *)me->texcomesh);
+
+       if(me->mtface) {
+               MTFace *tface;
+               int a, i;
+
+               for(i=0; i<me->fdata.totlayer; i++) {
+                       if(me->fdata.layers[i].type == CD_MTFACE) {
+                               tface= (MTFace*)me->fdata.layers[i].data;
+
+                               for(a=0; a<me->totface; a++, tface++) {
+                                       if(tface->tpage) {
+                                               id_lib_extern((ID *)tface->tpage);
                                        }
                                }
                        }
                }
        }
+
+       if(me->mat) {
+               extern_local_matarar(me->mat, me->totcol);
+       }
 }
 
 void make_local_mesh(Mesh *me)
 {
        Main *bmain= G.main;
        Object *ob;
-       Mesh *men;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-               * - only local users: set flag
-               * - mixed: make copy
-               */
-       
+        * - only local users: set flag
+        * - mixed: make copy
+        */
+
        if(me->id.lib==NULL) return;
        if(me->id.us==1) {
-               me->id.lib= NULL;
-               me->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)me, NULL);
-               
-               if(me->mtface) make_local_tface(me);
-               
+               id_clear_lib_data(bmain, (ID *)me);
+               expand_local_mesh(me);
                return;
        }
-       
-       ob= bmain->object.first;
-       while(ob) {
-               if( me==get_mesh(ob) ) {
+
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+               if(me == ob->data) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
-       
+
        if(local && lib==0) {
-               me->id.lib= NULL;
-               me->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)me, NULL);
-               
-               if(me->mtface) make_local_tface(me);
-               
+               id_clear_lib_data(bmain, (ID *)me);
+               expand_local_mesh(me);
        }
        else if(local && lib) {
-               men= copy_mesh(me);
+               Mesh *men= copy_mesh(me);
                men->id.us= 0;
-               
-               ob= bmain->object.first;
-               while(ob) {
-                       if( me==get_mesh(ob) ) {                                
+
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
+                       if(me == ob->data) {
                                if(ob->id.lib==NULL) {
                                        set_mesh(ob, men);
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
@@ -835,7 +819,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
        }
 
        *allvert= mvert= MEM_callocN(sizeof (MVert) * totvert, "nurbs_init mvert");
-       *allface= mface= MEM_callocN(sizeof (MVert) * totvlak, "nurbs_init mface");
+       *allface= mface= MEM_callocN(sizeof (MFace) * totvlak, "nurbs_init mface");
 
        /* verts and faces */
        vertcount= 0;
@@ -908,7 +892,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
                                mface->v2= startvert+index[2];
                                mface->v3= startvert+index[1];
                                mface->v4= 0;
-                               mface->mat_nr= (unsigned char)dl->col;
+                               mface->mat_nr= dl->col;
                                test_index_face(mface, NULL, 0, 3);
 
                                if(smooth) mface->flag |= ME_SMOOTH;
@@ -957,7 +941,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
                                        mface->v2= p3;
                                        mface->v3= p4;
                                        mface->v4= p2;
-                                       mface->mat_nr= (unsigned char)dl->col;
+                                       mface->mat_nr= dl->col;
                                        test_index_face(mface, NULL, 0, 4);
 
                                        if(smooth) mface->flag |= ME_SMOOTH;
@@ -1243,12 +1227,12 @@ void mesh_to_curve(Scene *scene, Object *ob)
        }
 }
 
-void mesh_delete_material_index(Mesh *me, int index)
+void mesh_delete_material_index(Mesh *me, short index)
 {
+       MFace *mf;
        int i;
 
-       for (i=0; i<me->totface; i++) {
-               MFace *mf = &((MFace*) me->mface)[i];
+       for (i=0, mf=me->mface; i<me->totface; i++, mf++) {
                if (mf->mat_nr && mf->mat_nr>=index) 
                        mf->mat_nr--;
        }
@@ -1277,59 +1261,20 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces,
        float (*tnorms)[3]= MEM_callocN(numVerts*sizeof(*tnorms), "tnorms");
        float (*fnors)[3]= (faceNors_r)? faceNors_r: MEM_callocN(sizeof(*fnors)*numFaces, "meshnormals");
        int i;
-       int found_flat=0;
 
        for(i=0; i<numFaces; i++) {
                MFace *mf= &mfaces[i];
                float *f_no= fnors[i];
+               float *n4 = (mf->v4)? tnorms[mf->v4]: NULL;
+               float *c4 = (mf->v4)? mverts[mf->v4].co: NULL;
 
                if(mf->v4)
                        normal_quad_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, mverts[mf->v4].co);
                else
                        normal_tri_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
 
-               if(mf->flag & ME_SMOOTH) {
-                       float *n4 = (mf->v4)? tnorms[mf->v4]: NULL;
-                       float *c4 = (mf->v4)? mverts[mf->v4].co: NULL;
-
-                       accumulate_vertex_normals(tnorms[mf->v1], tnorms[mf->v2], tnorms[mf->v3], n4,
-                               f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, c4);
-               }
-               else {
-                       found_flat=1;
-               }
-       }
-
-       /* build smooth normals for uninitialized normals at faces set to flat */
-       /* For such faces the renderer/3Dview and exporters will be using the face normal */
-       /* The vertex normals built inside this if-statement are entirely to support the needs of the modeler */
-       if(found_flat!=0) {
-               const int nr_bits= sizeof(int)*8;
-               const int nr_words= (numVerts+(nr_bits-1))/nr_bits;
-               int *bit_array= (int*)MEM_callocN(sizeof(int)*MAX2(nr_words, 1), "temp buffer");
-
-               for(i=0; i<numFaces; i++) {
-                       MFace *mf= &mfaces[i];
-
-                       if(!(mf->flag & ME_SMOOTH)) {
-                               if(is_zero_v3(tnorms[mf->v1])) bit_array[mf->v1/nr_bits]|=(1<<(mf->v1&(nr_bits-1)));
-                               if(is_zero_v3(tnorms[mf->v2])) bit_array[mf->v2/nr_bits]|=(1<<(mf->v2&(nr_bits-1)));
-                               if(is_zero_v3(tnorms[mf->v3])) bit_array[mf->v3/nr_bits]|=(1<<(mf->v3&(nr_bits-1)));
-                               if(mf->v4 && is_zero_v3(tnorms[mf->v4])) bit_array[mf->v4/nr_bits]|=(1<<(mf->v4&(nr_bits-1)));
-                       }
-               }
-
-               for(i=0; i<numFaces; i++) {
-                       MFace *mf= &mfaces[i];
-                       float *f_no= fnors[i];
-
-                       if(bit_array[mf->v1/nr_bits]&(1<<(mf->v1&(nr_bits-1)))) add_v3_v3(tnorms[mf->v1], f_no);
-                       if(bit_array[mf->v2/nr_bits]&(1<<(mf->v2&(nr_bits-1)))) add_v3_v3(tnorms[mf->v2], f_no);
-                       if(bit_array[mf->v3/nr_bits]&(1<<(mf->v3&(nr_bits-1)))) add_v3_v3(tnorms[mf->v3], f_no);
-                       if(mf->v4 && bit_array[mf->v4/nr_bits]&(1<<(mf->v4&(nr_bits-1)))) add_v3_v3(tnorms[mf->v4], f_no);
-               }
-
-               MEM_freeN(bit_array);
+               accumulate_vertex_normals(tnorms[mf->v1], tnorms[mf->v2], tnorms[mf->v3], n4,
+                       f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, c4);
        }
 
        /* following Mesh convention; we use vertex coordinate itself for normal in this case */
@@ -1502,7 +1447,7 @@ void create_vert_edge_map(ListBase **map, IndexNode **mem, const MEdge *medge, c
        (*map) = MEM_callocN(sizeof(ListBase) * totvert, "vert edge map");
        (*mem) = MEM_callocN(sizeof(IndexNode) * totedge * 2, "vert edge map mem");
        node = *mem;
-       
+
        /* Find the users */
        for(i = 0; i < totedge; ++i){
                for(j = 0; j < 2; ++j, ++node) {
@@ -1636,3 +1581,19 @@ void mesh_translate(Mesh *me, float offset[3], int do_keys)
                }
        }
 }
+
+
+void BKE_mesh_ensure_navmesh(Mesh *me)
+{
+       if (!CustomData_has_layer(&me->fdata, CD_RECAST)) {
+               int i;
+               int numFaces = me->totface;
+               int* recastData;
+               CustomData_add_layer_named(&me->fdata, CD_RECAST, CD_CALLOC, NULL, numFaces, "recastData");
+               recastData = (int*)CustomData_get_layer(&me->fdata, CD_RECAST);
+               for (i=0; i<numFaces; i++) {
+                       recastData[i] = i+1;
+               }
+               CustomData_add_layer_named(&me->fdata, CD_RECAST, CD_REFERENCE, recastData, numFaces, "recastData");
+       }
+}