diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-10-12 21:12:55 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-10-12 21:12:55 +0300 |
commit | cdd727b7ceab5772503b702322e93620b7df651b (patch) | |
tree | b7d7f675a464dfe7bd994aeafaed44f21b73779d /source/blender/makesrna/intern/rna_key.c | |
parent | ee688e24a766d1352d9eac5b22113b118c227ceb (diff) |
Add functions to compute normals (verts, polys and loops ones) for a given shapekey.
Title says pretty much everything, we now have BKE and RNA funcs to get vertex, poly and
loop normals of a given shapekey.
This will be used e.g. in FBX exporter (shapekeys need normal data too).
Reviewed By: campbellbarton
Differential Revision: https://developer.blender.org/D1510
Diffstat (limited to 'source/blender/makesrna/intern/rna_key.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_key.c | 139 |
1 files changed, 138 insertions, 1 deletions
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index c25566b6e33..b567e0f00f3 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -156,6 +156,112 @@ static void rna_ShapeKey_slider_max_set(PointerRNA *ptr, float value) #undef SHAPEKEY_SLIDER_TOL +/* ***** Normals accessors for shapekeys. ***** */ +/* Note: with this we may recompute several times the same data, should we want to access verts, then polys, then loops + * normals... However, such case looks rather unlikely - and not worth adding some kind of caching in KeyBlocks. + */ + +static Mesh *rna_KeyBlock_normals_get_mesh(PointerRNA *ptr, ID *id) +{ + Key *key = rna_ShapeKey_find_key((id == NULL && ptr != NULL) ? ptr->id.data : id); + id = key ? key->from : NULL; + + if (id != NULL) { + switch (GS(id->name)) { + case ID_ME: + return (Mesh *)id; + case ID_OB: + { + Object *ob = (Object *)id; + if (ob->type == OB_MESH) { + return ob->data; + } + } + } + } + + return NULL; +} + +static int rna_KeyBlock_normals_vert_len(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) +{ + Mesh *me = rna_KeyBlock_normals_get_mesh(ptr, NULL); + + length[0] = me ? me->totvert : 0; + length[1] = 3; + + return (length[0] * length[1]); +} + +static void rna_KeyBlock_normals_vert_calc(ID *id, KeyBlock *data, int *normals_len, float **normals) +{ + Mesh *me = rna_KeyBlock_normals_get_mesh(NULL, id); + + *normals_len = (me ? me->totvert : 0) * 3; + + if (ELEM(NULL, me, data) || (me->totvert == 0)) { + *normals = NULL; + return; + } + + *normals = MEM_mallocN(sizeof(**normals) * (size_t)(*normals_len), __func__); + + BKE_keyblock_mesh_calc_normals(data, me, (float (*)[3])(*normals), NULL, NULL); +} + +static int rna_KeyBlock_normals_poly_len(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) +{ + Mesh *me = rna_KeyBlock_normals_get_mesh(ptr, NULL); + + length[0] = me ? me->totpoly : 0; + length[1] = 3; + + return (length[0] * length[1]); +} + +static void rna_KeyBlock_normals_poly_calc(ID *id, KeyBlock *data, int *normals_len, float **normals) +{ + Mesh *me = rna_KeyBlock_normals_get_mesh(NULL, id); + + *normals_len = (me ? me->totpoly : 0) * 3; + + if (ELEM(NULL, me, data) || (me->totpoly == 0)) { + *normals = NULL; + return; + } + + *normals = MEM_mallocN(sizeof(**normals) * (size_t)(*normals_len), __func__); + + BKE_keyblock_mesh_calc_normals(data, me, NULL, (float (*)[3])(*normals), NULL); +} + +static int rna_KeyBlock_normals_loop_len(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) +{ + Mesh *me = rna_KeyBlock_normals_get_mesh(ptr, NULL); + + length[0] = me ? me->totloop : 0; + length[1] = 3; + + return (length[0] * length[1]); +} + +static void rna_KeyBlock_normals_loop_calc(ID *id, KeyBlock *data, int *normals_len, float **normals) +{ + Mesh *me = rna_KeyBlock_normals_get_mesh(NULL, id); + + *normals_len = (me ? me->totloop : 0) * 3; + + if (ELEM(NULL, me, data) || (me->totloop == 0)) { + *normals = NULL; + return; + } + + *normals = MEM_mallocN(sizeof(**normals) * (size_t)(*normals_len), __func__); + + BKE_keyblock_mesh_calc_normals(data, me, NULL, NULL, (float (*)[3])(*normals)); +} + + PointerRNA rna_object_shapekey_index_get(ID *id, int value) { Key *key = rna_ShapeKey_find_key(id); @@ -558,7 +664,8 @@ static void rna_def_keydata(BlenderRNA *brna) static void rna_def_keyblock(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; + PropertyRNA *prop, *parm; + FunctionRNA *func; srna = RNA_def_struct(brna, "ShapeKey", NULL); RNA_def_struct_ui_text(srna, "Shape Key", "Shape key in a shape keys datablock"); @@ -633,6 +740,36 @@ static void rna_def_keyblock(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Data", ""); RNA_def_property_collection_funcs(prop, "rna_ShapeKey_data_begin", NULL, NULL, "rna_ShapeKey_data_get", "rna_ShapeKey_data_length", NULL, NULL, NULL); + + /* XXX multi-dim dynamic arrays are very badly supported by (py)rna currently, those are defined for the day + * it works better, for now user will get a 1D tuple... + **/ + func = RNA_def_function(srna, "normals_vertex_get", "rna_KeyBlock_normals_vert_calc"); + RNA_def_function_ui_description(func, "Compute local space vertices' normals for this shape key"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_property(func, "normals", PROP_FLOAT, /* PROP_DIRECTION */ PROP_NONE); + RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_OUTPUT); + RNA_def_property_multi_array(parm, 2, NULL); + RNA_def_property_range(parm, -1.0f, 1.0f); + RNA_def_property_dynamic_array_funcs(parm, "rna_KeyBlock_normals_vert_len"); + + func = RNA_def_function(srna, "normals_polygon_get", "rna_KeyBlock_normals_poly_calc"); + RNA_def_function_ui_description(func, "Compute local space faces' normals for this shape key"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_property(func, "normals", PROP_FLOAT, /* PROP_DIRECTION */ PROP_NONE); + RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_OUTPUT); + RNA_def_property_multi_array(parm, 2, NULL); + RNA_def_property_range(parm, -1.0f, 1.0f); + RNA_def_property_dynamic_array_funcs(parm, "rna_KeyBlock_normals_poly_len"); + + func = RNA_def_function(srna, "normals_split_get", "rna_KeyBlock_normals_loop_calc"); + RNA_def_function_ui_description(func, "Compute local space face corners' normals for this shape key"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_property(func, "normals", PROP_FLOAT, /* PROP_DIRECTION */ PROP_NONE); + RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_OUTPUT); + RNA_def_property_multi_array(parm, 2, NULL); + RNA_def_property_range(parm, -1.0f, 1.0f); + RNA_def_property_dynamic_array_funcs(parm, "rna_KeyBlock_normals_loop_len"); } static void rna_def_key(BlenderRNA *brna) |