Added support for different railing cap types

Very similar to this - https://i.imgur.com/SNyvfgh.png
This commit is contained in:
Andrej730
2023-04-28 17:23:04 +05:00
parent 3b69a4cc78
commit 9b22b5000f
2 changed files with 58 additions and 14 deletions
@@ -499,12 +499,12 @@ class BIMRailingProperties(PropertyGroup):
("WALL_MOUNTED_HANDRAIL", "WALL_MOUNTED_HANDRAIL", ""), ("WALL_MOUNTED_HANDRAIL", "WALL_MOUNTED_HANDRAIL", ""),
) )
cap_types = ( cap_types = (
("none", "none", ""), ("TO_END_POST_AND_FLOOR", "TO_END_POST_AND_FLOOR", ""),
("TO_END_POST", "TO_END_POST", ""),
("TO_FLOOR", "TO_FLOOR", ""),
("TO_WALL", "TO_WALL", ""),
("180", "180", ""), ("180", "180", ""),
("to_wall", "to_wall", ""), ("NONE", "NONE", ""),
("to_floor", "to_floor", ""),
("to_end_post", "to_end_post", ""),
("to_end_post_and_floor", "to_end_post_and_floor", ""),
) )
railing_added_previously: bpy.props.BoolProperty(default=False) railing_added_previously: bpy.props.BoolProperty(default=False)
@@ -23,7 +23,7 @@ from mathutils import Vector, Matrix
import collections import collections
import mathutils import mathutils
from pprint import pprint from pprint import pprint
from math import pi, cos, sin, tan from math import pi, cos, sin, tan, radians
def mm(x): def mm(x):
@@ -75,7 +75,8 @@ class Usecase:
railing_radius = self.settings["railing_diameter"] / 2 railing_radius = self.settings["railing_diameter"] / 2
support_spacing = self.settings["support_spacing"] support_spacing = self.settings["support_spacing"]
clear_width = self.settings["clear_width"] clear_width = self.settings["clear_width"]
height = self.settings["height"] # for calculations purposes we use height without railing radius
height = self.settings["height"] - railing_radius
cap_type = self.settings["terminal_type"] cap_type = self.settings["terminal_type"]
ifc_context = self.settings["context"] ifc_context = self.settings["context"]
railing_coords = self.settings["railing_path"] railing_coords = self.settings["railing_path"]
@@ -130,7 +131,7 @@ class Usecase:
)[0] )[0]
midpointco = center + ((fillet_v1co.lerp(fillet_v2co, 0.5) - center).normalized() * radius) midpointco = center + ((fillet_v1co.lerp(fillet_v2co, 0.5) - center).normalized() * radius)
return fillet_v1co, midpointco, fillet_v2co return [fillet_v1co, midpointco, fillet_v2co]
def add_arcs_on_turnings_points(base_points): def add_arcs_on_turnings_points(base_points):
"""add 3 point fillet arcs on turning points of the railing path""" """add 3 point fillet arcs on turning points of the railing path"""
@@ -207,12 +208,54 @@ class Usecase:
# TODO: implement more cap types # TODO: implement more cap types
railing_coords_for_cap = railing_coords[::-1] if start else railing_coords railing_coords_for_cap = railing_coords[::-1] if start else railing_coords
start = railing_coords_for_cap[-1] start_point = railing_coords_for_cap[-1]
cap_dir = (railing_coords_for_cap[-1] - railing_coords_for_cap[-2]).xy.to_3d().normalized() cap_dir = (railing_coords_for_cap[-1] - railing_coords_for_cap[-2]).xy.to_3d().normalized()
arc_point = start + cap_dir * terminal_radius + terminal_radius * z_down ortho_dir = (cap_dir.yx * V(1, -1)).to_3d().normalized()
arc_points.append(arc_point) if start:
cap_coords = [arc_point, start + terminal_radius * 2 * z_down] ortho_dir = -ortho_dir
arc_middle_point_cos = sin(radians(45))
if cap_type in ('180', 'TO_END_POST'):
arc_point = start_point + cap_dir * terminal_radius + terminal_radius * z_down
arc_points.append(arc_point)
cap_coords = [arc_point, start_point + terminal_radius * 2 * z_down]
if cap_type == 'TO_END_POST':
end_point = railing_coords_for_cap[-2].copy()
end_point.z -= terminal_radius * 2
cap_coords.append(end_point)
elif cap_type == 'TO_WALL':
arc_point = start_point + cap_dir * clear_width * arc_middle_point_cos + ortho_dir * clear_width * (1-arc_middle_point_cos)
arc_points.append(arc_point)
cap_coords = [arc_point, start_point + ortho_dir * clear_width + cap_dir * clear_width]
elif cap_type == 'TO_FLOOR':
arc_point = start_point + cap_dir * terminal_radius * arc_middle_point_cos + z_down * terminal_radius * (1-arc_middle_point_cos)
arc_points.append(arc_point)
arc_end = start_point + cap_dir * terminal_radius + terminal_radius * z_down
cap_coords = [
arc_point,
arc_end,
arc_end+z_down*(height-terminal_radius),
]
elif cap_type == 'TO_END_POST_AND_FLOOR':
first_arc_end = start_point + cap_dir * terminal_radius + terminal_radius * z_down
first_arc_coords = get_fillet_points(
start_point, start_point + cap_dir * terminal_radius,
first_arc_end, terminal_radius)
arc_points.append(first_arc_coords[1])
end_point = railing_coords_for_cap[-2].copy()
end_point.z -= height
second_arc_coords = get_fillet_points(
first_arc_end, first_arc_end + z_down * terminal_radius, end_point, terminal_radius
)
arc_points.append(second_arc_coords[1])
cap_coords = [start_point] + first_arc_coords + second_arc_coords + [end_point]
railing_coords = railing_coords_for_cap + cap_coords railing_coords = railing_coords_for_cap + cap_coords
if start: if start:
@@ -222,8 +265,9 @@ class Usecase:
items_3d.extend(create_supports_items(railing_coords, manual_supports=use_manual_supports)) items_3d.extend(create_supports_items(railing_coords, manual_supports=use_manual_supports))
railing_coords = add_arcs_on_turnings_points(railing_coords) railing_coords = add_arcs_on_turnings_points(railing_coords)
railing_coords, arc_points = add_cap(railing_coords, arc_points, start=True) if cap_type != 'NONE':
railing_coords, arc_points = add_cap(railing_coords, arc_points, start=False) railing_coords, arc_points = add_cap(railing_coords, arc_points, start=True)
railing_coords, arc_points = add_cap(railing_coords, arc_points, start=False)
railing_path = builder.polyline( railing_path = builder.polyline(
railing_coords, closed=False, arc_points=[railing_coords.index(p) for p in arc_points] railing_coords, closed=False, arc_points=[railing_coords.index(p) for p in arc_points]