From 3b825e35ae4509c69cc5f23c7760311273edf320 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 7 May 2022 20:28:24 +1000 Subject: [PATCH] #1153 You can now provide custom stylesheets, markers, symbols, and hatches --- .../bim/data/pset/EPset_Drawing.ifc | 6 +++- .../blenderbim/bim/module/drawing/operator.py | 8 ++++-- .../bim/module/drawing/svgwriter.py | 28 +++++++++---------- src/blenderbim/blenderbim/tool/ifc.py | 5 ++++ 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/data/pset/EPset_Drawing.ifc b/src/blenderbim/blenderbim/bim/data/pset/EPset_Drawing.ifc index 9bcbda6d2c..3883e8ef5f 100644 --- a/src/blenderbim/blenderbim/bim/data/pset/EPset_Drawing.ifc +++ b/src/blenderbim/blenderbim/bim/data/pset/EPset_Drawing.ifc @@ -5,7 +5,7 @@ FILE_NAME('EPset_Drawing.ifc','2020-01-01T00:00:00',(),(),'EPset_Drawing','EPset FILE_SCHEMA(('IFC4')); ENDSEC; DATA; -#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11)); +#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15)); #2=IFCSIMPLEPROPERTYTEMPLATE('23JavTMk98ZxXhrUEnjAcf',$,'TargetView','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); #3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); #4=IFCSIMPLEPROPERTYTEMPLATE('3gsuPBtU93b8f0gg1pjkq6',$,'HumanScale','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); @@ -16,5 +16,9 @@ DATA; #9=IFCSIMPLEPROPERTYTEMPLATE('10hT_1zrzEbRRKMXYAWvtD',$,'Metadata','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); #10=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); #11=IFCSIMPLEPROPERTYTEMPLATE('1RVts_g3PAw98PJA2yL3bO',$,'Exclude','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); +#12=IFCSIMPLEPROPERTYTEMPLATE('0c1$8NpYDEaBiJrj16jHIo',$,'Stylesheet','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.); +#13=IFCSIMPLEPROPERTYTEMPLATE('3mRF52q81FQB$h4oTh7M45',$,'Markers','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.); +#14=IFCSIMPLEPROPERTYTEMPLATE('1rhr_0N3LDtuORcEJP0KXM',$,'Symbols','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.); +#15=IFCSIMPLEPROPERTYTEMPLATE('2sHDBuW7P4TROy$hL2w7ct',$,'Patterns','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.); ENDSEC; END-ISO-10303-21; diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index b4132c1884..187b0c1c14 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -129,8 +129,6 @@ class CreateDrawing(bpy.types.Operator): self.svg_writer.human_scale = self.human_scale self.svg_writer.scale = self.scale self.svg_writer.data_dir = context.scene.BIMProperties.data_dir - drawing_style = context.scene.DocProperties.drawing_styles[self.cprops.active_drawing_style_index] - self.svg_writer.vector_style = drawing_style.vector_style self.svg_writer.camera = self.camera self.svg_writer.camera_width, self.svg_writer.camera_height = self.get_camera_dimensions() self.svg_writer.camera_projection = tuple(self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))) @@ -167,7 +165,11 @@ class CreateDrawing(bpy.types.Operator): # Hacky :) svg_path = os.path.join(context.scene.BIMProperties.data_dir, "diagrams", self.drawing_name + ".svg") with open(svg_path, "w") as outfile: - boilerplate = self.svg_writer.create_blank_svg(svg_path).define_boilerplate().svg.tostring() + pset = ifcopenshell.util.element.get_psets(self.camera_element)["EPset_Drawing"] + self.svg_writer.create_blank_svg(svg_path).define_boilerplate( + pset.get("Stylesheet"), pset.get("Markers"), pset.get("Symbols"), pset.get("Patterns") + ) + boilerplate = self.svg_writer.svg.tostring() outfile.write(boilerplate.replace("", "")) if underlay: with open(underlay) as infile: diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index 9297e45481..891b8f2092 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -56,7 +56,6 @@ class External(svgwrite.container.Group): class SvgWriter: def __init__(self): self.data_dir = None - self.vector_style = None self.human_scale = "NTS" self.metadata = [] self.scale = 1 / 100 # 1:100 @@ -87,11 +86,11 @@ class SvgWriter: ) return self - def define_boilerplate(self): - self.add_stylesheet() - self.add_markers() - self.add_symbols() - self.add_patterns() + def define_boilerplate(self, stylesheet=None, markers=None, symbols=None, patterns=None): + self.add_stylesheet(stylesheet) + self.add_markers(markers) + self.add_symbols(symbols) + self.add_patterns(patterns) return self def calculate_scale(self): @@ -101,24 +100,25 @@ class SvgWriter: self.width = self.raw_width * self.svg_scale self.height = self.raw_height * self.svg_scale - def add_stylesheet(self): - with open(os.path.join(self.data_dir, "styles", f"{self.vector_style}.css"), "r") as stylesheet: + def add_stylesheet(self, uri): + default_stylesheet = os.path.join(self.data_dir, "styles", f"default.css") + with open(tool.Ifc.resolve_uri(uri) or default_stylesheet, "r") as stylesheet: self.svg.defs.add(self.svg.style(stylesheet.read())) - def add_markers(self): - tree = ET.parse(os.path.join(self.data_dir, "templates", "markers.svg")) + def add_markers(self, uri): + tree = ET.parse(tool.Ifc.resolve_uri(uri) or os.path.join(self.data_dir, "templates", "markers.svg")) root = tree.getroot() for child in root: self.svg.defs.add(External(child)) - def add_symbols(self): - tree = ET.parse(os.path.join(self.data_dir, "templates", "symbols.svg")) + def add_symbols(self, uri): + tree = ET.parse(tool.Ifc.resolve_uri(uri) or os.path.join(self.data_dir, "templates", "symbols.svg")) root = tree.getroot() for child in root: self.svg.defs.add(External(child)) - def add_patterns(self): - tree = ET.parse(os.path.join(self.data_dir, "templates", "patterns.svg")) + def add_patterns(self, uri): + tree = ET.parse(tool.Ifc.resolve_uri(uri) or os.path.join(self.data_dir, "templates", "patterns.svg")) root = tree.getroot() for child in root: self.svg.defs.add(External(child)) diff --git a/src/blenderbim/blenderbim/tool/ifc.py b/src/blenderbim/blenderbim/tool/ifc.py index d487aafbcb..efc7e09e35 100644 --- a/src/blenderbim/blenderbim/tool/ifc.py +++ b/src/blenderbim/blenderbim/tool/ifc.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . +import os import bpy import numpy as np import ifcopenshell.api @@ -91,6 +92,10 @@ class Ifc(blenderbim.core.tool.Ifc): def delete(cls, element): IfcStore.delete_element(element) + @classmethod + def resolve_uri(cls, uri): + return uri if not uri or os.path.isabs(uri) else os.path.join(os.path.dirname(cls.get_path()), uri) + @classmethod def unlink(cls, element=None, obj=None): IfcStore.unlink_element(element, obj)