[Bf-blender-cvs] [2e0fa54] mathutils_bvhtree: Support for BVHTree construction and ray casting from a BMesh.
Lukas Tönne
noreply at git.blender.org
Sat Jan 3 11:09:19 CET 2015
Commit: 2e0fa54eb1cd350c83fb4c889328c11facf699ec
Author: Lukas Tönne
Date: Thu Dec 18 13:40:30 2014 +0100
Branches: mathutils_bvhtree
https://developer.blender.org/rB2e0fa54eb1cd350c83fb4c889328c11facf699ec
Support for BVHTree construction and ray casting from a BMesh.
===================================================================
M source/blender/python/mathutils/CMakeLists.txt
M source/blender/python/mathutils/mathutils_bvhtree.c
===================================================================
diff --git a/source/blender/python/mathutils/CMakeLists.txt b/source/blender/python/mathutils/CMakeLists.txt
index 54eeef6..c744673 100644
--- a/source/blender/python/mathutils/CMakeLists.txt
+++ b/source/blender/python/mathutils/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
.
../../blenlib
../../blenkernel
+ ../../bmesh
../../makesdna
../../../../intern/guardedalloc
)
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 3de77d6..a47777e 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -42,7 +42,10 @@
#include "BKE_DerivedMesh.h"
#include "BKE_editmesh_bvh.h"
+#include "bmesh.h"
+
#include "../generic/py_capi_utils.h"
+#include "../bmesh/bmesh_py_types.h"
#include "mathutils.h"
#include "mathutils_bvhtree.h" /* own include */
@@ -280,6 +283,41 @@ static PyObject *py_BVHTree_from_object_edges(PyBVHTree *self, PyObject *args, P
Py_RETURN_NONE;
}
+PyDoc_STRVAR(py_BVHTree_from_bmesh_doc,
+".. method:: from_bmesh(object)\n"
+"\n"
+" Construct the BVHTree from a :class: BMesh.\n"
+"\n"
+" :arg bm: BMesh instance used for constructing the BVH tree.\n"
+" :type bm: :class:`BMesh`\n"
+);
+static PyObject *py_BVHTree_from_bmesh(PyBVHTree *self, PyObject *args, PyObject *kwargs)
+{
+ const char *keywords[] = {"bm", NULL};
+
+ PyObject *py_bm;
+ BMesh *bm;
+ int looptris_tot;
+ BMLoop *(*looptris)[3];
+ int flag = 0; /* TODO add optional RESPECT_SELECT and RESPECT_HIDDEN flag options */
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *)"O!:from_bmesh", (char **)keywords,
+ &BPy_BMesh_Type, &py_bm))
+ {
+ return NULL;
+ }
+ bm = ((BPy_BMesh *)py_bm)->bm;
+
+ /* free existing data */
+ free_BVHTree(self);
+
+ looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ looptris = MEM_mallocN(sizeof(*looptris) * (size_t)looptris_tot, __func__);
+ self->bmdata = BKE_bmbvh_new(bm, looptris, looptris_tot, flag, NULL, false);
+
+ Py_RETURN_NONE;
+}
+
PyDoc_STRVAR(py_BVHTree_clear_doc,
".. method:: clear()\n"
"\n"
@@ -311,44 +349,57 @@ static PyObject *py_BVHTree_ray_cast(PyBVHTree *self, PyObject *args, PyObject *
static const float ZERO[3] = {0.0f, 0.0f, 0.0f};
BVHTreeFromMesh *meshdata = &self->meshdata;
+ BMBVHTree *bmdata = self->bmdata;
Object *ob = self->ob;
const char *keywords[] = {"ray_start", "ray_end", "use_poly_index", NULL};
- PyObject *py_start, *py_end;
- float start[3], end[3];
+ PyObject *py_ray_start, *py_ray_end;
+ float ray_start[3], ray_end[3];
int use_poly_index = true;
- float ray_nor[3], dist;
- BVHTreeRayHit hit;
+ float ray_nor[3], ray_len;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *)"O!O!|i:ray_cast", (char **)keywords,
- &vector_Type, &py_start,
- &vector_Type, &py_end,
+ &vector_Type, &py_ray_start,
+ &vector_Type, &py_ray_end,
&use_poly_index))
{
return NULL;
}
- if (!parse_vector(py_start, start))
+ if (!parse_vector(py_ray_start, ray_start))
return NULL;
- if (!parse_vector(py_end, end))
+ if (!parse_vector(py_ray_end, ray_end))
return NULL;
- sub_v3_v3v3(ray_nor, end, start);
- dist = hit.dist = normalize_v3(ray_nor);
- hit.index = -1;
+ sub_v3_v3v3(ray_nor, ray_end, ray_start);
+ ray_len = normalize_v3(ray_nor);
/* may fail if the mesh has no faces, in that case the ray-cast misses */
if (meshdata->tree && meshdata->raycast_callback && ob->derivedFinal)
{
- if (BLI_bvhtree_ray_cast(meshdata->tree, start, ray_nor, 0.0f, &hit,
+ BVHTreeRayHit hit;
+ hit.dist = ray_len;
+ hit.index = -1;
+
+ if (BLI_bvhtree_ray_cast(meshdata->tree, ray_start, ray_nor, 0.0f, &hit,
meshdata->raycast_callback, meshdata) != -1)
{
- if (hit.dist <= dist) {
+ if (hit.dist <= ray_len) {
int ret_index = use_poly_index ? dm_tessface_to_poly_index_safe(ob->derivedFinal, hit.index) : hit.index;
return bvhtree_ray_hit_to_py(hit.co, hit.no, ret_index, hit.dist);
}
}
}
+ else if (bmdata) {
+ BMFace *hit_face;
+ float hit_co[3], hit_dist;
+
+ hit_face = BKE_bmbvh_ray_cast(bmdata, ray_start, ray_nor, 0.0f, &hit_dist, hit_co, NULL);
+ if (hit_face && hit_dist <= ray_len) {
+ int ret_index = use_poly_index ? dm_tessface_to_poly_index_safe(ob->derivedFinal, BM_elem_index_get(hit_face)) : BM_elem_index_get(hit_face);
+ return bvhtree_ray_hit_to_py(hit_co, hit_face->no, ret_index, hit_dist);
+ }
+ }
return bvhtree_ray_hit_to_py(ZERO, ZERO, -1, 0.0f);
}
@@ -414,6 +465,7 @@ static PyMethodDef PyBVHTree_methods[] = {
{"from_object_verts", (PyCFunction)py_BVHTree_from_object_verts, METH_VARARGS | METH_KEYWORDS, py_BVHTree_from_object_verts_doc},
{"from_object_faces", (PyCFunction)py_BVHTree_from_object_faces, METH_VARARGS | METH_KEYWORDS, py_BVHTree_from_object_faces_doc},
{"from_object_edges", (PyCFunction)py_BVHTree_from_object_edges, METH_VARARGS | METH_KEYWORDS, py_BVHTree_from_object_edges_doc},
+ {"from_bmesh", (PyCFunction)py_BVHTree_from_bmesh, METH_VARARGS | METH_KEYWORDS, py_BVHTree_from_bmesh_doc},
{"clear", (PyCFunction)py_BVHTree_clear, METH_VARARGS | METH_KEYWORDS, py_BVHTree_clear_doc},
{"ray_cast", (PyCFunction)py_BVHTree_ray_cast, METH_VARARGS | METH_KEYWORDS, py_BVHTree_ray_cast_doc},
{"find_nearest", (PyCFunction)py_BVHTree_find_nearest, METH_VARARGS | METH_KEYWORDS, py_BVHTree_find_nearest_doc},
More information about the Bf-blender-cvs
mailing list