Finding the top of an object?

How can I us the API to put the 3D cursor on the top of the active object (max Y)? If the selected object is text, then the origin is at the bottom. So that would be location.y+dimension.y. However, I don’t always know it is text. It could be anything and the origin can be anywhere. I’m sure I’m missing something easy, but I just can’t find the attribute I’m looking for.

bounding box max or “local” max?

I guess “local” max, but I’d think they would be the same thing, wouldn’t they? If you were to orient the 3D view by hitting 7, what is the highest a horizontal plane can be while still touching the top edge?

When I try to use the bounding box (bpy.context.scene.objects.active.bound_box.data.location or .dimensions) it reports the same location as bpy.context.scene.objects.active.location and bpy.context.scene.objects.active.dimensions. I can move the origin somewhere far off, and the location will then become the new origin, yet the dimensions remain the same. If the “location” of the bounding box was always the center of the bounding box, then that would be all I needed, but it doesn’t seem to work that way.

It sounds like you want to find the highest Y-value for the object in World space. To do this you can multiply the bounding box coordinates by the Objects ‘matrix_world’ property.

Note, that depending on the shape of your model and if you rotate it in addition to translating it, then this might give results that are higher than the highest point in the model. If you are rotating the model and you need an exact answer, then the answer becomes a little more tricky. You will have to rotate the object then project all the vertices onto the Y-axis to find the highest one.


import bpy
from mathutils import Vector


def maxY(obj):
    
    # Pick a max Y that should be smaller than anything else in the scene
    maxY = -100000
    
    # Find the max Y by moving the bounding box into World Space
    for coord in obj.bound_box:
        worldCoord = obj.matrix_world * Vector( (coord[0], coord[1], coord[2]) )
        
        maxY = max(maxY, worldCoord.y)


    return maxY
    
if __name__ == "__main__":
    print(maxY(bpy.context.active_object))

That worked like a champ. I appreciate it!