Skip to content

Commit

Permalink
Visual clean up of annotation tool to only activate when a drawing is…
Browse files Browse the repository at this point in the history
… active and have a type manager similar to the BIM tool.
  • Loading branch information
Moult committed Jul 9, 2023
1 parent 43fd012 commit cc59929
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 65 deletions.
6 changes: 5 additions & 1 deletion src/blenderbim/blenderbim/bim/module/drawing/__init__.py
Expand Up @@ -24,20 +24,22 @@
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,
operator.CleanWireframes,
operator.ContractSheet,
operator.CreateDrawing,
operator.CreateSheets,
operator.DisableAddAnnotationType,
operator.DisableEditingAssignedProduct,
operator.DisableEditingDrawings,
operator.DisableEditingSchedules,
Expand All @@ -47,6 +49,7 @@
operator.EditAssignedProduct,
operator.EditSheet,
operator.EditText,
operator.EnableAddAnnotationType,
operator.EditTextPopup,
operator.EnableEditingAssignedProduct,
operator.EnableEditingText,
Expand Down Expand Up @@ -102,6 +105,7 @@
gizmos.DimensionLabelGizmo,
gizmos.ExtrusionGuidesGizmo,
gizmos.ExtrusionWidget,
workspace.LaunchAnnotationTypeManager,
workspace.Hotkey,
)

Expand Down
25 changes: 19 additions & 6 deletions src/blenderbim/blenderbim/bim/module/drawing/data.py
Expand Up @@ -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"])
46 changes: 46 additions & 0 deletions src/blenderbim/blenderbim/bim/module/drawing/operator.py
Expand Up @@ -84,6 +84,52 @@ def execute(self, context):
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"
Expand Down
19 changes: 8 additions & 11 deletions src/blenderbim/blenderbim/bim/module/drawing/prop.py
Expand Up @@ -499,7 +499,7 @@ class BIMAssignedProductProperties(PropertyGroup):
"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"),
Expand All @@ -510,13 +510,10 @@ class BIMAssignedProductProperties(PropertyGroup):
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):
Expand All @@ -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")
125 changes: 79 additions & 46 deletions src/blenderbim/blenderbim/bim/module/drawing/workspace.py
Expand Up @@ -30,14 +30,85 @@
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)
blenderbim.bim.handler.refresh_ui_data()
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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -171,6 +208,11 @@ def draw(cls, context, layout):
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()

Expand All @@ -182,11 +224,6 @@ def draw(cls, context, layout):

@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")

Expand All @@ -207,10 +244,9 @@ def draw_type_selection_interface(cls):
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(
Expand Down Expand Up @@ -284,6 +320,3 @@ def hotkey_S_G(self):
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)
2 changes: 1 addition & 1 deletion src/blenderbim/blenderbim/bim/module/type/operator.py
Expand Up @@ -200,7 +200,7 @@ def execute(self, context):
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
Expand Down

0 comments on commit cc59929

Please sign in to comment.