Add API documentation for the material module

This commit is contained in:
Dion Moult
2022-12-07 17:30:08 +11:00
parent 7da3d9ee70
commit cf87852d9c
23 changed files with 1129 additions and 90 deletions
@@ -18,11 +18,68 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, constituent_set=None, material=None):
"""Adds a new constituent to a constituent set
A constituent describes how a portion of an object is made out of a
material whereas other portions of the object is made out of other
materials. For example, a window might be made out of an aluminium frame
and a glass panel. The aluminium used for the frame is one constituent
of the material, and glass would be another constituent. Another example
might be concrete, where one constituent might be cement, and another
constituent might be binder. In the case of the window, the constituent
is represented explicitly by the geometry of the window frame and the
geometry of the window panel. In the case of a concrete slab, the
constituents might be represented in terms of percentages.
Constituents are not available in IFC2X3.
:param constituent_set: The IfcMaterialConstituentSet that the
constituent is part of. The constituent set represents a group of
constituents. See ifcopenshell.api.material.add_material_set for
information on how to add a constituent set.
:type constituent_set: ifcopenshell.entity_instance.entity_instance
:param material: The IfcMaterial that the constituent is made out of.
:type material: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcMaterialConstituent
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Let's imagine we have a window type that has an aluminium frame
# and a glass glazing panel. Notice we are assigning to the type
# only, as all occurrences of that type will automatically inherit
# the material.
window_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWindowType")
# First, let's create a constituent set. This will later be assigned
# to our window element.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialConstituentSet")
# Let's create a few materials, it's important to also give them
# categories. This makes it easy for model recipients to do things
# like "show me everything made out of aluminium / concrete / steel
# / glass / etc". The IFC specification states a list of categories
# you can use.
aluminium = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
glass = ifcopenshell.api.run("material.add_material", model, name="GLZ01", category="glass")
# Now let's use those materials as two constituents in our set.
ifcopenshell.api.run("material.add_constituent", model,
constituent_set=material_set, material=aluminium)
ifcopenshell.api.run("material.add_constituent", model,
constituent_set=material_set, material=glass)
# Great! Let's assign our material set to our window type.
# We're technically not done here, we might want to add geometry to
# our window too, but to keep this example simple, geometry is
# optional and it is enough to say that this window is made out of
# aluminium and glass.
ifcopenshell.api.run("material.assign_material", model, product=window_type, material=material_set)
"""
self.file = file
self.settings = {"constituent_set": None, "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"constituent_set": constituent_set, "material": material}
def execute(self):
constituents = list(self.settings["constituent_set"].MaterialConstituents or [])
@@ -18,11 +18,66 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, layer_set=None, material=None):
"""Adds a new layer to a layer set
A layer represents a portion of material within a layered build up,
defined by a thickness. Typical layered construction includes walls and
slabs, where a wall might include a layer of finish, a layer of
structure, a layer of insulation, and so on. It is recommended to define
layered construction this way where it is unnecessary to define the
exact geometry of how the wall or slab will be built, and it will
instead be determined on site by a trade.
Layers are defined in a particular order and thickness, so that it is
clear which layer comes next.
:param layer_set: The IfcMaterialLayerSet that the layer is part of. The
layer set represents a group of layers. See
ifcopenshell.api.material.add_material_set for more information on
how to add a layer set.
:type layer_set: ifcopenshell.entity_instance.entity_instance
:param material: The IfcMaterial that the layer is made out of.
:type material: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcMaterialLayer
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Let's imagine we have a wall type that has two layers of
# gypsum with steel studs inside. Notice we are assigning to
# the type only, as all occurrences of that type will automatically
# inherit the material.
wall_type = ifcopenshell.api.run("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.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="GYP-ST-GYP", set_type="IfcMaterialLayerSet")
# Let's create a few materials, it's important to also give them
# categories. This makes it easy for model recipients to do things
# like "show me everything made out of aluminium / concrete / steel
# / glass / etc". The IFC specification states a list of categories
# you can use.
gypsum = ifcopenshell.api.run("material.add_material", model, name="PB01", category="gypsum")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Now let's use those materials as three layers in our set, such
# that the steel studs are sandwiched by the gypsum. Let's imagine
# we're setting the layer thickness in millimeters.
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 92})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13})
# Great! Let's assign our material set to our wall type.
ifcopenshell.api.run("material.assign_material", model, product=wall_type, material=material_set)
"""
self.file = file
self.settings = {"layer_set": None, "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"layer_set": layer_set, "material": material}
def execute(self):
layers = list(self.settings["layer_set"].MaterialLayers or [])
@@ -20,11 +20,65 @@ import ifcopenshell
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material_list=None, material=None):
"""Adds a new material in a list of materials
In IFC2X3, if you wanted an object to have multiple materials (i.e. a
composite material) you would assign the object to a material list,
which would contain a list of materials. For example, a window might
have a list of 2 materials, one being aluminium for the frame, and
another being glass for the panel.
In IFC4 and above, this is deprecated and should not be used. Instead,
you should use constituent sets instead, which achieve the same thing
but are more powerful as they allow you to define the properties of the
constituents too.
However if you're stuck on IFC2X3, you have my condolences as well as
this function.
:param material_list: The IfcMaterialList the material should be added
to.
:type material_list: ifcopenshell.entity_instance.entity_instance
:param material: The IfcMaterial to add to the list
:type material: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Let's imagine we have a window type that has an aluminium frame
# and a glass glazing panel. Notice we are assigning to the type
# only, as all occurrences of that type will automatically inherit
# the material.
window_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWindowType")
# First, let's create a list. This will later be assigned to our
# window element.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialList")
# Let's create a few materials, it's important to also give them
# categories. This makes it easy for model recipients to do things
# like "show me everything made out of aluminium / concrete / steel
# / glass / etc". The IFC specification states a list of categories
# you can use.
aluminium = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
glass = ifcopenshell.api.run("material.add_material", model, name="GLZ01", category="glass")
# Now let's use those materials as two items in our list.
ifcopenshell.api.run("material.add_list_item", model, material_list=material_set, material=aluminium)
ifcopenshell.api.run("material.add_list_item", model, material_list=material_set, material=glass)
# Great! Let's assign our material set to our window type.
# We're technically not done here, we might want to add geometry to
# our window too, but to keep this example simple, geometry is
# optional and it is enough to say that this window is made out of
# aluminium and glass.
ifcopenshell.api.run("material.assign_material", model, product=window_type, material=material_set)
"""
self.file = file
self.settings = {"material_list": None, "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"material_list": material_list, "material": material}
def execute(self):
materials = list(self.settings["material_list"].Materials or [])
@@ -18,11 +18,61 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, name=None, category=None):
"""Adds a new material
A material in IFC represents a physical material, such as timber, steel,
concrete, aluminium, etc. It may also contain physical properties used
for structural or lighting simulation. Note that unlike the computer
graphics industry, a material by itself does not define any colour or
lighting information. Colours in IFC are known as "styles", and an IFC
material may or may not have any style information associated with it.
See ifcopenshell.api.style for more information.
A material is typically given a code name which is used by architects in
elevations and details when tagging finishes. Materials are also useful
to structural engineers in specifying the exact types of concrete and
steel to be used in structural simulations.
In addition, materials can belong to a category. Specifying this
category is critical to allow model recipients to make simple queries
like "show me all concrete / steel" elements in the model. Without
standardised category naming of all materials, this type of query
becomes a bespoke and inefficient task. A list of categories are:
'concrete', 'steel', 'aluminium', 'block', 'brick', 'stone', 'wood',
'glass', 'gypsum', 'plastic', and 'earth'. The user is allowed to
specify their own category instead if none of these categories are
appropriate.
Note that categories are not available in IFC2X3. This shortcoming is
one of the big reasons projects should upgrade to IFC4.
:param name: The name of the material, typically tagged in a finishes
drawing or schedule.
:type name: str
:param category: The category of the material.
:type category: str, optional
:return: The newly created IfcMaterial
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Let's create two materials with their respective categories
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Let's imagine an urban concrete bench which is purely made out of concrete
concrete_bench = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurnitureType")
# Assign the concrete material to that bench. Note that no colour
# "Style" has been specified.
ifcopenshell.api.run("material.assign_material", model, product=concrete_bench, material=concrete)
"""
self.file = file
self.settings = {"name": "Unnamed"}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"name": name or "Unnamed", "category": category}
def execute(self):
return self.file.create_entity("IfcMaterial", **{"Name": self.settings["name"] or "Unnamed"})
material = self.file.create_entity("IfcMaterial", **{"Name": self.settings["name"] or "Unnamed"})
if self.settings["category"]:
material.Category = self.settings["category"]
return material
@@ -18,11 +18,90 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, name="Unnamed", set_type="IfcMaterialConstituentSet"):
"""Adds a new material set
IFC allows you to state that objects are made out of multiple materials.
These are known generically as material sets, but may also be called
layered materials, composite materials, or other names in software.
There are three types of material sets:
- A layer set, used for layered construction such as walls, where the
element is parametrically made out of extruded layers, each layer
having a thickness defined. Even though this is known as a layer
"set" it is still recommended to use it for all standared layered
construction as it describes the intent of the element to be layered
construction and thus can be used for parametric editing.
- A profile set, used for profiled construction such as beams or
columns, where the element is parametrically made out of one or more
extruded profiles, where each profile may be parametric from a
standard section (e.g. standardised steel profile) or an arbitrary
shape (e.g. cold rolled sections, or skirtings, moldings, etc). Note
that even though this is called a profile "set", it should still be
used even if there is only a single profile. This is not available in
IFC2X3.
- A constituent set, used for arbitrary composite construction where
the object is made out of multiple materials. The constituents may be
explicitly defined via a shape, such as a window where the frame
geometry is made from one material and the panel geometry is made
from another material. Alternatively, the constituents may be
represented in terms of percentages, such as in mixtures like
concrete where there might be a percentage constituent of cement and
another percentage constituent of binder. This is not available in
IFC2X3.
There is also a fourth material set known as a material list, which is a
legacy type of set used by IFC2X3. It should not be used on IFC4 and
above, and constituent sets should be used instead.
:param name: The name of the material set, which may be purely
descriptive or annotated in drawings. Defaults to "Unnamed".
:type name: str, optional
:param set_type: What type of set you want to create, chosen from
IfcMaterialLayerSet, IfcMaterialProfileSet,
IfcMaterialConstituentSet, or IfcMaterialList. Defaults to
IfcMaterialConstituentSet.
:type set_type: str, optional
:return: The newly created material set element
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Let's imagine we have a wall type that has two layers of
# gypsum with steel studs inside. Notice we are assigning to
# the type only, as all occurrences of that type will automatically
# inherit the material.
wall_type = ifcopenshell.api.run("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.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="GYP-ST-GYP", set_type="IfcMaterialLayerSet")
# Let's create a few materials, it's important to also give them
# categories. This makes it easy for model recipients to do things
# like "show me everything made out of aluminium / concrete / steel
# / glass / etc". The IFC specification states a list of categories
# you can use.
gypsum = ifcopenshell.api.run("material.add_material", model, name="PB01", category="gypsum")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Now let's use those materials as three layers in our set, such
# that the steel studs are sandwiched by the gypsum. Let's imagine
# we're setting the layer thickness in millimeters.
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 92})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13})
# Great! Let's assign our material set to our wall type.
ifcopenshell.api.run("material.assign_material", model, product=wall_type, material=material_set)
"""
self.file = file
self.settings = {"name": "Unnamed", "set_type": "IfcMaterialConstituentSet"}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"name": name or "Unnamed", "set_type": set_type or "IfcMaterialConstituentSet"}
def execute(self):
if self.settings["set_type"] == "IfcMaterialLayerSet":
@@ -18,11 +18,69 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, profile_set=None, material=None, profile=None):
"""Add a new profile item to a profile set
A profile item in a profile set represents an extruded 2D profile curve
that is extruded along the axis of the element. Most commonly there will
only be a single profile item in a profile set. For example, a beam will
have a material profile set containing a single profile item, which may
have a steel material and a I-beam shaped profile curve.
Note that the "profile item" represents a single extrusion in the
profile set, whereas the "profile curve" represents a 2D curve used by a
"profile item".
In some cases, a profiled element (i.e. beam, column) may be a composite
beam or column and include multiple extrusions. This is rare. The order
of the profiles does not matter.
:param profile_set: The IfcMaterialProfileSet that the profile is part of. The
profile set represents a group of profile items. See
ifcopenshell.api.material.add_material_set for more information on
how to add a profile set.
:type profile_set: ifcopenshell.entity_instance.entity_instance
:param material: The IfcMaterial that the profile item is made out of.
:type material: ifcopenshell.entity_instance.entity_instance
:param profile: The IfcProfileDef that represents the 2D cross section
of the the profile item.
:type profile: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcMaterialProfile
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Let's imagine we have a steel I-beam. Notice we are assigning to
# the type only, as all occurrences of that type will automatically
# inherit the material.
beam_type = ifcopenshell.api.run("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.
material_set = ifcopenshell.api.run("material.add_profile_set", model,
name="B1", set_type="IfcMaterialProfileSet")
# Create a steel material.
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Create an I-beam profile curve. Notice how we name our profiles
# based on standardised steel profile names.
hea100 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA100", ProfileType="AREA",
OverallWidth=100, OverallDepth=96, WebThickness=5, FlangeThickness=8, FilletRadius=12,
)
# 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, but this is rarely the case in most construction.
ifcopenshell.api.run("material.add_profile", model,
profile_set=material_set, material=steel, profile=hea100)
# Great! Let's assign our material set to our beam type.
ifcopenshell.api.run("material.assign_material", model, product=beam_type, material=material_set)
"""
self.file = file
self.settings = {"profile_set": None, "material": None, "profile": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"profile_set": profile_set, "material": material, "profile": profile}
def execute(self):
profiles = list(self.settings["profile_set"].MaterialProfiles or [])
@@ -23,17 +23,119 @@ import ifcopenshell.util.representation
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, product=None, type="IfcMaterial", material=None):
"""Assigns a material to a product
When a material is assigned to a product, it means that the product is
made out of that material. In its simplest form, a single material may
be assigned to a product, meaning that the entire product is made out of
that one material. Alternatively, a material set may be assigned to a
product, meaning that the product is made out of a set of materials.
There are three types of sets, including layered construction, profiled
materials, and arbitrary material constituents. See
ifcopenshell.api.material.add_material_set for details.
Materials are typically assigned to the element types rather than
individual occurrences of elements. Individual occurrences would then
inherit the material from the type.
If the type has a material set, then the geometry of the occurrences
must comply with the material set. For example, if the type has a
constituent set, then it is expected that all occurrences also inherit
the geometry of the type, which is made out of those constituents.
Alternatively, if the type has a layer set, then all occurrences must
have geometry that has a thickness equal to the sum of all layers. If a
type has a profile set, then all occurrences must has the same profile
extruded along its axis.
For layers and profiles assigned to types, the occurrences must be
assigned an IfcMaterialLayerSetUsage or an IfcMaterialProfileSetUsage.
This allows individual occurrences to override the layered or profiled
construction offset from a reference line.
:param product: The IfcProduct to assign the material or material set
to.
:type product: ifcopenshell.entity_instance.entity_instance
:param type: Choose from "IfcMaterial", "IfcMaterialConstituentSet",
"IfcMaterialLayerSet", "IfcMaterialLayerSetUsage",
"IfcMaterialProfileSet", "IfcMaterialProfileSetUsage", or
"IfcMaterialList". Note that "Set Usages" may only be assigned to
occurrences, not types.
:type type: str
:param material: The IfcMaterial or material set you are assigning here.
:type material: ifcopenshell.entity_instance.entity_instance
:return: The IfcRelAssociatesMaterial entity
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Let's start with a simple concrete material
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
# Let's imagine a concrete bench made out of a single concrete
# material. Let's assign it to the type.
bench_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurnitureType")
ifcopenshell.api.run("material.assign_material", model,
product=bench_type, type="IfcMaterial", material=concrete)
# Let's imagine there are a two occurrences of this bench. It's not
# necessary to assign any material to these benches as they
# automatically inherit the material from the type.
bench1 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
bench2 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
ifcopenshell.api.run("type.assign_type", model, related_object=bench1, relating_type=bench_type)
ifcopenshell.api.run("type.assign_type", model, related_object=bench2, relating_type=bench_type)
# If we have a concrete wall, we should use a layer set. Again,
# let's start with a wall type, not occurrences.
wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name="WAL01")
# Even though there is only one layer in our layer set, we still use
# a layer set because it makes it clear that this is a layered
# construction. Let's say it's a 200mm thick concrete layer.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="CON200", set_type="IfcMaterialLayerSet")
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 200})
# Our wall type now has the layer set assigned to it
ifcopenshell.api.run("material.assign_material", model,
product=wall_type, type="IfcMaterialLayerSet", material=material_set)
# Let's imagine an occurrence of this wall type.
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type)
# Our wall occurrence needs to have a "set usage" which describes
# how the layers relate to a reference line (typically a 2D line
# representing the extents of the wall). Usages are special since
# they automatically detect the inherited material set from the
# type. You'd write similar code for a profile set.
ifcopenshell.api.run("material.assign_material", model,
product=wall, type="IfcMaterialLayerSetUsage")
# To be complete, let's create the wall's axis and body
# representation. Notice how the axis guides the walls "reference
# line" which determines where layers are extruded from, and the
# body has a thickness of 200mm, same as our total layer set
# thickness.
axis = ifcopenshell.api.run("geometry.add_axis_representation", model,
context=axis_context, axis=[(0.0, 0.0), (5000.0, 0.0)])
body = ifcopenshell.api.run("geometry.add_wall_representation", model,
context=body_context, length=5000, height=3000, thickness=200)
ifcopenshell.api.run("geometry.assign_representation", model, product=wall, representation=axis)
ifcopenshell.api.run("geometry.assign_representation", model, product=wall, representation=body)
"""
self.file = file
self.settings = {"product": None, "type": "IfcMaterial", "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"product": product, "type": type, "material": material}
def execute(self):
material = ifcopenshell.util.element.get_material(self.settings["product"])
if material:
ifcopenshell.api.run("material.unassign_material", self.file, product=self.settings["product"])
if self.settings["type"] == "IfcMaterial":
if self.settings["type"] == "IfcMaterial" or (
self.settings["material"] and not self.settings["material"].is_a("IfcMaterial")
):
return self.assign_ifc_material()
elif self.settings["type"] == "IfcMaterialConstituentSet":
material_set = self.file.create_entity(self.settings["type"])
@@ -20,11 +20,73 @@ import ifcopenshell.util.representation
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material_profile=None, profile=None):
"""Changes the profile curve of a material profile item in a profile set
In addition to changing the profile curve, it will also change the
profile curve used in any body representation extrusions.
:param material_profile: The IfcMaterialProfile to change the profile
curve of. See ifcopenshell.api.material.add_profile to see how to
create profiles.
:type material_profile: ifcopenshell.entity_instance.entity_instance
:param profile: The IfcProfileDef to set the profile item's curve to.
:type profile: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Let's imagine we have a steel I-beam. Notice we are assigning to
# the type only, as all occurrences of that type will automatically
# inherit the material.
beam_type = ifcopenshell.api.run("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.
material_set = ifcopenshell.api.run("material.add_profile_set", model,
name="B1", set_type="IfcMaterialProfileSet")
# Create a steel material.
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Create an I-beam profile curve. Notice how we name our profiles
# based on standardised steel profile names.
hea100 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA100", ProfileType="AREA",
OverallWidth=100, OverallDepth=96, WebThickness=5, FlangeThickness=8, FilletRadius=12,
)
# 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, but this is rarely the case in most construction.
profile_item = ifcopenshell.api.run("material.add_profile", model,
profile_set=material_set, material=steel, profile=hea100)
# Great! Let's assign our material set to our beam type.
ifcopenshell.api.run("material.assign_material", model, product=beam_type, material=material_set)
# Let's create an occurrence of this beam.
beam = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBeam", name="B1.01")
ifcopenshell.api.run("material.assign_material", model,
product=beam, type="IfcMaterialProfileSetUsage")
# Let's give a 1000mm long beam body representation.
body = ifcopenshell.api.run("geoemtry.add_profile_representation",
context=body_context, profile=hea100, depth=1000)
ifcopenshell.api.run("geometry.assign_representation", model, product=beam, representation=body)
# Now let's change the profile to a HEA200 standard profile instead.
# This will automatically change the body representation that we
# just added as well to a HEA200 profile.
hea200 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA200", ProfileType="AREA",
OverallWidth=200, OverallDepth=190, WebThickness=6.5, FlangeThickness=10, FilletRadius=18,
)
ifcopenshell.api.run("material.assign_profile", model, material_profile=profile_item, profile=hea200)
"""
self.file = file
self.settings = {"material_profile": None, "profile": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"material_profile": material_profile, "profile": profile}
def execute(self):
# TODO: handle composite profiles
@@ -21,9 +21,46 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material=None, element=None):
"""Copies a material to an element
This convenience function exists to allow you to easily unassign any
existing material an element has, and assign a new material to it.
Essentially, it is a form a copy / pasting a material from one element
to another.
It's a bit out of place, and will likely be redesigned or removed in the
future. It's not recommended to use this function, and
ifcopenshell.api.material.assign_material should be used instead.
:param material: The IfcMaterial to assign to the element.
:type material: ifcopenshell.entity_instance.entity_instance
:param element: The IfcElement or IfcElementType to remove all previous
materials from and assign the new material to.
:type element: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
wood = ifcopenshell.api.run("material.add_material", model, name="TIM01", category="wood")
# Let's imagine a concrete bench made out of concrete.
bench = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
ifcopenshell.api.run("material.assign_material", model,
product=bench, type="IfcMaterial", material=concrete)
# And some street furniture made from wood.
street_furniture = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
ifcopenshell.api.run("material.assign_material", model,
product=street_furniture, type="IfcMaterial", material=wood)
# Let's copy the concrete over to the street furniture.
ifcopenshell.api.run("material.copy_material", model, material=wood, element=street_furniture)
"""
self.file = file
self.settings = {"material": None, "element": None}
self.settings = {"material": material, "element": element}
for key, value in settings.items():
self.settings[key] = value
@@ -18,11 +18,27 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, element=None, attributes=None):
"""Edits the attributes of an IfcMaterial
For more information about the attributes and data types of an
IfcMaterial, consult the IFC documentation.
:param element: The IfcMaterial entity you want to edit
:type element: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
ifcopenshell.api.run("material.edit_assigned_material", model,
element=concrete, attributes={"Description": "40MPA concrete with broom finish"})
"""
self.file = file
self.settings = {"element": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"element": element, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,47 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, constituent=None, attributes=None, material=None):
"""Edits the attributes of an IfcMaterialConstituent
For more information about the attributes and data types of an
IfcMaterialConstituent, consult the IFC documentation.
:param constituent: The IfcMaterialConstituent entity you want to edit
:type constituent: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:param material: The IfcMaterial entity you want to change the constituent to
:type material: ifcopenshell.entity_instance.entity_instance, optional
:return: None
:rtype: None
Example::
# Let's add two materials
aluminium1 = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
aluminium2 = ifcopenshell.api.run("material.add_material", model, name="AL02", category="aluminium")
glass = ifcopenshell.api.run("material.add_material", model, name="GLZ01", category="glass")
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialConstituentSet")
# Set up two constituents, one for the frame and the other for the glazing.
framing = ifcopenshell.api.run("material.add_constituent", model,
constituent_set=material_set, material=aluminium1)
glazing = ifcopenshell.api.run("material.add_constituent", model,
constituent_set=material_set, material=glass)
# Let's make sure this constituent refers to the framing of the
# window and uses the second aluminium material instead.
ifcopenshell.api.run("material.edit_constituent", model,
constituent=framing, attributes={"Name": "Framing"}, material=aluminium2)
ifcopenshell.api.run("material.edit_constituent", model,
constituent=constituent, attributes={"Name": "Glazing"})
"""
self.file = file
self.settings = {"constituent": None, "attributes": {}, "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"constituent": constituent, "attributes": attributes or {}, "material": material}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,45 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, layer=None, attributes=None, material=None):
"""Edits the attributes of an IfcMaterialLayer
For more information about the attributes and data types of an
IfcMaterialLayer, consult the IFC documentation.
:param layer: The IfcMaterialLayer entity you want to edit
:type layer: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:param material: The IfcMaterial entity you want the layer to be made
from.
:type material: ifcopenshell.entity_instance.entity_instance, optional
:return: None
:rtype: None
Example::
# Let's create two materials typically used for steel stud partition
# walls with gypsum lining.
gypsum = ifcopenshell.api.run("material.add_material", model, name="PB01", category="gypsum")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Create a material layer set to contain our layers.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="GYP-ST-GYP", set_type="IfcMaterialLayerSet")
# Now let's use those materials as three layers in our set, such
# that the steel studs are sandwiched by the gypsum. Let's imagine
# we're setting the layer thickness in millimeters.
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 92})
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 13})
"""
self.file = file
self.settings = {"layer": None, "attributes": {}, "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"layer": layer, "attributes": attributes or {}, "material": material}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,62 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, usage=None, attributes=None):
"""Edits the attributes of an IfcMaterialLayerSetUsage
This is typically used to change the offset from the reference line to
the layers.
For more information about the attributes and data types of an
IfcMaterialLayerSetUsage, consult the IFC documentation.
:param usage: The IfcMaterialLayerSetUsage entity you want to edit
:type usage: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
# Let's start with a simple concrete material
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
# If we have a concrete wall, we should use a layer set. Again,
# let's start with a wall type, not occurrences.
wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name="WAL01")
# Even though there is only one layer in our layer set, we still use
# a layer set because it makes it clear that this is a layered
# construction. Let's say it's a 200mm thick concrete layer.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="CON200", set_type="IfcMaterialLayerSet")
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer, attributes={"LayerThickness": 200})
# Our wall type now has the layer set assigned to it
ifcopenshell.api.run("material.assign_material", model,
product=wall_type, type="IfcMaterialLayerSet", material=material_set)
# Let's imagine an occurrence of this wall type.
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type)
# Our wall occurrence needs to have a "set usage" which describes
# how the layers relate to a reference line (typically a 2D line
# representing the extents of the wall). Usages are special since
# they automatically detect the inherited material set from the
# type. You'd write similar code for a profile set.
rel = ifcopenshell.api.run("material.assign_material", model,
product=wall, type="IfcMaterialLayerSetUsage")
# Let's change the offset from the reference line to be 200mm
# instead of the default of 0mm.
ifcopenshell.api.run("material.edit_layer_usage", model,
usage=rel.RelatingMaterial, attributes={"OffsetFromReferenceLine": 200})
"""
self.file = file
self.settings = {"usage": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"usage": usage, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,64 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, profile=None, attributes=None, profile_def=None, material=None):
"""Edits the attributes of an IfcMaterialProfile
For more information about the attributes and data types of an
IfcMaterialProfile, consult the IFC documentation.
:param profile: The IfcMaterialProfile entity you want to edit
:type profile: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:param profile_def: The IfcProfileDef entity the profile curve should be
extruded from.
:type profile_def: ifcopenshell.entity_instance.entity_instance, optional
:param material: The IfcMaterial entity you want to change the profile
to be made from.
:type material: ifcopenshell.entity_instance.entity_instance, optional
:return: None
:rtype: None
Example::
# Let's create a material set to store our profiles.
material_set = ifcopenshell.api.run("material.add_profile_set", model,
name="B1", set_type="IfcMaterialProfileSet")
# Create a couple steel materials.
steel1 = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
steel2 = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Create some I-shaped profiles. Notice how we name our profiles based
# on standardised steel profile names.
hea100 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA100", ProfileType="AREA",
OverallWidth=100, OverallDepth=96, WebThickness=5, FlangeThickness=8, FilletRadius=12,
)
hea200 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA200", ProfileType="AREA",
OverallWidth=200, OverallDepth=190, WebThickness=6.5, FlangeThickness=10, FilletRadius=18,
)
# 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, but this is rarely the case in most construction.
profile_item = ifcopenshell.api.run("material.add_profile", model,
profile_set=material_set, material=steel1, profile=hea100)
# Edit our profile item to use a HEA200 profile instead made out of
# another type of steel.
ifcopenshell.api.run("material.edit_profile", model,
profile=profile_item, profile_def=hea200, material=steel2)
"""
self.file = file
self.settings = {"profile": None, "attributes": {}, "profile_def": None, "material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {
"profile": profile,
"attributes": attributes or {},
"profile_def": profile_def,
"material": material,
}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -21,11 +21,74 @@ import ifcopenshell.util.representation
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, usage=None, attributes=None):
"""Edits the attributes of an IfcMaterialProfileSetUsage
This is typically used to change the cardinal point of the profile.
The cardinal point represents whether the profile is extruded along the
center of the axis line, at a corner, at a shear center, at the bottom,
top, etc.
For more information about the attributes and data types of an
IfcMaterialProfileSetUsage, consult the IFC documentation.
:param usage: The IfcMaterialProfileSetUsage entity you want to edit
:type usage: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
# Let's imagine we have a steel I-beam. Notice we are assigning to
# the type only, as all occurrences of that type will automatically
# inherit the material.
beam_type = ifcopenshell.api.run("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.
material_set = ifcopenshell.api.run("material.add_profile_set", model,
name="B1", set_type="IfcMaterialProfileSet")
# Create a steel material.
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Create an I-beam profile curve. Notice how we name our profiles
# based on standardised steel profile names.
hea100 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA100", ProfileType="AREA",
OverallWidth=100, OverallDepth=96, WebThickness=5, FlangeThickness=8, FilletRadius=12,
)
# 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, but this is rarely the case in most construction.
profile_item = ifcopenshell.api.run("material.add_profile", model,
profile_set=material_set, material=steel, profile=hea100)
# Great! Let's assign our material set to our beam type.
ifcopenshell.api.run("material.assign_material", model, product=beam_type, material=material_set)
# Let's create an occurrence of this beam.
beam = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBeam", name="B1.01")
rel = ifcopenshell.api.run("material.assign_material", model,
product=beam, type="IfcMaterialProfileSetUsage")
# Let's give a 1000mm long beam body representation.
body = ifcopenshell.api.run("geoemtry.add_profile_representation",
context=body_context, profile=hea100, depth=1000)
ifcopenshell.api.run("geometry.assign_representation", model, product=beam, representation=body)
# Let's change the cardinal point to be the top center of the axis
# line. This is represented by the number "8". Consult the IFC
# documentation for all the numbers you can use.
ifcopenshell.api.run("material.edit_profile_usage", model,
usage=rel.RelatingMaterial, attributes={"CardinalPoint": 8})
"""
self.file = file
self.settings = {"usage": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"usage": usage, "attributes": attributes or {}}
def execute(self):
self.cardinal_point = self.settings["attributes"].get("CardinalPoint")
@@ -18,11 +18,39 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, constituent=None):
"""Removes a constituent from a constituent set
Note that it is invalid to have zero items in a set, so you should leave
at least one constituent to ensure a valid IFC dataset.
:param constituent: The IfcMaterialConstituent entity you want to remove
:type constituent: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Create a material set for windows made out of aluminium and glass.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialConstituentSet")
aluminium = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
glass = ifcopenshell.api.run("material.add_material", model, name="GLZ01", category="glass")
# Now let's use those materials as two constituents in our set.
framing = ifcopenshell.api.run("material.add_constituent", model,
constituent_set=material_set, material=aluminium)
glazing = ifcopenshell.api.run("material.add_constituent", model,
constituent_set=material_set, material=glass)
# Let's remove the glass constituent. Note that we should not remove
# the framing, at this would mean there are no constituents which is
# invalid.
ifcopenshell.api.run("material.remove_constituent", model, constituent=glazing)
"""
self.file = file
self.settings = {"constituent": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"constituent": constituent}
def execute(self):
self.file.remove(self.settings["constituent"])
@@ -18,11 +18,42 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, layer=None):
"""Removes a layer from a layer set
Note that it is invalid to have zero items in a set, so you should leave
at least one layer to ensure a valid IFC dataset.
:param layer: The IfcMaterialLayer entity you want to remove
:type layer: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Create a material set for steel stud partition walls.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialConstituentSet")
gypsum = ifcopenshell.api.run("material.add_material", model, name="PB01", category="gypsum")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Now let's use those materials as three layers in our set, such
# that the steel studs are sandwiched by the gypsum. Let's imagine
# we're setting the layer thickness in millimeters.
layer1 = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer1, attributes={"LayerThickness": 13})
layer2 = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
ifcopenshell.api.run("material.edit_layer", model, layer=layer2, attributes={"LayerThickness": 92})
layer3 = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
ifcopenshell.api.run("material.edit_layer", model, layer=layer3, attributes={"LayerThickness": 13})
# Let's remove the last layer, such that the wall might be clad only
# one one side such as to line a services riser.
ifcopenshell.api.run("material.remove_layer", model, layer=layer3)
"""
self.file = file
self.settings = {"layer": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"layer": layer}
def execute(self):
self.file.remove(self.settings["layer"])
@@ -20,11 +20,39 @@ import ifcopenshell
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material_list=None, material_index=0):
"""Removes an item in an material list
Note that it is invalid to have zero items in a list, so you should leave
at least one item to ensure a valid IFC dataset.
:param material_list: The IfcMaterialList entity you want to remove an
item from.
:type material_list: ifcopenshell.entity_instance.entity_instance
:param material_index: The index of the material you want to remove from
the list. Starts counting at 0. Defaults to 0.
:type material_index: int, optional
:return: None
:rtype: None
Example::
# Create a material list for aluminium windows.
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialMaterialList")
aluminium = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
glass = ifcopenshell.api.run("material.add_material", model, name="GLZ01", category="glass")
# Now let's use those materials as two items in our list.
ifcopenshell.api.run("material.add_list_item", model, material_list=material_set, material=aluminium)
ifcopenshell.api.run("material.add_list_item", model, material_list=material_set, material=glass)
# Let's remove the glass
ifcopenshell.api.run("material.remove_list_item", model, material_list=material_set, material_index=1)
"""
self.file = file
self.settings = {"material_list": None, "material_index": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"material_list": material_list, "material_index": material_index}
def execute(self):
materials = list(self.settings["material_list"].Materials)
@@ -20,11 +20,29 @@ import ifcopenshell
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material=None):
"""Removes a material
If the material is used in a material set, the corresponding layer,
profile, or constituent is also removed. Note that this may result in a
material set with zero items in it, which is invalid, so the user must
take care of this situation themselves.
:param material: The IfcMaterial entity you want to remove
:type material: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Create a material
aluminium = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
# ... and remove it
ifcopenshell.api.run("material.remove_material", model, material=aluminium)
"""
self.file = file
self.settings = {"material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"material": material}
def execute(self):
inverse_elements = self.file.get_inverse(self.settings["material"])
@@ -20,11 +20,41 @@ import ifcopenshell
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material=None):
"""Removes a material set
All set items, such as layers, profiles, or constituents will also be
removed. However, the materials and profile curves used by the layers,
profiles and constituents will not be removed.
:param material: The IfcMaterialLayerSet, IfcMaterialConstituentSet,
IfcMaterialProfileSet entity you want to remove.
:type material: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Create a material set
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="GYP-ST-GYP", set_type="IfcMaterialLayerSet")
# Create some materials
gypsum = ifcopenshell.api.run("material.add_material", model, name="PB01", category="gypsum")
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Add some layers
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=steel)
layer = ifcopenshell.api.run("material.add_layer", model, layer_set=material_set, material=gypsum)
# Completely delete the set and all layers. The gypsum and steel
# material still exist, though.
ifcopenshell.api.run("material.remove_material_set", model, material=material_set)
"""
self.file = file
self.settings = {"material": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"material": material}
def execute(self):
inverse_elements = self.file.get_inverse(self.settings["material"])
@@ -18,11 +18,49 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, profile=None):
"""Removes a profile item from a profile set
Note that it is invalid to have zero items in a set, so you should leave
at least one profile to ensure a valid IFC dataset.
:param profile: The IfcMaterialProfile entity you want to remove
:type profile: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# First, let's create a material set.
material_set = ifcopenshell.api.run("material.add_profile_set", model,
name="B1", set_type="IfcMaterialProfileSet")
# Create a steel material.
steel = ifcopenshell.api.run("material.add_material", model, name="ST01", category="steel")
# Create an I-beam profile curve. Notice how we name our profiles
# based on standardised steel profile names.
hea100 = self.file.create_entity(
"IfcIShapeProfileDef", ProfileName="HEA100", ProfileType="AREA",
OverallWidth=100, OverallDepth=96, WebThickness=5, FlangeThickness=8, FilletRadius=12,
)
# Define that steel material and cross section as a single profile item.
ifcopenshell.api.run("material.add_profile", model,
profile_set=material_set, material=steel, profile=hea100)
# Imagine a welded square along the length of the profile.
welded_square = ifcopenshell.api.run("profile.add_arbitrary_profile", model,
profile=[(2.5, 2.5), (32.5, 2.5), (32.5, -2.5), (2.5, -2.5)])
weld_profile = ifcopenshell.api.run("material.add_profile", model,
profile_set=material_set, material=steel, profile=welded_square)
# Let's remove our welded square.
ifcopenshell.api.run("material.remove_profile", model, profile=weld_profile)
"""
self.file = file
self.settings = {"profile": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"profile": profile}
def execute(self):
self.file.remove(self.settings["profile"])
@@ -18,9 +18,43 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, material_set=None, old_index=0, new_index=0):
"""Reorders an item in a material set
In some material sets, the order have meaning, like in a layer set. In
other cases, it is purely for human convenience.
:param material_set: The IfcMaterialSet which you want to reorder an
item in.
:type material_set: ifcopenshell.entity_instance.entity_instance
:param old_index: The index of the item you want to move. This starts
counting from 0.
:type old_index: int
:param new_index: The index of the new position the item will move to.
This starts counting from 0.
:type new_index: int
:return: None
:rtype: None
Example::
material_set = ifcopenshell.api.run("material.add_material_set", model,
name="Window", set_type="IfcMaterialList")
aluminium = ifcopenshell.api.run("material.add_material", model, name="AL01", category="aluminium")
glass = ifcopenshell.api.run("material.add_material", model, name="GLZ01", category="glass")
# Now let's use those materials as two items in our list.
ifcopenshell.api.run("material.add_list_item", model, material_list=material_set, material=aluminium)
ifcopenshell.api.run("material.add_list_item", model, material_list=material_set, material=glass)
# Switch the order around, this has no meaning for a list, so this
# is just for fun.
ifcopenshell.api.run("material.reorder_set_item", model,
material_set=material_set, old_index=0, new_index=1)
"""
self.file = file
self.settings = {"material_set": None, "old_index": 0, "new_index": 0}
self.settings = {"material_set": material_set, "old_index": old_index, "new_index": new_index}
for key, value in settings.items():
self.settings[key] = value
@@ -21,11 +21,36 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, product=None):
"""Removes any material relationship with a product
A product can only have one material assigned to it, which is why it is
not necessary to specify the material to unassign. The material is not
removed, only the relationship is removed.
If the product does not have a material, nothing happens.
:param product: The IfcProduct that may or may not have a material
:type product: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
# Let's imagine a concrete bench made out of concrete.
bench_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurnitureType")
ifcopenshell.api.run("material.assign_material", model,
product=bench_type, type="IfcMaterial", material=concrete)
# Let's change our mind and remove the concrete assignment. The
# concrete material still exists, but the bench is no longer made
# out of concrete now.
ifcopenshell.api.run("material.unassign_material", model, product=bench_type)
"""
self.file = file
self.settings = {"product": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"product": product}
def execute(self):
if self.settings["product"].is_a("IfcTypeObject"):