From 9650bbb5ee6229c6825520084206496414f20fa3 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 7 Dec 2022 08:59:24 +1100 Subject: [PATCH] Add docs to layer API --- .../ifcopenshell/api/context/add_context.py | 3 +- .../ifcopenshell/api/group/edit_group.py | 1 - .../ifcopenshell/api/group/unassign_group.py | 2 +- .../ifcopenshell/api/layer/add_layer.py | 31 ++++++++++-- .../ifcopenshell/api/layer/assign_layer.py | 48 +++++++++++++++++-- .../ifcopenshell/api/layer/edit_layer.py | 24 ++++++++-- .../ifcopenshell/api/layer/remove_layer.py | 21 ++++++-- .../ifcopenshell/api/layer/unassign_layer.py | 47 +++++++++++++++--- 8 files changed, 149 insertions(+), 28 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py b/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py index 990516fb42..cada87c4bb 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py +++ b/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py @@ -170,7 +170,8 @@ class Usecase: context=body, length=5, height=3, thickness=0.2) # Assign our new body geometry back to our wall - run("geometry.assign_representation", model, product=wall, representation=representation) + ifcopenshell.api.run("geometry.assign_representation", model, + product=wall, representation=representation) """ self.file = file self.settings = { diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py index 51d5f8503f..d7abda228b 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py @@ -37,7 +37,6 @@ class Usecase: ifcopenshell.api.run("group.edit_group", model, group=group, attributes={"Description": "All furniture and joinery included in the unit"}) """ - self.file = file self.settings = {"group": group, "attributes": attributes or {}} diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py index 1491d7dc5d..b8c4a3df6b 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py @@ -28,7 +28,7 @@ class Usecase: :param product: A IfcProduct element to unassign from the group :type product: ifcopenshell.entity_instance.entity_instance - :param group: The IfcGroup to assign the products to + :param group: The IfcGroup to unassign from :type group: ifcopenshell.entity_instance.entity_instance :return: None :rtype: None diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py index 8f29811be5..848dc423ce 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py @@ -18,11 +18,32 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, Name=None): + """Adds a new layer + + An IFC layer is like a CAD layer. Portions of an object's geometry + (typically portions of its 2D linework) can be assigned to layers, which + can provide stylistic information such as line weights, colours, or + simply be used for filtering. + + Layers have historically been used to organise CAD data and included in + ISO standards such as ISO 13567 or by the AIA. This alllows IFC data to + be compatible with older, 2D-oriented, layer-based workflows. + + Some software that are still based on layers, such as Tekla or ArchiCAD + may also use this layer information for filtering. + + :param Name: The name of the layer. Defaults to "Unnamed". + :type Name: str, optional + :return: The newly created IfcPresentationLayerAssignment element + :rtype: ifcopenshell.entity_instance.entity_instance + + Example: + + ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL-FULL-DIMS-N") + """ self.file = file - self.settings = {} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"Name": Name or "Unnamed"} def execute(self): - return self.file.create_entity("IfcPresentationLayerAssignment", **{"Name": "Unnamed"}) + return self.file.create_entity("IfcPresentationLayerAssignment", Name=self.settings["Name"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py index 17a22cdf3e..0fd6321e64 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/assign_layer.py @@ -20,14 +20,52 @@ import ifcopenshell class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, item=None, layer=None): + """Assigns a representation item to a layer + + In IFC, instead of objects being assigned to layers, representation + items are assigned to layers. Representation items are portions of the + object's representation. For example, this allows a single IFC Window + element to have portions of its 2D linework (e.g. the cross section of + its frame) assigned to one layer, and another portion (e.g. the glazing + panels) assigned to another layer. + + :param item: The IfcRepresentationItem to assign to the layer. This + should be one of the items in the object's IfcShapeRepresentation. + :type item: ifcopenshell.entity_instance.entity_instance + :param layer: The IfcPresentationLayerAssignment layer to assign the + item to. + :type layer: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example:: + + # Remember, all geometry needs to specify the context it is part of first. + # See ifcopenshell.api.context.add_context for details. + model = 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=model + ) + + wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall") + representation = ifcopenshell.api.run("geometry.add_wall_representation", model, + context=body, length=5, height=3, thickness=0.2) + ifcopenshell.api.run("geometry.assign_representation", model, + product=wall, representation=representation) + + # Now let's create a layer that contains walls + layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + + # And assign our wall representation item (in this example, there is + # only one item) to the layer. + ifcopenshell.api.run("layer.assign_layer", model, item=representation.Items[0], layer=layer) + """ self.file = file self.settings = { - "item": None, - "layer": None, + "item": item, + "layer": layer, } - for key, value in settings.items(): - self.settings[key] = value def execute(self): assigned_items = set(self.settings["layer"].AssignedItems or []) diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py index 0eb20dc1e2..24f1883458 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py @@ -18,11 +18,27 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, layer=None, attributes=None): + """Edits the attributes of an IfcPresentationLayerAssignment + + For more information about the attributes and data types of an + IfcPresentationLayerAssignment, consult the IFC documentation. + + :param layer: The IfcPresentationLayerAssignment 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 + :return: None + :rtype: None + + Example:: + + layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + ifcopenshell.api.run("layer.edit_layer", model, + layer=layer, attributes={"Description": "All walls, based on the AIA standard."}) + """ self.file = file - self.settings = {"layer": None, "attributes": {}} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"layer": layer, "attributes": attributes or {}} def execute(self): for name, value in self.settings["attributes"].items(): diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py index a3c61fa410..b9c41e2114 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/remove_layer.py @@ -18,11 +18,24 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, layer=None): + """Removes a layer + + All representation items assigned to the layer will remain, but the + relationship to the layer will be removed. + + :param layer: The IfcPresentationLayerAssignment entity to remove + :type layer: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example:: + + layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + ifcopenshell.api.run("layer.remove_layer", model, layer=layer) + """ 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"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py index 0617d9e792..3a1d92c3f1 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/layer/unassign_layer.py @@ -16,18 +16,51 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . -import ifcopenshell - class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, item=None, layer=None): + """Unassigns an item from a layer + + If the representation item isn't assigned to the layer, nothing will + happen. + + :param item: An IfcRepresentationItem element to unassign + :type item: ifcopenshell.entity_instance.entity_instance + :param layer: The IfcPresentationLayerAssignment to unassign from + :type layer: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example:: + + # Remember, all geometry needs to specify the context it is part of first. + # See ifcopenshell.api.context.add_context for details. + model = 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=model + ) + + wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall") + representation = ifcopenshell.api.run("geometry.add_wall_representation", model, + context=body, length=5, height=3, thickness=0.2) + ifcopenshell.api.run("geometry.assign_representation", model, + product=wall, representation=representation) + + # Now let's create a layer that contains walls + layer = ifcopenshell.api.run("layer.add_layer", model, Name="AI-WALL") + + # And assign our wall representation item (in this example, there is + # only one item) to the layer. + ifcopenshell.api.run("layer.assign_layer", model, item=representation.Items[0], layer=layer) + + # Let's undo it! + ifcopenshell.api.run("layer.unassign_layer", model, item=representation.Items[0], layer=layer) + """ self.file = file self.settings = { - "item": None, - "layer": None, + "item": item, + "layer": layer, } - for key, value in settings.items(): - self.settings[key] = value def execute(self): assigned_items = set(self.settings["layer"].AssignedItems) or set()