Page MenuHome

Python API: BVHTree return PyStructSequence instead of PyTuple
Needs RevisionPublic

Authored by Jacques Lucke (JacquesLucke) on Nov 1 2018, 12:34 PM.



From my own experience I know that using bvhtree.ray_cast(...) and similiar functions is always a bit annoying.
This is because these functions return a tuple and I always have to look into the documentation to find the correct order of the returned elements.
In Python namedtuples are there to solve this problem. A PyStructSequence in the CPython C API is the C equivalent of that.

This change breaks scripts that expect that bvhtree.ray_cast(...) and bvhtree.find_nearest(...) return a tuple when no surface point is found.
Instead of returning a tuple in that case, just None is returned. In my opinion that works much better in practice.

I haven't tested it but I don't expect there to be any noticable performance impact. We might even be able to speed it up later on by lazy generation of mathutils.Vector objects. I don't think this complexity is necessary atm. If we really want this api to support very fast access we should have new api functions that allow to run many queries at the same time + they should support the Python buffer protocol.

hit = bvhtree.ray_cast(origin, direction)
if hit is not None:
    do_something(hit.location, ...)

nearest = bvhtree.find_nearest(origin)
if nearest is not None:
    do_something(nearest.normal, ...)

When this patch is accepted, I'll update the already ported addons that use the bvhtree.
Furthermore I'll do the same change mathutils.KDTree.

Diff Detail

rB Blender
bvh_query_return (branched from blender2.8)
Build Status
Buildable 2360
Build 2360: arc lint + arc unit

Event Timeline

Campbell Barton (campbellbarton) requested changes to this revision.Nov 1 2018, 10:56 PM

Agree this is a paint-point, but overall, I'd rather not do this.
This is not so different to having to remember the order of arguments passed to a function (admittedly we have keyword arguments for that, nevertheless it's quite common not to use them even when available).

The issue with having per-return value types is we then need to document them, people will still need to check docs and forget which exact names to use for the named tuples.

In this case the values themselves are different enough (eg, it's not returning 10x floats which all do completely different things).

This is also about consistency in the general case: in nearly all cases it's fine to return tuples, if in 5% of cases it's slightly useful to return a different type it introduces some exceptional cases.

Overall this adds API and maintenance (where names will most likely become inconsistent between Python modules and therefor hard to remember, or we change them but break scripts).

Note: if you think this is an important improvement, I'd like to see a list of all areas of the API that'd use this, add support for RNA functions... and see how this would look once implemented.

This revision now requires changes to proceed.Nov 1 2018, 10:56 PM