diff --git a/src/blenderbim/scripts/au-library.blend b/src/blenderbim/scripts/au-library.blend new file mode 100644 index 0000000000..0bf2d9f7b7 Binary files /dev/null and b/src/blenderbim/scripts/au-library.blend differ diff --git a/src/blenderbim/scripts/generate_au_library.py b/src/blenderbim/scripts/generate_au_library.py new file mode 100644 index 0000000000..7dab03c45f --- /dev/null +++ b/src/blenderbim/scripts/generate_au_library.py @@ -0,0 +1,254 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2020, 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +# fmt: off +# pylint: skip-file + +import bpy +import ifcopenshell +import ifcopenshell.api +import blenderbim.tool as tool + + +class LibraryGenerator: + def generate(self): + ifcopenshell.api.pre_listeners = {} + ifcopenshell.api.post_listeners = {} + + self.materials = {} + + self.file = ifcopenshell.api.run("project.create_file") + self.project = ifcopenshell.api.run( + "root.create_entity", self.file, ifc_class="IfcProject", name="Australian Library" + ) + self.library = ifcopenshell.api.run( + "root.create_entity", self.file, ifc_class="IfcProjectLibrary", name="Australian Library" + ) + ifcopenshell.api.run( + "project.assign_declaration", self.file, definition=self.library, relating_context=self.project + ) + unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", name="METRE", prefix="MILLI") + ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit]) + + model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") + plan = ifcopenshell.api.run("context.add_context", self.file, context_type="Plan") + self.representations = { + "body": ifcopenshell.api.run( + "context.add_context", + self.file, + context_type="Model", + context_identifier="Body", + target_view="MODEL_VIEW", + parent=model, + ), + "annotation": ifcopenshell.api.run( + "context.add_context", + self.file, + context_type="Plan", + context_identifier="Annotation", + target_view="PLAN_VIEW", + parent=plan, + ), + } + + self.materials = { + "TBD": {"Category": "other"}, + "BRK": {"Category": "brick"}, + "BLK": {"Category": "block"}, + "CON": {"Category": "concrete"}, + "WD": {"Category": "wood"}, + "ST": {"Category": "steel"}, + "AL": {"Category": "aluminium"}, + "GLZ": {"Category": "glass"}, + "PBD": {"Category": "gypsum"}, + "AIR": {"Category": "air"}, + "MEM": {"Category": "membrane"}, + } + + for name, data in self.materials.items(): + self.materials[name]["ifc"] = ifcopenshell.api.run("material.add_material", self.file, name=name) + self.materials[name]["ifc"].Category = data["Category"] + + self.layer_types = { + "WAL01": {"type": "IfcWallType", "Description": "110mm Single brick", + "Layers": [("LoadBearing", "BRK", 110)]}, + "WAL02": {"type": "IfcWallType", "Description": "250mm Brick veneer", + "Layers": [("Finish", "BRK", 110), ("Ventilation", "AIR", 50), ("LoadBearing", "WD", 90)]}, + "WAL03": {"type": "IfcWallType", "Description": "270mm Double brick", + "Layers": [("Finish", "BRK", 110), ("Ventilation", "AIR", 50), ("LoadBearing", "BRK", 110)]}, + "WAL04": {"type": "IfcWallType", "Description": "150mm Reinforced concrete", + "Layers": [("LoadBearing", "CON", 150)]}, + "WAL05": {"type": "IfcWallType", "Description": "200mm Reinforced concrete", + "Layers": [("LoadBearing", "CON", 200)]}, + "WAL06": {"type": "IfcWallType", "Description": "250mm Reinforced concrete", + "Layers": [("LoadBearing", "CON", 250)]}, + "WAL07": {"type": "IfcWallType", "Description": "300mm Reinforced concrete", + "Layers": [("LoadBearing", "CON", 300)]}, + "WAL08": {"type": "IfcWallType", "Description": "140mm Hollow core block", + "Layers": [("LoadBearing", "BLK", 190)]}, + "WAL09": {"type": "IfcWallType", "Description": "140mm Core filled block", + "Layers": [("LoadBearing", "BLK", 190)]}, + "WAL10": {"type": "IfcWallType", "Description": "190mm Hollow core block", + "Layers": [("LoadBearing", "BLK", 190)]}, + "WAL11": {"type": "IfcWallType", "Description": "190mm Core filled block", + "Layers": [("LoadBearing", "BLK", 190)]}, + "WAL12": {"type": "IfcWallType", "Description": "90mm Wooden frame", + "Layers": [("LoadBearing", "WD", 90)]}, + "WAL13": {"type": "IfcWallType", "Description": "64mm Steel frame", + "Layers": [("LoadBearing", "ST", 64)]}, + "CLD01": {"type": "IfcCoveringType", "Description": "110mm Face brick", + "Layers": [("LoadBearing", "BRK", 110)]}, + "CLD02": {"type": "IfcCoveringType", "Description": "13mm Plasterboard lining", + "Layers": [("LoadBearing", "PBD", 13)]}, + } + + for name, data in self.layer_types.items(): + self.layer_types[name]["ifc"] = self.create_layer_set_type(name, data) + + product = self.create_layer_type("IfcCoveringType", "DEMO20", 0.02) + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=product, name="EPset_Parametric") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"LayerSetDirection": "AXIS2"}) + + product = self.create_layer_type("IfcCoveringType", "DEMO30", 0.03) + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=product, name="EPset_Parametric") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"LayerSetDirection": "AXIS3"}) + + self.create_layer_type("IfcRampType", "DEMO200", 0.2) + + profile = self.file.create_entity("IfcCircleProfileDef", ProfileType="AREA", Radius=0.3) + self.create_profile_type("IfcPileType", "DEMO1", profile) + + self.create_layer_type("IfcSlabType", "DEMO150", 0.2) + self.create_layer_type("IfcSlabType", "DEMO250", 0.3) + + profile = self.file.create_entity("IfcRectangleProfileDef", ProfileType="AREA", XDim=0.5, YDim=0.6) + self.create_profile_type("IfcColumnType", "DEMO1", profile) + + profile = self.file.create_entity( + "IfcCircleHollowProfileDef", ProfileType="AREA", Radius=0.25, WallThickness=0.005 + ) + self.create_profile_type("IfcColumnType", "DEMO2", profile) + + profile = self.file.create_entity( + "IfcRectangleHollowProfileDef", + ProfileType="AREA", + XDim=0.075, + YDim=0.15, + WallThickness=0.005, + InnerFilletRadius=0.005, + OuterFilletRadius=0.005, + ) + self.create_profile_type("IfcColumnType", "DEMO3", profile) + + profile = self.file.create_entity( + "IfcIShapeProfileDef", + ProfileName="DEMO-I", + ProfileType="AREA", + OverallWidth=0.1, + OverallDepth=0.2, + WebThickness=0.005, + FlangeThickness=0.01, + FilletRadius=0.005, + ) + self.create_profile_type("IfcBeamType", "DEMO1", profile) + + profile = self.file.create_entity( + "IfcCShapeProfileDef", + ProfileName="DEMO-C", + ProfileType="AREA", + Depth=0.2, + Width=0.1, + WallThickness=0.0015, + Girth=0.03, + InternalFilletRadius=0.005, + ) + self.create_profile_type("IfcBeamType", "DEMO2", profile) + + self.create_type("IfcWindowType", "DEMO1", {"body": "Window", "annotation": "Window-Annotation"}) + self.create_type("IfcDoorType", "DEMO1", {"body": "Door", "annotation": "Door-Annotation"}) + self.create_type("IfcFurnitureType", "BUNNY", {"body": "Bunny", "annotation": "Bunny-Annotation"}) + + self.file.write("blenderbim-au-library.ifc") + + def create_layer_set_type(self, name, data): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=data["type"], name=name) + element.Description = data["Description"] + rel = ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSet") + layer_set = rel.RelatingMaterial + for layer_data in data["Layers"]: + layer = ifcopenshell.api.run( + "material.add_layer", self.file, layer_set=layer_set, material=self.materials[layer_data[1]]["ifc"] + ) + layer.Name = layer_data[0] + layer.LayerThickness = layer_data[2] + ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library) + return element + + def create_layer_type(self, ifc_class, name, thickness): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSet") + layer_set = rel.RelatingMaterial + layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"]) + layer.LayerThickness = thickness + ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library) + return element + + def create_profile_type(self, ifc_class, name, profile): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + rel = ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSet") + profile_set = rel.RelatingMaterial + material_profile = ifcopenshell.api.run( + "material.add_profile", self.file, profile_set=profile_set, material=self.materials["TBD"]["ifc"] + ) + ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile) + ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library) + + def create_type(self, ifc_class, name, representations): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name) + for rep_name, obj_name in representations.items(): + obj = bpy.data.objects.get(obj_name) + representation = ifcopenshell.api.run( + "geometry.add_representation", + self.file, + context=self.representations[rep_name], + blender_object=obj, + geometry=obj.data, + total_items=max(1, len(obj.material_slots)), + ) + styles = [] + for slot in obj.material_slots: + style = ifcopenshell.api.run("style.add_style", self.file, name=slot.material.name) + ifcopenshell.api.run( + "style.add_surface_style", + self.file, + style=style, + ifc_class="IfcSurfaceStyleRendering", + attributes=tool.Style.get_surface_rendering_attributes(slot.material), + ) + styles.append(style) + if styles: + ifcopenshell.api.run( + "style.assign_representation_styles", self.file, shape_representation=representation, styles=styles + ) + ifcopenshell.api.run( + "geometry.assign_representation", self.file, product=element, representation=representation + ) + ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library) + + +LibraryGenerator().generate()