[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11732] trunk/blender/source/blender/ python/api2_2x: added face sorting to mesh so you can do mesh.faces.sort(.. .)

Campbell Barton cbarton at metavr.com
Mon Aug 20 12:08:59 CEST 2007


Revision: 11732
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11732
Author:   campbellbarton
Date:     2007-08-20 12:08:59 +0200 (Mon, 20 Aug 2007)

Log Message:
-----------
added face sorting to mesh so you can do mesh.faces.sort(...)
uses list sorting internally so is exactly the same as list sorting.

Modified Paths:
--------------
    trunk/blender/source/blender/python/api2_2x/Mesh.c
    trunk/blender/source/blender/python/api2_2x/doc/Mesh.py
    trunk/blender/source/blender/python/api2_2x/gen_utils.c
    trunk/blender/source/blender/python/api2_2x/gen_utils.h

Modified: trunk/blender/source/blender/python/api2_2x/Mesh.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/Mesh.c	2007-08-20 08:40:14 UTC (rev 11731)
+++ trunk/blender/source/blender/python/api2_2x/Mesh.c	2007-08-20 10:08:59 UTC (rev 11732)
@@ -5548,6 +5548,70 @@
 	Py_RETURN_NONE;
 }
 
+/* copied from meshtools.c - should make generic? */
+static void permutate(void *list, int num, int size, int *index)
+{
+	void *buf;
+	int len;
+	int i;
+
+	len = num * size;
+
+	buf = MEM_mallocN(len, "permutate");
+	memcpy(buf, list, len);
+	
+	for (i = 0; i < num; i++) {
+		memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
+	}
+	MEM_freeN(buf);
+}
+
+/* this wrapps list sorting then applies back to the mesh */
+static PyObject *MFaceSeq_sort( BPy_MEdgeSeq * self, PyObject *args,
+	  PyObject *keywds )
+{
+	PyObject *ret, *sort_func, *newargs;
+	
+	Mesh *mesh = self->mesh;
+	PyObject *sorting_list;
+	CustomDataLayer *layer;
+	int i, *index;
+	
+	/* get a list for internal use */
+	sorting_list = PySequence_List( (PyObject *)self );
+	if( !sorting_list )
+		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+				"PyList_New() failed" );
+	
+	/* create index list */
+	index = (int *) MEM_mallocN(sizeof(int) * mesh->totface, "sort faces");
+	if (!index)
+		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+				"faces.sort(...) failed to allocate memory" );
+	
+	newargs = EXPP_PyTuple_New_Prepend(args, sorting_list);
+	sort_func = PyObject_GetAttrString( ((PyObject *)&PyList_Type), "sort");
+	
+	ret = PyObject_Call(sort_func, newargs, keywds);
+	
+	Py_DECREF(newargs);
+	Py_DECREF(sort_func);
+	
+	if (ret) {
+		/* copy the faces indicies to index */
+		for (i = 0; i < mesh->totface; i++)
+			index[i] = ((BPy_MFace *)PyList_GET_ITEM(sorting_list, i))->index;
+		
+		for(i = 0; i < mesh->fdata.totlayer; i++) {
+			layer = &mesh->fdata.layers[i];
+			permutate(layer->data, mesh->totface, CustomData_sizeof(layer->type), index);
+		}
+	}
+	Py_DECREF(sorting_list);
+	MEM_freeN(index);
+	return ret;
+}
+
 static PyObject *MFaceSeq_selected( BPy_MFaceSeq * self )
 {
 	int i, count;
@@ -5611,6 +5675,8 @@
 		"add faces to mesh"},
 	{"delete", (PyCFunction)MFaceSeq_delete, METH_VARARGS,
 		"delete faces from mesh"},
+	{"sort", (PyCFunction)MFaceSeq_sort, METH_VARARGS|METH_KEYWORDS,
+		"sort the faces using list sorts syntax"},
 	{"selected", (PyCFunction)MFaceSeq_selected, METH_NOARGS,
 		"returns a list containing indices of selected faces"},
 	{"addPropertyLayer",(PyCFunction)MFaceSeq_add_layertype, METH_VARARGS,
@@ -5618,7 +5684,7 @@
 	{"removePropertyLayer",(PyCFunction)MFaceSeq_del_layertype, METH_O,
 		"removes a property layer"},
 	{"renamePropertyLayer",(PyCFunction)MFaceSeq_rename_layertype, METH_VARARGS,
-		"renames an existing property layer"},
+		"renames an existing property layer"},		
 	{NULL, NULL, 0, NULL}
 };
 static PyGetSetDef BPy_MFaceSeq_getseters[] = {

Modified: trunk/blender/source/blender/python/api2_2x/doc/Mesh.py
===================================================================
--- trunk/blender/source/blender/python/api2_2x/doc/Mesh.py	2007-08-20 08:40:14 UTC (rev 11731)
+++ trunk/blender/source/blender/python/api2_2x/doc/Mesh.py	2007-08-20 10:08:59 UTC (rev 11732)
@@ -690,6 +690,22 @@
 			- a integer, specifying an index into the mesh's face list
 		"""
 
+	def sort():
+		"""
+		Sorts the faces using exactly the same syntax as pythons own list sorting function.
+
+		Example::
+			import Blender
+			from Blender import Mesh
+			me = Mesh.Get('mymesh')
+			
+			me.faces.sort(key=lambda f: f.area)
+			
+			me.faces.sort(key=lambda f: f.cent)
+		
+		@note: Internally faces only refer to their index, so after sorting, faces you alredy have will not have their index changed to match the new sorted order. 
+		"""
+		
 	def selected():
 		"""
 		Get selected faces.

Modified: trunk/blender/source/blender/python/api2_2x/gen_utils.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/gen_utils.c	2007-08-20 08:40:14 UTC (rev 11731)
+++ trunk/blender/source/blender/python/api2_2x/gen_utils.c	2007-08-20 10:08:59 UTC (rev 11732)
@@ -918,3 +918,31 @@
 	Py_DECREF( value ); /* delete original */
 	return ret;
 }
+
+/*
+ * Helper function for subtypes that what the base types methods.
+ * The command below needs to have args modified to have 'self' added at the start
+ * ret = PyObject_Call(PyDict_GetItemString(PyList_Type.tp_dict, "sort"), newargs, keywds);
+ * 
+ * This is not easy with the python API so adding a function here,
+ * remember to Py_DECREF the tuple after
+ */
+
+PyObject * EXPP_PyTuple_New_Prepend(PyObject *tuple, PyObject *value)
+{
+	PyObject *item;
+	PyObject *new_tuple;
+	int i;
+	
+	i = PyTuple_Size(tuple);
+	new_tuple = PyTuple_New(i+1);
+	PyTuple_SetItem(new_tuple, 0, value);
+	Py_INCREF(value);
+	while (i) {
+		i--;
+		item = PyTuple_GetItem(tuple, i);
+		PyTuple_SetItem(new_tuple, i+1, item);
+		Py_INCREF(item);
+	}
+	return new_tuple;
+}
\ No newline at end of file

Modified: trunk/blender/source/blender/python/api2_2x/gen_utils.h
===================================================================
--- trunk/blender/source/blender/python/api2_2x/gen_utils.h	2007-08-20 08:40:14 UTC (rev 11731)
+++ trunk/blender/source/blender/python/api2_2x/gen_utils.h	2007-08-20 10:08:59 UTC (rev 11732)
@@ -170,6 +170,7 @@
 
 /* helper to keep dictionaries from causing memory leaks */
 int EXPP_dict_set_item_str( PyObject *dict, char *key, PyObject *value);
+PyObject * EXPP_PyTuple_New_Prepend(PyObject *tuple, PyObject *value);
 
 #endif				/* EXPP_gen_utils_h */
 




More information about the Bf-blender-cvs mailing list