mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
UI drawing improvements (#5677)
* Fix Shift-clicking SVG-DXF conversion * Fix Schedules and References not incrementing the ID number properly * Remove the superfluous Create and Open buttons from the Active Drawing pane * Add active camera indicator to the Drawing list * Improved enable/disabled icon behaviour As many operators as possible now use polling method to set enabled/disabled state. Icons set their enabled/disabled state intelligently depending on what is selected. When an operator is disabled it says why it is disabled in the tooltip. * Rename core open_sheet, operator OpenSheet/bim.open_sheet to better reflect what it actually does, i.e. open_layout * Added selection checkmarks to Sheets, and operator to select all/none, to do batch ops on sheets * Missed adding the renamed operator to __init__ in commit4cfc0bd9f3* Decouple creating and viewing drawings/sheets to avoid focus stealing popups polluting display on long batch runs * Improve drawing selections in OpenDrawing operator * Add the Shift+click power move to Create Sheet * Add the Open Sheet + Shift+click power move * Improve drawing selections in RemoveDrawing operator * All operators are now documented with standardised language and terms. * Add status bar Info messages for feedback on create tasks that now don't have visual feedback * Fix enable/disable for ActivateDrawing operator icons. This was a strange one. They have common invoke and execute methods, but the polling has different conditions. I tried subclassing the original ActivateDrawing for the Sheets version, but something about Blenders operators breaks the classmethod decorated poll. This was the cleanest solution I found, but maybe there's a better one. * Placeholder operator for DuplicateSheet function. Does nothing but report Not Implemented. Could be omitted if this kind of thing is frowned upon. * Change icons to be more consistent * Final changes to toolbars Change button order and spacing for better usability. Add a checkmark all/none button, to do batch ops on sheets. Moved Bonsai Web UI button up to sheets toolbar. Some general cleanup of unnecessary clutter in the toolbar code. * Sheet/Drawing checkmarks remember their state properly * Adjust sheet/drawing operators to view after singular create, but not when batch creating more than one. * By special request, add back the opening windows when creating, but requiring Ctrl to be pressed. * black the files * Second attempt at blacking ui.py because I used an old black * Change method of getting active drawing to use one in tool import as requested * Fix for incorrectd1fc5158d- actually checked it this time
This commit is contained in:
@@ -21,6 +21,7 @@ from . import ui, prop, operator, handler, gizmos, workspace
|
||||
|
||||
classes = (
|
||||
operator.ActivateDrawing,
|
||||
operator.ActivateDrawingFromSheet,
|
||||
operator.ActivateDrawingStyle,
|
||||
operator.ActivateModel,
|
||||
operator.AddAnnotation,
|
||||
@@ -52,6 +53,7 @@ classes = (
|
||||
operator.DisableEditingSheets,
|
||||
operator.DisableEditingText,
|
||||
operator.DuplicateDrawing,
|
||||
operator.DuplicateSheet,
|
||||
operator.EditAssignedProduct,
|
||||
operator.EditElementFilter,
|
||||
operator.EditSheet,
|
||||
@@ -68,6 +70,7 @@ classes = (
|
||||
operator.LoadSchedules,
|
||||
operator.LoadSheets,
|
||||
operator.OpenDrawing,
|
||||
operator.OpenLayout,
|
||||
operator.OpenReference,
|
||||
operator.OpenSchedule,
|
||||
operator.OpenSheet,
|
||||
@@ -86,6 +89,7 @@ classes = (
|
||||
operator.SaveDrawingStyle,
|
||||
operator.SaveDrawingStylesData,
|
||||
operator.SelectAllDrawings,
|
||||
operator.SelectAllSheets,
|
||||
operator.SelectAssignedProduct,
|
||||
operator.SelectDocIfcFile,
|
||||
operator.OpenDocumentationWebUi,
|
||||
|
||||
@@ -154,10 +154,19 @@ class AddDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
class DuplicateDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.duplicate_drawing"
|
||||
bl_label = "Duplicate Drawing"
|
||||
bl_description = "Make a copy of currently selected drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
drawing: bpy.props.IntProperty()
|
||||
should_duplicate_annotations: bpy.props.BoolProperty(name="Should Duplicate Annotations", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not tool.Drawing.get_active_drawing_item():
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
@@ -190,10 +199,16 @@ class CreateDrawing(bpy.types.Operator):
|
||||
bl_idname = "bim.create_drawing"
|
||||
bl_label = "Create Drawing"
|
||||
bl_description = (
|
||||
"Creates/refreshes a .svg drawing based on currently active camera.\n\n"
|
||||
+ "SHIFT+CLICK to print all selected drawings"
|
||||
"Creates/refreshes a .svg drawing based on currently active camera\n"
|
||||
+ 'and open with default system viewer or using "svg_command" or\n'
|
||||
+ '"pdf_command" from the Bonsai preferences (if provided).\n\n'
|
||||
+ "SHIFT+CLICK to create/refresh all shown checked drawings, but doesn't\n"
|
||||
+ "open them for viewing.\n\n"
|
||||
+ "Add the CTRL modifier to optionally open drawings to view them as\n"
|
||||
+ "they are created"
|
||||
)
|
||||
print_all: bpy.props.BoolProperty(name="Print All", default=False, options={"SKIP_SAVE"})
|
||||
open_viewer: bpy.props.BoolProperty(name="Open in Viewer", default=False, options={"SKIP_SAVE"})
|
||||
sync: bpy.props.BoolProperty(
|
||||
name="Sync Before Creating Drawing",
|
||||
description="Could save some time if you're sure IFC and current Blender session are already in sync",
|
||||
@@ -223,6 +238,8 @@ class CreateDrawing(bpy.types.Operator):
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
if event.type == "LEFTMOUSE" and event.shift:
|
||||
self.print_all = True
|
||||
if event.type == "LEFTMOUSE" and event.ctrl:
|
||||
self.open_viewer = True
|
||||
return self.execute(context)
|
||||
|
||||
def execute(self, context):
|
||||
@@ -291,8 +308,11 @@ class CreateDrawing(bpy.types.Operator):
|
||||
with profile("Combine SVG layers"):
|
||||
svg_path = self.combine_svgs(context, underlay_svg, linework_svg, annotation_svg)
|
||||
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, svg_path)
|
||||
|
||||
if self.open_viewer:
|
||||
drawing_uri = tool.Drawing.get_document_uri(tool.Drawing.get_drawing_document(self.drawing))
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, drawing_uri)
|
||||
if not self.open_viewer:
|
||||
self.report({"INFO"}, f"{len(drawings_to_print)} drawings created...")
|
||||
if self.print_all:
|
||||
bpy.ops.bim.activate_drawing(drawing=original_drawing_id, should_view_from_camera=False)
|
||||
return {"FINISHED"}
|
||||
@@ -1436,22 +1456,163 @@ class AddSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
core.add_sheet(tool.Ifc, tool.Drawing, titleblock=context.scene.DocProperties.titleblock)
|
||||
|
||||
|
||||
class OpenSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.open_sheet"
|
||||
bl_label = "Open Sheet Layout"
|
||||
class DuplicateSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.duplicate_sheet"
|
||||
bl_label = "Duplicate Sheet"
|
||||
bl_description = "Make a copy of currently selected sheet"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
drawing: bpy.props.IntProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# Unconditionally disable until implemented
|
||||
cls.poll_message_set("Not implemented yet.")
|
||||
return False
|
||||
|
||||
props = context.scene.DocProperties
|
||||
if not tool.Drawing.get_active_drawing_item():
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _execute(self, context):
|
||||
pass
|
||||
"""
|
||||
self.props = context.scene.DocProperties
|
||||
core.duplicate_sheet(
|
||||
tool.Ifc,
|
||||
tool.Drawing,
|
||||
sheet=tool.Ifc.get().by_id(self.sheet),
|
||||
)
|
||||
try:
|
||||
sheet = tool.Ifc.get().by_id(self.props.active_sheet_id)
|
||||
core.sync_references(tool.Ifc, tool.Collector, tool.Sheet, drawing=sheet)
|
||||
except:
|
||||
pass
|
||||
"""
|
||||
|
||||
|
||||
class OpenLayout(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.open_layout"
|
||||
bl_label = "Open Sheet Layout"
|
||||
bl_description = (
|
||||
"Opens selected .svg layout with default system viewer\n"
|
||||
+ 'or using "layout_svg_command" from the Bonsai preferences\n'
|
||||
+ "(if provided)"
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
active_sheet = props.sheets[props.active_sheet_index]
|
||||
if not active_sheet.is_sheet:
|
||||
cls.poll_message_set("No sheet selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _execute(self, context):
|
||||
self.props = context.scene.DocProperties
|
||||
sheet = tool.Ifc.get().by_id(self.props.sheets[self.props.active_sheet_index].ifc_definition_id)
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.update_sheet_drawing_sizes(sheet)
|
||||
core.open_sheet(tool.Drawing, sheet=sheet)
|
||||
core.open_layout(tool.Drawing, sheet=sheet)
|
||||
|
||||
|
||||
class SelectAllSheets(bpy.types.Operator):
|
||||
bl_idname = "bim.select_all_sheets"
|
||||
bl_label = "Select All Sheetss"
|
||||
view: bpy.props.StringProperty()
|
||||
bl_description = "Select all sheets in the sheet list.\n\n" + "SHIFT+CLICK to deselect all sheets"
|
||||
select_all: bpy.props.BoolProperty(name="Open All", default=True, options={"SKIP_SAVE"})
|
||||
|
||||
def invoke(self, context, event):
|
||||
# deselect all sheets on shift+click
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
if event.type == "LEFTMOUSE" and event.shift:
|
||||
self.select_all = False
|
||||
return self.execute(context)
|
||||
|
||||
def execute(self, context):
|
||||
for sheet in context.scene.DocProperties.sheets:
|
||||
if sheet.is_selected != self.select_all:
|
||||
sheet.is_selected = self.select_all
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class OpenSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.open_sheet"
|
||||
bl_label = "Open Sheet"
|
||||
bl_description = (
|
||||
"Opens selected sheet with default system viewer\n"
|
||||
+ 'or using "svg_command" or "pdf_command" from\n'
|
||||
+ "the Bonsai preferences (if provided).\n\n"
|
||||
+ "SHIFT+CLICK to open all shown checked sheets"
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
open_all: bpy.props.BoolProperty(name="Open All", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
active_sheet = props.sheets[props.active_sheet_index]
|
||||
if not active_sheet.is_sheet:
|
||||
cls.poll_message_set("No sheet selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def invoke(self, context, event):
|
||||
# opening all sheets on shift+click
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
if event.type == "LEFTMOUSE" and event.shift:
|
||||
self.open_all = True
|
||||
return self.execute(context)
|
||||
|
||||
def execute(self, context):
|
||||
self.props = context.scene.DocProperties
|
||||
svg2pdf_command = tool.Blender.get_addon_preferences().svg2pdf_command
|
||||
|
||||
if self.open_all:
|
||||
sheets = [
|
||||
tool.Ifc.get().by_id(s.ifc_definition_id) for s in self.props.sheets if s.is_sheet and s.is_selected
|
||||
]
|
||||
else:
|
||||
sheets = [tool.Ifc.get().by_id(self.props.sheets[self.props.active_sheet_index].ifc_definition_id)]
|
||||
|
||||
sheet_uris = []
|
||||
sheets_not_found = []
|
||||
|
||||
for sheet in sheets:
|
||||
if not sheet.is_a("IfcDocumentInformation"):
|
||||
continue
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
references = sheet_builder.build(sheet)
|
||||
sheet_uri = references["SHEET"]
|
||||
if svg2pdf_command:
|
||||
sheet_uri = os.path.splitext(sheet_uri)[0] + ".pdf"
|
||||
sheet_uris.append(sheet_uri)
|
||||
if not os.path.exists(sheet_uri):
|
||||
sheets_not_found.append(sheet.Name)
|
||||
|
||||
if sheets_not_found:
|
||||
msg = "Some sheets .svg/.pdf files were not found, need to create them first: \n{}.".format(
|
||||
"\n".join(sheets_not_found)
|
||||
)
|
||||
self.report({"ERROR"}, msg)
|
||||
return {"CANCELLED"}
|
||||
|
||||
for sheet_uri in sheet_uris:
|
||||
if svg2pdf_command:
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().pdf_command, sheet_uri)
|
||||
else:
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, sheet_uri)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddDrawingToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_drawing_to_sheet"
|
||||
bl_label = "Add Drawing To Sheet"
|
||||
bl_label = "Add Selected Drawing To Sheet"
|
||||
bl_description = "Add the drawing selected in the\nDrawings list below to the sheet"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
@@ -1496,7 +1657,14 @@ class AddDrawingToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
attributes = tool.Drawing.generate_reference_attributes(
|
||||
reference,
|
||||
Identification=str(
|
||||
len([r for r in references if tool.Drawing.get_reference_description(r) in ("DRAWING", "SCHEDULE")]) + 1
|
||||
len(
|
||||
[
|
||||
r
|
||||
for r in references
|
||||
if tool.Drawing.get_reference_description(r) in ("DRAWING", "SCHEDULE", "REFERENCE")
|
||||
]
|
||||
)
|
||||
+ 1
|
||||
),
|
||||
Location=drawing_reference.Location,
|
||||
Description="DRAWING",
|
||||
@@ -1512,9 +1680,20 @@ class AddDrawingToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
class RemoveDrawingFromSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.remove_drawing_from_sheet"
|
||||
bl_label = "Remove Drawing From Sheet"
|
||||
bl_description = "Remove currently selected drawing from sheet"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
reference: bpy.props.IntProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
active_sheet = props.sheets[props.active_sheet_index]
|
||||
|
||||
if active_sheet.reference_type == "TITLEBLOCK":
|
||||
cls.poll_message_set("No effect deleting this.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _execute(self, context):
|
||||
reference = tool.Ifc.get().by_id(self.reference)
|
||||
sheet = tool.Drawing.get_reference_document(reference)
|
||||
@@ -1531,98 +1710,129 @@ class RemoveDrawingFromSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
class CreateSheets(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.create_sheets"
|
||||
bl_label = "Create Sheets"
|
||||
bl_description = "Build a sheet from the sheet layout"
|
||||
bl_description = (
|
||||
"Build and open selected sheet from the sheet layout and\n"
|
||||
+ "optionally create .pdf and .dxf from commands in\n"
|
||||
+ "the Bonsai preferences (if provided).\n\n"
|
||||
+ "SHIFT+CLICK to create all shown checked sheets, but doesn't\n"
|
||||
+ "open them for viewing\n\n"
|
||||
+ "Add the CTRL modifier to optionally open sheets to view them as\n"
|
||||
+ "they are created"
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
create_all: bpy.props.BoolProperty(name="Create All", default=False, options={"SKIP_SAVE"})
|
||||
open_viewer: bpy.props.BoolProperty(name="Open in Viewer", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.DocProperties.sheets and context.scene.BIMProperties.data_dir
|
||||
props = context.scene.DocProperties
|
||||
active_sheet = props.sheets[props.active_sheet_index]
|
||||
if not active_sheet.is_sheet:
|
||||
cls.poll_message_set("No sheet selected.")
|
||||
return False
|
||||
return props.sheets and context.scene.BIMProperties.data_dir
|
||||
|
||||
def invoke(self, context, event):
|
||||
# opening all sheets on shift+click
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
if event.type == "LEFTMOUSE" and event.shift:
|
||||
self.create_all = True
|
||||
if event.type == "LEFTMOUSE" and event.ctrl:
|
||||
self.open_viewer = True
|
||||
return self.execute(context)
|
||||
|
||||
def _execute(self, context):
|
||||
scene = context.scene
|
||||
props = scene.DocProperties
|
||||
active_sheet = props.sheets[props.active_sheet_index]
|
||||
sheet = tool.Ifc.get().by_id(active_sheet.ifc_definition_id)
|
||||
|
||||
# Update any drawing boundary changes
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.update_sheet_drawing_sizes(sheet)
|
||||
|
||||
if not sheet.is_a("IfcDocumentInformation"):
|
||||
return
|
||||
|
||||
name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.data_dir = scene.BIMProperties.data_dir
|
||||
|
||||
references = sheet_builder.build(sheet)
|
||||
raster_references = [tool.Ifc.get_relative_uri(r) for r in references["RASTER"]]
|
||||
|
||||
# These variables will be made available to the evaluated commands
|
||||
svg = references["SHEET"]
|
||||
pdf = os.path.splitext(svg)[0] + ".pdf"
|
||||
replacements = {
|
||||
"svg": svg,
|
||||
"basename": os.path.basename(svg),
|
||||
"path": os.path.dirname(svg),
|
||||
"pdf": pdf,
|
||||
"eps": os.path.splitext(svg)[0] + ".eps",
|
||||
"dxf": os.path.splitext(svg)[0] + ".dxf",
|
||||
}
|
||||
|
||||
has_sheet_reference = False
|
||||
for reference in tool.Drawing.get_document_references(sheet):
|
||||
reference_description = tool.Drawing.get_reference_description(reference)
|
||||
if reference_description == "SHEET":
|
||||
has_sheet_reference = True
|
||||
elif reference_description == "RASTER":
|
||||
if reference.Location in raster_references:
|
||||
raster_references.remove(reference.Location)
|
||||
else:
|
||||
tool.Ifc.run("document.remove_reference", reference=reference)
|
||||
|
||||
if not has_sheet_reference:
|
||||
reference = tool.Ifc.run("document.add_reference", information=sheet)
|
||||
tool.Ifc.run(
|
||||
"document.edit_reference",
|
||||
reference=reference,
|
||||
attributes=tool.Drawing.generate_reference_attributes(
|
||||
reference, Location=tool.Ifc.get_relative_uri(svg), Description="SHEET"
|
||||
),
|
||||
)
|
||||
|
||||
for raster_reference in raster_references:
|
||||
reference = tool.Ifc.run("document.add_reference", information=sheet)
|
||||
tool.Ifc.run(
|
||||
"document.edit_reference",
|
||||
reference=reference,
|
||||
attributes=tool.Drawing.generate_reference_attributes(
|
||||
reference, Location=tool.Ifc.get_relative_uri(raster_reference), Description="RASTER"
|
||||
),
|
||||
)
|
||||
|
||||
svg2pdf_command = tool.Blender.get_addon_preferences().svg2pdf_command
|
||||
svg2dxf_command = tool.Blender.get_addon_preferences().svg2dxf_command
|
||||
|
||||
if svg2pdf_command:
|
||||
# With great power comes great responsibility. Example:
|
||||
# [["inkscape", "svg", "-o", "pdf"]]
|
||||
commands = json.loads(svg2pdf_command)
|
||||
for command in commands:
|
||||
subprocess.run([replacements.get(c, c) for c in command])
|
||||
|
||||
if svg2dxf_command:
|
||||
# With great power comes great responsibility. Example:
|
||||
# [["inkscape", "svg", "-o", "eps"], ["pstoedit", "-dt", "-f", "dxf:-polyaslines -mm", "eps", "dxf", "-psarg", "-dNOSAFER"]]
|
||||
commands = json.loads(svg2dxf_command)
|
||||
for command in commands:
|
||||
command[0] = shutil.which(command[0]) or command[0]
|
||||
subprocess.run([replacements.get(c, c) for c in command])
|
||||
|
||||
if svg2pdf_command:
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().pdf_command, pdf)
|
||||
if self.create_all:
|
||||
sheets = [tool.Ifc.get().by_id(s.ifc_definition_id) for s in props.sheets if s.is_sheet and s.is_selected]
|
||||
else:
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, svg)
|
||||
sheets = [tool.Ifc.get().by_id(props.sheets[props.active_sheet_index].ifc_definition_id)]
|
||||
|
||||
for sheet in sheets:
|
||||
# Update any drawing boundary changes
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.update_sheet_drawing_sizes(sheet)
|
||||
|
||||
if not sheet.is_a("IfcDocumentInformation"):
|
||||
return
|
||||
|
||||
name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.data_dir = scene.BIMProperties.data_dir
|
||||
|
||||
references = sheet_builder.build(sheet)
|
||||
raster_references = [tool.Ifc.get_relative_uri(r) for r in references["RASTER"]]
|
||||
|
||||
# These variables will be made available to the evaluated commands
|
||||
svg = references["SHEET"]
|
||||
pdf = os.path.splitext(svg)[0] + ".pdf"
|
||||
replacements = {
|
||||
"svg": svg,
|
||||
"basename": os.path.basename(svg),
|
||||
"path": os.path.dirname(svg),
|
||||
"pdf": pdf,
|
||||
"eps": os.path.splitext(svg)[0] + ".eps",
|
||||
"dxf": os.path.splitext(svg)[0] + ".dxf",
|
||||
}
|
||||
|
||||
has_sheet_reference = False
|
||||
for reference in tool.Drawing.get_document_references(sheet):
|
||||
reference_description = tool.Drawing.get_reference_description(reference)
|
||||
if reference_description == "SHEET":
|
||||
has_sheet_reference = True
|
||||
elif reference_description == "RASTER":
|
||||
if reference.Location in raster_references:
|
||||
raster_references.remove(reference.Location)
|
||||
else:
|
||||
tool.Ifc.run("document.remove_reference", reference=reference)
|
||||
|
||||
if not has_sheet_reference:
|
||||
reference = tool.Ifc.run("document.add_reference", information=sheet)
|
||||
tool.Ifc.run(
|
||||
"document.edit_reference",
|
||||
reference=reference,
|
||||
attributes=tool.Drawing.generate_reference_attributes(
|
||||
reference, Location=tool.Ifc.get_relative_uri(svg), Description="SHEET"
|
||||
),
|
||||
)
|
||||
|
||||
for raster_reference in raster_references:
|
||||
reference = tool.Ifc.run("document.add_reference", information=sheet)
|
||||
tool.Ifc.run(
|
||||
"document.edit_reference",
|
||||
reference=reference,
|
||||
attributes=tool.Drawing.generate_reference_attributes(
|
||||
reference, Location=tool.Ifc.get_relative_uri(raster_reference), Description="RASTER"
|
||||
),
|
||||
)
|
||||
|
||||
if svg2pdf_command:
|
||||
# With great power comes great responsibility. Example:
|
||||
# [["inkscape", "svg", "-o", "pdf"]]
|
||||
commands = json.loads(svg2pdf_command)
|
||||
for command in commands:
|
||||
subprocess.run([replacements.get(c, c) for c in command])
|
||||
|
||||
if svg2dxf_command:
|
||||
# With great power comes great responsibility. Example:
|
||||
# [["inkscape", "svg", "-o", "eps"], ["pstoedit", "-dt", "-f", "dxf:-polyaslines -mm", "eps", "dxf", "-psarg", "-dNOSAFER"]]
|
||||
commands = json.loads(svg2dxf_command)
|
||||
for command in commands:
|
||||
command[0] = shutil.which(command[0]) or command[0]
|
||||
subprocess.run([replacements.get(c, c) for c in command])
|
||||
|
||||
if self.open_viewer:
|
||||
if svg2pdf_command:
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().pdf_command, pdf)
|
||||
else:
|
||||
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, svg)
|
||||
if not self.open_viewer:
|
||||
self.report({"INFO"}, f"{len(sheets)} sheets created...")
|
||||
|
||||
|
||||
class SelectAllDrawings(bpy.types.Operator):
|
||||
@@ -1651,12 +1861,20 @@ class OpenDrawing(bpy.types.Operator):
|
||||
bl_label = "Open Drawing"
|
||||
view: bpy.props.StringProperty()
|
||||
bl_description = (
|
||||
"Opens a .svg drawing based on currently active camera with default system viewer\n"
|
||||
"Opens selected .svg drawing with default system viewer\n"
|
||||
+ 'or using "svg_command" from the Bonsai preferences (if provided).\n\n'
|
||||
+ "SHIFT+CLICK to open all selected drawings"
|
||||
+ "SHIFT+CLICK to open all shown checked drawings"
|
||||
)
|
||||
open_all: bpy.props.BoolProperty(name="Open All", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not tool.Drawing.get_active_drawing_item():
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def invoke(self, context, event):
|
||||
# opening all drawings on shift+click
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
@@ -1665,12 +1883,13 @@ class OpenDrawing(bpy.types.Operator):
|
||||
return self.execute(context)
|
||||
|
||||
def execute(self, context):
|
||||
self.props = context.scene.DocProperties
|
||||
if self.open_all:
|
||||
drawings = [
|
||||
tool.Ifc.get().by_id(d.ifc_definition_id) for d in context.scene.DocProperties.drawings if d.is_selected
|
||||
tool.Ifc.get().by_id(d.ifc_definition_id) for d in self.props.drawings if d.is_drawing and d.is_selected
|
||||
]
|
||||
else:
|
||||
drawings = [tool.Ifc.get().by_id(context.scene.DocProperties.drawings.get(self.view).ifc_definition_id)]
|
||||
drawings = [tool.Ifc.get().by_id(self.props.drawings.get(self.view).ifc_definition_id)]
|
||||
|
||||
drawing_uris = []
|
||||
drawings_not_found = []
|
||||
@@ -1682,7 +1901,7 @@ class OpenDrawing(bpy.types.Operator):
|
||||
drawings_not_found.append(drawing.Name)
|
||||
|
||||
if drawings_not_found:
|
||||
msg = "Some drawings .svg files were not found, need to print them first: \n{}.".format(
|
||||
msg = "Some drawings .svg files were not found, need to create them first: \n{}.".format(
|
||||
"\n".join(drawings_not_found)
|
||||
)
|
||||
self.report({"ERROR"}, msg)
|
||||
@@ -1755,20 +1974,7 @@ class ActivateModel(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ActivateDrawing(bpy.types.Operator):
|
||||
bl_idname = "bim.activate_drawing"
|
||||
bl_label = "Activate Drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = (
|
||||
"Activates the selected drawing view.\n\n"
|
||||
+ "ALT+CLICK to keep the viewport position.\n\n"
|
||||
+ "SHIFT+CLICK to load a quick preview of the drawing view."
|
||||
)
|
||||
|
||||
drawing: bpy.props.IntProperty()
|
||||
should_view_from_camera: bpy.props.BoolProperty(name="Should View From Camera", default=True, options={"SKIP_SAVE"})
|
||||
use_quick_preview: bpy.props.BoolProperty(name="Use Quick Preview", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
class ActivateDrawingBase:
|
||||
def invoke(self, context, event):
|
||||
if event.type == "LEFTMOUSE" and event.alt:
|
||||
self.should_view_from_camera = False
|
||||
@@ -1817,6 +2023,54 @@ class ActivateDrawing(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ActivateDrawing(bpy.types.Operator, ActivateDrawingBase):
|
||||
bl_idname = "bim.activate_drawing"
|
||||
bl_label = "Activate Drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = (
|
||||
"Activates the selected drawing view.\n\n"
|
||||
+ "ALT+CLICK to keep the viewport position.\n\n"
|
||||
+ "SHIFT+CLICK to load a quick preview of the drawing view"
|
||||
)
|
||||
|
||||
drawing: bpy.props.IntProperty()
|
||||
should_view_from_camera: bpy.props.BoolProperty(name="Should View From Camera", default=True, options={"SKIP_SAVE"})
|
||||
use_quick_preview: bpy.props.BoolProperty(name="Use Quick Preview", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not tool.Drawing.get_active_drawing_item():
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class ActivateDrawingFromSheet(bpy.types.Operator, ActivateDrawingBase):
|
||||
bl_idname = "bim.activate_drawing_from_sheet"
|
||||
bl_label = "Activate Drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = (
|
||||
"Activates the selected drawing view.\n\n"
|
||||
+ "ALT+CLICK to keep the viewport position.\n\n"
|
||||
+ "SHIFT+CLICK to load a quick preview of the drawing view"
|
||||
)
|
||||
|
||||
drawing: bpy.props.IntProperty()
|
||||
should_view_from_camera: bpy.props.BoolProperty(name="Should View From Camera", default=True, options={"SKIP_SAVE"})
|
||||
use_quick_preview: bpy.props.BoolProperty(name="Use Quick Preview", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
active_sheet = props.sheets[props.active_sheet_index]
|
||||
is_drawing_selected = active_sheet.reference_type == "DRAWING"
|
||||
if not is_drawing_selected:
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class SelectDocIfcFile(bpy.types.Operator):
|
||||
bl_idname = "bim.select_doc_ifc_file"
|
||||
bl_label = "Select Documentation IFC File"
|
||||
@@ -1856,6 +2110,14 @@ class RemoveDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
drawing: bpy.props.IntProperty()
|
||||
remove_all: bpy.props.BoolProperty(name="Remove All", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not tool.Drawing.get_active_drawing_item():
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def invoke(self, context, event):
|
||||
# removing all selected drawings on shift+click
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
@@ -1866,7 +2128,9 @@ class RemoveDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
def _execute(self, context):
|
||||
if self.remove_all:
|
||||
drawings = [
|
||||
tool.Ifc.get().by_id(d.ifc_definition_id) for d in context.scene.DocProperties.drawings if d.is_selected
|
||||
tool.Ifc.get().by_id(d.ifc_definition_id)
|
||||
for d in context.scene.DocProperties.drawings
|
||||
if d.is_drawing and d.is_selected
|
||||
]
|
||||
else:
|
||||
if not self.drawing:
|
||||
@@ -2192,6 +2456,7 @@ class RemoveSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.remove_sheet"
|
||||
bl_label = "Remove Sheet"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Remove currently selected sheet"
|
||||
sheet: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
@@ -2260,11 +2525,15 @@ class BuildSchedule(bpy.types.Operator, tool.Ifc.Operator):
|
||||
class AddScheduleToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_schedule_to_sheet"
|
||||
bl_label = "Add Schedule To Sheet"
|
||||
bl_description = "Add the schedule selected in the\nSchedules list below to the sheet"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not props.schedules:
|
||||
cls.poll_message_set("No schedule selected.")
|
||||
return False
|
||||
return props.schedules and props.sheets and context.scene.BIMProperties.data_dir
|
||||
|
||||
def _execute(self, context):
|
||||
@@ -2299,7 +2568,14 @@ class AddScheduleToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
attributes = tool.Drawing.generate_reference_attributes(
|
||||
reference,
|
||||
Identification=str(
|
||||
len([r for r in references if tool.Drawing.get_reference_description(r) in ("DRAWING", "SCHEDULE")]) + 1
|
||||
len(
|
||||
[
|
||||
r
|
||||
for r in references
|
||||
if tool.Drawing.get_reference_description(r) in ("DRAWING", "SCHEDULE", "REFERENCE")
|
||||
]
|
||||
)
|
||||
+ 1
|
||||
),
|
||||
Location=schedule_location,
|
||||
Description="SCHEDULE",
|
||||
@@ -2316,11 +2592,15 @@ class AddScheduleToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
class AddReferenceToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_reference_to_sheet"
|
||||
bl_label = "Add Reference To Sheet"
|
||||
bl_description = "Add the reference selected in the\nReferences list below to the sheet"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not props.references:
|
||||
cls.poll_message_set("No reference selected.")
|
||||
return False
|
||||
return props.references and props.sheets and context.scene.BIMProperties.data_dir
|
||||
|
||||
def _execute(self, context):
|
||||
@@ -2355,7 +2635,13 @@ class AddReferenceToSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
attributes = tool.Drawing.generate_reference_attributes(
|
||||
reference,
|
||||
Identification=str(
|
||||
len([r for r in references if tool.Drawing.get_reference_description(r) in ("DRAWING", "REFERENCE")])
|
||||
len(
|
||||
[
|
||||
r
|
||||
for r in references
|
||||
if tool.Drawing.get_reference_description(r) in ("DRAWING", "SCHEDULE", "REFERENCE")
|
||||
]
|
||||
)
|
||||
+ 1
|
||||
),
|
||||
Location=extref_location,
|
||||
@@ -2720,7 +3006,8 @@ class LoadSheets(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
class EditSheet(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_sheet"
|
||||
bl_label = "Edit Sheet"
|
||||
bl_label = "Edit Sheet / Drawing"
|
||||
bl_description = "Edit details of sheet or drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
identification: bpy.props.StringProperty()
|
||||
name: bpy.props.StringProperty()
|
||||
@@ -3069,20 +3356,30 @@ class ConvertSVGToDXF(bpy.types.Operator):
|
||||
bl_label = "Convert SVG to DXF"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
view: bpy.props.StringProperty()
|
||||
bl_description = "Convert current drawing's .svg to .dxf.\n\nSHIFT+CLICK to convert all selected drawings"
|
||||
bl_description = "Convert selected drawing's .svg to .dxf.\n\nSHIFT+CLICK to convert all shown checked drawings"
|
||||
convert_all: bpy.props.BoolProperty(name="Convert All", default=False, options={"SKIP_SAVE"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
if not tool.Drawing.get_active_drawing_item():
|
||||
cls.poll_message_set("No drawing selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def invoke(self, context, event):
|
||||
# convert all drawings on shift+click
|
||||
# make sure to use SKIP_SAVE on property, otherwise it might get stuck
|
||||
if event.type == "LEFTMOUSE" and event.shift:
|
||||
self.open_all = True
|
||||
self.convert_all = True
|
||||
return self.execute(context)
|
||||
|
||||
def execute(self, context):
|
||||
if self.convert_all:
|
||||
drawings = [
|
||||
tool.Ifc.get().by_id(d.ifc_definition_id) for d in context.scene.DocProperties.drawings if d.is_selected
|
||||
tool.Ifc.get().by_id(d.ifc_definition_id)
|
||||
for d in context.scene.DocProperties.drawings
|
||||
if d.is_drawing and d.is_selected
|
||||
]
|
||||
else:
|
||||
drawings = [tool.Ifc.get().by_id(context.scene.DocProperties.drawings.get(self.view).ifc_definition_id)]
|
||||
|
||||
@@ -290,6 +290,7 @@ class Sheet(PropertyGroup):
|
||||
identification: StringProperty(name="Identification")
|
||||
name: StringProperty(name="Name")
|
||||
is_sheet: BoolProperty(name="Is Sheet", default=False)
|
||||
is_selected: BoolProperty(name="Is Selected", default=True)
|
||||
reference_type: StringProperty(name="Reference Type")
|
||||
is_expanded: BoolProperty(name="Is Expanded", default=False)
|
||||
|
||||
|
||||
@@ -92,11 +92,6 @@ class BIM_PT_camera(Panel):
|
||||
row = self.layout.row()
|
||||
row.prop(props, "dpi")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.create_drawing", text="Create Drawing", icon="OUTPUT")
|
||||
op = row.operator("bim.open_drawing", icon="URL", text="")
|
||||
op.view = context.scene.camera.name.split("/")[1]
|
||||
|
||||
|
||||
class BIM_PT_element_filters(Panel):
|
||||
bl_label = "Element Filters"
|
||||
@@ -252,43 +247,29 @@ class BIM_PT_drawings(Panel):
|
||||
if self.props.active_drawing_index < len(self.props.drawings):
|
||||
active_drawing = self.props.drawings[self.props.active_drawing_index]
|
||||
row = self.layout.row(align=True)
|
||||
col = row.column()
|
||||
col.alignment = "LEFT"
|
||||
row2 = col.row(align=True)
|
||||
row2 = row.row(align=True)
|
||||
row2.operator("bim.remove_drawing", icon="X", text="").drawing = active_drawing.ifc_definition_id
|
||||
|
||||
row2.operator("bim.duplicate_drawing", icon="COPYDOWN", text="").drawing = (
|
||||
row2.separator(factor=0.5, type="SPACE")
|
||||
|
||||
row2.operator("bim.duplicate_drawing", icon="DUPLICATE", text="").drawing = (
|
||||
active_drawing.ifc_definition_id
|
||||
)
|
||||
|
||||
col = row.column()
|
||||
col.alignment = "RIGHT"
|
||||
row3 = row.row(align=True)
|
||||
row3.alignment = "RIGHT"
|
||||
|
||||
convert_to_dxf = row.row(align=True)
|
||||
op = convert_to_dxf.operator("bim.convert_svg_to_dxf", text="", icon="IMAGE_DATA")
|
||||
op.view = active_drawing.name
|
||||
convert_to_dxf.enabled = active_drawing.ifc_definition_id > 0
|
||||
row3.operator("bim.activate_drawing", icon="OUTLINER_OB_CAMERA", text="").drawing = (
|
||||
active_drawing.ifc_definition_id
|
||||
)
|
||||
row3.operator("bim.activate_model", icon="VIEW3D", text="")
|
||||
|
||||
op = row.operator("bim.select_all_drawings", icon="SELECT_SUBTRACT", text="")
|
||||
row3.separator(factor=0.5, type="SPACE")
|
||||
|
||||
open_drawing_button = row.row(align=True)
|
||||
op = open_drawing_button.operator("bim.open_drawing", icon="URL", text="")
|
||||
op.view = active_drawing.name
|
||||
open_drawing_button.enabled = active_drawing.ifc_definition_id > 0
|
||||
|
||||
row.operator("bim.activate_model", icon="VIEW3D", text="")
|
||||
|
||||
drawing_button = row.row(align=True)
|
||||
op = drawing_button.operator("bim.activate_drawing", icon="OUTLINER_OB_CAMERA", text="")
|
||||
op.drawing = active_drawing.ifc_definition_id
|
||||
drawing_button.enabled = active_drawing.ifc_definition_id > 0
|
||||
|
||||
create_drawing_button = row.row(align=True)
|
||||
create_drawing_button.operator("bim.create_drawing", text="", icon="OUTPUT")
|
||||
create_drawing_button.enabled = active_drawing.ifc_definition_id > 0
|
||||
|
||||
# might need a different icon since the URL icon is already used by the open_drawing
|
||||
row.operator("bim.open_documentation_web_ui", icon="URL", text="")
|
||||
row3.operator("bim.select_all_drawings", icon="CHECKBOX_HLT", text="")
|
||||
row3.operator("bim.create_drawing", text="", icon="OUTPUT")
|
||||
row3.operator("bim.convert_svg_to_dxf", text="", icon="SEQ_PREVIEW").view = active_drawing.name
|
||||
row3.operator("bim.open_drawing", icon="HIDE_OFF", text="").view = active_drawing.name
|
||||
self.layout.template_list(
|
||||
"BIM_UL_drawinglist", "", self.props, "drawings", self.props, "active_drawing_index"
|
||||
)
|
||||
@@ -325,7 +306,7 @@ class BIM_PT_schedules(Panel):
|
||||
|
||||
if not self.props.is_editing_schedules:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=f"{DocumentsData.data['total_schedules']} Schedules Found", icon="LONGDISPLAY")
|
||||
row.label(text=f"{DocumentsData.data['total_schedules']} Schedules Found", icon="PRESET")
|
||||
row.operator("bim.load_schedules", text="", icon="IMPORT")
|
||||
return
|
||||
|
||||
@@ -375,7 +356,7 @@ class BIM_PT_references(Panel):
|
||||
|
||||
if not self.props.is_editing_references:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=f"{DocumentsData.data['total_references']} References Found", icon="OBJECT_HIDDEN")
|
||||
row.label(text=f"{DocumentsData.data['total_references']} References Found", icon="IMAGE_REFERENCE")
|
||||
row.operator("bim.load_references", text="", icon="IMPORT")
|
||||
return
|
||||
|
||||
@@ -429,7 +410,23 @@ class BIM_PT_sheets(Panel):
|
||||
if self.props.sheets and self.props.active_sheet_index < len(self.props.sheets):
|
||||
active_sheet = self.props.sheets[self.props.active_sheet_index]
|
||||
row = self.layout.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
row2 = row.row(align=True)
|
||||
if active_sheet.is_sheet:
|
||||
row2.operator("bim.remove_sheet", icon="X", text="").sheet = active_sheet.ifc_definition_id
|
||||
else:
|
||||
row2.operator("bim.remove_drawing_from_sheet", icon="X", text="").reference = (
|
||||
active_sheet.ifc_definition_id
|
||||
)
|
||||
|
||||
row2.separator(factor=0.5, type="SPACE")
|
||||
|
||||
row2.operator("bim.duplicate_sheet", icon="DUPLICATE", text="").drawing = active_sheet.ifc_definition_id
|
||||
row2.operator("bim.open_documentation_web_ui", icon="URL", text="")
|
||||
|
||||
row3 = row.row(align=True)
|
||||
row3.alignment = "RIGHT"
|
||||
|
||||
op = row3.operator("bim.activate_drawing_from_sheet", icon="OUTLINER_OB_CAMERA", text="")
|
||||
|
||||
if active_sheet.reference_type == "DRAWING":
|
||||
drawingnamesvg = active_sheet.name
|
||||
@@ -445,23 +442,21 @@ class BIM_PT_sheets(Panel):
|
||||
break
|
||||
|
||||
if drawingid is not None:
|
||||
drawing_button = row.row(align=True)
|
||||
op = drawing_button.operator("bim.activate_drawing", icon="OUTLINER_OB_CAMERA", text="")
|
||||
op.drawing = drawingid
|
||||
else:
|
||||
print(f"No matching drawing ID found for {drawingname}")
|
||||
|
||||
row.operator("bim.edit_sheet", icon="GREASEPENCIL", text="")
|
||||
row.operator("bim.open_sheet", icon="URL", text="")
|
||||
row.operator("bim.add_drawing_to_sheet", icon="IMAGE_PLANE", text="")
|
||||
row.operator("bim.add_schedule_to_sheet", icon="PRESET_NEW", text="")
|
||||
row.operator("bim.add_reference_to_sheet", icon="IMAGE_REFERENCE", text="")
|
||||
row.operator("bim.create_sheets", icon="FILE_REFRESH", text="")
|
||||
if active_sheet.is_sheet:
|
||||
row.operator("bim.remove_sheet", icon="X", text="").sheet = active_sheet.ifc_definition_id
|
||||
else:
|
||||
op = row.operator("bim.remove_drawing_from_sheet", icon="X", text="")
|
||||
op.reference = active_sheet.ifc_definition_id
|
||||
row3.separator(factor=0.5, type="SPACE")
|
||||
|
||||
row3.operator("bim.edit_sheet", icon="GREASEPENCIL", text="")
|
||||
row3.operator("bim.add_drawing_to_sheet", icon="IMAGE_PLANE", text="")
|
||||
row3.operator("bim.add_schedule_to_sheet", icon="PRESET_NEW", text="")
|
||||
row3.operator("bim.add_reference_to_sheet", icon="IMAGE_REFERENCE", text="")
|
||||
row3.operator("bim.open_layout", icon="CURRENT_FILE", text="")
|
||||
|
||||
row3.separator(factor=0.5, type="SPACE")
|
||||
|
||||
row3.operator("bim.select_all_sheets", icon="CHECKBOX_HLT", text="")
|
||||
row3.operator("bim.create_sheets", icon="OUTPUT", text="")
|
||||
row3.operator("bim.open_sheet", icon="HIDE_OFF", text="")
|
||||
|
||||
self.layout.template_list("BIM_UL_sheets", "", self.props, "sheets", self.props, "active_sheet_index")
|
||||
|
||||
@@ -600,6 +595,13 @@ class BIM_UL_drawinglist(bpy.types.UIList):
|
||||
selected_icon = "CHECKBOX_HLT" if item.is_selected else "CHECKBOX_DEHLT"
|
||||
row.prop(item, "is_selected", text="", icon=selected_icon, emboss=False)
|
||||
row.prop(item, "name", text="", emboss=False)
|
||||
self.props = context.scene.DocProperties
|
||||
if (
|
||||
self.props.drawings
|
||||
and self.props.active_drawing_id
|
||||
and item.ifc_definition_id == self.props.active_drawing_id
|
||||
):
|
||||
row.label(text="", icon="OUTLINER_OB_CAMERA")
|
||||
else:
|
||||
if item.target_view == "PLAN_VIEW":
|
||||
icon = "UV_FACESEL"
|
||||
@@ -641,13 +643,16 @@ class BIM_UL_sheets(bpy.types.UIList):
|
||||
item.ifc_definition_id
|
||||
)
|
||||
|
||||
selected_icon = "CHECKBOX_HLT" if item.is_selected else "CHECKBOX_DEHLT"
|
||||
row.prop(item, "is_selected", text="", icon=selected_icon, emboss=False)
|
||||
|
||||
row.label(text=f"{item.identification} - {item.name}")
|
||||
else:
|
||||
row.label(text="", icon="BLANK1")
|
||||
if item.reference_type == "DRAWING":
|
||||
row.label(text="", icon="IMAGE_DATA")
|
||||
elif item.reference_type == "SCHEDULE":
|
||||
row.label(text="", icon="LONGDISPLAY")
|
||||
row.label(text="", icon="PRESET")
|
||||
elif item.reference_type == "TITLEBLOCK":
|
||||
row.label(text="", icon="MENU_PANEL")
|
||||
elif item.reference_type == "REVISION":
|
||||
|
||||
@@ -113,7 +113,7 @@ def regenerate_sheet(drawing: tool.Drawing, sheet: ifcopenshell.entity_instance)
|
||||
drawing.delete_file(path_layout)
|
||||
|
||||
|
||||
def open_sheet(drawing: tool.Drawing, sheet: ifcopenshell.entity_instance) -> None:
|
||||
def open_layout(drawing: tool.Drawing, sheet: ifcopenshell.entity_instance) -> None:
|
||||
drawing.open_layout_svg(drawing.get_document_uri(sheet, "LAYOUT"))
|
||||
|
||||
|
||||
|
||||
@@ -774,7 +774,9 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
def import_drawings(cls) -> None:
|
||||
props = bpy.context.scene.DocProperties
|
||||
expanded_target_views = {d.target_view for d in props.drawings if d.is_expanded}
|
||||
current_drawings_selection = {d.ifc_definition_id: d.is_selected for d in props.drawings}
|
||||
if not hasattr(cls, "drawing_selected_states"):
|
||||
cls.drawing_selected_states = {}
|
||||
cls.drawing_selected_states.update({d.ifc_definition_id: d.is_selected for d in props.drawings if d.is_drawing})
|
||||
props.drawings.clear()
|
||||
drawings = [e for e in tool.Ifc.get().by_type("IfcAnnotation") if e.ObjectType == "DRAWING"]
|
||||
grouped_drawings = {
|
||||
@@ -801,7 +803,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
for drawing in sorted(drawings, key=lambda x: x.Name or "Unnamed"):
|
||||
new = props.drawings.add()
|
||||
new.name = drawing.Name or "Unnamed"
|
||||
new.is_selected = current_drawings_selection.get(drawing.id(), True)
|
||||
new.is_selected = cls.drawing_selected_states.setdefault(drawing.id(), True)
|
||||
new.is_drawing = True
|
||||
new.ifc_definition_id = drawing.id() # Last, to prevent unnecessary prop callbacks
|
||||
|
||||
@@ -828,6 +830,9 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
def import_sheets(cls) -> None:
|
||||
props = bpy.context.scene.DocProperties
|
||||
expanded_sheets = {s.ifc_definition_id for s in props.sheets if s.is_expanded}
|
||||
if not hasattr(cls, "sheet_selected_states"):
|
||||
cls.sheet_selected_states = {}
|
||||
cls.sheet_selected_states.update({s.ifc_definition_id: s.is_selected for s in props.sheets if s.is_sheet})
|
||||
props.sheets.clear()
|
||||
sheets = [d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "SHEET"]
|
||||
for sheet in sorted(sheets, key=lambda s: getattr(s, "Identification", getattr(s, "DocumentId", None))):
|
||||
@@ -840,6 +845,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
new.name = sheet.Name
|
||||
new.is_sheet = True
|
||||
new.is_expanded = sheet.id() in expanded_sheets
|
||||
new.is_selected = cls.sheet_selected_states.setdefault(sheet.id(), True)
|
||||
|
||||
if not new.is_expanded:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user