[Bf-blender-cvs] [18af73e] master: Add mathutils.bvhtree API
Campbell Barton
noreply at git.blender.org
Wed Jul 29 13:29:16 CEST 2015
Commit: 18af73e461f9a943ae606fcc1401297f4afad20f
Author: Campbell Barton
Date: Wed Jul 29 21:16:28 2015 +1000
Branches: master
https://developer.blender.org/rB18af73e461f9a943ae606fcc1401297f4afad20f
Add mathutils.bvhtree API
Originally D966 by @lukastoenne, with own additions
- trees can be initialized from Object's, BMesh,
or passed in as vert+polygon arrays.
- original indices of ngons/faces are used. (instead of tessellated indices).
- ray_cast, find_nearest methods
- find overlapping faces between 2 trees
===================================================================
M doc/python_api/sphinx_doc_gen.py
M source/blender/python/mathutils/CMakeLists.txt
M source/blender/python/mathutils/mathutils.c
A source/blender/python/mathutils/mathutils_bvhtree.c
A source/blender/python/mathutils/mathutils_bvhtree.h
===================================================================
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 05ea0d0..4e14706 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -263,6 +263,7 @@ else:
"gpu",
"mathutils",
"mathutils.geometry",
+ "mathutils.bvhtree",
"mathutils.kdtree",
"mathutils.noise",
"freestyle",
@@ -1644,7 +1645,7 @@ def write_rst_contents(basepath):
standalone_modules = (
# mathutils
- "mathutils", "mathutils.geometry", "mathutils.kdtree", "mathutils.noise",
+ "mathutils", "mathutils.geometry", "mathutils.bvhtree", "mathutils.kdtree", "mathutils.noise",
# misc
"freestyle", "bgl", "blf", "gpu", "aud", "bpy_extras",
# bmesh, submodules are in own page
@@ -1796,6 +1797,7 @@ def write_rst_importable_modules(basepath):
"bpy.props" : "Property Definitions",
"mathutils" : "Math Types & Utilities",
"mathutils.geometry" : "Geometry Utilities",
+ "mathutils.bvhtree" : "BVHTree Utilities",
"mathutils.kdtree" : "KDTree Utilities",
"mathutils.noise" : "Noise Utilities",
"freestyle" : "Freestyle Module",
diff --git a/source/blender/python/mathutils/CMakeLists.txt b/source/blender/python/mathutils/CMakeLists.txt
index ef6b090..f70f893 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
)
@@ -37,6 +38,7 @@ set(SRC
mathutils_Matrix.c
mathutils_Quaternion.c
mathutils_Vector.c
+ mathutils_bvhtree.c
mathutils_geometry.c
mathutils_interpolate.c
mathutils_kdtree.c
@@ -48,6 +50,7 @@ set(SRC
mathutils_Matrix.h
mathutils_Quaternion.h
mathutils_Vector.h
+ mathutils_bvhtree.h
mathutils_geometry.h
mathutils_interpolate.h
mathutils_kdtree.h
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index ba7f351..ec249e8 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -600,6 +600,7 @@ static struct PyModuleDef M_Mathutils_module_def = {
#include "mathutils_geometry.h"
#include "mathutils_interpolate.h"
#ifndef MATH_STANDALONE
+# include "mathutils_bvhtree.h"
# include "mathutils_kdtree.h"
# include "mathutils_noise.h"
#endif
@@ -653,6 +654,11 @@ PyMODINIT_FUNC PyInit_mathutils(void)
PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
Py_INCREF(submodule);
+ /* BVHTree submodule */
+ PyModule_AddObject(mod, "bvhtree", (submodule = PyInit_mathutils_bvhtree()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
/* KDTree submodule */
PyModule_AddObject(mod, "kdtree", (submodule = PyInit_mathutils_kdtree()));
PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
new file mode 100644
index 0000000..b3b9532
--- /dev/null
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -0,0 +1,1193 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Lukas Toenne, Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/mathutils/mathutils_bvhtree.c
+ * \ingroup mathutils
+ *
+ * This file defines the 'mathutils.bvhtree' module, a general purpose module to access
+ * blenders bvhtree for mesh surface nearest-element search and ray casting.
+ */
+
+#include <Python.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_kdopbvh.h"
+#include "BLI_polyfill2d.h"
+#include "BLI_math.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+
+#include "BKE_bvhutils.h"
+
+#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
+
+#include "mathutils.h"
+#include "mathutils_bvhtree.h" /* own include */
+
+#ifndef MATH_STANDALONE
+#include "DNA_object_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_editmesh_bvh.h"
+
+#include "bmesh.h"
+
+#include "../bmesh/bmesh_py_types.h"
+#endif /* MATH_STANDALONE */
+
+
+#include "BLI_strict_flags.h"
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Docstring (snippets)
+ * \{ */
+
+#define PYBVH_FIND_GENERIC_DISTANCE_DOC \
+" :arg distance: Maximum distance threshold.\n" \
+" :type distance: float\n"
+
+#define PYBVH_FIND_GENERIC_RETURN_DOC \
+" :return: Returns a tuple (:class:`Vector` location, :class:`Vector` normal, int index, float distance),\n" \
+" Values will all be None if no hit is found.\n" \
+" :rtype: :class:`tuple`\n"
+
+#define PYBVH_FROM_GENERIC_EPSILON_DOC \
+" :arg epsilon: Increase the threshold for detecting overlap and raycast hits.\n" \
+" :type epsilon: float\n"
+
+/** \} */
+
+/* sqrt(FLT_MAX) */
+#define PYBVH_MAX_DIST_STR "1.84467e+19"
+static const float max_dist_default = 1.844674352395373e+19f;
+
+static const char PY_BVH_TREE_TYPE_DEFAULT = 4;
+static const char PY_BVH_AXIS_DEFAULT = 6;
+
+typedef struct {
+ PyObject_HEAD
+ BVHTree *tree;
+ float epsilon;
+
+ float (*coords)[3];
+ unsigned int (*tris)[3];
+ unsigned int coords_len, tris_len;
+
+ /* Optional members */
+ /* aligned with 'tris' */
+ int *orig_index;
+ /* aligned with array that 'orig_index' points to */
+ float (*orig_normal)[3];
+} PyBVHTree;
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Utility helper functions
+ * \{ */
+
+static PyObject *bvhtree_CreatePyObject(
+ BVHTree *tree, float epsilon,
+
+ float (*coords)[3], unsigned int coords_len,
+ unsigned int (*tris)[3], unsigned int tris_len,
+
+ /* optional arrays */
+ int *orig_index, float (*orig_normal)[3])
+{
+ PyBVHTree *result = PyObject_New(PyBVHTree, &PyBVHTree_Type);
+
+ result->tree = tree;
+ result->epsilon = epsilon;
+
+ result->coords = coords;
+ result->tris = tris;
+ result->coords_len = coords_len;
+ result->tris_len = tris_len;
+
+ result->orig_index = orig_index;
+ result->orig_normal = orig_normal;
+
+ return (PyObject *)result;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name BVHTreeRayHit to Python utilities
+ * \{ */
+
+static void py_bvhtree_raycast_to_py_tuple(const BVHTreeRayHit *hit, PyObject *py_retval)
+{
+ BLI_assert(hit->index >= 0);
+ BLI_assert(PyTuple_GET_SIZE(py_retval) == 4);
+
+ PyTuple_SET_ITEMS(py_retval,
+ Vector_CreatePyObject(hit->co, 3, NULL),
+ Vector_CreatePyObject(hit->no, 3, NULL),
+ PyLong_FromLong(hit->index),
+ PyFloat_FromDouble(hit->dist));
+
+}
+
+static PyObject *py_bvhtree_raycast_to_py(const BVHTreeRayHit *hit)
+{
+ PyObject *py_retval = PyTuple_New(4);
+
+ py_bvhtree_raycast_to_py_tuple(hit, py_retval);
+
+ return py_retval;
+}
+
+static PyObject *py_bvhtree_raycast_to_py_none(void)
+{
+ PyObject *py_retval = PyTuple_New(4);
+
+ PyC_Tuple_Fill(py_retval, Py_None);
+
+ return py_retval;
+}
+
+#if 0
+static PyObject *py_bvhtree_raycast_to_py_and_check(const BVHTreeRayHit *hit)
+{
+ PyObject *py_retval;
+
+ py_retval = PyTuple_New(4);
+
+ if (hit->index != -1) {
+ py_bvhtree_raycast_to_py_tuple(hit, py_retval);
+ }
+ else {
+ PyC_Tuple_Fill(py_retval, Py_None);
+ }
+
+ return py_retval;
+}
+#endif
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name BVHTreeNearest to Python utilities
+ * \{ */
+
+static void py_bvhtree_nearest_to_py_tuple(const BVHTreeNearest *nearest, PyObject *py_retval)
+{
+ BLI_assert(nearest->index >= 0);
+ BLI_assert(PyTuple_GET_SIZE(py_retval) == 4);
+
+ PyTuple_SET_ITEMS(py_retval,
+ Vector_CreatePyObject(nearest->co, 3, NULL),
+ Vector_CreatePyObject(nearest->no, 3, NULL),
+ PyLong_FromLong(nearest->index),
+ PyFloat_FromDouble(sqrtf(nearest->dist_sq)));
+
+}
+
+static PyObject *py_bvhtree_nearest_to_py(const BVHTreeNearest *nearest)
+{
+ PyObject *py_retval = PyTuple_New(4);
+
+ py_bvhtree_nearest_to_py_tuple(nearest, py_retval);
+
+ return py_retval;
+}
+
+static PyObject *py_bvhtree_nearest_to_py_none(void)
+{
+ PyObject *py_retval = PyTuple_New(4);
+
+ PyC_Tuple_Fill(py_retval, Py_None);
+
+ return py_retval;
+}
+
+#if 0
+static PyObject *py_bvhtree_nearest_to_py_and_check(const BVHTreeNearest *nearest)
+{
+ PyObject *py_retval;
+
+ py_retval = PyTuple_New(4);
+
+ if (nearest->index != -1) {
+ py_bvhtree_nearest_to_py_tuple(nearest, py_retval);
+ }
+ else {
+ PyC_Tuple_Fill(py_retval, Py_None);
+ }
+
+ return py_retval;
+}
+#endif
+
+/** \} */
+
+static void py_bvhtree__tp_dealloc(PyBVHTree *self)
+{
+ if (self->tree) {
+ BLI_bvhtree_free(self->tree);
+ }
+
+ MEM_SAFE_FREE(self->coords);
+ MEM_SAFE_FREE(self->tris);
+
+ MEM_SAFE_FREE(self->orig_index);
+ MEM_SAFE_FREE(self->orig_normal);
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Methods
+ * \{ */
+
+static void py_bvhtree_raycast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+ const PyBVHTree *self = userdata;
+
+ const float (*coords)[3] = self->coords;
+ const un
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list