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,27 @@
#
# 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_actor import add_actor
from .add_address import add_address
from .add_application import add_application
from .add_organisation import add_organisation
from .add_person import add_person
from .add_person_and_organisation import add_person_and_organisation
from .add_role import add_role
from .assign_actor import assign_actor
from .create_owner_history import create_owner_history
from .edit_actor import edit_actor
from .edit_address import edit_address
from .edit_organisation import edit_organisation
from .edit_person import edit_person
from .edit_role import edit_role
from .remove_actor import remove_actor
from .remove_address import remove_address
from .remove_application import remove_application
from .remove_organisation import remove_organisation
from .remove_person import remove_person
from .remove_person_and_organisation import remove_person_and_organisation
from .remove_role import remove_role
from .unassign_actor import unassign_actor
from .update_owner_history import update_owner_history
@@ -21,49 +21,46 @@ import ifcopenshell
import ifcopenshell.api
class Usecase:
def __init__(self, file, actor=None, ifc_class="IfcActor"):
"""Adds a new actor
def add_actor(file, actor=None, ifc_class="IfcActor") -> None:
"""Adds a new actor
An actor is a person or an organisation who has a responsibility or role
to play in a project. Actor roles include design consultants,
architects, engineers, cost planners, suppliers, manufacturers,
warrantors, owners, subcontractors, etc.
An actor is a person or an organisation who has a responsibility or role
to play in a project. Actor roles include design consultants,
architects, engineers, cost planners, suppliers, manufacturers,
warrantors, owners, subcontractors, etc.
Actors may either be project actors, who are responsible for the
delivery of the project, or occupants, who are responsible for the
consumption of the project.
Actors may either be project actors, who are responsible for the
delivery of the project, or occupants, who are responsible for the
consumption of the project.
Identifying and managing actors is critical for asset management, and
identifying liability for legal submissions.
Identifying and managing actors is critical for asset management, and
identifying liability for legal submissions.
:param actor: Most commonly, an IfcOrganization (in compliance with GDPR
requirements for non personally identifiable information), or an
IfcPerson if it is a sole individual, or an IfcPersonAndOrganization
if a specific person is liable within an organisation and must be
legally nominated.
:type actor: ifcopenshell.entity_instance
:param ifc_class: Either "IfcActor" or "IfcOccupant".
:type ifc_class: str, optional
:return: The newly created IfcActor or IfcOccupant
:rtype: ifcopenshell.entity_instance
:param actor: Most commonly, an IfcOrganization (in compliance with GDPR
requirements for non personally identifiable information), or an
IfcPerson if it is a sole individual, or an IfcPersonAndOrganization
if a specific person is liable within an organisation and must be
legally nominated.
:type actor: ifcopenshell.entity_instance
:param ifc_class: Either "IfcActor" or "IfcOccupant".
:type ifc_class: str, optional
:return: The newly created IfcActor or IfcOccupant
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
"""
self.file = file
self.settings = {"actor": actor, "ifc_class": ifc_class or "IfcActor"}
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
"""
settings = {"actor": actor, "ifc_class": ifc_class or "IfcActor"}
def execute(self):
actor = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=self.settings["ifc_class"])
actor.TheActor = self.settings["actor"]
return actor
actor = ifcopenshell.api.run("root.create_entity", file, ifc_class=settings["ifc_class"])
actor.TheActor = settings["actor"]
return actor
@@ -17,58 +17,53 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, assigned_object=None, ifc_class="IfcPostalAddress"):
"""Add a new telecom or postal address to an organisation or person
def add_address(file, assigned_object=None, ifc_class="IfcPostalAddress") -> None:
"""Add a new telecom or postal address to an organisation or person
A person or organisation may have associated contact details such as
phone numbers, mailing addresses, websites, email addresses, and instant
messaging handles. This information is critical in recording the contact
information of manufacturers and suppliers for facility management, or
liable actors.
A person or organisation may have associated contact details such as
phone numbers, mailing addresses, websites, email addresses, and instant
messaging handles. This information is critical in recording the contact
information of manufacturers and suppliers for facility management, or
liable actors.
There are two types of addresses, postal addresses for physical snail
mail, and telecom addresses for telephone or internet contact numbers
and addresses.
There are two types of addresses, postal addresses for physical snail
mail, and telecom addresses for telephone or internet contact numbers
and addresses.
:param assigned_object: The IfcOrganization or IfcPerson the contact
address belongs to.
:type assigned_object: ifcopenshell.entity_instance
:param ifc_class: Either IfcPostalAddress or IfcTelecomAddress. Defaults
to IfcPostalAddress.
:type ifc_class: str, optional
:return: The new IfcPostalAddress or IfcTelecomAddress
:rtype: ifcopenshell.entity_instance
:param assigned_object: The IfcOrganization or IfcPerson the contact
address belongs to.
:type assigned_object: ifcopenshell.entity_instance
:param ifc_class: Either IfcPostalAddress or IfcTelecomAddress. Defaults
to IfcPostalAddress.
:type ifc_class: str, optional
:return: The new IfcPostalAddress or IfcTelecomAddress
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
organisation = ifcopenshell.api.run("owner.add_organisation", model)
organisation = ifcopenshell.api.run("owner.add_organisation", model)
# A snail mail address
postal = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcPostalAddress")
ifcopenshell.api.run("owner.edit_address", model, address=postal,
attributes={"Purpose": "OFFICE", "AddressLines": ["42 Wallaby Way"],
"Town": "Sydney", "Region": "NSW", "PostalCode": "2000"})
# A snail mail address
postal = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcPostalAddress")
ifcopenshell.api.run("owner.edit_address", model, address=postal,
attributes={"Purpose": "OFFICE", "AddressLines": ["42 Wallaby Way"],
"Town": "Sydney", "Region": "NSW", "PostalCode": "2000"})
# A phone or internet address
telecom = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcTelecomAddress")
ifcopenshell.api.run("owner.edit_address", model, address=telecom,
attributes={"Purpose": "OFFICE", "TelephoneNumbers": ["+61432466949"],
"ElectronicMailAddresses": ["bobthebuilder@example.com"],
"WWWHomePageURL": "https://thinkmoult.com"})
"""
self.file = file
self.settings = {"assigned_object": assigned_object, "ifc_class": ifc_class}
# A phone or internet address
telecom = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcTelecomAddress")
ifcopenshell.api.run("owner.edit_address", model, address=telecom,
attributes={"Purpose": "OFFICE", "TelephoneNumbers": ["+61432466949"],
"ElectronicMailAddresses": ["bobthebuilder@example.com"],
"WWWHomePageURL": "https://thinkmoult.com"})
"""
settings = {"assigned_object": assigned_object, "ifc_class": ifc_class}
def execute(self):
address = self.file.create_entity(self.settings["ifc_class"], "OFFICE")
addresses = (
list(self.settings["assigned_object"].Addresses) if self.settings["assigned_object"].Addresses else []
)
addresses.append(address)
self.settings["assigned_object"].Addresses = addresses
return address
address = file.create_entity(settings["ifc_class"], "OFFICE")
addresses = list(settings["assigned_object"].Addresses) if settings["assigned_object"].Addresses else []
addresses.append(address)
settings["assigned_object"].Addresses = addresses
return address
@@ -19,50 +19,52 @@
import ifcopenshell.api
def add_application(
file,
application_developer=None,
version=None,
application_full_name="IfcOpenShell",
application_identifier="IfcOpenShell",
) -> None:
"""Adds a new application
IFC data may be associated with an authoring application to identify
which application was responsible for editing or authoring the data. An
application is defined by the developing organisation, as well as a full
name and identifier. This is akin to how web browsers have an
identification string.
:param application_developer: The IfcOrganization responsible for
creating the application. Defaults to generating an IfcOpenShell
organisation if none is provided.
:type application_developer: ifcopenshell.entity_instance, optional
:param version: The version of the application. Defaults to the
ifcopenshell.version data if not specified.
:type version: str, optional
:param application_full_name: The name of the application
:type application_full_name: str, optional
:param application_identifier: An identification string for the
application intended for computers to read.
:type application_identifier: str, optional
Example:
.. code:: python
application = ifcopenshell.api.run("owner.add_application", model)
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {
"application_developer": application_developer,
"version": version or ifcopenshell.version,
"application_full_name": application_full_name,
"application_identifier": application_identifier,
}
return usecase.execute()
class Usecase:
def __init__(
self,
file,
application_developer=None,
version=None,
application_full_name="IfcOpenShell",
application_identifier="IfcOpenShell",
):
"""Adds a new application
IFC data may be associated with an authoring application to identify
which application was responsible for editing or authoring the data. An
application is defined by the developing organisation, as well as a full
name and identifier. This is akin to how web browsers have an
identification string.
:param application_developer: The IfcOrganization responsible for
creating the application. Defaults to generating an IfcOpenShell
organisation if none is provided.
:type application_developer: ifcopenshell.entity_instance, optional
:param version: The version of the application. Defaults to the
ifcopenshell.version data if not specified.
:type version: str, optional
:param application_full_name: The name of the application
:type application_full_name: str, optional
:param application_identifier: An identification string for the
application intended for computers to read.
:type application_identifier: str, optional
Example:
.. code:: python
application = ifcopenshell.api.run("owner.add_application", model)
"""
self.file = file
self.settings = {
"application_developer": application_developer,
"version": version or ifcopenshell.version,
"application_full_name": application_full_name,
"application_identifier": application_identifier,
}
def execute(self):
if not self.settings["application_developer"]:
self.settings["application_developer"] = self.create_application_organisation()
@@ -18,38 +18,37 @@
import ifcopenshell
class Usecase:
def __init__(self, file: ifcopenshell.file, identification: str = "APTR", name: str = "Aperture Science"):
"""Adds a new organisation
def add_organisation(
file: ifcopenshell.file, identification: str = "APTR", name: str = "Aperture Science"
) -> ifcopenshell.entity_instance:
"""Adds a new organisation
Organisations are the main way to identify manufacturers, suppliers, and
other actors who do not have a single representative or must not have
any personally identifiable information.
Organisations are the main way to identify manufacturers, suppliers, and
other actors who do not have a single representative or must not have
any personally identifiable information.
:param identification: The short code identifying the organisation.
Sometimes used in drawing naming schemes. Otherise used as a
canonicalised way of computers to identify the organisation. Like
their stock name.
:type identification: str, optional
:param name: The legal name of the organisation
:type name: str, optional
:return: The newly created IfcOrganization
:rtype: ifcopenshell.entity_instance
:param identification: The short code identifying the organisation.
Sometimes used in drawing naming schemes. Otherise used as a
canonicalised way of computers to identify the organisation. Like
their stock name.
:type identification: str, optional
:param name: The legal name of the organisation
:type name: str, optional
:return: The newly created IfcOrganization
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
"""
self.file = file
self.settings = {"identification": identification, "name": name}
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
"""
settings = {"identification": identification, "name": name}
def execute(self) -> ifcopenshell.entity_instance:
data = {"Name": self.settings["name"]}
if self.file.schema == "IFC2X3":
data["Id"] = self.settings["identification"]
else:
data["Identification"] = self.settings["identification"]
return self.file.create_entity("IfcOrganization", **data)
data = {"Name": settings["name"]}
if file.schema == "IFC2X3":
data["Id"] = settings["identification"]
else:
data["Identification"] = settings["identification"]
return file.create_entity("IfcOrganization", **data)
@@ -18,47 +18,43 @@
import ifcopenshell
class Usecase:
def __init__(
self,
file: ifcopenshell.entity_instance,
identification: str = "HSeldon",
family_name: str = "Seldon",
given_name: str = "Hari",
):
"""Adds a new person
def add_person(
file: ifcopenshell.entity_instance,
identification: str = "HSeldon",
family_name: str = "Seldon",
given_name: str = "Hari",
) -> None:
"""Adds a new person
Persons are used to identify a legal or liable representative of an
organisation or point of contact.
Persons are used to identify a legal or liable representative of an
organisation or point of contact.
:param identification: The computer readable unique identification of
the person. For example, their username in a CDE or alias.
:type identification: str, optional
:param family_name: The family name
:type family_name: str, optional
:param given_name: The given name
:type given_name: str, optional
:return: The newly created IfcPerson
:rtype: ifcopenshell.entity_instance
:param identification: The computer readable unique identification of
the person. For example, their username in a CDE or alias.
:type identification: str, optional
:param family_name: The family name
:type family_name: str, optional
:param given_name: The given name
:type given_name: str, optional
:return: The newly created IfcPerson
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
"""
self.file = file
self.settings = {
"identification": identification,
"family_name": family_name,
"given_name": given_name,
}
ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
"""
settings = {
"identification": identification,
"family_name": family_name,
"given_name": given_name,
}
def execute(self) ->ifcopenshell.entity_instance:
data = {"FamilyName": self.settings["family_name"], "GivenName": self.settings["given_name"]}
if self.file.schema == "IFC2X3":
data["Id"] = self.settings["identification"]
else:
data["Identification"] = self.settings["identification"]
return self.file.create_entity("IfcPerson", **data)
data = {"FamilyName": settings["family_name"], "GivenName": settings["given_name"]}
if file.schema == "IFC2X3":
data["Id"] = settings["identification"]
else:
data["Identification"] = settings["identification"]
return file.create_entity("IfcPerson", **data)
@@ -18,40 +18,36 @@
import ifcopenshell
class Usecase:
def __init__(
self,
file: ifcopenshell.entity_instance,
person: ifcopenshell.entity_instance,
organisation: ifcopenshell.entity_instance,
):
"""Adds a paired person and organisation
def add_person_and_organisation(
file: ifcopenshell.entity_instance,
person: ifcopenshell.entity_instance,
organisation: ifcopenshell.entity_instance,
) -> ifcopenshell.entity_instance:
"""Adds a paired person and organisation
A person and an organisation may be paired to create a representative
belonging to a company.
A person and an organisation may be paired to create a representative
belonging to a company.
:param person: The IfcPerson being the representative of the
organisation.
:type person: ifcopenshell.entity_instance
:param organisation: The IfcOrganization itself.
:type organisation: ifcopenshell.entity_instance
:return: The newly created IfcPersonAndOrganization
:rtype: ifcopenshell.entity_instance
:param person: The IfcPerson being the representative of the
organisation.
:type person: ifcopenshell.entity_instance
:param organisation: The IfcOrganization it
:type organisation: ifcopenshell.entity_instance
:return: The newly created IfcPersonAndOrganization
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
person = ifcopenshell.api.run("owner.add_person", model,
identification="lecorbycorbycorb", family_name="Curbosiar", given_name="Le")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
person = ifcopenshell.api.run("owner.add_person", model,
identification="lecorbycorbycorb", family_name="Curbosiar", given_name="Le")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
ifcopenshell.api.run("owner.add_person_and_organisation", model,
person=person, organisation=organisation)
"""
self.file = file
self.settings = {"person": person, "organisation": organisation}
ifcopenshell.api.run("owner.add_person_and_organisation", model,
person=person, organisation=organisation)
"""
settings = {"person": person, "organisation": organisation}
def execute(self) -> ifcopenshell.entity_instance:
return self.file.createIfcPersonAndOrganization(self.settings["person"], self.settings["organisation"])
return file.createIfcPersonAndOrganization(settings["person"], settings["organisation"])
@@ -17,47 +17,44 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, assigned_object=None, role="ARCHITECT"):
"""Adds and assigns a new role
def add_role(file, assigned_object=None, role="ARCHITECT") -> None:
"""Adds and assigns a new role
People and organisations must play one or more roles on a project. Roles
include architects, engineers, subcontractors, clients, manufacturers,
etc. Typically these roles and their corresponding responsibilities will
be outlined in contractual documents.
People and organisations must play one or more roles on a project. Roles
include architects, engineers, subcontractors, clients, manufacturers,
etc. Typically these roles and their corresponding responsibilities will
be outlined in contractual documents.
This function will both add and assign the role to the person or
organisation.
This function will both add and assign the role to the person or
organisation.
:param assigned_object: The IfcPerson or IfcOrganization the role should
be assigned to.
:type assigned_object: ifcopenshell.entity_instance
:param role: The type of role, taken from the IFC documentation for
IfcActorRole, or a custom name.
:type role: str, optional
:return: The newly created IfcActorRole
:rtype: ifcopenshell.entity_instance
:param assigned_object: The IfcPerson or IfcOrganization the role should
be assigned to.
:type assigned_object: ifcopenshell.entity_instance
:param role: The type of role, taken from the IFC documentation for
IfcActorRole, or a custom name.
:type role: str, optional
:return: The newly created IfcActorRole
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
"""
self.file = file
self.settings = {"assigned_object": assigned_object, "role": role}
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
"""
settings = {"assigned_object": assigned_object, "role": role}
def execute(self):
element = self.file.createIfcActorRole("ARCHITECT")
if self.settings["role"]:
try:
element.Role = self.settings["role"]
except:
element.Role = "USERDEFINED"
element.UserDefinedRole = self.settings["role"]
roles = list(self.settings["assigned_object"].Roles) if self.settings["assigned_object"].Roles else []
roles.append(element)
self.settings["assigned_object"].Roles = roles
return element
element = file.createIfcActorRole("ARCHITECT")
if settings["role"]:
try:
element.Role = settings["role"]
except:
element.Role = "USERDEFINED"
element.UserDefinedRole = settings["role"]
roles = list(settings["assigned_object"].Roles) if settings["assigned_object"].Roles else []
roles.append(element)
settings["assigned_object"].Roles = roles
return element
@@ -20,88 +20,85 @@ import ifcopenshell
import ifcopenshell.api
class Usecase:
def __init__(self, file, relating_actor=None, related_object=None):
"""Assigns an actor to an object
def assign_actor(file, relating_actor=None, related_object=None) -> None:
"""Assigns an actor to an object
An actor may be assigned to objects which implies that the actor is
responsible for. This is most commonly used in facility management for
indicating the manufacturers, suppliers, and warrantors for product
types.
An actor may be assigned to objects which implies that the actor is
responsible for. This is most commonly used in facility management for
indicating the manufacturers, suppliers, and warrantors for product
types.
Here are a list of objects you may assign an actor to:
Here are a list of objects you may assign an actor to:
* IfcControl: Indicates project directives issued by the actor.
* IfcGroup: Indicates groups for which the actor is responsible.
* IfcProduct: Indicates products for which the actor is responsible.
* IfcProcess: Indicates processes for which the actor is responsible.
* IfcResource: Indicates resources for which the actor is responsible to
allocate, manage, or delegate. This is not the actor actually using
the resource or performing the work. For that type of actor, see
ifcopenshell.api.resource.assign_resource.
* IfcControl: Indicates project directives issued by the actor.
* IfcGroup: Indicates groups for which the actor is responsible.
* IfcProduct: Indicates products for which the actor is responsible.
* IfcProcess: Indicates processes for which the actor is responsible.
* IfcResource: Indicates resources for which the actor is responsible to
allocate, manage, or delegate. This is not the actor actually using
the resource or performing the work. For that type of actor, see
ifcopenshell.api.resource.assign_resource.
:param relating_actor: The IfcActor who is responsible for the object.
:type relating_actor: ifcopenshell.entity_instance
:param related_object: The object the actor is responsible for.
:type related_object: ifcopenshell.entity_instance
:return: The newly created IfcRelAssignsToActor relationship.
:rtype: ifcopenshell.entity_instance
:param relating_actor: The IfcActor who is responsible for the object.
:type relating_actor: ifcopenshell.entity_instance
:param related_object: The object the actor is responsible for.
:type related_object: ifcopenshell.entity_instance
:return: The newly created IfcRelAssignsToActor relationship.
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
# We need to procure and install 2 of this particular pump type in our facility.
pump_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcPumpType")
# We need to procure and install 2 of this particular pump type in our facility.
pump_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcPumpType")
# Define who the manufacturer is
manufacturer = ifcopenshell.api.run("owner.add_organisation", model,
identification="PWP", name="Pumps With Power")
ifcopenshell.api.run("owner.add_role", model, assigned_object=manufacturer, role="MANUFACTURER")
# Define who the manufacturer is
manufacturer = ifcopenshell.api.run("owner.add_organisation", model,
identification="PWP", name="Pumps With Power")
ifcopenshell.api.run("owner.add_role", model, assigned_object=manufacturer, role="MANUFACTURER")
# To help our facility manager, it's nice to provide contact details
# of the manufacturer so they know how to call when the pump breaks.
telecom = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcTelecomAddress")
ifcopenshell.api.run("owner.edit_address", model, address=telecom,
attributes={"Purpose": "OFFICE", "TelephoneNumbers": ["+61432466949"],
"ElectronicMailAddresses": ["contact@example.com"],
"WWWHomePageURL": "https://example.com"})
# To help our facility manager, it's nice to provide contact details
# of the manufacturer so they know how to call when the pump breaks.
telecom = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcTelecomAddress")
ifcopenshell.api.run("owner.edit_address", model, address=telecom,
attributes={"Purpose": "OFFICE", "TelephoneNumbers": ["+61432466949"],
"ElectronicMailAddresses": ["contact@example.com"],
"WWWHomePageURL": "https://example.com"})
# Make the manufacturer responsible for that pump type.
ifcopenshell.api.run("owner.assign_actor", model,
relating_actor=manufacturer, related_object=pump_type)
"""
self.file = file
self.settings = {
"relating_actor": relating_actor,
"related_object": related_object,
}
# Make the manufacturer responsible for that pump type.
ifcopenshell.api.run("owner.assign_actor", model,
relating_actor=manufacturer, related_object=pump_type)
"""
settings = {
"relating_actor": relating_actor,
"related_object": related_object,
}
def execute(self):
if self.settings["related_object"].HasAssignments:
for rel in self.settings["related_object"].HasAssignments:
if rel.is_a("IfcRelAssignsToActor") and rel.RelatingActor == self.settings["relating_actor"]:
return
if settings["related_object"].HasAssignments:
for rel in settings["related_object"].HasAssignments:
if rel.is_a("IfcRelAssignsToActor") and rel.RelatingActor == settings["relating_actor"]:
return
rel = None
rel = None
if self.settings["relating_actor"].IsActingUpon:
rel = self.settings["relating_actor"].IsActingUpon[0]
if settings["relating_actor"].IsActingUpon:
rel = settings["relating_actor"].IsActingUpon[0]
if rel:
related_objects = list(rel.RelatedObjects)
related_objects.append(self.settings["related_object"])
rel.RelatedObjects = related_objects
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": rel})
else:
rel = self.file.create_entity(
"IfcRelAssignsToActor",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
"RelatedObjects": [self.settings["related_object"]],
"RelatingActor": self.settings["relating_actor"],
}
)
return rel
if rel:
related_objects = list(rel.RelatedObjects)
related_objects.append(settings["related_object"])
rel.RelatedObjects = related_objects
ifcopenshell.api.run("owner.update_owner_history", file, **{"element": rel})
else:
rel = file.create_entity(
"IfcRelAssignsToActor",
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", file),
"RelatedObjects": [settings["related_object"]],
"RelatingActor": settings["relating_actor"],
}
)
return rel
@@ -22,100 +22,97 @@ import ifcopenshell.api.owner.settings
from typing import Union
class Usecase:
def __init__(self, file: ifcopenshell.entity_instance):
"""Creates a new owner history indicating an element was added
def create_owner_history(file: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
"""Creates a new owner history indicating an element was added
Any object in IFC with a unique ID and name (such as physical products,
tasks, calendars, etc) may have an owner associated with it. An owner is
a liable person and/or organisation which a bit of metadata indicating
whether they have created the object, edited the object, when the change
was made, and which application they used.
Any object in IFC with a unique ID and name (such as physical products,
tasks, calendars, etc) may have an owner associated with it. An owner is
a liable person and/or organisation which a bit of metadata indicating
whether they have created the object, edited the object, when the change
was made, and which application they used.
IFC does not offer a comprehensive specification for version control and
change tracking, as this is completely out of scope. However this
similar ability allows IFC to satisfy legal requirements where object
ownership, responsibilities, and permissions must be specified.
Recording the owner is mandatory in IFC2X3 but optional in IFC4. It is
not recommended to store this ownership data in IFC4 unless a legal
requirement is in place.
IFC does not offer a comprehensive specification for version control and
change tracking, as this is completely out of scope. However this
similar ability allows IFC to satisfy legal requirements where object
ownership, responsibilities, and permissions must be specified.
Recording the owner is mandatory in IFC2X3 but optional in IFC4. It is
not recommended to store this ownership data in IFC4 unless a legal
requirement is in place.
Because owner tracking is mandatory in IFC2X3, be aware that some
configuration may be required to work correctly. Read on.
Because owner tracking is mandatory in IFC2X3, be aware that some
configuration may be required to work correctly. Read on.
To track the owner, at a minimum we have to know the application that
the element was authored from, as well as the user (person and
organisation) that made the change. The IfcOpenShell API is a low level
software library and will not know what application the API is being
called from, and nor does it have the responsibility to manage the
"active user" making edits, which may be as simple as hardcoding it to
"Bob" or even be as complex as integration with a CDE's authentication
system. As a result, the developer responsible to integrate with
IfcOpenShell is expected to overload the
ifcopenshell.api.owner.settings.get_user and
ifcopenshell.api.owner.settings.get_application functions.
To track the owner, at a minimum we have to know the application that
the element was authored from, as well as the user (person and
organisation) that made the change. The IfcOpenShell API is a low level
software library and will not know what application the API is being
called from, and nor does it have the responsibility to manage the
"active user" making edits, which may be as simple as hardcoding it to
"Bob" or even be as complex as integration with a CDE's authentication
system. As a result, the developer responsible to integrate with
IfcOpenShell is expected to overload the
ifcopenshell.api.owner.settings.get_user and
ifcopenshell.api.owner.settings.get_application functions.
It is not necessary to call this function directly if you are already
using other API calls. It is a low level function only available if you
are writing your own advanced scripts and want to take advantage of the
easier ownership tracking.
It is not necessary to call this function directly if you are already
using other API calls. It is a low level function only available if you
are writing your own advanced scripts and want to take advantage of the
easier ownership tracking.
:return: The newly created IfcOwnerHistory element or `None` if it's
not IFC2X3 and user or application is not found in the current project.
:rtype: Union[ifcopenshell.entity_instance, None]
:return: The newly created IfcOwnerHistory element or `None` if it's
not IFC2X3 and user or application is not found in the current project.
:rtype: Union[ifcopenshell.entity_instance, None]
Example:
Example:
.. code:: python
.. code:: python
# Let's imagine we're writing a small script, not large enough to be
# its own fully branded application. In this case, let's use the
# default application which is prepopulated with "IfcOpenShell" as
# the name and version.
application = ifcopenshell.api.run("owner.add_application", model)
# Let's imagine we're writing a small script, not large enough to be
# its own fully branded application. In this case, let's use the
# default application which is prepopulated with "IfcOpenShell" as
# the name and version.
application = ifcopenshell.api.run("owner.add_application", model)
# Let's imagine we run this as an automated QA process in an
# architectural firm. However, the results must be signed off by the
# registered architect who is liable for the project.
person = ifcopenshell.api.run("owner.add_person", model,
identification="LPARTEE", family_name="Partee", given_name="Leeable")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
user = ifcopenshell.api.run("owner.add_person_and_organisation", model,
person=person, organisation=organisation)
# Let's imagine we run this as an automated QA process in an
# architectural firm. However, the results must be signed off by the
# registered architect who is liable for the project.
person = ifcopenshell.api.run("owner.add_person", model,
identification="LPARTEE", family_name="Partee", given_name="Leeable")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
user = ifcopenshell.api.run("owner.add_person_and_organisation", model,
person=person, organisation=organisation)
# Let's configure our owner settings to hardcode always returning
# the application and user. In theory, you could build complex user
# access control lookup functions here, but this is simple enough.
ifcopenshell.api.owner.settings.get_user = lambda x: user
ifcopenshell.api.owner.settings.get_application = lambda x: application
# Let's configure our owner settings to hardcode always returning
# the application and user. In theory, you could build complex user
# access control lookup functions here, but this is simple enough.
ifcopenshell.api.owner.settings.get_user = lambda x: user
ifcopenshell.api.owner.settings.get_application = lambda x: application
# We've finished our ownership setup. Now let's start our script and
# create a space. Notice we don't actually call
# create_owner_history at all. This is already automatically handled
# by the API when necessary. Under the hood, the API is actually
# running this code on the IfcSpace element:
# element.OwnerHistory = ifcopenshell.api.run("owner.create_owner_history", model)
space = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSpace")
"""
self.file = file
self.settings = {}
# We've finished our ownership setup. Now let's start our script and
# create a space. Notice we don't actually call
# create_owner_history at all. This is already automatically handled
# by the API when necessary. Under the hood, the API is actually
# running this code on the IfcSpace element:
# element.OwnerHistory = ifcopenshell.api.run("owner.create_owner_history", model)
space = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSpace")
"""
settings = {}
def execute(self) -> Union[ifcopenshell.entity_instance, None]:
user = ifcopenshell.api.owner.settings.get_user(self.file)
if self.file.schema != "IFC2X3" and not user:
return
application = ifcopenshell.api.owner.settings.get_application(self.file)
if self.file.schema != "IFC2X3" and not application:
return
return self.file.create_entity(
"IfcOwnerHistory",
OwningUser=user,
OwningApplication=application,
State="READWRITE",
ChangeAction="ADDED",
LastModifiedDate=int(time.time()),
LastModifyingUser=user,
LastModifyingApplication=application,
CreationDate=int(time.time()),
)
user = ifcopenshell.api.owner.settings.get_user(file)
if file.schema != "IFC2X3" and not user:
return
application = ifcopenshell.api.owner.settings.get_application(file)
if file.schema != "IFC2X3" and not application:
return
return file.create_entity(
"IfcOwnerHistory",
OwningUser=user,
OwningApplication=application,
State="READWRITE",
ChangeAction="ADDED",
LastModifiedDate=int(time.time()),
LastModifyingUser=user,
LastModifyingApplication=application,
CreationDate=int(time.time()),
)
@@ -17,40 +17,37 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, actor=None, attributes=None):
"""Edits the attributes of an IfcActor
def edit_actor(file, actor=None, attributes=None) -> None:
"""Edits the attributes of an IfcActor
For more information about the attributes and data types of an
IfcActor, consult the IFC documentation.
For more information about the attributes and data types of an
IfcActor, consult the IFC documentation.
:param actor: The IfcActor entity you want to edit
:type actor: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
:param actor: The IfcActor entity you want to edit
:type actor: 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
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation)
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "ARCHITECT"})
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation)
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "ARCHITECT"})
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
# Edit the description of the attribute.
ifcopenshell.api.run("actor.edit_actor", model,
actor=actor, attributes={"Description": "Responsible for buildings A, B, and C."})
"""
self.file = file
self.settings = {"actor": actor, "attributes": attributes or {}}
# Edit the description of the attribute.
ifcopenshell.api.run("actor.edit_actor", model,
actor=actor, attributes={"Description": "Responsible for buildings A, B, and C."})
"""
settings = {"actor": actor, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["actor"], name, value)
for name, value in settings["attributes"].items():
setattr(settings["actor"], name, value)
@@ -17,42 +17,39 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, address=None, attributes=None):
"""Edits the attributes of an IfcAddress
def edit_address(file, address=None, attributes=None) -> None:
"""Edits the attributes of an IfcAddress
For more information about the attributes and data types of an
IfcAddress, consult the IFC documentation.
For more information about the attributes and data types of an
IfcAddress, consult the IFC documentation.
:param address: The IfcAddress entity you want to edit
:type address: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
:param address: The IfcAddress entity you want to edit
:type address: 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
# A snail mail address
postal = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcPostalAddress")
ifcopenshell.api.run("owner.edit_address", model, address=postal,
attributes={"Purpose": "OFFICE", "AddressLines": ["42 Wallaby Way"],
"Town": "Sydney", "Region": "NSW", "PostalCode": "2000"})
# A snail mail address
postal = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcPostalAddress")
ifcopenshell.api.run("owner.edit_address", model, address=postal,
attributes={"Purpose": "OFFICE", "AddressLines": ["42 Wallaby Way"],
"Town": "Sydney", "Region": "NSW", "PostalCode": "2000"})
# A phone or internet address
telecom = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcTelecomAddress")
ifcopenshell.api.run("owner.edit_address", model, address=telecom,
attributes={"Purpose": "OFFICE", "TelephoneNumbers": ["+61432466949"],
"ElectronicMailAddresses": ["bobthebuilder@example.com"],
"WWWHomePageURL": "https://thinkmoult.com"})
"""
self.file = file
self.settings = {"address": address, "attributes": attributes or {}}
# A phone or internet address
telecom = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcTelecomAddress")
ifcopenshell.api.run("owner.edit_address", model, address=telecom,
attributes={"Purpose": "OFFICE", "TelephoneNumbers": ["+61432466949"],
"ElectronicMailAddresses": ["bobthebuilder@example.com"],
"WWWHomePageURL": "https://thinkmoult.com"})
"""
settings = {"address": address, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["address"], name, value)
for name, value in settings["attributes"].items():
setattr(settings["address"], name, value)
@@ -17,32 +17,29 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, organisation=None, attributes=None):
"""Edits the attributes of an IfcOrganization
def edit_organisation(file, organisation=None, attributes=None) -> None:
"""Edits the attributes of an IfcOrganization
For more information about the attributes and data types of an
IfcOrganization, consult the IFC documentation.
For more information about the attributes and data types of an
IfcOrganization, consult the IFC documentation.
:param organisation: The IfcOrganization entity you want to edit
:type organisation: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
:param organisation: The IfcOrganization entity you want to edit
:type organisation: 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
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects With Ballpens")
ifcopenshell.api.run("owner.edit_organisation", model, organisation=organisation,
attributes={"name": "Architects Without Ballpens"})
"""
self.file = file
self.settings = {"organisation": organisation, "attributes": attributes or {}}
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects With Ballpens")
ifcopenshell.api.run("owner.edit_organisation", model, organisation=organisation,
attributes={"name": "Architects Without Ballpens"})
"""
settings = {"organisation": organisation, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["organisation"], name, value)
for name, value in settings["attributes"].items():
setattr(settings["organisation"], name, value)
@@ -17,32 +17,29 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, person=None, attributes=None):
"""Edits the attributes of an IfcPerson
def edit_person(file, person=None, attributes=None) -> None:
"""Edits the attributes of an IfcPerson
For more information about the attributes and data types of an
IfcPerson, consult the IFC documentation.
For more information about the attributes and data types of an
IfcPerson, consult the IFC documentation.
:param person: The IfcPerson entity you want to edit
:type person: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
:param person: The IfcPerson entity you want to edit
:type person: 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
person = ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
ifcopenshell.api.run("owner.edit_person", model, person=person,
attributes={"MiddleNames": ["The"], "FamilyName": "Builder"})
"""
self.file = file
self.settings = {"person": person, "attributes": attributes or {}}
person = ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
ifcopenshell.api.run("owner.edit_person", model, person=person,
attributes={"MiddleNames": ["The"], "FamilyName": "Builder"})
"""
settings = {"person": person, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["person"], name, value)
for name, value in settings["attributes"].items():
setattr(settings["person"], name, value)
@@ -17,36 +17,33 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, role=None, attributes=None):
"""Edits the attributes of an IfcActorRole
def edit_role(file, role=None, attributes=None) -> None:
"""Edits the attributes of an IfcActorRole
For more information about the attributes and data types of an
IfcActorRole, consult the IFC documentation.
For more information about the attributes and data types of an
IfcActorRole, consult the IFC documentation.
:param role: The IfcActorRole entity you want to edit
:type role: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
:param role: The IfcActorRole entity you want to edit
:type role: 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
person = ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
person = ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
# By default, the role is an architect
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=person)
# By default, the role is an architect
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=person)
# But Bob is not an architect
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "CONSTRUCTIONMANAGER"})
"""
self.file = file
self.settings = {"role": role, "attributes": attributes or {}}
# But Bob is not an architect
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "CONSTRUCTIONMANAGER"})
"""
settings = {"role": role, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["role"], name, value)
for name, value in settings["attributes"].items():
setattr(settings["role"], name, value)
@@ -20,36 +20,33 @@ import ifcopenshell
import ifcopenshell.util.element
class Usecase:
def __init__(self, file, actor=None):
"""Removes an actor
def remove_actor(file, actor=None) -> None:
"""Removes an actor
:param actor: The IfcActor to remove.
:type actor: ifcopenshell.entity_instance
:return: None
:rtype: None
:param actor: The IfcActor to remove.
:type actor: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation)
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "ARCHITECT"})
# Setup an organisation with a single role
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation)
ifcopenshell.api.run("owner.edit_role", model, role=role, attributes={"Role": "ARCHITECT"})
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
# Assign that organisation to a newly created actor
actor = ifcopenshell.api.run("owner.add_actor", model, actor=organisation)
# Actually we need ballpens on this project
ifcopenshell.api.run("owner.remove_actor", model, actor=actor)
"""
self.file = file
self.settings = {"actor": actor}
# Actually we need ballpens on this project
ifcopenshell.api.run("owner.remove_actor", model, actor=actor)
"""
settings = {"actor": actor}
def execute(self):
history = self.settings["actor"].OwnerHistory
self.file.remove(self.settings["actor"])
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
history = settings["actor"].OwnerHistory
file.remove(settings["actor"])
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -17,35 +17,32 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, address=None):
"""Removes an address
def remove_address(file, address=None) -> None:
"""Removes an address
Naturally, any organisations or people using that address will have the
relationship removed.
Naturally, any organisations or people using that address will have the
relationship removed.
:param address: The IfcAddress to remove.
:type address: ifcopenshell.entity_instance
:return: None
:rtype: None
:param address: The IfcAddress to remove.
:type address: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
organisation = ifcopenshell.api.run("owner.add_organisation", model)
address = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcPostalAddress")
organisation = ifcopenshell.api.run("owner.add_organisation", model)
address = ifcopenshell.api.run("owner.add_address", model,
assigned_object=organisation, ifc_class="IfcPostalAddress")
# Change our mind and delete it
ifcopenshell.api.run("owner.remove_address", model, address=address)
"""
self.file = file
self.settings = {"address": address}
# Change our mind and delete it
ifcopenshell.api.run("owner.remove_address", model, address=address)
"""
settings = {"address": address}
def execute(self):
for inverse in self.file.get_inverse(self.settings["address"]):
if inverse.is_a() in ("IfcOrganization", "IfcPerson"):
if inverse.Addresses == (self.settings["address"],):
inverse.Addresses = None
self.file.remove(self.settings["address"])
for inverse in file.get_inverse(settings["address"]):
if inverse.is_a() in ("IfcOrganization", "IfcPerson"):
if inverse.Addresses == (settings["address"],):
inverse.Addresses = None
file.remove(settings["address"])
@@ -17,27 +17,24 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, application=None):
"""Removes an application
def remove_application(file, application=None) -> None:
"""Removes an application
Warning: removing an application may invalidate ownership histories.
Check whether or not the application is used anywhere prior to removal.
Warning: removing an application may invalidate ownership histories.
Check whether or not the application is used anywhere prior to removal.
:param address: The IfcApplication to remove.
:type address: ifcopenshell.entity_instance
:return: None
:rtype: None
:param address: The IfcApplication to remove.
:type address: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
application = ifcopenshell.api.run("owner.add_application", model)
ifcopenshell.api.run("owner.remove_address", model, application=application)
"""
self.file = file
self.settings = {"application": application}
application = ifcopenshell.api.run("owner.add_application", model)
ifcopenshell.api.run("owner.remove_address", model, application=application)
"""
settings = {"application": application}
def execute(self):
self.file.remove(self.settings["application"])
file.remove(settings["application"])
@@ -19,53 +19,50 @@
import ifcopenshell.api
class Usecase:
def __init__(self, file, organisation=None):
"""Remove an organisation
def remove_organisation(file, organisation=None) -> None:
"""Remove an organisation
All roles and addresses assigned to the organisation will also be
removed.
All roles and addresses assigned to the organisation will also be
removed.
:param organisation: The IfcOrganization to remove
:type organisation: ifcopenshell.entity_instance
:return: None
:rtype: None
:param organisation: The IfcOrganization to remove
:type organisation: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
ifcopenshell.api.run("owner.remove_organisation", model, organisation=organisation)
"""
self.file = file
self.settings = {"organisation": organisation}
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
ifcopenshell.api.run("owner.remove_organisation", model, organisation=organisation)
"""
settings = {"organisation": organisation}
def execute(self):
for role in self.settings["organisation"].Roles or []:
if len(self.file.get_inverse(role)) == 1:
ifcopenshell.api.run("owner.remove_role", self.file, role=role)
for address in self.settings["organisation"].Addresses or []:
if len(self.file.get_inverse(address)) == 1:
ifcopenshell.api.run("owner.remove_address", self.file, address=address)
for inverse in self.file.get_inverse(self.settings["organisation"]):
if inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatingOrganization == self.settings["organisation"]:
self.file.remove(inverse)
elif inverse.RelatedOrganizations == (self.settings["organisation"],):
self.file.remove(inverse)
elif inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (self.settings["organisation"],):
inverse.Editors = None
elif inverse.is_a("IfcPersonAndOrganization"):
ifcopenshell.api.run("owner.remove_person_and_organisation", self.file, person_and_organisation=inverse)
elif inverse.is_a("IfcActor"):
ifcopenshell.api.run("root.remove_product", self.file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship") and not inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatedResourceObjects == (self.settings["organisation"],):
self.file.remove(inverse)
elif inverse.is_a("IfcApplication"):
ifcopenshell.api.run("owner.remove_application", self.file, application=inverse)
for role in settings["organisation"].Roles or []:
if len(file.get_inverse(role)) == 1:
ifcopenshell.api.run("owner.remove_role", file, role=role)
for address in settings["organisation"].Addresses or []:
if len(file.get_inverse(address)) == 1:
ifcopenshell.api.run("owner.remove_address", file, address=address)
for inverse in file.get_inverse(settings["organisation"]):
if inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatingOrganization == settings["organisation"]:
file.remove(inverse)
elif inverse.RelatedOrganizations == (settings["organisation"],):
file.remove(inverse)
elif inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (settings["organisation"],):
inverse.Editors = None
elif inverse.is_a("IfcPersonAndOrganization"):
ifcopenshell.api.run("owner.remove_person_and_organisation", file, person_and_organisation=inverse)
elif inverse.is_a("IfcActor"):
ifcopenshell.api.run("root.remove_product", file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship") and not inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatedResourceObjects == (settings["organisation"],):
file.remove(inverse)
elif inverse.is_a("IfcApplication"):
ifcopenshell.api.run("owner.remove_application", file, application=inverse)
self.file.remove(self.settings["organisation"])
file.remove(settings["organisation"])
@@ -19,51 +19,48 @@
import ifcopenshell.api
class Usecase:
def __init__(self, file, person=None):
"""Remove an person
def remove_person(file, person=None) -> None:
"""Remove an person
All roles and addresses assigned to the person will also be
removed.
All roles and addresses assigned to the person will also be
removed.
:param person: The IfcPerson to remove
:type person: ifcopenshell.entity_instance
:return: None
:rtype: None
:param person: The IfcPerson to remove
:type person: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
ifcopenshell.api.run("owner.remove_person", model, person=person)
"""
self.file = file
self.settings = {"person": person}
ifcopenshell.api.run("owner.add_person", model,
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
ifcopenshell.api.run("owner.remove_person", model, person=person)
"""
settings = {"person": person}
def execute(self):
for role in self.settings["person"].Roles or []:
if len(self.file.get_inverse(role)) == 1:
ifcopenshell.api.run("owner.remove_role", self.file, role=role)
for address in self.settings["person"].Addresses or []:
if len(self.file.get_inverse(address)) == 1:
ifcopenshell.api.run("owner.remove_address", self.file, address=address)
for inverse in self.file.get_inverse(self.settings["person"]):
if inverse.is_a("IfcWorkControl"):
if inverse.Creators == (self.settings["person"],):
inverse.Creators = None
elif inverse.is_a("IfcInventory"):
if inverse.ResponsiblePersons == (self.settings["person"],):
inverse.ResponsiblePersons = None
elif inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (self.settings["person"],):
inverse.Editors = None
elif inverse.is_a("IfcPersonAndOrganization"):
ifcopenshell.api.run("owner.remove_person_and_organisation", self.file, person_and_organisation=inverse)
elif inverse.is_a("IfcActor"):
ifcopenshell.api.run("root.remove_product", self.file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship"):
if inverse.RelatedResourceObjects == (self.settings["person"],):
self.file.remove(inverse)
self.file.remove(self.settings["person"])
for role in settings["person"].Roles or []:
if len(file.get_inverse(role)) == 1:
ifcopenshell.api.run("owner.remove_role", file, role=role)
for address in settings["person"].Addresses or []:
if len(file.get_inverse(address)) == 1:
ifcopenshell.api.run("owner.remove_address", file, address=address)
for inverse in file.get_inverse(settings["person"]):
if inverse.is_a("IfcWorkControl"):
if inverse.Creators == (settings["person"],):
inverse.Creators = None
elif inverse.is_a("IfcInventory"):
if inverse.ResponsiblePersons == (settings["person"],):
inverse.ResponsiblePersons = None
elif inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (settings["person"],):
inverse.Editors = None
elif inverse.is_a("IfcPersonAndOrganization"):
ifcopenshell.api.run("owner.remove_person_and_organisation", file, person_and_organisation=inverse)
elif inverse.is_a("IfcActor"):
ifcopenshell.api.run("root.remove_product", file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship"):
if inverse.RelatedResourceObjects == (settings["person"],):
file.remove(inverse)
file.remove(settings["person"])
@@ -19,45 +19,42 @@
import ifcopenshell.api
class Usecase:
def __init__(self, file, person_and_organisation=None):
"""Removes a person and organisation
def remove_person_and_organisation(file, person_and_organisation=None) -> None:
"""Removes a person and organisation
Note that the underlying person and organisation is not removed, only
the "person and organisation" group.
Note that the underlying person and organisation is not removed, only
the "person and organisation" group.
:param person_and_organisation: The IfcPersonAndOrganization to remove.
:type person_and_organisation: ifcopenshell.entity_instance
:return: None
:rtype: None
:param person_and_organisation: The IfcPersonAndOrganization to remove.
:type person_and_organisation: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
person = ifcopenshell.api.run("owner.add_person", model,
identification="lecorbycorbycorb", family_name="Curbosiar", given_name="Le")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
person = ifcopenshell.api.run("owner.add_person", model,
identification="lecorbycorbycorb", family_name="Curbosiar", given_name="Le")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
user = ifcopenshell.api.run("owner.add_person_and_organisation", model,
person=person, organisation=organisation)
user = ifcopenshell.api.run("owner.add_person_and_organisation", model,
person=person, organisation=organisation)
ifcopenshell.api.run("owner.remove_person_and_organisation", model, person_and_organisation=user)
"""
self.file = file
self.settings = {"person_and_organisation": person_and_organisation}
ifcopenshell.api.run("owner.remove_person_and_organisation", model, person_and_organisation=user)
"""
settings = {"person_and_organisation": person_and_organisation}
def execute(self):
for inverse in self.file.get_inverse(self.settings["person_and_organisation"]):
if inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (self.settings["person_and_organisation"],):
inverse.Editors = None
elif inverse.is_a("IfcActor"):
ifcopenshell.api.run("root.remove_product", self.file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship"):
if inverse.RelatedResourceObjects == (self.settings["person_and_organisation"],):
self.file.remove(inverse)
elif inverse.is_a("IfcOwnerHistory"):
self.file.remove(inverse)
self.file.remove(self.settings["person_and_organisation"])
for inverse in file.get_inverse(settings["person_and_organisation"]):
if inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (settings["person_and_organisation"],):
inverse.Editors = None
elif inverse.is_a("IfcActor"):
ifcopenshell.api.run("root.remove_product", file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship"):
if inverse.RelatedResourceObjects == (settings["person_and_organisation"],):
file.remove(inverse)
elif inverse.is_a("IfcOwnerHistory"):
file.remove(inverse)
file.remove(settings["person_and_organisation"])
@@ -17,38 +17,35 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
class Usecase:
def __init__(self, file, role=None):
"""Removes a role
def remove_role(file, role=None) -> None:
"""Removes a role
People and organisations using the role will be untouched. This may
leave some of them without roles.
People and organisations using the role will be untouched. This may
leave some of them without roles.
:param role: The IfcActorRole to remove.
:type role: ifcopenshell.entity_instance
:return: None
:rtype: None
:param role: The IfcActorRole to remove.
:type role: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
Example:
.. code:: python
.. code:: python
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
organisation = ifcopenshell.api.run("owner.add_organisation", model,
identification="AWB", name="Architects Without Ballpens")
role = ifcopenshell.api.run("owner.add_role", model, assigned_object=organisation, role="ARCHITECT")
# After running this, the organisation will have no role again
ifcopenshell.api.run("owner.remove_role", model, role=role)
"""
self.file = file
self.settings = {"role": role}
# After running this, the organisation will have no role again
ifcopenshell.api.run("owner.remove_role", model, role=role)
"""
settings = {"role": role}
def execute(self):
for inverse in self.file.get_inverse(self.settings["role"]):
if inverse.is_a() in ("IfcOrganization", "IfcPerson", "IfcPersonAndOrganization"):
if inverse.Roles == (self.settings["role"],):
inverse.Roles = None
elif inverse.is_a("IfcResourceLevelRelationship") and not inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatedResourceObjects == (self.settings["organisation"],):
self.file.remove(inverse)
self.file.remove(self.settings["role"])
for inverse in file.get_inverse(settings["role"]):
if inverse.is_a() in ("IfcOrganization", "IfcPerson", "IfcPersonAndOrganization"):
if inverse.Roles == (settings["role"],):
inverse.Roles = None
elif inverse.is_a("IfcResourceLevelRelationship") and not inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatedResourceObjects == (settings["organisation"],):
file.remove(inverse)
file.remove(settings["role"])
@@ -21,58 +21,55 @@ import ifcopenshell.api
import ifcopenshell.util.element
class Usecase:
def __init__(self, file, relating_actor=None, related_object=None):
"""Unassigns an actor to an object
def unassign_actor(file, relating_actor=None, related_object=None) -> None:
"""Unassigns an actor to an object
This means that the actor is no longer responsible for the object.
This means that the actor is no longer responsible for the object.
:param relating_actor: The IfcActor who is responsible for the object.
:type relating_actor: ifcopenshell.entity_instance
:param related_object: The object the actor is responsible for.
:type related_object: ifcopenshell.entity_instance
:return: The updated IfcRelAssignsToActor relationship or none if there
is no more valid relationship.
:rtype: None, ifcopenshell.entity_instance
:param relating_actor: The IfcActor who is responsible for the object.
:type relating_actor: ifcopenshell.entity_instance
:param related_object: The object the actor is responsible for.
:type related_object: ifcopenshell.entity_instance
:return: The updated IfcRelAssignsToActor relationship or none if there
is no more valid relationship.
:rtype: None, ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
# We need to procure and install 2 of this particular pump type in our facility.
pump_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcPumpType")
# We need to procure and install 2 of this particular pump type in our facility.
pump_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcPumpType")
# Define who the manufacturer is
manufacturer = ifcopenshell.api.run("owner.add_organisation", model,
identification="PWP", name="Pumps With Power")
ifcopenshell.api.run("owner.add_role", model, assigned_object=manufacturer, role="MANUFACTURER")
# Define who the manufacturer is
manufacturer = ifcopenshell.api.run("owner.add_organisation", model,
identification="PWP", name="Pumps With Power")
ifcopenshell.api.run("owner.add_role", model, assigned_object=manufacturer, role="MANUFACTURER")
# Make the manufacturer responsible for that pump type.
ifcopenshell.api.run("owner.assign_actor", model,
relating_actor=manufacturer, related_object=pump_type)
# Make the manufacturer responsible for that pump type.
ifcopenshell.api.run("owner.assign_actor", model,
relating_actor=manufacturer, related_object=pump_type)
# Undo the assignment
ifcopenshell.api.run("owner.unassign_actor", model,
relating_actor=manufacturer, related_object=pump_type)
"""
self.file = file
self.settings = {
"relating_actor": relating_actor,
"related_object": related_object,
}
# Undo the assignment
ifcopenshell.api.run("owner.unassign_actor", model,
relating_actor=manufacturer, related_object=pump_type)
"""
settings = {
"relating_actor": relating_actor,
"related_object": related_object,
}
def execute(self):
for rel in self.settings["related_object"].HasAssignments or []:
if not rel.is_a("IfcRelAssignsToActor") or rel.RelatingActor != self.settings["relating_actor"]:
continue
if len(rel.RelatedObjects) == 1:
history = rel.OwnerHistory
self.file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
return
related_objects = list(rel.RelatedObjects)
related_objects.remove(self.settings["related_object"])
rel.RelatedObjects = related_objects
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": rel})
return rel
for rel in settings["related_object"].HasAssignments or []:
if not rel.is_a("IfcRelAssignsToActor") or rel.RelatingActor != settings["relating_actor"]:
continue
if len(rel.RelatedObjects) == 1:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
return
related_objects = list(rel.RelatedObjects)
related_objects.remove(settings["related_object"])
rel.RelatedObjects = related_objects
ifcopenshell.api.run("owner.update_owner_history", file, **{"element": rel})
return rel
@@ -24,71 +24,70 @@ import ifcopenshell.util.element
from typing import Union
class Usecase:
def __init__(self, file: ifcopenshell.file, element: ifcopenshell.entity_instance):
"""Updates the owner that is assigned to an object
def update_owner_history(
file: ifcopenshell.file, element: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
"""Updates the owner that is assigned to an object
This ensures that the owner is tracked to have modified the object last,
including the time when the change occured. See
ifcopenshell.api.owner.create_owner_history for details.
This ensures that the owner is tracked to have modified the object last,
including the time when the change occured. See
ifcopenshell.api.owner.create_owner_history for details.
:param element: The IfcRoot element to update the ownership details on
when a change is made.
:type element: ifcopenshell.entity_instance
:return: The updated IfcOwnerHistory element.
:rtype: ifcopenshell.entity_instance
:param element: The IfcRoot element to update the ownership details on
when a change is made.
:type element: ifcopenshell.entity_instance
:return: The updated IfcOwnerHistory element.
:rtype: ifcopenshell.entity_instance
Example:
Example:
.. code:: python
.. code:: python
# See ifcopenshell.api.owner.create_owner_history for setup
# [ ... example setup code ... ]
# See ifcopenshell.api.owner.create_owner_history for setup
# [ ... example setup code ... ]
# We've finished our ownership setup. Now let's start our script and
# create a space. Notice we don't actually call
# create_owner_history at all. This is already automatically handled
# by the API when necessary. Under the hood, the API is actually
# running this code on the IfcSpace element:
# element.OwnerHistory = ifcopenshell.api.run("owner.create_owner_history", model)
space = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSpace")
# We've finished our ownership setup. Now let's start our script and
# create a space. Notice we don't actually call
# create_owner_history at all. This is already automatically handled
# by the API when necessary. Under the hood, the API is actually
# running this code on the IfcSpace element:
# element.OwnerHistory = ifcopenshell.api.run("owner.create_owner_history", model)
space = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSpace")
# Any edits we make will have ownership tracking automatically
# applied. There is no need to run any owner.update_owner_history
# API calls either.
ifcopenshell.api.run("attribute.edit_attributes", model, product=space, attributes={"Name": "Lobby"})
"""
self.file = file
self.settings = {"element": element}
# Any edits we make will have ownership tracking automatically
# applied. There is no need to run any owner.update_owner_history
# API calls either.
ifcopenshell.api.run("attribute.edit_attributes", model, product=space, attributes={"Name": "Lobby"})
"""
settings = {"element": element}
def execute(self) -> Union[ifcopenshell.entity_instance, None]:
element = self.settings["element"]
if not element.is_a("IfcRoot"):
return
user = ifcopenshell.api.owner.settings.get_user(self.file)
if not user:
return
application = ifcopenshell.api.owner.settings.get_application(self.file)
if not application:
return
element = settings["element"]
if not element.is_a("IfcRoot"):
return
user = ifcopenshell.api.owner.settings.get_user(file)
if not user:
return
application = ifcopenshell.api.owner.settings.get_application(file)
if not application:
return
# 1 IfcRoot IfcOwnerHistory
owner_history = element[1]
if not owner_history:
owner_history = ifcopenshell.api.run("owner.create_owner_history", self.file)
element[1] = owner_history
return owner_history
if self.file.get_total_inverses(owner_history) > 1:
owner_history = ifcopenshell.util.element.copy(self.file, owner_history)
element[1] = owner_history
# 3 IfcOwnerHistory ChangeAction
owner_history[3] = "MODIFIED"
# 4 IfcOwnerHistory LastModifiedDate
owner_history[4] = int(time.time())
# 5 IfcOwnerHistory LastModifyingUser
owner_history[5] = user
# 6 IfcOwnerHistory LastModifyingApplication
owner_history[6] = application
# 1 IfcRoot IfcOwnerHistory
owner_history = element[1]
if not owner_history:
owner_history = ifcopenshell.api.run("owner.create_owner_history", file)
element[1] = owner_history
return owner_history
if file.get_total_inverses(owner_history) > 1:
owner_history = ifcopenshell.util.element.copy(file, owner_history)
element[1] = owner_history
# 3 IfcOwnerHistory ChangeAction
owner_history[3] = "MODIFIED"
# 4 IfcOwnerHistory LastModifiedDate
owner_history[4] = int(time.time())
# 5 IfcOwnerHistory LastModifyingUser
owner_history[5] = user
# 6 IfcOwnerHistory LastModifyingApplication
owner_history[6] = application
return owner_history