mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Expose camera type to UI and automatically update IFC camera type on drawing activation
Noticed fixing #6670 that though example project in this issue had camera named "PERSPECTIVE" but it was saved to IFC as orthogonal and there is no straightforward way to change it, besides changing Blender camera props and updating representation. Example - https://imgur.com/a/GQ9A3EK It's kind of exposed to UI now, but there's still bunch of issues with it to address.
This commit is contained in:
@@ -45,6 +45,10 @@ def set_active_camera_resolution(scene: bpy.types.Scene) -> None:
|
||||
return
|
||||
assert isinstance((camera := camera_obj.data), bpy.types.Camera)
|
||||
props = tool.Drawing.get_camera_props(camera)
|
||||
|
||||
if camera.type != props.camera_type:
|
||||
camera.type = props.camera_type
|
||||
|
||||
ortho_scale, aspect_ratio = props.get_scale_and_aspect_ratio()
|
||||
scene_render = scene.render
|
||||
if (camera.ortho_scale != ortho_scale) or not tool.Cad.is_x(
|
||||
|
||||
@@ -46,7 +46,7 @@ from bpy.props import (
|
||||
CollectionProperty,
|
||||
BoolVectorProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Literal, Any, Callable
|
||||
from typing import TYPE_CHECKING, Literal, Any, Callable, get_args
|
||||
|
||||
|
||||
diagram_scales_enum = []
|
||||
@@ -57,11 +57,11 @@ def purge():
|
||||
diagram_scales_enum = []
|
||||
|
||||
|
||||
def update_target_view(self, context):
|
||||
def update_target_view(self: "DocProperties", context: bpy.types.Context) -> None:
|
||||
DrawingsData.data["location_hint"] = DrawingsData.location_hint()
|
||||
|
||||
|
||||
def get_location_hint(self, context):
|
||||
def get_location_hint(self: "DocProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
|
||||
if not DrawingsData.is_loaded:
|
||||
DrawingsData.load()
|
||||
return DrawingsData.data["location_hint"]
|
||||
@@ -232,6 +232,12 @@ def update_has_linework(self: "BIMCameraProperties", context: bpy.types.Context)
|
||||
update_layer(self, context, "HasLinework", self.has_linework)
|
||||
|
||||
|
||||
def update_target_view(self: "BIMCameraProperties", context: bpy.types.Context) -> None:
|
||||
if self.target_view != "MODEL_VIEW":
|
||||
self.camera_type = "ORTHO"
|
||||
update_layer(self, context, "TargetView", self.target_view)
|
||||
|
||||
|
||||
def update_dpi(self: "BIMCameraProperties", context: bpy.types.Context) -> None:
|
||||
update_layer(self, context, "DPI", self.dpi)
|
||||
|
||||
@@ -497,6 +503,18 @@ def update_width_height(self: "BIMCameraProperties", context: bpy.types.Context)
|
||||
self.update_camera_resolution()
|
||||
|
||||
|
||||
def update_camera_type(self: "BIMCameraProperties", context: bpy.types.Context) -> None:
|
||||
assert isinstance(camera := self.id_data, bpy.types.Camera)
|
||||
camera.type = self.camera_type
|
||||
|
||||
|
||||
CameraType = Literal["PERSP", "ORTHO"]
|
||||
CAMERA_TYPE_NAMES: dict[CameraType, str] = {
|
||||
"PERSP": "Perspective",
|
||||
"ORTHO": "Ortographic",
|
||||
}
|
||||
|
||||
|
||||
class BIMCameraProperties(PropertyGroup):
|
||||
linework_mode: EnumProperty(
|
||||
items=[
|
||||
@@ -547,7 +565,7 @@ class BIMCameraProperties(PropertyGroup):
|
||||
name="Target View",
|
||||
default="PLAN_VIEW",
|
||||
items=TARGET_VIEW_ITEMS,
|
||||
update=get_update_layer_callback("target_view", "TargetView"),
|
||||
update=update_target_view,
|
||||
)
|
||||
|
||||
representation: StringProperty(name="Representation")
|
||||
@@ -560,6 +578,13 @@ class BIMCameraProperties(PropertyGroup):
|
||||
dpi: IntProperty(name="DPI", default=75, update=update_dpi)
|
||||
width: FloatProperty(name="Width", default=50, subtype="DISTANCE", update=update_width_height)
|
||||
height: FloatProperty(name="Height", default=50, subtype="DISTANCE", update=update_width_height)
|
||||
# Bonsai property is needed to prevent user from using unsupported panoramic camera.
|
||||
camera_type: EnumProperty(
|
||||
name="Camera Type",
|
||||
default="ORTHO",
|
||||
items=[(key, name, "") for key, name in CAMERA_TYPE_NAMES.items()],
|
||||
update=update_camera_type,
|
||||
)
|
||||
is_nts: BoolProperty(name="Is NTS", update=update_is_nts)
|
||||
active_drawing_style_index: IntProperty(name="Active Drawing Style Index")
|
||||
filter_mode: StringProperty(name="Filter Mode", default="NONE")
|
||||
@@ -591,6 +616,7 @@ class BIMCameraProperties(PropertyGroup):
|
||||
dpi: int
|
||||
width: float
|
||||
height: float
|
||||
camera_type: CameraType
|
||||
is_nts: bool
|
||||
active_drawing_style_index: int
|
||||
filter_mode: str
|
||||
@@ -618,6 +644,7 @@ class BIMCameraProperties(PropertyGroup):
|
||||
|
||||
representation = json.dumps(
|
||||
{
|
||||
"type": self.camera_type,
|
||||
"matrix": [[round_(v) for v in row] for row in matrix_world],
|
||||
"raster_x": self.raster_x,
|
||||
"raster_y": self.raster_y,
|
||||
|
||||
@@ -74,6 +74,10 @@ class BIM_PT_camera(Panel):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "target_view")
|
||||
|
||||
if props.target_view == "MODEL_VIEW":
|
||||
row = self.layout.row()
|
||||
row.prop(props, "camera_type")
|
||||
|
||||
row = self.layout.row()
|
||||
row.prop(props, "linework_mode")
|
||||
if props.linework_mode == "OPENCASCADE":
|
||||
|
||||
@@ -303,9 +303,9 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
camera.location = (0, 0, 1.5) # The view shall be 1.5m above the origin
|
||||
camera_data.show_limits = True
|
||||
if location_hint == "PERSPECTIVE":
|
||||
camera_data.type = "PERSP"
|
||||
props.camera_type = "PERSP"
|
||||
else:
|
||||
camera_data.type = "ORTHO"
|
||||
props.camera_type = "ORTHO"
|
||||
camera_data.ortho_scale = 50 # The default of 6m is too small
|
||||
camera_data.clip_start = 0.002 # 2mm is close to zero but allows any GPU-drawn lines to be visible.
|
||||
camera_data.clip_end = 10 # A slightly more reasonable default
|
||||
|
||||
@@ -830,9 +830,9 @@ class Loader(bonsai.core.tool.Loader):
|
||||
camera_type = "PERSP"
|
||||
|
||||
camera = bpy.data.cameras.new(tool.Loader.get_mesh_name_from_shape(geometry))
|
||||
camera.type = camera_type
|
||||
camera.show_limits = True
|
||||
props = tool.Drawing.get_camera_props(camera)
|
||||
props.camera_type = camera_type
|
||||
camera.show_limits = True
|
||||
|
||||
if camera_type == "ORTHO":
|
||||
depth = ifcopenshell.util.shape.get_z(geometry)
|
||||
@@ -860,7 +860,6 @@ class Loader(bonsai.core.tool.Loader):
|
||||
camera.angle = fov
|
||||
|
||||
tool.Drawing.import_camera_props(element, camera)
|
||||
props = tool.Drawing.get_camera_props(camera)
|
||||
props.update_camera_resolution() # Only after all props are imported.
|
||||
mat = tool.Drawing.get_camera_shape_matrix(element, shape)
|
||||
props.update_representation(mat)
|
||||
|
||||
Reference in New Issue
Block a user