[Bf-blender-cvs] [5a26375] mathutils_bvhtree: Avoid using PySequence functions, instead use PySequence_Fast

Campbell Barton noreply at git.blender.org
Wed Jul 15 18:58:02 CEST 2015


Commit: 5a2637538dce95a9503e701370f8ea29ad0f2e15
Author: Campbell Barton
Date:   Thu Jul 16 02:52:12 2015 +1000
Branches: mathutils_bvhtree
https://developer.blender.org/rB5a2637538dce95a9503e701370f8ea29ad0f2e15

Avoid using PySequence functions, instead use PySequence_Fast

to support same featureset but avoid slow lookups.

Also fixes refcount leak accessing verts.

===================================================================

M	source/blender/python/mathutils/mathutils_bvhtree.c

===================================================================

diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 6fc2fa5..c1086dc 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -760,12 +760,14 @@ static BVHTree *bvhtree_from_triangles_create_tree(float epsilon, int tree_type,
 
 static int PyBVHTreeCustom__tp_init(PyBVHTree_Custom *self, PyObject *args, PyObject *kwargs)
 {
+	const char *error_prefix = "BVHTreeCustom";
 	const char *keywords[] = {"vertices", "triangles", NULL};
 	
 	PyObject *py_verts, *py_tris;
+	PyObject *py_verts_fast = NULL, *py_tris_fast = NULL;
 	int numverts, numtris;
-	BVHVertex *verts, *vp;
-	BVHTriangle *tris, *tp;
+	BVHVertex *verts = NULL;
+	BVHTriangle *tris = NULL;
 	int i;
 	bool valid = true;
 	
@@ -778,23 +780,20 @@ static int PyBVHTreeCustom__tp_init(PyBVHTree_Custom *self, PyObject *args, PyOb
 		return -1;
 	}
 	
-	if (!PySequence_Check(py_verts)) {
-		PyErr_SetString(PyExc_TypeError,
-		                "expected a sequence of vectors");
-		return -1;
-	}
-	
-	if (!PySequence_Check(py_tris)) {
-		PyErr_SetString(PyExc_TypeError,
-		                "expected a sequence of lists of integers");
-		return -1;
+	if (!(py_verts_fast = PySequence_Fast(py_verts, error_prefix)) ||
+	    !(py_tris_fast  = PySequence_Fast(py_tris, error_prefix)))
+	{
+		Py_XDECREF(py_verts_fast);
+		return NULL;
 	}
 	
 	if (valid) {
-		numverts = (int)PySequence_Size(py_verts);
+		BVHVertex *vp;
+
+		numverts = (int)PySequence_Fast_GET_SIZE(py_verts_fast);
 		vp = verts = MEM_mallocN(sizeof(BVHVertex) * (size_t)numverts, "BPy BVHTree vertices");
 		for (i = 0; i < numverts; i++, vp++) {
-			PyObject *py_vert = PySequence_GetItem(py_verts, i);
+			PyObject *py_vert = PySequence_Fast_GET_ITEM(py_verts_fast, i);
 			
 			if (mathutils_array_parse(vp->co, 3, 3, py_vert, "BVHTree vertex: ") == -1) {
 				valid = false;
@@ -804,27 +803,38 @@ static int PyBVHTreeCustom__tp_init(PyBVHTree_Custom *self, PyObject *args, PyOb
 	}
 	
 	if (valid) {
-		numtris = (int)PySequence_Size(py_tris);
+		BVHTriangle *tp;
+
+		numtris = (int)PySequence_Fast_GET_SIZE(py_tris_fast);
 		/* now construct loop list */
 		tp = tris = MEM_mallocN(sizeof(BVHTriangle) * (size_t)numtris, "BPy BVHTree triangles");
 		for (i = 0; i < numtris; i++) {
-			PyObject *py_triverts = PySequence_GetItem(py_tris, i);
-			int tottri = (int)PySequence_Size(py_triverts);
+			PyObject *py_triverts = PySequence_Fast_GET_ITEM(py_tris_fast, i);
+			PyObject *py_triverts_fast = PySequence_Fast(py_triverts, error_prefix);
+
+			if (py_triverts_fast == NULL) {
+				valid = false;
+				break;
+			}
 			
-			if (tottri != 3) {
-				Py_XDECREF(py_triverts); /* may be null so use Py_XDECREF*/
+			if (PySequence_Fast_GET_SIZE(py_triverts_fast) != 3) {
+				Py_DECREF(py_triverts_fast);
 				PyErr_SetString(PyExc_TypeError,
 				                "One or more of the triangles does not have 3 indices");
 				valid = false;
 				break;
 			}
 			
-			tp->tri[0] = _PyLong_AsInt(PySequence_GetItem(py_triverts, 0));
-			tp->tri[1] = _PyLong_AsInt(PySequence_GetItem(py_triverts, 1));
-			tp->tri[2] = _PyLong_AsInt(PySequence_GetItem(py_triverts, 2));
+			tp->tri[0] = _PyLong_AsInt(PySequence_Fast_GET_ITEM(py_triverts_fast, 0));
+			tp->tri[1] = _PyLong_AsInt(PySequence_Fast_GET_ITEM(py_triverts_fast, 1));
+			tp->tri[2] = _PyLong_AsInt(PySequence_Fast_GET_ITEM(py_triverts_fast, 2));
+			Py_DECREF(py_triverts_fast);
 		}
 	}
 	
+	Py_DECREF(py_verts_fast);
+	Py_DECREF(py_tris_fast);
+
 	if (valid) {
 		self->vert_array = verts;
 		self->totvert = numverts;




More information about the Bf-blender-cvs mailing list