Show warnings if some sheets related files are missing

Previously when you would load/open/create sheets and some files were missing you would get traceback errors.

Also removed warnings for missing sheets svgs since they can go missing if someone is opening ifc project and want to regenerate sheets. We'll be able to return them in the future, if needed, but they will need some refinement.
This commit is contained in:
Andrej730
2025-07-07 14:08:45 +05:00
parent d7668c3e3f
commit d4f32802aa
3 changed files with 76 additions and 11 deletions
@@ -1792,12 +1792,16 @@ class OpenSheet(bpy.types.Operator):
else: else:
sheets = [tool.Ifc.get().by_id(self.props.sheets[self.props.active_sheet_index].ifc_definition_id)] sheets = [tool.Ifc.get().by_id(self.props.sheets[self.props.active_sheet_index].ifc_definition_id)]
sheet_uris = [] sheet_uris: list[str] = []
sheets_not_found = [] sheets_not_found: list[str] = []
warnings: list[tool.Drawing.SheetWarningType] = []
for sheet in sheets: for sheet in sheets:
if not sheet.is_a("IfcDocumentInformation"): if not sheet.is_a("IfcDocumentInformation"):
continue continue
warnings.extend(sheets_warnings := tool.Drawing.validate_sheet_files(sheet))
if sheets_warnings:
continue
sheet_builder = sheeter.SheetBuilder() sheet_builder = sheeter.SheetBuilder()
references = sheet_builder.build(sheet) references = sheet_builder.build(sheet)
sheet_uri = references["SHEET"] sheet_uri = references["SHEET"]
@@ -1807,6 +1811,11 @@ class OpenSheet(bpy.types.Operator):
if not os.path.exists(sheet_uri): if not os.path.exists(sheet_uri):
sheets_not_found.append(sheet.Name) sheets_not_found.append(sheet.Name)
if warnings:
self.report({"ERROR"}, f"There were errors opening sheets. See system console for the details.")
print("-" * 10)
print("\n".join(str(w) for w in warnings))
if sheets_not_found: if sheets_not_found:
msg = "Some sheets .svg/.pdf files were not found, need to create them first: \n{}.".format( msg = "Some sheets .svg/.pdf files were not found, need to create them first: \n{}.".format(
"\n".join(sheets_not_found) "\n".join(sheets_not_found)
@@ -1962,7 +1971,14 @@ class CreateSheets(bpy.types.Operator, tool.Ifc.Operator):
else: else:
sheets = [tool.Ifc.get().by_id(props.sheets[props.active_sheet_index].ifc_definition_id)] sheets = [tool.Ifc.get().by_id(props.sheets[props.active_sheet_index].ifc_definition_id)]
warnings: list[tool.Drawing.SheetWarningType] = []
n_sheets_created = 0
for sheet in sheets: for sheet in sheets:
warnings.extend(sheet_warnings := tool.Drawing.validate_sheet_files(sheet))
if sheet_warnings:
continue
# Update any drawing boundary changes # Update any drawing boundary changes
sheet_builder = sheeter.SheetBuilder() sheet_builder = sheeter.SheetBuilder()
sheet_builder.update_sheet_drawing_sizes(sheet) sheet_builder.update_sheet_drawing_sizes(sheet)
@@ -2023,8 +2039,16 @@ class CreateSheets(bpy.types.Operator, tool.Ifc.Operator):
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().pdf_command, pdf) tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().pdf_command, pdf)
else: else:
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, svg) tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, svg)
n_sheets_created += 1
if not self.open_viewer: if not self.open_viewer:
self.report({"INFO"}, f"{len(sheets)} sheets created...") self.report({"INFO"}, f"{n_sheets_created} sheets created...")
if warnings:
self.report({"ERROR"}, f"There were errors creating sheets. See system console for the details.")
print("-" * 10)
print("\n".join(str(w) for w in warnings))
class SelectAllDrawings(bpy.types.Operator): class SelectAllDrawings(bpy.types.Operator):
@@ -3162,7 +3186,7 @@ class LoadSheets(bpy.types.Operator, tool.Ifc.Operator):
core.load_sheets(tool.Drawing) core.load_sheets(tool.Drawing)
props = tool.Drawing.get_document_props() props = tool.Drawing.get_document_props()
sheets_not_found = [] warnings: list[tool.Drawing.SheetWarningType] = []
for sheet_prop in props.sheets: for sheet_prop in props.sheets:
if not sheet_prop.is_sheet: if not sheet_prop.is_sheet:
continue continue
@@ -3173,12 +3197,14 @@ class LoadSheets(bpy.types.Operator, tool.Ifc.Operator):
filepath = Path(document_uri) filepath = Path(document_uri)
if not filepath.is_file(): if not filepath.is_file():
sheet_name = f"{sheet_prop.identification} - {sheet_prop.name}" res = core.regenerate_sheet(tool.Drawing, sheet)
sheets_not_found.append(f'"{sheet_name}" - {document_uri}') if res:
core.regenerate_sheet(tool.Drawing, sheet) warnings.extend(res)
if sheets_not_found: if warnings:
self.report({"ERROR"}, "Some sheets svg files are missing:\n" + "\n".join(sheets_not_found)) self.report({"WARNING"}, f"There were warnings loading sheets. See system console for the details.")
print("-" * 10)
print("\n".join(str(w) for w in warnings))
class EditSheet(bpy.types.Operator, tool.Ifc.Operator): class EditSheet(bpy.types.Operator, tool.Ifc.Operator):
+11 -2
View File
@@ -18,7 +18,7 @@
from __future__ import annotations from __future__ import annotations
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Optional, Union from typing import TYPE_CHECKING, Optional, Union, Literal
if TYPE_CHECKING: if TYPE_CHECKING:
import bpy import bpy
@@ -108,13 +108,22 @@ def add_sheet(ifc: type[tool.Ifc], drawing: type[tool.Drawing], titleblock: ifco
drawing.import_sheets() drawing.import_sheets()
def regenerate_sheet(drawing: type[tool.Drawing], sheet: ifcopenshell.entity_instance) -> None: def regenerate_sheet(
drawing: type[tool.Drawing], sheet: ifcopenshell.entity_instance
) -> Union[list[tool.Drawing.SheetWarningType], None]:
warnings = drawing.validate_sheet_files(sheet)
if warnings:
return warnings
titleblock_uri = drawing.get_document_uri(sheet, "TITLEBLOCK") titleblock_uri = drawing.get_document_uri(sheet, "TITLEBLOCK")
assert titleblock_uri
drawing.create_svg_sheet(sheet, drawing.sanitise_filename(Path(titleblock_uri).stem)) drawing.create_svg_sheet(sheet, drawing.sanitise_filename(Path(titleblock_uri).stem))
try: try:
drawing.add_drawings(sheet) drawing.add_drawings(sheet)
except FileNotFoundError: except FileNotFoundError:
path_layout = drawing.get_document_uri(sheet, "LAYOUT") path_layout = drawing.get_document_uri(sheet, "LAYOUT")
assert path_layout
if drawing.does_file_exist(path_layout): if drawing.does_file_exist(path_layout):
drawing.delete_file(path_layout) drawing.delete_file(path_layout)
+30
View File
@@ -374,6 +374,7 @@ class Drawing(bonsai.core.tool.Drawing):
sheet_builder = sheeter.SheetBuilder() sheet_builder = sheeter.SheetBuilder()
uri = cls.get_document_uri(document, "LAYOUT") uri = cls.get_document_uri(document, "LAYOUT")
assert uri
sheet_builder.create(uri, titleblock) sheet_builder.create(uri, titleblock)
return uri return uri
@@ -1245,6 +1246,35 @@ class Drawing(bonsai.core.tool.Drawing):
# TODO below this point is highly experimental prototype code with no tests # TODO below this point is highly experimental prototype code with no tests
class SheetWarningType(NamedTuple):
warning_type: Literal["MISSING_LAYOUT", "MISSING_TITLEBLOCK"]
message: str
def __str__(self) -> str:
return f"{self.warning_type:<20} - {self.message}"
@classmethod
def validate_sheet_files(cls, sheet: ifcopenshell.entity_instance) -> list[SheetWarningType]:
warnings: list[tool.Drawing.SheetWarningType] = []
layout_path = cls.get_document_uri(sheet, "LAYOUT")
assert layout_path
sheet_id = cls.get_sheet_identification(sheet)
if not Path(layout_path).exists():
warnings.append(
cls.SheetWarningType("MISSING_LAYOUT", f"Sheet '{sheet_id}' - missing layout '{layout_path}'.")
)
titleblock_path = cls.get_document_uri(sheet, "TITLEBLOCK")
assert titleblock_path
if not Path(titleblock_path).exists():
warnings.append(
cls.SheetWarningType(
"MISSING_TITLEBLOCK", f"Sheet '{sheet_id}' - missing titleblock '{titleblock_path}'."
)
)
return warnings
@classmethod @classmethod
def does_file_exist(cls, uri: str) -> bool: def does_file_exist(cls, uri: str) -> bool:
return os.path.exists(uri) return os.path.exists(uri)