fix: bbox work for non-mesh objects+ins.collection
This commit is contained in:
parent
37cfed489c
commit
5098e5135d
@ -94,15 +94,35 @@ def project_to_viewport(region: bpy.types.Region, rv3d: bpy.types.RegionView3D,
|
|||||||
return [target.x, target.y, target.z]
|
return [target.x, target.y, target.z]
|
||||||
|
|
||||||
|
|
||||||
def bbox_from_obj(obj: bpy.types.Object, radius: float) -> list:
|
def bbox_from_obj(obj: bpy.types.Object) -> list:
|
||||||
""" Generate a bounding box for a given object by using its world matrix
|
""" Generate a bounding box for a given object by using its world matrix
|
||||||
|
|
||||||
:param obj: target object
|
:param obj: target object
|
||||||
:type obj: bpy.types.Object
|
:type obj: bpy.types.Object
|
||||||
:param radius: bounding box radius
|
:return: list of 8 points [(x,y,z),...], list of 12 link between these points [(1,2),...]
|
||||||
:type radius: float
|
|
||||||
:return: list of 8 points [(x,y,z),...]
|
|
||||||
"""
|
"""
|
||||||
|
radius = 1.0 # Radius of the bounding box
|
||||||
|
vertex_indices = (
|
||||||
|
(0, 1), (0, 2), (1, 3), (2, 3),
|
||||||
|
(4, 5), (4, 6), (5, 7), (6, 7),
|
||||||
|
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||||
|
|
||||||
|
if obj.type == 'EMPTY':
|
||||||
|
radius = obj.empty_display_size
|
||||||
|
elif obj.type == 'LIGHT':
|
||||||
|
radius = obj.data.shadow_soft_size
|
||||||
|
elif obj.type == 'LIGHT_PROBE':
|
||||||
|
radius = obj.data.influence_distance
|
||||||
|
elif obj.type == 'CAMERA':
|
||||||
|
radius = obj.data.display_size
|
||||||
|
elif hasattr(obj, 'bound_box'):
|
||||||
|
vertex_indices = (
|
||||||
|
(0, 1), (1, 2), (2, 3), (0, 3),
|
||||||
|
(4, 5), (5, 6), (6, 7), (4, 7),
|
||||||
|
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||||
|
vertex_pos = get_bb_coords_from_obj(obj)
|
||||||
|
return vertex_pos, vertex_indices
|
||||||
|
|
||||||
coords = [
|
coords = [
|
||||||
(-radius, -radius, -radius), (+radius, -radius, -radius),
|
(-radius, -radius, -radius), (+radius, -radius, -radius),
|
||||||
(-radius, +radius, -radius), (+radius, +radius, -radius),
|
(-radius, +radius, -radius), (+radius, +radius, -radius),
|
||||||
@ -112,9 +132,41 @@ def bbox_from_obj(obj: bpy.types.Object, radius: float) -> list:
|
|||||||
base = obj.matrix_world
|
base = obj.matrix_world
|
||||||
bbox_corners = [base @ mathutils.Vector(corner) for corner in coords]
|
bbox_corners = [base @ mathutils.Vector(corner) for corner in coords]
|
||||||
|
|
||||||
return [(point.x, point.y, point.z)
|
vertex_pos = [(point.x, point.y, point.z) for point in bbox_corners]
|
||||||
for point in bbox_corners]
|
|
||||||
|
|
||||||
|
return vertex_pos, vertex_indices
|
||||||
|
|
||||||
|
def bbox_from_instance_collection(ic: bpy.types.Object) -> list:
|
||||||
|
""" Generate a bounding box for a given instance collection by using its objects
|
||||||
|
|
||||||
|
:param ic: target instance collection
|
||||||
|
:type ic: bpy.types.Object
|
||||||
|
:param radius: bounding box radius
|
||||||
|
:type radius: float
|
||||||
|
:return: list of 8*objs points [(x,y,z),...], tuple of 12*objs link between these points [(1,2),...]
|
||||||
|
"""
|
||||||
|
vertex_pos = []
|
||||||
|
vertex_indices = ()
|
||||||
|
nb_obj = 0
|
||||||
|
|
||||||
|
for obj in ic.instance_collection.objects:
|
||||||
|
vertex_pos_temp, vertex_indices_temp = bbox_from_obj(obj)
|
||||||
|
vertex_pos += vertex_pos_temp
|
||||||
|
|
||||||
|
vertex_indices_list_temp = list(list(indice) for indice in vertex_indices_temp)
|
||||||
|
for indice in vertex_indices_list_temp:
|
||||||
|
indice[0] += 8*nb_obj
|
||||||
|
indice[1] += 8*nb_obj
|
||||||
|
vertex_indices_temp = tuple(tuple(indice) for indice in vertex_indices_list_temp)
|
||||||
|
vertex_indices += vertex_indices_temp
|
||||||
|
|
||||||
|
nb_obj += 1
|
||||||
|
|
||||||
|
bbox_corners = [ic.matrix_world @ mathutils.Vector(vertex) for vertex in vertex_pos]
|
||||||
|
|
||||||
|
vertex_pos = [(point.x, point.y, point.z) for point in bbox_corners]
|
||||||
|
|
||||||
|
return vertex_pos, vertex_indices
|
||||||
|
|
||||||
def generate_user_camera() -> list:
|
def generate_user_camera() -> list:
|
||||||
""" Generate a basic camera represention of the user point of view
|
""" Generate a basic camera represention of the user point of view
|
||||||
@ -296,36 +348,14 @@ class UserSelectionWidget(Widget):
|
|||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
user_selection = self.data.get('selected_objects')
|
user_selection = self.data.get('selected_objects')
|
||||||
for select_ob in user_selection:
|
for select_obj in user_selection:
|
||||||
ob = find_from_attr("uuid", select_ob, bpy.data.objects)
|
obj = find_from_attr("uuid", select_obj, bpy.data.objects)
|
||||||
if not ob:
|
if not obj:
|
||||||
return
|
return
|
||||||
|
if obj.instance_collection:
|
||||||
vertex_pos = bbox_from_obj(ob, 1.0)
|
vertex_pos, vertex_indices = bbox_from_instance_collection(obj)
|
||||||
vertex_indices = (
|
else :
|
||||||
(0, 1), (1, 2), (2, 3), (0, 3),
|
vertex_pos, vertex_indices = bbox_from_obj(obj)
|
||||||
(4, 5), (5, 6), (6, 7), (4, 7),
|
|
||||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
|
||||||
|
|
||||||
if ob.instance_collection:
|
|
||||||
for obj in ob.instance_collection.objects:
|
|
||||||
if obj.type == 'MESH' and hasattr(obj, 'bound_box'):
|
|
||||||
vertex_pos = get_bb_coords_from_obj(obj, instance=ob)
|
|
||||||
break
|
|
||||||
elif ob.type == 'EMPTY':
|
|
||||||
vertex_pos = bbox_from_obj(ob, ob.empty_display_size)
|
|
||||||
elif ob.type == 'LIGHT':
|
|
||||||
vertex_pos = bbox_from_obj(ob, ob.data.shadow_soft_size)
|
|
||||||
elif ob.type == 'LIGHT_PROBE':
|
|
||||||
vertex_pos = bbox_from_obj(ob, ob.data.influence_distance)
|
|
||||||
elif ob.type == 'CAMERA':
|
|
||||||
vertex_pos = bbox_from_obj(ob, ob.data.display_size)
|
|
||||||
elif hasattr(ob, 'bound_box'):
|
|
||||||
vertex_indices = (
|
|
||||||
(0, 1), (1, 2), (2, 3), (0, 3),
|
|
||||||
(4, 5), (5, 6), (6, 7), (4, 7),
|
|
||||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
|
||||||
vertex_pos = get_bb_coords_from_obj(ob)
|
|
||||||
|
|
||||||
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
||||||
batch = batch_for_shader(
|
batch = batch_for_shader(
|
||||||
@ -338,7 +368,6 @@ class UserSelectionWidget(Widget):
|
|||||||
shader.uniform_float("color", self.data.get('color'))
|
shader.uniform_float("color", self.data.get('color'))
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
|
|
||||||
class UserNameWidget(Widget):
|
class UserNameWidget(Widget):
|
||||||
draw_type = 'POST_PIXEL'
|
draw_type = 'POST_PIXEL'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user