Page MenuHome

[mathutils.bvhtree] Separate methods for creating the BVHTree of its own BVHTree class (now BVHTriData)
AbandonedPublic

Authored by Germano Cavalcante (mano-wii) on Feb 15 2016, 5:30 AM.

Details

Summary

The BVHTree functions should not be limited to trees of tris.
They may extend to any element that can be contained within a volume (such as edges, vertices, polygons, objects ...).
So the first thing to do is to separate the methods of creating the tree of its own class that will have the settings of tris.

With this patch the mathutils.bvhtree module works like this:

>>> from mathutils import bvhtree
>>> bvhtree.from_
                 bmesh_faces(
                 object_polygons(
                 polygons(
>>> treeTri = bvhtree.from_object_polygons(C.object, C.scene)
>>> treeTri.
            find_nearest(
            overlap(
            ray_cast(

It is also important to allow the user to create their own kinds of BVHTrees, so the settings of a BVHTree can now be stored in the UserData class, and finally the tree can be created.
Here is a example of using customized BVHTrees:

import bpy
from mathutils import bvhtree, geometry
print("------------------------------")

## defining userdata ##
my_userdata = bvhtree.UserData()

## setting up userdata ##
obj = bpy.context.object
vertices = [v.co for v in obj.data.vertices]
indices = [e.vertices for e in obj.data.edges] #edges
my_userdata.set_coords(vertices, indices)

## defining a custom "find_nearest" callback ##
my_ret_co = None # the result will be stored here
dist_sq = 1000 # max dist squared 
def find_nearest_to_edge_cb(self, co, index):
    global dist_sq
    global my_ret_co
    edge = self.coords[index]
    isect, fac = geometry.intersect_point_line(co, *edge)
    if fac <= 0:
        isect = edge[0]
    elif fac >= 1:
        isect = edge[1]

    tmp_dist_sq = (isect-co).length_squared
    if tmp_dist_sq < dist_sq:
        dist_sq = tmp_dist_sq
        my_ret_co = isect
        return dist_sq

my_userdata.find_nearest_callback = find_nearest_to_edge_cb

## creating tree ##
tree = bvhtree.BVHTree(my_userdata)

## Executing the custom find_nearest (no return) ##
print("Previous", my_ret_co)
my_coord = obj.matrix_world.inverted() * bpy.context.scene.cursor_location

tree.find_nearest(my_coord) # the custom callback is being used here

print("New", my_ret_co)

bpy.context.scene.cursor_location = obj.matrix_world * my_ret_co

del tree
del my_userdata

I also changed the Non returns of raycast and find_nearest from (None, None, None, None) to only None (This summarizes the code).

Diff Detail

Event Timeline

Germano Cavalcante (mano-wii) retitled this revision from to [mathutils.bvhtree] Separate methods for creating the BVH Tree of its own BVHTree class.
Germano Cavalcante (mano-wii) updated this object.
Germano Cavalcante (mano-wii) set the repository for this revision to rB Blender.
  • Fixed a major bug mine, the choice of tree
  • forgotten editions to correct the last error
Germano Cavalcante (mano-wii) updated this object.
  • removes nearest_to_ray and get_tri methods.

@Campbell Barton (campbellbarton) since the commit rB08fb55ee is already breaking the API for 2.77 (e.g., retopoflow needs an update), isn't it a good time to push this change as well? Code aside, I find this functionality (the possibility of vertex snapping) really relevant for Blender (e.g., for an Object Mode architecture measurement addon).

Germano Cavalcante (mano-wii) retitled this revision from [mathutils.bvhtree] Separate methods for creating the BVH Tree of its own BVHTree class to [mathutils.bvhtree] Separate methods for creating the BVHTree of its own BVHTree class (now BVHTriData).
Germano Cavalcante (mano-wii) updated this object.
Germano Cavalcante (mano-wii) removed rB Blender as the repository for this revision.

Since now PyBVHTree is a subtype of BVHTriData and the PyBVHTree is an independent PyObject with its own destructor. It has now been added as a member of the class BVHTriData.

Germano Cavalcante (mano-wii) updated this object.

All types of BVH Tree may be contained in a single struct PyUserData

This patch is getting outdated and disorganized.
Here a branch that promises the same changes:
https://developer.blender.org/diffusion/BS/history/mathutils_bvhtree_extension2/