mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Visual clean up of annotation tool to only activate when a drawing is active and have a type manager similar to the BIM tool.
This commit is contained in:
@@ -24,13 +24,14 @@ classes = (
|
||||
operator.ActivateDrawingStyle,
|
||||
operator.ActivateModel,
|
||||
operator.AddAnnotation,
|
||||
operator.AddAnnotationType,
|
||||
operator.AddDrawing,
|
||||
operator.AddDrawingStyle,
|
||||
operator.AddDrawingStyleAttribute,
|
||||
operator.AddDrawingToSheet,
|
||||
operator.AddReferenceToSheet,
|
||||
operator.AddSchedule,
|
||||
operator.AddScheduleToSheet,
|
||||
operator.AddReferenceToSheet,
|
||||
operator.AddSheet,
|
||||
operator.AddTextLiteral,
|
||||
operator.BuildSchedule,
|
||||
@@ -38,6 +39,7 @@ classes = (
|
||||
operator.ContractSheet,
|
||||
operator.CreateDrawing,
|
||||
operator.CreateSheets,
|
||||
operator.DisableAddAnnotationType,
|
||||
operator.DisableEditingAssignedProduct,
|
||||
operator.DisableEditingDrawings,
|
||||
operator.DisableEditingSchedules,
|
||||
@@ -47,6 +49,7 @@ classes = (
|
||||
operator.EditAssignedProduct,
|
||||
operator.EditSheet,
|
||||
operator.EditText,
|
||||
operator.EnableAddAnnotationType,
|
||||
operator.EditTextPopup,
|
||||
operator.EnableEditingAssignedProduct,
|
||||
operator.EnableEditingText,
|
||||
@@ -102,6 +105,7 @@ classes = (
|
||||
gizmos.DimensionLabelGizmo,
|
||||
gizmos.ExtrusionGuidesGizmo,
|
||||
gizmos.ExtrusionWidget,
|
||||
workspace.LaunchAnnotationTypeManager,
|
||||
workspace.Hotkey,
|
||||
)
|
||||
|
||||
|
||||
@@ -335,18 +335,31 @@ class AnnotationData:
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.props = bpy.context.scene.BIMAnnotationProperties
|
||||
cls.data["relating_types"] = cls.get_relating_types()
|
||||
cls.data["relating_type_id"] = cls.relating_type_id()
|
||||
cls.data["relating_types"] = cls.relating_types()
|
||||
|
||||
@classmethod
|
||||
def get_relating_types(cls):
|
||||
def relating_type_id(cls):
|
||||
object_type = cls.props.object_type
|
||||
relating_types = []
|
||||
for relating_type in tool.Ifc.get().by_type("IfcTypeProduct"):
|
||||
if tool.Drawing.is_annotation_object_type(relating_type, object_type):
|
||||
relating_types.append(relating_type)
|
||||
|
||||
enum_items = [(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in relating_types]
|
||||
results = [("0", "Untyped", "")]
|
||||
results.extend([(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in relating_types])
|
||||
return results
|
||||
|
||||
# item to create anootations without relating types
|
||||
enum_items.insert(0, ("0", "-", ""))
|
||||
return enum_items
|
||||
@classmethod
|
||||
def relating_types(cls):
|
||||
object_type = cls.props.object_type
|
||||
relating_types = []
|
||||
for relating_type in tool.Ifc.get().by_type("IfcTypeProduct"):
|
||||
if tool.Drawing.is_annotation_object_type(relating_type, object_type):
|
||||
relating_types.append({
|
||||
"id": relating_type.id(),
|
||||
"name": relating_type.Name or "Unnamed",
|
||||
"description": relating_type.Description or "No Description",
|
||||
})
|
||||
|
||||
return sorted(relating_types, key=lambda x: x["name"])
|
||||
|
||||
@@ -84,6 +84,52 @@ class Operator:
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddAnnotationType(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_annotation_type"
|
||||
bl_label = "Add Annotation Type"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMAnnotationProperties
|
||||
object_type = props.object_type
|
||||
has_representation = props.create_representation_for_type
|
||||
drawing = tool.Ifc.get_entity(bpy.context.scene.camera)
|
||||
|
||||
if props.create_representation_for_type:
|
||||
obj = tool.Drawing.create_annotation_object(drawing, object_type)
|
||||
else:
|
||||
obj = bpy.data.objects.new(object_type, None)
|
||||
|
||||
obj.name = props.type_name
|
||||
element = tool.Drawing.run_root_assign_class(
|
||||
obj=obj,
|
||||
ifc_class="IfcTypeProduct",
|
||||
predefined_type=object_type,
|
||||
should_add_representation=has_representation,
|
||||
context=ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Annotation", "MODEL_VIEW"),
|
||||
ifc_representation_class=tool.Drawing.get_ifc_representation_class(object_type),
|
||||
)
|
||||
element.ApplicableOccurrence = f"IfcAnnotation/{object_type}"
|
||||
|
||||
|
||||
class EnableAddAnnotationType(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.enable_add_annotation_type"
|
||||
bl_label = "Enable Add Annotation Type"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
bpy.context.scene.BIMAnnotationProperties.is_adding_type = True
|
||||
|
||||
|
||||
class DisableAddAnnotationType(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.disable_add_annotation_type"
|
||||
bl_label = "Disable Add Annotation Type"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
bpy.context.scene.BIMAnnotationProperties.is_adding_type = False
|
||||
|
||||
|
||||
class AddDrawing(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_drawing"
|
||||
bl_label = "Add Drawing"
|
||||
|
||||
@@ -499,7 +499,7 @@ ANNOTATION_TYPES_DATA = {
|
||||
"PLAN_LEVEL": ("Level (Plan)", "", "SORTBYEXT", "curve"),
|
||||
"SECTION_LEVEL": ("Level (Section)", "", "TRIA_DOWN", "curve"),
|
||||
"BREAKLINE": ("Breakline", "", "FCURVE", "mesh"),
|
||||
"LINEWORK": ("Line", "", "MESH_MONKEY", "mesh"),
|
||||
"LINEWORK": ("Line", "", "SNAP_MIDPOINT", "mesh"),
|
||||
"BATTING": ("Batting", "Add batting annotation.\nThickness could be changed through Thickness property of BBIM_Batting property set", "FORCE_FORCE", "mesh"),
|
||||
"REVISION_CLOUD":("Revision Cloud", "Add revision cloud", "VOLUME_DATA", "mesh"),
|
||||
"FILL_AREA": ("Fill Area", "", "NODE_TEXTURE", "mesh"),
|
||||
@@ -510,13 +510,10 @@ ANNOTATION_TYPES_DATA = {
|
||||
annotation_classes = [(x, *ANNOTATION_TYPES_DATA[x][:3], i) for i, x in enumerate(ANNOTATION_TYPES_DATA)]
|
||||
|
||||
|
||||
def get_annotation_data_prop(prop_name):
|
||||
def function(self, context):
|
||||
if not AnnotationData.is_loaded:
|
||||
AnnotationData.load()
|
||||
return AnnotationData.data[prop_name]
|
||||
|
||||
return function
|
||||
def get_relating_type_id(self, context):
|
||||
if not AnnotationData.is_loaded:
|
||||
AnnotationData.load()
|
||||
return AnnotationData.data["relating_type_id"]
|
||||
|
||||
|
||||
def update_annotation_object_type(self, context):
|
||||
@@ -533,12 +530,12 @@ class BIMAnnotationProperties(PropertyGroup):
|
||||
object_type: bpy.props.EnumProperty(
|
||||
name="Annotation Object Type", items=annotation_classes, default="TEXT", update=update_annotation_object_type
|
||||
)
|
||||
relating_type_id: bpy.props.EnumProperty(
|
||||
name="Relating Annotation Type", items=get_annotation_data_prop("relating_types")
|
||||
)
|
||||
relating_type_id: bpy.props.EnumProperty(name="Relating Annotation Type", items=get_relating_type_id)
|
||||
create_representation_for_type: bpy.props.BoolProperty(
|
||||
name="Create Representation For Type",
|
||||
default=False,
|
||||
description='Whether "Add type" should define a representation for the type \n'
|
||||
"or allow occurences to have their own",
|
||||
)
|
||||
is_adding_type: bpy.props.BoolProperty(default=False)
|
||||
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
||||
|
||||
@@ -30,7 +30,8 @@ from blenderbim.bim.ifc import IfcStore
|
||||
import blenderbim.bim.handler
|
||||
|
||||
|
||||
# declaring it here to avoid circular import problems
|
||||
# TODO: Fix circular import.
|
||||
# Declaring it here to avoid circular import problems
|
||||
class Operator:
|
||||
def execute(self, context):
|
||||
IfcStore.execute_ifc_operator(self, context)
|
||||
@@ -38,6 +39,76 @@ class Operator:
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class LaunchAnnotationTypeManager(bpy.types.Operator):
|
||||
bl_idname = "bim.launch_annotation_type_manager"
|
||||
bl_label = "Launch Annotation Type Manager"
|
||||
bl_options = {"REGISTER"}
|
||||
bl_description = "Manage annotation types and templates"
|
||||
|
||||
def execute(self, context):
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_popup(self, width=550)
|
||||
|
||||
def draw(self, context):
|
||||
if not AnnotationData.is_loaded:
|
||||
AnnotationData.load()
|
||||
|
||||
props = context.scene.BIMAnnotationProperties
|
||||
|
||||
columns = self.layout.column_flow(columns=3)
|
||||
row = columns.row()
|
||||
row.alignment = "LEFT"
|
||||
row.label(text=f"{len(AnnotationData.data['relating_types'])} Types", icon="FILE_VOLUME")
|
||||
|
||||
row = columns.row(align=True)
|
||||
row.alignment = "CENTER"
|
||||
# In case you want something here in the future
|
||||
|
||||
row = columns.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
# In case you want something here in the future
|
||||
|
||||
if props.is_adding_type:
|
||||
row = self.layout.row()
|
||||
box = row.box()
|
||||
row = box.row()
|
||||
row.prop(props, "type_name")
|
||||
row = box.row()
|
||||
row.prop(props, "create_representation_for_type", text="Geometric Type")
|
||||
row = box.row(align=True)
|
||||
row.operator("bim.add_annotation_type", icon="CHECKMARK", text="Save New Type")
|
||||
row.operator("bim.disable_add_annotation_type", icon="CANCEL", text="")
|
||||
else:
|
||||
row = self.layout.row()
|
||||
row.operator("bim.enable_add_annotation_type", icon="ADD", text="Create New Type")
|
||||
|
||||
flow = self.layout.grid_flow(row_major=True, columns=3, even_columns=True, even_rows=True, align=True)
|
||||
|
||||
for relating_type in AnnotationData.data["relating_types"]:
|
||||
outer_col = flow.column()
|
||||
box = outer_col.box()
|
||||
|
||||
row = box.row()
|
||||
row.alignment = "CENTER"
|
||||
row.label(text=relating_type["name"], icon="FILE_3D")
|
||||
|
||||
row = box.row()
|
||||
row.alignment = "CENTER"
|
||||
row.label(text=relating_type["description"])
|
||||
|
||||
row = box.row(align=True)
|
||||
|
||||
op = row.operator("bim.select_type", icon="OBJECT_DATA")
|
||||
op.relating_type = relating_type["id"]
|
||||
op = row.operator("bim.duplicate_type", icon="DUPLICATE", text="")
|
||||
op.element = relating_type["id"]
|
||||
op = row.operator("bim.remove_type", icon="X", text="")
|
||||
op.element = relating_type["id"]
|
||||
|
||||
|
||||
|
||||
class AnnotationTool(WorkSpaceTool):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_context_mode = "OBJECT"
|
||||
@@ -89,42 +160,8 @@ def add_layout_hotkey_operator(layout, text, hotkey, description):
|
||||
return op, row
|
||||
|
||||
|
||||
# TODO: move to operator
|
||||
def create_annotation_type(context):
|
||||
# just empty to store parameters
|
||||
props = context.scene.BIMAnnotationProperties
|
||||
object_type = props.object_type
|
||||
create_representation = props.create_representation_for_type
|
||||
drawing = tool.Ifc.get_entity(bpy.context.scene.camera)
|
||||
|
||||
if props.create_representation_for_type:
|
||||
obj = tool.Drawing.create_annotation_object(drawing, object_type)
|
||||
else:
|
||||
obj = bpy.data.objects.new(object_type, None)
|
||||
|
||||
obj.name = f"{object_type}_TYPE"
|
||||
obj.location = context.scene.cursor.location
|
||||
tool.Drawing.ensure_annotation_in_drawing_plane(obj)
|
||||
|
||||
drawing = tool.Ifc.get_entity(context.scene.camera)
|
||||
ifc_context = tool.Drawing.get_annotation_context(tool.Drawing.get_drawing_target_view(drawing), object_type)
|
||||
|
||||
element = tool.Drawing.run_root_assign_class(
|
||||
obj=obj,
|
||||
ifc_class="IfcTypeProduct",
|
||||
predefined_type=object_type,
|
||||
should_add_representation=create_representation,
|
||||
context=ifc_context,
|
||||
ifc_representation_class=tool.Drawing.get_ifc_representation_class(object_type),
|
||||
)
|
||||
element.ApplicableOccurrence = f"IfcAnnotation/{object_type}"
|
||||
|
||||
tool.Blender.select_and_activate_single_object(context, obj)
|
||||
|
||||
|
||||
# TODO: move to operator
|
||||
def create_annotation_occurence(context):
|
||||
# object_type = context.scene.BIMAnnotationProperties.object_type
|
||||
props = context.scene.BIMAnnotationProperties
|
||||
relating_type = tool.Ifc.get().by_id(int(props.relating_type_id))
|
||||
object_type = props.object_type
|
||||
@@ -171,6 +208,11 @@ class AnnotationToolUI:
|
||||
row.label(text="No IFC Project", icon="ERROR")
|
||||
return
|
||||
|
||||
drawing = tool.Ifc.get_entity(context.scene.camera)
|
||||
if not drawing:
|
||||
row.label(text="No Active Drawing", icon="ERROR")
|
||||
return
|
||||
|
||||
if not AnnotationData.is_loaded:
|
||||
AnnotationData.load()
|
||||
|
||||
@@ -182,11 +224,6 @@ class AnnotationToolUI:
|
||||
|
||||
@classmethod
|
||||
def draw_create_object_interface(cls):
|
||||
row = cls.layout.row(align=True)
|
||||
op, row = add_layout_hotkey_operator(cls.layout, "Add Type", "S_C", "Create a new annotation type")
|
||||
selected_icon = "CHECKBOX_HLT" if cls.props.create_representation_for_type else "CHECKBOX_DEHLT"
|
||||
row.prop(cls.props, "create_representation_for_type", text="", icon=selected_icon)
|
||||
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(bpy.context.scene.DocProperties, "should_draw_decorations", text="Viewport Annotations")
|
||||
|
||||
@@ -207,10 +244,9 @@ class AnnotationToolUI:
|
||||
row = cls.layout.row(align=True)
|
||||
row.label(text="", icon="FILE_3D")
|
||||
prop_with_search(row, cls.props, "relating_type_id", text="")
|
||||
row.operator("bim.launch_annotation_type_manager", icon="LIGHTPROBE_GRID", text="")
|
||||
|
||||
create_type_occurence = cls.props.relating_type_id != "0"
|
||||
label = "Add Type Occurence" if create_type_occurence else "Add Annotation"
|
||||
add_layout_hotkey_operator(cls.layout, label, "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"):
|
||||
add_layout_hotkey_operator(
|
||||
@@ -284,6 +320,3 @@ class Hotkey(bpy.types.Operator, Operator):
|
||||
related_object = tool.Ifc.get_object(related_product)
|
||||
|
||||
tool.Drawing.setup_annotation_object(obj, element.ObjectType, related_object)
|
||||
|
||||
def hotkey_S_C(self):
|
||||
create_annotation_type(bpy.context)
|
||||
|
||||
@@ -200,7 +200,7 @@ class SelectTypeObjects(bpy.types.Operator):
|
||||
class AddType(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_type"
|
||||
bl_label = "Add Type"
|
||||
bl_options = {"REGISTER"}
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMModelProperties
|
||||
|
||||
Reference in New Issue
Block a user