diff options
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 46 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 21 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 122 |
5 files changed, 189 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 56724b6ada9..3fd8c34ad21 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -992,6 +992,38 @@ static void layerInterp_shapekey(void **sources, float *weights, } } +static void layerDefault_mvert_skin(void *data, int count) +{ + MVertSkin *vs = data; + int i; + + for(i = 0; i < count; i++) { + copy_v3_fl(vs[i].radius, 0.25f); + vs[i].flag = 0; + } +} + +static void layerInterp_mvert_skin(void **sources, float *weights, + float *UNUSED(sub_weights), + int count, void *dest) +{ + float radius[3], w; + MVertSkin *vs; + int i; + + zero_v3(radius); + for(i = 0; i < count; i++) { + w = weights ? weights[i] : 1.0f; + vs = sources[i]; + + madd_v3_v3fl(radius, vs->radius, w); + } + + vs = dest; + copy_v3_v3(vs->radius, radius); + vs->flag &= ~MVERT_SKIN_ROOT; +} + static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 0: CD_MVERT */ {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, @@ -1093,7 +1125,10 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 35: CD_GRID_PAINT_MASK */ {sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_mask, - layerFree_grid_paint_mask, NULL, NULL, NULL} + layerFree_grid_paint_mask, NULL, NULL, NULL}, + /* 36: CD_SKIN_NODE */ + {sizeof(MVertSkin), "MVertSkin", 1, "Skin", NULL, NULL, + layerInterp_mvert_skin, NULL, layerDefault_mvert_skin} }; /* note, numbers are from trunk and need updating for bmesh */ @@ -1108,10 +1143,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* BMESH ONLY */ /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", /* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask", - /* 35 */ "CDGridPaintMask" - -/* END BMESH ONLY */ - + /* 35-36 */ "CDGridPaintMask", "CDMVertSkin" }; @@ -1123,7 +1155,7 @@ const CustomDataMask CD_MASK_MESH = CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP | CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK | - CD_MASK_GRID_PAINT_MASK; + CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN; const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX | @@ -1142,7 +1174,7 @@ const CustomDataMask CD_MASK_BMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK | - CD_MASK_GRID_PAINT_MASK; + CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN; const CustomDataMask CD_MASK_FACECORNERS = CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 5792953fe49..377af042922 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -63,12 +63,11 @@ typedef struct CustomDataExternal { * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ - int typemap[36]; /* runtime only! - maps types to indices of first layer of that type, + int typemap[37]; /* runtime only! - maps types to indices of first layer of that type, * MUST be >= CD_NUMTYPES, but we cant use a define here. * Correct size is ensured in CustomData_update_typemap assert() */ - int totlayer, maxlayer; /* number of layers, size of layers array */ - int totsize, pad2; /* in editmode, total size of all data layers */ + int totsize; /* in editmode, total size of all data layers */ void *pool; /* Bmesh: Memory pool for allocation of blocks */ CustomDataExternal *external; /* external file storing customdata layers */ } CustomData; @@ -114,8 +113,8 @@ typedef struct CustomData { #define CD_PAINT_MASK 34 #define CD_GRID_PAINT_MASK 35 - -#define CD_NUMTYPES 36 +#define CD_MVERT_SKIN 36 +#define CD_NUMTYPES 37 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -156,6 +155,7 @@ typedef struct CustomData { #define CD_MASK_PAINT_MASK (1LL << CD_PAINT_MASK) #define CD_MASK_GRID_PAINT_MASK (1LL << CD_GRID_PAINT_MASK) +#define CD_MASK_MVERT_SKIN (1LL << CD_MVERT_SKIN) /* CustomData.flag */ diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index c3b0bc39388..0bd83e73271 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -257,6 +257,27 @@ typedef struct GridPaintMask { int pad; } GridPaintMask; +typedef enum MVertSkinFlag { + /* Marks a vertex as the edge-graph root, used for calculating + rotations for all connected edges (recursively.) Also used to + choose a root when generating an armature. */ + MVERT_SKIN_ROOT = 1, + + /* Marks a branch vertex (vertex with more than two connected + edges) so that it's neighbors are directly hulled together, + rather than the default of generating intermediate frames. */ + MVERT_SKIN_LOOSE = 2 +} MVertSkinFlag; + +typedef struct MVertSkin { + /* Radii of the skin, define how big the generated frames + are. Currently only the first two elements are used. */ + float radius[3]; + + /* MVertSkinFlag */ + int flag; +} MVertSkin; + /* mvert->flag (1=SELECT) */ #define ME_SPHERETEST 2 #define ME_VERT_TMP_TAG 4 diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 826ebb72979..1f3529d2f65 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -318,6 +318,8 @@ extern StructRNA RNA_MeshFloatProperty; extern StructRNA RNA_MeshFloatPropertyLayer; extern StructRNA RNA_MeshIntProperty; extern StructRNA RNA_MeshIntPropertyLayer; +extern StructRNA RNA_MeshSkinVertexLayer; +extern StructRNA RNA_MeshSkinVertex; extern StructRNA RNA_MeshSticky; extern StructRNA RNA_MeshStringProperty; extern StructRNA RNA_MeshStringPropertyLayer; diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 466cf0ed412..7eb0bdf75df 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -76,6 +76,11 @@ static Mesh *rna_mesh(PointerRNA *ptr) return me; } +static CustomData *rna_mesh_vdata_helper(Mesh *me) +{ + return (me->edit_btmesh) ? &me->edit_btmesh->bm->vdata : &me->vdata; +} + static CustomData *rna_mesh_pdata_helper(Mesh *me) { return (me->edit_btmesh) ? &me->edit_btmesh->bm->pdata : &me->pdata; @@ -91,6 +96,11 @@ static CustomData *rna_mesh_fdata_helper(Mesh *me) return (me->edit_btmesh) ? NULL : &me->fdata; } +static CustomData *rna_mesh_vdata(PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + return rna_mesh_vdata_helper(me); +} static CustomData *rna_mesh_pdata(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); @@ -856,6 +866,42 @@ static int rna_Mesh_polygon_string_layers_length(PointerRNA *ptr) return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_STR); } +/* Skin vertices */ +DEFINE_CUSTOMDATA_LAYER_COLLECTION(skin_vertice, vdata, CD_MVERT_SKIN); + +static char *rna_MeshSkinVertexLayer_path(PointerRNA *ptr) +{ + return BLI_sprintfN("skin_vertices[\"%s\"]", ((CustomDataLayer *)ptr->data)->name); +} + +static char *rna_VertCustomData_data_path(PointerRNA *ptr, char *collection, int type); +static char *rna_MeshSkinVertex_path(PointerRNA *ptr) +{ + return rna_VertCustomData_data_path(ptr, "skin_vertices", CD_MVERT_SKIN); +} + +static void rna_MeshSkinVertexLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + rna_iterator_array_begin(iter, layer->data, sizeof(MVertSkin), me->totvert, 0, NULL); +} + +static int rna_MeshSkinVertexLayer_data_length(PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + return me->totvert; +} + +static void rna_MeshSkinVertexLayer_name_set(PointerRNA *ptr, const char *value) +{ + CustomDataLayer *cdl = (CustomDataLayer *)ptr->data; + BLI_strncpy_utf8(cdl->name, value, sizeof(cdl->name)); + CustomData_set_layer_unique_name(rna_mesh_vdata(ptr), cdl - rna_mesh_vdata(ptr)->layers); +} + +/* End skin vertices */ + static void rna_TexturePoly_image_set(PointerRNA *ptr, PointerRNA value) { MTexPoly *tf = (MTexPoly *)ptr->data; @@ -1056,6 +1102,24 @@ static char *rna_MeshTexturePolyLayer_path(PointerRNA *ptr) return BLI_sprintfN("uv_textures[\"%s\"]", ((CustomDataLayer *)ptr->data)->name); } +static char *rna_VertCustomData_data_path(PointerRNA *ptr, char *collection, int type) +{ + CustomDataLayer *cdl; + Mesh *me = rna_mesh(ptr); + CustomData *vdata = rna_mesh_vdata(ptr); + int a, b, totvert = (me->edit_btmesh) ? 0 : me->totvert; + + for (cdl = vdata->layers, a = 0; a < vdata->totlayer; cdl++, a++) { + if (cdl->type == type) { + b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type); + if (b >= 0 && b < totvert) + return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, cdl->name, b); + } + } + + return NULL; +} + static char *rna_PolyCustomData_data_path(PointerRNA *ptr, char *collection, int type) { CustomDataLayer *cdl; @@ -2499,6 +2563,54 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } +static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MeshSkinVertexLayer", NULL); + RNA_def_struct_ui_text(srna, "Mesh Skin Vertex Layer", "Per-vertex skin data for use with the Skin modifier"); + RNA_def_struct_sdna(srna, "CustomDataLayer"); + RNA_def_struct_path_func(srna, "rna_MeshSkinVertexLayer_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_MeshSkinVertexLayer_name_set"); + RNA_def_property_ui_text(prop, "Name", "Name of skin 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, "MeshSkinVertex"); + RNA_def_property_ui_text(prop, "Data", ""); + RNA_def_property_collection_funcs(prop, "rna_MeshSkinVertexLayer_data_begin", "rna_iterator_array_next", + "rna_iterator_array_end", "rna_iterator_array_get", + "rna_MeshSkinVertexLayer_data_length", NULL, NULL, NULL); + + /* SkinVertex struct */ + srna = RNA_def_struct(brna, "MeshSkinVertex", NULL); + RNA_def_struct_sdna(srna, "MVertSkin"); + RNA_def_struct_ui_text(srna, "Skin Vertex", "Per-vertex skin data for use with the Skin modifier"); + RNA_def_struct_path_func(srna, "rna_MeshSkinVertex_path"); + + prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, 0.001, 100, 1, 3); + RNA_def_property_ui_text(prop, "Radius", "Radius of the skin"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + + /* Flags */ + + prop = RNA_def_property(srna, "use_root", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MVERT_SKIN_ROOT); + RNA_def_property_ui_text(prop, "Root", "Vertex is a root for rotation calculations and armature generation"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + + prop = RNA_def_property(srna, "use_loose", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MVERT_SKIN_LOOSE); + RNA_def_property_ui_text(prop, "Loose", "If vertex has multiple adjacent edges, it is hulled to them directly"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); +} + static void rna_def_mesh(BlenderRNA *brna) { StructRNA *srna; @@ -2671,6 +2783,16 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "String Property Layers", ""); rna_def_polygon_string_layers(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"); + RNA_def_property_collection_funcs(prop, "rna_Mesh_skin_vertices_begin", NULL, NULL, NULL, + "rna_Mesh_skin_vertices_length", NULL, NULL, NULL); + RNA_def_property_struct_type(prop, "MeshSkinVertexLayer"); + RNA_def_property_ui_text(prop, "Skin Vertices", "All skin vertices"); + rna_def_skin_vertices(brna, prop); + /* End skin vertices */ + prop = RNA_def_property(srna, "use_auto_smooth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_AUTOSMOOTH); RNA_def_property_ui_text(prop, "Auto Smooth", |