mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-31 08:56:34 +00:00
Write docs for type API module
This commit is contained in:
@@ -22,14 +22,147 @@ import ifcopenshell.util.element
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, related_object=None, relating_type=None):
|
||||||
|
"""Assigns a type to an occurrence of an object
|
||||||
|
|
||||||
|
IFC supports the concept of occurrences and types. An occurrence is an
|
||||||
|
actual physical product in the real world: like a wall, a chair, a door,
|
||||||
|
a column, a pump, and so on.
|
||||||
|
|
||||||
|
Most occurrences have a corresponding type. A type describes either a
|
||||||
|
common shape and set of properties of a particular model of equipment,
|
||||||
|
or a construction typology. An occurrence may only have zero or one
|
||||||
|
type.
|
||||||
|
|
||||||
|
For example, architects would typically have a door schedule for
|
||||||
|
individual occurrences of doors and a door types schedule for a handful
|
||||||
|
of door types, described by the door hardware, frame, and panel. Other
|
||||||
|
examples might be window types or wall types. Structural engineers would
|
||||||
|
have a list of column types, beam types, slab types, etc, such as a 400
|
||||||
|
diameter column, a 500 diameter column, and so on. Services consultant
|
||||||
|
might nominate a particular type of sprinkler which have many
|
||||||
|
occurrences, or light fixture types, and so on.
|
||||||
|
|
||||||
|
Types are critical as they communicate to the procurement team what
|
||||||
|
types of equipment and products need to be procured. The individual
|
||||||
|
occurrences of that type tell them how many to procure. Types are also
|
||||||
|
critical in construction as they indicate succinctly how to manufacture
|
||||||
|
or construct something. For example, a wall type is enough information
|
||||||
|
for a builder to understand the build up and construction of a wall.
|
||||||
|
Types are used to help break down cost plans, or isolate portions of an
|
||||||
|
assembly process for construction scheduling. Types are also used in
|
||||||
|
facility maintenance, as occurrences sharing the same type can be
|
||||||
|
repaired in the same way or by replacing the same parts.
|
||||||
|
|
||||||
|
An occurrence of a type inherits all the properties and materials of the
|
||||||
|
type. For example, a 2HR fire rated wall type implies that all
|
||||||
|
wall occurrences of that wall type will also be 2HR fire rated.
|
||||||
|
|
||||||
|
A type may or may not have a geometric representation. If a type does
|
||||||
|
not have any representation, then the occurrences are free to have any
|
||||||
|
representation of their own. However, if a type has a representation,
|
||||||
|
all occurrences must have the same representation. For example, if a
|
||||||
|
light fixture downlight type has a representation of a cylinder, then
|
||||||
|
all occurrences must have exactly the same cylinder as its
|
||||||
|
representation. If you change the cylinder's shape of the type, then all
|
||||||
|
occurrence representations will also change.
|
||||||
|
|
||||||
|
If a type does not have any geometric representation, they may have a
|
||||||
|
parametric material representation. This may be either a parametric
|
||||||
|
layered material or parametric cross-sectional profile material. If this
|
||||||
|
is the case, the occurrence must be constructed out of the parametric
|
||||||
|
material. For example, if a wall type uses a list of parametric layers
|
||||||
|
indicating a thickness of 13mm plasterboard and 90mm stud, then the
|
||||||
|
thickness of every wall occurrence representation must be 103mm. The
|
||||||
|
length of each wall, however, may vary. Similarly, if a beam type has a
|
||||||
|
parametric profile material of an I-beam, then all beam occurrences must
|
||||||
|
also be this I-beam shape, though the length may vary.
|
||||||
|
|
||||||
|
It is highly recommended for every occurence to have a type. There are
|
||||||
|
some exceptions to the rule, such as in heritage architecture or
|
||||||
|
as-built or dilapidation models, where existing conditions are
|
||||||
|
ambiguous, unknown or are so bespoke as to have no logical type.
|
||||||
|
|
||||||
|
:param related_object: The IfcElement occurrence.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param relating_type: The IfcElementType type.
|
||||||
|
:type relating_type: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: The IfcRelDefinesByType relationship
|
||||||
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# A furniture type. This would correlate to a particular model in a
|
||||||
|
# manufacturer's catalogue. Like an Ikea sofa :)
|
||||||
|
furniture_type = ifcopenshell.api.run("root.create_entity", model,
|
||||||
|
ifc_class="IfcFurnitureType", name="FUN01")
|
||||||
|
|
||||||
|
# An individual occurrence of a that sofa.
|
||||||
|
furniture = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
|
||||||
|
|
||||||
|
# Assign the furniture to the furniture type. If the furniture_type
|
||||||
|
# had a representation, the furniture occurrence will also now have
|
||||||
|
# the exact same representation. This is highly efficient as you
|
||||||
|
# don't need to define the representation for every occurrence.
|
||||||
|
ifcopenshell.api.run("type.assign_type", model, related_object=furniture, relating_type=furniture_type)
|
||||||
|
|
||||||
|
# Let's imagine a parametric material layer set
|
||||||
|
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": .013})
|
||||||
|
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": .092})
|
||||||
|
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": .013})
|
||||||
|
|
||||||
|
# Great! Let's assign our material set to our wall type.
|
||||||
|
ifcopenshell.api.run("material.assign_material", model, product=wall_type, material=material_set)
|
||||||
|
|
||||||
|
# Now, let's create a wall.
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||||
|
|
||||||
|
# The wall is a WAL01 wall type.
|
||||||
|
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type)
|
||||||
|
|
||||||
|
# A bit of preparation, let's create some geometric contexts since
|
||||||
|
# we want to create some geometry for our wall.
|
||||||
|
model3d = ifcopenshell.api.run("context.add_context", model, context_type="Model")
|
||||||
|
body = ifcopenshell.api.run("context.add_context", model,
|
||||||
|
context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model3d)
|
||||||
|
|
||||||
|
# Notice how our thickness of 0.118 must equal .013 + .092 + .013 from our type
|
||||||
|
representation = ifcopenshell.api.run("geometry.add_wall_representation", model,
|
||||||
|
context=body, length=5, height=3, thickness=0.118)
|
||||||
|
|
||||||
|
# Assign our new body geometry back to our wall
|
||||||
|
ifcopenshell.api.run("geometry.assign_representation", model,
|
||||||
|
product=wall, representation=representation)
|
||||||
|
|
||||||
|
# Place our wall at the origin
|
||||||
|
ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
"relating_type": None,
|
"relating_type": relating_type,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if self.file.schema == "IFC2X3":
|
if self.file.schema == "IFC2X3":
|
||||||
|
|||||||
@@ -20,14 +20,25 @@ import ifcopenshell
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, related_object=None, relating_type=None):
|
||||||
|
"""Gets all the related occurrences of a type
|
||||||
|
|
||||||
|
Do not use this function. It will be removed. Use
|
||||||
|
ifcopenshell.util.element.get_type or
|
||||||
|
ifcopenshell.util.element.get_types instead.
|
||||||
|
|
||||||
|
:param related_object: The IfcElement occurrence.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param relating_type: The IfcElementType type.
|
||||||
|
:type relating_type: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: A list of occurrences of the type.
|
||||||
|
:rtype: list[ifcopenshell.entity_instance.entity_instance]
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
"relating_type": None,
|
"relating_type": relating_type,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if self.settings["related_object"]:
|
if self.settings["related_object"]:
|
||||||
|
|||||||
@@ -22,14 +22,68 @@ import ifcopenshell.util.element
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, related_object=None, relating_type=None):
|
||||||
|
"""Ensures that all occurrences has the same representation as the type
|
||||||
|
|
||||||
|
If a type has a representation, all occurrences must have the same
|
||||||
|
representation. If the type's representation changes, this function may
|
||||||
|
be used to ensure consistency of the occurrence's representations.
|
||||||
|
|
||||||
|
:param related_object: The IfcElement occurrence.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:param relating_type: The IfcElementType type.
|
||||||
|
:type relating_type: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# A furniture type. This would correlate to a particular model in a
|
||||||
|
# manufacturer's catalogue. Like an Ikea sofa :)
|
||||||
|
furniture_type = ifcopenshell.api.run("root.create_entity", model,
|
||||||
|
ifc_class="IfcFurnitureType", name="FUN01")
|
||||||
|
|
||||||
|
# An individual occurrence of a that sofa.
|
||||||
|
furniture = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
|
||||||
|
|
||||||
|
# Place our furniture at the origin
|
||||||
|
ifcopenshell.api.run("geometry.edit_object_placement", model, product=furniture)
|
||||||
|
|
||||||
|
# Assign the furniture to the furniture type. Right now, the
|
||||||
|
# furniture type has no representation, so the furniture may also
|
||||||
|
# have no representation, or any arbitrary representation that may
|
||||||
|
# vary from occurrence to occurrence.
|
||||||
|
ifcopenshell.api.run("type.assign_type", model, related_object=furniture, relating_type=furniture_type)
|
||||||
|
|
||||||
|
# A bit of preparation, let's create some geometric contexts since
|
||||||
|
# we want to create some geometry for our furniture type.
|
||||||
|
model3d = ifcopenshell.api.run("context.add_context", model, context_type="Model")
|
||||||
|
body = ifcopenshell.api.run("context.add_context", model,
|
||||||
|
context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model3d)
|
||||||
|
|
||||||
|
# Let's create a mesh representation of an arbitrary 2m cube.
|
||||||
|
representation = ifcopenshell.api.run("geometry.add_sverchok_representation", model, context=body,
|
||||||
|
vertices=[[(-1.0, -1.0, 0.0), (-1.0, -1.0, 2.0), (-1.0, 1.0, 0.0), (-1.0, 1.0, 2.0),
|
||||||
|
(1.0, -1.0, 0.0), (1.0, -1.0, 2.0), (1.0, 1.0, 0.0), (1.0, 1.0, 2.0)]],
|
||||||
|
faces=[[[0, 1, 3, 2], [2, 3, 7, 6], [6, 7, 5, 4], [4, 5, 1, 0], [2, 6, 4, 0], [7, 3, 1, 5]]])
|
||||||
|
|
||||||
|
# Assign our new body geometry back to our furniture type. In this
|
||||||
|
# case, since we use the API, all occurrences automatically get the
|
||||||
|
# representation mapped, so there is nothing more we need to do.
|
||||||
|
ifcopenshell.api.run("geometry.assign_representation", model,
|
||||||
|
product=furniture_type, representation=representation)
|
||||||
|
|
||||||
|
# However, if you were doing some sort of manual IFC patching, like
|
||||||
|
# assigning furniture_type.RepresentationMaps directly, then you
|
||||||
|
# might make this call:
|
||||||
|
# ifcopenshell.api.run("type.map_type_representations", model,
|
||||||
|
# related_object=furniture, relating_type=furniture_type)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {
|
||||||
"related_object": None,
|
"related_object": related_object,
|
||||||
"relating_type": None,
|
"relating_type": relating_type,
|
||||||
}
|
}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if not self.settings["relating_type"].RepresentationMaps:
|
if not self.settings["relating_type"].RepresentationMaps:
|
||||||
|
|||||||
@@ -21,11 +21,32 @@ import ifcopenshell.api
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, related_object=None):
|
||||||
|
"""Unassigns a type of an occurrence
|
||||||
|
|
||||||
|
:param related_object: The IfcElement occurrence.
|
||||||
|
:type related_object: ifcopenshell.entity_instance.entity_instance
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
# A furniture type. This would correlate to a particular model in a
|
||||||
|
# manufacturer's catalogue. Like an Ikea sofa :)
|
||||||
|
furniture_type = ifcopenshell.api.run("root.create_entity", model,
|
||||||
|
ifc_class="IfcFurnitureType", name="FUN01")
|
||||||
|
|
||||||
|
# An individual occurrence of a that sofa.
|
||||||
|
furniture = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
|
||||||
|
|
||||||
|
# Assign the furniture to the furniture type.
|
||||||
|
ifcopenshell.api.run("type.assign_type", model, related_object=furniture, relating_type=furniture_type)
|
||||||
|
|
||||||
|
# Change our mind. Maybe it's a different type?
|
||||||
|
ifcopenshell.api.run("type.unassign_type", model, related_object=furniture)
|
||||||
|
"""
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {"related_object": None}
|
self.settings = {"related_object": related_object}
|
||||||
for key, value in settings.items():
|
|
||||||
self.settings[key] = value
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
if self.file.schema == "IFC2X3":
|
if self.file.schema == "IFC2X3":
|
||||||
|
|||||||
Reference in New Issue
Block a user