Run black on BBIM

This commit is contained in:
Dion Moult
2024-07-26 12:19:21 +10:00
parent e7b791f4a2
commit 1fef4c5857
91 changed files with 747 additions and 582 deletions
@@ -1,5 +1,6 @@
try:
import bpy
# Ensure it's not fake-bpy-module.
if not hasattr(bpy, "context"):
raise ModuleNotFoundError
@@ -1,23 +1,27 @@
import ifcopenshell
from brickschema.graph import Graph
class Generator():
class Generator:
def __init__(self):
self.file = ifcopenshell.file(schema='IFC4')
self.file = ifcopenshell.file(schema="IFC4")
self.schema = Graph()
self.schema.load_file("Brick.ttl") # stable 1.3 loaded from external file
self.schema.load_file("Brick.ttl") # stable 1.3 loaded from external file
def generate(self):
classification = self.file.create_entity('IfcClassification', **{
'Source': 'Brick',
'Edition': 'August-11',
'EditionDate': '2023-08-11',
'Name': 'Brick',
'Description': '',
'Location': 'https://brickschema.org/schema/Brick',
'ReferenceTokens': []
})
classification = self.file.create_entity(
"IfcClassification",
**{
"Source": "Brick",
"Edition": "August-11",
"EditionDate": "2023-08-11",
"Name": "Brick",
"Description": "",
"Location": "https://brickschema.org/schema/Brick",
"ReferenceTokens": [],
}
)
query = self.schema.query(
"""
PREFIX brick: <https://brickschema.org/schema/Brick#>
@@ -54,11 +58,11 @@ class Generator():
for row in query:
# location is the entity URI
location = row.get("entity")
# description is the entity's definition
description = row.get("definition")
if not description:
description = ''
description = ""
# name is the entity's label if it exists, else the name in the URI
name = row.get("label")
@@ -66,13 +70,11 @@ class Generator():
name = location.split("#")[-1].replace("_", " ")
# create the reference
ref = self.file.create_entity('IfcClassificationReference', **{
'Location': location,
'Description': description,
'Identification': name,
'Name': name
})
ref = self.file.create_entity(
"IfcClassificationReference",
**{"Location": location, "Description": description, "Identification": name, "Name": name}
)
# get all parents of the entity
query = self.schema.query(
"""
@@ -88,7 +90,7 @@ class Generator():
# filter parents for the brick entity
for row in query:
parent = row.get("parent").toPython()
if "brickschema.org" in parent and parent in references.keys():
if "brickschema.org" in parent and parent in references.keys():
# some parents are not a brick type, so those should be ignored
# some entities have multiple parents that are a brick type
# since the query traverses down the graph, we can assume at least one parent has been seen, so pick that one
@@ -96,7 +98,7 @@ class Generator():
break
parent = None
# assign reference source
# assign reference source
if parent:
ref.ReferencedSource = references[parent]
else:
@@ -105,7 +107,8 @@ class Generator():
# save this reference for future reference sources
references[location.toPython()] = ref
self.file.write('Brick.ifc')
self.file.write("Brick.ifc")
generator = Generator()
generator.generate()
generator.generate()
+28 -23
View File
@@ -1,30 +1,35 @@
import csv
import os
import json
#import pystache
# import pystache
import subprocess
import ifcopenshell
from pathlib import Path
class Generator():
class Generator:
def __init__(self):
self.file = ifcopenshell.file(schema='IFC4')
self.out_dir = './'
self.file = ifcopenshell.file(schema="IFC4")
self.out_dir = "./"
def generate(self):
classification = self.file.create_entity('IfcClassification', **{
'Source': 'VBIS',
'Edition': 'May-20',
'EditionDate': '2020-05-01',
'Name': 'VBIS',
'Description': '',
'Location': 'https://vbis.com.au/',
'ReferenceTokens': ['-']
})
classification = self.file.create_entity(
"IfcClassification",
**{
"Source": "VBIS",
"Edition": "May-20",
"EditionDate": "2020-05-01",
"Name": "VBIS",
"Description": "",
"Location": "https://vbis.com.au/",
"ReferenceTokens": ["-"],
}
)
# We assume all the Excel spreadsheets are re-exported in CSV format
for filename in Path('./').glob('*.csv'):
with open(filename, newline='') as csvfile:
reader = csv.reader(csvfile, delimiter=',', quotechar='"')
for filename in Path("./").glob("*.csv"):
with open(filename, newline="") as csvfile:
reader = csv.reader(csvfile, delimiter=",", quotechar='"')
name = None
levels = [None, None, None, None]
ref = classification
@@ -39,17 +44,17 @@ class Generator():
name = row[2]
elif row[3]:
name = row[3]
ref = self.file.create_entity('IfcClassificationReference', **{
'Identification': row[4],
'Name': name
})
cur_level = len(row[4].split('-')) - 1
ref = self.file.create_entity(
"IfcClassificationReference", **{"Identification": row[4], "Name": name}
)
cur_level = len(row[4].split("-")) - 1
levels[cur_level] = ref
if cur_level == 0:
ref.ReferencedSource = classification
else:
ref.ReferencedSource = levels[cur_level-1]
self.file.write('VBIS.ifc')
ref.ReferencedSource = levels[cur_level - 1]
self.file.write("VBIS.ifc")
generator = Generator()
generator.generate()
@@ -7,86 +7,92 @@ import ifcopenshell
import ifcopenshell.guid
import os
class IFC4Extractor:
def __init__(self, xml_file):
self.xml_file = xml_file
self.tree = ET.parse(self.xml_file)
self.root = self.tree.getroot()
self.ns = {'xs': 'http://www.w3.org/2001/XMLSchema'}
self.ns = {"xs": "http://www.w3.org/2001/XMLSchema"}
self.file = ifcopenshell.file()
self.data = {
'BB/SfB (3/4 cijfers)': {'source': 'Regie der Gebouwen', 'tokens': ['.']},
'BIMTypeCode': {'source': 'BIMStockholm', 'tokens': None},
'Common Arrangement of Work Sections (CAWS)': {'source': 'NBS', 'tokens': ['/']},
'CBI Classification - Level 2': {'source': 'Masterspec', 'tokens': None},
'CBI Classification - Level 4': {'source': 'Masterspec', 'tokens': None},
'Rumsfunktionskoder CC001 - 001': {'source': 'BIMAlliance', 'tokens': ['-']},
'CCS': {'source': 'Molio', 'tokens': None},
'CCTB': {'source': 'CCT-Bâtiments', 'tokens': ['.']},
'Funktionskoder Regionservice CD001 - 001': {'source': 'BIMAlliance', 'tokens': None},
'Rumsfunktion Blekinge CD002 - 001': {'source': 'BIMAlliance', 'tokens': None},
'EcoQuaestor Codetabel': {'source': 'EcoQuaestor', 'tokens': ['.', '-']},
'GuBIMclass CA': {'source': 'GuBIMClass', 'tokens': ['.']},
'GuBIMclass ES': {'source': 'GuBIMClass', 'tokens': ['.']},
'MasterFormat': {'source': 'CSI', 'tokens': [' ', '.']},
'NATSPEC Worksections': {'source': 'NATSPEC', 'tokens': None},
'NBS Create': {'source': 'NBS', 'tokens': ['_', '/']},
'NL/SfB (4 cijfers)': {'source': 'BIMLoket', 'tokens': ['.']},
'NS 3451 - Bygningsdelstabell': {'source': 'Standard Norge', 'tokens': None},
'OmniClass': {'source': 'OmniClass', 'tokens': ['-', ' ']},
'ÖNORM 6241-2': {'source': 'freeBIM 2', 'tokens': None},
'RICS NRM1': {'source': 'RICS', 'tokens': ['.']},
'RICS NRM3': {'source': 'RICS', 'tokens': ['.']},
'SFG20': {'source': 'SFG20', 'tokens': ['-']},
'SINAPI': {'source': 'Caixa', 'tokens': ['/']},
'STABU-Element': {'source': 'STABU', 'tokens': ['.']},
'TALO 2000 Building Component Classification': {'source': 'Rakennustieto', 'tokens': ['.']},
'TALO 2000 Hankenimikkeistö': {'source': 'Rakennustieto', 'tokens': ['.']},
'Uniclass': {'source': 'RIBA Enterprises Ltd', 'tokens': ['_']},
'Uniclass 2015': {'source': 'RIBA Enterprises Ltd', 'tokens': ['_']},
'UniFormat': {'source': 'UniFormat', 'tokens': ['.']},
'Uniformat': {'source': 'UniFormat', 'tokens': ['.']},
'VMSW': {'source': 'VMSW', 'tokens': ['.']}
"BB/SfB (3/4 cijfers)": {"source": "Regie der Gebouwen", "tokens": ["."]},
"BIMTypeCode": {"source": "BIMStockholm", "tokens": None},
"Common Arrangement of Work Sections (CAWS)": {"source": "NBS", "tokens": ["/"]},
"CBI Classification - Level 2": {"source": "Masterspec", "tokens": None},
"CBI Classification - Level 4": {"source": "Masterspec", "tokens": None},
"Rumsfunktionskoder CC001 - 001": {"source": "BIMAlliance", "tokens": ["-"]},
"CCS": {"source": "Molio", "tokens": None},
"CCTB": {"source": "CCT-Bâtiments", "tokens": ["."]},
"Funktionskoder Regionservice CD001 - 001": {"source": "BIMAlliance", "tokens": None},
"Rumsfunktion Blekinge CD002 - 001": {"source": "BIMAlliance", "tokens": None},
"EcoQuaestor Codetabel": {"source": "EcoQuaestor", "tokens": [".", "-"]},
"GuBIMclass CA": {"source": "GuBIMClass", "tokens": ["."]},
"GuBIMclass ES": {"source": "GuBIMClass", "tokens": ["."]},
"MasterFormat": {"source": "CSI", "tokens": [" ", "."]},
"NATSPEC Worksections": {"source": "NATSPEC", "tokens": None},
"NBS Create": {"source": "NBS", "tokens": ["_", "/"]},
"NL/SfB (4 cijfers)": {"source": "BIMLoket", "tokens": ["."]},
"NS 3451 - Bygningsdelstabell": {"source": "Standard Norge", "tokens": None},
"OmniClass": {"source": "OmniClass", "tokens": ["-", " "]},
"ÖNORM 6241-2": {"source": "freeBIM 2", "tokens": None},
"RICS NRM1": {"source": "RICS", "tokens": ["."]},
"RICS NRM3": {"source": "RICS", "tokens": ["."]},
"SFG20": {"source": "SFG20", "tokens": ["-"]},
"SINAPI": {"source": "Caixa", "tokens": ["/"]},
"STABU-Element": {"source": "STABU", "tokens": ["."]},
"TALO 2000 Building Component Classification": {"source": "Rakennustieto", "tokens": ["."]},
"TALO 2000 Hankenimikkeistö": {"source": "Rakennustieto", "tokens": ["."]},
"Uniclass": {"source": "RIBA Enterprises Ltd", "tokens": ["_"]},
"Uniclass 2015": {"source": "RIBA Enterprises Ltd", "tokens": ["_"]},
"UniFormat": {"source": "UniFormat", "tokens": ["."]},
"Uniformat": {"source": "UniFormat", "tokens": ["."]},
"VMSW": {"source": "VMSW", "tokens": ["."]},
}
def extract(self):
for system in self.tree.findall('Classification/System'):
project = self.file.create_entity('IfcProjectLibrary', Name=system.find('Name').text)
parent = self.file.create_entity('IfcClassification', **{
'Source': self.data[system.find('Name').text]['source'],
'Edition': system.find('EditionVersion').text,
'EditionDate': self.get_edition_date(system),
'Name': system.find('Name').text,
'Description': system.find('Description').text,
'Location': system.find('Source').text,
'ReferenceTokens': self.data[system.find('Name').text]['tokens']
})
self.file.createIfcRelAssociatesClassification(
ifcopenshell.guid.new(), None, None, None, [project], parent)
children = system.findall('Items/Item')
for system in self.tree.findall("Classification/System"):
project = self.file.create_entity("IfcProjectLibrary", Name=system.find("Name").text)
parent = self.file.create_entity(
"IfcClassification",
**{
"Source": self.data[system.find("Name").text]["source"],
"Edition": system.find("EditionVersion").text,
"EditionDate": self.get_edition_date(system),
"Name": system.find("Name").text,
"Description": system.find("Description").text,
"Location": system.find("Source").text,
"ReferenceTokens": self.data[system.find("Name").text]["tokens"],
},
)
self.file.createIfcRelAssociatesClassification(ifcopenshell.guid.new(), None, None, None, [project], parent)
children = system.findall("Items/Item")
self.get_children(children, parent)
def get_children(self, children, parent):
for child in children:
reference = self.file.create_entity('IfcClassificationReference', **{
'Identification': child.find('ID').text,
'Name': child.find('Name').text,
'ReferencedSource': parent,
'Description': child.find('Description').text
})
children = child.find('Children')
reference = self.file.create_entity(
"IfcClassificationReference",
**{
"Identification": child.find("ID").text,
"Name": child.find("Name").text,
"ReferencedSource": parent,
"Description": child.find("Description").text,
},
)
children = child.find("Children")
if children:
self.get_children(children, reference)
def get_edition_date(self, system):
d = system.find('EditionDate')
return '{}-{:02}-{:02}'.format(
d.find('Year').text, int(d.find('Month').text), int(d.find('Day').text))
d = system.find("EditionDate")
return "{}-{:02}-{:02}".format(d.find("Year").text, int(d.find("Month").text), int(d.find("Day").text))
def export(self, filename):
self.file.write(filename)
for filename in os.listdir('xml/'):
extractor = IFC4Extractor(f'xml/{filename}')
for filename in os.listdir("xml/"):
extractor = IFC4Extractor(f"xml/{filename}")
extractor.extract()
extractor.export(f'ifc/{filename[0:-3]}ifc')
extractor.export(f"ifc/{filename[0:-3]}ifc")
+28 -10
View File
@@ -155,10 +155,16 @@ class LibraryGenerator:
self.create_line_type("MEDIUM", "medium")
self.create_line_type("THICK", "thick")
self.create_line_type("STRONG", "strong")
self.create_text_type("SETOUT-TAG", "setout-tag", ["E ``round({{easting}}, 0.001)``", "N ``round({{northing}}, 0.001)``"])
self.create_text_type(
"SETOUT-TAG", "setout-tag", ["E ``round({{easting}}, 0.001)``", "N ``round({{northing}}, 0.001)``"]
)
self.create_text_type("DOOR-TAG", "door-tag", ["{{type.Name}}", "{{Name}}"])
self.create_text_type("WINDOW-TAG", "window-tag", ["{{Name}}"])
self.create_text_type("SPACE-TAG", "space-tag", ["{{Name}}", "{{Description}}", "``round({{Qto_SpaceBaseQuantities.NetFloorArea}}, 0.01)``"])
self.create_text_type(
"SPACE-TAG",
"space-tag",
["{{Name}}", "{{Description}}", "``round({{Qto_SpaceBaseQuantities.NetFloorArea}}, 0.01)``"],
)
self.create_text_type("MATERIAL-TAG", "rectangle-tag", ["{{material.Name}}"])
self.create_text_type("TYPE-TAG", "capsule-tag", ["{{type.Name}}"])
self.create_text_type("NAME-TAG", "capsule-tag", ["{{Name}}"])
@@ -189,9 +195,11 @@ class LibraryGenerator:
self.file.createIfcDirection((0.0, 0.0, 1.0)),
self.file.createIfcDirection((1.0, 0.0, 0.0)),
)
items.append(self.file.createIfcTextLiteralWithExtent(
literal, origin, "RIGHT", self.file.createIfcPlanarExtent(1000, 1000), "center"
))
items.append(
self.file.createIfcTextLiteralWithExtent(
literal, origin, "RIGHT", self.file.createIfcPlanarExtent(1000, 1000), "center"
)
)
representation = self.file.createIfcShapeRepresentation(
self.representations["model_annotation"],
@@ -205,22 +213,30 @@ class LibraryGenerator:
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, products=[element], type="IfcMaterialLayerSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet"
)
layer_set = rel.RelatingMaterial
layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=layer_set, material=self.material)
layer.LayerThickness = thickness
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[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, products=[element], type="IfcMaterialProfileSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet"
)
profile_set = rel.RelatingMaterial
material_profile = ifcopenshell.api.run(
"material.add_profile", self.file, profile_set=profile_set, material=self.material
)
ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[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)
@@ -252,7 +268,9 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
LibraryGenerator().generate()
@@ -131,7 +131,9 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
if __name__ == "__main__":
@@ -244,7 +244,9 @@ class LibraryGenerator:
polyline = builder.polyline((V(0, 0), V(width, 0)))
_, _, first_semicircle = builder.create_transition_arc_ifc(width, depth, create_ifc_curve=True)
_, _, second_semicircle = builder.create_transition_arc_ifc(second_arc_width, second_arc_depth, create_ifc_curve=True)
_, _, second_semicircle = builder.create_transition_arc_ifc(
second_arc_width, second_arc_depth, create_ifc_curve=True
)
builder.translate(second_semicircle, V((width - second_arc_width) / 2, 0))
builder.translate([polyline, first_semicircle, second_semicircle], shift_to_center)
@@ -934,34 +936,46 @@ class LibraryGenerator:
overall_width, overall_depth, overall_height = (900.0, 750.0, 2100.0)
representation_3d, representation_2d = create_shower_or_bathtube(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Shower 75x90", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Shower 75x90", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (800.0, 800.0, 2100.0)
representation_3d, representation_2d = create_shower_or_bathtube(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Shower 80x80", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Shower 80x80", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (900.0, 900.0, 2100.0)
representation_3d, representation_2d = create_shower_or_bathtube(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Shower 90x90", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Shower 90x90", representation_3d, representation_2d
)
# bathtubs
overall_width, overall_depth, overall_height = (1600.0, 700.0, 550.0)
representation_3d, representation_2d = create_shower_or_bathtube(
overall_width, overall_depth, overall_height, bathtube=True
)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Small Bathtub", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Small Bathtub", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (1700.0, 750.0, 550.0)
representation_3d, representation_2d = create_shower_or_bathtube(
overall_width, overall_depth, overall_height, bathtube=True
)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Medium Bathtub", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Medium Bathtub", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (1800.0, 800.0, 550.0)
representation_3d, representation_2d = create_shower_or_bathtube(
overall_width, overall_depth, overall_height, bathtube=True
)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Large Bathtub", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Large Bathtub", representation_3d, representation_2d
)
def create_toilet(width, depth, height, seat_level=0):
shift_to_center = V(-width / 2, 0)
@@ -1130,9 +1144,7 @@ class LibraryGenerator:
back_wall = builder.rectangle(V(width, height))
# example of rotating and extruding by Y axis btw
back_wall_extruded = builder.extrude(
back_wall,
back_wall_depth + back_wall_border_mask_depth,
**builder.extrude_kwargs("Y")
back_wall, back_wall_depth + back_wall_border_mask_depth, **builder.extrude_kwargs("Y")
)
items_3d_to_center.append(back_wall_extruded)
@@ -1202,15 +1214,21 @@ class LibraryGenerator:
overall_width, overall_depth, overall_height = (350.0, 350.0, 650.0)
representation_3d, representation_2d = create_urinal(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Small Urinal", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Small Urinal", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (400.0, 400.0, 650.0)
representation_3d, representation_2d = create_urinal(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Medium Urinal", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Medium Urinal", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (450.0, 450.0, 650.0)
representation_3d, representation_2d = create_urinal(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Large Urinal", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Large Urinal", representation_3d, representation_2d
)
def create_basin(width, depth, height):
second_width = 0.9 * width
@@ -1251,19 +1269,27 @@ class LibraryGenerator:
overall_width, overall_depth, overall_height = (450.0, 400.0, 250.0)
representation_3d, representation_2d = create_basin(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Extra Small Basin", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Extra Small Basin", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (500.0, 450.0, 250.0)
representation_3d, representation_2d = create_basin(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Small Basin", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Small Basin", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (550.0, 500.0, 250.0)
representation_3d, representation_2d = create_basin(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Medium Basin", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Medium Basin", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (600.0, 550.0, 250.0)
representation_3d, representation_2d = create_basin(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcSanitaryTerminalType", "Neufert Large Basin", representation_3d, representation_2d)
self.create_explicit_type(
"IfcSanitaryTerminalType", "Neufert Large Basin", representation_3d, representation_2d
)
def create_desk(width, depth, height, return_representations=False):
leg_width = 50.0
@@ -1421,7 +1447,9 @@ class LibraryGenerator:
overall_width, overall_depth, overall_height = (500.0, 570.0, 820.0)
representation_3d, representation_2d = create_dishwasher(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcElectricApplianceType", "Neufert Dishwasher", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Neufert Dishwasher", representation_3d, representation_2d
)
def create_cooktop(width, depth, height):
items_3d, items_2d = create_box_objects(width, depth, height)
@@ -1442,15 +1470,21 @@ class LibraryGenerator:
overall_width, overall_depth, overall_height = (580.0, 510.0, 50.0)
representation_3d, representation_2d = create_cooktop(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcElectricApplianceType", "Neufert Cooktop 58x51", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Neufert Cooktop 58x51", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (750.0, 510.0, 50.0)
representation_3d, representation_2d = create_cooktop(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcElectricApplianceType", "Neufert Cooktop 75x51", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Neufert Cooktop 75x51", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (890.0, 510.0, 50.0)
representation_3d, representation_2d = create_cooktop(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcElectricApplianceType", "Neufert Cooktop 89x51", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Neufert Cooktop 89x51", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (1750.0, 600.0, 850.0)
representation_3d, representation_2d = create_box_objects(
@@ -1520,7 +1554,9 @@ class LibraryGenerator:
representation_3d, representation_2d = create_box_objects(
overall_width, overall_depth, overall_height, return_representations=True
)
self.create_explicit_type("IfcElectricApplianceType", "Generic Small Fridge Zone", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Generic Small Fridge Zone", representation_3d, representation_2d
)
overall_width, overall_depth, overall_height = (900.0, 700.0, 1900.0)
representation_3d, representation_2d = create_box_objects(
@@ -1534,7 +1570,9 @@ class LibraryGenerator:
representation_3d, representation_2d = create_box_objects(
overall_width, overall_depth, overall_height, return_representations=True
)
self.create_explicit_type("IfcElectricApplianceType", "Generic Large Fridge Zone", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Generic Large Fridge Zone", representation_3d, representation_2d
)
def create_sink(width, depth, height, add_table):
shift_to_center = V(-width / 2, -depth)
@@ -1670,7 +1708,9 @@ class LibraryGenerator:
overall_width, overall_depth, overall_height = (595.0, 680.0, 850.0)
representation_3d, representation_2d = create_washing_machine(overall_width, overall_depth, overall_height)
self.create_explicit_type("IfcElectricApplianceType", "Neufert Washing Machine", representation_3d, representation_2d)
self.create_explicit_type(
"IfcElectricApplianceType", "Neufert Washing Machine", representation_3d, representation_2d
)
def create_dryer_machine(width, depth, height):
items_3d, items_2d = create_box_objects(width, depth, height)
@@ -1797,13 +1837,17 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation_2d
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
return element
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, products=[element], type="IfcMaterialLayerSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet"
)
layer_set = rel.RelatingMaterial
for layer_data in data["Layers"]:
layer = ifcopenshell.api.run(
@@ -1811,33 +1855,43 @@ class LibraryGenerator:
)
layer.Name = layer_data[0]
layer.LayerThickness = layer_data[2]
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[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, products=[element], type="IfcMaterialLayerSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[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, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[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, products=[element], type="IfcMaterialProfileSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet"
)
profile_set = rel.RelatingMaterial
material_profile = ifcopenshell.api.run(
"material.add_profile",
self.file,
profile_set=profile_set,
material=self.material
material=self.material,
# 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, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[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)
@@ -1869,7 +1923,9 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
if __name__ == "__main__":
@@ -394,9 +394,9 @@ class LibraryGenerator:
TreeData("Lollipop Tree (14m)", "simple", (14.0, 7.5, 0.44)),
TreeData("Lollipop Tree (18m)", "simple", (18.0, 9.5, 0.44)),
TreeData("Lollipop Tree (25m)", "simple", (25.0, 13.5, 0.50)),
TreeData("Tree Small (8m)", "low_poly", (8.0, 6.0, 0.0, .8, 1.0, 0.2, 10)),
TreeData("Tree Medium (12m)", "low_poly", (12.0, 10.0, 0.0, .8, 2.0, 0.4, 20)),
TreeData("Tree Big (20m)", "low_poly", (20.0, 15.0, 0.0, .8, 4.0, 0.6, 30)),
TreeData("Tree Small (8m)", "low_poly", (8.0, 6.0, 0.0, 0.8, 1.0, 0.2, 10)),
TreeData("Tree Medium (12m)", "low_poly", (12.0, 10.0, 0.0, 0.8, 2.0, 0.4, 20)),
TreeData("Tree Big (20m)", "low_poly", (20.0, 15.0, 0.0, 0.8, 4.0, 0.6, 30)),
]
for tree_data in trees:
@@ -409,7 +409,7 @@ class LibraryGenerator:
# From tree species table
with open(os.path.join(BLEND_DIR, "tree_species.csv"), 'r') as csvfile:
with open(os.path.join(BLEND_DIR, "tree_species.csv"), "r") as csvfile:
reader = csv.reader(csvfile)
for i, row in enumerate(reader):
if i == 0:
@@ -418,9 +418,7 @@ class LibraryGenerator:
data = [float(x) for x in row[2:]]
preset_data = preset.preset_class(*data)._asdict()
tree_geometry = preset.generator(builder, **preset_data)
self.create_explicit_type(
"IfcGeographicElementType", row[1], **self.get_representations(tree_geometry)
)
self.create_explicit_type("IfcGeographicElementType", row[1], **self.get_representations(tree_geometry))
self.file.write(output_filename)
@@ -447,7 +445,9 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation_2d
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
return element
def create_type(self, ifc_class, name, representations):
@@ -480,8 +480,9 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
if __name__ == "__main__":
@@ -98,7 +98,9 @@ class LibraryGenerator:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=element, representation=representation
)
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
ifcopenshell.api.run(
"project.assign_declaration", self.file, definitions=[element], relating_context=self.library
)
LibraryGenerator().generate()
+6 -6
View File
@@ -12,12 +12,12 @@ props = bpy.context.scene.BIMGeoreferenceProperties
# georeferencing coordinates in the IFC Georeferencing panel before filling out
# these details.
#props.blender_eastings = '334134181.0'
#props.blender_northings = '6254570511.0'
#props.blender_orthogonal_height = '0.0'
#props.blender_x_axis_abscissa = '0.147487884244522'
#props.blender_x_axis_ordinate = '0.989063862448262'
#props.has_blender_offset = True
# props.blender_eastings = '334134181.0'
# props.blender_northings = '6254570511.0'
# props.blender_orthogonal_height = '0.0'
# props.blender_x_axis_abscissa = '0.147487884244522'
# props.blender_x_axis_ordinate = '0.989063862448262'
# props.has_blender_offset = True
props = bpy.context.scene.BIMProjectProperties
+18 -14
View File
@@ -40,26 +40,30 @@ if not file:
print("No ifc file")
sys.exit()
annotations = file.by_type('IfcAnnotation')
annotations = file.by_type("IfcAnnotation")
count = 0
for annotation in annotations:
if annotation.ObjectType == 'DRAWING':
if annotation.ObjectType == "DRAWING":
psets = ifcopenshell.util.element.get_psets(annotation)
pset = psets['EPset_Drawing']
pset_ifc = file.by_id(pset['id'])
pset = psets["EPset_Drawing"]
pset_ifc = file.by_id(pset["id"])
wrong_sep = ""
if platform == 'linux' or platform == 'linux2' or platform == 'darwin':
if platform == "linux" or platform == "linux2" or platform == "darwin":
wrong_sep = "\\"
if platform == 'win32':
if platform == "win32":
wrong_sep = "/"
ifcopenshell.api.run("pset.edit_pset", file, pset = pset_ifc, properties = {
'Stylesheet' : pset['Stylesheet'].replace(wrong_sep, os.path.sep),
'Markers' : pset['Markers'].replace(wrong_sep, os.path.sep),
'Symbols' : pset['Symbols'].replace(wrong_sep, os.path.sep),
'Patterns' : pset['Patterns'].replace(wrong_sep, os.path.sep),
})
count+=1
ifcopenshell.api.run(
"pset.edit_pset",
file,
pset=pset_ifc,
properties={
"Stylesheet": pset["Stylesheet"].replace(wrong_sep, os.path.sep),
"Markers": pset["Markers"].replace(wrong_sep, os.path.sep),
"Symbols": pset["Symbols"].replace(wrong_sep, os.path.sep),
"Patterns": pset["Patterns"].replace(wrong_sep, os.path.sep),
},
)
count += 1
print(f"DONE! Checked {count} drawings")
@@ -9,7 +9,7 @@ V = lambda *x: Vector([float(i) for i in x])
def simple_uses():
ifc_file = ifcopenshell.file()
builder = ShapeBuilder(ifc_file)
triangle_curve = builder.polyline(( (0., 0.), (1., 2.), (2., 0.) ), closed=True)
triangle_curve = builder.polyline(((0.0, 0.0), (1.0, 2.0), (2.0, 0.0)), closed=True)
print(triangle_curve)
rectangle_curve = builder.rectangle()
@@ -18,26 +18,19 @@ def simple_uses():
circle_curve = builder.circle()
print(circle_curve)
translated_rect = builder.translate(rectangle_curve, Vector( (2.5, 2.5) ), create_copy=True)
translated_rect = builder.translate(rectangle_curve, Vector((2.5, 2.5)), create_copy=True)
print(translated_rect)
rotated_triangle = builder.rotate(triangle_curve, 90,
pivot_point=Vector( (1., 1.) ),
counter_clockwise=True,
create_copy=True)
rotated_triangle = builder.rotate(
triangle_curve, 90, pivot_point=Vector((1.0, 1.0)), counter_clockwise=True, create_copy=True
)
print(rotated_triangle)
a, b = builder.translate(
[rectangle_curve, circle_curve],
Vector( (5., 5.) ), create_copy=True)
a, b = builder.translate([rectangle_curve, circle_curve], Vector((5.0, 5.0)), create_copy=True)
print(f"Multiple translated objects: {a}, {b}")
c, d = builder.rotate(
[a, b], 90,
pivot_point=Vector( (0., 0.) ),
counter_clockwise=False,
create_copy=True)
print(f'Multiple rotated objects: {c}, {d}')
c, d = builder.rotate([a, b], 90, pivot_point=Vector((0.0, 0.0)), counter_clockwise=False, create_copy=True)
print(f"Multiple rotated objects: {c}, {d}")
mirrored_objects = builder.mirror(
[a, b],
@@ -57,8 +50,7 @@ def simple_uses():
print(rotated_circle)
profile = builder.profile(
rectangle_curve, "test_profile",
inner_curves=[builder.circle(center=Vector((0.5, 0.5)), radius=0.2)]
rectangle_curve, "test_profile", inner_curves=[builder.circle(center=Vector((0.5, 0.5)), radius=0.2)]
)
print(profile)
@@ -129,20 +121,14 @@ def mirror_placement_test():
rect_profile = builder.profile(rect, inner_curves=rect_small)
pl = builder.extrude(rect_profile,
magnitude=7.0,
position_z_axis=V(0, -1, 0),
extrusion_vector=V(0, 0, -1),
position=V(0, 5, 0)
pl = builder.extrude(
rect_profile, magnitude=7.0, position_z_axis=V(0, -1, 0), extrusion_vector=V(0, 0, -1), position=V(0, 5, 0)
)
rect = builder.rectangle(size=size)
back_wall = builder.extrude(rect,
magnitude=2.0,
position_z_axis=V(0, -1, 0),
extrusion_vector=V(0, 0, -1),
position=V(0, 1, 0)
back_wall = builder.extrude(
rect, magnitude=2.0, position_z_axis=V(0, -1, 0), extrusion_vector=V(0, 0, -1), position=V(0, 1, 0)
)
items_3d = [pl, back_wall]
@@ -195,20 +181,18 @@ def curve_between_two_points_test():
width, depth = (200.0, 200.0)
curve_coords = (
(V(0, depth), V(-width, 0)), # ccw
(V(0, depth), V(width, 0)), # cw
(V(0, -depth), V(width, 0)), # ccw
(V(0, -depth), V(-width, 0)), # cw
(V(+width/2, 0), V(0, depth)), # ccw
(V(-width/2, 0), V(0, depth)), # cw
(V(-width/2, 0), V(0, -depth)), # ccw
(V(+width/2, 0), V(0, -depth)), # cw
(V(0, depth/2), V(+width, 0)), # cw
(V(0, depth/2), V(-width, 0)), # ccw
(V(0, -depth/2), V(+width, 0)), # ccw
(V(0, -depth/2), V(-width, 0)), # cw
(V(0, depth), V(-width, 0)), # ccw
(V(0, depth), V(width, 0)), # cw
(V(0, -depth), V(width, 0)), # ccw
(V(0, -depth), V(-width, 0)), # cw
(V(+width / 2, 0), V(0, depth)), # ccw
(V(-width / 2, 0), V(0, depth)), # cw
(V(-width / 2, 0), V(0, -depth)), # ccw
(V(+width / 2, 0), V(0, -depth)), # cw
(V(0, depth / 2), V(+width, 0)), # cw
(V(0, depth / 2), V(-width, 0)), # ccw
(V(0, -depth / 2), V(+width, 0)), # ccw
(V(0, -depth / 2), V(-width, 0)), # cw
)
items_2d = [builder.curve_between_two_points(c) for c in curve_coords]
@@ -6,7 +6,7 @@ import multiprocessing
class BlenderImporter:
def __init__(self):
self.file = ifcopenshell.open('/home/dion/untitled.ifc')
self.file = ifcopenshell.open("/home/dion/untitled.ifc")
self.cache_path = "cache.h5"
self.should_use_cpu_multiprocessing = True
self.deflection_tolerance = 0.001
@@ -77,9 +77,7 @@ class BlenderImporter:
return results
settings = self.settings_2d if is_curve else self.settings
if self.should_use_cpu_multiprocessing:
iterator = ifcopenshell.geom.iterator(
settings, self.file, multiprocessing.cpu_count(), include=products
)
iterator = ifcopenshell.geom.iterator(settings, self.file, multiprocessing.cpu_count(), include=products)
else:
iterator = ifcopenshell.geom.iterator(settings, self.file, include=products)
cache = self.get_cache()
@@ -120,4 +118,5 @@ class BlenderImporter:
except:
return
BlenderImporter().execute()