Generate functions for all API usecases for better static code features. See #2693.

This commit is contained in:
Dion Moult
2024-05-06 14:35:39 +10:00
parent 10f894e2ea
commit d11ec67129
330 changed files with 13283 additions and 13751 deletions
@@ -15,3 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from .add_group import add_group
from .assign_group import assign_group
from .edit_group import edit_group
from .remove_group import remove_group
from .unassign_group import unassign_group
from .update_group_products import update_group_products
@@ -20,44 +20,41 @@ import ifcopenshell
import ifcopenshell.api
class Usecase:
def __init__(self, file, Name="Unnamed", Description=None):
"""Adds a new group
def add_group(file, Name="Unnamed", Description=None) -> None:
"""Adds a new group
An IFC group is an arbitrary collection of products, which are typically
physical. It may be used when there is no other more specific group
which may be used. Other types of groups include distribution systems,
which group together products that are connected and circulate a medium
(such as fluid or electricity), or zones, which group together spaces,
or structural load groups, which group together loads for structural
analysis, or inventories, which are groups of assets.
An IFC group is an arbitrary collection of products, which are typically
physical. It may be used when there is no other more specific group
which may be used. Other types of groups include distribution systems,
which group together products that are connected and circulate a medium
(such as fluid or electricity), or zones, which group together spaces,
or structural load groups, which group together loads for structural
analysis, or inventories, which are groups of assets.
:param Name: The name of the group. Defaults to "Unnamed"
:type Name: str, optional
:param Description: The description of the purpose of the group.
:type Description: str, optional
:return: The newly created IfcGroup
:rtype: ifcopenshell.entity_instance
:param Name: The name of the group. Defaults to "Unnamed"
:type Name: str, optional
:param Description: The description of the purpose of the group.
:type Description: str, optional
:return: The newly created IfcGroup
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
ifcopenshell.api.run("group.add_group", model, Name="Unit 1A")
"""
self.file = file
self.settings = {
"Name": Name or "Unnamed",
"Description": Description,
ifcopenshell.api.run("group.add_group", model, Name="Unit 1A")
"""
settings = {
"Name": Name or "Unnamed",
"Description": Description,
}
return file.create_entity(
"IfcGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", file),
"Name": settings["Name"],
"Description": settings["Description"],
}
def execute(self):
return self.file.create_entity(
"IfcGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
"Name": self.settings["Name"],
"Description": self.settings["Description"],
}
)
)
@@ -21,56 +21,53 @@ import ifcopenshell.api
from typing import Union
class Usecase:
def __init__(
self, file: ifcopenshell.file, products: list[ifcopenshell.entity_instance], group: ifcopenshell.entity_instance
):
"""Assigns products to a group
def assign_group(
file: ifcopenshell.file, products: list[ifcopenshell.entity_instance], group: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
"""Assigns products to a group
If a product is already assigned to the group, it will not be assigned
twice.
If a product is already assigned to the group, it will not be assigned
twice.
:param products: A list of IfcProduct elements to assign to the group
:type products: list[ifcopenshell.entity_instance]
:param group: The IfcGroup to assign the products to
:type group: ifcopenshell.entity_instance
:return: The IfcRelAssignsToGroup relationship
or `None` if `products` was empty list.
:rtype: Union[ifcopenshell.entity_instance, None]
:param products: A list of IfcProduct elements to assign to the group
:type products: list[ifcopenshell.entity_instance]
:param group: The IfcGroup to assign the products to
:type group: ifcopenshell.entity_instance
:return: The IfcRelAssignsToGroup relationship
or `None` if `products` was empty list.
:rtype: Union[ifcopenshell.entity_instance, None]
Example:
Example:
.. code:: python
.. code:: python
group = ifcopenshell.api.run("group.add_group", model, Name="Furniture")
ifcopenshell.api.run("group.assign_group", model,
products=model.by_type("IfcFurniture"), group=group)
"""
self.file = file
self.settings = {
"products": products,
"group": group,
}
group = ifcopenshell.api.run("group.add_group", model, Name="Furniture")
ifcopenshell.api.run("group.assign_group", model,
products=model.by_type("IfcFurniture"), group=group)
"""
settings = {
"products": products,
"group": group,
}
def execute(self) -> Union[ifcopenshell.entity_instance, None]:
if not self.settings["products"]:
return
if not settings["products"]:
return
if not self.settings["group"].IsGroupedBy:
return self.file.create_entity(
"IfcRelAssignsToGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
"RelatedObjects": self.settings["products"],
"RelatingGroup": self.settings["group"],
}
)
rel = self.settings["group"].IsGroupedBy[0]
related_objects = set(rel.RelatedObjects) or set()
products = set(self.settings["products"])
if products.issubset(related_objects):
return rel
rel.RelatedObjects = list(related_objects | products)
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": rel})
if not settings["group"].IsGroupedBy:
return file.create_entity(
"IfcRelAssignsToGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", file),
"RelatedObjects": settings["products"],
"RelatingGroup": settings["group"],
}
)
rel = settings["group"].IsGroupedBy[0]
related_objects = set(rel.RelatedObjects) or set()
products = set(settings["products"])
if products.issubset(related_objects):
return rel
rel.RelatedObjects = list(related_objects | products)
ifcopenshell.api.run("owner.update_owner_history", file, **{"element": rel})
return rel
@@ -17,31 +17,28 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, group=None, attributes=None):
"""Edits the attributes of an IfcGroup
def edit_group(file, group=None, attributes=None) -> None:
"""Edits the attributes of an IfcGroup
For more information about the attributes and data types of an
IfcGroup, consult the IFC documentation.
For more information about the attributes and data types of an
IfcGroup, consult the IFC documentation.
:param group: The IfcGroup entity you want to edit
:type group: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
:param group: The IfcGroup entity you want to edit
:type group: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
group = ifcopenshell.api.run("group.add_group", model, Name="Unit 1A")
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 {}}
group = ifcopenshell.api.run("group.add_group", model, Name="Unit 1A")
ifcopenshell.api.run("group.edit_group", model,
group=group, attributes={"Description": "All furniture and joinery included in the unit"})
"""
settings = {"group": group, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["group"], name, value)
for name, value in settings["attributes"].items():
setattr(settings["group"], name, value)
@@ -21,53 +21,50 @@ import ifcopenshell.api
import ifcopenshell.util.element
class Usecase:
def __init__(self, file, group=None):
"""Removes a group
def remove_group(file, group=None) -> None:
"""Removes a group
All products assigned to the group will remain, but the relationship to
the group will be removed.
All products assigned to the group will remain, but the relationship to
the group will be removed.
:param group: The IfcGroup entity you want to remove
:type group: ifcopenshell.entity_instance
:return: None
:rtype: None
:param group: The IfcGroup entity you want to remove
:type group: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
group = ifcopenshell.api.run("group.add_group", model, Name="Unit 1A")
ifcopenshell.api.run("group.remove_group", model, group=group)
"""
self.file = file
self.settings = {"group": group}
group = ifcopenshell.api.run("group.add_group", model, Name="Unit 1A")
ifcopenshell.api.run("group.remove_group", model, group=group)
"""
settings = {"group": group}
def execute(self):
for inverse_id in [i.id() for i in self.file.get_inverse(self.settings["group"])]:
try:
inverse = self.file.by_id(inverse_id)
except:
continue
if inverse.is_a("IfcRelDefinesByProperties"):
ifcopenshell.api.run(
"pset.remove_pset",
self.file,
product=self.settings["group"],
pset=inverse.RelatingPropertyDefinition,
)
elif inverse.is_a("IfcRelAssignsToGroup"):
if inverse.RelatingGroup == self.settings["group"]:
history = inverse.OwnerHistory
self.file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
elif len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
self.file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
history = self.settings["group"].OwnerHistory
self.file.remove(self.settings["group"])
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
for inverse_id in [i.id() for i in file.get_inverse(settings["group"])]:
try:
inverse = file.by_id(inverse_id)
except:
continue
if inverse.is_a("IfcRelDefinesByProperties"):
ifcopenshell.api.run(
"pset.remove_pset",
file,
product=settings["group"],
pset=inverse.RelatingPropertyDefinition,
)
elif inverse.is_a("IfcRelAssignsToGroup"):
if inverse.RelatingGroup == settings["group"]:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
elif len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = settings["group"].OwnerHistory
file.remove(settings["group"])
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -21,48 +21,47 @@ import ifcopenshell.api
import ifcopenshell.util.element
class Usecase:
def __init__(self, file: ifcopenshell.file, products: list[ifcopenshell.entity_instance], group: ifcopenshell.entity_instance):
"""Unassigns products from a group
def unassign_group(
file: ifcopenshell.file, products: list[ifcopenshell.entity_instance], group: ifcopenshell.entity_instance
) -> None:
"""Unassigns products from a group
If the product isn't assigned to the group, nothing will happen.
If the product isn't assigned to the group, nothing will happen.
:param products: A list of IfcProduct elements to unassign from the group
:type products: list[ifcopenshell.entity_instance]
:param group: The IfcGroup to unassign from
:type group: ifcopenshell.entity_instance
:return: None
:rtype: None
:param products: A list of IfcProduct elements to unassign from the group
:type products: list[ifcopenshell.entity_instance]
:param group: The IfcGroup to unassign from
:type group: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
group = ifcopenshell.api.run("group.add_group", model, Name="Furniture")
furniture = model.by_type("IfcFurniture")
ifcopenshell.api.run("group.assign_group", model, products=furniture, group=group)
group = ifcopenshell.api.run("group.add_group", model, Name="Furniture")
furniture = model.by_type("IfcFurniture")
ifcopenshell.api.run("group.assign_group", model, products=furniture, group=group)
bad_furniture = furniture[0]
ifcopenshell.api.run("group.unassign_group", model, products=[bad_furniture], group=group)
"""
self.file = file
self.settings = {
"products": products,
"group": group,
}
bad_furniture = furniture[0]
ifcopenshell.api.run("group.unassign_group", model, products=[bad_furniture], group=group)
"""
settings = {
"products": products,
"group": group,
}
def execute(self) -> None:
if not self.settings["group"].IsGroupedBy:
return
rel = self.settings["group"].IsGroupedBy[0]
related_objects = set(rel.RelatedObjects) or set()
products = set(self.settings["products"])
related_objects -= products
if related_objects:
rel.RelatedObjects = list(related_objects)
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": rel})
else:
history = rel.OwnerHistory
self.file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
if not settings["group"].IsGroupedBy:
return
rel = settings["group"].IsGroupedBy[0]
related_objects = set(rel.RelatedObjects) or set()
products = set(settings["products"])
related_objects -= products
if related_objects:
rel.RelatedObjects = list(related_objects)
ifcopenshell.api.run("owner.update_owner_history", file, **{"element": rel})
else:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -20,51 +20,48 @@ import ifcopenshell
import ifcopenshell.api
class Usecase:
def __init__(self, file, group=None, products=None):
"""Sets a group products to be an explicit list of products
def update_group_products(file, group=None, products=None) -> None:
"""Sets a group products to be an explicit list of products
Any previous products assigned to that group will have their assignment
removed.
Any previous products assigned to that group will have their assignment
removed.
:param products: A list of IfcProduct elements to assign to the group
:type products: list[ifcopenshell.entity_instance]
:param group: The IfcGroup to assign the products to
:type group: ifcopenshell.entity_instance
:return: The IfcRelAssignsToGroup relationship
:rtype: ifcopenshell.entity_instance
:param products: A list of IfcProduct elements to assign to the group
:type products: list[ifcopenshell.entity_instance]
:param group: The IfcGroup to assign the products to
:type group: ifcopenshell.entity_instance
:return: The IfcRelAssignsToGroup relationship
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
group = ifcopenshell.api.run("group.add_group", model, Name="Furniture")
ifcopenshell.api.run("group.update_group_products", model,
products=model.by_type("IfcFurniture"), group=group)
"""
self.file = file
self.settings = {
"group": group,
"products": products,
}
group = ifcopenshell.api.run("group.add_group", model, Name="Furniture")
ifcopenshell.api.run("group.update_group_products", model,
products=model.by_type("IfcFurniture"), group=group)
"""
settings = {
"group": group,
"products": products,
}
def execute(self):
if not self.settings["group"].IsGroupedBy:
return self.file.create_entity(
"IfcRelAssignsToGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
"RelatedObjects": self.settings["products"],
"RelatingGroup": self.settings["group"],
}
)
else:
# assumes 1:1 cardinality, will need to be updated to reflect IFC4 changes
# where the cardinality is 0:? - vulevukusej
rel = self.settings["group"].IsGroupedBy[0]
existing_sub_groups = [g for g in rel.RelatedObjects if g.is_a("IfcGroup")]
if not settings["group"].IsGroupedBy:
return file.create_entity(
"IfcRelAssignsToGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", file),
"RelatedObjects": settings["products"],
"RelatingGroup": settings["group"],
}
)
else:
# assumes 1:1 cardinality, will need to be updated to reflect IFC4 changes
# where the cardinality is 0:? - vulevukusej
rel = settings["group"].IsGroupedBy[0]
existing_sub_groups = [g for g in rel.RelatedObjects if g.is_a("IfcGroup")]
rel.RelatedObjects = self.settings["products"]
for g in existing_sub_groups:
rel.RelatedObjects.add(g)
rel.RelatedObjects = settings["products"]
for g in existing_sub_groups:
rel.RelatedObjects.add(g)