Add API documentation for classification module

This commit is contained in:
Dion Moult
2022-11-15 16:11:47 +09:00
parent c87924c4ba
commit 308ee7f7a9
6 changed files with 232 additions and 29 deletions
@@ -22,13 +22,62 @@ import ifcopenshell.util.date
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, classification=None):
"""Adds a new classification system to the project
External classification systems such as Uniclass or Omniclass are
ways of categorising elements in the AEC industry, typically
standardised or nominated by governments or companies. A system
typically contains a series of hierarchical reference codes and labels
like Pr_12_23_34.
Classifications may be applied to many things, not just physical
elements, such as doors and windows, spatial elements, tasks, cost
items, or even resources.
Prior to assigning classificaion references, you need to add the name
and metadata of the classification system that you will use in your
project. Classification systems may be revised over time, so this
metadata includes the edition date.
Common classification systems are provided as an IFC library which may
be downloaded from https://github.com/Moult/IfcClassification for your
convenience. It is advised to use these to ensure that the
classification metadata is standardised.
Adding a classification system will not add the entire hierarchy of
references available in the classification. References need to be added
separately. Typically, you'd only add the references that you use in
your project, see ifcopenshell.api.classification.add_reference for more
information.
:param classification: If a string is provided, it is assumed to be the
name of your classification system. This is necessary if you are
creating your own custom classification system. Alternatively, you
may provide an entity_instance of an IfcClassification from an IFC
classification library. The latter approach is preferred if you are
using a commonly known system such as Uniclass, as this will ensure
all metadata is added correctly.
:type classification: str,ifcopenshell.entity_instance.entity_instance
:return: The added IfcClassification element
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Option 1: adding a custom clasification from scratch
ifcopenshell.api.run("classification.add_classification", model,
classification="MyCustomClassification")
# Option 2: adding a popular classification from a library
library = ifcopenshell.open("/path/to/Uniclass.ifc")
classification = library.by_type("IfcClassification")[0]
ifcopenshell.api.run("classification.add_classification", model,
classification=classification)
"""
self.file = file
self.settings = {
"classification": None,
"classification": classification,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
if isinstance(self.settings["classification"], str):
@@ -21,18 +21,99 @@ import ifcopenshell.util.schema
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, product=None, reference=None, identification=None, name=None, classification=None, is_lightweight=True):
"""Adds a new classification reference and assigns it to a product
A classification reference is a single entry such as "Pr_12_23_34" that
is part of an external classification system (such as Uniclass or
Omniclass).
References can be added to almost any object in IFC, including physical
objects, object types, properties, tasks, costs, resources, or even
resources such as profiles, documents, libraries, and so on.
Classification references can be added in two ways. Option 1) specify a
custom arbitrary reference, where you have the manually specify the
identification (e.g. "Pr_12_23_45") and name (e.g. "Door Products").
Option 2) add a reference from an IFC classification library. The latter
is preferred if you are using a common classification system such as
Uniclass, as the library will be prepopulated with all the valid
classifications already.
Objects are allowed to have multiple classification references from
multiple classification systems. This means that adding a new reference
will not remove existing references.
References can be inherited from types. This means that if an
IfcWallType has a classification reference of Pr_12_23_34, then all
IfcWall occurrences of that type automatically get the same
classification of Pr_12_23_34. This means that it is more efficient to
assign to types where possible. If a classification reference is
assigned to both the type and an occurrence, then the assignment at the
occurrence will override the type classification.
:param product: The IFC object, property, or resource you want to
associate the classification reference to.
:type product: ifcopenshell.entity_instance.entity_instance
:param reference: The classification reference entity taken from an
IFC classification library. If you supply this parameter, you will
use option 2.
:type product: ifcopenshell.entity_instance.entity_instance, optional
:param identification: If you choose option 1 and do not specify a
reference, you may manually specify an identification code. The code
is typically a short identifier and may have punctuation to separate
the levels of hierarchy in the classificaion (e.g. Pr_12_23_34).
:type identification: str, optional
:param name: If you choose option 1 and do not specify a reference, you
may manually specify a name. The name is typically human readable.
:type name: str, optional
:param classification: The IfcClassification entity in your IFC model
(not the library, if you are doing option 2) that the reference is
part of.
:type product: ifcopenshell.entity_instance.entity_instance
:param is_lightweight: If you are doing option 2, choose whether or not
to only add that particular reference (lighweight) or also add all
of its parent references in the classification hierarchy (not
lighweight). For example, adding a lightweight reference to
Pr_12_23_34 will only add Pr_12_23_34, but adding a heavy reference
to Pr_12_23_34 will also add Pr_12_23 and Pr_12. These parent
references merely help describe the "tree" of classifications, but
is generally unnecessary. Using lightweight classifications are
recommended and is the default.
:type is_lightweight: bool, optional
:return: The newly added IfcClassificationReference
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# Option 1: adding and assigning a new reference from scratch
wall_type = model.by_type("IfcWallType")[0]
classification = ifcopenshell.api.run("classification.add_classification",
model, classification="MyCustomClassification")
ifcopenshell.api.run("classification.add_reference", model,
product=wall_type, classification=classification,
identification="W_01", name="Interior Walls")
# Option 2: adding a popular classification from a library
library = ifcopenshell.open("/path/to/Uniclass.ifc")
lib_classification = library.by_type("IfcClassification")[0]
classification = ifcopenshell.api.run("classification.add_classification",
model, classification=lib_classification)
reference = [r for r in library.by_type("IfcClassificationReference")
if r.Identification == "XYZ"][0]
ifcopenshell.api.run("classification.add_reference", model,
product=wall_type, classification=classification,
reference=reference)
"""
self.file = file
self.settings = {
"product": None,
"reference": None,
"identification": None,
"name": None,
"classification": None,
"is_lightweight": True,
"product": product,
"reference": reference,
"identification": identification,
"name": name,
"classification": classification,
"is_lightweight": is_lightweight,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
self.is_rooted = self.settings["product"].is_a("IfcRoot")
@@ -18,11 +18,28 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, classification=None, attributes=None):
"""Edits the attributes of an IfcClassification
For more information about the attributes and data types of an
IfcClassification, consult the IFC documentation.
:param classification: The IfcClassification entity you want to edit
:type classification: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
classification = model.by_type("IfcClassification")[0]
# Change the name of the classification system to "Foo"
ifcopenshell.api.run("classification.edit_classification", model,
classification=classification, attributes={"Name": "Foo"})
"""
self.file = file
self.settings = {"classification": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"classification": classification, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,28 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, reference=None, attributes=None):
"""Edits the attributes of an IfcClassificationReference
For more information about the attributes and data types of an
IfcClassificationReference, consult the IFC documentation.
:param reference: The IfcClassificationReference entity you want to edit
:type reference: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
reference = model.by_type("IfcClassification")[0]
# Change the name of the reference to "Foo"
ifcopenshell.api.run("classification.edit_reference", model,
reference=reference, attributes={"Name": "Foo"})
"""
self.file = file
self.settings = {"reference": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"reference": reference, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,27 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, classifcation=None):
"""Removes an IfcClassification from the project and all references
The classification and all of its relationships, children references,
and relationships between objectse and child references are completely
removed from a project.
:param classification: The IfcClassification entity you want to remove
:type classification: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
classification = model.by_type("IfcClassification")[0]
ifcopenshell.api.run("classification.remove_classification", model,
classification=classification)
"""
self.file = file
self.settings = {"classification": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"classification": classification}
def execute(self):
references = self.get_references(self.settings["classification"])
@@ -18,11 +18,34 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, reference=None, product=None):
"""Removes a classification reference from a product
If the classification reference is no longer associated to any products,
the classification reference itself is also removed.
:param reference: The IfcClassificationReference entity of the
relationship you want to remove.
:type reference: ifcopenshell.entity_instance.entity_instance
:param product: The object entity of the relationship you want to
remove.
:type reference: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
wall_type = model.by_type("IfcWallType")[0]
classification = ifcopenshell.api.run("classification.add_classification",
model, classification="MyCustomClassification")
reference = ifcopenshell.api.run("classification.add_reference", model,
product=wall_type, classification=classification,
identification="W_01", name="Interior Walls")
ifcopenshell.api.run("classification.remove_reference", model,
reference=reference, product=wall_type)
"""
self.file = file
self.settings = {"reference": None, "product": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"reference": reference, "product": product}
def execute(self):
if self.settings["product"].is_a("IfcRoot"):