Update doc code examples to use static functions

This commit is contained in:
Dion Moult
2024-06-28 12:54:14 +10:00
parent 07060fc769
commit 70bb0e5481
2 changed files with 110 additions and 87 deletions
@@ -178,18 +178,24 @@ Copy an entity instance is possible in different ways, depending on the task.
.. code-block:: python .. code-block:: python
wall_copy_class = ifcopenshell.api.run("root.copy_class", model, product = wall) import ifcopenshell.api.root
wall_copy_class = ifcopenshell.api.root.copy_class(model, product = wall)
This is high level and makes sensible assumptions about copying things like properties and quantities. It does not copy the element's representation, however. This is high level and makes sensible assumptions about copying things like properties and quantities. It does not copy the element's representation, however.
.. code-block:: python .. code-block:: python
import ifcopenshell.util.element
wall_shallow_copy = ifcopenshell.util.element.copy(model, wall) wall_shallow_copy = ifcopenshell.util.element.copy(model, wall)
This is for shallow copies. That is, associated things like the element's type, materials, and properties are not copied. The new element, however, has the same representation and placement as the original. This is for shallow copies. That is, associated things like the element's type, materials, and properties are not copied. The new element, however, has the same representation and placement as the original.
.. code-block:: python .. code-block:: python
import ifcopenshell.util.element
wall_deepgraph_copy = ifcopenshell.util.element.copy_deep(model, wall, exclude = None) wall_deepgraph_copy = ifcopenshell.util.element.copy_deep(model, wall, exclude = None)
This is for deep graph copy. Like shallow copy, it does not copy over things like associated type/properties/quantities, but it does copy the representation and placement. This is for deep graph copy. Like shallow copy, it does not copy over things like associated type/properties/quantities, but it does copy the representation and placement.
@@ -209,50 +215,55 @@ Create a simple model from scratch
.. code-block:: python .. code-block:: python
import ifcopenshell import ifcopenshell.api.root
from ifcopenshell.api import run import ifcopenshell.api.unit
import ifcopenshell.api.context
import ifcopenshell.api.project
import ifcopenshell.api.spatial
import ifcopenshell.api.geometry
import ifcopenshell.api.aggregate
# Create a blank model # Create a blank model
model = ifcopenshell.file() model = ifcopenshell.api.project.create_file()
# All projects must have one IFC Project element # All projects must have one IFC Project element
project = run("root.create_entity", model, ifc_class="IfcProject", name="My Project") project = ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject", name="My Project")
# Geometry is optional in IFC, but because we want to use geometry in this example, let's define units # Geometry is optional in IFC, but because we want to use geometry in this example, let's define units
# Assigning without arguments defaults to metric units # Assigning without arguments defaults to metric units
run("unit.assign_unit", model) ifcopenshell.api.unit.assign_unit(model)
# Let's create a modeling geometry context, so we can store 3D geometry (note: IFC supports 2D too!) # Let's create a modeling geometry context, so we can store 3D geometry (note: IFC supports 2D too!)
context = run("context.add_context", model, context_type="Model") context = ifcopenshell.api.context.add_context(model, context_type="Model")
# In particular, in this example we want to store the 3D "body" geometry of objects, i.e. the body shape # In particular, in this example we want to store the 3D "body" geometry of objects, i.e. the body shape
body = run("context.add_context", model, context_type="Model", body = ifcopenshell.api.context.add_context(model, context_type="Model",
context_identifier="Body", target_view="MODEL_VIEW", parent=context) context_identifier="Body", target_view="MODEL_VIEW", parent=context)
# Create a site, building, and storey. Many hierarchies are possible. # Create a site, building, and storey. Many hierarchies are possible.
site = run("root.create_entity", model, ifc_class="IfcSite", name="My Site") site = ifcopenshell.api.root.create_entity(model, ifc_class="IfcSite", name="My Site")
building = run("root.create_entity", model, ifc_class="IfcBuilding", name="Building A") building = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuilding", name="Building A")
storey = run("root.create_entity", model, ifc_class="IfcBuildingStorey", name="Ground Floor") storey = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey", name="Ground Floor")
# Since the site is our top level location, assign it to the project # Since the site is our top level location, assign it to the project
# Then place our building on the site, and our storey in the building # Then place our building on the site, and our storey in the building
run("aggregate.assign_object", model, relating_object=project, products=[site]) ifcopenshell.api.aggregate.assign_object(model, relating_object=project, products=[site])
run("aggregate.assign_object", model, relating_object=site, products=[building]) ifcopenshell.api.aggregate.assign_object(model, relating_object=site, products=[building])
run("aggregate.assign_object", model, relating_object=building, products=[storey]) ifcopenshell.api.aggregate.assign_object(model, relating_object=building, products=[storey])
# Let's create a new wall # Let's create a new wall
wall = run("root.create_entity", model, ifc_class="IfcWall") wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
# Give our wall a local origin at (0, 0, 0) # Give our wall a local origin at (0, 0, 0)
run("geometry.edit_object_placement", model, product=wall) ifcopenshell.api.geometry.edit_object_placement(model, product=wall)
# Add a new wall-like body geometry, 5 meters long, 3 meters high, and 200mm thick # Add a new wall-like body geometry, 5 meters long, 3 meters high, and 200mm thick
representation = run("geometry.add_wall_representation", model, context=body, length=5, height=3, thickness=0.2) representation = ifcopenshell.api.geometry.add_wall_representation(model, context=body, length=5, height=3, thickness=0.2)
# Assign our new body geometry back to our wall # Assign our new body geometry back to our wall
run("geometry.assign_representation", model, product=wall, representation=representation) ifcopenshell.api.geometry.assign_representation(model, product=wall, representation=representation)
# Place our wall in the ground floor # Place our wall in the ground floor
run("spatial.assign_container", model, relating_structure=storey, product=wall) ifcopenshell.api.spatial.assign_container(model, relating_structure=storey, product=wall)
# Write out to a file # Write out to a file
model.write("/home/dion/model.ifc") model.write("/home/dion/model.ifc")
@@ -268,27 +279,26 @@ Create a work schedule constructing a building floor by floor
.. code-block:: python .. code-block:: python
import datetime import datetime
import ifcopenshell import ifcopenshell.api.sequence
from ifcopenshell.api import run
from ifcopenshell.util.element import get_decomposition from ifcopenshell.util.element import get_decomposition
from ifcopenshell.util.placement import get_storey_elevation from ifcopenshell.util.placement import get_storey_elevation
# Define a convenience function to add a task chained to a predecessor # Define a convenience function to add a task chained to a predecessor
def add_task(model, name, predecessor, work_schedule): def add_task(model, name, predecessor, work_schedule):
# Add a construction task # Add a construction task
task = run("sequence.add_task", model, task = ifcopenshell.api.sequence.add_task(model,
work_schedule=work_schedule, name=name, predefined_type="CONSTRUCTION") work_schedule=work_schedule, name=name, predefined_type="CONSTRUCTION")
# Give it a time # Give it a time
task_time = run("sequence.add_task_time", model, task=task) task_time = ifcopenshell.api.sequence.add_task_time(model, task=task)
# Arbitrarily set the task's scheduled time duration to be 1 week # Arbitrarily set the task's scheduled time duration to be 1 week
run("sequence.edit_task_time", model, task_time=task_time, ifcopenshell.api.sequence.edit_task_time(model, task_time=task_time,
attributes={"ScheduleStart": datetime.date(2000, 1, 1), "ScheduleDuration": "P1W"}) attributes={"ScheduleStart": datetime.date(2000, 1, 1), "ScheduleDuration": "P1W"})
# If a predecessor exists, create a finish to start relationship # If a predecessor exists, create a finish to start relationship
if predecessor: if predecessor:
run("sequence.assign_sequence", model, relating_process=predecessor, related_process=task) ifcopenshell.api.sequence.assign_sequence(model, relating_process=predecessor, related_process=task)
return task return task
@@ -296,7 +306,7 @@ Create a work schedule constructing a building floor by floor
model = ifcopenshell.open("/path/to/existing/model.ifc") model = ifcopenshell.open("/path/to/existing/model.ifc")
# Create a new construction schedule # Create a new construction schedule
schedule = run("sequence.add_work_schedule", model, name="Construction") schedule = ifcopenshell.api.sequence.add_work_schedule(model, name="Construction")
# Let's imagine a starting task for site establishment. # Let's imagine a starting task for site establishment.
task = add_task(model, "Site establishment", None, schedule) task = add_task(model, "Site establishment", None, schedule)
@@ -313,16 +323,16 @@ Create a work schedule constructing a building floor by floor
# Assign all the products in that storey to the task as construction outputs. # Assign all the products in that storey to the task as construction outputs.
for product in get_decomposition(storey): for product in get_decomposition(storey):
run("sequence.assign_product", model, relating_product=product, related_object=task) ifcopenshell.api.sequence.assign_product(model, relating_product=product, related_object=task)
# Ask the computer to calculate all the dates for us from the start task. # Ask the computer to calculate all the dates for us from the start task.
# For example, if the first task started on the 1st of January and took a # For example, if the first task started on the 1st of January and took a
# week, the next task will start on the 8th of January. This saves us # week, the next task will start on the 8th of January. This saves us
# manually doing date calculations. # manually doing date calculations.
run("sequence.cascade_schedule", model, task=start_task) ifcopenshell.api.sequence.cascade_schedule(model, task=start_task)
# Calculate the critical path and floats. # Calculate the critical path and floats.
run("sequence.recalculate_schedule", model, work_schedule=schedule) ifcopenshell.api.sequence.recalculate_schedule(model, work_schedule=schedule)
# Write out to a file # Write out to a file
model.write("/home/dion/model.ifc") model.write("/home/dion/model.ifc")
@@ -87,17 +87,20 @@ might define units:
.. code-block:: python .. code-block:: python
import ifcopenshell.api.root
import ifcopenshell.api.unit
# You need a project before you can assign units. # You need a project before you can assign units.
run("root.create_entity", model, ifc_class="IfcProject") ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject")
# Let's say we want coordinates to be in millimeters. # Let's say we want coordinates to be in millimeters.
length = run("unit.add_si_unit", model, unit_type="LENGTHUNIT", prefix="MILLI") length = ifcopenshell.api.unit.add_si_unit(model, unit_type="LENGTHUNIT", prefix="MILLI")
run("unit.assign_unit", model, units=[length]) ifcopenshell.api.unit.assign_unit(model, units=[length])
# Alternatively, you may specify without any arguments to automatically # Alternatively, you may specify without any arguments to automatically
# create millimeters, square meters, and cubic meters as a convenience for # create millimeters, square meters, and cubic meters as a convenience for
# testing purposes. Sorry imperial folks, we prioritise metric here. # testing purposes. Sorry imperial folks, we prioritise metric here.
run("unit.assign_unit", model) ifcopenshell.api.unit.assign_unit(model)
Object placements Object placements
@@ -155,9 +158,11 @@ Here's how we might do the same operation with Python code:
.. code-block:: python .. code-block:: python
import numpy import numpy
import ifcopenshell.api.root
import ifcopenshell.api.geometry
# Create a wall. Our wall currently has no object placement or representations. # Create a wall. Our wall currently has no object placement or representations.
wall = run("root.create_entity", model, ifc_class="IfcWall") wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
# Create a 4x4 identity matrix. This matrix is at the origin with no rotation. # Create a 4x4 identity matrix. This matrix is at the origin with no rotation.
matrix = numpy.eye(4) matrix = numpy.eye(4)
@@ -172,7 +177,7 @@ Here's how we might do the same operation with Python code:
# Set our wall's Object Placement using our matrix. # Set our wall's Object Placement using our matrix.
# `is_si=True` states that we are using SI units instead of project units. # `is_si=True` states that we are using SI units instead of project units.
run("geometry.edit_object_placement", model, product=wall, matrix=matrix, is_si=True) ifcopenshell.api.geometry.edit_object_placement(model, product=wall, matrix=matrix, is_si=True)
Representation contexts Representation contexts
----------------------- -----------------------
@@ -220,48 +225,50 @@ MODEL_VIEW **Representation Context**.
.. code-block:: python .. code-block:: python
import ifcopenshell.api.context
# If we plan to store 3D geometry in our IFC model, we have to setup # If we plan to store 3D geometry in our IFC model, we have to setup
# a "Model" context. # a "Model" context.
model3d = run("context.add_context", model, context_type="Model") model3d = ifcopenshell.api.context.add_context(model, context_type="Model")
# And/Or, if we plan to store 2D geometry, we need a "Plan" context # And/Or, if we plan to store 2D geometry, we need a "Plan" context
plan = run("context.add_context", model, context_type="Plan") plan = ifcopenshell.api.context.add_context(model, context_type="Plan")
# Now we setup the subcontexts with each of the geometric "purposes" # Now we setup the subcontexts with each of the geometric "purposes"
# we plan to store in our model. "Body" is by far the most important # we plan to store in our model. "Body" is by far the most important
# and common context, as most IFC models are assumed to be viewable # and common context, as most IFC models are assumed to be viewable
# in 3D. # in 3D.
body = run("context.add_context", model, body = ifcopenshell.api.context.add_context(model,
context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model3d) context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model3d)
# The 3D Axis subcontext is important if any "axis-based" parametric # The 3D Axis subcontext is important if any "axis-based" parametric
# geometry is going to be created. For example, a beam, or column # geometry is going to be created. For example, a beam, or column
# may be drawn using a single 3D axis line, and for this we need an # may be drawn using a single 3D axis line, and for this we need an
# Axis subcontext. # Axis subcontext.
run("context.add_context", model, ifcopenshell.api.context.add_context(model,
context_type="Model", context_identifier="Axis", target_view="GRAPH_VIEW", parent=model3d) context_type="Model", context_identifier="Axis", target_view="GRAPH_VIEW", parent=model3d)
# It's also important to have a 2D Axis subcontext for things like # It's also important to have a 2D Axis subcontext for things like
# walls and claddings which can be drawn using a 2D axis line. # walls and claddings which can be drawn using a 2D axis line.
run("context.add_context", model, ifcopenshell.api.context.add_context(model,
context_type="Plan", context_identifier="Axis", target_view="GRAPH_VIEW", parent=plan) context_type="Plan", context_identifier="Axis", target_view="GRAPH_VIEW", parent=plan)
# The 3D Box subcontext is useful for clash detection or shape # The 3D Box subcontext is useful for clash detection or shape
# analysis, or even lazy-loading of large models. # analysis, or even lazy-loading of large models.
run("context.add_context", model, ifcopenshell.api.context.add_context(model,
context_type="Model", context_identifier="Box", target_view="MODEL_VIEW", parent=model3d) context_type="Model", context_identifier="Box", target_view="MODEL_VIEW", parent=model3d)
# A 2D annotation subcontext for plan views are important for door # A 2D annotation subcontext for plan views are important for door
# swings, window cuts, and symbols for equipment like GPOs, fire # swings, window cuts, and symbols for equipment like GPOs, fire
# extinguishers, and so on. # extinguishers, and so on.
run("context.add_context", model, ifcopenshell.api.context.add_context(model,
context_type="Plan", context_identifier="Annotation", target_view="PLAN_VIEW", parent=plan) context_type="Plan", context_identifier="Annotation", target_view="PLAN_VIEW", parent=plan)
# You may also create 2D annotation subcontexts for sections and # You may also create 2D annotation subcontexts for sections and
# elevation views. # elevation views.
run("context.add_context", model, ifcopenshell.api.context.add_context(model,
context_type="Plan", context_identifier="Annotation", target_view="SECTION_VIEW", parent=plan) context_type="Plan", context_identifier="Annotation", target_view="SECTION_VIEW", parent=plan)
run("context.add_context", model, ifcopenshell.api.context.add_context(model,
context_type="Plan", context_identifier="Annotation", target_view="ELEVATION_VIEW", parent=plan) context_type="Plan", context_identifier="Annotation", target_view="ELEVATION_VIEW", parent=plan)
Representations Representations
@@ -284,28 +291,34 @@ general pattern in code:
.. code-block:: python .. code-block:: python
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.api.context
import ifcopenshell.api.project
import ifcopenshell.api.geometry
# Let's create a new project using millimeters with a single furniture element at the origin. # Let's create a new project using millimeters with a single furniture element at the origin.
model = run("project.create_file") model = ifcopenshell.api.project.create_file
run("root.create_entity", model, ifc_class="IfcProject") ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject")
run("unit.assign_unit", model) ifcopenshell.api.unit.assign_unit(model)
# We want our representation to be the 3D body of the element. # We want our representation to be the 3D body of the element.
# This representation context is only created once per project. # This representation context is only created once per project.
# You must reuse the same body context every time you create a new representation. # You must reuse the same body context every time you create a new representation.
model3d = run("context.add_context", model, context_type="Model") model3d = ifcopenshell.api.context.add_context(model, context_type="Model")
body = run("context.add_context", model, body = ifcopenshell.api.context.add_context(model,
context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model3d) context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model3d)
# Create our element with an object placement. # Create our element with an object placement.
element = run("root.create_entity", model, ifc_class="IfcFurniture") element = ifcopenshell.api.root.create_entity(model, ifc_class="IfcFurniture")
run("geometry.edit_object_placement", model, product=element) ifcopenshell.api.geometry.edit_object_placement(model, product=element)
# Let's create our representation! # Let's create our representation!
# See below sections for examples on how to create representations. # See below sections for examples on how to create representations.
representation = ... representation = ...
# Assign our new body representation back to our element # Assign our new body representation back to our element
run("geometry.assign_representation", model, product=element, representation=representation) ifcopenshell.api.geometry.assign_representation(model, product=element, representation=representation)
Mesh representations Mesh representations
@@ -329,7 +342,7 @@ In IFC, meshes may be stored as **Faceted BReps**, **Tessellations**, or
# Note how they are nested lists. Each nested list represents a "mesh". There may be multiple meshes. # Note how they are nested lists. Each nested list represents a "mesh". There may be multiple meshes.
vertices = [[(0.,0.,0.), (0.,2.,0.), (2.,2.,0.), (2.,0.,0.), (1.,1.,1.)]] vertices = [[(0.,0.,0.), (0.,2.,0.), (2.,2.,0.), (2.,0.,0.), (1.,1.,1.)]]
faces = [[(0,1,2,3), (0,4,1), (1,4,2), (2,4,3), (3,4,0)]] faces = [[(0,1,2,3), (0,4,1), (1,4,2), (2,4,3), (3,4,0)]]
representation = run("geometry.add_mesh_representation", model, context=body, vertices=vertices, faces=faces) representation = ifcopenshell.api.geometry.add_mesh_representation(model, context=body, vertices=vertices, faces=faces)
.. image:: images/mesh-representation.png .. image:: images/mesh-representation.png
@@ -349,7 +362,7 @@ ends, cladding, and other uniformly thick blocks that extend along an imaginary
.. code-block:: python .. code-block:: python
# A wall-like representation, 5 meters long, 3 meters high, and 200mm thick # A wall-like representation, 5 meters long, 3 meters high, and 200mm thick
representation = run("geometry.add_wall_representation", model, representation = ifcopenshell.api.geometry.add_wall_representation(model,
context=body, length=5, height=3, thickness=0.2) context=body, length=5, height=3, thickness=0.2)
.. image:: images/wall-representation.png .. image:: images/wall-representation.png
@@ -363,7 +376,7 @@ rotation as appropriate. This can be done using the API:
.. code-block:: python .. code-block:: python
# A wall-like representation starting and ending at a particular 2D point # A wall-like representation starting and ending at a particular 2D point
representation = run("geometry.create_2pt_wall", model, representation = ifcopenshell.api.geometry.create_2pt_wall(model,
element=element, context=body, p1=(1., 1.), p2=(3., 2.), elevation=0, height=3, thickness=0.2) element=element, context=body, p1=(1., 1.), p2=(3., 2.), elevation=0, height=3, thickness=0.2)
.. image:: images/wall-2pt-representation.png .. image:: images/wall-2pt-representation.png
@@ -465,7 +478,7 @@ Placement** to place the element on its side.
.. code-block:: python .. code-block:: python
# A profile-based representation, 1 meter long # A profile-based representation, 1 meter long
representation = run("geometry.add_profile_representation", model, context=body, profile=profile, depth=1) representation = ifcopenshell.api.geometry.add_profile_representation(model, context=body, profile=profile, depth=1)
.. image:: images/profile-representation.png .. image:: images/profile-representation.png
@@ -633,22 +646,22 @@ efficient and implies that the type is interchangable (e.g. for maintenance).
.. code-block:: python .. code-block:: python
# Create our element type. Types do not have an object placement. # Create our element type. Types do not have an object placement.
element_type = run("root.create_entity", model, ifc_class="IfcFurnitureType") element_type = ifcopenshell.api.root.create_entity(model, ifc_class="IfcFurnitureType")
# Let's create our representation! # Let's create our representation!
# See above sections for examples on how to create representations. # See above sections for examples on how to create representations.
representation = ... representation = ...
# Assign our representation to the element type. # Assign our representation to the element type.
run("geometry.assign_representation", model, product=element_type, representation=representation) ifcopenshell.api.geometry.assign_representation(model, product=element_type, representation=representation)
# Create our element occurrence with an object placement. # Create our element occurrence with an object placement.
element = run("root.create_entity", model, ifc_class="IfcFurniture") element = ifcopenshell.api.root.create_entity(model, ifc_class="IfcFurniture")
run("geometry.edit_object_placement", model, product=element) ifcopenshell.api.geometry.edit_object_placement(model, product=element)
# Assign our furniture occurrence to the type. # Assign our furniture occurrence to the type.
# That's it! The representation will automatically be mapped! # That's it! The representation will automatically be mapped!
run("type.assign_type", model, related_objects=[element], relating_type=element_type) ifcopenshell.api.type.assign_type(model, related_objects=[element], relating_type=element_type)
Material layer sets Material layer sets
------------------- -------------------
@@ -667,42 +680,42 @@ responsibility to make sure the geometry is correct.
.. code-block:: python .. code-block:: python
# Let's imagine a wall type called WAL01 using a material layer set. # Let's imagine a wall type called WAL01 using a material layer set.
wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name="WAL01") wall_type = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWallType", name="WAL01")
# First, let's create a material set. This will later be assigned to our wall type element. # First, let's create a material set. This will later be assigned to our wall type element.
material_set = ifcopenshell.api.run("material.add_material_set", model, material_set = ifcopenshell.api.material.add_material_set(model,
name="GYP-ST-GYP", set_type="IfcMaterialLayerSet") name="GYP-ST-GYP", set_type="IfcMaterialLayerSet")
# Let's create a few materials. # Let's create a few materials.
gypsum = ifcopenshell.api.run("material.add_material", model, name="PB01", category="gypsum") gypsum = ifcopenshell.api.material.add_material(model, name="PB01", category="gypsum")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel") steel = ifcopenshell.api.material.add_material(model, name="ST01", category="steel")
# Create 3 layers for a steel studded plasterboard wall. # Create 3 layers for a steel studded plasterboard wall.
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum) layer = ifcopenshell.api.material.add_layer(model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13}) ifcopenshell.api.material.edit_layer(model, layer=layer, attributes={"LayerThickness": 13})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel) layer = ifcopenshell.api.material.add_layer(model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 92}) ifcopenshell.api.material.edit_layer(model, layer=layer, attributes={"LayerThickness": 92})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum) layer = ifcopenshell.api.material.add_layer(model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13}) ifcopenshell.api.material.edit_layer(model, layer=layer, attributes={"LayerThickness": 13})
# Great! Let's assign our material set to our wall type. # Great! Let's assign our material set to our wall type.
ifcopenshell.api.run("material.assign_material", model, products=[wall_type], material=material_set) ifcopenshell.api.material.assign_material(model, products=[wall_type], material=material_set)
# Now, let's create a wall at the origin. # Now, let's create a wall at the origin.
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall") wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall) ifcopenshell.api.geometry.edit_object_placement(model, product=wall)
# The wall is a WAL01 wall type. The material layer set is inherited. # The wall is a WAL01 wall type. The material layer set is inherited.
ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type) ifcopenshell.api.type.assign_type(model, related_objects=[wall], relating_type=wall_type)
# It's now our responsibility to create a compatible representation. # It's now our responsibility to create a compatible representation.
# Notice how our thickness of 0.118 must equal .013 + .092 + .013 from our type # Notice how our thickness of 0.118 must equal .013 + .092 + .013 from our type
body = ifcopenshell.util.representation.get_context(model, "Model", "Body", "MODEL_VIEW") body = ifcopenshell.util.representation.get_context(model, "Model", "Body", "MODEL_VIEW")
representation = ifcopenshell.api.run("geometry.add_wall_representation", model, representation = ifcopenshell.api.geometry.add_wall_representation(model,
context=body, length=5, height=3, thickness=0.118) context=body, length=5, height=3, thickness=0.118)
# Assign our new body geometry back to our wall # Assign our new body geometry back to our wall
ifcopenshell.api.run("geometry.assign_representation", model, product=wall, representation=representation) ifcopenshell.api.geometry.assign_representation(model, product=wall, representation=representation)
Material profile sets Material profile sets
--------------------- ---------------------
@@ -721,14 +734,14 @@ responsibility to make sure the geometry is correct.
.. code-block:: python .. code-block:: python
# Let's imagine we have a steel I-beam type called B1. # Let's imagine we have a steel I-beam type called B1.
beam_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBeamType", name="B1") beam_type = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBeamType", name="B1")
# First, let's create a material set. This will later be assigned to our beam type element. # First, let's create a material set. This will later be assigned to our beam type element.
material_set = ifcopenshell.api.run("material.add_material_set", model, material_set = ifcopenshell.api.material.add_material_set(model,
name="B1", set_type="IfcMaterialProfileSet") name="B1", set_type="IfcMaterialProfileSet")
# Create a steel material. # Create a steel material.
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel") steel = ifcopenshell.api.material.add_material(model, name="ST01", category="steel")
# Create an I-beam profile curve. Notice how we use standardised steel profile names. # Create an I-beam profile curve. Notice how we use standardised steel profile names.
hea100 = model.create_entity( hea100 = model.create_entity(
@@ -739,22 +752,22 @@ responsibility to make sure the geometry is correct.
# Define that steel material and cross section as a single profile item. If # Define that steel material and cross section as a single profile item. If
# this were a composite beam, we might add multiple profile items instead, # this were a composite beam, we might add multiple profile items instead,
# but this is rarely the case in most construction. # but this is rarely the case in most construction.
ifcopenshell.api.run("material.add_profile", model, profile_set=material_set, material=steel, profile=hea100) ifcopenshell.api.material.add_profile(model, profile_set=material_set, material=steel, profile=hea100)
# Great! Let's assign our material set to our beam type. # Great! Let's assign our material set to our beam type.
ifcopenshell.api.run("material.assign_material", model, products=[beam_type], material=material_set) ifcopenshell.api.material.assign_material(model, products=[beam_type], material=material_set)
# Now, let's create a beam at the origin. # Now, let's create a beam at the origin.
beam = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBeam") beam = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBeam")
ifcopenshell.api.run("geometry.edit_object_placement", model, product=beam) ifcopenshell.api.geometry.edit_object_placement(model, product=beam)
# The beam is a B1 beam type. The material profile set is inherited. # The beam is a B1 beam type. The material profile set is inherited.
ifcopenshell.api.run("type.assign_type", model, related_objects=[beam], relating_type=beam_type) ifcopenshell.api.type.assign_type(model, related_objects=[beam], relating_type=beam_type)
# It's now our responsibility to create a compatible representation. # It's now our responsibility to create a compatible representation.
# Notice how we reuse our profile instead of creating a new profile. # Notice how we reuse our profile instead of creating a new profile.
body = ifcopenshell.util.representation.get_context(model, "Model", "Body", "MODEL_VIEW") body = ifcopenshell.util.representation.get_context(model, "Model", "Body", "MODEL_VIEW")
representation = run("geometry.add_profile_representation", model, context=body, profile=hea100, depth=1) representation = geometry.add_profile_representation(model, context=body, profile=hea100, depth=1)
# Assign our new body geometry back to our beam # Assign our new body geometry back to our beam
ifcopenshell.api.run("geometry.assign_representation", model, product=beam, representation=representation) ifcopenshell.api.geometry.assign_representation(model, product=beam, representation=representation)