mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
fix error reloading camera representation
After 4b4ede7 it was leading to non-existing code
This commit is contained in:
@@ -68,6 +68,8 @@ def get_location_hint(self, context):
|
||||
|
||||
|
||||
def update_diagram_scale(self, context):
|
||||
if not self.update_props:
|
||||
return
|
||||
if not context.scene.camera or context.scene.camera.data != self.id_data:
|
||||
return
|
||||
element = tool.Ifc.get_entity(context.scene.camera)
|
||||
@@ -94,6 +96,8 @@ def update_diagram_scale(self, context):
|
||||
|
||||
|
||||
def update_is_nts(self, context):
|
||||
if not self.update_props:
|
||||
return
|
||||
if not context.scene.camera or context.scene.camera.data != self.id_data:
|
||||
return
|
||||
element = tool.Ifc.get_entity(context.scene.camera)
|
||||
@@ -220,6 +224,8 @@ def update_has_annotation(self, context):
|
||||
|
||||
|
||||
def update_layer(self, context, name, value):
|
||||
if not self.update_props:
|
||||
return
|
||||
if not context.scene.camera or context.scene.camera.data != self.id_data:
|
||||
return
|
||||
element = tool.Ifc.get_entity(context.scene.camera)
|
||||
@@ -400,6 +406,7 @@ class BIMCameraProperties(PropertyGroup):
|
||||
filter_mode: StringProperty(name="Filter Mode", default="NONE")
|
||||
include_filter_groups: CollectionProperty(type=BIMFilterGroup, name="Include Filter")
|
||||
exclude_filter_groups: CollectionProperty(type=BIMFilterGroup, name="Exclude Filter")
|
||||
update_props: BoolProperty(name="Enable Props Auto Update", default=True)
|
||||
|
||||
# For now, this JSON dump are all the parameters that determine a camera's "Block representation"
|
||||
# By checking this, you will know whether or not the camera IFC representation needs to be refreshed
|
||||
|
||||
@@ -689,53 +689,15 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
def import_drawing(cls, drawing: ifcopenshell.entity_instance) -> bpy.types.Object:
|
||||
settings = ifcopenshell.geom.settings()
|
||||
|
||||
camera_type = "ORTHO"
|
||||
body = ifcopenshell.util.representation.get_representation(drawing, "Model", "Body", "MODEL_VIEW")
|
||||
if "IfcRectangularPyramid" in {e.is_a() for e in tool.Ifc.get().traverse(body)}:
|
||||
camera_type = "PERSP"
|
||||
representation = ifcopenshell.util.representation.get_representation(drawing, "Model", "Body", "MODEL_VIEW")
|
||||
assert representation
|
||||
|
||||
shape = ifcopenshell.geom.create_shape(settings, drawing)
|
||||
geometry = shape.geometry
|
||||
|
||||
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(tool.Loader.get_mesh_name_from_shape(geometry))
|
||||
camera.type = camera_type
|
||||
camera.show_limits = True
|
||||
|
||||
if camera_type == "ORTHO":
|
||||
camera.clip_start = 0.002 # Technically 0, but Blender doesn't allow this, so 2mm it is!
|
||||
camera.clip_end = depth
|
||||
|
||||
camera.BIMCameraProperties.width = width
|
||||
camera.BIMCameraProperties.height = height
|
||||
elif camera_type == "PERSP":
|
||||
abs_min_z = abs(min(z))
|
||||
abs_max_z = abs(max(z))
|
||||
camera.clip_start = abs_max_z
|
||||
camera.clip_end = abs_min_z
|
||||
max_res = 1000
|
||||
|
||||
camera.BIMCameraProperties.width = width
|
||||
camera.BIMCameraProperties.height = height
|
||||
|
||||
if width > height:
|
||||
fov = 2 * math.atan(width / (2 * abs_min_z))
|
||||
else:
|
||||
fov = 2 * math.atan(height / (2 * abs_min_z))
|
||||
|
||||
camera.angle = fov
|
||||
|
||||
camera = tool.Loader.create_camera(drawing, representation, shape)
|
||||
tool.Loader.link_mesh(shape, camera)
|
||||
|
||||
obj = bpy.data.objects.new(tool.Loader.get_name(drawing), camera)
|
||||
cls.import_camera_props(drawing, obj)
|
||||
cls.import_camera_props(drawing, camera)
|
||||
tool.Ifc.link(drawing, obj)
|
||||
|
||||
mat = Matrix(ifcopenshell.util.shape.get_shape_matrix(shape))
|
||||
@@ -750,14 +712,14 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def import_camera_props(cls, drawing: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
|
||||
def import_camera_props(cls, drawing: ifcopenshell.entity_instance, camera: bpy.types.Camera) -> None:
|
||||
from bonsai.bim.module.drawing.prop import get_diagram_scales
|
||||
|
||||
# Temporarily clear the definition id to prevent prop update callbacks to IFC.
|
||||
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
|
||||
obj.BIMObjectProperties.ifc_definition_id = 0
|
||||
camera_props = camera.BIMCameraProperties
|
||||
update_props = camera_props.update_props
|
||||
camera_props.update_props = False
|
||||
|
||||
camera = obj.data
|
||||
camera.BIMCameraProperties.has_underlay = False
|
||||
camera.BIMCameraProperties.has_linework = True
|
||||
camera.BIMCameraProperties.has_annotation = True
|
||||
@@ -791,7 +753,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
if "IsNTS" in pset:
|
||||
camera.BIMCameraProperties.is_nts = bool(pset["IsNTS"])
|
||||
|
||||
obj.BIMObjectProperties.ifc_definition_id = ifc_definition_id
|
||||
camera_props.update_props = update_props
|
||||
|
||||
@classmethod
|
||||
def import_drawings(cls) -> None:
|
||||
@@ -1906,7 +1868,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
if obj.name in element_obj_names or not tool.Ifc.get_entity(obj)
|
||||
]
|
||||
|
||||
cls.import_camera_props(drawing, camera)
|
||||
cls.import_camera_props(drawing, camera.data)
|
||||
|
||||
for obj in selected_objects_before:
|
||||
obj.hide_set(False)
|
||||
|
||||
@@ -617,7 +617,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
shape = ifcopenshell.geom.create_shape(settings, element, representation)
|
||||
|
||||
if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
||||
mesh = ifc_importer.create_camera(element, shape)
|
||||
mesh = tool.Loader.create_camera(element, representation, shape)
|
||||
if element.is_a("IfcAnnotation") and ifc_importer.is_curve_annotation(element):
|
||||
mesh = ifc_importer.create_curve(element, shape)
|
||||
elif shape:
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import re
|
||||
import math
|
||||
import bpy
|
||||
import bmesh
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.geolocation
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.unit
|
||||
import bonsai.core.tool
|
||||
@@ -671,6 +673,62 @@ class Loader(bonsai.core.tool.Loader):
|
||||
mesh.from_pydata(vertex_list, [], [])
|
||||
return mesh
|
||||
|
||||
@classmethod
|
||||
def create_camera(
|
||||
cls,
|
||||
element: ifcopenshell.entity_instance,
|
||||
representation: ifcopenshell.entity_instance,
|
||||
shape: Union[ifcopenshell.geom.ShapeElementType, ifcopenshell.geom.ShapeType],
|
||||
) -> bpy.types.Camera:
|
||||
from bonsai.bim.module.drawing.prop import get_diagram_scales
|
||||
|
||||
if isinstance(shape, ifcopenshell.geom.ShapeElementType):
|
||||
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_type = "ORTHO"
|
||||
if "IfcRectangularPyramid" in {e.is_a() for e in tool.Ifc.get().traverse(representation)}:
|
||||
camera_type = "PERSP"
|
||||
|
||||
camera = bpy.data.cameras.new(tool.Loader.get_mesh_name_from_shape(geometry))
|
||||
camera.type = camera_type
|
||||
camera.show_limits = True
|
||||
|
||||
if camera_type == "ORTHO":
|
||||
camera.clip_start = 0.002 # Technically 0, but Blender doesn't allow this, so 2mm it is!
|
||||
camera.clip_end = depth
|
||||
|
||||
camera.BIMCameraProperties.width = width
|
||||
camera.BIMCameraProperties.height = height
|
||||
elif camera_type == "PERSP":
|
||||
abs_min_z = abs(min(z))
|
||||
abs_max_z = abs(max(z))
|
||||
camera.clip_start = abs_max_z
|
||||
camera.clip_end = abs_min_z
|
||||
max_res = 1000
|
||||
|
||||
camera.BIMCameraProperties.width = width
|
||||
camera.BIMCameraProperties.height = height
|
||||
|
||||
if width > height:
|
||||
fov = 2 * math.atan(width / (2 * abs_min_z))
|
||||
else:
|
||||
fov = 2 * math.atan(height / (2 * abs_min_z))
|
||||
|
||||
camera.angle = fov
|
||||
|
||||
tool.Drawing.import_camera_props(element, camera)
|
||||
return camera
|
||||
|
||||
@classmethod
|
||||
def get_offset_point(cls, ifc_file: ifcopenshell.file) -> Union[npt.NDArray[np.float64], None]:
|
||||
elements_checked = 0
|
||||
|
||||
Reference in New Issue
Block a user