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:
sheets = [tool.Ifc.get().by_id(self.props.sheets[self.props.active_sheet_index].ifc_definition_id)]
sheet_uris = []
sheets_not_found = []
sheet_uris: list[str] = []
sheets_not_found: list[str] = []
warnings: list[tool.Drawing.SheetWarningType] = []
for sheet in sheets:
if not sheet.is_a("IfcDocumentInformation"):
continue
warnings.extend(sheets_warnings := tool.Drawing.validate_sheet_files(sheet))
if sheets_warnings:
continue
sheet_builder = sheeter.SheetBuilder()
references = sheet_builder.build(sheet)
sheet_uri = references["SHEET"]
@@ -1807,6 +1811,11 @@ class OpenSheet(bpy.types.Operator):
if not os.path.exists(sheet_uri):
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:
msg = "Some sheets .svg/.pdf files were not found, need to create them first: \n{}.".format(
"\n".join(sheets_not_found)
@@ -1962,7 +1971,14 @@ class CreateSheets(bpy.types.Operator, tool.Ifc.Operator):
else:
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:
warnings.extend(sheet_warnings := tool.Drawing.validate_sheet_files(sheet))
if sheet_warnings:
continue
# Update any drawing boundary changes
sheet_builder = sheeter.SheetBuilder()
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)
else:
tool.Drawing.open_with_user_command(tool.Blender.get_addon_preferences().svg_command, svg)
n_sheets_created += 1
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):
@@ -3162,7 +3186,7 @@ class LoadSheets(bpy.types.Operator, tool.Ifc.Operator):
core.load_sheets(tool.Drawing)
props = tool.Drawing.get_document_props()
sheets_not_found = []
warnings: list[tool.Drawing.SheetWarningType] = []
for sheet_prop in props.sheets:
if not sheet_prop.is_sheet:
continue
@@ -3173,12 +3197,14 @@ class LoadSheets(bpy.types.Operator, tool.Ifc.Operator):
filepath = Path(document_uri)
if not filepath.is_file():
sheet_name = f"{sheet_prop.identification} - {sheet_prop.name}"
sheets_not_found.append(f'"{sheet_name}" - {document_uri}')
core.regenerate_sheet(tool.Drawing, sheet)
res = core.regenerate_sheet(tool.Drawing, sheet)
if res:
warnings.extend(res)
if sheets_not_found:
self.report({"ERROR"}, "Some sheets svg files are missing:\n" + "\n".join(sheets_not_found))
if warnings:
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):
+11 -2
View File
@@ -18,7 +18,7 @@
from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, Optional, Union, Literal
if TYPE_CHECKING:
import bpy
@@ -108,13 +108,22 @@ def add_sheet(ifc: type[tool.Ifc], drawing: type[tool.Drawing], titleblock: ifco
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")
assert titleblock_uri
drawing.create_svg_sheet(sheet, drawing.sanitise_filename(Path(titleblock_uri).stem))
try:
drawing.add_drawings(sheet)
except FileNotFoundError:
path_layout = drawing.get_document_uri(sheet, "LAYOUT")
assert path_layout
if drawing.does_file_exist(path_layout):
drawing.delete_file(path_layout)
+30
View File
@@ -374,6 +374,7 @@ class Drawing(bonsai.core.tool.Drawing):
sheet_builder = sheeter.SheetBuilder()
uri = cls.get_document_uri(document, "LAYOUT")
assert uri
sheet_builder.create(uri, titleblock)
return uri
@@ -1245,6 +1246,35 @@ class Drawing(bonsai.core.tool.Drawing):
# 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
def does_file_exist(cls, uri: str) -> bool:
return os.path.exists(uri)