New feature in BCF to allow extracting specific files like header files, snippets, or bitmaps.

This commit is contained in:
Dion Moult
2023-02-18 21:11:05 +11:00
parent f91e9a3119
commit e712ef344d
2 changed files with 55 additions and 7 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ with load("/path/to/file.bcf") as bcfxml:
# Get a dictionary of topics # Get a dictionary of topics
topics = bcfxml.topics topics = bcfxml.topics
for topic_handler in bcfxml.topics: for topic_guid, topic_handler in bcfxml.topics.items():
topic = topic_handler.topic topic = topic_handler.topic
print("Topic guid is", topic.guid) print("Topic guid is", topic.guid)
print("Topic title is", topic.title) print("Topic title is", topic.title)
+54 -6
View File
@@ -1,7 +1,8 @@
"""BCF XML V2 Topic handler.""" """BCF XML V2 Topic handler."""
import datetime
import uuid import uuid
import zipfile import zipfile
import tempfile
import datetime
from pathlib import Path from pathlib import Path
from typing import Any, NoReturn, Optional from typing import Any, NoReturn, Optional
@@ -218,9 +219,56 @@ class TopicHandler:
real_path = real_path.parent if path_part == ".." else real_path.joinpath(path_part) real_path = real_path.parent if path_part == ".." else real_path.joinpath(path_part)
destination_zip.writestr(real_path.at, self.document_references[doc.referenced_document]) destination_zip.writestr(real_path.at, self.document_references[doc.referenced_document])
def add_viewpoint(self, element: entity_instance) -> None: def extract_file(self, entity, outfile: Optional[Path] = None) -> Path:
"""Extracts an element with a file into a temporary directory
These include header files, bim snippets, document references, and
viewpoint bitmaps. External reference are not downloaded. Instead, the
URI reference is returned.
:param entity: The entity with a file reference to extract
:type entity: bcf.v2.model.HeaderFile,bcf.v2.model.BimSnippet,bcf.v2.model.TopicDocumentReference
:param outfile: If provided, save the header file to that location.
Otherwise, a temporary directory is created and the filename is
derived from the header's original filename.
:type outfile: pathlib.Path,optional
:return: The filepath of the extracted file. It may be a URL if the
header file is external.
:rtype: Path
""" """
Add a viewpoint tergeting an IFC element to the topic. if hasattr(entity, "reference"):
reference = entity.reference
else:
reference = entity.referenced_document
if not reference:
return
if getattr(entity, "is_external", False):
return entity.reference
resolved_reference = self._topic_dir
for part in Path(reference).parts:
if part == "..":
resolved_reference = resolved_reference.parent
else:
resolved_reference = resolved_reference.joinpath(part)
if not outfile:
if getattr(entity, "filename", None):
filename = entity.filename
else:
filename = resolved_reference.name
outfile = Path(tempfile.mkdtemp()) / filename
with open(outfile, "wb") as f:
f.write(resolved_reference.read_bytes())
return outfile
def add_viewpoint(self, element: entity_instance) -> None:
"""Add a viewpoint pointed at the placement of an IFC element to the topic.
Args: Args:
element: The IFC element. element: The IFC element.
@@ -229,11 +277,11 @@ class TopicHandler:
self.add_visinfo_handler(new_viewpoint) self.add_visinfo_handler(new_viewpoint)
def add_viewpoint_from_point_and_guids(self, position: NDArray[np.float_], *guids: str) -> None: def add_viewpoint_from_point_and_guids(self, position: NDArray[np.float_], *guids: str) -> None:
""" """Add a viewpoint pointing at an XYZ point in space
Add a viewpoint tergeting an IFC element to the topic.
Args: Args:
element: The IFC element. position: the XYZ point in space
guids: one or more element GlobalIds.
""" """
vi_handler = VisualizationInfoHandler.create_from_point_and_guids( vi_handler = VisualizationInfoHandler.create_from_point_and_guids(
position, *guids, xml_handler=self._xml_handler position, *guids, xml_handler=self._xml_handler