diff options
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 140 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 1 |
5 files changed, 109 insertions, 54 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 1dd8e372100..99c421c0c24 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -156,6 +156,7 @@ int CustomData_number_of_layers(const struct CustomData *data, int type); void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type); void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, int type, const char *name); +int CustomData_is_referenced_layer(struct CustomData *data, int type); /* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is * zero for the layer type, so only layer types specified by the mask diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 8db9d3f5447..a8bc2323d0f 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -136,8 +136,13 @@ void mesh_strip_loose_edges(struct Mesh *me); * and vertex normals are stored in actual mverts. */ void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MLoop *mloop, - struct MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3], + struct MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3], struct MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3]); + /* extended version of 'mesh_calc_normals' with option not to calc vertex normals */ +void mesh_calc_normals_ex(struct MVert *mverts, int numVerts, struct MLoop *mloop, + struct MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3], + struct MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3], + const short only_face_normals); /* Return a newly MEM_malloc'd array of all the mesh vertex locations * (_numVerts_r_ may be NULL) */ diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index fe49c4f1bec..f06d62da007 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1740,6 +1740,20 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, return layer->data; } +int CustomData_is_referenced_layer(struct CustomData *data, int type) +{ + CustomDataLayer *layer; + int layer_index; + + /* get the layer index of the first layer of type */ + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return 0; + + layer = &data->layers[layer_index]; + + return (layer->flag & CD_FLAG_NOFREE) != 0; +} + void CustomData_free_temporary(CustomData *data, int totelem) { CustomDataLayer *layer; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e7e8065e436..156f6464885 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1668,69 +1668,111 @@ void mesh_set_smooth_flag(Object *meshOb, int enableSmooth) me->totpoly, NULL, NULL, 0, NULL, NULL); } -void mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys, - int UNUSED(numLoops), int numPolys, float (*polyNors_r)[3], MFace *mfaces, int numFaces, - int *origIndexFace, float (*faceNors_r)[3]) +void mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys, + int numLoops, int numPolys, float (*polyNors_r)[3], MFace *mfaces, int numFaces, + int *origIndexFace, float (*faceNors_r)[3]) +{ + mesh_calc_normals_ex(mverts, numVerts, mloop, mpolys, + numLoops, numPolys, polyNors_r, mfaces, numFaces, + origIndexFace, faceNors_r, TRUE); +} +void mesh_calc_normals_ex(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys, + int UNUSED(numLoops), int numPolys, float (*polyNors_r)[3], MFace *mfaces, int numFaces, + int *origIndexFace, float (*faceNors_r)[3], + const short only_face_normals) { float (*pnors)[3] = polyNors_r, (*fnors)[3] = faceNors_r; - float (*tnorms)[3], (*edgevecbuf)[3]; - float **vertcos = NULL, **vertnos = NULL; - BLI_array_declare(vertcos); - BLI_array_declare(vertnos); - int i, j, maxPolyVerts = 0; + int i, j; MFace *mf; MPoly *mp; MLoop *ml; + int maxPolyVerts = 0; if (numPolys == 0) { return; } - mp = mpolys; - for (i=0; i<numPolys; i++, mp++) { - maxPolyVerts = MAX2(mp->totloop, maxPolyVerts); + if (only_face_normals == FALSE) { + mp = mpolys; + for (i=0; i<numPolys; i++, mp++) { + maxPolyVerts = MAX2(mp->totloop, maxPolyVerts); + } + + if (maxPolyVerts == 0) { + return; + } } - if (maxPolyVerts == 0) { + /* if we are not calculating verts and no verts were passes thene we have nothign to do */ + if ((only_face_normals == TRUE) && (polyNors_r == NULL) && (faceNors_r == NULL)) { + printf("%s: called with nothing to do\n", __func__); return; } - /*first go through and calculate normals for all the polys*/ - edgevecbuf = MEM_callocN(sizeof(float)*3*maxPolyVerts, "edgevecbuf mesh.c"); - tnorms = MEM_callocN(sizeof(float)*3*numVerts, "tnorms mesh.c"); - if (!pnors) - pnors = MEM_callocN(sizeof(float)*3*numPolys, "poly_nors mesh.c"); - if (!fnors) - fnors = MEM_callocN(sizeof(float)*3*numFaces, "face nors mesh.c"); - - mp = mpolys; - for (i=0; i<numPolys; i++, mp++) { - mesh_calc_poly_normal(mp, mloop+mp->loopstart, mverts, pnors[i]); - ml = mloop + mp->loopstart; + if (!pnors) pnors = MEM_callocN(sizeof(float) * 3 * numPolys, "poly_nors mesh.c"); + /* if (!fnors) fnors = MEM_callocN(sizeof(float) * 3 * numFaces, "face nors mesh.c"); */ /* NO NEED TO ALLOC YET */ + + + if (only_face_normals == FALSE) { + /* vertex normals are optional, they require some extra calculations, + * so make them optional */ + + float (*tnorms)[3], (*edgevecbuf)[3]; + float **vertcos = NULL, **vertnos = NULL; + BLI_array_declare(vertcos); + BLI_array_declare(vertnos); - BLI_array_empty(vertcos); - BLI_array_empty(vertnos); - for (j=0; j<mp->totloop; j++) { - int vindex = ml[j].v; - BLI_array_append(vertcos, mverts[vindex].co); - BLI_array_append(vertnos, tnorms[vindex]); + + /*first go through and calculate normals for all the polys*/ + edgevecbuf = MEM_callocN(sizeof(float)*3*maxPolyVerts, "edgevecbuf mesh.c"); + tnorms = MEM_callocN(sizeof(float)*3*numVerts, "tnorms mesh.c"); + + mp = mpolys; + for (i=0; i<numPolys; i++, mp++) { + mesh_calc_poly_normal(mp, mloop+mp->loopstart, mverts, pnors[i]); + ml = mloop + mp->loopstart; + + BLI_array_empty(vertcos); + BLI_array_empty(vertnos); + for (j=0; j<mp->totloop; j++) { + int vindex = ml[j].v; + BLI_array_append(vertcos, mverts[vindex].co); + BLI_array_append(vertnos, tnorms[vindex]); + } + + accumulate_vertex_normals_poly(vertnos, pnors[i], vertcos, edgevecbuf, mp->totloop); } - accumulate_vertex_normals_poly(vertnos, pnors[i], vertcos, edgevecbuf, mp->totloop); - } - - /* 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]; - - if(normalize_v3(no) == 0.0f) - normalize_v3_v3(no, mv->co); + BLI_array_free(vertcos); + BLI_array_free(vertnos); + MEM_freeN(edgevecbuf); - normal_float_to_short_v3(mv->no, no); + /* 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]; + + if(normalize_v3(no) == 0.0f) + normalize_v3_v3(no, mv->co); + + normal_float_to_short_v3(mv->no, no); + } + + MEM_freeN(tnorms); } - - if (origIndexFace && fnors==faceNors_r && numFaces) { + else { + /* only calc poly normals */ + mp = mpolys; + for (i=0; i<numPolys; i++, mp++) { + mesh_calc_poly_normal(mp, mloop+mp->loopstart, mverts, pnors[i]); + } + } + + if ( origIndexFace && + /* fnors==faceNors_r */ /* NO NEED TO ALLOC YET */ + fnors != NULL && + numFaces) + { mf = mfaces; for (i=0; i<numFaces; i++, mf++, origIndexFace++) { if (*origIndexFace < numPolys) { @@ -1742,15 +1784,9 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys, } } - BLI_array_free(vertcos); - BLI_array_free(vertnos); - MEM_freeN(edgevecbuf); - MEM_freeN(tnorms); - if (fnors != faceNors_r) - MEM_freeN(fnors); - if (pnors != polyNors_r) - MEM_freeN(pnors); - + if (pnors != polyNors_r) MEM_freeN(pnors); + /* if (fnors != faceNors_r) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */ + fnors = pnors = NULL; } diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 67be7519729..f9a48453b63 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2363,7 +2363,6 @@ void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3], /* Add weighted face normal component into normals of the face vertices. Caller must pass pre-allocated vdiffs of nverts length. */ -#define VERT_BUF_SIZE 100 void accumulate_vertex_normals_poly(float **vertnos, float polyno[3], float **vertcos, float vdiffs[][3], int nverts) { |