diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index 02c919eb90..8497947cd4 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -555,17 +555,11 @@ class AddDrawingToSheet(bpy.types.Operator): has_drawing = False for reference in references: - new = props.sheets.add() - new.ifc_definition_id = reference.id() - new.is_sheet = False - if tool.Ifc.get_schema() == "IFC2X3": - new.identification = reference.ItemReference or "X" element = [r for r in tool.Ifc.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == reference][ 0 ].RelatedObjects[0] else: - new.identification = reference.Identification or "X" element = reference.DocumentRefForObjects[0].RelatedObjects[0] if element == drawing: has_drawing = True @@ -583,7 +577,7 @@ class AddDrawingToSheet(bpy.types.Operator): tool.Ifc.run("document.assign_document", product=drawing, document=reference) sheet_builder = sheeter.SheetBuilder() sheet_builder.data_dir = context.scene.BIMProperties.data_dir - sheet_builder.add_drawing(drawing, sheet) + sheet_builder.add_drawing(reference, drawing, sheet) tool.Drawing.import_sheets() return {"FINISHED"} @@ -597,15 +591,18 @@ class RemoveDrawingFromSheet(bpy.types.Operator): def execute(self, context): reference = tool.Ifc.get().by_id(self.reference) - sheet = tool.Drawing.get_reference_sheet(reference) - drawing = tool.Drawing.get_reference_element(reference) - - tool.Ifc.run("document.unassign_document", product=drawing, document=reference) - tool.Ifc.run("document.remove_reference", reference=reference) + sheet = tool.Drawing.get_reference_document(reference) sheet_builder = sheeter.SheetBuilder() sheet_builder.data_dir = context.scene.BIMProperties.data_dir - sheet_builder.remove_drawing(drawing, sheet) + sheet_builder.remove_drawing(reference, sheet) + + drawing = tool.Drawing.get_reference_element(reference) + if drawing: + tool.Ifc.run("document.unassign_document", product=drawing, document=reference) + + tool.Ifc.run("document.remove_reference", reference=reference) + tool.Drawing.import_sheets() return {"FINISHED"} @@ -624,6 +621,10 @@ class CreateSheets(bpy.types.Operator): props = scene.DocProperties active_sheet = props.sheets[props.active_sheet_index] sheet = tool.Ifc.get().by_id(active_sheet.ifc_definition_id) + + if not sheet.is_a("IfcDocumentInformation"): + return {"FINISHED"} + 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 @@ -978,9 +979,40 @@ class AddScheduleToSheet(bpy.types.Operator): def execute(self, context): props = context.scene.DocProperties + active_schedule = props.schedules[props.active_schedule_index] + active_sheet = props.sheets[props.active_sheet_index] + schedule = tool.Ifc.get().by_id(active_schedule.ifc_definition_id) + sheet = tool.Ifc.get().by_id(active_sheet.ifc_definition_id) + if not sheet.is_a("IfcDocumentInformation"): + return {"FINISHED"} + + if tool.Ifc.get_schema() == "IFC2X3": + references = sheet.DocumentReferences or [] + else: + references = sheet.HasDocumentReferences or [] + + has_schedule = False + for reference in references: + if reference.Location == tool.Drawing.get_schedule_location(schedule): + has_schedule = True + break + + if has_schedule: + return {"FINISHED"} + + reference = tool.Ifc.run("document.add_reference", information=sheet) + if tool.Ifc.get_schema() == "IFC2X3": + attributes = {"ItemReference": str(len(sheet.DocumentReferences or []))} + else: + attributes = {"Identification": str(len(sheet.HasDocumentReferences or []))} + attributes["Location"] = tool.Drawing.get_schedule_location(schedule) + tool.Ifc.run("document.edit_reference", reference=reference, attributes=attributes) + sheet_builder = sheeter.SheetBuilder() sheet_builder.data_dir = context.scene.BIMProperties.data_dir - sheet_builder.add_schedule(props.active_schedule.name, props.active_sheet.name) + sheet_builder.add_schedule(reference, schedule, sheet) + + tool.Drawing.import_sheets() return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py b/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py index e90d7a9c6a..7855e6067c 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py @@ -59,7 +59,7 @@ class SheetBuilder: with open(sheet_path, "w") as f: f.write(minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")) - def add_drawing(self, drawing, sheet): + def add_drawing(self, reference, drawing, sheet): filename = drawing.Name sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0] sheet_dir = os.path.join(self.data_dir, "sheets") @@ -85,7 +85,8 @@ class SheetBuilder: # here to accommodate browsers which do not nest images. view = ET.SubElement(sheet_root, "g") view.attrib["data-type"] = "drawing" - view.attrib["data-guid"] = drawing.GlobalId + view.attrib["data-id"] = str(reference.id()) + view.attrib["data-drawing"] = drawing.GlobalId view_width = self.convert_to_mm(view_root.attrib.get("width")) view_height = self.convert_to_mm(view_root.attrib.get("height")) @@ -110,26 +111,24 @@ class SheetBuilder: self.add_view_title(30, view_height + 35, view) sheet_tree.write(sheet_path) - def remove_drawing(self, drawing, sheet): - sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0] - sheet_dir = os.path.join(self.data_dir, "sheets") - sheet_path = os.path.join(sheet_dir, sheet_name + ".svg") - + def remove_drawing(self, reference, sheet): ET.register_namespace("", "http://www.w3.org/2000/svg") + sheet_path = tool.Drawing.get_document_uri(sheet) sheet_tree = ET.parse(sheet_path) sheet_root = sheet_tree.getroot() - for g in sheet_root.findall("{http://www.w3.org/2000/svg}g"): - if g.attrib["data-type"] == "drawing" and g.attrib["data-guid"] == drawing.GlobalId: + for g in sheet_root.findall('{http://www.w3.org/2000/svg}g'): + if g.attrib.get("data-id") == str(reference.id()): sheet_root.remove(g) break sheet_tree.write(sheet_path) - def add_schedule(self, schedule_name, sheet_name): - sheet_path = os.path.join(self.data_dir, "sheets", sheet_name + ".svg") - view_path = os.path.join(self.data_dir, "schedules", schedule_name + ".svg") + def add_schedule(self, reference, schedule, sheet): + view_path = tool.Drawing.get_document_uri(schedule) + schedule_name = os.path.splitext(os.path.basename(view_path))[0] + sheet_path = tool.Drawing.get_document_uri(sheet) ET.register_namespace("", "http://www.w3.org/2000/svg") ET.register_namespace("xlink", "http://www.w3.org/1999/xlink") @@ -142,17 +141,20 @@ class SheetBuilder: view_width = self.convert_to_mm(view_root.attrib.get("width")) view_height = self.convert_to_mm(view_root.attrib.get("height")) - group = ET.SubElement(sheet_root, "g") - group.attrib["data-type"] = "schedule" + view = ET.SubElement(sheet_root, "g") + view.attrib["data-type"] = "schedule" + view.attrib["data-id"] = str(reference.id()) + view.attrib["data-schedule"] = str(schedule.id()) - foreground = ET.SubElement(group, "image") + foreground = ET.SubElement(view, "image") + foreground.attrib["data-type"] = "table" foreground.attrib["xlink:href"] = "../schedules/{}.svg".format(schedule_name) foreground.attrib["x"] = "30" foreground.attrib["y"] = "30" foreground.attrib["width"] = str(view_width) foreground.attrib["height"] = str(view_height) - self.add_view_title(30, view_height + 35, group) + self.add_view_title(30, view_height + 35, view) sheet_tree.write(sheet_path) def add_view_title(self, x, y, parent): @@ -180,7 +182,7 @@ class SheetBuilder: self.build_titleblock(root, sheet) self.build_drawings(root, sheet) - self.build_schedules(root.findall('{http://www.w3.org/2000/svg}g[@data-type="schedule"]')) + self.build_schedules(root) with open(os.path.join(self.data_dir, "build", sheet_name, f"{sheet_name}.svg"), "wb") as output: tree.write(output) @@ -193,12 +195,10 @@ class SheetBuilder: def build_drawings(self, root, sheet): sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0] - references = tool.Drawing.get_document_references(sheet) - drawing_references = {tool.Drawing.get_reference_element(r): r for r in references} for view in root.findall('{http://www.w3.org/2000/svg}g[@data-type="drawing"]'): - drawing = [d for d in drawing_references.keys() if d and d.GlobalId == view.attrib["data-guid"]][0] - reference = drawing_references[drawing] + reference = tool.Ifc.get().by_id(int(view.attrib["data-id"])) + drawing = tool.Ifc.get().by_id(view.attrib["data-drawing"]) images = view.findall("{http://www.w3.org/2000/svg}image") @@ -232,24 +232,34 @@ class SheetBuilder: for image in images: view.remove(image) - def build_schedules(self, schedules): - for group in schedules: - images = group.findall("{http://www.w3.org/2000/svg}image") - schedule = images[0] - group_title = images[1] - self.scale = "NTS" + def build_schedules(self, root): + for view in root.findall('{http://www.w3.org/2000/svg}g[@data-type="schedule"]'): + reference = tool.Ifc.get().by_id(int(view.attrib["data-id"])) + schedule = tool.Ifc.get().by_id(int(view.attrib["data-schedule"])) - group.append(self.parse_embedded_svg(schedule, {})) + images = view.findall("{http://www.w3.org/2000/svg}image") - path = self.get_href(schedule) - group.append( - self.parse_embedded_svg( - group_title, {"no": 1, "name": ntpath.basename(path)[0:-4], "scale": self.scale} - ) - ) + table = None + view_title = None for image in images: - group.remove(image) + if image.attrib["data-type"] == "table": + table = image + elif image.attrib["data-type"] == "view-title": + view_title = image + + if table is not None: + view.append(self.parse_embedded_svg(table, {})) + + if view_title is not None: + path = self.get_href(table) + data = reference.get_info() + if not data["Name"]: + data["Name"] = schedule.Name or "Unnamed" + view.append(self.parse_embedded_svg(view_title, data)) + + for image in images: + view.remove(image) def get_href(self, element): return urllib.parse.unquote(element.attrib.get("{http://www.w3.org/1999/xlink}href")) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/ui.py b/src/blenderbim/blenderbim/bim/module/drawing/ui.py index 8c3335d945..fd40ff178e 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/ui.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/ui.py @@ -420,6 +420,8 @@ class BIM_UL_sheets(bpy.types.UIList): 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") name = "{} - {}".format(item.identification or "X", item.name or "Unnamed") row.label(text=name) diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index ad7b472eed..22e91b7ebb 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -340,9 +340,12 @@ class Drawing(blenderbim.core.tool.Drawing): new.identification = reference.Identification or "X" element = cls.get_reference_element(reference) - - new.name = element.Name - new.reference_type = "DRAWING" + if element: + new.name = element.Name + new.reference_type = "DRAWING" + else: + new.name = cls.get_reference_document(reference).Name or "Unnamed" + new.reference_type = "SCHEDULE" @classmethod def import_text_attributes(cls, obj): @@ -838,10 +841,11 @@ class Drawing(blenderbim.core.tool.Drawing): @classmethod def get_reference_element(cls, reference): if tool.Ifc.get_schema() == "IFC2X3": - return [r for r in tool.Ifc.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == reference][ - 0 - ].RelatedObjects[0] - return reference.DocumentRefForObjects[0].RelatedObjects[0] + refs = [r for r in tool.Ifc.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == reference] + else: + refs = reference.DocumentRefForObjects + if refs: + return refs[0].RelatedObjects[0] @classmethod def get_drawing_human_scale(cls, drawing): @@ -893,7 +897,7 @@ class Drawing(blenderbim.core.tool.Drawing): return rel.RelatingDocument @classmethod - def get_reference_sheet(cls, reference): + def get_reference_document(cls, reference): if tool.Ifc.get_schema() == "IFC2X3": return reference.ReferenceToDocument[0] return reference.ReferencedDocument