[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [10874] trunk/blender/source/blender: -> Custom Properties for Mesh entities

Geoffrey Bantle hairbat at yahoo.com
Mon Jun 4 21:18:20 CEST 2007


Revision: 10874
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=10874
Author:   briggs
Date:     2007-06-04 21:18:19 +0200 (Mon, 04 Jun 2007)

Log Message:
-----------
-> Custom Properties for Mesh entities

In order to give import/export script authors the ability to add properties
to inidividual faces, vertices and edges in the same manner as they are able
to do with ID structures three new custom data types have been added to blender
for floats, integers and strings.

Things to note:

-Since property Layers are custom data, they are added to all verts, edges 
 or faces at once.
-Only one property layer for each unique property name may exist. In  other 
 words, you cannot have a float layer as well as an integer layer
 both with the same name.
-No user interface for this exists at the moment.

The following methods and attributes have been added to the Blender.Mesh
Python module and it's object types:

->MVert/Edge/FaceSeq:
	addPropertyLayer(name, type)
	removePropertyLayer(name)
	renamePropertyLayer(original name, new name)
	properties(readonly list.)

->MVert/Edge/Face
	getProperty(name)
	setProperty(name, value)

->Mesh module
	PropertyTypes (readonly dictionary)

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/customdata.c
    trunk/blender/source/blender/blenlib/BLI_editVert.h
    trunk/blender/source/blender/makesdna/DNA_customdata_types.h
    trunk/blender/source/blender/makesdna/DNA_meshdata_types.h
    trunk/blender/source/blender/python/api2_2x/Mesh.c
    trunk/blender/source/blender/src/editmesh.c

Modified: trunk/blender/source/blender/blenkernel/intern/customdata.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/customdata.c	2007-06-04 10:53:37 UTC (rev 10873)
+++ trunk/blender/source/blender/blenkernel/intern/customdata.c	2007-06-04 19:18:19 UTC (rev 10874)
@@ -367,20 +367,24 @@
 	/* 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 @@
 	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 @@
 	/* 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 @@
 		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) {

Modified: trunk/blender/source/blender/blenlib/BLI_editVert.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_editVert.h	2007-06-04 10:53:37 UTC (rev 10873)
+++ trunk/blender/source/blender/blenlib/BLI_editVert.h	2007-06-04 19:18:19 UTC (rev 10874)
@@ -106,6 +106,7 @@
 	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 @@
 
 	struct RetopoPaintData *retopo_paint_data;
 
-	CustomData vdata, fdata;
+	CustomData vdata, edata, fdata;
 
 #ifdef WITH_VERSE
 	void *vnode;

Modified: trunk/blender/source/blender/makesdna/DNA_customdata_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_customdata_types.h	2007-06-04 10:53:37 UTC (rev 10873)
+++ trunk/blender/source/blender/makesdna/DNA_customdata_types.h	2007-06-04 19:18:19 UTC (rev 10874)
@@ -64,7 +64,10 @@
 #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,7 +80,11 @@
 #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 */
 
 /* indicates layer should not be copied by CustomData_from_template or

Modified: trunk/blender/source/blender/makesdna/DNA_meshdata_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_meshdata_types.h	2007-06-04 10:53:37 UTC (rev 10873)
+++ trunk/blender/source/blender/makesdna/DNA_meshdata_types.h	2007-06-04 19:18:19 UTC (rev 10874)
@@ -86,6 +86,18 @@
 	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;

Modified: trunk/blender/source/blender/python/api2_2x/Mesh.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/Mesh.c	2007-06-04 10:53:37 UTC (rev 10873)
+++ trunk/blender/source/blender/python/api2_2x/Mesh.c	2007-06-04 19:18:19 UTC (rev 10874)
@@ -1226,6 +1226,237 @@
 	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 );
+	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)) {
+			PyList_Append( list, PyString_FromString(layer->name) );
+		}
+	}
+	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);
+		}

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list