mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Revision Clouds - option to match revision cloud with the selected object
Works similarly to tagging, example - https://imgur.com/a/Atr0nYE This feature also can be useful in the future if we integrate revision clouds with ifcgit
This commit is contained in:
@@ -248,16 +248,16 @@ class AnnotationToolUI:
|
||||
|
||||
add_layout_hotkey_operator(cls.layout, "Add", "S_A", "Create a new annotation")
|
||||
|
||||
if object_type in ("TEXT", "STAIR_ARROW"):
|
||||
if object_type in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
||||
add_layout_hotkey_operator(
|
||||
cls.layout,
|
||||
"Bulk Tag",
|
||||
"S_T",
|
||||
"Create new annotations and automatically adjust them to the selected objects",
|
||||
)
|
||||
add_layout_hotkey_operator(
|
||||
cls.layout, "Readjust", "S_G", "Readjust tags based on the products they are assigned to"
|
||||
)
|
||||
add_layout_hotkey_operator(
|
||||
cls.layout, "Readjust", "S_G", "Readjust tags based on the products they are assigned to"
|
||||
)
|
||||
|
||||
|
||||
class Hotkey(bpy.types.Operator, Operator):
|
||||
@@ -289,14 +289,18 @@ class Hotkey(bpy.types.Operator, Operator):
|
||||
|
||||
def hotkey_S_T(self):
|
||||
props = bpy.context.scene.BIMAnnotationProperties
|
||||
object_type = props.object_type
|
||||
annotation_type = props.object_type
|
||||
|
||||
if annotation_type not in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
||||
self.report({"ERROR"}, f"Annotation type {annotation_type} is not supported for tagging.")
|
||||
return
|
||||
|
||||
related_objects = bpy.context.selected_objects
|
||||
for related_object in related_objects:
|
||||
create_annotation()
|
||||
obj = bpy.context.active_object
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
tool.Drawing.setup_annotation_object(obj, object_type, related_object)
|
||||
tool.Drawing.setup_annotation_object(obj, annotation_type, related_object)
|
||||
|
||||
def hotkey_S_A(self):
|
||||
create_annotation()
|
||||
@@ -314,9 +318,15 @@ class Hotkey(bpy.types.Operator, Operator):
|
||||
if not element or not element.is_a("IfcAnnotation"):
|
||||
continue
|
||||
|
||||
annotation_type = element.ObjectType
|
||||
if annotation_type not in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
||||
self.report({"ERROR"}, f"Annotation type {annotation_type} is not supported for readjustment.")
|
||||
continue
|
||||
|
||||
related_product = tool.Drawing.get_assigned_product(element)
|
||||
if not related_product:
|
||||
self.report({"ERROR"}, "Selected annotation has no product assigned.")
|
||||
continue
|
||||
related_object = tool.Ifc.get_object(related_product)
|
||||
|
||||
tool.Drawing.setup_annotation_object(obj, element.ObjectType, related_object)
|
||||
tool.Drawing.setup_annotation_object(obj, annotation_type, related_object)
|
||||
|
||||
@@ -24,6 +24,8 @@ import lark
|
||||
import bmesh
|
||||
import shutil
|
||||
import logging
|
||||
import shapely
|
||||
from shapely.ops import unary_union
|
||||
import mathutils
|
||||
import webbrowser
|
||||
import subprocess
|
||||
@@ -97,6 +99,8 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
current_pos = camera.matrix_world @ current_pos
|
||||
obj.location = current_pos
|
||||
|
||||
ANNOTATION_TYPES_SUPPORT_SETUP = ("STAIR_ARROW", "TEXT", "REVISION_CLOUD", "FILL_AREA")
|
||||
|
||||
@classmethod
|
||||
def setup_annotation_object(cls, obj, object_type, related_object=None):
|
||||
"""Finish object's adjustments after both object and entity are created"""
|
||||
@@ -135,6 +139,30 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
cls.ensure_annotation_in_drawing_plane(obj)
|
||||
assign_product = True
|
||||
|
||||
elif object_type == "REVISION_CLOUD":
|
||||
revised_object, cloud = related_object, obj
|
||||
|
||||
verts = [np.array(revised_object.matrix_world @ v.co) for v in revised_object.data.vertices]
|
||||
verts = [(np.around(v[[0, 1]], decimals=3)).tolist() for v in verts]
|
||||
edges = [e.vertices for e in revised_object.data.edges]
|
||||
|
||||
# shapely magic
|
||||
boundary_lines = [shapely.LineString([verts[v] for v in e]) for e in edges]
|
||||
unioned_boundaries = shapely.union_all(shapely.GeometryCollection(boundary_lines))
|
||||
all_polygons = shapely.polygonize(unioned_boundaries.geoms).geoms
|
||||
outer_shell = unary_union(all_polygons)
|
||||
|
||||
bm = tool.Blender.get_bmesh_for_mesh(obj.data, clean=True)
|
||||
new_verts = list(outer_shell.exterior.coords)
|
||||
bm_verts = [bm.verts.new(v + (0,)) for v in new_verts]
|
||||
bm_edges = [bm.edges.new([bm_verts[i], bm_verts[i + 1]]) for i in range(len(new_verts) - 1)]
|
||||
bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
|
||||
|
||||
tool.Blender.apply_bmesh(obj.data, bm, obj)
|
||||
cloud.location = Vector((0, 0, 0))
|
||||
cls.ensure_annotation_in_drawing_plane(cloud)
|
||||
assign_product = True
|
||||
|
||||
if assign_product and not cls.get_assigned_product(obj_entity):
|
||||
tool.Ifc.run("drawing.assign_product", relating_product=related_entity, related_object=obj_entity)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user