Basic infrastructure for IfcCostSchedule PDF export with typst (#6860)

This commit is contained in:
carlopav
2025-07-03 15:18:03 +02:00
committed by GitHub
parent 3055dfa1a6
commit 5f5c0b41d5
9 changed files with 546 additions and 1 deletions
@@ -59,6 +59,7 @@ classes = (
operator.ExpandCostItemRate,
operator.ExpandCostItems,
operator.ExportCostSchedules,
operator.ExportCostSchedulesToPDF,
operator.HighlightProductCostItem,
operator.ImportCostScheduleCsv,
operator.RefreshCostScheduleCsv,
@@ -824,6 +824,81 @@ class ExportCostSchedules(bpy.types.Operator, ExportHelper):
self.layout.label(text="Select a directory.")
class ExportCostSchedulesToPDF(bpy.types.Operator, ExportHelper):
bl_idname = "bim.export_cost_schedules_to_pdf"
bl_label = "Export Cost Schedule to PDF"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Print chosen cost schedule to pdf."
filename_ext = ".pdf"
filter_glob: bpy.props.StringProperty(default="*.pdf", options={"HIDDEN"}, maxlen=255)
cost_schedules_items = []
def get_cost_schedules_enum_items(self, context):
return ExportCostSchedulesToPDF.cost_schedules_items
cost_schedules_enum: bpy.props.EnumProperty(
name="",
description="Choose IfcCostSchedule to print",
items=get_cost_schedules_enum_items,
)
should_print_summary: bpy.props.BoolProperty(
name="Should print summary",
description="Print summary at the end of the document",
default=True,
)
def draw(self, context):
layout = self.layout
box = layout.box()
box.label(text="Select Ifc Cost Schedule:")
box.prop(self, "cost_schedules_enum", text="")
layout.separator()
box = layout.box()
box.label(text="Export properties:")
box.prop(self, "should_print_summary")
@classmethod
def poll(cls, context):
try:
import typst
return True
except:
cls.poll_message_set(
"Typst not available.\nIt can be installed from Quality and\nControl -> Debug and using 'typst' with Pip Install.\n(Run Blender as Administrator)"
)
return False
def invoke(self, context, event):
ExportCostSchedulesToPDF.cost_schedules_items.clear()
file = tool.Ifc.get()
schedules = file.by_type("IfcCostSchedule")
for schedule in schedules:
ExportCostSchedulesToPDF.cost_schedules_items.append(
(
str(schedule.id()),
"{} ({})".format(
schedule.Name if schedule.Name is not None else "Unnamed",
schedule.PredefinedType if schedule.PredefinedType is not None else "UNTYPED",
),
"",
)
)
return ExportHelper.invoke(self, context, event)
def execute(self, context):
file = tool.Ifc.get()
self.props = tool.Cost.get_cost_props()
cost_schedule = file.by_id(int(self.cost_schedules_enum))
options = {"should_print_summary": self.should_print_summary}
core.export_cost_schedules_to_pdf(
tool.Cost, filepath=self.filepath, cost_schedule=cost_schedule, options=options
)
return {"FINISHED"}
class ClearCostItemAssignments(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.clear_cost_item_assignments"
bl_label = "Clear Cost Item Product Assignments"
+1
View File
@@ -53,6 +53,7 @@ class BIM_PT_cost_schedules(Panel):
if CostSchedulesData.data["total_cost_schedules"]:
row.alignment = "RIGHT"
row.operator("bim.export_cost_schedules", icon="EXPORT", text="Export All Schedules")
row.operator("bim.export_cost_schedules_to_pdf", icon="OUTPUT", text="")
row = self.layout.row(align=True)
row.label(text=f"{CostSchedulesData.data['total_cost_schedules']} Cost Schedules Found", icon="TEXT")
else:
+7
View File
@@ -397,6 +397,13 @@ def export_cost_schedules(
return cost.export_cost_schedules(dirpath, format, cost_schedule)
def export_cost_schedules_to_pdf(
cost: type[tool.Cost], filepath: str, cost_schedule: ifcopenshell.entity_instance, options: dict
):
cost.play_sound()
return cost.export_cost_schedules_to_pdf(filepath, cost_schedule, options)
def clear_cost_item_assignments(
ifc: type[tool.Ifc],
cost: type[tool.Cost],
+1
View File
@@ -223,6 +223,7 @@ class Cost:
def expand_cost_item(cls, cost_item_id): pass
def expand_cost_items(cls): pass
def export_cost_schedules(cls, filepath, format, cost_schedule): pass
def export_cost_schedules_to_pdf(cls, filepath, cost_schedule, options): pass
def format_unit(cls, unit): pass
def get_active_cost_item(cls): pass
def get_active_cost_schedule(cls): pass
+7
View File
@@ -843,6 +843,13 @@ class Cost(bonsai.core.tool.Cost):
except:
return "Could not open file location"
@classmethod
def export_cost_schedules_to_pdf(cls, filepath: str, cost_schedule: ifcopenshell.entity_instance, options: dict):
from ifc5d.ifc5Dspreadsheet import Ifc5DPdfWriter
writer = Ifc5DPdfWriter(file=tool.Ifc.get(), output=filepath, cost_schedule=cost_schedule, options=options)
writer.write()
@classmethod
def get_units(cls) -> dict[int, str]:
units = {}