mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-01 17:36:27 +00:00
black .
This commit is contained in:
@@ -1558,9 +1558,7 @@ def snap_to_mesh(
|
|||||||
return _snap_manager.snap_to_mesh(location, context, active_obj, mouse_coords, include_active)
|
return _snap_manager.snap_to_mesh(location, context, active_obj, mouse_coords, include_active)
|
||||||
|
|
||||||
|
|
||||||
def build_snap_cache(
|
def build_snap_cache(context: bpy.types.Context, active_obj: bpy.types.Object, include_active: bool = False) -> None:
|
||||||
context: bpy.types.Context, active_obj: bpy.types.Object, include_active: bool = False
|
|
||||||
) -> None:
|
|
||||||
_snap_manager.build_snap_cache(context, active_obj, include_active)
|
_snap_manager.build_snap_cache(context, active_obj, include_active)
|
||||||
|
|
||||||
|
|
||||||
@@ -2013,7 +2011,6 @@ class UglyDotGizmo(OffsetHandle, types.Gizmo):
|
|||||||
self.draw_custom_shape(self.custom_shape, select_id=select_id)
|
self.draw_custom_shape(self.custom_shape, select_id=select_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExtrusionGuidesGizmo(CustomGizmo, types.Gizmo):
|
class ExtrusionGuidesGizmo(CustomGizmo, types.Gizmo):
|
||||||
"""Extrusion guides
|
"""Extrusion guides
|
||||||
|
|
||||||
@@ -2047,7 +2044,6 @@ class ExtrusionGuidesGizmo(CustomGizmo, types.Gizmo):
|
|||||||
self.matrix_offset.col[2][2] = depth # z-scaled
|
self.matrix_offset.col[2][2] = depth # z-scaled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExtrusionWidget(types.GizmoGroup):
|
class ExtrusionWidget(types.GizmoGroup):
|
||||||
bl_idname = "bim.extrusion_widget"
|
bl_idname = "bim.extrusion_widget"
|
||||||
bl_label = "Extrusion Gizmos"
|
bl_label = "Extrusion Gizmos"
|
||||||
@@ -2098,7 +2094,6 @@ class ExtrusionWidget(types.GizmoGroup):
|
|||||||
gz.target_set_prop("depth", prop, "value")
|
gz.target_set_prop("depth", prop, "value")
|
||||||
gz.scale_value = scale_value
|
gz.scale_value = scale_value
|
||||||
|
|
||||||
|
|
||||||
def refresh(self, context: bpy.types.Context) -> None:
|
def refresh(self, context: bpy.types.Context) -> None:
|
||||||
"""updating gizmos"""
|
"""updating gizmos"""
|
||||||
target = context.active_object
|
target = context.active_object
|
||||||
@@ -2146,10 +2141,12 @@ class ExtrusionWidget(types.GizmoGroup):
|
|||||||
scale_value /= si_conversions["thou"]
|
scale_value /= si_conversions["thou"]
|
||||||
return scale_value
|
return scale_value
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Core Gizmo Classes
|
# Core Gizmo Classes
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
class BIM_OT_gizmo_value_input(bpy.types.Operator):
|
class BIM_OT_gizmo_value_input(bpy.types.Operator):
|
||||||
"""Enter a numeric value for a gizmo property. Click or Enter to confirm, ESC to cancel."""
|
"""Enter a numeric value for a gizmo property. Click or Enter to confirm, ESC to cancel."""
|
||||||
|
|
||||||
@@ -2462,10 +2459,7 @@ class GizmoMovable(bpy.types.Gizmo):
|
|||||||
self.keyboard_input.reset()
|
self.keyboard_input.reset()
|
||||||
|
|
||||||
should_invoke_keyboard = (
|
should_invoke_keyboard = (
|
||||||
not cancel
|
not cancel and hasattr(self, "_has_dragged") and not self._has_dragged and self.move_set_cb is not None
|
||||||
and hasattr(self, "_has_dragged")
|
|
||||||
and not self._has_dragged
|
|
||||||
and self.move_set_cb is not None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if should_invoke_keyboard:
|
if should_invoke_keyboard:
|
||||||
@@ -2528,7 +2522,7 @@ class GizmoMovable(bpy.types.Gizmo):
|
|||||||
if not self._has_dragged and hasattr(self, "_start_mouse_pos"):
|
if not self._has_dragged and hasattr(self, "_start_mouse_pos"):
|
||||||
dx = current_coord[0] - self._start_mouse_pos[0]
|
dx = current_coord[0] - self._start_mouse_pos[0]
|
||||||
dy = current_coord[1] - self._start_mouse_pos[1]
|
dy = current_coord[1] - self._start_mouse_pos[1]
|
||||||
if (dx * dx + dy * dy) > (self.DRAG_THRESHOLD ** 2):
|
if (dx * dx + dy * dy) > (self.DRAG_THRESHOLD**2):
|
||||||
self._has_dragged = True
|
self._has_dragged = True
|
||||||
view_origin = region_2d_to_origin_3d(region, rv3d, current_coord)
|
view_origin = region_2d_to_origin_3d(region, rv3d, current_coord)
|
||||||
view_direction = region_2d_to_vector_3d(region, rv3d, current_coord)
|
view_direction = region_2d_to_vector_3d(region, rv3d, current_coord)
|
||||||
@@ -2576,9 +2570,7 @@ class GizmoMovable(bpy.types.Gizmo):
|
|||||||
|
|
||||||
return {"RUNNING_MODAL"}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
def _handle_keyboard_input(
|
def _handle_keyboard_input(self, context: bpy.types.Context, event: bpy.types.Event) -> set[str] | None:
|
||||||
self, context: bpy.types.Context, event: bpy.types.Event
|
|
||||||
) -> set[str] | None:
|
|
||||||
"""Handle keyboard numeric input."""
|
"""Handle keyboard numeric input."""
|
||||||
kb = self.keyboard_input
|
kb = self.keyboard_input
|
||||||
|
|
||||||
@@ -3266,10 +3258,16 @@ class GizmoArrow2D(GizmoMovable):
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
# Shaft
|
# Shaft
|
||||||
(0, -w, 0), (shaft, -w, 0), (0, w, 0),
|
(0, -w, 0),
|
||||||
(0, w, 0), (shaft, -w, 0), (shaft, w, 0),
|
(shaft, -w, 0),
|
||||||
|
(0, w, 0),
|
||||||
|
(0, w, 0),
|
||||||
|
(shaft, -w, 0),
|
||||||
|
(shaft, w, 0),
|
||||||
# Head
|
# Head
|
||||||
(shaft, -hw, 0), (shaft + head, 0, 0), (shaft, hw, 0),
|
(shaft, -hw, 0),
|
||||||
|
(shaft + head, 0, 0),
|
||||||
|
(shaft, hw, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup(self) -> None:
|
def setup(self) -> None:
|
||||||
@@ -3434,14 +3432,30 @@ class GizmoDimension(GizmoMovable):
|
|||||||
"""Generate a simple clickable bar shape (unit length along X)."""
|
"""Generate a simple clickable bar shape (unit length along X)."""
|
||||||
hw = self.HIT_WIDTH / 2
|
hw = self.HIT_WIDTH / 2
|
||||||
return (
|
return (
|
||||||
(0, -hw, -hw), (1, -hw, -hw), (0, hw, -hw),
|
(0, -hw, -hw),
|
||||||
(0, hw, -hw), (1, -hw, -hw), (1, hw, -hw),
|
(1, -hw, -hw),
|
||||||
(0, -hw, hw), (0, hw, hw), (1, -hw, hw),
|
(0, hw, -hw),
|
||||||
(1, -hw, hw), (0, hw, hw), (1, hw, hw),
|
(0, hw, -hw),
|
||||||
(0, -hw, -hw), (0, -hw, hw), (1, -hw, -hw),
|
(1, -hw, -hw),
|
||||||
(1, -hw, -hw), (0, -hw, hw), (1, -hw, hw),
|
(1, hw, -hw),
|
||||||
(0, hw, -hw), (1, hw, -hw), (0, hw, hw),
|
(0, -hw, hw),
|
||||||
(0, hw, hw), (1, hw, -hw), (1, hw, hw),
|
(0, hw, hw),
|
||||||
|
(1, -hw, hw),
|
||||||
|
(1, -hw, hw),
|
||||||
|
(0, hw, hw),
|
||||||
|
(1, hw, hw),
|
||||||
|
(0, -hw, -hw),
|
||||||
|
(0, -hw, hw),
|
||||||
|
(1, -hw, -hw),
|
||||||
|
(1, -hw, -hw),
|
||||||
|
(0, -hw, hw),
|
||||||
|
(1, -hw, hw),
|
||||||
|
(0, hw, -hw),
|
||||||
|
(1, hw, -hw),
|
||||||
|
(0, hw, hw),
|
||||||
|
(0, hw, hw),
|
||||||
|
(1, hw, -hw),
|
||||||
|
(1, hw, hw),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup(self) -> None:
|
def setup(self) -> None:
|
||||||
@@ -3483,9 +3497,7 @@ class GizmoDimension(GizmoMovable):
|
|||||||
display_value=getattr(self, "_display_value", self._dimension_length),
|
display_value=getattr(self, "_display_value", self._dimension_length),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _calculate_screen_endpoints(
|
def _calculate_screen_endpoints(self, context: bpy.types.Context) -> tuple[Vector, Vector, Vector, float] | None:
|
||||||
self, context: bpy.types.Context
|
|
||||||
) -> tuple[Vector, Vector, Vector, float] | None:
|
|
||||||
"""Calculate screen-space endpoints and direction for the dimension line.
|
"""Calculate screen-space endpoints and direction for the dimension line.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -3726,7 +3738,7 @@ class GizmoDimension(GizmoMovable):
|
|||||||
if not self._has_dragged and hasattr(self, "_start_mouse_pos"):
|
if not self._has_dragged and hasattr(self, "_start_mouse_pos"):
|
||||||
dx = current_coord[0] - self._start_mouse_pos[0]
|
dx = current_coord[0] - self._start_mouse_pos[0]
|
||||||
dy = current_coord[1] - self._start_mouse_pos[1]
|
dy = current_coord[1] - self._start_mouse_pos[1]
|
||||||
if (dx * dx + dy * dy) > (self.DRAG_THRESHOLD ** 2):
|
if (dx * dx + dy * dy) > (self.DRAG_THRESHOLD**2):
|
||||||
self._has_dragged = True
|
self._has_dragged = True
|
||||||
view_origin = region_2d_to_origin_3d(region, rv3d, current_coord)
|
view_origin = region_2d_to_origin_3d(region, rv3d, current_coord)
|
||||||
view_direction = region_2d_to_vector_3d(region, rv3d, current_coord)
|
view_direction = region_2d_to_vector_3d(region, rv3d, current_coord)
|
||||||
@@ -3815,10 +3827,7 @@ class GizmoDimension(GizmoMovable):
|
|||||||
self.keyboard_input.reset()
|
self.keyboard_input.reset()
|
||||||
|
|
||||||
should_invoke_keyboard = (
|
should_invoke_keyboard = (
|
||||||
not cancel
|
not cancel and hasattr(self, "_has_dragged") and not self._has_dragged and self.move_set_cb is not None
|
||||||
and hasattr(self, "_has_dragged")
|
|
||||||
and not self._has_dragged
|
|
||||||
and self.move_set_cb is not None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if should_invoke_keyboard:
|
if should_invoke_keyboard:
|
||||||
@@ -3989,7 +3998,7 @@ class BaseParametricGizmoGroup:
|
|||||||
GIZMO_CLAMP_MAX = 10000.0 # Maximum value for dimension clamping (meters)
|
GIZMO_CLAMP_MAX = 10000.0 # Maximum value for dimension clamping (meters)
|
||||||
|
|
||||||
# Pre-computed flip matrix for negative value handling (180° rotation around Z)
|
# Pre-computed flip matrix for negative value handling (180° rotation around Z)
|
||||||
FLIP_MATRIX = Matrix.Rotation(math.pi, 4, 'Z')
|
FLIP_MATRIX = Matrix.Rotation(math.pi, 4, "Z")
|
||||||
|
|
||||||
# === Icon Gizmo Layout (meters) ===
|
# === Icon Gizmo Layout (meters) ===
|
||||||
# Icons are positioned in a horizontal row above the element:
|
# Icons are positioned in a horizontal row above the element:
|
||||||
@@ -4073,9 +4082,7 @@ class BaseParametricGizmoGroup:
|
|||||||
from_neg_y, from_neg_x = self.get_local_view_direction(context, world_matrix)
|
from_neg_y, from_neg_x = self.get_local_view_direction(context, world_matrix)
|
||||||
return ViewDirection(from_negative_y=from_neg_y, from_negative_x=from_neg_x)
|
return ViewDirection(from_negative_y=from_neg_y, from_negative_x=from_neg_x)
|
||||||
|
|
||||||
def update_gizmo_visibility(
|
def update_gizmo_visibility(self, gizmo: bpy.types.Gizmo, is_editing: bool, pref_enabled: bool) -> bool:
|
||||||
self, gizmo: bpy.types.Gizmo, is_editing: bool, pref_enabled: bool
|
|
||||||
) -> bool:
|
|
||||||
"""Update gizmo visibility based on modal state, editing state, and preference.
|
"""Update gizmo visibility based on modal state, editing state, and preference.
|
||||||
|
|
||||||
Consolidates the common pattern:
|
Consolidates the common pattern:
|
||||||
@@ -4154,9 +4161,7 @@ class BaseParametricGizmoGroup:
|
|||||||
"""
|
"""
|
||||||
return Matrix.Translation(translation) @ self.get_axis_rotation_matrix(axis)
|
return Matrix.Translation(translation) @ self.get_axis_rotation_matrix(axis)
|
||||||
|
|
||||||
def get_lining_y_position_for_view(
|
def get_lining_y_position_for_view(self, props, viewing_from_negative_y: bool, use_offset: bool = True) -> float:
|
||||||
self, props, viewing_from_negative_y: bool, use_offset: bool = True
|
|
||||||
) -> float:
|
|
||||||
"""Get Y position for lining-based elements (doors, windows) based on view direction.
|
"""Get Y position for lining-based elements (doors, windows) based on view direction.
|
||||||
|
|
||||||
For elements with lining_offset property, this calculates the Y position
|
For elements with lining_offset property, this calculates the Y position
|
||||||
@@ -4207,9 +4212,7 @@ class BaseParametricGizmoGroup:
|
|||||||
Override in subclass if different positioning is needed.
|
Override in subclass if different positioning is needed.
|
||||||
"""
|
"""
|
||||||
width = getattr(props, "overall_width", 0)
|
width = getattr(props, "overall_width", 0)
|
||||||
return self.compose_gizmo_matrix(
|
return self.compose_gizmo_matrix(Vector((width + self.GIZMO_OFFSET, 0, -self.GIZMO_OFFSET)), (0, 1, 0))
|
||||||
Vector((width + self.GIZMO_OFFSET, 0, -self.GIZMO_OFFSET)), (0, 1, 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_casing_offset(self, props) -> float:
|
def get_casing_offset(self, props) -> float:
|
||||||
"""Get casing offset for view-dependent dimension positioning.
|
"""Get casing offset for view-dependent dimension positioning.
|
||||||
@@ -4219,9 +4222,7 @@ class BaseParametricGizmoGroup:
|
|||||||
"""
|
"""
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
def _update_view_dependent_dimensions(
|
def _update_view_dependent_dimensions(self, context: bpy.types.Context, mw: Matrix, props) -> None:
|
||||||
self, context: bpy.types.Context, mw: Matrix, props
|
|
||||||
) -> None:
|
|
||||||
"""Update overall_width, overall_height, and lining_offset based on view direction.
|
"""Update overall_width, overall_height, and lining_offset based on view direction.
|
||||||
|
|
||||||
This base implementation handles the common pattern for door/window gizmos.
|
This base implementation handles the common pattern for door/window gizmos.
|
||||||
@@ -4358,9 +4359,7 @@ class BaseParametricGizmoGroup:
|
|||||||
self.update_dimension_gizmos(mw, props)
|
self.update_dimension_gizmos(mw, props)
|
||||||
self._refresh_element_specific(context, mw, props)
|
self._refresh_element_specific(context, mw, props)
|
||||||
|
|
||||||
def _refresh_element_specific(
|
def _refresh_element_specific(self, context: bpy.types.Context, mw: "Matrix", props) -> None: # noqa: ARG002
|
||||||
self, context: bpy.types.Context, mw: "Matrix", props # noqa: ARG002
|
|
||||||
) -> None:
|
|
||||||
"""Override for element-specific refresh logic.
|
"""Override for element-specific refresh logic.
|
||||||
|
|
||||||
Called after update_editing_gizmos and update_dimension_gizmos.
|
Called after update_editing_gizmos and update_dimension_gizmos.
|
||||||
@@ -4383,6 +4382,7 @@ class BaseParametricGizmoGroup:
|
|||||||
if self.props_getter:
|
if self.props_getter:
|
||||||
return getattr(tool.Model, self.props_getter)(obj)
|
return getattr(tool.Model, self.props_getter)(obj)
|
||||||
raise NotImplementedError("Subclass must define props_getter or override get_props()")
|
raise NotImplementedError("Subclass must define props_getter or override get_props()")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_addon_prefs():
|
def get_addon_prefs():
|
||||||
"""Get addon preferences (cached accessor)."""
|
"""Get addon preferences (cached accessor)."""
|
||||||
@@ -4803,7 +4803,9 @@ class BaseParametricGizmoGroup:
|
|||||||
self.cycle_gizmo.hide = self.is_gizmo_hidden_by_modal(self.cycle_gizmo)
|
self.cycle_gizmo.hide = self.is_gizmo_hidden_by_modal(self.cycle_gizmo)
|
||||||
local_pos_cycle = Vector((self.ICON_VALIDATE_X + self.ICON_CYCLE_X, icon_y, icon_z))
|
local_pos_cycle = Vector((self.ICON_VALIDATE_X + self.ICON_CYCLE_X, icon_y, icon_z))
|
||||||
world_pos_cycle = mw @ local_pos_cycle
|
world_pos_cycle = mw @ local_pos_cycle
|
||||||
self.cycle_gizmo.matrix_basis = Matrix.Translation(world_pos_cycle) @ billboard_rot @ Matrix.Scale(0.30, 4)
|
self.cycle_gizmo.matrix_basis = (
|
||||||
|
Matrix.Translation(world_pos_cycle) @ billboard_rot @ Matrix.Scale(0.30, 4)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.pen_gizmo.hide = self.is_gizmo_hidden_by_modal(self.pen_gizmo)
|
self.pen_gizmo.hide = self.is_gizmo_hidden_by_modal(self.pen_gizmo)
|
||||||
self.pen_gizmo.matrix_basis = icon_matrix_base
|
self.pen_gizmo.matrix_basis = icon_matrix_base
|
||||||
|
|||||||
@@ -1007,7 +1007,7 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
for polygon in closed_polygons.geoms:
|
for polygon in closed_polygons.geoms:
|
||||||
# Less than 0.1mm2 is not worth styling on sheet
|
# Less than 0.1mm2 is not worth styling on sheet
|
||||||
if polygon.area < .1:
|
if polygon.area < 0.1:
|
||||||
continue
|
continue
|
||||||
centroid = polygon.centroid
|
centroid = polygon.centroid
|
||||||
centroid = centroid if polygon.contains(centroid) else polygon.representative_point()
|
centroid = centroid if polygon.contains(centroid) else polygon.representative_point()
|
||||||
|
|||||||
@@ -3408,11 +3408,27 @@ class ImportRepresentationItems(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
tool.Root.reload_item_decorator()
|
tool.Root.reload_item_decorator()
|
||||||
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if element and element.is_a("IfcAnnotation") and element.ObjectType in {
|
if (
|
||||||
"TEXT_LEADER", "DIMENSION", "RADIUS", "DIAMETER", "ANGLE",
|
element
|
||||||
"FALL", "SLOPE_ANGLE", "SLOPE_FRACTION", "SLOPE_PERCENT",
|
and element.is_a("IfcAnnotation")
|
||||||
"STAIR_ARROW", "PLAN_LEVEL", "SECTION_LEVEL", "SECTION", "ELEVATION"
|
and element.ObjectType
|
||||||
}:
|
in {
|
||||||
|
"TEXT_LEADER",
|
||||||
|
"DIMENSION",
|
||||||
|
"RADIUS",
|
||||||
|
"DIAMETER",
|
||||||
|
"ANGLE",
|
||||||
|
"FALL",
|
||||||
|
"SLOPE_ANGLE",
|
||||||
|
"SLOPE_FRACTION",
|
||||||
|
"SLOPE_PERCENT",
|
||||||
|
"STAIR_ARROW",
|
||||||
|
"PLAN_LEVEL",
|
||||||
|
"SECTION_LEVEL",
|
||||||
|
"SECTION",
|
||||||
|
"ELEVATION",
|
||||||
|
}
|
||||||
|
):
|
||||||
for item_obj_data in props.item_objs:
|
for item_obj_data in props.item_objs:
|
||||||
item_obj = item_obj_data.obj
|
item_obj = item_obj_data.obj
|
||||||
if item_obj and isinstance(item_obj.data, bpy.types.Mesh) and item_obj.data.vertices:
|
if item_obj and isinstance(item_obj.data, bpy.types.Mesh) and item_obj.data.vertices:
|
||||||
|
|||||||
@@ -779,89 +779,105 @@ class GizmoDoorEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
# matrix_position lambdas replace the get_dimension_matrix_* methods
|
# matrix_position lambdas replace the get_dimension_matrix_* methods
|
||||||
dimension_gizmo_props = [
|
dimension_gizmo_props = [
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="overall_width", axis=(1, 0, 0), min_value=0.01, text_offset_sign=-1,
|
attr_name="overall_width",
|
||||||
|
axis=(1, 0, 0),
|
||||||
|
min_value=0.01,
|
||||||
|
text_offset_sign=-1,
|
||||||
# Position set dynamically in _update_dimension_gizmo_positions based on view
|
# Position set dynamically in _update_dimension_gizmo_positions based on view
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="overall_height", axis=(0, 0, 1), min_value=0.01, text_alignment="start",
|
attr_name="overall_height",
|
||||||
|
axis=(0, 0, 1),
|
||||||
|
min_value=0.01,
|
||||||
|
text_alignment="start",
|
||||||
# Position set dynamically in _update_dimension_gizmo_positions based on view
|
# Position set dynamically in _update_dimension_gizmo_positions based on view
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="threshold_thickness", axis=(0, 0, 1),
|
attr_name="threshold_thickness",
|
||||||
|
axis=(0, 0, 1),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2, p.threshold_offset + p.threshold_depth, 0),
|
matrix_position=lambda p: V_(p.overall_width / 2, p.threshold_offset + p.threshold_depth, 0),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="threshold_depth", axis=(0, 1, 0),
|
attr_name="threshold_depth",
|
||||||
|
axis=(0, 1, 0),
|
||||||
visibility_condition=lambda p: p.has_threshold_depth(),
|
visibility_condition=lambda p: p.has_threshold_depth(),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2, p.threshold_offset, p.threshold_thickness),
|
matrix_position=lambda p: V_(p.overall_width / 2, p.threshold_offset, p.threshold_thickness),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="threshold_offset", axis=(0, 1, 0),
|
attr_name="threshold_offset",
|
||||||
|
axis=(0, 1, 0),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2 - _G.GIZMO_STACK_OFFSET, 0, p.threshold_thickness),
|
matrix_position=lambda p: V_(p.overall_width / 2 - _G.GIZMO_STACK_OFFSET, 0, p.threshold_thickness),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_offset", axis=(0, 1, 0), min_value=-10.0,
|
attr_name="lining_offset",
|
||||||
|
axis=(0, 1, 0),
|
||||||
|
min_value=-10.0,
|
||||||
# Position set dynamically in _update_dimension_gizmo_positions based on view
|
# Position set dynamically in _update_dimension_gizmo_positions based on view
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_depth", axis=(0, 1, 0),
|
attr_name="lining_depth",
|
||||||
|
axis=(0, 1, 0),
|
||||||
matrix_position=lambda p: V_(p.overall_width, p.lining_offset, p.overall_height),
|
matrix_position=lambda p: V_(p.overall_width, p.lining_offset, p.overall_height),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_thickness", axis=(-1, 0, 0),
|
attr_name="lining_thickness",
|
||||||
|
axis=(-1, 0, 0),
|
||||||
matrix_position=lambda p: V_(p.overall_width, p.lining_depth / 2, p.overall_height / 2),
|
matrix_position=lambda p: V_(p.overall_width, p.lining_depth / 2, p.overall_height / 2),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="transom_offset", axis=(0, 0, 1),
|
attr_name="transom_offset",
|
||||||
|
axis=(0, 0, 1),
|
||||||
visibility_condition=lambda p: p.has_transom(),
|
visibility_condition=lambda p: p.has_transom(),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, 0),
|
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, 0),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="transom_thickness", axis=(0, 0, 1),
|
attr_name="transom_thickness",
|
||||||
|
axis=(0, 0, 1),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, p.transom_offset),
|
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, p.transom_offset),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="casing_thickness", axis=(-1, 0, 0),
|
attr_name="casing_thickness",
|
||||||
|
axis=(-1, 0, 0),
|
||||||
visibility_condition=lambda p: p.has_casing(),
|
visibility_condition=lambda p: p.has_casing(),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.lining_thickness,
|
p.lining_thickness, p.lining_depth + p.lining_offset + p.casing_depth / 2, p.overall_height / 2
|
||||||
p.lining_depth + p.lining_offset + p.casing_depth / 2,
|
|
||||||
p.overall_height / 2
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="casing_depth", axis=(0, 1, 0),
|
attr_name="casing_depth",
|
||||||
|
axis=(0, 1, 0),
|
||||||
visibility_condition=lambda p: p.has_casing_depth(),
|
visibility_condition=lambda p: p.has_casing_depth(),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.lining_thickness - p.casing_thickness,
|
p.lining_thickness - p.casing_thickness, p.lining_depth + p.lining_offset, p.overall_height / 2
|
||||||
p.lining_depth + p.lining_offset,
|
|
||||||
p.overall_height / 2
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="panel_depth", axis=(0, 1, 0),
|
attr_name="panel_depth",
|
||||||
|
axis=(0, 1, 0),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.lining_to_panel_offset_x + p.overall_width * p.panel_width_ratio / 2,
|
p.lining_to_panel_offset_x + p.overall_width * p.panel_width_ratio / 2,
|
||||||
p.lining_offset + p.lining_to_panel_offset_y,
|
p.lining_offset + p.lining_to_panel_offset_y,
|
||||||
p.threshold_thickness + p.get_panel_center_z()
|
p.threshold_thickness + p.get_panel_center_z(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="frame_thickness", axis=(-1, 0, 0),
|
attr_name="frame_thickness",
|
||||||
|
axis=(-1, 0, 0),
|
||||||
visibility_condition=lambda p: p.has_transom(),
|
visibility_condition=lambda p: p.has_transom(),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.overall_width,
|
p.overall_width,
|
||||||
p.lining_offset + p.lining_to_panel_offset_y + p.frame_depth / 2,
|
p.lining_offset + p.lining_to_panel_offset_y + p.frame_depth / 2,
|
||||||
p.get_transom_window_center_z()
|
p.get_transom_window_center_z(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="frame_depth", axis=(0, 1, 0),
|
attr_name="frame_depth",
|
||||||
|
axis=(0, 1, 0),
|
||||||
visibility_condition=lambda p: p.has_transom(),
|
visibility_condition=lambda p: p.has_transom(),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.overall_width - p.frame_thickness,
|
p.overall_width - p.frame_thickness,
|
||||||
p.lining_offset + p.lining_to_panel_offset_y,
|
p.lining_offset + p.lining_to_panel_offset_y,
|
||||||
p.get_transom_window_center_z()
|
p.get_transom_window_center_z(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@@ -895,12 +911,14 @@ class GizmoDoorEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
special_color = prefs.decorator_color_special[:3]
|
special_color = prefs.decorator_color_special[:3]
|
||||||
|
|
||||||
self.gizmo_door_type = self.create_arc_gizmo(
|
self.gizmo_door_type = self.create_arc_gizmo(
|
||||||
special_color, "bim.toggle_door_swing",
|
special_color,
|
||||||
|
"bim.toggle_door_swing",
|
||||||
prop_path="BIMDoorProperties.door_type",
|
prop_path="BIMDoorProperties.door_type",
|
||||||
flip_geometry=False,
|
flip_geometry=False,
|
||||||
)
|
)
|
||||||
self.gizmo_flip_arc = self.create_arc_gizmo(
|
self.gizmo_flip_arc = self.create_arc_gizmo(
|
||||||
inactive_color, "bim.toggle_door_swing",
|
inactive_color,
|
||||||
|
"bim.toggle_door_swing",
|
||||||
prop_path="BIMDoorProperties.door_type",
|
prop_path="BIMDoorProperties.door_type",
|
||||||
flip_geometry=True,
|
flip_geometry=True,
|
||||||
flip_local_axes="XY",
|
flip_local_axes="XY",
|
||||||
@@ -916,7 +934,9 @@ class GizmoDoorEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
"""Override to return casing_thickness when lining_offset is 0."""
|
"""Override to return casing_thickness when lining_offset is 0."""
|
||||||
return props.get_casing_offset()
|
return props.get_casing_offset()
|
||||||
|
|
||||||
def _update_dimension_gizmo_positions(self, context: bpy.types.Context, mw: Matrix, props: "BIMDoorProperties") -> None:
|
def _update_dimension_gizmo_positions(
|
||||||
|
self, context: bpy.types.Context, mw: Matrix, props: "BIMDoorProperties"
|
||||||
|
) -> None:
|
||||||
"""Update dimension gizmo positions based on camera view direction."""
|
"""Update dimension gizmo positions based on camera view direction."""
|
||||||
self._update_view_dependent_dimensions(context, mw, props)
|
self._update_view_dependent_dimensions(context, mw, props)
|
||||||
|
|
||||||
|
|||||||
@@ -417,12 +417,14 @@ class RecalculateFill(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
representation=representation,
|
representation=representation,
|
||||||
)
|
)
|
||||||
|
|
||||||
#Refresh cut decorator
|
# Refresh cut decorator
|
||||||
DecoratorData.cut_cache.clear()
|
DecoratorData.cut_cache.clear()
|
||||||
DecoratorData.fill_cache.clear()
|
DecoratorData.fill_cache.clear()
|
||||||
DecoratorData.slice_cache.clear()
|
DecoratorData.slice_cache.clear()
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class FlipFill(bpy.types.Operator, tool.Ifc.Operator):
|
class FlipFill(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.flip_fill"
|
bl_idname = "bim.flip_fill"
|
||||||
bl_label = "Flip Fill"
|
bl_label = "Flip Fill"
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ def _get_updater(module_name: str, func_name: str) -> Callable:
|
|||||||
cache_key = f"{module_name}.{func_name}"
|
cache_key = f"{module_name}.{func_name}"
|
||||||
if cache_key not in _updater_cache:
|
if cache_key not in _updater_cache:
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
module = importlib.import_module(f"bonsai.bim.module.model.{module_name}")
|
module = importlib.import_module(f"bonsai.bim.module.model.{module_name}")
|
||||||
_updater_cache[cache_key] = getattr(module, func_name)
|
_updater_cache[cache_key] = getattr(module, func_name)
|
||||||
return _updater_cache[cache_key]
|
return _updater_cache[cache_key]
|
||||||
@@ -476,12 +477,18 @@ class BIMStairProperties(PropertyGroup):
|
|||||||
name="Lock Total Length",
|
name="Lock Total Length",
|
||||||
description="Lock Total Length when changing number of treads or tread run",
|
description="Lock Total Length when changing number of treads or tread run",
|
||||||
)
|
)
|
||||||
tread_depth: bpy.props.FloatProperty(name="Tread Depth", default=0.25, min=0.01, subtype="DISTANCE", update=update_stair)
|
tread_depth: bpy.props.FloatProperty(
|
||||||
|
name="Tread Depth", default=0.25, min=0.01, subtype="DISTANCE", update=update_stair
|
||||||
|
)
|
||||||
tread_run: bpy.props.FloatProperty(
|
tread_run: bpy.props.FloatProperty(
|
||||||
name="Tread Run", default=0.3, min=0.01, subtype="DISTANCE", update=update_tread_run
|
name="Tread Run", default=0.3, min=0.01, subtype="DISTANCE", update=update_tread_run
|
||||||
)
|
)
|
||||||
base_slab_depth: bpy.props.FloatProperty(name="Base Slab Depth", default=0.25, min=0, subtype="DISTANCE", update=update_stair)
|
base_slab_depth: bpy.props.FloatProperty(
|
||||||
top_slab_depth: bpy.props.FloatProperty(name="Top Slab Depth", default=0.25, min=0, subtype="DISTANCE", update=update_stair)
|
name="Base Slab Depth", default=0.25, min=0, subtype="DISTANCE", update=update_stair
|
||||||
|
)
|
||||||
|
top_slab_depth: bpy.props.FloatProperty(
|
||||||
|
name="Top Slab Depth", default=0.25, min=0, subtype="DISTANCE", update=update_stair
|
||||||
|
)
|
||||||
has_top_nib: bpy.props.BoolProperty(name="Has Top Nib", default=True, update=update_stair)
|
has_top_nib: bpy.props.BoolProperty(name="Has Top Nib", default=True, update=update_stair)
|
||||||
stair_type: bpy.props.EnumProperty(
|
stair_type: bpy.props.EnumProperty(
|
||||||
name="Stair Type",
|
name="Stair Type",
|
||||||
@@ -515,7 +522,12 @@ class BIMStairProperties(PropertyGroup):
|
|||||||
update=validate_nosing_value,
|
update=validate_nosing_value,
|
||||||
)
|
)
|
||||||
nosing_depth: bpy.props.FloatProperty(
|
nosing_depth: bpy.props.FloatProperty(
|
||||||
name="Nosing Depth", description="Depth of the tread's nosing", min=0, default=0, unit="LENGTH", update=update_stair
|
name="Nosing Depth",
|
||||||
|
description="Depth of the tread's nosing",
|
||||||
|
min=0,
|
||||||
|
default=0,
|
||||||
|
unit="LENGTH",
|
||||||
|
update=update_stair,
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -1087,7 +1099,7 @@ class BIMWindowProperties(PropertyGroup):
|
|||||||
value: New value (clamped to min 0.0)
|
value: New value (clamped to min 0.0)
|
||||||
"""
|
"""
|
||||||
current = getattr(self, attr_name)
|
current = getattr(self, attr_name)
|
||||||
new_value = tuple(current[:panel_index]) + (max(0.0, value),) + tuple(current[panel_index + 1:])
|
new_value = tuple(current[:panel_index]) + (max(0.0, value),) + tuple(current[panel_index + 1 :])
|
||||||
setattr(self, attr_name, new_value)
|
setattr(self, attr_name, new_value)
|
||||||
|
|
||||||
|
|
||||||
@@ -1401,7 +1413,10 @@ class BIMRailingProperties(PropertyGroup):
|
|||||||
is_editing_path: bpy.props.BoolProperty(default=False)
|
is_editing_path: bpy.props.BoolProperty(default=False)
|
||||||
|
|
||||||
railing_type: bpy.props.EnumProperty(
|
railing_type: bpy.props.EnumProperty(
|
||||||
name="Railing Type", items=[(i, i, "") for i in get_args(RailingType)], default="FRAMELESS_PANEL", update=update_railing
|
name="Railing Type",
|
||||||
|
items=[(i, i, "") for i in get_args(RailingType)],
|
||||||
|
default="FRAMELESS_PANEL",
|
||||||
|
update=update_railing,
|
||||||
)
|
)
|
||||||
height: bpy.props.FloatProperty(name="Height", default=1.0, subtype="DISTANCE", update=update_railing)
|
height: bpy.props.FloatProperty(name="Height", default=1.0, subtype="DISTANCE", update=update_railing)
|
||||||
thickness: bpy.props.FloatProperty(name="Thickness", default=0.050, subtype="DISTANCE", update=update_railing)
|
thickness: bpy.props.FloatProperty(name="Thickness", default=0.050, subtype="DISTANCE", update=update_railing)
|
||||||
@@ -1423,7 +1438,9 @@ class BIMRailingProperties(PropertyGroup):
|
|||||||
subtype="DISTANCE",
|
subtype="DISTANCE",
|
||||||
update=update_railing,
|
update=update_railing,
|
||||||
)
|
)
|
||||||
railing_diameter: bpy.props.FloatProperty(name="Railing Diameter", default=0.050, subtype="DISTANCE", update=update_railing)
|
railing_diameter: bpy.props.FloatProperty(
|
||||||
|
name="Railing Diameter", default=0.050, subtype="DISTANCE", update=update_railing
|
||||||
|
)
|
||||||
clear_width: bpy.props.FloatProperty(
|
clear_width: bpy.props.FloatProperty(
|
||||||
name="Clear Width",
|
name="Clear Width",
|
||||||
default=0.040,
|
default=0.040,
|
||||||
@@ -1529,10 +1546,17 @@ class BIMRoofProperties(PropertyGroup):
|
|||||||
name="Roof Type", items=[(i, i, "") for i in get_args(RoofType)], default="HIP/GABLE ROOF", update=update_roof
|
name="Roof Type", items=[(i, i, "") for i in get_args(RoofType)], default="HIP/GABLE ROOF", update=update_roof
|
||||||
)
|
)
|
||||||
generation_method: bpy.props.EnumProperty(
|
generation_method: bpy.props.EnumProperty(
|
||||||
name="Roof Generation Method", items=[(i, i, "") for i in get_args(RoofGenerationMethod)], default="ANGLE", update=update_roof
|
name="Roof Generation Method",
|
||||||
|
items=[(i, i, "") for i in get_args(RoofGenerationMethod)],
|
||||||
|
default="ANGLE",
|
||||||
|
update=update_roof,
|
||||||
)
|
)
|
||||||
height: bpy.props.FloatProperty(
|
height: bpy.props.FloatProperty(
|
||||||
name="Height", default=1.0, description="Maximum height of the roof to be generated.", subtype="DISTANCE", update=update_roof
|
name="Height",
|
||||||
|
default=1.0,
|
||||||
|
description="Maximum height of the roof to be generated.",
|
||||||
|
subtype="DISTANCE",
|
||||||
|
update=update_roof,
|
||||||
)
|
)
|
||||||
angle: bpy.props.FloatProperty(
|
angle: bpy.props.FloatProperty(
|
||||||
name="Slope Angle",
|
name="Slope Angle",
|
||||||
|
|||||||
@@ -488,11 +488,16 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
matrix_position=lambda p: V_(0, -_G.GIZMO_OFFSET, -_G.GIZMO_OFFSET),
|
matrix_position=lambda p: V_(0, -_G.GIZMO_OFFSET, -_G.GIZMO_OFFSET),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="height", axis=(0, 0, 1), min_value=0.01, text_alignment="start",
|
attr_name="height",
|
||||||
|
axis=(0, 0, 1),
|
||||||
|
min_value=0.01,
|
||||||
|
text_alignment="start",
|
||||||
matrix_position=lambda p: V_(p.get_total_run() + _G.GIZMO_OFFSET, -_G.GIZMO_OFFSET, 0),
|
matrix_position=lambda p: V_(p.get_total_run() + _G.GIZMO_OFFSET, -_G.GIZMO_OFFSET, 0),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="width", axis=(0, 1, 0), min_value=0.01,
|
attr_name="width",
|
||||||
|
axis=(0, 1, 0),
|
||||||
|
min_value=0.01,
|
||||||
matrix_position=lambda p: V_(_G.GIZMO_OFFSET, 0, -_G.GIZMO_OFFSET),
|
matrix_position=lambda p: V_(_G.GIZMO_OFFSET, 0, -_G.GIZMO_OFFSET),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
@@ -503,7 +508,7 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
0 if p.custom_tread_lock else p.custom_first_last_tread_run[0],
|
0 if p.custom_tread_lock else p.custom_first_last_tread_run[0],
|
||||||
0,
|
0,
|
||||||
p.get_riser_height() if p.custom_tread_lock else p.get_riser_height() * 2
|
p.get_riser_height() if p.custom_tread_lock else p.get_riser_height() * 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
@@ -524,12 +529,11 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
visibility_condition=lambda p: p.has_custom_treads(),
|
visibility_condition=lambda p: p.has_custom_treads(),
|
||||||
compute_value=_tread_run_accessors[1][0],
|
compute_value=_tread_run_accessors[1][0],
|
||||||
apply_value=_tread_run_accessors[1][1],
|
apply_value=_tread_run_accessors[1][1],
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(p.get_total_run() - p.custom_first_last_tread_run[1], 0, p.height),
|
||||||
p.get_total_run() - p.custom_first_last_tread_run[1], 0, p.height
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="nosing_length", axis=(-1, 0, 0),
|
attr_name="nosing_length",
|
||||||
|
axis=(-1, 0, 0),
|
||||||
matrix_position=lambda p: V_(0, p.width / 2, p.get_riser_height()),
|
matrix_position=lambda p: V_(0, p.width / 2, p.get_riser_height()),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
@@ -578,12 +582,16 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
def setup_element_specific_gizmos(self, context: bpy.types.Context) -> None:
|
def setup_element_specific_gizmos(self, context: bpy.types.Context) -> None:
|
||||||
"""Create stair-specific icon gizmos (lock, plus, minus)."""
|
"""Create stair-specific icon gizmos (lock, plus, minus)."""
|
||||||
self.lock_gizmo = self.create_icon_gizmo(
|
self.lock_gizmo = self.create_icon_gizmo(
|
||||||
"VIEW3D_GT_lock", self.COLOR_BLUE, "bim.toggle_stair_property",
|
"VIEW3D_GT_lock",
|
||||||
|
self.COLOR_BLUE,
|
||||||
|
"bim.toggle_stair_property",
|
||||||
prop_path="BIMStairProperties.total_length_lock",
|
prop_path="BIMStairProperties.total_length_lock",
|
||||||
property_name="total_length_lock",
|
property_name="total_length_lock",
|
||||||
)
|
)
|
||||||
self.tread_lock_gizmo = self.create_icon_gizmo(
|
self.tread_lock_gizmo = self.create_icon_gizmo(
|
||||||
"VIEW3D_GT_lock", (1.0, 1.0, 1.0), "bim.toggle_stair_property",
|
"VIEW3D_GT_lock",
|
||||||
|
(1.0, 1.0, 1.0),
|
||||||
|
"bim.toggle_stair_property",
|
||||||
prop_path="BIMStairProperties.custom_tread_lock",
|
prop_path="BIMStairProperties.custom_tread_lock",
|
||||||
property_name="custom_tread_lock",
|
property_name="custom_tread_lock",
|
||||||
)
|
)
|
||||||
@@ -594,9 +602,7 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
"VIEW3D_GT_minus", self.COLOR_RED, "bim.adjust_stair_treads", increment=-1
|
"VIEW3D_GT_minus", self.COLOR_RED, "bim.adjust_stair_treads", increment=-1
|
||||||
)
|
)
|
||||||
|
|
||||||
def _refresh_element_specific(
|
def _refresh_element_specific(self, context: bpy.types.Context, mw: Matrix, props: "BIMStairProperties") -> None:
|
||||||
self, context: bpy.types.Context, mw: Matrix, props: "BIMStairProperties"
|
|
||||||
) -> None:
|
|
||||||
"""Update stair-specific lock and tread count gizmos."""
|
"""Update stair-specific lock and tread count gizmos."""
|
||||||
billboard_rot = gizmo.get_billboard_rotation(context)
|
billboard_rot = gizmo.get_billboard_rotation(context)
|
||||||
self.update_lock_gizmo(mw, props, billboard_rot)
|
self.update_lock_gizmo(mw, props, billboard_rot)
|
||||||
@@ -637,7 +643,9 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
self.minus_gizmo, props.is_editing and props.number_of_treads > 1, gizmo_prefs.minus
|
self.minus_gizmo, props.is_editing and props.number_of_treads > 1, gizmo_prefs.minus
|
||||||
)
|
)
|
||||||
|
|
||||||
def _update_dimension_gizmo_positions(self, context: bpy.types.Context, mw: Matrix, props: "BIMStairProperties") -> None:
|
def _update_dimension_gizmo_positions(
|
||||||
|
self, context: bpy.types.Context, mw: Matrix, props: "BIMStairProperties"
|
||||||
|
) -> None:
|
||||||
"""Update dimension gizmo positions based on camera view direction."""
|
"""Update dimension gizmo positions based on camera view direction."""
|
||||||
viewing_from_negative_y, viewing_from_negative_x = self.get_local_view_direction(context, mw)
|
viewing_from_negative_y, viewing_from_negative_x = self.get_local_view_direction(context, mw)
|
||||||
billboard_rot = gizmo.get_billboard_rotation(context)
|
billboard_rot = gizmo.get_billboard_rotation(context)
|
||||||
@@ -651,7 +659,12 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
self._update_editing_icon_positions(mw, props, viewing_from_negative_y, billboard_rot)
|
self._update_editing_icon_positions(mw, props, viewing_from_negative_y, billboard_rot)
|
||||||
|
|
||||||
def _update_overall_dimension_gizmos(
|
def _update_overall_dimension_gizmos(
|
||||||
self, mw: Matrix, props: "BIMStairProperties", viewing_from_negative_y: bool, viewing_from_negative_x: bool, total_run: float
|
self,
|
||||||
|
mw: Matrix,
|
||||||
|
props: "BIMStairProperties",
|
||||||
|
viewing_from_negative_y: bool,
|
||||||
|
viewing_from_negative_x: bool,
|
||||||
|
total_run: float,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update overall dimension gizmos (total_length, width, height)."""
|
"""Update overall dimension gizmos (total_length, width, height)."""
|
||||||
y_pos_offset = self.get_y_position_for_view(props, viewing_from_negative_y, use_offset=True)
|
y_pos_offset = self.get_y_position_for_view(props, viewing_from_negative_y, use_offset=True)
|
||||||
@@ -662,7 +675,12 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
self.set_dimension_gizmo_position("height", mw, V_(total_run + self.GIZMO_OFFSET, y_pos_offset, 0), (0, 0, 1))
|
self.set_dimension_gizmo_position("height", mw, V_(total_run + self.GIZMO_OFFSET, y_pos_offset, 0), (0, 0, 1))
|
||||||
|
|
||||||
def _update_tread_dimension_gizmos(
|
def _update_tread_dimension_gizmos(
|
||||||
self, mw: Matrix, props: "BIMStairProperties", viewing_from_negative_y: bool, total_run: float, riser_height: float
|
self,
|
||||||
|
mw: Matrix,
|
||||||
|
props: "BIMStairProperties",
|
||||||
|
viewing_from_negative_y: bool,
|
||||||
|
total_run: float,
|
||||||
|
riser_height: float,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update tread-related dimension gizmos (tread_run, custom first/last tread)."""
|
"""Update tread-related dimension gizmos (tread_run, custom first/last tread)."""
|
||||||
y_pos = self.get_y_position_for_view(props, viewing_from_negative_y, use_offset=False)
|
y_pos = self.get_y_position_for_view(props, viewing_from_negative_y, use_offset=False)
|
||||||
@@ -689,18 +707,33 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
self.set_dimension_gizmo_position("nosing_length", mw, V_(0, props.width / 2, riser_height), (-1, 0, 0))
|
self.set_dimension_gizmo_position("nosing_length", mw, V_(0, props.width / 2, riser_height), (-1, 0, 0))
|
||||||
self.set_dimension_gizmo_position("tread_depth", mw, V_(0, y_pos, riser_height), (0, 0, -1))
|
self.set_dimension_gizmo_position("tread_depth", mw, V_(0, y_pos, riser_height), (0, 0, -1))
|
||||||
self.set_dimension_gizmo_position("riser_height", mw, V_(props.tread_run, y_pos, 0), (0, 0, 1))
|
self.set_dimension_gizmo_position("riser_height", mw, V_(props.tread_run, y_pos, 0), (0, 0, 1))
|
||||||
self.set_dimension_gizmo_position("nosing_depth", mw, V_(-props.nosing_length, props.width / 2, riser_height), (0, 0, -1))
|
self.set_dimension_gizmo_position(
|
||||||
|
"nosing_depth", mw, V_(-props.nosing_length, props.width / 2, riser_height), (0, 0, -1)
|
||||||
|
)
|
||||||
|
|
||||||
def _update_lock_gizmo_position(
|
def _update_lock_gizmo_position(
|
||||||
self, mw: Matrix, props: "BIMStairProperties", viewing_from_negative_y: bool, billboard_rot: Matrix, total_run: float
|
self,
|
||||||
|
mw: Matrix,
|
||||||
|
props: "BIMStairProperties",
|
||||||
|
viewing_from_negative_y: bool,
|
||||||
|
billboard_rot: Matrix,
|
||||||
|
total_run: float,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update lock gizmo position based on Y view direction."""
|
"""Update lock gizmo position based on Y view direction."""
|
||||||
y_pos = self.get_y_position_for_view(props, viewing_from_negative_y, use_offset=True)
|
y_pos = self.get_y_position_for_view(props, viewing_from_negative_y, use_offset=True)
|
||||||
self.set_icon_gizmo_position(
|
self.set_icon_gizmo_position(
|
||||||
"lock_gizmo", mw, total_run + self.ICON_Z_OFFSET, y_pos, -self.GIZMO_OFFSET, billboard_rot, scale=self.EDITING_ICON_SCALE
|
"lock_gizmo",
|
||||||
|
mw,
|
||||||
|
total_run + self.ICON_Z_OFFSET,
|
||||||
|
y_pos,
|
||||||
|
-self.GIZMO_OFFSET,
|
||||||
|
billboard_rot,
|
||||||
|
scale=self.EDITING_ICON_SCALE,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _update_editing_icon_positions(self, mw: Matrix, props: "BIMStairProperties", viewing_from_negative_y: bool, billboard_rot: Matrix) -> None:
|
def _update_editing_icon_positions(
|
||||||
|
self, mw: Matrix, props: "BIMStairProperties", viewing_from_negative_y: bool, billboard_rot: Matrix
|
||||||
|
) -> None:
|
||||||
"""Update editing icon positions, flipping Y based on viewing angle."""
|
"""Update editing icon positions, flipping Y based on viewing angle."""
|
||||||
if not props.is_editing:
|
if not props.is_editing:
|
||||||
return
|
return
|
||||||
@@ -710,10 +743,17 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
|
|
||||||
self.set_icon_gizmo_position("validate_gizmo", mw, 0, y_pos, icon_z, billboard_rot)
|
self.set_icon_gizmo_position("validate_gizmo", mw, 0, y_pos, icon_z, billboard_rot)
|
||||||
self.set_icon_gizmo_position("cancel_gizmo", mw, self.ICON_CANCEL_X, y_pos, icon_z, billboard_rot)
|
self.set_icon_gizmo_position("cancel_gizmo", mw, self.ICON_CANCEL_X, y_pos, icon_z, billboard_rot)
|
||||||
self.set_icon_gizmo_position("cycle_gizmo", mw, self.ICON_CYCLE_X, y_pos, icon_z, billboard_rot, scale=self.ICON_CYCLE_SCALE)
|
|
||||||
self.set_icon_gizmo_position(
|
self.set_icon_gizmo_position(
|
||||||
"tread_lock_gizmo", mw, self.ICON_TREAD_LOCK_X, y_pos,
|
"cycle_gizmo", mw, self.ICON_CYCLE_X, y_pos, icon_z, billboard_rot, scale=self.ICON_CYCLE_SCALE
|
||||||
icon_z - self.EDITING_ICON_SCALE / 2, billboard_rot, scale=self.EDITING_ICON_SCALE
|
)
|
||||||
|
self.set_icon_gizmo_position(
|
||||||
|
"tread_lock_gizmo",
|
||||||
|
mw,
|
||||||
|
self.ICON_TREAD_LOCK_X,
|
||||||
|
y_pos,
|
||||||
|
icon_z - self.EDITING_ICON_SCALE / 2,
|
||||||
|
billboard_rot,
|
||||||
|
scale=self.EDITING_ICON_SCALE,
|
||||||
)
|
)
|
||||||
self.set_icon_gizmo_position(
|
self.set_icon_gizmo_position(
|
||||||
"plus_gizmo", mw, self.ICON_PLUS_X, y_pos, icon_z, billboard_rot, scale=self.ICON_PLUS_MINUS_SCALE
|
"plus_gizmo", mw, self.ICON_PLUS_X, y_pos, icon_z, billboard_rot, scale=self.ICON_PLUS_MINUS_SCALE
|
||||||
|
|||||||
@@ -605,9 +605,10 @@ class CycleWindowType(bpy.types.Operator, tool.Ifc.Operator, gizmo.CycleTypeMixi
|
|||||||
|
|
||||||
|
|
||||||
# Frame accessor factory - creates callbacks that delegate to BIMWindowProperties methods
|
# Frame accessor factory - creates callbacks that delegate to BIMWindowProperties methods
|
||||||
def _make_frame_accessors(
|
def _make_frame_accessors(attr_name: str, panel_index: int) -> tuple[
|
||||||
attr_name: str, panel_index: int
|
"collections.abc.Callable[[BIMWindowProperties], float]",
|
||||||
) -> tuple["collections.abc.Callable[[BIMWindowProperties], float]", "collections.abc.Callable[[BIMWindowProperties, float], None]"]:
|
"collections.abc.Callable[[BIMWindowProperties, float], None]",
|
||||||
|
]:
|
||||||
"""Create compute/apply callbacks for frame properties at a specific panel index.
|
"""Create compute/apply callbacks for frame properties at a specific panel index.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -624,9 +625,7 @@ def _make_frame_accessors(
|
|||||||
|
|
||||||
|
|
||||||
_frame_accessors = {
|
_frame_accessors = {
|
||||||
(attr, idx): _make_frame_accessors(attr, idx)
|
(attr, idx): _make_frame_accessors(attr, idx) for attr in ("frame_depth", "frame_thickness") for idx in range(3)
|
||||||
for attr in ("frame_depth", "frame_thickness")
|
|
||||||
for idx in range(3)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -645,112 +644,137 @@ class GizmoWindowEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
# matrix_position lambdas replace the get_dimension_matrix_* methods
|
# matrix_position lambdas replace the get_dimension_matrix_* methods
|
||||||
dimension_gizmo_props = [
|
dimension_gizmo_props = [
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="overall_width", axis=(1, 0, 0), min_value=0.01, text_offset_sign=-1,
|
attr_name="overall_width",
|
||||||
|
axis=(1, 0, 0),
|
||||||
|
min_value=0.01,
|
||||||
|
text_offset_sign=-1,
|
||||||
matrix_position=lambda p: V_(0, p.lining_offset - _G.GIZMO_OFFSET, -_G.GIZMO_OFFSET),
|
matrix_position=lambda p: V_(0, p.lining_offset - _G.GIZMO_OFFSET, -_G.GIZMO_OFFSET),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="overall_height", axis=(0, 0, 1), min_value=0.01, text_alignment="start",
|
attr_name="overall_height",
|
||||||
|
axis=(0, 0, 1),
|
||||||
|
min_value=0.01,
|
||||||
|
text_alignment="start",
|
||||||
matrix_position=lambda p: V_(p.overall_width + _G.GIZMO_OFFSET, p.lining_offset - _G.GIZMO_OFFSET, 0),
|
matrix_position=lambda p: V_(p.overall_width + _G.GIZMO_OFFSET, p.lining_offset - _G.GIZMO_OFFSET, 0),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_depth", axis=(0, 1, 0),
|
attr_name="lining_depth",
|
||||||
|
axis=(0, 1, 0),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, p.overall_height),
|
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, p.overall_height),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_thickness", axis=(1, 0, 0),
|
attr_name="lining_thickness",
|
||||||
|
axis=(1, 0, 0),
|
||||||
matrix_position=lambda p: V_(0, p.lining_depth / 2 + p.lining_offset, p.overall_height / 2),
|
matrix_position=lambda p: V_(0, p.lining_depth / 2 + p.lining_offset, p.overall_height / 2),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_to_panel_offset_x", axis=(1, 0, 0),
|
attr_name="lining_to_panel_offset_x",
|
||||||
|
axis=(1, 0, 0),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
0,
|
0,
|
||||||
p.get_lining_to_panel_offset_y_full() + p.frame_depth[0] + p.lining_offset,
|
p.get_lining_to_panel_offset_y_full() + p.frame_depth[0] + p.lining_offset,
|
||||||
p.lining_to_panel_offset_x
|
p.lining_to_panel_offset_x,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="lining_to_panel_offset_y", axis=(0, 1, 0), min_value=-10.0,
|
attr_name="lining_to_panel_offset_y",
|
||||||
|
axis=(0, 1, 0),
|
||||||
|
min_value=-10.0,
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.overall_width - p.lining_to_panel_offset_x,
|
p.overall_width - p.lining_to_panel_offset_x,
|
||||||
p.lining_depth + p.lining_offset,
|
p.lining_depth + p.lining_offset,
|
||||||
p.lining_to_panel_offset_x
|
p.lining_to_panel_offset_x,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="frame_depth", axis=(0, -1, 0),
|
attr_name="frame_depth",
|
||||||
|
axis=(0, -1, 0),
|
||||||
compute_value=_frame_accessors[("frame_depth", 0)][0],
|
compute_value=_frame_accessors[("frame_depth", 0)][0],
|
||||||
apply_value=_frame_accessors[("frame_depth", 0)][1],
|
apply_value=_frame_accessors[("frame_depth", 0)][1],
|
||||||
matrix_position=lambda p: p.get_frame_position(0, is_depth=True),
|
matrix_position=lambda p: p.get_frame_position(0, is_depth=True),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="frame_thickness", axis=(1, 0, 0),
|
attr_name="frame_thickness",
|
||||||
|
axis=(1, 0, 0),
|
||||||
compute_value=_frame_accessors[("frame_thickness", 0)][0],
|
compute_value=_frame_accessors[("frame_thickness", 0)][0],
|
||||||
apply_value=_frame_accessors[("frame_thickness", 0)][1],
|
apply_value=_frame_accessors[("frame_thickness", 0)][1],
|
||||||
matrix_position=lambda p: p.get_frame_position(0, is_depth=False),
|
matrix_position=lambda p: p.get_frame_position(0, is_depth=False),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="second_frame_depth", axis=(0, -1, 0),
|
attr_name="second_frame_depth",
|
||||||
|
axis=(0, -1, 0),
|
||||||
compute_value=_frame_accessors[("frame_depth", 1)][0],
|
compute_value=_frame_accessors[("frame_depth", 1)][0],
|
||||||
apply_value=_frame_accessors[("frame_depth", 1)][1],
|
apply_value=_frame_accessors[("frame_depth", 1)][1],
|
||||||
visibility_condition=lambda p: p.has_second_panel(),
|
visibility_condition=lambda p: p.has_second_panel(),
|
||||||
matrix_position=lambda p: p.get_frame_position(1, is_depth=True),
|
matrix_position=lambda p: p.get_frame_position(1, is_depth=True),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="second_frame_thickness", axis=(1, 0, 0),
|
attr_name="second_frame_thickness",
|
||||||
|
axis=(1, 0, 0),
|
||||||
compute_value=_frame_accessors[("frame_thickness", 1)][0],
|
compute_value=_frame_accessors[("frame_thickness", 1)][0],
|
||||||
apply_value=_frame_accessors[("frame_thickness", 1)][1],
|
apply_value=_frame_accessors[("frame_thickness", 1)][1],
|
||||||
visibility_condition=lambda p: p.has_second_panel(),
|
visibility_condition=lambda p: p.has_second_panel(),
|
||||||
matrix_position=lambda p: p.get_frame_position(1, is_depth=False),
|
matrix_position=lambda p: p.get_frame_position(1, is_depth=False),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="third_frame_depth", axis=(0, -1, 0),
|
attr_name="third_frame_depth",
|
||||||
|
axis=(0, -1, 0),
|
||||||
compute_value=_frame_accessors[("frame_depth", 2)][0],
|
compute_value=_frame_accessors[("frame_depth", 2)][0],
|
||||||
apply_value=_frame_accessors[("frame_depth", 2)][1],
|
apply_value=_frame_accessors[("frame_depth", 2)][1],
|
||||||
visibility_condition=lambda p: p.has_third_panel(),
|
visibility_condition=lambda p: p.has_third_panel(),
|
||||||
matrix_position=lambda p: p.get_frame_position(2, is_depth=True),
|
matrix_position=lambda p: p.get_frame_position(2, is_depth=True),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="third_frame_thickness", axis=(1, 0, 0),
|
attr_name="third_frame_thickness",
|
||||||
|
axis=(1, 0, 0),
|
||||||
compute_value=_frame_accessors[("frame_thickness", 2)][0],
|
compute_value=_frame_accessors[("frame_thickness", 2)][0],
|
||||||
apply_value=_frame_accessors[("frame_thickness", 2)][1],
|
apply_value=_frame_accessors[("frame_thickness", 2)][1],
|
||||||
visibility_condition=lambda p: p.has_third_panel(),
|
visibility_condition=lambda p: p.has_third_panel(),
|
||||||
matrix_position=lambda p: p.get_frame_position(2, is_depth=False),
|
matrix_position=lambda p: p.get_frame_position(2, is_depth=False),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="mullion_thickness", axis=(1, 0, 0), delta_scale=2.0,
|
attr_name="mullion_thickness",
|
||||||
|
axis=(1, 0, 0),
|
||||||
|
delta_scale=2.0,
|
||||||
visibility_condition=lambda p: p.has_mullion(),
|
visibility_condition=lambda p: p.has_mullion(),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.first_mullion_offset - p.mullion_thickness / 2,
|
p.first_mullion_offset - p.mullion_thickness / 2,
|
||||||
p.lining_offset,
|
p.lining_offset,
|
||||||
p.overall_height / 2 + 3 * _G.GIZMO_STACK_OFFSET
|
p.overall_height / 2 + 3 * _G.GIZMO_STACK_OFFSET,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="first_mullion_offset", axis=(1, 0, 0),
|
attr_name="first_mullion_offset",
|
||||||
|
axis=(1, 0, 0),
|
||||||
visibility_condition=lambda p: p.has_mullion(),
|
visibility_condition=lambda p: p.has_mullion(),
|
||||||
matrix_position=lambda p: V_(0, p.lining_offset, p.overall_height / 2 + _G.GIZMO_STACK_OFFSET),
|
matrix_position=lambda p: V_(0, p.lining_offset, p.overall_height / 2 + _G.GIZMO_STACK_OFFSET),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="second_mullion_offset", axis=(1, 0, 0),
|
attr_name="second_mullion_offset",
|
||||||
|
axis=(1, 0, 0),
|
||||||
visibility_condition=lambda p: p.has_second_mullion(),
|
visibility_condition=lambda p: p.has_second_mullion(),
|
||||||
matrix_position=lambda p: V_(0, p.lining_offset, p.overall_height / 2 + 2 * _G.GIZMO_STACK_OFFSET),
|
matrix_position=lambda p: V_(0, p.lining_offset, p.overall_height / 2 + 2 * _G.GIZMO_STACK_OFFSET),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="transom_thickness", axis=(0, 0, 1), delta_scale=2.0,
|
attr_name="transom_thickness",
|
||||||
|
axis=(0, 0, 1),
|
||||||
|
delta_scale=2.0,
|
||||||
visibility_condition=lambda p: p.has_transom(),
|
visibility_condition=lambda p: p.has_transom(),
|
||||||
matrix_position=lambda p: V_(
|
matrix_position=lambda p: V_(
|
||||||
p.overall_width / 2 + 2 * _G.GIZMO_STACK_OFFSET,
|
p.overall_width / 2 + 2 * _G.GIZMO_STACK_OFFSET,
|
||||||
p.lining_offset,
|
p.lining_offset,
|
||||||
p.first_transom_offset - p.transom_thickness / 2
|
p.first_transom_offset - p.transom_thickness / 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="first_transom_offset", axis=(0, 0, 1),
|
attr_name="first_transom_offset",
|
||||||
|
axis=(0, 0, 1),
|
||||||
visibility_condition=lambda p: p.has_transom(),
|
visibility_condition=lambda p: p.has_transom(),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, 0),
|
matrix_position=lambda p: V_(p.overall_width / 2, p.lining_offset, 0),
|
||||||
),
|
),
|
||||||
DimensionGizmoConfig(
|
DimensionGizmoConfig(
|
||||||
attr_name="second_transom_offset", axis=(0, 0, 1),
|
attr_name="second_transom_offset",
|
||||||
|
axis=(0, 0, 1),
|
||||||
visibility_condition=lambda p: p.has_second_transom(),
|
visibility_condition=lambda p: p.has_second_transom(),
|
||||||
matrix_position=lambda p: V_(p.overall_width / 2 + _G.GIZMO_STACK_OFFSET, p.lining_offset, 0),
|
matrix_position=lambda p: V_(p.overall_width / 2 + _G.GIZMO_STACK_OFFSET, p.lining_offset, 0),
|
||||||
),
|
),
|
||||||
@@ -772,17 +796,16 @@ class GizmoWindowEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
depending on lining_offset (which can be negative).
|
depending on lining_offset (which can be negative).
|
||||||
"""
|
"""
|
||||||
furthest_positive_y = (
|
furthest_positive_y = (
|
||||||
max(0, props.lining_offset)
|
max(0, props.lining_offset) + props.lining_depth + props.lining_to_panel_offset_y + 2 * self.GIZMO_OFFSET
|
||||||
+ props.lining_depth
|
|
||||||
+ props.lining_to_panel_offset_y
|
|
||||||
+ 2 * self.GIZMO_OFFSET
|
|
||||||
)
|
)
|
||||||
furthest_negative_y = abs(min(0, props.lining_offset)) + 2 * self.GIZMO_OFFSET
|
furthest_negative_y = abs(min(0, props.lining_offset)) + 2 * self.GIZMO_OFFSET
|
||||||
return (furthest_positive_y, furthest_negative_y)
|
return (furthest_positive_y, furthest_negative_y)
|
||||||
|
|
||||||
# Window uses base class setup() and refresh() - no element-specific gizmos needed
|
# Window uses base class setup() and refresh() - no element-specific gizmos needed
|
||||||
|
|
||||||
def _update_dimension_gizmo_positions(self, context: bpy.types.Context, mw: Matrix, props: "BIMWindowProperties") -> None:
|
def _update_dimension_gizmo_positions(
|
||||||
|
self, context: bpy.types.Context, mw: Matrix, props: "BIMWindowProperties"
|
||||||
|
) -> None:
|
||||||
"""Update dimension gizmo positions based on camera view direction."""
|
"""Update dimension gizmo positions based on camera view direction."""
|
||||||
# Window uses base implementation with default casing_offset=0
|
# Window uses base implementation with default casing_offset=0
|
||||||
self._update_view_dependent_dimensions(context, mw, props)
|
self._update_view_dependent_dimensions(context, mw, props)
|
||||||
|
|||||||
@@ -673,6 +673,3 @@ class BIM_PT_purge(Panel):
|
|||||||
row.prop(ifc_parameter, "name", text="")
|
row.prop(ifc_parameter, "name", text="")
|
||||||
row.prop(ifc_parameter, "value", text="")
|
row.prop(ifc_parameter, "value", text="")
|
||||||
row.operator("bim.update_parametric_representation", icon="FILE_REFRESH", text="").index = index
|
row.operator("bim.update_parametric_representation", icon="FILE_REFRESH", text="").index = index
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -409,6 +409,10 @@ class DuplicateType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
self.layout.prop(self, "name")
|
self.layout.prop(self, "name")
|
||||||
self.layout.prop(self, "description")
|
self.layout.prop(self, "description")
|
||||||
selected_objects = tool.Blender.get_selected_objects()
|
selected_objects = tool.Blender.get_selected_objects()
|
||||||
ifc_objects = [obj for obj in selected_objects if tool.Ifc.get_entity(obj) and tool.Ifc.get_entity(obj).is_a("IfcObject")]
|
ifc_objects = [
|
||||||
|
obj for obj in selected_objects if tool.Ifc.get_entity(obj) and tool.Ifc.get_entity(obj).is_a("IfcObject")
|
||||||
|
]
|
||||||
if ifc_objects:
|
if ifc_objects:
|
||||||
self.layout.prop(self, "assign_selected_objects", text=f"Assign {len(ifc_objects)} Selected Object(s) to New Type")
|
self.layout.prop(
|
||||||
|
self, "assign_selected_objects", text=f"Assign {len(ifc_objects)} Selected Object(s) to New Type"
|
||||||
|
)
|
||||||
|
|||||||
@@ -1907,9 +1907,20 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
# ADD THIS AT THE END - Store initial vertex order for annotations
|
# ADD THIS AT THE END - Store initial vertex order for annotations
|
||||||
if rep_obj and (element := tool.Ifc.get_entity(rep_obj)):
|
if rep_obj and (element := tool.Ifc.get_entity(rep_obj)):
|
||||||
if element.is_a("IfcAnnotation") and element.ObjectType in {
|
if element.is_a("IfcAnnotation") and element.ObjectType in {
|
||||||
"TEXT_LEADER", "DIMENSION", "RADIUS", "DIAMETER", "ANGLE",
|
"TEXT_LEADER",
|
||||||
"FALL", "SLOPE_ANGLE", "SLOPE_FRACTION", "SLOPE_PERCENT",
|
"DIMENSION",
|
||||||
"STAIR_ARROW", "PLAN_LEVEL", "SECTION_LEVEL", "SECTION", "ELEVATION"
|
"RADIUS",
|
||||||
|
"DIAMETER",
|
||||||
|
"ANGLE",
|
||||||
|
"FALL",
|
||||||
|
"SLOPE_ANGLE",
|
||||||
|
"SLOPE_FRACTION",
|
||||||
|
"SLOPE_PERCENT",
|
||||||
|
"STAIR_ARROW",
|
||||||
|
"PLAN_LEVEL",
|
||||||
|
"SECTION_LEVEL",
|
||||||
|
"SECTION",
|
||||||
|
"ELEVATION",
|
||||||
}:
|
}:
|
||||||
# Store the initial first vertex position
|
# Store the initial first vertex position
|
||||||
if isinstance(obj.data, bpy.types.Mesh) and obj.data.vertices:
|
if isinstance(obj.data, bpy.types.Mesh) and obj.data.vertices:
|
||||||
|
|||||||
Reference in New Issue
Block a user