mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +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")
|
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(
|
add_layout_hotkey_operator(
|
||||||
cls.layout,
|
cls.layout,
|
||||||
"Bulk Tag",
|
"Bulk Tag",
|
||||||
"S_T",
|
"S_T",
|
||||||
"Create new annotations and automatically adjust them to the selected objects",
|
"Create new annotations and automatically adjust them to the selected objects",
|
||||||
)
|
)
|
||||||
add_layout_hotkey_operator(
|
add_layout_hotkey_operator(
|
||||||
cls.layout, "Readjust", "S_G", "Readjust tags based on the products they are assigned to"
|
cls.layout, "Readjust", "S_G", "Readjust tags based on the products they are assigned to"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Hotkey(bpy.types.Operator, Operator):
|
class Hotkey(bpy.types.Operator, Operator):
|
||||||
@@ -289,14 +289,18 @@ class Hotkey(bpy.types.Operator, Operator):
|
|||||||
|
|
||||||
def hotkey_S_T(self):
|
def hotkey_S_T(self):
|
||||||
props = bpy.context.scene.BIMAnnotationProperties
|
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
|
related_objects = bpy.context.selected_objects
|
||||||
for related_object in related_objects:
|
for related_object in related_objects:
|
||||||
create_annotation()
|
create_annotation()
|
||||||
obj = bpy.context.active_object
|
obj = bpy.context.active_object
|
||||||
bpy.ops.object.mode_set(mode="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):
|
def hotkey_S_A(self):
|
||||||
create_annotation()
|
create_annotation()
|
||||||
@@ -314,9 +318,15 @@ class Hotkey(bpy.types.Operator, Operator):
|
|||||||
if not element or not element.is_a("IfcAnnotation"):
|
if not element or not element.is_a("IfcAnnotation"):
|
||||||
continue
|
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)
|
related_product = tool.Drawing.get_assigned_product(element)
|
||||||
if not related_product:
|
if not related_product:
|
||||||
|
self.report({"ERROR"}, "Selected annotation has no product assigned.")
|
||||||
continue
|
continue
|
||||||
related_object = tool.Ifc.get_object(related_product)
|
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 bmesh
|
||||||
import shutil
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
|
import shapely
|
||||||
|
from shapely.ops import unary_union
|
||||||
import mathutils
|
import mathutils
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -97,6 +99,8 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
current_pos = camera.matrix_world @ current_pos
|
current_pos = camera.matrix_world @ current_pos
|
||||||
obj.location = current_pos
|
obj.location = current_pos
|
||||||
|
|
||||||
|
ANNOTATION_TYPES_SUPPORT_SETUP = ("STAIR_ARROW", "TEXT", "REVISION_CLOUD", "FILL_AREA")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_annotation_object(cls, obj, object_type, related_object=None):
|
def setup_annotation_object(cls, obj, object_type, related_object=None):
|
||||||
"""Finish object's adjustments after both object and entity are created"""
|
"""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)
|
cls.ensure_annotation_in_drawing_plane(obj)
|
||||||
assign_product = True
|
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):
|
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)
|
tool.Ifc.run("drawing.assign_product", relating_product=related_entity, related_object=obj_entity)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user