IFC drawings are now roundtrip and are imported as Blender camera objects. See #1153.

This commit is contained in:
Dion Moult
2021-05-15 18:05:15 +10:00
parent fdcafa98b3
commit 5aec0718f4
2 changed files with 59 additions and 2 deletions
+58 -1
View File
@@ -18,6 +18,7 @@ import multiprocessing
import zipfile import zipfile
import tempfile import tempfile
import numpy as np import numpy as np
import blenderbim.bim.prop
from pathlib import Path from pathlib import Path
from itertools import cycle from itertools import cycle
from datetime import datetime from datetime import datetime
@@ -702,11 +703,15 @@ class IfcImporter:
checkpoint = time.time() checkpoint = time.time()
shape = iterator.get() shape = iterator.get()
if shape: if shape:
product = self.file.by_id(shape.guid)
if shape.context != "Body" and shape.guid in IfcStore.guid_map: if shape.context != "Body" and shape.guid in IfcStore.guid_map:
# We only load a single context, and we prioritise the Body context. See #1290. # We only load a single context, and we prioritise the Body context. See #1290.
pass pass
elif product.is_a("IfcAnnotation") and product.ObjectType == "DRAWING":
# We have already processed this during the create_annotation step
pass
else: else:
self.create_product(self.file.by_id(shape.guid), shape) self.create_product(product, shape)
if not iterator.next(): if not iterator.next():
break break
print("Done creating geometry") print("Done creating geometry")
@@ -784,6 +789,8 @@ class IfcImporter:
if mesh: if mesh:
pass pass
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
mesh = self.create_camera(element, shape)
elif shape: elif shape:
mesh_name = self.get_mesh_name(shape.geometry) mesh_name = self.get_mesh_name(shape.geometry)
mesh = self.meshes.get(mesh_name) mesh = self.meshes.get(mesh_name)
@@ -1206,6 +1213,14 @@ class IfcImporter:
self.structural_member_collection.objects.link(obj) self.structural_member_collection.objects.link(obj)
elif element.is_a("IfcStructuralConnection"): elif element.is_a("IfcStructuralConnection"):
self.structural_connection_collection.objects.link(obj) self.structural_connection_collection.objects.link(obj)
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
view_collection = bpy.data.collections.get("Views")
if not view_collection:
view_collection = bpy.data.collections.new("Views")
bpy.context.scene.collection.children.link(view_collection)
drawing_collection = bpy.data.collections.new(obj.name)
view_collection.children.link(drawing_collection)
drawing_collection.objects.link(obj)
else: else:
self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element) self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element)
bpy.context.scene.collection.objects.link(obj) bpy.context.scene.collection.objects.link(obj)
@@ -1294,6 +1309,48 @@ class IfcImporter:
context_id = representation.ContextOfItems.id() if hasattr(representation, "ContextOfItems") else 0 context_id = representation.ContextOfItems.id() if hasattr(representation, "ContextOfItems") else 0
return "{}/{}".format(context_id, representation_id) return "{}/{}".format(context_id, representation_id)
def create_camera(self, element, shape):
if hasattr(shape, "geometry"):
geometry = shape.geometry
else:
geometry = shape
v = geometry.verts
x = [v[i] for i in range(0, len(v), 3)]
y = [v[i + 1] for i in range(0, len(v), 3)]
z = [v[i + 2] for i in range(0, len(v), 3)]
width = max(x) - min(x)
height = max(y) - min(y)
depth = max(z) - min(z)
camera = bpy.data.cameras.new(self.get_mesh_name(geometry))
camera.type = "ORTHO"
camera.ortho_scale = width if width > height else height
camera.clip_end = depth
if width > height:
camera.BIMCameraProperties.raster_x = 1000
camera.BIMCameraProperties.raster_y = round(1000 * (height / width))
else:
camera.BIMCameraProperties.raster_x = round(1000 * (width / height))
camera.BIMCameraProperties.raster_y = 1000
psets = ifcopenshell.util.element.get_psets(element)
pset = psets.get("EPset_Drawing")
if pset:
if "TargetView" in pset:
camera.BIMCameraProperties.target_view = pset["TargetView"]
if "Scale" in pset:
valid_scales = [
i[0] for i in blenderbim.bim.prop.getDiagramScales(None, None) if pset["Scale"] == i[0].split("|")[-1]
]
if valid_scales:
camera.BIMCameraProperties.diagram_scale = valid_scales[0]
else:
camera.BIMCameraProperties.diagram_scale = "CUSTOM"
camera.BIMCameraProperties.custom_diagram_scale = pset["Scale"]
return camera
def create_mesh(self, element, shape): def create_mesh(self, element, shape):
try: try:
if hasattr(shape, "geometry"): if hasattr(shape, "geometry"):
+1 -1
View File
@@ -1552,7 +1552,7 @@ class RefreshDrawingList(bpy.types.Operator):
for obj in bpy.context.scene.objects: for obj in bpy.context.scene.objects:
if not isinstance(obj.data, bpy.types.Camera): if not isinstance(obj.data, bpy.types.Camera):
continue continue
if "IfcGroup/" in obj.name and obj.users_collection[0].name == obj.name: if "IfcAnnotation/" in obj.name and obj.users_collection[0].name == obj.name:
new = bpy.context.scene.DocProperties.drawings.add() new = bpy.context.scene.DocProperties.drawings.add()
new.name = obj.name.split("/")[1] new.name = obj.name.split("/")[1]
new.camera = obj new.camera = obj