diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-07-20 11:37:30 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-07-20 12:52:26 +0300 |
commit | f5f34a9aa6cb3d09a28997c95fd85a1bda3f114a (patch) | |
tree | 48cccfe76248cd4026c5cab231cf4efdc3e67734 /source | |
parent | 819f3b37da3c6b4732f84f3e06efb95ebbcf8122 (diff) |
RNA: face-map access
Currently RNA doesn't give us a good way of accessing singleton layers,
for now expose as a layer list (skin & paint-pask do this too).
Noted in T47811 that this should be changed.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 42 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 164 |
3 files changed, 207 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 9a94b9513f4..bc56d2a210f 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -91,6 +91,9 @@ struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me); void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd); void BKE_mesh_ensure_skin_customdata(struct Mesh *me); +bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me); +bool BKE_mesh_clear_facemap_customdata(struct Mesh *me); + void BKE_mesh_make_local(struct Main *bmain, struct Mesh *me, const bool lib_local); void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]); void BKE_mesh_texspace_calc(struct Mesh *me); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 8c9690b01df..6ee1eedec94 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -387,6 +387,48 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me) } } +bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me) +{ + BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL; + bool changed = false; + if (bm) { + if (!CustomData_has_layer(&bm->pdata, CD_FACEMAP)) { + BM_data_layer_add(bm, &bm->pdata, CD_FACEMAP); + changed = true; + } + } + else { + if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) { + CustomData_add_layer(&me->pdata, + CD_FACEMAP, + CD_DEFAULT, + NULL, + me->totpoly); + changed = true; + } + } + return changed; +} + +bool BKE_mesh_clear_facemap_customdata(struct Mesh *me) +{ + BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL; + bool changed = false; + if (bm) { + if (CustomData_has_layer(&bm->pdata, CD_FACEMAP)) { + BM_data_layer_free(bm, &bm->pdata, CD_FACEMAP); + changed = true; + } + } + else { + if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { + CustomData_free_layers(&me->pdata, CD_FACEMAP, me->totpoly); + changed = true; + } + } + return changed; +} + /* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or * mloopcol and mcol) have the same relative active/render/clone/mask indices. * diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 3accd2f23f1..a76a53fb667 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -186,12 +186,10 @@ static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value) rna_cd_layer_name_set(rna_mesh_edata(ptr), (CustomDataLayer *)ptr->data, value); } #endif -#if 0 static void rna_MeshPolyLayer_name_set(PointerRNA *ptr, const char *value) { rna_cd_layer_name_set(rna_mesh_pdata(ptr), (CustomDataLayer *)ptr->data, value); } -#endif static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value) { rna_cd_layer_name_set(rna_mesh_ldata(ptr), (CustomDataLayer *)ptr->data, value); @@ -1176,6 +1174,75 @@ static int rna_MeshPaintMaskLayer_data_length(PointerRNA *ptr) /* End paint mask */ +/* Face maps */ + +DEFINE_CUSTOMDATA_LAYER_COLLECTION(face_map, pdata, CD_FACEMAP) +DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(face_map, pdata, CD_FACEMAP, active, MeshFaceMapLayer) + +static char *rna_MeshFaceMapLayer_path(PointerRNA *ptr) +{ + CustomDataLayer *cdl = ptr->data; + char name_esc[sizeof(cdl->name) * 2]; + BLI_strescape(name_esc, cdl->name, sizeof(name_esc)); + return BLI_sprintfN("face_maps[\"%s\"]", name_esc); +} + +static void rna_MeshFaceMapLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + rna_iterator_array_begin(iter, layer->data, sizeof(int), me->totpoly, 0, NULL); +} + +static int rna_MeshFaceMapLayer_data_length(PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + return me->totpoly; +} + +static PointerRNA rna_Mesh_face_map_new(struct Mesh *me, ReportList *reports, const char *name) +{ + if (BKE_mesh_ensure_facemap_customdata(me) == false) { + BKE_report(reports, RPT_ERROR, "Currently only single face-map layers are supported"); + return PointerRNA_NULL; + } + + CustomData *pdata = rna_mesh_pdata_helper(me); + + int index = CustomData_get_layer_index(pdata, CD_FACEMAP); + BLI_assert(index != -1); + CustomDataLayer *cdl = &pdata->layers[index]; + rna_cd_layer_name_set(pdata, cdl, name); + + PointerRNA ptr; + RNA_pointer_create(&me->id, &RNA_MeshFaceMapLayer, cdl, &ptr); + return ptr; +} + +static void rna_Mesh_face_map_remove(struct Mesh *me, ReportList *reports, struct CustomDataLayer *layer) +{ + /* just for sanity check */ + { + CustomData *pdata = rna_mesh_pdata_helper(me); + int index = CustomData_get_layer_index(pdata, CD_FACEMAP); + if (index != -1) { + CustomDataLayer *layer_test = &pdata->layers[index]; + if (layer != layer_test) { + /* don't show name, its likely freed memory */ + BKE_report(reports, RPT_ERROR, "FaceMap not in mesh"); + return; + } + } + } + + if (BKE_mesh_clear_facemap_customdata(me) == false) { + BKE_reportf(reports, RPT_ERROR, "Error removing face-map"); + } +} + +/* End face maps */ + + static int rna_MeshTessFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { MFace *face = (MFace *)ptr->data; @@ -1608,6 +1675,12 @@ void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value) MStringProperty *ms = (MStringProperty *)ptr->data; BLI_strncpy(ms->s, value, sizeof(ms->s)); } + +static char *rna_MeshFaceMap_path(PointerRNA *ptr) +{ + return rna_PolyCustomData_data_path(ptr, "face_maps", CD_FACEMAP); +} + /***************************************/ static int rna_Mesh_tot_vert_get(PointerRNA *ptr) @@ -1796,6 +1869,10 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void) (void)rna_Mesh_vertex_color_render_index_get; (void)rna_Mesh_vertex_color_render_index_set; (void)rna_Mesh_vertex_color_render_set; + (void)rna_Mesh_face_map_index_range; + (void)rna_Mesh_face_map_active_index_set; + (void)rna_Mesh_face_map_active_index_get; + (void)rna_Mesh_face_map_active_set; /* end unused function block */ } @@ -3091,6 +3168,79 @@ static void rna_def_paint_mask(BlenderRNA *brna, PropertyRNA *UNUSED(cprop)) RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } +static void rna_def_face_map(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MeshFaceMapLayer", NULL); + RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index"); + RNA_def_struct_sdna(srna, "CustomDataLayer"); + RNA_def_struct_path_func(srna, "rna_MeshFaceMapLayer_path"); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set"); + RNA_def_property_ui_text(prop, "Name", "Name of face-map layer"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + + prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MeshFaceMap"); + RNA_def_property_ui_text(prop, "Data", ""); + RNA_def_property_collection_funcs(prop, "rna_MeshFaceMapLayer_data_begin", "rna_iterator_array_next", + "rna_iterator_array_end", "rna_iterator_array_get", + "rna_MeshFaceMapLayer_data_length", NULL, NULL, NULL); + + /* FaceMap struct */ + srna = RNA_def_struct(brna, "MeshFaceMap", NULL); + RNA_def_struct_sdna(srna, "MIntProperty"); + RNA_def_struct_ui_text(srna, "Int Property", ""); + RNA_def_struct_path_func(srna, "rna_MeshFaceMap_path"); + + prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "i"); + RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); +} + +static void rna_def_face_maps(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + RNA_def_property_srna(cprop, "MeshFaceMapLayers"); + srna = RNA_def_struct(brna, "MeshFaceMapLayers", NULL); + RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index"); + RNA_def_struct_sdna(srna, "Mesh"); + RNA_def_struct_ui_text(srna, "Mesh FaceMaps", "Collection of mesh face-maps"); + + /* add this since we only ever have one layer anyway, don't bother with active_index */ + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MeshFaceMapLayer"); + RNA_def_property_pointer_funcs(prop, "rna_Mesh_face_map_active_get", + NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Active FaceMap Layer", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + + FunctionRNA *func; + PropertyRNA *parm; + + func = RNA_def_function(srna, "new", "rna_Mesh_face_map_new"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Add a float property layer to Mesh"); + RNA_def_string(func, "name", "Face Map", 0, "", "Face map name"); + parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The newly created layer"); + RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Mesh_face_map_remove"); + RNA_def_function_ui_description(func, "Remove a face map layer"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The layer to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); +} + static void rna_def_mesh(BlenderRNA *brna) { StructRNA *srna; @@ -3250,6 +3400,15 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "String Property Layers", ""); rna_def_polygon_string_layers(brna, prop); + /* face-maps */ + prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); + RNA_def_property_collection_funcs(prop, "rna_Mesh_face_maps_begin", NULL, NULL, NULL, + "rna_Mesh_face_maps_length", NULL, NULL, NULL); + RNA_def_property_struct_type(prop, "MeshFaceMapLayer"); + RNA_def_property_ui_text(prop, "FaceMap", ""); + rna_def_face_maps(brna, prop); + /* Skin vertices */ prop = RNA_def_property(srna, "skin_vertices", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer"); @@ -3523,6 +3682,7 @@ void RNA_def_mesh(BlenderRNA *brna) rna_def_mcol(brna); rna_def_mloopcol(brna); rna_def_mproperties(brna); + rna_def_face_map(brna); } #endif |