├── LICENSE ├── README.md ├── img ├── rwth_ifc_viewer.png └── tue_viewer_screen_shot.png └── src └── snippets.conf /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 jakob-beetz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IfcOpenShell Scripting Tutorial 2 | 3 | ![Viewer screenshot](img/rwth_ifc_viewer.png) 4 | 5 | This repository contains educational resources including a tutorial to learn scripting your own applications for processing **Industry Foundation Classes (IFC)** files. It is based on a scriptable viewer tool that uses the [IfcOpenShell](http://ifcopenshell.org) toolkit. The scriptable viewer tool has been created for teaching purposes and is used at the [Eindhoven University at Technology](https://www.isbe.tue.nl) and the [RWTH Aachen University](http://dc.rwth-aachen.de) . 6 | 7 | A packaged __binary version of the tool (Windows at the moment)__ is available at the [the release page]( https://github.com/jakob-beetz/IfcOpenShellScriptingTutorial/releases/ )(175 MB!) to get you started. It comes with "all batteries included", including python, IfcOpenShell and the Python OpenCascade wrappers. 8 | 9 | The package includes alls necessary source code to extend, modify, reuse the scripting viewer to your liking. 10 | 11 | The viewer and the tutorial are **Open Educational Resource (OER)** that can be used under MIT license conditions in academic or commericial educational settings. 12 | 13 | Follow these simple steps to 'install' the viewer/scripting application: 14 | 15 | - Download tue_viewer.zip (175 MB) and the [snippets configuration file](https://raw.githubusercontent.com/jakob-beetz/IfcOpenShellScriptingTutorial/master/src/snippets.conf) which contains a few example snippets to get you started. 16 | - in your home directory (e.g. C:/Users/yourname) create a directory called ".ifcopenshell" (*note: Microsoft is "protecting" you from creating a directory starting with a "." in MS Explorer. Open a command shell (press the windows button on your keyboard, type "cmd"), change to your home directory (cd C:\Users\myname) and create the directory by typing "mkdir .ifcopenshell) in this create another directory called "app" and place the snippets.conf there (Note, if you have started the application once allready, you will find the directory structure and a default snipptes.conf there. You can overwrite this) 17 | - Unpack tue_viewer.zip and start the viewer by double-clicking start_viewer.cmd 18 | - Follow the tutorial in [this wiki](https://github.com/jakob-beetz/IfcOpenShellScriptingTutorial/wiki/Home) 19 | -------------------------------------------------------------------------------- /img/rwth_ifc_viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakob-beetz/IfcOpenShellScriptingTutorial/c0806db40fb5f2aa98dd1f3cb5ae61109c4c3642/img/rwth_ifc_viewer.png -------------------------------------------------------------------------------- /img/tue_viewer_screen_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakob-beetz/IfcOpenShellScriptingTutorial/c0806db40fb5f2aa98dd1f3cb5ae61109c4c3642/img/tue_viewer_screen_shot.png -------------------------------------------------------------------------------- /src/snippets.conf: -------------------------------------------------------------------------------- 1 | [quickload_model] 2 | r'd = \jakob\teaching\7m900_fundamentals_of_bim\2016_2017\assignment_B1\7m900_tue_hello_wall_with_door.ifc' 3 | 4 | [snippets] 5 | print all wall ids = ########################################################################### 6 | |# A simple script that iterates over all walls in the current model # 7 | |# and prints their Globally unique IDs (GUIDS) to the console window # 8 | |########################################################################### 9 | | 10 | |for wall in model.by_type("IfcWall"): 11 | | print ("wall with global id: "+str(wall.GlobalId)) 12 | | 13 | print properties of current selection = ########################################################################### 14 | |# A simple script that iterates over all IfcPropertySets of the currently # 15 | |# selected object and prints them to the console # 16 | |########################################################################### 17 | | 18 | |# check if something is selected 19 | |if selection: 20 | | #get the IfcProduct that is stored in the global variable 'selection' 21 | | obj = selection 22 | | for relDefinesByProperties in obj.IsDefinedBy: 23 | | print("[{0}]".format(relDefinesByProperties.RelatingPropertyDefinition.Name)) 24 | | for prop in relDefinesByProperties.RelatingPropertyDefinition.HasProperties: 25 | | print ("{:<20} :{}".format(prop.Name,prop.NominalValue.wrappedValue)) 26 | | print ("\\n") 27 | | 28 | asdfasdf = ########################################################################### 29 | |# A simple script that iterates over all walls in the current model # 30 | |# and prints their Globally unique IDs (GUIDS) to the console window # 31 | |########################################################################### 32 | | 33 | |for wall in model.by_type("IfcWall"): 34 | | print ("wall with global id: "+str(wall.GlobalId)) 35 | | 36 | 37 | get all selected products = print (viewer.get_selection_set(model)) 38 | | 39 | hightlight all selected products = sel = viewer.get_selection_set(model) 40 | |for p in sel: 41 | | viewer.set_color(p,1,0,1) 42 | save properties to csv = ########################################################################### 43 | |# A simple script that iterates over all IfcPropertySets of the currently # 44 | |# selected object and prints them to the console # 45 | |########################################################################### 46 | |import csv 47 | |# check if something is selected 48 | |sel_set = viewer.get_selection_set(model) 49 | | #get the IfcProduct that is stored in the global variable 'selection' 50 | |with open(r'D:\\test1.csv', 'wb') as testfile: 51 | | for p in sel_set: 52 | | 53 | | csv_writer = csv.writer(testfile) 54 | | for relDefinesByProperties in p.IsDefinedBy: 55 | | print("[{0}]".format(relDefinesByProperties.RelatingPropertyDefinition.Name)) 56 | | for prop in relDefinesByProperties.RelatingPropertyDefinition.HasProperties: 57 | | print ("{:<20} :{}".format(prop.Name,prop.NominalValue.wrappedValue)) 58 | | print ("\\n") 59 | | csv_writer.writerow([p.GlobalId, p.Name, relDefinesByProperties.RelatingPropertyDefinition.Name,prop.Name,prop.NominalValue.wrappedValue]) 60 | | 61 | | 62 | | 63 | print project information = project = model.by_type("IfcProject") 64 | |print (project[0].Name) 65 | |print (project[0].GlobalId) 66 | |print (project[0].Description) 67 | |print (project[0].LongName) 68 | get model object by guid = project = model.by_guid('0YvctVUKr0kugbFTf53O9L') 69 | |print (project.Name) 70 | all attribute names of an instance = project = model.by_type("IfcProject")[0] 71 | |for att_idx in range(0,len(project)): 72 | | print(project.attribute_name(att_idx)) 73 | | 74 | all attribute names, values and types = door = model.by_type("IfcDoor")[0] 75 | |for att_idx in range(0,len(project)-1): 76 | | field_width = 20 77 | | # In case we are dealing with a different IFC version 78 | | # there might by attributes that do not exist in a 2x3 file 79 | | # handle the attempt to print out a value where there is no 80 | | # attribute gracefully 81 | | try: 82 | | att_name = door.attribute_name(att_idx) 83 | | att_type = door.attribute_type(att_name) 84 | | att_value = door[att_name] 85 | | print("{}\\t{}\\t{}".format(att_name.ljust(field_width),att_type.ljust(field_width), att_value)) 86 | | except: 87 | | pass 88 | | 89 | mark selection red = products = viewer.get_selection_set(model) 90 | |for product in products: 91 | | viewer.set_color(product, 0.8,0,0) 92 | add properties to selected object = import ifcopenshell 93 | |import uuid 94 | |if selection: 95 | | product = selection 96 | | prop_set_guid = ifcopenshell.guid.compress(uuid.uuid1().hex) 97 | | property_values = [ 98 | | model.createIfcPropertySingleValue("My own property", "Description of My Own Property", model.create_entity("IfcText", "some textual Value"), None), 99 | | model.createIfcPropertySingleValue("isMadeUp", "whether or not this is a made up valeue", model.create_entity("IfcBoolean", True), None), 100 | | ] 101 | | property_set = model.createIfcPropertySet(prop_set_guid, product.OwnerHistory, "MyOwnPropSet", None, property_values) 102 | | rel_guid = ifcopenshell.guid.compress(uuid.uuid1().hex) 103 | | model.createIfcRelDefinesByProperties(rel_guid, product.OwnerHistory, None, None, [product], property_set) 104 | | 105 | |model.write(r'D:\\properties_added.ifc') 106 | |print("writing done") 107 | minimalistic model checker = ########################################################################### 108 | |# Minimalistic Model checker script 109 | |# A simple to use external information defined in e.g. Excel to check 110 | |# values in an IFC file. Create a minimal CSV like: 111 | |# 112 | |# Element;Attribute;Min_height 113 | |# IfcDoor;OverallHeight;2.1 114 | |# IfcWindow;OverallHeight;1 115 | |# 116 | |# and save it to a convient location 117 | |########################################################################### 118 | |import csv 119 | |#open the file 120 | |with open(r'D:\\simple_check.csv') as checkfile: 121 | | # create a reader, that reads the columns into a dictionary 122 | | # using the first row as keys ("Element", "Attribute", "Min_height" 123 | | reader = csv.DictReader(checkfile,delimiter=";") 124 | | # iterate over all rows 125 | | for row in reader: 126 | | print(row['Element'], row["Attribute"],row['Min_height']) 127 | | # get all elements 128 | | for element in model.by_type(row["Element"]): 129 | | attribute_value=element[row["Attribute"]] 130 | | if float(attribute_value) < float(row['Min_height']): 131 | | print ("Element {} violates the minimum height requirement with {}".format(element.GlobalId,attribute_value)) 132 | | 133 | | 134 | | 135 | | 136 | 137 | --------------------------------------------------------------------------------