mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
IFC drawings are now roundtrip and are imported as Blender camera objects. See #1153.
This commit is contained in:
@@ -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"):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user