mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Fix #2979. Batch drawling unselected and selected cut lines.
This commit is contained in:
@@ -1908,45 +1908,29 @@ class CutDecorator:
|
|||||||
cls.installed = None
|
cls.installed = None
|
||||||
|
|
||||||
def __call__(self, context):
|
def __call__(self, context):
|
||||||
for obj in self.get_objects(None):
|
all_vertices = []
|
||||||
self.decorate(context, obj)
|
all_edges = []
|
||||||
|
selected_vertices = []
|
||||||
|
selected_edges = []
|
||||||
|
all_vertex_i_offset = 0
|
||||||
|
selected_vertex_i_offset = 0
|
||||||
|
for obj in [o for o in bpy.context.visible_objects if o.type == "MESH"]:
|
||||||
|
verts, edges = self.decorate(context, obj)
|
||||||
|
if not verts:
|
||||||
|
continue
|
||||||
|
|
||||||
def get_objects(self, collection):
|
if obj.select_get():
|
||||||
return [o for o in bpy.context.visible_objects if o.type == "MESH"]
|
selected_vertices.extend(verts)
|
||||||
|
selected_edges.extend([[vi + selected_vertex_i_offset for vi in e] for e in edges])
|
||||||
def draw_batch(self, shader_type, content_pos, color, indices=None):
|
selected_vertex_i_offset += len(verts)
|
||||||
shader = self.line_shader if shader_type == "LINES" else self.shader
|
else:
|
||||||
batch = batch_for_shader(shader, shader_type, {"pos": content_pos}, indices=indices)
|
all_vertices.extend(verts)
|
||||||
shader.uniform_float("color", color)
|
all_edges.extend([[vi + all_vertex_i_offset for vi in e] for e in edges])
|
||||||
batch.draw(shader)
|
all_vertex_i_offset += len(verts)
|
||||||
|
|
||||||
def decorate(self, context, obj):
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
|
||||||
if not element:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Currently selected objects shall not be cached as they may be being moved / edited.
|
|
||||||
# If the camera is selected, we also disable the cache as the user may be moving the camera.
|
|
||||||
if obj.select_get() or context.scene.camera.select_get():
|
|
||||||
all_vertices, all_edges = None, None
|
|
||||||
else:
|
|
||||||
all_vertices, all_edges = DecoratorData.cut_cache.get(element.id(), (None, None))
|
|
||||||
|
|
||||||
if all_vertices is False:
|
|
||||||
return
|
|
||||||
|
|
||||||
if not self.is_intersecting_camera(obj, context.scene.camera):
|
|
||||||
DecoratorData.cut_cache[element.id()] = (False, False)
|
|
||||||
return
|
|
||||||
|
|
||||||
if all_vertices is None:
|
|
||||||
all_vertices, all_edges = self.bisect_mesh(obj, context.scene.camera)
|
|
||||||
DecoratorData.cut_cache[element.id()] = (all_vertices, all_edges)
|
|
||||||
|
|
||||||
gpu.state.point_size_set(2)
|
gpu.state.point_size_set(2)
|
||||||
gpu.state.blend_set("ALPHA")
|
gpu.state.blend_set("ALPHA")
|
||||||
|
|
||||||
### Actually drawing
|
|
||||||
# 3D_POLYLINE_UNIFORM_COLOR is good for smoothed lines since `bgl.enable(GL_LINE_SMOOTH)` is deprecated
|
# 3D_POLYLINE_UNIFORM_COLOR is good for smoothed lines since `bgl.enable(GL_LINE_SMOOTH)` is deprecated
|
||||||
self.line_shader = gpu.shader.from_builtin("3D_POLYLINE_UNIFORM_COLOR")
|
self.line_shader = gpu.shader.from_builtin("3D_POLYLINE_UNIFORM_COLOR")
|
||||||
self.line_shader.bind()
|
self.line_shader.bind()
|
||||||
@@ -1959,10 +1943,44 @@ class CutDecorator:
|
|||||||
self.shader.bind()
|
self.shader.bind()
|
||||||
|
|
||||||
green = (0.545, 0.863, 0, 1)
|
green = (0.545, 0.863, 0, 1)
|
||||||
white = (0, 0, 0, 1)
|
black = (0, 0, 0, 1)
|
||||||
color = green if obj.select_get() else white
|
|
||||||
self.draw_batch("LINES", all_vertices, color, all_edges)
|
if all_vertices:
|
||||||
self.draw_batch("POINTS", all_vertices, color)
|
self.draw_batch("LINES", all_vertices, black, all_edges)
|
||||||
|
self.draw_batch("POINTS", all_vertices, black)
|
||||||
|
if selected_vertices:
|
||||||
|
self.draw_batch("LINES", selected_vertices, green, selected_edges)
|
||||||
|
self.draw_batch("POINTS", selected_vertices, green)
|
||||||
|
|
||||||
|
def draw_batch(self, shader_type, content_pos, color, indices=None):
|
||||||
|
shader = self.line_shader if shader_type == "LINES" else self.shader
|
||||||
|
batch = batch_for_shader(shader, shader_type, {"pos": content_pos}, indices=indices)
|
||||||
|
shader.uniform_float("color", color)
|
||||||
|
batch.draw(shader)
|
||||||
|
|
||||||
|
def decorate(self, context, obj):
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not element:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
# Currently selected objects shall not be cached as they may be being moved / edited.
|
||||||
|
# If the camera is selected, we also disable the cache as the user may be moving the camera.
|
||||||
|
if obj.select_get() or context.scene.camera.select_get():
|
||||||
|
verts, edges = None, None
|
||||||
|
else:
|
||||||
|
verts, edges = DecoratorData.cut_cache.get(element.id(), (None, None))
|
||||||
|
|
||||||
|
if verts is False:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
if not self.is_intersecting_camera(obj, context.scene.camera):
|
||||||
|
DecoratorData.cut_cache[element.id()] = (False, False)
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
if verts is None:
|
||||||
|
verts, edges = self.bisect_mesh(obj, context.scene.camera)
|
||||||
|
DecoratorData.cut_cache[element.id()] = (verts, edges)
|
||||||
|
return verts, edges
|
||||||
|
|
||||||
def is_intersecting_camera(self, obj, camera):
|
def is_intersecting_camera(self, obj, camera):
|
||||||
# Based on separating axis theorem
|
# Based on separating axis theorem
|
||||||
|
|||||||
Reference in New Issue
Block a user