mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 10:51:13 +00:00
#1153 You can now provide custom stylesheets, markers, symbols, and hatches
This commit is contained in:
@@ -5,7 +5,7 @@ FILE_NAME('EPset_Drawing.ifc','2020-01-01T00:00:00',(),(),'EPset_Drawing','EPset
|
|||||||
FILE_SCHEMA(('IFC4'));
|
FILE_SCHEMA(('IFC4'));
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
DATA;
|
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.);
|
#2=IFCSIMPLEPROPERTYTEMPLATE('23JavTMk98ZxXhrUEnjAcf',$,'TargetView','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3gsuPBtU93b8f0gg1pjkq6',$,'HumanScale','',.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.);
|
#9=IFCSIMPLEPROPERTYTEMPLATE('10hT_1zrzEbRRKMXYAWvtD',$,'Metadata','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
#10=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||||
#11=IFCSIMPLEPROPERTYTEMPLATE('1RVts_g3PAw98PJA2yL3bO',$,'Exclude','',.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;
|
ENDSEC;
|
||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
|
|||||||
@@ -129,8 +129,6 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
self.svg_writer.human_scale = self.human_scale
|
self.svg_writer.human_scale = self.human_scale
|
||||||
self.svg_writer.scale = self.scale
|
self.svg_writer.scale = self.scale
|
||||||
self.svg_writer.data_dir = context.scene.BIMProperties.data_dir
|
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 = self.camera
|
||||||
self.svg_writer.camera_width, self.svg_writer.camera_height = self.get_camera_dimensions()
|
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)))
|
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 :)
|
# Hacky :)
|
||||||
svg_path = os.path.join(context.scene.BIMProperties.data_dir, "diagrams", self.drawing_name + ".svg")
|
svg_path = os.path.join(context.scene.BIMProperties.data_dir, "diagrams", self.drawing_name + ".svg")
|
||||||
with open(svg_path, "w") as outfile:
|
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("</svg>", ""))
|
outfile.write(boilerplate.replace("</svg>", ""))
|
||||||
if underlay:
|
if underlay:
|
||||||
with open(underlay) as infile:
|
with open(underlay) as infile:
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ class External(svgwrite.container.Group):
|
|||||||
class SvgWriter:
|
class SvgWriter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.data_dir = None
|
self.data_dir = None
|
||||||
self.vector_style = None
|
|
||||||
self.human_scale = "NTS"
|
self.human_scale = "NTS"
|
||||||
self.metadata = []
|
self.metadata = []
|
||||||
self.scale = 1 / 100 # 1:100
|
self.scale = 1 / 100 # 1:100
|
||||||
@@ -87,11 +86,11 @@ class SvgWriter:
|
|||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def define_boilerplate(self):
|
def define_boilerplate(self, stylesheet=None, markers=None, symbols=None, patterns=None):
|
||||||
self.add_stylesheet()
|
self.add_stylesheet(stylesheet)
|
||||||
self.add_markers()
|
self.add_markers(markers)
|
||||||
self.add_symbols()
|
self.add_symbols(symbols)
|
||||||
self.add_patterns()
|
self.add_patterns(patterns)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def calculate_scale(self):
|
def calculate_scale(self):
|
||||||
@@ -101,24 +100,25 @@ class SvgWriter:
|
|||||||
self.width = self.raw_width * self.svg_scale
|
self.width = self.raw_width * self.svg_scale
|
||||||
self.height = self.raw_height * self.svg_scale
|
self.height = self.raw_height * self.svg_scale
|
||||||
|
|
||||||
def add_stylesheet(self):
|
def add_stylesheet(self, uri):
|
||||||
with open(os.path.join(self.data_dir, "styles", f"{self.vector_style}.css"), "r") as stylesheet:
|
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()))
|
self.svg.defs.add(self.svg.style(stylesheet.read()))
|
||||||
|
|
||||||
def add_markers(self):
|
def add_markers(self, uri):
|
||||||
tree = ET.parse(os.path.join(self.data_dir, "templates", "markers.svg"))
|
tree = ET.parse(tool.Ifc.resolve_uri(uri) or os.path.join(self.data_dir, "templates", "markers.svg"))
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
for child in root:
|
for child in root:
|
||||||
self.svg.defs.add(External(child))
|
self.svg.defs.add(External(child))
|
||||||
|
|
||||||
def add_symbols(self):
|
def add_symbols(self, uri):
|
||||||
tree = ET.parse(os.path.join(self.data_dir, "templates", "symbols.svg"))
|
tree = ET.parse(tool.Ifc.resolve_uri(uri) or os.path.join(self.data_dir, "templates", "symbols.svg"))
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
for child in root:
|
for child in root:
|
||||||
self.svg.defs.add(External(child))
|
self.svg.defs.add(External(child))
|
||||||
|
|
||||||
def add_patterns(self):
|
def add_patterns(self, uri):
|
||||||
tree = ET.parse(os.path.join(self.data_dir, "templates", "patterns.svg"))
|
tree = ET.parse(tool.Ifc.resolve_uri(uri) or os.path.join(self.data_dir, "templates", "patterns.svg"))
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
for child in root:
|
for child in root:
|
||||||
self.svg.defs.add(External(child))
|
self.svg.defs.add(External(child))
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
@@ -91,6 +92,10 @@ class Ifc(blenderbim.core.tool.Ifc):
|
|||||||
def delete(cls, element):
|
def delete(cls, element):
|
||||||
IfcStore.delete_element(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
|
@classmethod
|
||||||
def unlink(cls, element=None, obj=None):
|
def unlink(cls, element=None, obj=None):
|
||||||
IfcStore.unlink_element(element, obj)
|
IfcStore.unlink_element(element, obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user