fix error reloading camera representation

After 4b4ede7 it was leading to non-existing code
This commit is contained in:
Andrej730
2024-08-23 16:23:03 +05:00
parent 9f00e8aef0
commit 92f4cb0ffa
4 changed files with 76 additions and 49 deletions
@@ -68,6 +68,8 @@ def get_location_hint(self, context):
def update_diagram_scale(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: if not context.scene.camera or context.scene.camera.data != self.id_data:
return return
element = tool.Ifc.get_entity(context.scene.camera) element = tool.Ifc.get_entity(context.scene.camera)
@@ -94,6 +96,8 @@ def update_diagram_scale(self, context):
def update_is_nts(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: if not context.scene.camera or context.scene.camera.data != self.id_data:
return return
element = tool.Ifc.get_entity(context.scene.camera) 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): 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: if not context.scene.camera or context.scene.camera.data != self.id_data:
return return
element = tool.Ifc.get_entity(context.scene.camera) element = tool.Ifc.get_entity(context.scene.camera)
@@ -400,6 +406,7 @@ class BIMCameraProperties(PropertyGroup):
filter_mode: StringProperty(name="Filter Mode", default="NONE") filter_mode: StringProperty(name="Filter Mode", default="NONE")
include_filter_groups: CollectionProperty(type=BIMFilterGroup, name="Include Filter") include_filter_groups: CollectionProperty(type=BIMFilterGroup, name="Include Filter")
exclude_filter_groups: CollectionProperty(type=BIMFilterGroup, name="Exclude 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" # 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 # By checking this, you will know whether or not the camera IFC representation needs to be refreshed
+10 -48
View File
@@ -689,53 +689,15 @@ class Drawing(bonsai.core.tool.Drawing):
def import_drawing(cls, drawing: ifcopenshell.entity_instance) -> bpy.types.Object: def import_drawing(cls, drawing: ifcopenshell.entity_instance) -> bpy.types.Object:
settings = ifcopenshell.geom.settings() settings = ifcopenshell.geom.settings()
camera_type = "ORTHO" representation = ifcopenshell.util.representation.get_representation(drawing, "Model", "Body", "MODEL_VIEW")
body = ifcopenshell.util.representation.get_representation(drawing, "Model", "Body", "MODEL_VIEW") assert representation
if "IfcRectangularPyramid" in {e.is_a() for e in tool.Ifc.get().traverse(body)}:
camera_type = "PERSP"
shape = ifcopenshell.geom.create_shape(settings, drawing) shape = ifcopenshell.geom.create_shape(settings, drawing)
geometry = shape.geometry camera = tool.Loader.create_camera(drawing, representation, 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(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.Loader.link_mesh(shape, camera) tool.Loader.link_mesh(shape, camera)
obj = bpy.data.objects.new(tool.Loader.get_name(drawing), 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) tool.Ifc.link(drawing, obj)
mat = Matrix(ifcopenshell.util.shape.get_shape_matrix(shape)) mat = Matrix(ifcopenshell.util.shape.get_shape_matrix(shape))
@@ -750,14 +712,14 @@ class Drawing(bonsai.core.tool.Drawing):
return obj return obj
@classmethod @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 from bonsai.bim.module.drawing.prop import get_diagram_scales
# Temporarily clear the definition id to prevent prop update callbacks to IFC. # Temporarily clear the definition id to prevent prop update callbacks to IFC.
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id camera_props = camera.BIMCameraProperties
obj.BIMObjectProperties.ifc_definition_id = 0 update_props = camera_props.update_props
camera_props.update_props = False
camera = obj.data
camera.BIMCameraProperties.has_underlay = False camera.BIMCameraProperties.has_underlay = False
camera.BIMCameraProperties.has_linework = True camera.BIMCameraProperties.has_linework = True
camera.BIMCameraProperties.has_annotation = True camera.BIMCameraProperties.has_annotation = True
@@ -791,7 +753,7 @@ class Drawing(bonsai.core.tool.Drawing):
if "IsNTS" in pset: if "IsNTS" in pset:
camera.BIMCameraProperties.is_nts = bool(pset["IsNTS"]) camera.BIMCameraProperties.is_nts = bool(pset["IsNTS"])
obj.BIMObjectProperties.ifc_definition_id = ifc_definition_id camera_props.update_props = update_props
@classmethod @classmethod
def import_drawings(cls) -> None: 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) 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: for obj in selected_objects_before:
obj.hide_set(False) obj.hide_set(False)
+1 -1
View File
@@ -617,7 +617,7 @@ class Geometry(bonsai.core.tool.Geometry):
shape = ifcopenshell.geom.create_shape(settings, element, representation) shape = ifcopenshell.geom.create_shape(settings, element, representation)
if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING": 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): if element.is_a("IfcAnnotation") and ifc_importer.is_curve_annotation(element):
mesh = ifc_importer.create_curve(element, shape) mesh = ifc_importer.create_curve(element, shape)
elif shape: elif shape:
+58
View File
@@ -19,12 +19,14 @@
from __future__ import annotations from __future__ import annotations
import os import os
import re import re
import math
import bpy import bpy
import bmesh import bmesh
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.geolocation import ifcopenshell.util.geolocation
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape import ifcopenshell.util.shape
import ifcopenshell.util.unit import ifcopenshell.util.unit
import bonsai.core.tool import bonsai.core.tool
@@ -671,6 +673,62 @@ class Loader(bonsai.core.tool.Loader):
mesh.from_pydata(vertex_list, [], []) mesh.from_pydata(vertex_list, [], [])
return mesh 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 @classmethod
def get_offset_point(cls, ifc_file: ifcopenshell.file) -> Union[npt.NDArray[np.float64], None]: def get_offset_point(cls, ifc_file: ifcopenshell.file) -> Union[npt.NDArray[np.float64], None]:
elements_checked = 0 elements_checked = 0