diff options
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 41 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_editVert.h | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 12 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Mesh.c | 417 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 15 |
6 files changed, 479 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index e239583c4eb..2c8199f90f3 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -367,20 +367,24 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 3 floats per normal vector */ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL}, + {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL}, + {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL}, }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", - "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags"}; + "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty","CDMIntProperty","CDMStringProperty"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; const CustomDataMask CD_MASK_MESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | - CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL; + CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | + CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | - CD_MASK_MCOL; + CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX; @@ -1335,6 +1339,13 @@ const char *CustomData_layertype_name(int type) return layerType_getName(type); } +static int CustomData_is_property_layer(int type) +{ + if((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR)) + return 1; + return 0; +} + void CustomData_set_layer_unique_name(CustomData *data, int index) { char tempname[64]; @@ -1355,9 +1366,17 @@ void CustomData_set_layer_unique_name(CustomData *data, int index) /* see if there is a duplicate */ for(i=0; i<data->totlayer; i++) { layer = &data->layers[i]; - - if(i!=index && layer->type==type && strcmp(layer->name, name)==0) - break; + + if(CustomData_is_property_layer(type)){ + if(i!=index && CustomData_is_property_layer(layer->type) && + strcmp(layer->name, name)==0) + break; + + } + else{ + if(i!=index && layer->type==type && strcmp(layer->name, name)==0) + break; + } } if(i == data->totlayer) @@ -1373,8 +1392,16 @@ void CustomData_set_layer_unique_name(CustomData *data, int index) for(i=0; i<data->totlayer; i++) { layer = &data->layers[i]; - if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0) + if(CustomData_is_property_layer(type)){ + if(i!=index && CustomData_is_property_layer(layer->type) && + strcmp(layer->name, tempname)==0) + break; + } + else{ + if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0) + break; + } } if(i == data->totlayer) { diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index a763ad53f1f..c05d33f2792 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -106,6 +106,7 @@ typedef struct EditEdge short fast; /* only 0 or 1, for editmesh_fastmalloc */ short fgoni; /* index for fgon, for search */ HashEdge hash; + void *data; /*custom edge data*/ } EditEdge; /* note; changing this also might affect the undo copy in editmesh.c */ @@ -171,7 +172,7 @@ typedef struct EditMesh struct RetopoPaintData *retopo_paint_data; - CustomData vdata, fdata; + CustomData vdata, edata, fdata; #ifdef WITH_VERSE void *vnode; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index b9f6ab0e60b..1c1676ba277 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -64,7 +64,10 @@ typedef struct CustomData { #define CD_ORIGINDEX 7 #define CD_NORMAL 8 #define CD_FLAGS 9 -#define CD_NUMTYPES 10 +#define CD_PROP_FLT 10 +#define CD_PROP_INT 11 +#define CD_PROP_STR 12 +#define CD_NUMTYPES 13 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -77,6 +80,10 @@ typedef struct CustomData { #define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX) #define CD_MASK_NORMAL (1 << CD_NORMAL) #define CD_MASK_FLAGS (1 << CD_FLAGS) +#define CD_MASK_PROP_FLT (1 << CD_PROP_FLT) +#define CD_MASK_PROP_INT (1 << CD_PROP_INT) +#define CD_MASK_PROP_STR (1 << CD_PROP_STR) + /* CustomData.flag */ diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index af9c1ae629d..b2aecc57269 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -86,6 +86,18 @@ typedef struct MTFace { short mode, tile, unwrap; } MTFace; +/*Custom Data Properties*/ +typedef struct MFloatProperty{ + float f; +} MFloatProperty; +typedef struct MIntProperty{ + int i; +} MIntProperty; +typedef struct MStringProperty{ + char s[256]; +} MStringProperty; + + /* Multiresolution modeling */ typedef struct MultiresCol { float a, r, g, b; diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index bd78900f625..bd79c2878d9 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -1226,6 +1226,239 @@ static long MVert_hash( BPy_MVert *self ) return (long)self->index; } +static PyObject *Mesh_addPropLayer_internal(Mesh *mesh, CustomData *data, int tot, PyObject *args) +{ + char *name=NULL; + int type = -1; + + if( !PyArg_ParseTuple( args, "si", &name, &type) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected a string and an int" ); + if (strlen(name)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31"); + if((type != CD_PROP_FLT) && (type != CD_PROP_INT) && (type != CD_PROP_STR)) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, unknown layer type"); + if (name) + CustomData_add_layer_named(data, type, CD_DEFAULT, NULL,tot,name); + + mesh_update_customdata_pointers(mesh); + Py_RETURN_NONE; +} + +static PyObject *Mesh_removePropLayer_internal(Mesh *mesh, CustomData *data, int tot,PyObject *args) +{ + CustomDataLayer *layer; + char *name=NULL; + int i; + + if( !PyArg_ParseTuple( args, "s", &name ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected string argument" ); + + if (strlen(name)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); + + i = CustomData_get_named_layer_index(data, CD_PROP_FLT, name); + if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_INT, name); + if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_STR, name); + if (i==-1) + return EXPP_ReturnPyObjError(PyExc_ValueError, + "No matching layers to remove" ); + layer = &data->layers[i]; + CustomData_free_layer(data, layer->type, tot, i); + mesh_update_customdata_pointers(mesh); + + Py_RETURN_NONE; +} + +static PyObject *Mesh_renamePropLayer_internal(Mesh *mesh, CustomData *data, PyObject *args) +{ + CustomDataLayer *layer; + int i; + char *name_from, *name_to; + + if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected 2 strings" ); + + if (strlen(name_from)>31 || strlen(name_to)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); + + i = CustomData_get_named_layer_index(data, CD_PROP_FLT, name_from); + if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_INT, name_from); + if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_STR, name_from); + if(i == -1) + return EXPP_ReturnPyObjError(PyExc_ValueError, + "No matching layers to rename" ); + + layer = &data->layers[i]; + + strcpy(layer->name, name_to); /* we alredy know the string sizes are under 32 */ + CustomData_set_layer_unique_name(data, i); + Py_RETURN_NONE; +} + +static PyObject *Mesh_propList_internal(CustomData *data) +{ + CustomDataLayer *layer; + PyObject *list = PyList_New( 0 ), *item; + int i; + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + if( (layer->type == CD_PROP_FLT) || (layer->type == CD_PROP_INT) || (layer->type == CD_PROP_STR)) { + item = PyString_FromString(layer->name); + PyList_Append( list, item ); + Py_DECREF(item); + } + } + return list; +} + +static PyObject *Mesh_getProperty_internal(CustomData *data, int eindex, PyObject *args) +{ + CustomDataLayer *layer; + char *name=NULL; + int i; + MFloatProperty *pf; + MIntProperty *pi; + MStringProperty *ps; + + if(!PyArg_ParseTuple(args, "s", &name)) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected an string argument" ); + + if (strlen(name)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); + + i = CustomData_get_named_layer_index(data, CD_PROP_FLT, name); + if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_INT, name); + if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_STR, name); + if(i == -1) + return EXPP_ReturnPyObjError(PyExc_ValueError, + "No matching layers" ); + + layer = &data->layers[i]; + + if(layer->type == CD_PROP_FLT){ + pf = layer->data; + return PyFloat_FromDouble(pf[eindex].f); + } + else if(layer->type == CD_PROP_INT){ + pi = layer->data; + return PyInt_FromLong(pi[eindex].i); + + } + else if(layer->type == CD_PROP_STR){ + ps = layer->data; + return PyString_FromString(ps[eindex].s); + } + Py_RETURN_NONE; +} + +static PyObject *Mesh_setProperty_internal(CustomData *data, int eindex, PyObject *args) +{ + CustomDataLayer *layer; + int i,index, type = -1; + float f; + char *s=NULL, *name=NULL; + MFloatProperty *pf; + MIntProperty *pi; + MStringProperty *ps; + PyObject *val; + + if(PyArg_ParseTuple(args, "sO", &name, &val)){ + if (strlen(name)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); + + if(PyInt_CheckExact(val)){ + type = CD_PROP_INT; + i = (int)PyInt_AS_LONG(val); + } + else if(PyFloat_CheckExact(val)){ + type = CD_PROP_FLT; + f = (float)PyFloat_AsDouble(val); + } + else if(PyString_CheckExact(val)){ + type = CD_PROP_STR; + s = PyString_AsString(val); + } + else + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected an name plus either float/int/string" ); + + } + + index = CustomData_get_named_layer_index(data, type, name); + if(index == -1) + return EXPP_ReturnPyObjError(PyExc_ValueError, + "No matching layers or type mismatch" ); + + layer = &data->layers[index]; + + if(type==CD_PROP_STR){ + if (strlen(s)>255){ + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum string length is 255"); + } + else{ + ps = layer->data; + strcpy(ps[eindex].s,s); + } + } + else if(type==CD_PROP_FLT){ + pf = layer->data; + pf[eindex].f = f; + } + else{ + pi = layer->data; + pi[eindex].i = i; + } + Py_RETURN_NONE; +} + +static PyObject *MVert_getProp( BPy_MVert *self, PyObject *args) +{ + if( BPy_MVert_Check( self ) ){ + Mesh *me = (Mesh *)self->data; + if(self->index >= me->totvert) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, MVert is no longer valid part of mesh!"); + else + return Mesh_getProperty_internal(&(me->vdata), self->index, args); + } + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, Vertex not part of a mesh!"); +} + +static PyObject *MVert_setProp( BPy_MVert *self, PyObject *args) +{ + if( BPy_MVert_Check( self ) ){ + Mesh *me = (Mesh *)self->data; + if(self->index >= me->totvert) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, MVert is no longer valid part of mesh!"); + else + return Mesh_setProperty_internal(&(me->vdata), self->index, args); + } + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, Vertex not part of a mesh!"); +} + +static struct PyMethodDef BPy_MVert_methods[] = { + {"getProperty", (PyCFunction)MVert_getProp, METH_VARARGS, + "get property indicated by name"}, + {"setProperty", (PyCFunction)MVert_setProp, METH_VARARGS, + "set property indicated by name"}, + {NULL, NULL, 0, NULL} +}; + + /************************************************************************ * * Python MVert_Type structure definition @@ -1290,7 +1523,7 @@ PyTypeObject MVert_Type = { NULL, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ - NULL, /* struct PyMethodDef *tp_methods; */ + BPy_MVert_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ BPy_MVert_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ @@ -1955,6 +2188,37 @@ static PyObject *MVertSeq_selected( BPy_MVertSeq * self ) } return list; } +static PyObject *MVertSeq_add_layertype(BPy_MVertSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_addPropLayer_internal(me, &(me->vdata), me->totvert, args); +} +static PyObject *MVertSeq_del_layertype(BPy_MVertSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_removePropLayer_internal(me, &(me->vdata), me->totvert, args); +} +static PyObject *MVertSeq_rename_layertype(BPy_MVertSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_renamePropLayer_internal(me,&(me->vdata),args); +} +static PyObject *MVertSeq_PropertyList(BPy_MVertSeq *self) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_propList_internal(&(me->vdata)); +} +static PyObject *M_Mesh_PropertiesTypeDict(void) +{ + PyObject *Types = PyConstant_New( ); + if(Types) { + BPy_constant *d = (BPy_constant *) Types; + PyConstant_Insert(d, "FLOAT", PyInt_FromLong(CD_PROP_FLT)); + PyConstant_Insert(d, "INT" , PyInt_FromLong(CD_PROP_INT)); + PyConstant_Insert(d, "STRING", PyInt_FromLong(CD_PROP_STR)); + } + return Types; +} static struct PyMethodDef BPy_MVertSeq_methods[] = { {"extend", (PyCFunction)MVertSeq_extend, METH_VARARGS, @@ -1963,9 +2227,25 @@ static struct PyMethodDef BPy_MVertSeq_methods[] = { "delete vertices from mesh"}, {"selected", (PyCFunction)MVertSeq_selected, METH_NOARGS, "returns a list containing indices of selected vertices"}, + {"addPropertyLayer",(PyCFunction)MVertSeq_add_layertype, METH_VARARGS, + "add a new property layer"}, + {"removePropertyLayer",(PyCFunction)MVertSeq_del_layertype, METH_VARARGS, + "removes a property layer"}, + {"renamePropertyLayer",(PyCFunction)MVertSeq_rename_layertype, METH_VARARGS, + "renames an existing property layer"}, {NULL, NULL, 0, NULL} }; +static PyGetSetDef BPy_MVertSeq_getseters[] = { + {"properties", + (getter)MVertSeq_PropertyList, (setter)NULL, + "vertex property layers, read only", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + + + /************************************************************************ * * Python MVertSeq_Type standard operations @@ -2035,7 +2315,7 @@ PyTypeObject MVertSeq_Type = { /*** Attribute descriptor and subclassing stuff ***/ BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ - NULL, /* struct PyGetSetDef *tp_getset; */ + BPy_MVertSeq_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ NULL, /* PyObject *tp_dict; */ NULL, /* descrgetfunc tp_descr_get; */ @@ -2452,7 +2732,25 @@ static long MEdge_hash( BPy_MEdge *self ) { return (long)self->index; } +static PyObject *MEdge_getProp( BPy_MEdge *self, PyObject *args) +{ + Mesh *me = (Mesh *)self->mesh; + return Mesh_getProperty_internal(&(me->edata), self->index, args); +} + +static PyObject *MEdge_setProp( BPy_MEdge *self, PyObject *args) +{ + Mesh *me = (Mesh *)self->mesh; + return Mesh_setProperty_internal(&(me->edata), self->index, args); +} +static struct PyMethodDef BPy_MEdge_methods[] = { + {"getProperty", (PyCFunction)MEdge_getProp, METH_VARARGS, + "get property indicated by name"}, + {"setProperty", (PyCFunction)MEdge_setProp, METH_VARARGS, + "set property indicated by name"}, + {NULL, NULL, 0, NULL} +}; /************************************************************************ * * Python MEdge_Type structure definition @@ -2517,7 +2815,7 @@ PyTypeObject MEdge_Type = { ( iternextfunc ) MEdge_nextIter, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ - NULL, /* struct PyMethodDef *tp_methods; */ + BPy_MEdge_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ BPy_MEdge_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ @@ -3311,6 +3609,28 @@ static PyObject *MEdgeSeq_selected( BPy_MEdgeSeq * self ) return list; } +static PyObject *MEdgeSeq_add_layertype(BPy_MEdgeSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_addPropLayer_internal(me, &(me->edata), me->totedge, args); +} +static PyObject *MEdgeSeq_del_layertype(BPy_MEdgeSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_removePropLayer_internal(me, &(me->edata), me->totedge, args); +} +static PyObject *MEdgeSeq_rename_layertype(BPy_MEdgeSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_renamePropLayer_internal(me,&(me->edata),args); +} +static PyObject *MEdgeSeq_PropertyList(BPy_MEdgeSeq *self) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_propList_internal(&(me->edata)); +} + + static struct PyMethodDef BPy_MEdgeSeq_methods[] = { {"extend", (PyCFunction)MEdgeSeq_extend, METH_VARARGS, "add edges to mesh"}, @@ -3320,8 +3640,23 @@ static struct PyMethodDef BPy_MEdgeSeq_methods[] = { "returns a list containing indices of selected edges"}, {"collapse", (PyCFunction)MEdgeSeq_collapse, METH_VARARGS, "collapse one or more edges to a vertex"}, + {"addPropertyLayer",(PyCFunction)MEdgeSeq_add_layertype, METH_VARARGS, + "add a new property layer"}, + {"removePropertyLayer",(PyCFunction)MEdgeSeq_del_layertype, METH_VARARGS, + "removes a property layer"}, + {"renamePropertyLayer",(PyCFunction)MEdgeSeq_rename_layertype, METH_VARARGS, + "renames an existing property layer"}, + {NULL, NULL, 0, NULL} }; +static PyGetSetDef BPy_MEdgeSeq_getseters[] = { + {"properties", + (getter)MEdgeSeq_PropertyList, (setter)NULL, + "edge property layers, read only", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + /************************************************************************ * @@ -3392,7 +3727,7 @@ PyTypeObject MEdgeSeq_Type = { /*** Attribute descriptor and subclassing stuff ***/ BPy_MEdgeSeq_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ - NULL, /* struct PyGetSetDef *tp_getset; */ + BPy_MEdgeSeq_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ NULL, /* PyObject *tp_dict; */ NULL, /* descrgetfunc tp_descr_get; */ @@ -4469,6 +4804,35 @@ static PySequenceMethods MFace_as_sequence = { 0,0,0, }; +static PyObject *MFace_getProp( BPy_MFace *self, PyObject *args) +{ + Mesh *me = (Mesh *)self->mesh; + MFace *face = MFace_get_pointer( self ); + if( !face ) + return NULL; + mesh_update_customdata_pointers(me); //! + return Mesh_getProperty_internal(&(me->fdata), self->index, args); +} + +static PyObject *MFace_setProp( BPy_MFace *self, PyObject *args) +{ + Mesh *me = (Mesh *)self->mesh; + PyObject *obj; + MFace *face = MFace_get_pointer( self ); + if( !face ) + return NULL; + obj = Mesh_setProperty_internal(&(me->fdata), self->index, args); + mesh_update_customdata_pointers(me); //! + return obj; +} + +static struct PyMethodDef BPy_MFace_methods[] = { + {"getProperty", (PyCFunction)MFace_getProp, METH_VARARGS, + "get property indicated by name"}, + {"setProperty", (PyCFunction)MFace_setProp, METH_VARARGS, + "set property indicated by name"}, + {NULL, NULL, 0, NULL} +}; /************************************************************************ * * Python MFace_Type structure definition @@ -4533,7 +4897,7 @@ PyTypeObject MFace_Type = { ( iternextfunc ) MFace_nextIter, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ - NULL, /* struct PyMethodDef *tp_methods; */ + BPy_MFace_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ BPy_MFace_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ @@ -5242,6 +5606,27 @@ static PyObject *MFaceSeq_selected( BPy_MFaceSeq * self ) return list; } +static PyObject *MFaceSeq_add_layertype(BPy_MFaceSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_addPropLayer_internal(me, &(me->fdata), me->totface, args); +} +static PyObject *MFaceSeq_del_layertype(BPy_MFaceSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_removePropLayer_internal(me, &(me->fdata), me->totface, args); +} +static PyObject *MFaceSeq_rename_layertype(BPy_MFaceSeq *self, PyObject *args) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_renamePropLayer_internal(me,&(me->fdata),args); +} +static PyObject *MFaceSeq_PropertyList(BPy_MFaceSeq *self) +{ + Mesh *me = (Mesh*)self->mesh; + return Mesh_propList_internal(&(me->fdata)); +} + static struct PyMethodDef BPy_MFaceSeq_methods[] = { {"extend", (PyCFunction)MFaceSeq_extend, METH_VARARGS|METH_KEYWORDS, "add faces to mesh"}, @@ -5249,8 +5634,22 @@ static struct PyMethodDef BPy_MFaceSeq_methods[] = { "delete faces from mesh"}, {"selected", (PyCFunction)MFaceSeq_selected, METH_NOARGS, "returns a list containing indices of selected faces"}, + {"addPropertyLayer",(PyCFunction)MFaceSeq_add_layertype, METH_VARARGS, + "add a new property layer"}, + {"removePropertyLayer",(PyCFunction)MFaceSeq_del_layertype, METH_VARARGS, + "removes a property layer"}, + {"renamePropertyLayer",(PyCFunction)MFaceSeq_rename_layertype, METH_VARARGS, + "renames an existing property layer"}, {NULL, NULL, 0, NULL} }; +static PyGetSetDef BPy_MFaceSeq_getseters[] = { + {"properties", + (getter)MFaceSeq_PropertyList, (setter)NULL, + "vertex property layers, read only", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + /************************************************************************ * @@ -5321,7 +5720,7 @@ PyTypeObject MFaceSeq_Type = { /*** Attribute descriptor and subclassing stuff ***/ BPy_MFaceSeq_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ - NULL, /* struct PyGetSetDef *tp_getset; */ + BPy_MFaceSeq_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ NULL, /* PyObject *tp_dict; */ NULL, /* descrgetfunc tp_descr_get; */ @@ -8156,7 +8555,8 @@ PyObject *Mesh_Init( void ) PyObject *EdgeFlags = M_Mesh_EdgeFlagsDict( ); PyObject *AssignModes = M_Mesh_VertAssignDict( ); PyObject *SelectModes = M_Mesh_SelectModeDict( ); - + PyObject *PropertyTypes = M_Mesh_PropertiesTypeDict( ); + if( PyType_Ready( &MCol_Type ) < 0 ) return NULL; if( PyType_Ready( &MVert_Type ) < 0 ) @@ -8196,6 +8596,9 @@ PyObject *Mesh_Init( void ) PyModule_AddObject( submodule, "AssignModes", AssignModes ); if( SelectModes ) PyModule_AddObject( submodule, "SelectModes", SelectModes ); + if( PropertyTypes ) + PyModule_AddObject( submodule, "PropertyTypes", PropertyTypes ); + return submodule; diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 9b0811bf788..fe6708f5959 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -859,6 +859,7 @@ void make_editMesh() else { MEdge *medge= me->medge; + CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0); /* make edges */ for(a=0; a<me->totedge; a++, medge++) { eed= addedgelist(evlist[medge->v1], evlist[medge->v2], NULL); @@ -873,6 +874,7 @@ void make_editMesh() if(medge->flag & ME_HIDE) eed->h |= 1; if(G.scene->selectmode==SCE_SELECT_EDGE) EM_select_edge(eed, eed->f & SELECT); // force edge selection to vertices, seems to be needed ... + CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data); } } @@ -1014,6 +1016,7 @@ void load_editMesh(void) me->totface= G.totface; CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert); + CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge); CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface); CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert); @@ -1071,7 +1074,8 @@ void load_editMesh(void) if(eed->h & 1) medge->flag |= ME_HIDE; medge->crease= (char)(255.0*eed->crease); - + CustomData_from_em_block(&em->edata, &me->edata, eed->data, a); + eed->tmp.l = a++; medge++; @@ -1823,7 +1827,7 @@ typedef struct UndoMesh { short selectmode; RetopoPaintData *retopo_paint_data; char retopo_mode; - CustomData vdata, fdata; + CustomData vdata, edata, fdata; EM_MultiresUndo *mru; } UndoMesh; @@ -1839,6 +1843,7 @@ static void free_undoMesh(void *umv) if(um->selected) MEM_freeN(um->selected); if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data); CustomData_free(&um->vdata, um->totvert); + CustomData_free(&um->edata, um->totedge); CustomData_free(&um->fdata, um->totface); if(um->mru) { --um->mru->users; @@ -1881,6 +1886,7 @@ static void *editMesh_to_undoMesh(void) if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections"); if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert); + if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge); if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface); /* now copy vertices */ @@ -1909,6 +1915,8 @@ static void *editMesh_to_undoMesh(void) eedc->crease= (short)(eed->crease*255.0); eedc->fgoni= eed->fgoni; eed->tmp.l = a; /*store index*/ + CustomData_from_em_block(&em->edata, &um->edata, eed->data, a); + } /* copy faces */ @@ -2000,9 +2008,11 @@ static void undoMesh_to_editMesh(void *umv) #endif CustomData_free(&em->vdata, 0); + CustomData_free(&em->edata, 0); CustomData_free(&em->fdata, 0); CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); + CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0); CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0); /* now copy vertices */ @@ -2030,6 +2040,7 @@ static void undoMesh_to_editMesh(void *umv) eed->sharp= eedc->sharp; eed->fgoni= eedc->fgoni; eed->crease= ((float)eedc->crease)/255.0; + CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data); } /* copy faces */ |