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.
This commit is contained in:
parent
819f3b37da
commit
f5f34a9aa6
Notes:
blender-bot
2023-02-14 06:57:56 +01:00
Referenced by issue #52127, Combed hair from 2.78 not showing when appending
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue