Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/customdata.c41
-rw-r--r--source/blender/blenlib/BLI_editVert.h3
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h9
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h12
-rw-r--r--source/blender/python/api2_2x/Mesh.c417
-rw-r--r--source/blender/src/editmesh.c15
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 */