mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +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 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"):
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user