First Commit
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
# 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/>.
|
||||
|
||||
"""Reference external project documents and associate them to model elements
|
||||
|
||||
Some project information (drawings, specifications, certificates, reports, etc)
|
||||
may be stored in external documents (locally or in a CDE). IFC lets you store a
|
||||
register of documents with metadata and associate them with elements (both
|
||||
physical and non-physical).
|
||||
"""
|
||||
|
||||
from .. import wrap_usecases
|
||||
from .add_information import add_information
|
||||
from .add_reference import add_reference
|
||||
from .assign_document import assign_document
|
||||
from .edit_information import edit_information
|
||||
from .edit_reference import edit_reference
|
||||
from .remove_information import remove_information
|
||||
from .remove_reference import remove_reference
|
||||
from .unassign_document import unassign_document
|
||||
|
||||
wrap_usecases(__path__, __name__)
|
||||
|
||||
__all__ = [
|
||||
"add_information",
|
||||
"add_reference",
|
||||
"assign_document",
|
||||
"edit_information",
|
||||
"edit_reference",
|
||||
"remove_information",
|
||||
"remove_reference",
|
||||
"unassign_document",
|
||||
]
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,83 @@
|
||||
# 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_information(
|
||||
file: ifcopenshell.file, parent: Optional[ifcopenshell.entity_instance] = None
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new document information to the project
|
||||
|
||||
An IFC document information is a document associated with the project.
|
||||
It may be a drawing, specification, schedule, certificate, warranty
|
||||
guarantee, manual, contract, and so on. They are often used for drawings
|
||||
and facility management purposes.
|
||||
|
||||
A document may also be a subdocument of a larger document, this is
|
||||
useful for superseding documents or tracking older versions. The parent
|
||||
is considered the latest version and the children are older revisions.
|
||||
|
||||
:param parent: The parent document, if necessary.
|
||||
:return: The newly created IfcDocumentInformation entity
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
# A document typically has a unique drawing or document name (which
|
||||
# follows a coding system depending on the project), as well as a
|
||||
# title. This should match what is shown on the titleblock or title
|
||||
# page of the document. At a minimum you'd also want to specify a
|
||||
# URI location. The location may be on local, or on a CDE, or any
|
||||
# other platform.
|
||||
ifcopenshell.api.document.edit_information(model,
|
||||
information=document,
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
"""
|
||||
id_attribute = "DocumentId" if file.schema == "IFC2X3" else "Identification"
|
||||
information = file.create_entity("IfcDocumentInformation", **{id_attribute: "X", "Name": "Unnamed"})
|
||||
|
||||
if not parent and not (parent := next(iter(file.by_type("IfcProject")), None)):
|
||||
raise Exception("IfcProject is not found.")
|
||||
|
||||
if parent.is_a("IfcProject") or parent.is_a("IfcContext"):
|
||||
file.create_entity(
|
||||
"IfcRelAssociatesDocument",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||
RelatingDocument=information,
|
||||
RelatedObjects=[parent],
|
||||
)
|
||||
elif parent.is_a("IfcDocumentInformation"):
|
||||
if parent.IsPointer:
|
||||
rel = parent.IsPointer[0]
|
||||
documents = set(rel.RelatedDocuments)
|
||||
documents.add(information)
|
||||
rel.RelatedDocuments = list(documents)
|
||||
else:
|
||||
file.create_entity(
|
||||
"IfcDocumentInformationRelationship", RelatingDocument=parent, RelatedDocuments=[information]
|
||||
)
|
||||
return information
|
||||
@@ -0,0 +1,71 @@
|
||||
# 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
|
||||
|
||||
|
||||
def add_reference(file: ifcopenshell.file, information: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
"""Creates a new reference to a document to assign to products
|
||||
|
||||
A document may be associated with physical products, tasks, cost items,
|
||||
and so on. For example, spaces, storeys, and buildings may have a list
|
||||
of associated drawings so you can see which drawings (e.g. plans,
|
||||
sections, details) are documenting that location. Alternatively,
|
||||
equipment may have associated training manuals, operation and
|
||||
maintenance manuals or detailed assembly drawings. Resources may be
|
||||
training certification required, schedules may have gantt charts or bid
|
||||
documents, and so on.
|
||||
|
||||
In order to associate a document with an object, a reference to that
|
||||
document needs to be created. It could be a reference to the entire
|
||||
document, or a reference to a particular page or chapter. See
|
||||
ifcopenshell.api.document.assign_document for more information.
|
||||
|
||||
:param information: The IfcDocumentInformation that the reference will
|
||||
be created for
|
||||
:return: The newly created IfcDocumentReference entity
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
ifcopenshell.api.document.edit_information(model,
|
||||
information=document,
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
|
||||
# In this case, we don't specify any more information, and so the
|
||||
# reference is for the entire document, as opposed to a single page or
|
||||
# chapter or section.
|
||||
reference = ifcopenshell.api.document.add_reference(model, information=document)
|
||||
|
||||
# Alternatively, we can specify a single section, such as by a
|
||||
# subheading code.
|
||||
reference2 = ifcopenshell.api.document.add_reference(model, information=document)
|
||||
ifcopenshell.api.document.edit_reference(model,
|
||||
reference=reference2, attributes={"Identification": "2.1.15"})
|
||||
"""
|
||||
if file.schema == "IFC2X3":
|
||||
reference = file.create_entity("IfcDocumentReference", ItemReference="X")
|
||||
if information:
|
||||
references = list(information.DocumentReferences or [])
|
||||
references.append(reference)
|
||||
information.DocumentReferences = references
|
||||
return reference
|
||||
return file.create_entity("IfcDocumentReference", ReferencedDocument=information, Identification="X")
|
||||
@@ -0,0 +1,103 @@
|
||||
# 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
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def assign_document(
|
||||
file: ifcopenshell.file,
|
||||
products: list[ifcopenshell.entity_instance],
|
||||
document: ifcopenshell.entity_instance,
|
||||
) -> Union[ifcopenshell.entity_instance, None]:
|
||||
"""Assigns a document to a list of products
|
||||
|
||||
An object may be assigned to zero, one, or multiple documents. Almost
|
||||
any object or property may be assigned to a document, though typically
|
||||
we'd only use it for spaces, types, physical products and schedules.
|
||||
Adding a new assignment is typically done using a document reference and
|
||||
an object. IFC technically allows association with a document
|
||||
information and an object, but this is not encouraged because it is not
|
||||
consistent with other external relationships (such as classification
|
||||
systems or libraries).
|
||||
|
||||
:param product: The list of objects to associate the document to. This could be
|
||||
almost any sensible object in IFC.
|
||||
:param document: The IfcDocumentReference to associate to, or
|
||||
alternatively an IfcDocumentInformation, though this is not
|
||||
recommended.
|
||||
:return: The IfcRelAssociatesDocument relationship
|
||||
or `None` if `products` was an empty list or all products were
|
||||
already assigned to the `document`.
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
ifcopenshell.api.document.edit_information(model,
|
||||
information=document,
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
reference = ifcopenshell.api.document.add_reference(model, information=document)
|
||||
|
||||
# Let's imagine storey represents an IfcBuildingStorey for the ground floor
|
||||
ifcopenshell.api.document.assign_document(model, products=[storey], document=reference)
|
||||
"""
|
||||
|
||||
# TODO: do we need to support non-ifcroot elements like we do in classification.add_reference?
|
||||
# NOTE: reuses code from `library.assign_reference`
|
||||
|
||||
referenced_elements = ifcopenshell.util.element.get_referenced_elements(document)
|
||||
products_set: set[ifcopenshell.entity_instance] = set(products)
|
||||
products_set = products_set - referenced_elements
|
||||
|
||||
if not products_set:
|
||||
return
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
rel = next(
|
||||
(r for r in file.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == document),
|
||||
None,
|
||||
)
|
||||
else:
|
||||
ifc_class = document.is_a()
|
||||
if ifc_class == "IfcDocumentReference":
|
||||
rel = next(iter(document.DocumentRefForObjects), None)
|
||||
elif ifc_class == "IfcDocumentInformation":
|
||||
rel = next(iter(document.DocumentInfoForObjects), None)
|
||||
else:
|
||||
assert False, f"Unexpected document type: {ifc_class}"
|
||||
|
||||
if not rel:
|
||||
return file.create_entity(
|
||||
"IfcRelAssociatesDocument",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||
RelatedObjects=list(products_set),
|
||||
RelatingDocument=document,
|
||||
)
|
||||
|
||||
related_objects = set(rel.RelatedObjects) | products_set
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(file, element=rel)
|
||||
return rel
|
||||
@@ -0,0 +1,48 @@
|
||||
# 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_information(
|
||||
file: ifcopenshell.file,
|
||||
information: ifcopenshell.entity_instance,
|
||||
attributes: dict[str, Any],
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcDocumentInformation
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
IfcDocumentInformation, consult the IFC documentation.
|
||||
|
||||
:param reference: The IfcDocumentInformation entity you want to edit
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
ifcopenshell.api.document.edit_information(model,
|
||||
information=document,
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
"""
|
||||
for name, value in attributes.items():
|
||||
setattr(information, name, value)
|
||||
@@ -0,0 +1,51 @@
|
||||
# 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_reference(
|
||||
file: ifcopenshell.file,
|
||||
reference: ifcopenshell.entity_instance,
|
||||
attributes: dict[str, Any],
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcDocumentReference
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
IfcDocumentReference, consult the IFC documentation.
|
||||
|
||||
:param reference: The IfcDocumentReference entity you want to edit
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
ifcopenshell.api.document.edit_information(model,
|
||||
information=document,
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
reference = ifcopenshell.api.document.add_reference(model, information=document)
|
||||
ifcopenshell.api.document.edit_reference(model,
|
||||
reference=reference, attributes={"Identification": "2.1.15"})
|
||||
"""
|
||||
for name, value in attributes.items():
|
||||
setattr(reference, name, value)
|
||||
@@ -0,0 +1,70 @@
|
||||
# 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/>.
|
||||
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.document
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_information(file: ifcopenshell.file, information: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a document information
|
||||
|
||||
All references and associations are also removed.
|
||||
|
||||
:param information: The IfcDocumentInformation to remove
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Add a document
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
# ... and remove it!
|
||||
ifcopenshell.api.document.remove_information(model, information=document)
|
||||
"""
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
references = information.DocumentReferences or []
|
||||
else:
|
||||
references = information.HasDocumentReferences
|
||||
|
||||
for reference in references:
|
||||
ifcopenshell.api.document.remove_reference(file, reference=reference)
|
||||
|
||||
for rel in information.IsPointer or []:
|
||||
for info in rel.RelatedDocuments:
|
||||
ifcopenshell.api.document.remove_information(file, information=info)
|
||||
|
||||
for rel in information.IsPointedTo or []:
|
||||
if rel.RelatedDocuments == (information,):
|
||||
# This relationship is non-rooted
|
||||
file.remove(rel)
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
rels = [r for r in file.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == information]
|
||||
else:
|
||||
rels = information.DocumentInfoForObjects
|
||||
|
||||
for rel in rels:
|
||||
history = rel.OwnerHistory
|
||||
file.remove(rel)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
file.remove(information)
|
||||
@@ -0,0 +1,50 @@
|
||||
# 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/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_reference(file: ifcopenshell.file, reference: ifcopenshell.entity_instance) -> None:
|
||||
"""Remove a document reference
|
||||
|
||||
All associations with objects are removed.
|
||||
|
||||
:param reference: The IfcDocumentReference to remove
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
reference = ifcopenshell.api.document.add_reference(model, information=document)
|
||||
ifcopenshell.api.document.remove_reference(model, reference=reference)
|
||||
"""
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
rels = [r for r in file.get_inverse(reference) if r.is_a("IfcRelAssociatesDocument")]
|
||||
else:
|
||||
rels = reference.DocumentRefForObjects
|
||||
|
||||
for rel in rels:
|
||||
history = rel.OwnerHistory
|
||||
file.remove(rel)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
file.remove(reference)
|
||||
@@ -0,0 +1,76 @@
|
||||
# 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_document(
|
||||
file: ifcopenshell.file,
|
||||
products: list[ifcopenshell.entity_instance],
|
||||
document: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
"""Unassigns a document and an association to the list of products
|
||||
|
||||
:param product: The list of objects that the document reference or information is
|
||||
related to.
|
||||
:param document: The IfcDocumentReference (typically) or in rare cases
|
||||
the IfcDocumentInformation that is associated with the product
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
document = ifcopenshell.api.document.add_information(model)
|
||||
ifcopenshell.api.document.edit_information(model,
|
||||
information=document,
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
reference = ifcopenshell.api.document.add_reference(model, information=document)
|
||||
|
||||
# Let's imagine storey represents an IfcBuildingStorey for the ground floor
|
||||
ifcopenshell.api.document.assign_document(model, products=[storey], document=reference)
|
||||
|
||||
# Now let's change our mind and remove the association
|
||||
ifcopenshell.api.document.unassign_document(model, products=[storey], document=reference)
|
||||
"""
|
||||
|
||||
# TODO: do we need to support non-ifcroot elements like we do in classification.add_reference?
|
||||
# NOTE: reuses code from `library.un assign_reference`
|
||||
|
||||
reference_rels: set[ifcopenshell.entity_instance] = set()
|
||||
products_set = set(products)
|
||||
for product in products_set:
|
||||
reference_rels.update(product.HasAssociations)
|
||||
|
||||
reference_rels = {
|
||||
rel for rel in reference_rels if rel.is_a("IfcRelAssociatesDocument") and rel.RelatingDocument == document
|
||||
}
|
||||
|
||||
for rel in reference_rels:
|
||||
related_objects = set(rel.RelatedObjects) - 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)
|
||||
Reference in New Issue
Block a user