Creating a simple wall with property set and quantity information
The following recipe creates a simple wall from scratch using a templating technique to quickly populate the entity instances for the IFC project structure. Simple extrusion geometries, an IfcPropertySet and an IfcElementQuantity are added using the procedural entity instance creation functions. The script is written for a research project with Dr. Patrick Janssen in National University of Singapore. The script takes reference from the FreeCAD IFC exporter script and HelloWall miniExample.
First some helper functions are defined.
import uuid import time import tempfile import ifcopenshell O = 0., 0., 0. X = 1., 0., 0. Y = 0., 1., 0. Z = 0., 0., 1.
Helper function definitions
# Creates an IfcAxis2Placement3D from Location, Axis and RefDirection specified as Python tuples def create_ifcaxis2placement(ifcfile, point=O, dir1=Z, dir2=X): point = ifcfile.createIfcCartesianPoint(point) dir1 = ifcfile.createIfcDirection(dir1) dir2 = ifcfile.createIfcDirection(dir2) axis2placement = ifcfile.createIfcAxis2Placement3D(point, dir1, dir2) return axis2placement # Creates an IfcLocalPlacement from Location, Axis and RefDirection, specified as Python tuples, and relative placement def create_ifclocalplacement(ifcfile, point=O, dir1=Z, dir2=X, relative_to=None): axis2placement = create_ifcaxis2placement(ifcfile,point,dir1,dir2) ifclocalplacement2 = ifcfile.createIfcLocalPlacement(relative_to,axis2placement) return ifclocalplacement2 # Creates an IfcPolyLine from a list of points, specified as Python tuples def create_ifcpolyline(ifcfile, point_list): ifcpts = [] for point in point_list: point = ifcfile.createIfcCartesianPoint(point) ifcpts.append(point) polyline = ifcfile.createIfcPolyLine(ifcpts) return polyline # Creates an IfcExtrudedAreaSolid from a list of points, specified as Python tuples def create_ifcextrudedareasolid(ifcfile, point_list, ifcaxis2placement, extrude_dir, extrusion): polyline = create_ifcpolyline(ifcfile, point_list) ifcclosedprofile = ifcfile.createIfcArbitraryClosedProfileDef("AREA", None, polyline) ifcdir = ifcfile.createIfcDirection(extrude_dir) ifcextrudedareasolid = ifcfile.createIfcExtrudedAreaSolid(ifcclosedprofile, ifcaxis2placement, ifcdir, extrusion) return ifcextrudedareasolid create_guid = lambda: ifcopenshell.guid.compress(uuid.uuid1().hex)
A template is defined and instantiated using local variable definitions. This quickly defines the entity instances required for the IFC project structure and the fields of the header structure.
# IFC template creation filename = "hello_wall.ifc" timestamp = time.time() timestring = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(timestamp)) creator = "Kianwee Chen" organization = "NUS" application, application_version = "IfcOpenShell", "0.5" project_globalid, project_name = create_guid(), "Hello Wall" # A template IFC file to quickly populate entity instances for an IfcProject with its dependencies template = """ISO-10303-21; HEADER; FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); FILE_NAME('%(filename)s','%(timestring)s',('%(creator)s'),('%(organization)s'),'%(application)s','%(application)s',''); FILE_SCHEMA(('IFC2X3')); ENDSEC; DATA; #1=IFCPERSON($,$,'%(creator)s',$,$,$,$,$); #2=IFCORGANIZATION($,'%(organization)s',$,$,$); #3=IFCPERSONANDORGANIZATION(#1,#2,$); #4=IFCAPPLICATION(#2,'%(application_version)s','%(application)s',''); #5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,%(timestamp)s); #6=IFCDIRECTION((1.,0.,0.)); #7=IFCDIRECTION((0.,0.,1.)); #8=IFCCARTESIANPOINT((0.,0.,0.)); #9=IFCAXIS2PLACEMENT3D(#8,#7,#6); #10=IFCDIRECTION((0.,1.,0.)); #11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10); #12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0); #13=IFCSIUNIT(\*,.LENGTHUNIT.,$,.METRE.); #14=IFCSIUNIT(\*,.AREAUNIT.,$,.SQUARE_METRE.); #15=IFCSIUNIT(\*,.VOLUMEUNIT.,$,.CUBIC_METRE.); #16=IFCSIUNIT(\*,.PLANEANGLEUNIT.,$,.RADIAN.); #17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16); #18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17); #19=IFCUNITASSIGNMENT((#13,#14,#15,#18)); #20=IFCPROJECT('%(project_globalid)s',#5,'%(project_name)s',$,$,$,$,(#11),#19); ENDSEC; END-ISO-10303-21; """ % locals() # Write the template to a temporary file temp_handle, temp_filename = tempfile.mkstemp(suffix=".ifc") with open(temp_filename, "wb") as f: f.write(template) # Obtain references to instances defined in template ifcfile = ifcopenshell.open(temp_filename) owner_history = ifcfile.by_type("IfcOwnerHistory")[0] project = ifcfile.by_type("IfcProject")[0] context = ifcfile.by_type("IfcGeometricRepresentationContext")[0]
Subsequently, the hierarchical structure of Site, Building and Building storey is instantiated.
# IFC hierarchy creation site_placement = create_ifclocalplacement(ifcfile) site = ifcfile.createIfcSite(create_guid(), owner_history, "Site", None, None, site_placement, None, None, "ELEMENT", None, None, None, None, None) building_placement = create_ifclocalplacement(ifcfile, relative_to=site_placement) building = ifcfile.createIfcBuilding(create_guid(), owner_history, 'Building', None, None, building_placement, None, None, "ELEMENT", None, None, None) storey_placement = create_ifclocalplacement(ifcfile, relative_to=building_placement) elevation = 0.0 building_storey = ifcfile.createIfcBuildingStorey(create_guid(), owner_history, 'Storey', None, None, storey_placement, None, None, "ELEMENT", elevation) container_storey = ifcfile.createIfcRelAggregates(create_guid(), owner_history, "Building Container", None, building, [building_storey]) container_site = ifcfile.createIfcRelAggregates(create_guid(), owner_history, "Site Container", None, site, [building]) container_project = ifcfile.createIfcRelAggregates(create_guid(), owner_history, "Project Container", None, project, [site])
The wall is created with simply extrusion geometry
# Wall creation: Define the wall shape as a polyline axis and an extruded area solid wall_placement = create_ifclocalplacement(ifcfile, relative_to=storey_placement) polyline = create_ifcpolyline(ifcfile, [(0.0, 0.0, 0.0), (5.0, 0.0, 0.0)]) axis_representation = ifcfile.createIfcShapeRepresentation(context, "Axis", "Curve2D", [polyline]) extrusion_placement = create_ifcaxis2placement(ifcfile, (0.0, 0.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)) point_list_extrusion_area = [(0.0, -0.1, 0.0), (5.0, -0.1, 0.0), (5.0, 0.1, 0.0), (0.0, 0.1, 0.0), (0.0, -0.1, 0.0)] solid = create_ifcextrudedareasolid(ifcfile, point_list_extrusion_area, extrusion_placement, (0.0, 0.0, 1.0), 3.0) body_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "SweptSolid", [solid]) product_shape = ifcfile.createIfcProductDefinitionShape(None, None, [axis_representation, body_representation]) wall = ifcfile.createIfcWallStandardCase(create_guid(), owner_history, "Wall", "An awesome wall", None, wall_placement, product_shape, None)
An IfcMaterialLayerSet is created. This is a mandatory construct for an IfcWallStandardCase. # Define and associate the wall material material = ifcfile.createIfcMaterial("wall material") material_layer = ifcfile.createIfcMaterialLayer(material, 0.2, None) material_layer_set = ifcfile.createIfcMaterialLayerSet([material_layer], None) material_layer_set_usage = ifcfile.createIfcMaterialLayerSetUsage(material_layer_set, "AXIS2", "POSITIVE", -0.1) ifcfile.createIfcRelAssociatesMaterial(create_guid(), owner_history, RelatedObjects=[wall], RelatingMaterial=material_layer_set_usage)
Next, an IfcPropertySet and IfcElementQuantity are instantiated. The quantities are derived from instances describing the wall above.
# Create and assign property set property_values = [ ifcfile.createIfcPropertySingleValue("Reference", "Reference", ifcfile.create_entity("IfcText", "Describe the Reference"), None), ifcfile.createIfcPropertySingleValue("IsExternal", "IsExternal", ifcfile.create_entity("IfcBoolean", True), None), ifcfile.createIfcPropertySingleValue("ThermalTransmittance", "ThermalTransmittance", ifcfile.create_entity("IfcReal", 2.569), None), ifcfile.createIfcPropertySingleValue("IntValue", "IntValue", ifcfile.create_entity("IfcInteger", 2), None) ] property_set = ifcfile.createIfcPropertySet(create_guid(), owner_history, "Pset_WallCommon", None, property_values) ifcfile.createIfcRelDefinesByProperties(create_guid(), owner_history, None, None, [wall], property_set) # Add quantity information quantity_values = [ ifcfile.createIfcQuantityLength("Length", "Length of the wall", None, 5.0), ifcfile.createIfcQuantityArea("Area", "Area of the front face", None, 5.0 \* solid.Depth), ifcfile.createIfcQuantityVolume("Volume", "Volume of the wall", None, 5.0 \* solid.Depth \* material_layer.LayerThickness) ] element_quantity = ifcfile.createIfcElementQuantity(create_guid(), owner_history, "BaseQuantities", None, None, quantity_values) ifcfile.createIfcRelDefinesByProperties(create_guid(), owner_history, None, None, [wall], element_quantity)
An opening element and window are created and associated to the wall. An opening element describes the geometry to be subtracted from the wall.
# Create and associate an opening for the window in the wall opening_placement = create_ifclocalplacement(ifcfile, (0.5, 0.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0), wall_placement) opening_extrusion_placement = create_ifcaxis2placement(ifcfile, (0.0, 0.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)) point_list_opening_extrusion_area = [(0.0, -0.1, 0.0), (3.0, -0.1, 0.0), (3.0, 0.1, 0.0), (0.0, 0.1, 0.0), (0.0, -0.1, 0.0)] opening_solid = create_ifcextrudedareasolid(ifcfile, point_list_opening_extrusion_area, opening_extrusion_placement, (0.0, 0.0, 1.0), 1.0) opening_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "SweptSolid", [opening_solid]) opening_shape = ifcfile.createIfcProductDefinitionShape(None, None, [opening_representation]) opening_element = ifcfile.createIfcOpeningElement(create_guid(), owner_history, "Opening", "An awesome opening", None, opening_placement, opening_shape, None) ifcfile.createIfcRelVoidsElement(create_guid(), owner_history, None, None, wall, opening_element) # Create a simplified representation for the Window window_placement = create_ifclocalplacement(ifcfile, (0.0, 0.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0), opening_placement) window_extrusion_placement = create_ifcaxis2placement(ifcfile, (0.0, 0.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)) point_list_window_extrusion_area = [(0.0, -0.01, 0.0), (3.0, -0.01, 0.0), (3.0, 0.01, 0.0), (0.0, 0.01, 0.0), (0.0, -0.01, 0.0)] window_solid = create_ifcextrudedareasolid(ifcfile, point_list_window_extrusion_area, window_extrusion_placement, (0.0, 0.0, 1.0), 1.0) window_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "SweptSolid", [window_solid]) window_shape = ifcfile.createIfcProductDefinitionShape(None, None, [window_representation]) window = ifcfile.createIfcWindow(create_guid(), owner_history, "Window", "An awesome window", None, window_placement, window_shape, None, None) # Relate the window to the opening element ifcfile.createIfcRelFillsElement(create_guid(), owner_history, None, None, opening_element, window)
The wall and windows are related to building hierarchy and the file is written to disk
# Relate the window and wall to the building storey ifcfile.createIfcRelContainedInSpatialStructure(create_guid(), owner_history, "Building Storey Container", None, [wall, window], building_storey) # Write the contents of the file to disk ifcfile.write(filename)
Download source code
Download the full source code of this recipe here
Comments