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 tempfile
import numpy as np
import blenderbim.bim.prop
from pathlib import Path
from itertools import cycle
from datetime import datetime
@@ -702,11 +703,15 @@ class IfcImporter:
checkpoint = time.time()
shape = iterator.get()
if shape:
product = self.file.by_id(shape.guid)
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.
pass
elif product.is_a("IfcAnnotation") and product.ObjectType == "DRAWING":
# We have already processed this during the create_annotation step
pass
else:
self.create_product(self.file.by_id(shape.guid), shape)
self.create_product(product, shape)
if not iterator.next():
break
print("Done creating geometry")
@@ -784,6 +789,8 @@ class IfcImporter:
if mesh:
pass
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
mesh = self.create_camera(element, shape)
elif shape:
mesh_name = self.get_mesh_name(shape.geometry)
mesh = self.meshes.get(mesh_name)
@@ -1206,6 +1213,14 @@ class IfcImporter:
self.structural_member_collection.objects.link(obj)
elif element.is_a("IfcStructuralConnection"):
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:
self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element)
bpy.context.scene.collection.objects.link(obj)
@@ -1294,6 +1309,48 @@ class IfcImporter:
context_id = representation.ContextOfItems.id() if hasattr(representation, "ContextOfItems") else 0
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):
try:
if hasattr(shape, "geometry"):
+1 -1
View File
@@ -1552,7 +1552,7 @@ class RefreshDrawingList(bpy.types.Operator):
for obj in bpy.context.scene.objects:
if not isinstance(obj.data, bpy.types.Camera):
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.name = obj.name.split("/")[1]
new.camera = obj