edits ontop of Alex's patch from r41292.
[blender.git] / source / blender / blenkernel / intern / mesh.c
index 247e48a557689ac10ecf6b54b713dc36edbba3d4..5c7d9278783733dccf57da14b37b281155e9a48f 100644 (file)
@@ -1,10 +1,4 @@
-
-/*  mesh.c
- *
- *  
- * 
- * $Id$
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * ***** 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->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);
        
 
        men->bb= MEM_dupallocN(men->bb);
        
@@ -245,83 +241,71 @@ Mesh *copy_mesh(Mesh *me)
        return men;
 }
 
        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;
 }
 
 void make_local_mesh(Mesh *me)
 {
        Main *bmain= G.main;
        Object *ob;
-       Mesh *men;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
        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) {
        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;
        }
                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;
                }
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
        }
-       
+
        if(local && lib==0) {
        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) {
        }
        else if(local && lib) {
-               men= copy_mesh(me);
+               Mesh *men= copy_mesh(me);
                men->id.us= 0;
                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);
                                }
                        }
                                if(ob->id.lib==NULL) {
                                        set_mesh(ob, men);
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
                }
        }
 }
@@ -362,9 +346,9 @@ void tex_space_mesh(Mesh *me)
 
        if(me->texflag & AUTOSPACE) {
                for (a=0; a<3; a++) {
 
        if(me->texflag & AUTOSPACE) {
                for (a=0; a<3; a++) {
-                       if(size[a]==0.0) size[a]= 1.0;
-                       else if(size[a]>0.0 && size[a]<0.00001) size[a]= 0.00001;
-                       else if(size[a]<0.0 && size[a]> -0.00001) size[a]= -0.00001;
+                       if(size[a]==0.0f) size[a]= 1.0f;
+                       else if(size[a]>0.0f && size[a]<0.00001f) size[a]= 0.00001f;
+                       else if(size[a]<0.0f && size[a]> -0.00001f) size[a]= -0.00001f;
                }
 
                copy_v3_v3(me->loc, loc);
                }
 
                copy_v3_v3(me->loc, loc);
@@ -751,9 +735,7 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
                verts= dl->verts;
                while(a--) {
                        VECCOPY(mvert->co, verts);
                verts= dl->verts;
                while(a--) {
                        VECCOPY(mvert->co, verts);
-                       mvert->no[0]= (short int)(nors[0]*32767.0);
-                       mvert->no[1]= (short int)(nors[1]*32767.0);
-                       mvert->no[2]= (short int)(nors[2]*32767.0);
+                       normal_float_to_short_v3(mvert->no, nors);
                        mvert++;
                        nors+= 3;
                        verts+= 3;
                        mvert++;
                        nors+= 3;
                        verts+= 3;
@@ -837,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");
        }
 
        *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;
 
        /* verts and faces */
        vertcount= 0;
@@ -910,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->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;
                                test_index_face(mface, NULL, 0, 3);
 
                                if(smooth) mface->flag |= ME_SMOOTH;
@@ -959,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->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;
                                        test_index_face(mface, NULL, 0, 4);
 
                                        if(smooth) mface->flag |= ME_SMOOTH;
@@ -1245,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;
 
        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--;
        }
                if (mf->mat_nr && mf->mat_nr>=index) 
                        mf->mat_nr--;
        }
@@ -1270,34 +1252,37 @@ void mesh_set_smooth_flag(Object *meshOb, int enableSmooth)
                        mf->flag &= ~ME_SMOOTH;
                }
        }
                        mf->flag &= ~ME_SMOOTH;
                }
        }
+
+       mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
 }
 
 }
 
-void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float **faceNors_r
+void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3]
 {
        float (*tnorms)[3]= MEM_callocN(numVerts*sizeof(*tnorms), "tnorms");
 {
        float (*tnorms)[3]= MEM_callocN(numVerts*sizeof(*tnorms), "tnorms");
-       float *fnors= MEM_callocN(sizeof(*fnors)*3*numFaces, "meshnormals");
+       float (*fnors)[3]= (faceNors_r)? faceNors_r: MEM_callocN(sizeof(*fnors)*numFaces, "meshnormals");
        int i;
 
        int i;
 
-       for (i=0; i<numFaces; i++) {
+       for(i=0; i<numFaces; i++) {
                MFace *mf= &mfaces[i];
                MFace *mf= &mfaces[i];
-               float *f_no= &fnors[i*3];
+               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);
+               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
                else
-                       normal_tri_v3( f_no,mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
-               
-               add_v3_v3(tnorms[mf->v1], f_no);
-               add_v3_v3(tnorms[mf->v2], f_no);
-               add_v3_v3(tnorms[mf->v3], f_no);
-               if (mf->v4)
-                       add_v3_v3(tnorms[mf->v4], f_no);
+                       normal_tri_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
+
+               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);
        }
        }
-       for (i=0; i<numVerts; i++) {
+
+       /* following Mesh convention; we use vertex coordinate itself for normal in this case */
+       for(i=0; i<numVerts; i++) {
                MVert *mv= &mverts[i];
                float *no= tnorms[i];
                
                MVert *mv= &mverts[i];
                float *no= tnorms[i];
                
-               if (normalize_v3(no)==0.0)
+               if(normalize_v3(no) == 0.0f)
                        normalize_v3_v3(no, mv->co);
 
                normal_float_to_short_v3(mv->no, no);
                        normalize_v3_v3(no, mv->co);
 
                normal_float_to_short_v3(mv->no, no);
@@ -1305,11 +1290,8 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces,
        
        MEM_freeN(tnorms);
 
        
        MEM_freeN(tnorms);
 
-       if (faceNors_r) {
-               *faceNors_r = fnors;
-       } else {
+       if(fnors != faceNors_r)
                MEM_freeN(fnors);
                MEM_freeN(fnors);
-       }
 }
 
 float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
 }
 
 float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
@@ -1398,7 +1380,7 @@ UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned
                                sub_v2_v2v2(uvdiff, uv2, uv);
 
 
                                sub_v2_v2v2(uvdiff, uv2, uv);
 
 
-                               if(fabs(uv[0]-uv2[0]) < limit[0] && fabs(uv[1]-uv2[1]) < limit[1]) {
+                               if(fabsf(uv[0]-uv2[0]) < limit[0] && fabsf(uv[1]-uv2[1]) < limit[1]) {
                                        if(lastv) lastv->next= next;
                                        else vlist= next;
                                        iterv->next= newvlist;
                                        if(lastv) lastv->next= next;
                                        else vlist= next;
                                        iterv->next= newvlist;
@@ -1465,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;
        (*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) {
        /* Find the users */
        for(i = 0; i < totedge; ++i){
                for(j = 0; j < 2; ++j, ++node) {
@@ -1599,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");
+       }
+}