First Commit

This commit is contained in:
2026-05-31 10:17:09 +07:00
commit 17a9c69379
4547 changed files with 1170384 additions and 0 deletions
@@ -0,0 +1,43 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
"""Elements may be arbitrarily assigned to groups for organisation
Groups are useful for filtering elements or non-hierarchical organisation of a
model. Note that this only targets arbitrary groups. If you want to group
elements into a distribution system, see :mod:`ifcopenshell.api.system`.
"""
from .. import wrap_usecases
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
wrap_usecases(__path__, __name__)
__all__ = [
"add_group",
"assign_group",
"edit_group",
"remove_group",
"unassign_group",
"update_group_products",
]
@@ -0,0 +1,56 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# 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 typing import Optional
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
def add_group(
file: ifcopenshell.file, name: str = "Unnamed", description: Optional[str] = None
) -> ifcopenshell.entity_instance:
"""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.
:param name: The name of the group. Defaults to "Unnamed"
:param description: The description of the purpose of the group.
:return: The newly created IfcGroup
Example:
.. code:: python
ifcopenshell.api.group.add_group(model, name="Unit 1A")
"""
return file.create_entity(
"IfcGroup",
GlobalId=ifcopenshell.guid.new(),
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
Name=name,
Description=description,
)
@@ -0,0 +1,68 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# 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 typing import Union
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
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.
:param products: A list of IfcProduct elements to assign to the group
:param group: The IfcGroup to assign the products to
:return: The IfcRelAssignsToGroup relationship
or `None` if `products` was empty list.
Example:
.. code:: python
group = ifcopenshell.api.group.add_group(model, name="Furniture")
ifcopenshell.api.group.assign_group(model,
products=model.by_type("IfcFurniture"), group=group)
"""
if not products:
return
is_grouped_by: tuple[ifcopenshell.entity_instance, ...]
if not (is_grouped_by := group.IsGroupedBy):
return file.create_entity(
"IfcRelAssignsToGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
"RelatedObjects": products,
"RelatingGroup": group,
},
)
rel = is_grouped_by[0]
related_objects = set(rel.RelatedObjects) or set()
products_set = set(products)
if products_set.issubset(related_objects):
return rel
rel.RelatedObjects = list(related_objects | products_set)
ifcopenshell.api.owner.update_owner_history(file, element=rel)
return rel
@@ -0,0 +1,42 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# 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 typing import Any
import ifcopenshell
def edit_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcGroup
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
:param attributes: a dictionary of attribute names and values.
:return: None
Example:
.. code:: python
group = ifcopenshell.api.group.add_group(model, name="Unit 1A")
ifcopenshell.api.group.edit_group(model,
group=group, attributes={"Description": "All furniture and joinery included in the unit"})
"""
for name, value in attributes.items():
setattr(group, name, value)
@@ -0,0 +1,65 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.util.element
def remove_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance) -> None:
"""Removes a group
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
:return: None
Example:
.. code:: python
group = ifcopenshell.api.group.add_group(model, name="Unit 1A")
ifcopenshell.api.group.remove_group(model, group=group)
"""
for inverse_id in [i.id() for i in file.get_inverse(group)]:
try:
inverse = file.by_id(inverse_id)
except:
continue
if inverse.is_a("IfcRelDefinesByProperties"):
ifcopenshell.api.pset.remove_pset(
file,
product=group,
pset=inverse.RelatingPropertyDefinition,
)
elif inverse.is_a("IfcRelAssignsToGroup"):
if inverse.RelatingGroup == 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 = group.OwnerHistory
file.remove(group)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -0,0 +1,59 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.util.element
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.
:param products: A list of IfcProduct elements to unassign from the group
:param group: The IfcGroup to unassign from
:return: None
Example:
.. code:: python
group = ifcopenshell.api.group.add_group(model, name="Furniture")
furniture = model.by_type("IfcFurniture")
ifcopenshell.api.group.assign_group(model, products=furniture, group=group)
bad_furniture = furniture[0]
ifcopenshell.api.group.unassign_group(model, products=[bad_furniture], group=group)
"""
if not group.IsGroupedBy:
return
rel = group.IsGroupedBy[0]
related_objects = set(rel.RelatedObjects) or set()
products_set = set(products)
related_objects -= products_set
if related_objects:
rel.RelatedObjects = list(related_objects)
ifcopenshell.api.owner.update_owner_history(file, element=rel)
else:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -0,0 +1,69 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
def update_group_products(
file: ifcopenshell.file, group: ifcopenshell.entity_instance, products: list[ifcopenshell.entity_instance]
) -> ifcopenshell.entity_instance:
"""Sets a group products to be an explicit list of products
Any previous products assigned to that group will have their assignment
removed.
:param products: A list of IfcProduct elements to assign to the group
:param group: The IfcGroup to assign the products to
:return: The IfcRelAssignsToGroup relationship
Example:
.. code:: python
group = ifcopenshell.api.group.add_group(model, name="Furniture")
ifcopenshell.api.group.update_group_products(model,
products=model.by_type("IfcFurniture"), group=group)
"""
if not group.IsGroupedBy:
return file.create_entity(
"IfcRelAssignsToGroup",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
"RelatedObjects": products,
"RelatingGroup": group,
}
)
else:
rels = group.IsGroupedBy
objects = set(products)
for rel in rels:
objects.update([g for g in rel.RelatedObjects if g.is_a("IfcGroup")])
to_purge = rels[1:]
for rel in to_purge:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
rels[0].RelatedObjects = list(objects)
return rels[0]