mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 18:43:26 +00:00
Fix #5416. Optimise item decorator and make decoration more subtle to make it easier to see the mesh.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import blf
|
||||
import gpu
|
||||
import bmesh
|
||||
@@ -34,11 +35,51 @@ class ItemDecorator:
|
||||
def install(cls, context):
|
||||
if cls.is_installed:
|
||||
cls.uninstall()
|
||||
obj_is_selected = {}
|
||||
objs = {}
|
||||
for item_obj in context.scene.BIMGeometryProperties.item_objs:
|
||||
if obj := item_obj.obj:
|
||||
objs[obj.name] = cls.get_obj_data(obj)
|
||||
obj_is_selected[obj.name] = obj.select_get()
|
||||
|
||||
handler = cls()
|
||||
handler.objs = objs
|
||||
handler.obj_is_selected = obj_is_selected
|
||||
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_text, (context,), "WINDOW", "POST_PIXEL"))
|
||||
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw, (context,), "WINDOW", "POST_VIEW"))
|
||||
cls.is_installed = True
|
||||
|
||||
@classmethod
|
||||
def get_obj_data(cls, obj):
|
||||
verts = []
|
||||
edges = []
|
||||
tris = []
|
||||
|
||||
if len(obj.data.loop_triangles) > 0:
|
||||
verts = [tuple(obj.matrix_world @ v.co) for v in obj.data.vertices]
|
||||
tris = [tuple(t.vertices) for t in obj.data.loop_triangles]
|
||||
|
||||
i = len(verts)
|
||||
matrix_world = obj.matrix_world
|
||||
bbox_verts = [matrix_world @ Vector(co) for co in obj.bound_box]
|
||||
bbox_edges = [
|
||||
(0 + i, 3 + i),
|
||||
(3 + i, 7 + i),
|
||||
(7 + i, 4 + i),
|
||||
(4 + i, 0 + i),
|
||||
(0 + i, 1 + i),
|
||||
(3 + i, 2 + i),
|
||||
(7 + i, 6 + i),
|
||||
(4 + i, 5 + i),
|
||||
(1 + i, 2 + i),
|
||||
(2 + i, 6 + i),
|
||||
(6 + i, 5 + i),
|
||||
(5 + i, 1 + i),
|
||||
]
|
||||
edges = bbox_edges
|
||||
verts.extend(bbox_verts)
|
||||
return {"verts": verts, "edges": edges, "tris": tris}
|
||||
|
||||
@classmethod
|
||||
def uninstall(cls):
|
||||
for handler in cls.handlers:
|
||||
@@ -80,7 +121,7 @@ class ItemDecorator:
|
||||
blf.disable(font_id, blf.SHADOW)
|
||||
|
||||
def draw(self, context):
|
||||
def transparent_color(color, alpha=0.3):
|
||||
def transparent_color(color, alpha=0.05):
|
||||
color = [i for i in color]
|
||||
color[3] = alpha
|
||||
return color
|
||||
@@ -89,72 +130,30 @@ class ItemDecorator:
|
||||
selected_elements_color = self.addon_prefs.decorator_color_selected
|
||||
unselected_elements_color = self.addon_prefs.decorator_color_unselected
|
||||
special_elements_color = self.addon_prefs.decorator_color_special
|
||||
decorator_color_background = self.addon_prefs.decorator_color_background
|
||||
|
||||
gpu.state.point_size_set(6)
|
||||
gpu.state.blend_set("ALPHA")
|
||||
|
||||
self.line_shader = gpu.shader.from_builtin("POLYLINE_UNIFORM_COLOR")
|
||||
self.line_shader.bind() # required to be able to change uniforms of the shader
|
||||
# POLYLINE_UNIFORM_COLOR specific uniforms
|
||||
self.line_shader.uniform_float("viewportSize", (context.region.width, context.region.height))
|
||||
self.line_shader.uniform_float("lineWidth", 2.0)
|
||||
self.line_shader.uniform_float("lineWidth", 1.0)
|
||||
|
||||
# general shader
|
||||
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||
|
||||
selected_verts = []
|
||||
selected_edges = []
|
||||
selected_tris = []
|
||||
unselected_verts = []
|
||||
unselected_edges = []
|
||||
unselected_tris = []
|
||||
for item in context.scene.BIMGeometryProperties.item_objs:
|
||||
if (obj := item.obj) and obj.hide_get() == False:
|
||||
for obj_name, data in self.objs.items():
|
||||
if (obj := bpy.data.objects.get(obj_name)) and obj.hide_get() == False:
|
||||
if self.obj_is_selected[obj_name] != obj.select_get():
|
||||
self.obj_is_selected[obj_name] = obj.select_get()
|
||||
data = ItemDecorator.get_obj_data(obj)
|
||||
self.objs[obj_name] = data
|
||||
if obj.select_get():
|
||||
if context.mode != "OBJECT":
|
||||
continue
|
||||
edges = selected_edges
|
||||
verts = selected_verts
|
||||
tris = selected_tris
|
||||
self.draw_batch("LINES", data["verts"], selected_elements_color, data["edges"])
|
||||
self.draw_batch("TRIS", data["verts"], transparent_color(selected_elements_color), data["tris"])
|
||||
else:
|
||||
edges = unselected_edges
|
||||
verts = unselected_verts
|
||||
tris = unselected_tris
|
||||
|
||||
i = len(verts)
|
||||
matrix_world = obj.matrix_world
|
||||
bbox_verts = [matrix_world @ Vector(co) for co in obj.bound_box]
|
||||
bbox_edges = [
|
||||
(0 + i, 3 + i),
|
||||
(3 + i, 7 + i),
|
||||
(7 + i, 4 + i),
|
||||
(4 + i, 0 + i),
|
||||
(0 + i, 1 + i),
|
||||
(3 + i, 2 + i),
|
||||
(7 + i, 6 + i),
|
||||
(4 + i, 5 + i),
|
||||
(1 + i, 2 + i),
|
||||
(2 + i, 6 + i),
|
||||
(6 + i, 5 + i),
|
||||
(5 + i, 1 + i),
|
||||
]
|
||||
edges.extend(bbox_edges)
|
||||
verts.extend(bbox_verts)
|
||||
|
||||
if (total_tris := len(obj.data.loop_triangles)) == 0:
|
||||
continue
|
||||
|
||||
if total_tris > 1000: # For performance
|
||||
continue
|
||||
|
||||
offset = len(verts)
|
||||
verts.extend([tuple(obj.matrix_world @ v.co) for v in obj.data.vertices])
|
||||
tris.extend([tuple([i + offset for i in t.vertices]) for t in obj.data.loop_triangles])
|
||||
|
||||
if unselected_verts:
|
||||
self.draw_batch("LINES", unselected_verts, transparent_color(unselected_elements_color), unselected_edges)
|
||||
self.draw_batch("TRIS", unselected_verts, transparent_color(special_elements_color), unselected_tris)
|
||||
|
||||
if selected_verts:
|
||||
self.draw_batch("LINES", selected_verts, selected_elements_color, selected_edges)
|
||||
self.draw_batch("TRIS", selected_verts, transparent_color(selected_elements_color), selected_tris)
|
||||
self.draw_batch("LINES", data["verts"], decorator_color_background, data["edges"])
|
||||
self.draw_batch("TRIS", data["verts"], transparent_color(special_elements_color), data["tris"])
|
||||
|
||||
@@ -1745,6 +1745,7 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return bpy.ops.bim.edit_boundary_geometry()
|
||||
elif tool.Geometry.is_representation_item(context.active_object):
|
||||
self.edit_representation_item(context.active_object)
|
||||
tool.Root.reload_item_decorator()
|
||||
return {"FINISHED"}
|
||||
|
||||
objs = context.selected_objects or [context.active_object]
|
||||
@@ -2358,6 +2359,8 @@ class ImportRepresentationItems(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if tool.Geometry.is_meshlike_item(item):
|
||||
tool.Geometry.lock_object(item_obj)
|
||||
|
||||
tool.Root.reload_item_decorator()
|
||||
|
||||
|
||||
class UpdateItemAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.update_item_attributes"
|
||||
|
||||
@@ -131,7 +131,6 @@ class CreateProject(bpy.types.Operator):
|
||||
)
|
||||
bonsai.bim.schema.reload(tool.Ifc.get().schema_identifier)
|
||||
tool.Blender.register_toolbar()
|
||||
tool.Root.reload_item_decorator()
|
||||
|
||||
def rollback(self, data):
|
||||
IfcStore.file = None
|
||||
@@ -843,7 +842,6 @@ class LoadProjectElements(bpy.types.Operator):
|
||||
tool.Project.set_default_context()
|
||||
tool.Project.set_default_modeling_dimensions()
|
||||
tool.Root.reload_grid_decorator()
|
||||
tool.Root.reload_item_decorator()
|
||||
return {"FINISHED"}
|
||||
|
||||
def get_decomposition_elements(self):
|
||||
|
||||
@@ -1434,7 +1434,8 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
has_changed = False
|
||||
|
||||
for item_obj in props.item_objs:
|
||||
obj = item_obj.obj
|
||||
if not (obj := item_obj.obj):
|
||||
continue
|
||||
item = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||
if item.is_a("IfcSweptAreaSolid"):
|
||||
if not tool.Ifc.is_moved(obj):
|
||||
@@ -1455,6 +1456,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_position)
|
||||
if has_changed:
|
||||
cls.reload_representation(rep_obj)
|
||||
tool.Root.reload_item_decorator()
|
||||
|
||||
@classmethod
|
||||
def import_item_attributes(cls, obj: bpy.types.Object) -> None:
|
||||
|
||||
@@ -217,8 +217,7 @@ class Root(bonsai.core.tool.Root):
|
||||
|
||||
@classmethod
|
||||
def reload_item_decorator(cls) -> None:
|
||||
item_objs = bpy.context.scene.BIMGeometryProperties.item_objs
|
||||
item_objs.clear()
|
||||
bpy.context.view_layer.update()
|
||||
ItemDecorator.install(bpy.context)
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user