mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 16:31:10 +00:00
See #3847. Preliminary support for including linked models when generating drawings.
This commit is contained in:
@@ -529,28 +529,35 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
files = {context.scene.BIMProperties.ifc_file: tool.Ifc.get()}
|
files = {context.scene.BIMProperties.ifc_file: tool.Ifc.get()}
|
||||||
|
|
||||||
|
for link in context.scene.BIMProjectProperties.links:
|
||||||
|
if link.name not in IfcStore.session_files:
|
||||||
|
IfcStore.session_files[link.name] = ifcopenshell.open(link.name)
|
||||||
|
files[link.name] = IfcStore.session_files[link.name]
|
||||||
|
|
||||||
|
target_view = ifcopenshell.util.element.get_psets(self.camera_element)["EPset_Drawing"]["TargetView"]
|
||||||
|
self.setup_serialiser(target_view)
|
||||||
|
|
||||||
|
tree = ifcopenshell.geom.tree()
|
||||||
|
tree.enable_face_styles(True)
|
||||||
|
|
||||||
for ifc_path, ifc in files.items():
|
for ifc_path, ifc in files.items():
|
||||||
# Don't use draw.main() just whilst we're prototyping and experimenting
|
# Don't use draw.main() just whilst we're prototyping and experimenting
|
||||||
# TODO: hash paths are never used
|
# TODO: hash paths are never used
|
||||||
ifc_hash = hashlib.md5(ifc_path.encode("utf-8")).hexdigest()
|
ifc_hash = hashlib.md5(ifc_path.encode("utf-8")).hexdigest()
|
||||||
ifc_cache_path = os.path.join(context.scene.BIMProperties.data_dir, "cache", f"{ifc_hash}.h5")
|
ifc_cache_path = os.path.join(context.scene.BIMProperties.data_dir, "cache", f"{ifc_hash}.h5")
|
||||||
|
|
||||||
|
self.serialiser.setFile(ifc)
|
||||||
|
drawing_elements = tool.Drawing.get_drawing_elements(self.camera_element, ifc_file=ifc)
|
||||||
|
|
||||||
# Get all representation contexts to see what we're dealing with.
|
# Get all representation contexts to see what we're dealing with.
|
||||||
# Drawings only draw bodies and annotations (and facetation, due to a Revit bug).
|
# Drawings only draw bodies and annotations (and facetation, due to a Revit bug).
|
||||||
# A drawing prioritises a target view context first, followed by a model view context as a fallback.
|
# A drawing prioritises a target view context first, followed by a model view context as a fallback.
|
||||||
# Specifically for PLAN_VIEW and REFLECTED_PLAN_VIEW, any Plan context is also prioritised.
|
# Specifically for PLAN_VIEW and REFLECTED_PLAN_VIEW, any Plan context is also prioritised.
|
||||||
target_view = ifcopenshell.util.element.get_psets(self.camera_element)["EPset_Drawing"]["TargetView"]
|
|
||||||
contexts = self.get_linework_contexts(ifc, target_view)
|
contexts = self.get_linework_contexts(ifc, target_view)
|
||||||
drawing_elements = tool.Drawing.get_drawing_elements(self.camera_element)
|
|
||||||
|
|
||||||
self.setup_serialiser(ifc, target_view)
|
|
||||||
tree = ifcopenshell.geom.tree()
|
|
||||||
tree.enable_face_styles(True)
|
|
||||||
|
|
||||||
self.serialize_contexts_elements(ifc, tree, contexts, "body", drawing_elements, target_view)
|
self.serialize_contexts_elements(ifc, tree, contexts, "body", drawing_elements, target_view)
|
||||||
self.serialize_contexts_elements(ifc, tree, contexts, "annotation", drawing_elements, target_view)
|
self.serialize_contexts_elements(ifc, tree, contexts, "annotation", drawing_elements, target_view)
|
||||||
|
|
||||||
if self.camera_element not in drawing_elements:
|
if tool.Ifc.get() == ifc and self.camera_element not in drawing_elements:
|
||||||
with profile("Camera element"):
|
with profile("Camera element"):
|
||||||
# The camera must always be included, regardless of any include/exclude filters.
|
# The camera must always be included, regardless of any include/exclude filters.
|
||||||
geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True)
|
geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True)
|
||||||
@@ -865,13 +872,12 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
return svg_path
|
return svg_path
|
||||||
|
|
||||||
def setup_serialiser(self, ifc, target_view):
|
def setup_serialiser(self, target_view):
|
||||||
self.svg_settings = ifcopenshell.geom.settings(
|
self.svg_settings = ifcopenshell.geom.settings(
|
||||||
DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True, INCLUDE_CURVES=True
|
DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True, INCLUDE_CURVES=True
|
||||||
)
|
)
|
||||||
self.svg_buffer = ifcopenshell.geom.serializers.buffer()
|
self.svg_buffer = ifcopenshell.geom.serializers.buffer()
|
||||||
self.serialiser = ifcopenshell.geom.serializers.svg(self.svg_buffer, self.svg_settings)
|
self.serialiser = ifcopenshell.geom.serializers.svg(self.svg_buffer, self.svg_settings)
|
||||||
self.serialiser.setFile(ifc)
|
|
||||||
self.serialiser.setWithoutStoreys(True)
|
self.serialiser.setWithoutStoreys(True)
|
||||||
self.serialiser.setPolygonal(True)
|
self.serialiser.setPolygonal(True)
|
||||||
self.serialiser.setUseHlrPoly(True)
|
self.serialiser.setUseHlrPoly(True)
|
||||||
@@ -935,6 +941,18 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
self.is_manifold_cache[obj.data.name] = True
|
self.is_manifold_cache[obj.data.name] = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_element_by_guid(self, guid):
|
||||||
|
try:
|
||||||
|
return tool.Ifc.get().by_guid(guid)
|
||||||
|
except:
|
||||||
|
for link in bpy.context.scene.BIMProjectProperties.links:
|
||||||
|
if link.name not in IfcStore.session_files:
|
||||||
|
IfcStore.session_files[link.name] = ifcopenshell.open(link.name)
|
||||||
|
try:
|
||||||
|
return IfcStore.session_files[link.name].by_guid(guid)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
def merge_linework_and_add_metadata(self, root):
|
def merge_linework_and_add_metadata(self, root):
|
||||||
join_criteria = ifcopenshell.util.element.get_pset(self.camera_element, "EPset_Drawing", "JoinCriteria")
|
join_criteria = ifcopenshell.util.element.get_pset(self.camera_element, "EPset_Drawing", "JoinCriteria")
|
||||||
if join_criteria:
|
if join_criteria:
|
||||||
@@ -949,7 +967,7 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
ifc = tool.Ifc.get()
|
ifc = tool.Ifc.get()
|
||||||
for el in root.findall(".//{http://www.w3.org/2000/svg}g[@{http://www.ifcopenshell.org/ns}guid]"):
|
for el in root.findall(".//{http://www.w3.org/2000/svg}g[@{http://www.ifcopenshell.org/ns}guid]"):
|
||||||
element = ifc.by_guid(el.get("{http://www.ifcopenshell.org/ns}guid"))
|
element = self.get_element_by_guid(el.get("{http://www.ifcopenshell.org/ns}guid"))
|
||||||
|
|
||||||
if "projection" in el.get("class", "").split():
|
if "projection" in el.get("class", "").split():
|
||||||
classes = self.get_svg_classes(element)
|
classes = self.get_svg_classes(element)
|
||||||
@@ -962,6 +980,10 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
el.set("class", " ".join(classes))
|
el.set("class", " ".join(classes))
|
||||||
|
|
||||||
obj = tool.Ifc.get_object(element)
|
obj = tool.Ifc.get_object(element)
|
||||||
|
|
||||||
|
if not obj: # This is a linked model object. For now, do nothing.
|
||||||
|
continue
|
||||||
|
|
||||||
if not self.is_manifold(obj):
|
if not self.is_manifold(obj):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -1625,11 +1625,17 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
return ifcopenshell.util.element.get_psets(drawing).get("EPset_Drawing", {}).get("HasAnnotation", False)
|
return ifcopenshell.util.element.get_psets(drawing).get("EPset_Drawing", {}).get("HasAnnotation", False)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_drawing_elements(cls, drawing: ifcopenshell.entity_instance) -> set[ifcopenshell.entity_instance]:
|
def get_drawing_elements(
|
||||||
|
cls, drawing: ifcopenshell.entity_instance, ifc_file: Optional[ifcopenshell.file] = None
|
||||||
|
) -> set[ifcopenshell.entity_instance]:
|
||||||
"""returns a set of elements that are included in the drawing"""
|
"""returns a set of elements that are included in the drawing"""
|
||||||
ifc_file = tool.Ifc.get()
|
if ifc_file is None:
|
||||||
|
ifc_file = tool.Ifc.get()
|
||||||
|
elements = cls.get_elements_in_camera_view(tool.Ifc.get_object(drawing), bpy.data.objects)
|
||||||
|
else:
|
||||||
|
# This can probably be smarter
|
||||||
|
elements = set(ifc_file.by_type("IfcElement"))
|
||||||
pset = ifcopenshell.util.element.get_psets(drawing).get("EPset_Drawing", {})
|
pset = ifcopenshell.util.element.get_psets(drawing).get("EPset_Drawing", {})
|
||||||
elements = cls.get_elements_in_camera_view(tool.Ifc.get_object(drawing), bpy.data.objects)
|
|
||||||
include = pset.get("Include", None)
|
include = pset.get("Include", None)
|
||||||
if include:
|
if include:
|
||||||
elements = ifcopenshell.util.selector.filter_elements(ifc_file, include)
|
elements = ifcopenshell.util.selector.filter_elements(ifc_file, include)
|
||||||
|
|||||||
Reference in New Issue
Block a user