mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Railing, Door Modifiers - project units props
Example - https://i.imgur.com/SJOQMMm.png
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
import bmesh
|
||||
from bmesh.types import BMVert, BMFace
|
||||
|
||||
@@ -27,8 +26,6 @@ from ifcopenshell.util.shape_builder import V
|
||||
import blenderbim
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.geometry as core
|
||||
from blenderbim.bim.helper import convert_property_group_from_si
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.model.window import create_bm_window, create_bm_box, update_simple_openings
|
||||
|
||||
from mathutils import Vector, Matrix
|
||||
@@ -44,32 +41,31 @@ def update_door_modifier_representation(context):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
ifc_file = tool.Ifc.get()
|
||||
sliding_door = "SLIDING" in props.door_type
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
|
||||
representation_data = {
|
||||
"operation_type": props.door_type,
|
||||
"overall_height": props.overall_height,
|
||||
"overall_width": props.overall_width,
|
||||
"overall_height": props.overall_height / si_conversion,
|
||||
"overall_width": props.overall_width / si_conversion,
|
||||
"lining_properties": {
|
||||
"LiningDepth": props.lining_depth,
|
||||
"LiningThickness": props.lining_thickness,
|
||||
"LiningOffset": props.lining_offset,
|
||||
"LiningToPanelOffsetX": props.lining_to_panel_offset_x,
|
||||
"LiningToPanelOffsetY": props.lining_to_panel_offset_y,
|
||||
"TransomThickness": props.transom_thickness,
|
||||
"TransomOffset": props.transom_offset,
|
||||
"transomThickness": props.transom_thickness,
|
||||
"TransomOffset": props.transom_offset,
|
||||
"CasingThickness": props.casing_thickness,
|
||||
"CasingDepth": props.casing_depth,
|
||||
"ThresholdThickness": props.threshold_thickness,
|
||||
"ThresholdDepth": props.threshold_depth,
|
||||
"ThresholdOffset": props.threshold_offset,
|
||||
"LiningDepth": props.lining_depth / si_conversion,
|
||||
"LiningThickness": props.lining_thickness / si_conversion,
|
||||
"LiningOffset": props.lining_offset / si_conversion,
|
||||
"LiningToPanelOffsetX": props.lining_to_panel_offset_x / si_conversion,
|
||||
"LiningToPanelOffsetY": props.lining_to_panel_offset_y / si_conversion,
|
||||
"TransomThickness": props.transom_thickness / si_conversion,
|
||||
"TransomOffset": props.transom_offset / si_conversion,
|
||||
"CasingThickness": props.casing_thickness / si_conversion,
|
||||
"CasingDepth": props.casing_depth / si_conversion,
|
||||
"ThresholdThickness": props.threshold_thickness / si_conversion,
|
||||
"ThresholdDepth": props.threshold_depth / si_conversion,
|
||||
"ThresholdOffset": props.threshold_offset / si_conversion,
|
||||
},
|
||||
"panel_properties": {
|
||||
"PanelDepth": props.panel_depth,
|
||||
"PanelDepth": props.panel_depth / si_conversion,
|
||||
"PanelWidth": props.panel_width_ratio,
|
||||
"FrameDepth": props.frame_depth,
|
||||
"FrameThickness": props.frame_thickness,
|
||||
"FrameDepth": props.frame_depth / si_conversion,
|
||||
"FrameThickness": props.frame_thickness / si_conversion,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -281,27 +277,26 @@ def create_bm_door_lining(bm, size: Vector, thickness: list, position: Vector =
|
||||
def update_door_modifier_bmesh(context):
|
||||
obj = context.object
|
||||
props = obj.BIMDoorProperties
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
|
||||
overall_width = props.overall_width * si_conversion
|
||||
overall_height = props.overall_height * si_conversion
|
||||
overall_width = props.overall_width
|
||||
overall_height = props.overall_height
|
||||
door_type = props.door_type
|
||||
double_swing_door = "DOUBLE_SWING" in door_type
|
||||
double_door = "DOUBLE_DOOR" in door_type
|
||||
sliding_door = "SLIDING" in door_type
|
||||
|
||||
# lining params
|
||||
lining_depth = props.lining_depth * si_conversion
|
||||
lining_thickness_default = props.lining_thickness * si_conversion
|
||||
lining_offset = props.lining_offset * si_conversion
|
||||
lining_depth = props.lining_depth
|
||||
lining_thickness_default = props.lining_thickness
|
||||
lining_offset = props.lining_offset
|
||||
lining_to_panel_offset_x = (
|
||||
props.lining_to_panel_offset_x * si_conversion if not sliding_door else lining_thickness_default
|
||||
props.lining_to_panel_offset_x if not sliding_door else lining_thickness_default
|
||||
)
|
||||
panel_depth = props.panel_depth * si_conversion
|
||||
lining_to_panel_offset_y = props.lining_to_panel_offset_y * si_conversion if not sliding_door else -panel_depth
|
||||
panel_depth = props.panel_depth
|
||||
lining_to_panel_offset_y = props.lining_to_panel_offset_y if not sliding_door else -panel_depth
|
||||
|
||||
transom_thickness = props.transom_thickness * si_conversion / 2
|
||||
transfom_offset = props.transom_offset * si_conversion
|
||||
transom_thickness = props.transom_thickness / 2
|
||||
transfom_offset = props.transom_offset
|
||||
if transom_thickness == 0:
|
||||
transfom_offset = 0
|
||||
window_lining_height = overall_height - transfom_offset - transom_thickness
|
||||
@@ -316,24 +311,24 @@ def update_door_modifier_bmesh(context):
|
||||
side_lining_thickness = side_lining_thickness - panel_lining_overlap_x
|
||||
top_lining_thickness = top_lining_thickness - panel_top_lining_overlap_x
|
||||
|
||||
threshold_thickness = props.threshold_thickness * si_conversion
|
||||
threshold_depth = props.threshold_depth * si_conversion
|
||||
threshold_offset = props.threshold_offset * si_conversion
|
||||
threshold_thickness = props.threshold_thickness
|
||||
threshold_depth = props.threshold_depth
|
||||
threshold_offset = props.threshold_offset
|
||||
threshold_width = overall_width - side_lining_thickness * 2
|
||||
|
||||
casing_thickness = props.casing_thickness * si_conversion
|
||||
casing_depth = props.casing_depth * si_conversion
|
||||
casing_thickness = props.casing_thickness
|
||||
casing_depth = props.casing_depth
|
||||
|
||||
# panel params
|
||||
panel_width = door_opening_width * props.panel_width_ratio
|
||||
frame_depth = props.frame_depth * si_conversion
|
||||
frame_thickness = props.frame_thickness * si_conversion
|
||||
frame_depth = props.frame_depth
|
||||
frame_thickness = props.frame_thickness
|
||||
frame_height = window_lining_height - lining_to_panel_offset_x * 2
|
||||
glass_thickness = 0.01 * si_conversion
|
||||
glass_thickness = 0.01
|
||||
|
||||
# handle dimensions (hardcoded)
|
||||
handle_size = V(120, 40, 20) * 0.001 * si_conversion
|
||||
handle_offset = V(60, 0, 1000) * 0.001 * si_conversion # to the handle center
|
||||
handle_size = V(120, 40, 20) * 0.001
|
||||
handle_offset = V(60, 0, 1000) * 0.001 # to the handle center
|
||||
handle_center_offset = V(handle_size.y / 2, 0, handle_size.z) / 2
|
||||
|
||||
if transfom_offset:
|
||||
@@ -418,7 +413,7 @@ def update_door_modifier_bmesh(context):
|
||||
|
||||
if double_door:
|
||||
# keeping a little space between doors for readibility
|
||||
double_door_offset = 0.001 * si_conversion
|
||||
double_door_offset = 0.001
|
||||
panel_size.x = panel_size.x / 2 - double_door_offset
|
||||
door_verts.extend(create_bm_door_panel(panel_size, panel_position, "LEFT"))
|
||||
|
||||
@@ -516,14 +511,9 @@ class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||
self.report({"ERROR"}, "Object has to be IfcDoor/IfcDoorType type to add a door.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
# need to make sure all default props will have correct units
|
||||
if not props.door_added_previously:
|
||||
skip_props = ("is_editing", "door_type", "door_added_previously", "panel_width_ratio")
|
||||
convert_property_group_from_si(props, skip_props=skip_props)
|
||||
|
||||
door_data = props.get_general_kwargs()
|
||||
lining_props = props.get_lining_kwargs()
|
||||
panel_props = props.get_panel_kwargs()
|
||||
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||
lining_props = props.get_lining_kwargs(convert_to_project_units=True)
|
||||
panel_props = props.get_panel_kwargs(convert_to_project_units=True)
|
||||
|
||||
door_data["lining_properties"] = lining_props
|
||||
door_data["panel_properties"] = panel_props
|
||||
@@ -550,11 +540,13 @@ class CancelEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||
def _execute(self, context):
|
||||
obj = context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
||||
props = obj.BIMDoorProperties
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
||||
data.update(data.pop("lining_properties"))
|
||||
data.update(data.pop("panel_properties"))
|
||||
|
||||
# restore previous settings since editing was canceled
|
||||
for prop_name in data:
|
||||
setattr(props, prop_name, data[prop_name])
|
||||
props.set_props_kwargs_from_ifc_data(data)
|
||||
|
||||
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||
blenderbim.core.geometry.switch_representation(
|
||||
@@ -581,9 +573,9 @@ class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
props = obj.BIMDoorProperties
|
||||
|
||||
door_data = props.get_general_kwargs()
|
||||
lining_props = props.get_lining_kwargs()
|
||||
panel_props = props.get_panel_kwargs()
|
||||
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||
lining_props = props.get_lining_kwargs(convert_to_project_units=True)
|
||||
panel_props = props.get_panel_kwargs(convert_to_project_units=True)
|
||||
|
||||
door_data["lining_properties"] = lining_props
|
||||
door_data["panel_properties"] = panel_props
|
||||
@@ -612,15 +604,7 @@ class EnableEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||
data.update(data.pop("panel_properties"))
|
||||
|
||||
# required since we could load pset from .ifc and BIMDoorProperties won't be set
|
||||
for prop_name in data:
|
||||
setattr(props, prop_name, data[prop_name])
|
||||
|
||||
# need to make sure all props that weren't used before
|
||||
# will have correct units
|
||||
skip_props = ("is_editing", "door_type", "door_added_previously", "panel_width_ratio")
|
||||
skip_props += tuple(data.keys())
|
||||
convert_property_group_from_si(props, skip_props=skip_props)
|
||||
|
||||
props.set_props_kwargs_from_ifc_data(data)
|
||||
props.is_editing = 1
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -638,7 +622,6 @@ class RemoveDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
|
||||
props.door_added_previously = True
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -183,7 +183,6 @@ class BIMStairProperties(PropertyGroup):
|
||||
("GENERIC", "Generic", ""),
|
||||
)
|
||||
|
||||
stair_added_previously: bpy.props.BoolProperty(default=False)
|
||||
is_editing: bpy.props.IntProperty(default=-1)
|
||||
width: bpy.props.FloatProperty(name="Width", default=1.2, soft_min=0.01, subtype="DISTANCE")
|
||||
height: bpy.props.FloatProperty(name="Height", default=1.0, soft_min=0.01, subtype="DISTANCE")
|
||||
@@ -246,7 +245,7 @@ def window_type_prop_update(self, context):
|
||||
|
||||
# default prop values are in mm and converted later
|
||||
class BIMWindowProperties(PropertyGroup):
|
||||
non_si_units_props = ("is_editing", "window_type", "window_added_previously")
|
||||
non_si_units_props = ("is_editing", "window_type")
|
||||
window_types = (
|
||||
("SINGLE_PANEL", "SINGLE_PANEL", ""),
|
||||
("DOUBLE_PANEL_HORIZONTAL", "DOUBLE_PANEL_HORIZONTAL", ""),
|
||||
@@ -274,7 +273,6 @@ class BIMWindowProperties(PropertyGroup):
|
||||
}
|
||||
# fmt: on
|
||||
|
||||
window_added_previously: bpy.props.BoolProperty(default=False)
|
||||
is_editing: bpy.props.IntProperty(default=-1)
|
||||
window_type: bpy.props.EnumProperty(
|
||||
name="Window Type", items=window_types, default="SINGLE_PANEL", update=window_type_prop_update
|
||||
@@ -392,6 +390,7 @@ class BIMWindowProperties(PropertyGroup):
|
||||
|
||||
|
||||
class BIMDoorProperties(PropertyGroup):
|
||||
non_si_units_props = ("is_editing", "door_type", "panel_width_ratio")
|
||||
door_types = (
|
||||
("SINGLE_SWING_LEFT", "SINGLE_SWING_LEFT", ""),
|
||||
("SINGLE_SWING_RIGHT", "SINGLE_SWING_RIGHT", ""),
|
||||
@@ -403,51 +402,56 @@ class BIMDoorProperties(PropertyGroup):
|
||||
("DOUBLE_DOOR_SLIDING", "DOUBLE_DOOR_SLIDING", ""),
|
||||
)
|
||||
|
||||
door_added_previously: bpy.props.BoolProperty(default=False)
|
||||
is_editing: bpy.props.IntProperty(default=-1)
|
||||
door_type: bpy.props.EnumProperty(name="Door Operation Type", items=door_types, default="SINGLE_SWING_LEFT")
|
||||
overall_height: bpy.props.FloatProperty(name="Overall Height", default=2.0)
|
||||
overall_width: bpy.props.FloatProperty(name="Overall Width", default=0.9)
|
||||
overall_height: bpy.props.FloatProperty(name="Overall Height", default=2.0, subtype="DISTANCE")
|
||||
overall_width: bpy.props.FloatProperty(name="Overall Width", default=0.9, subtype="DISTANCE")
|
||||
|
||||
# lining properties
|
||||
lining_depth: bpy.props.FloatProperty(name="Lining Depth", default=0.050)
|
||||
lining_thickness: bpy.props.FloatProperty(name="Lining Thickness", default=0.050)
|
||||
lining_depth: bpy.props.FloatProperty(name="Lining Depth", default=0.050, subtype="DISTANCE")
|
||||
lining_thickness: bpy.props.FloatProperty(name="Lining Thickness", default=0.050, subtype="DISTANCE")
|
||||
lining_offset: bpy.props.FloatProperty(
|
||||
name="Lining Offset",
|
||||
description="Offset from the outer side of the wall (by Y-axis). "
|
||||
"If present then adding casing is not possible.\n"
|
||||
"`0.025 mm` is good as default value",
|
||||
default=0.0,
|
||||
default=0.0,
|
||||
subtype="DISTANCE"
|
||||
)
|
||||
lining_to_panel_offset_x: bpy.props.FloatProperty(name="Lining to Panel Offset X", default=0.025)
|
||||
lining_to_panel_offset_y: bpy.props.FloatProperty(name="Lining to Panel Offset Y", default=0.025)
|
||||
lining_to_panel_offset_x: bpy.props.FloatProperty(name="Lining to Panel Offset X", default=0.025, subtype="DISTANCE")
|
||||
lining_to_panel_offset_y: bpy.props.FloatProperty(name="Lining to Panel Offset Y", default=0.025, subtype="DISTANCE")
|
||||
|
||||
transom_thickness: bpy.props.FloatProperty(
|
||||
name="Transom Thickness",
|
||||
description="Set values > 0 to add a transom.\n" "`0.050 mm` is good as default value",
|
||||
default=0.000,
|
||||
subtype="DISTANCE"
|
||||
)
|
||||
transom_offset: bpy.props.FloatProperty(
|
||||
name="Transom Offset",
|
||||
description="Distance from the bottom door opening to the beginning of the transom (unlike windows)",
|
||||
default=1.525,
|
||||
subtype="DISTANCE"
|
||||
)
|
||||
|
||||
casing_thickness: bpy.props.FloatProperty(
|
||||
name="Casing Thickness", description="Set values > 0 and LiningOffset = 0 to add a casing.", default=0.075
|
||||
name="Casing Thickness", description="Set values > 0 and LiningOffset = 0 to add a casing.", default=0.075,
|
||||
subtype="DISTANCE"
|
||||
)
|
||||
casing_depth: bpy.props.FloatProperty(name="Casing Depth", default=0.005)
|
||||
casing_depth: bpy.props.FloatProperty(name="Casing Depth", default=0.005, subtype="DISTANCE")
|
||||
|
||||
threshold_thickness: bpy.props.FloatProperty(
|
||||
name="Threshold Thickness", description="Set values > 0 to add a threshold.", default=0.025
|
||||
name="Threshold Thickness", description="Set values > 0 to add a threshold.", default=0.025,
|
||||
subtype="DISTANCE"
|
||||
)
|
||||
threshold_depth: bpy.props.FloatProperty(name="Threshold Depth", default=0.1)
|
||||
threshold_depth: bpy.props.FloatProperty(name="Threshold Depth", default=0.1, subtype="DISTANCE")
|
||||
threshold_offset: bpy.props.FloatProperty(
|
||||
name="Threshold Offset", description="`0.025 mm` is good as default value", default=0.000
|
||||
name="Threshold Offset", description="`0.025 mm` is good as default value", default=0.000,
|
||||
subtype="DISTANCE"
|
||||
)
|
||||
|
||||
# panel properties
|
||||
panel_depth: bpy.props.FloatProperty(name="Panel Depth", default=0.035)
|
||||
panel_depth: bpy.props.FloatProperty(name="Panel Depth", default=0.035, subtype="DISTANCE")
|
||||
panel_width_ratio: bpy.props.FloatProperty(
|
||||
name="Panel Width Ratio",
|
||||
description="Width of this panel, given as ratio " "relative to the total clear opening width of the door",
|
||||
@@ -455,17 +459,20 @@ class BIMDoorProperties(PropertyGroup):
|
||||
soft_min=0,
|
||||
soft_max=1,
|
||||
)
|
||||
frame_thickness: bpy.props.FloatProperty(name="Window Frame Thickness", default=0.035)
|
||||
frame_depth: bpy.props.FloatProperty(name="Window Frame Depth", default=0.035)
|
||||
frame_thickness: bpy.props.FloatProperty(name="Window Frame Thickness", default=0.035, subtype="DISTANCE")
|
||||
frame_depth: bpy.props.FloatProperty(name="Window Frame Depth", default=0.035, subtype="DISTANCE")
|
||||
|
||||
def get_general_kwargs(self):
|
||||
return {
|
||||
def get_general_kwargs(self, convert_to_project_units=False):
|
||||
kwargs = {
|
||||
"door_type": self.door_type,
|
||||
"overall_height": self.overall_height,
|
||||
"overall_width": self.overall_width,
|
||||
}
|
||||
if not convert_to_project_units:
|
||||
return kwargs
|
||||
return tool.Model.convert_data_to_project_units(kwargs, ["door_type"])
|
||||
|
||||
def get_lining_kwargs(self):
|
||||
def get_lining_kwargs(self, convert_to_project_units=False):
|
||||
kwargs = {
|
||||
"lining_depth": self.lining_depth,
|
||||
"lining_thickness": self.lining_thickness,
|
||||
@@ -490,19 +497,36 @@ class BIMDoorProperties(PropertyGroup):
|
||||
kwargs["threshold_depth"] = self.threshold_depth
|
||||
kwargs["threshold_offset"] = self.threshold_offset
|
||||
|
||||
return kwargs
|
||||
if not convert_to_project_units:
|
||||
return kwargs
|
||||
return tool.Model.convert_data_to_project_units(kwargs)
|
||||
|
||||
def get_panel_kwargs(self):
|
||||
def get_panel_kwargs(self, convert_to_project_units=False):
|
||||
kwargs = {"panel_depth": self.panel_depth, "panel_width_ratio": self.panel_width_ratio}
|
||||
|
||||
if self.transom_thickness:
|
||||
kwargs["frame_thickness"] = self.frame_thickness
|
||||
kwargs["frame_depth"] = self.frame_depth
|
||||
|
||||
return kwargs
|
||||
if not convert_to_project_units:
|
||||
return kwargs
|
||||
return tool.Model.convert_data_to_project_units(kwargs, ("panel_width_ratio", ))
|
||||
|
||||
def set_props_kwargs_from_ifc_data(self, kwargs):
|
||||
kwargs = tool.Model.convert_data_to_si_units(kwargs, self.non_si_units_props)
|
||||
for prop_name in kwargs:
|
||||
setattr(self, prop_name, kwargs[prop_name])
|
||||
|
||||
|
||||
class BIMRailingProperties(PropertyGroup):
|
||||
non_si_units_props = (
|
||||
"is_editing",
|
||||
"railing_type",
|
||||
"use_manual_supports",
|
||||
"terminal_type",
|
||||
"path_data",
|
||||
)
|
||||
|
||||
railing_types = (
|
||||
("FRAMELESS_PANEL", "FRAMELESS_PANEL", ""),
|
||||
("WALL_MOUNTED_HANDRAIL", "WALL_MOUNTED_HANDRAIL", ""),
|
||||
@@ -516,14 +540,13 @@ class BIMRailingProperties(PropertyGroup):
|
||||
("NONE", "NONE", ""),
|
||||
)
|
||||
|
||||
railing_added_previously: bpy.props.BoolProperty(default=False)
|
||||
is_editing: bpy.props.IntProperty(default=-1)
|
||||
is_editing_path: bpy.props.BoolProperty(default=False)
|
||||
|
||||
railing_type: bpy.props.EnumProperty(name="Railing Type", items=railing_types, default="FRAMELESS_PANEL")
|
||||
height: bpy.props.FloatProperty(name="Height", default=1.0)
|
||||
thickness: bpy.props.FloatProperty(name="Thickness", default=0.050)
|
||||
spacing: bpy.props.FloatProperty(name="Spacing", default=0.050)
|
||||
height: bpy.props.FloatProperty(name="Height", default=1.0, subtype="DISTANCE")
|
||||
thickness: bpy.props.FloatProperty(name="Thickness", default=0.050, subtype="DISTANCE")
|
||||
spacing: bpy.props.FloatProperty(name="Spacing", default=0.050, subtype="DISTANCE")
|
||||
|
||||
# wall mounted handrail specific properties
|
||||
use_manual_supports: bpy.props.BoolProperty(
|
||||
@@ -541,7 +564,7 @@ class BIMRailingProperties(PropertyGroup):
|
||||
)
|
||||
terminal_type: bpy.props.EnumProperty(name="Terminal Type", items=cap_types, default="180")
|
||||
|
||||
def get_general_kwargs(self):
|
||||
def get_general_kwargs(self, convert_to_project_units=False):
|
||||
base_kwargs = {
|
||||
"railing_type": self.railing_type,
|
||||
"height": self.height,
|
||||
@@ -560,15 +583,24 @@ class BIMRailingProperties(PropertyGroup):
|
||||
"support_spacing": self.support_spacing,
|
||||
"terminal_type": self.terminal_type,
|
||||
}
|
||||
return base_kwargs | additional_kwargs
|
||||
kwargs = base_kwargs | additional_kwargs
|
||||
|
||||
if not convert_to_project_units:
|
||||
return kwargs
|
||||
|
||||
kwargs = tool.Model.convert_data_to_project_units(kwargs, self.non_si_units_props)
|
||||
return kwargs
|
||||
|
||||
def set_props_kwargs_from_ifc_data(self, kwargs):
|
||||
kwargs = tool.Model.convert_data_to_si_units(kwargs, self.non_si_units_props)
|
||||
for prop_name in kwargs:
|
||||
setattr(self, prop_name, kwargs[prop_name])
|
||||
|
||||
class BIMRoofProperties(PropertyGroup):
|
||||
non_si_units_props = (
|
||||
"is_editing",
|
||||
"path_data",
|
||||
"roof_type",
|
||||
"roof_added_previously",
|
||||
"generation_method",
|
||||
"angle",
|
||||
"rafter_edge_angle",
|
||||
@@ -579,7 +611,6 @@ class BIMRoofProperties(PropertyGroup):
|
||||
("ANGLE", "ANGLE", ""),
|
||||
)
|
||||
|
||||
roof_added_previously: bpy.props.BoolProperty(default=False)
|
||||
is_editing: bpy.props.IntProperty(default=-1)
|
||||
is_editing_path: bpy.props.BoolProperty(default=False)
|
||||
|
||||
|
||||
@@ -38,14 +38,6 @@ import json
|
||||
# https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcRailingType.htm
|
||||
|
||||
|
||||
NON_SI_RAILING_PROPS = (
|
||||
"is_editing",
|
||||
"railing_type",
|
||||
"railing_added_previously",
|
||||
"use_manual_supports",
|
||||
"terminal_type",
|
||||
)
|
||||
|
||||
|
||||
def bm_split_edge_at_offset(edge, offset):
|
||||
v0, v1 = edge.verts
|
||||
@@ -92,16 +84,18 @@ def update_railing_modifier_ifc_data(context):
|
||||
if props.railing_type == "WALL_MOUNTED_HANDRAIL":
|
||||
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
|
||||
railing_path = [Vector(v) for v in RailingData.data["parameters"]["data_dict"]["path_data"]["verts"]]
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
|
||||
representation_data = {
|
||||
"railing_type": props.railing_type,
|
||||
"context": body,
|
||||
"railing_path": railing_path,
|
||||
"use_manual_supports": props.use_manual_supports,
|
||||
"support_spacing": props.support_spacing,
|
||||
"railing_diameter": props.railing_diameter,
|
||||
"clear_width": props.clear_width,
|
||||
"support_spacing": props.support_spacing / si_conversion,
|
||||
"railing_diameter": props.railing_diameter / si_conversion,
|
||||
"clear_width": props.clear_width / si_conversion,
|
||||
"terminal_type": props.terminal_type,
|
||||
"height": props.height,
|
||||
"height": props.height / si_conversion,
|
||||
}
|
||||
model_representation = ifcopenshell.api.run(
|
||||
"geometry.add_railing_representation", ifc_file, **representation_data
|
||||
@@ -153,9 +147,9 @@ def update_railing_modifier_bmesh(context):
|
||||
|
||||
def generate_frameless_panel_railing():
|
||||
# generating FRAMELESS_PANEL railing
|
||||
height = props.height * si_conversion
|
||||
thickness = props.thickness * si_conversion
|
||||
spacing = props.spacing * si_conversion
|
||||
height = props.height
|
||||
thickness = props.thickness
|
||||
spacing = props.spacing
|
||||
|
||||
# spacing
|
||||
# split each edge in 3 segments by 0.5 * spacing by x-y plane
|
||||
@@ -313,11 +307,8 @@ class AddRailing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
self.report({"ERROR"}, "Object has to be IfcRailing/IfcRailingType type to add a railing.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
# need to make sure all default props will have correct units
|
||||
if not props.railing_added_previously:
|
||||
convert_property_group_from_si(props, skip_props=NON_SI_RAILING_PROPS)
|
||||
|
||||
railing_data = props.get_general_kwargs()
|
||||
railing_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||
path_data = get_path_data(obj)
|
||||
if not path_data:
|
||||
path_data = {
|
||||
@@ -350,13 +341,7 @@ class EnableEditingRailing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
data["path_data"] = json.dumps(data["path_data"])
|
||||
|
||||
# required since we could load pset from .ifc and BIMRailingProperties won't be set
|
||||
for prop_name in data:
|
||||
setattr(props, prop_name, data[prop_name])
|
||||
|
||||
# need to make sure all props that weren't used before
|
||||
# will have correct units
|
||||
skip_props = NON_SI_RAILING_PROPS + tuple(data.keys())
|
||||
convert_property_group_from_si(props, skip_props=skip_props)
|
||||
props.set_props_kwargs_from_ifc_data(data)
|
||||
|
||||
props.is_editing = 1
|
||||
return {"FINISHED"}
|
||||
@@ -373,8 +358,7 @@ class CancelEditingRailing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Railing", "Data"))
|
||||
props = obj.BIMRailingProperties
|
||||
# restore previous settings since editing was canceled
|
||||
for prop_name in data:
|
||||
setattr(props, prop_name, data[prop_name])
|
||||
props.set_props_kwargs_from_ifc_data(data)
|
||||
|
||||
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||
blenderbim.core.geometry.switch_representation(
|
||||
@@ -405,7 +389,7 @@ class FinishEditingRailing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
RailingData.load()
|
||||
path_data = RailingData.data["parameters"]["data_dict"]["path_data"]
|
||||
|
||||
railing_data = props.get_general_kwargs()
|
||||
railing_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||
railing_data["path_data"] = path_data
|
||||
props.is_editing = -1
|
||||
|
||||
@@ -437,7 +421,7 @@ class FlipRailingPathOrder(bpy.types.Operator, tool.Ifc.Operator):
|
||||
edge = [abs(vi - last_vert_i) for vi in edge[::-1]]
|
||||
edges.append(edge)
|
||||
|
||||
railing_data = props.get_general_kwargs()
|
||||
railing_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||
railing_data["path_data"] = path_data
|
||||
|
||||
update_bbim_railing_pset(element, railing_data)
|
||||
@@ -496,7 +480,7 @@ class FinishEditingRailingPath(bpy.types.Operator, tool.Ifc.Operator):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
props = obj.BIMRailingProperties
|
||||
|
||||
railing_data = props.get_general_kwargs()
|
||||
railing_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||
path_data = get_path_data(obj)
|
||||
railing_data["path_data"] = path_data
|
||||
ProfileDecorator.uninstall()
|
||||
@@ -524,7 +508,6 @@ class RemoveRailing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
pset = tool.Pset.get_element_pset(element, "BBIM_Railing")
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
|
||||
props.railing_added_previously = True
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -772,7 +772,6 @@ class RemoveRoof(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
pset = tool.Pset.get_element_pset(element, "BBIM_Roof")
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
|
||||
props.roof_added_previously = True
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -437,7 +437,6 @@ class RemoveStair(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
pset = tool.Pset.get_element_pset(element, "BBIM_Stair")
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
|
||||
props.stair_added_previously = True
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -559,7 +559,6 @@ class RemoveWindow(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
pset = tool.Pset.get_element_pset(element, "BBIM_Window")
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
|
||||
props.window_added_previously = True
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user