mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-03 13:28:19 +00:00
The annotation adding code was a bit of a mess, spread around create_annotation, create_annotation_occurrence, and bpy.ops.bim.add_annotation. I've now consolidated it all into core.add_annotation and updated it to work with the new item editing mode (basically new objects need to reload their representation to populate item_ids). Things are still messy, but a bit less now.
This commit is contained in:
@@ -1423,27 +1423,33 @@ class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_idname = "bim.add_annotation"
|
bl_idname = "bim.add_annotation"
|
||||||
bl_label = "Add Annotation"
|
bl_label = "Add Annotation"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
object_type: bpy.props.StringProperty()
|
|
||||||
data_type: bpy.props.StringProperty()
|
|
||||||
description: bpy.props.StringProperty()
|
description: bpy.props.StringProperty()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return IfcStore.get_file() and context.scene.camera
|
return tool.Ifc.get() and context.scene.camera
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def description(cls, context, operator):
|
def description(cls, context, operator):
|
||||||
return operator.description or ""
|
return operator.description or ""
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
drawing = tool.Ifc.get_entity(context.scene.camera)
|
props = bpy.context.scene.BIMAnnotationProperties
|
||||||
if not drawing:
|
if not (drawing := tool.Ifc.get_entity(context.scene.camera)):
|
||||||
self.report({"WARNING"}, "Not a BIM camera")
|
self.report({"WARNING"}, "Not a BIM camera")
|
||||||
return
|
return
|
||||||
|
|
||||||
r = core.add_annotation(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing, object_type=self.object_type)
|
obj = core.add_annotation(
|
||||||
if isinstance(r, str):
|
tool.Ifc,
|
||||||
self.report({"WARNING"}, r)
|
tool.Collector,
|
||||||
|
tool.Drawing,
|
||||||
|
drawing=drawing,
|
||||||
|
object_type=props.object_type,
|
||||||
|
relating_type=tool.Ifc.get().by_id(int(props.relating_type_id)) if props.relating_type_id != "0" else None,
|
||||||
|
enable_editing=True,
|
||||||
|
)
|
||||||
|
if props.object_type == "IMAGE":
|
||||||
|
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", use_existing_object_by_name=obj.name)
|
||||||
|
|
||||||
|
|
||||||
class AddSheet(bpy.types.Operator, tool.Ifc.Operator):
|
class AddSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
import os
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
import bonsai.core.type
|
import bonsai.core.type
|
||||||
|
import bonsai.core.drawing as core
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
import ifcopenshell.util.representation
|
||||||
from bonsai.bim.module.drawing.data import DecoratorData, AnnotationData
|
from bonsai.bim.module.drawing.data import DecoratorData, AnnotationData
|
||||||
from bonsai.bim.helper import prop_with_search
|
from bonsai.bim.helper import prop_with_search
|
||||||
from bpy.types import WorkSpaceTool
|
from bpy.types import WorkSpaceTool
|
||||||
@@ -161,12 +163,12 @@ def create_annotation_occurrence(context):
|
|||||||
obj = tool.Drawing.create_annotation_object(drawing, object_type)
|
obj = tool.Drawing.create_annotation_object(drawing, object_type)
|
||||||
obj.name = relating_type.Name
|
obj.name = relating_type.Name
|
||||||
ifc_context = tool.Drawing.get_annotation_context(tool.Drawing.get_drawing_target_view(drawing), object_type)
|
ifc_context = tool.Drawing.get_annotation_context(tool.Drawing.get_drawing_target_view(drawing), object_type)
|
||||||
relating_type_repr = tool.Drawing.get_annotation_representation(relating_type)
|
relating_type_rep = tool.Drawing.get_annotation_representation(relating_type)
|
||||||
element = tool.Drawing.run_root_assign_class(
|
element = tool.Drawing.run_root_assign_class(
|
||||||
obj=obj,
|
obj=obj,
|
||||||
ifc_class="IfcAnnotation",
|
ifc_class="IfcAnnotation",
|
||||||
predefined_type=object_type,
|
predefined_type=object_type,
|
||||||
should_add_representation=not bool(relating_type_repr),
|
should_add_representation=not relating_type_rep,
|
||||||
context=ifc_context,
|
context=ifc_context,
|
||||||
ifc_representation_class=tool.Drawing.get_ifc_representation_class(object_type),
|
ifc_representation_class=tool.Drawing.get_ifc_representation_class(object_type),
|
||||||
)
|
)
|
||||||
@@ -175,27 +177,23 @@ def create_annotation_occurrence(context):
|
|||||||
|
|
||||||
tool.Ifc.run("group.assign_group", group=tool.Drawing.get_drawing_group(drawing), products=[element])
|
tool.Ifc.run("group.assign_group", group=tool.Drawing.get_drawing_group(drawing), products=[element])
|
||||||
tool.Collector.assign(obj)
|
tool.Collector.assign(obj)
|
||||||
tool.Blender.select_and_activate_single_object(context, obj)
|
|
||||||
|
|
||||||
if relating_type_repr is None and props.object_type == "IMAGE":
|
if relating_type_rep is None and props.object_type == "IMAGE":
|
||||||
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", use_existing_object_by_name=obj.name)
|
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", use_existing_object_by_name=obj.name)
|
||||||
|
|
||||||
|
if representation := ifcopenshell.util.representation.get_representation(element, ifc_context):
|
||||||
def create_annotation():
|
bonsai.core.geometry.switch_representation(
|
||||||
props = bpy.context.scene.BIMAnnotationProperties
|
tool.Ifc,
|
||||||
if props.relating_type_id != "0":
|
tool.Geometry,
|
||||||
create_annotation_occurrence(bpy.context)
|
obj=obj,
|
||||||
else:
|
representation=representation,
|
||||||
object_type = props.object_type
|
should_reload=True,
|
||||||
if not bpy.ops.bim.add_annotation.poll():
|
is_global=True,
|
||||||
return
|
should_sync_changes_first=False,
|
||||||
bpy.ops.bim.add_annotation(
|
|
||||||
object_type=object_type, data_type=tool.Drawing.ANNOTATION_TYPES_DATA[object_type][-1]
|
|
||||||
)
|
)
|
||||||
if props.object_type == "IMAGE":
|
|
||||||
bpy.ops.bim.add_reference_image(
|
if obj.data and not relating_type_rep:
|
||||||
"INVOKE_DEFAULT", use_existing_object_by_name=bpy.context.active_object.name
|
tool.Drawing.enable_editing(obj)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AnnotationToolUI:
|
class AnnotationToolUI:
|
||||||
@@ -294,21 +292,28 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def hotkey_S_T(self):
|
def hotkey_S_T(self):
|
||||||
props = bpy.context.scene.BIMAnnotationProperties
|
props = bpy.context.scene.BIMAnnotationProperties
|
||||||
annotation_type = props.object_type
|
object_type = props.object_type
|
||||||
|
|
||||||
if annotation_type not in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
if object_type not in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
||||||
self.report({"ERROR"}, f"Annotation type {annotation_type} is not supported for tagging.")
|
self.report({"ERROR"}, f"Annotation type {object_type} is not supported for tagging.")
|
||||||
return
|
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()
|
obj = core.add_annotation(
|
||||||
obj = bpy.context.active_object
|
tool.Ifc,
|
||||||
bpy.ops.object.mode_set(mode="OBJECT")
|
tool.Collector,
|
||||||
tool.Drawing.setup_annotation_object(obj, annotation_type, related_object)
|
tool.Drawing,
|
||||||
|
drawing=tool.Ifc.get_entity(bpy.context.scene.camera),
|
||||||
|
object_type=object_type,
|
||||||
|
relating_type=tool.Ifc.get().by_id(int(props.relating_type_id)) if props.relating_type_id != "0" else None,
|
||||||
|
enable_editing=False,
|
||||||
|
)
|
||||||
|
tool.Drawing.setup_annotation_object(obj, object_type, related_object)
|
||||||
|
|
||||||
def hotkey_S_A(self):
|
def hotkey_S_A(self):
|
||||||
create_annotation()
|
if bpy.ops.bim.add_annotation.poll():
|
||||||
|
bpy.ops.bim.add_annotation()
|
||||||
|
|
||||||
def hotkey_S_E(self):
|
def hotkey_S_E(self):
|
||||||
if not bpy.context.active_object:
|
if not bpy.context.active_object:
|
||||||
|
|||||||
@@ -406,7 +406,9 @@ def add_annotation(
|
|||||||
drawing_tool: tool.Drawing,
|
drawing_tool: tool.Drawing,
|
||||||
drawing: ifcopenshell.entity_instance,
|
drawing: ifcopenshell.entity_instance,
|
||||||
object_type: str,
|
object_type: str,
|
||||||
) -> None:
|
relating_type: ifcopenshell.entity_instance,
|
||||||
|
enable_editing: bool = False,
|
||||||
|
) -> bpy.types.Object:
|
||||||
target_view = drawing_tool.get_drawing_target_view(drawing)
|
target_view = drawing_tool.get_drawing_target_view(drawing)
|
||||||
context = drawing_tool.get_annotation_context(target_view, object_type)
|
context = drawing_tool.get_annotation_context(target_view, object_type)
|
||||||
if not context:
|
if not context:
|
||||||
@@ -416,17 +418,24 @@ def add_annotation(
|
|||||||
obj = drawing_tool.create_annotation_object(drawing, object_type)
|
obj = drawing_tool.create_annotation_object(drawing, object_type)
|
||||||
element = ifc.get_entity(obj)
|
element = ifc.get_entity(obj)
|
||||||
if not element:
|
if not element:
|
||||||
|
relating_type_rep = drawing_tool.get_annotation_representation(relating_type) if relating_type else None
|
||||||
element = drawing_tool.run_root_assign_class(
|
element = drawing_tool.run_root_assign_class(
|
||||||
obj=obj,
|
obj=obj,
|
||||||
ifc_class="IfcAnnotation",
|
ifc_class="IfcAnnotation",
|
||||||
predefined_type=object_type,
|
predefined_type=object_type,
|
||||||
should_add_representation=True,
|
should_add_representation=not relating_type_rep,
|
||||||
context=context,
|
context=context,
|
||||||
ifc_representation_class=drawing_tool.get_ifc_representation_class(object_type),
|
ifc_representation_class=drawing_tool.get_ifc_representation_class(object_type),
|
||||||
)
|
)
|
||||||
|
if relating_type:
|
||||||
|
drawing_tool.run_type_assign_type(element=element, relating_type=relating_type)
|
||||||
ifc.run("group.assign_group", group=drawing_tool.get_drawing_group(drawing), products=[element])
|
ifc.run("group.assign_group", group=drawing_tool.get_drawing_group(drawing), products=[element])
|
||||||
|
if representation := drawing_tool.get_representation(element, context):
|
||||||
|
drawing_tool.reload_representation(obj=obj, representation=representation)
|
||||||
collector.assign(obj, should_clean_users_collection=True)
|
collector.assign(obj, should_clean_users_collection=True)
|
||||||
drawing_tool.enable_editing(obj)
|
if not relating_type_rep and object_type != "IMAGE" and enable_editing:
|
||||||
|
drawing_tool.enable_editing(obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def build_schedule(drawing: tool.Drawing, schedule: ifcopenshell.entity_instance) -> None:
|
def build_schedule(drawing: tool.Drawing, schedule: ifcopenshell.entity_instance) -> None:
|
||||||
|
|||||||
@@ -348,11 +348,15 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing(cls, obj: bpy.types.Object) -> None:
|
def enable_editing(cls, obj: bpy.types.Object) -> None:
|
||||||
bpy.ops.object.select_all(action="DESELECT")
|
from bonsai.bim.module.geometry.data import ViewportData
|
||||||
bpy.context.view_layer.objects.active = obj
|
|
||||||
obj.select_set(True)
|
tool.Blender.select_and_activate_single_object(bpy.context, obj)
|
||||||
if obj.data:
|
if not obj.data:
|
||||||
bpy.ops.object.mode_set(mode="EDIT")
|
return
|
||||||
|
ViewportData.load() # Reload valid modes
|
||||||
|
bpy.ops.bim.override_mode_set_edit() # Enter item mode
|
||||||
|
ViewportData.load() # Reload valid modes
|
||||||
|
bpy.ops.bim.override_mode_set_edit() # Enter edit mode
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_drawings(cls) -> None:
|
def enable_editing_drawings(cls) -> None:
|
||||||
@@ -988,6 +992,26 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
ifc_representation_class=ifc_representation_class,
|
ifc_representation_class=ifc_representation_class,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run_type_assign_type(cls, element: ifcopenshell.entity_instance, relating_type: ifcopenshell.entity_instance):
|
||||||
|
return bonsai.core.type.assign_type(tool.Ifc, tool.Type, element=element, type=relating_type)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def reload_representation(cls, obj: bpy.types.Object, representation: ifcopenshell.entity_instance):
|
||||||
|
return bonsai.core.geometry.switch_representation(
|
||||||
|
tool.Ifc,
|
||||||
|
tool.Geometry,
|
||||||
|
obj=obj,
|
||||||
|
representation=representation,
|
||||||
|
should_reload=True,
|
||||||
|
is_global=True,
|
||||||
|
should_sync_changes_first=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_representation(cls, element, context):
|
||||||
|
return ifcopenshell.util.representation.get_representation(element, context)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_drawing_collection_name(
|
def set_drawing_collection_name(
|
||||||
cls, drawing: ifcopenshell.entity_instance, collection: bpy.types.Collection
|
cls, drawing: ifcopenshell.entity_instance, collection: bpy.types.Collection
|
||||||
|
|||||||
Reference in New Issue
Block a user