finish rail adder
This commit is contained in:
parent
31aa5c3127
commit
013096459a
@ -9,6 +9,27 @@ from . import UTIL_functions, UTIL_naming_convension
|
||||
# Equation: Sink = sqrt( ((RailRadius + BallRadius) ^ 2) - ((RailSpan / 2) ^ 2) ) - BallRadius - RailRadius
|
||||
# BallRadius is the radius of player ball. It always is 2.
|
||||
# Ref: https://tieba.baidu.com/p/6557180791
|
||||
#
|
||||
# For Normal Side Rail (paper ball + wood ball can pass it):
|
||||
# Rail Span: 3.864
|
||||
# Angle (between rail panel and XY panel): 79.563 degree
|
||||
# For Special Side Rail (stone ball can pass it):
|
||||
# Rail Span: 3.864
|
||||
# Angle (between rail panel and XY panel): 57 degree
|
||||
# These infos are gotten from BallanceBug.
|
||||
#
|
||||
# For Side Spiral Rail, the distance between each layer is 3.6
|
||||
# Measured in Level 9 and Level 13.
|
||||
# For Spiral Rail, the distance between each layer is 5
|
||||
# Measured in Level 10.
|
||||
|
||||
c_DefaultRailRadius: float = 0.35
|
||||
c_DefaultRailSpan: float = 3.75
|
||||
c_SideRailSpan: float = 3.864
|
||||
c_NormalSideRailAngle: float = 79.563
|
||||
c_StoneSideRailAngle: float = 57
|
||||
c_SpiralRailScrew: float = 5
|
||||
c_SideSpiralRailScrew: float = 3.6
|
||||
|
||||
#region Operator Helpers
|
||||
|
||||
@ -28,56 +49,12 @@ class SharedRailSectionInputProperty():
|
||||
default = 'RAIL',
|
||||
) # type: ignore
|
||||
|
||||
rail_radius: bpy.props.FloatProperty(
|
||||
name = "Radius",
|
||||
description = "Define rail section radius",
|
||||
default = 0.35,
|
||||
min = 0,
|
||||
unit = 'LENGTH'
|
||||
) # type: ignore
|
||||
|
||||
rail_span: bpy.props.FloatProperty(
|
||||
name = "Span",
|
||||
description = "The length between 2 single rails.",
|
||||
default = 3.75,
|
||||
min = 0,
|
||||
unit = 'LENGTH'
|
||||
) # type: ignore
|
||||
|
||||
def draw_rail_section_input(self, layout: bpy.types.UILayout, force_monorail: bool | None) -> None:
|
||||
"""
|
||||
Draw rail section properties
|
||||
|
||||
@param force_monorail[in] Force this draw method for monorail if True, or for rail if False. Accept None if you want user to choose it.
|
||||
"""
|
||||
# draw title
|
||||
layout = layout.box()
|
||||
layout.label(text = 'Section')
|
||||
|
||||
if force_monorail is None:
|
||||
# show picker to allow user pick
|
||||
# force it show horizontal
|
||||
def draw_rail_section_input(self, layout: bpy.types.UILayout) -> None:
|
||||
row = layout.row()
|
||||
row.prop(self, 'rail_type', expand = True)
|
||||
# show radius
|
||||
layout.prop(self, "rail_radius")
|
||||
# show span for rail
|
||||
if self.rail_type == 'RAIL':
|
||||
layout.prop(self, "rail_span")
|
||||
else:
|
||||
# according to force type to show
|
||||
# always show radius
|
||||
layout.prop(self, "rail_radius")
|
||||
# show span in condition
|
||||
if not force_monorail:
|
||||
layout.prop(self, "rail_span")
|
||||
|
||||
def general_get_is_monorail(self) -> bool:
|
||||
return self.rail_type == 'MONORAIL'
|
||||
def general_get_rail_radius(self) -> float:
|
||||
return self.rail_radius
|
||||
def general_get_rail_span(self) -> float:
|
||||
return self.rail_span
|
||||
|
||||
class SharedRailCapInputProperty():
|
||||
"""
|
||||
@ -98,9 +75,6 @@ class SharedRailCapInputProperty():
|
||||
) # type: ignore
|
||||
|
||||
def draw_rail_cap_input(self, layout: bpy.types.UILayout) -> None:
|
||||
# draw title
|
||||
layout = layout.box()
|
||||
layout.label(text = 'Cap')
|
||||
row = layout.row()
|
||||
row.prop(self, "rail_start_cap", toggle = 1)
|
||||
row.prop(self, "rail_end_cap", toggle = 1)
|
||||
@ -125,9 +99,6 @@ class SharedStraightRailInputProperty():
|
||||
) # type: ignore
|
||||
|
||||
def draw_straight_rail_input(self, layout: bpy.types.UILayout) -> None:
|
||||
# draw title
|
||||
layout = layout.box()
|
||||
layout.label(text = 'Straight Rail')
|
||||
layout.prop(self, "rail_length")
|
||||
|
||||
def general_get_rail_length(self) -> float:
|
||||
@ -138,69 +109,24 @@ class SharedScrewRailInputProperty():
|
||||
The properties for straight rail.
|
||||
"""
|
||||
|
||||
rail_screw_angle: bpy.props.FloatProperty(
|
||||
name = "Angle",
|
||||
description = "The angle of this screw rail rotated in one interation.",
|
||||
default = 90,
|
||||
subtype = 'ANGLE',
|
||||
) # type: ignore
|
||||
|
||||
rail_screw_screw: bpy.props.FloatProperty(
|
||||
name = "Screw",
|
||||
description = "The increased height in each iteration. Minus height also is accepted.",
|
||||
default = 6,
|
||||
unit = 'LENGTH'
|
||||
) # type: ignore
|
||||
|
||||
rail_screw_iterations: bpy.props.IntProperty(
|
||||
name = "Iterations",
|
||||
description = "The angle of this screw rail rotated in one interation.",
|
||||
default = 1,
|
||||
min = 1,
|
||||
) # type: ignore
|
||||
|
||||
rail_screw_steps: bpy.props.IntProperty(
|
||||
name = "Steps",
|
||||
description = "The segment count per iteration.",
|
||||
default = 20,
|
||||
description = "The segment count per iteration. More segment, more smooth but lower performance.",
|
||||
default = 16,
|
||||
min = 1,
|
||||
) # type: ignore
|
||||
|
||||
rail_screw_radius: bpy.props.FloatProperty(
|
||||
name = "Radius",
|
||||
description = "The screw radius. Minus radius will flip the built screw.",
|
||||
default = 10,
|
||||
default = 5,
|
||||
unit = 'LENGTH'
|
||||
) # type: ignore
|
||||
|
||||
def draw_screw_rail_input(self, layout: bpy.types.UILayout, show_for_screw: bool) -> None:
|
||||
# draw title
|
||||
layout = layout.box()
|
||||
layout.label(text = 'Screw Rail')
|
||||
|
||||
if show_for_screw:
|
||||
# screw do not need angle property
|
||||
layout.prop(self, "rail_screw_screw")
|
||||
layout.prop(self, "rail_screw_iterations")
|
||||
layout.prop(self, "rail_screw_radius")
|
||||
layout.prop(self, "rail_screw_steps")
|
||||
else:
|
||||
# curve do not need iterations (always is 1)
|
||||
# and do not need screw (always is 0)
|
||||
layout.prop(self, "rail_screw_angle")
|
||||
def draw_screw_rail_input(self, layout: bpy.types.UILayout) -> None:
|
||||
layout.prop(self, "rail_screw_radius")
|
||||
layout.prop(self, "rail_screw_steps")
|
||||
|
||||
# Getter should return default value if corresponding field
|
||||
# is not existing in that mode.
|
||||
|
||||
def general_get_rail_screw_angle(self, is_for_screw: bool) -> float:
|
||||
"""This function return angle in degree unit."""
|
||||
return 360 if is_for_screw else self.rail_screw_angle
|
||||
def general_get_rail_screw_screw(self, is_for_screw: bool) -> float:
|
||||
return self.rail_screw_screw if is_for_screw else 0
|
||||
def general_get_rail_screw_iterations(self, is_for_screw: bool) -> int:
|
||||
return self.rail_screw_iterations if is_for_screw else 1
|
||||
def general_get_rail_screw_radius(self) -> float:
|
||||
return self.rail_screw_radius
|
||||
def general_get_rail_screw_steps(self) -> int:
|
||||
@ -219,17 +145,17 @@ class BBP_OT_add_rail_section(SharedRailSectionInputProperty, bpy.types.Operator
|
||||
def execute(self, context):
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_rail_section(
|
||||
bm,
|
||||
self.general_get_is_monorail(), self.general_get_rail_radius(), self.general_get_rail_span()
|
||||
bm, self.general_get_is_monorail(),
|
||||
c_DefaultRailRadius, c_DefaultRailSpan
|
||||
)
|
||||
)
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
self.draw_rail_section_input(layout, None)
|
||||
self.draw_rail_section_input(layout)
|
||||
|
||||
class BBP_OT_add_transition_section(SharedRailSectionInputProperty, bpy.types.Operator):
|
||||
class BBP_OT_add_transition_section(bpy.types.Operator):
|
||||
"""Add Transition Section"""
|
||||
bl_idname = "bbp.add_transition_section"
|
||||
bl_label = "Transition Section"
|
||||
@ -237,17 +163,13 @@ class BBP_OT_add_transition_section(SharedRailSectionInputProperty, bpy.types.Op
|
||||
|
||||
def execute(self, context):
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_transition_section(
|
||||
bm,
|
||||
self.general_get_rail_radius(), self.general_get_rail_span()
|
||||
)
|
||||
lambda bm: _create_transition_section(bm, c_DefaultRailRadius, c_DefaultRailSpan)
|
||||
)
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
# force show double rail params
|
||||
self.draw_rail_section_input(layout, False)
|
||||
layout.label(text = 'No Options Available')
|
||||
|
||||
class BBP_OT_add_straight_rail(SharedRailSectionInputProperty, SharedRailCapInputProperty, SharedStraightRailInputProperty, bpy.types.Operator):
|
||||
"""Add Straight Rail"""
|
||||
@ -259,8 +181,8 @@ class BBP_OT_add_straight_rail(SharedRailSectionInputProperty, SharedRailCapInpu
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_straight_rail(
|
||||
bm,
|
||||
self.general_get_is_monorail(), self.general_get_rail_radius(), self.general_get_rail_span(),
|
||||
self.general_get_rail_length(),
|
||||
self.general_get_is_monorail(), c_DefaultRailRadius, c_DefaultRailSpan,
|
||||
self.general_get_rail_length(), 0,
|
||||
self.general_get_rail_start_cap(), self.general_get_rail_end_cap()
|
||||
)
|
||||
)
|
||||
@ -268,25 +190,71 @@ class BBP_OT_add_straight_rail(SharedRailSectionInputProperty, SharedRailCapInpu
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
self.draw_rail_section_input(layout, None)
|
||||
layout.separator()
|
||||
self.draw_rail_cap_input(layout)
|
||||
layout.separator()
|
||||
layout.label(text = 'Straight Rail')
|
||||
self.draw_rail_section_input(layout)
|
||||
self.draw_straight_rail_input(layout)
|
||||
layout.separator()
|
||||
layout.label(text = 'Rail Cap')
|
||||
self.draw_rail_cap_input(layout)
|
||||
|
||||
class BBP_OT_add_screw_rail(SharedRailSectionInputProperty, SharedRailCapInputProperty, SharedScrewRailInputProperty, bpy.types.Operator):
|
||||
"""Add Screw Rail"""
|
||||
bl_idname = "bbp.add_screw_rail"
|
||||
bl_label = "Screw Rail"
|
||||
class BBP_OT_add_side_rail(SharedRailCapInputProperty, SharedStraightRailInputProperty, bpy.types.Operator):
|
||||
"""Add Side Rail"""
|
||||
bl_idname = "bbp.add_side_rail"
|
||||
bl_label = "Side Rail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
side_rail_type: bpy.props.EnumProperty(
|
||||
name = "Side Type",
|
||||
description = "Side rail type",
|
||||
items = [
|
||||
('NORMAL', "Normal", "The normal side rail."),
|
||||
('STONE', "Stone Specific", "The side rail which also allow stone ball passed."),
|
||||
],
|
||||
default = 'NORMAL',
|
||||
) # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_straight_rail(
|
||||
bm,
|
||||
False, c_DefaultRailRadius, c_DefaultRailSpan,
|
||||
self.general_get_rail_length(),
|
||||
c_NormalSideRailAngle if self.side_rail_type == 'NORMAL' else c_StoneSideRailAngle,
|
||||
self.general_get_rail_start_cap(), self.general_get_rail_end_cap()
|
||||
)
|
||||
)
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text = 'Side Rail')
|
||||
layout.prop(self, 'side_rail_type')
|
||||
self.draw_straight_rail_input(layout)
|
||||
layout.separator()
|
||||
layout.label(text = 'Rail Cap')
|
||||
self.draw_rail_cap_input(layout)
|
||||
|
||||
class BBP_OT_add_arc_rail(SharedRailSectionInputProperty, SharedRailCapInputProperty, SharedScrewRailInputProperty, bpy.types.Operator):
|
||||
"""Add Arc Rail"""
|
||||
bl_idname = "bbp.add_arc_rail"
|
||||
bl_label = "Arc Rail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
rail_screw_angle: bpy.props.FloatProperty(
|
||||
name = "Angle",
|
||||
description = "The angle of this arc rail rotated.",
|
||||
default = math.radians(90),
|
||||
min = 0, max = math.radians(360),
|
||||
subtype = 'ANGLE',
|
||||
) # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_screw_rail(
|
||||
bm,
|
||||
self.general_get_is_monorail(), self.general_get_rail_radius(), self.general_get_rail_span(),
|
||||
self.general_get_is_monorail(), c_DefaultRailRadius, c_DefaultRailSpan,
|
||||
self.general_get_rail_start_cap(), self.general_get_rail_end_cap(),
|
||||
self.general_get_rail_screw_angle(True), self.general_get_rail_screw_screw(True), self.general_get_rail_screw_iterations(True),
|
||||
math.degrees(self.rail_screw_angle), 0, 1, # blender passed value is in radians
|
||||
self.general_get_rail_screw_steps(), self.general_get_rail_screw_radius()
|
||||
)
|
||||
)
|
||||
@ -294,11 +262,91 @@ class BBP_OT_add_screw_rail(SharedRailSectionInputProperty, SharedRailCapInputPr
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
self.draw_rail_section_input(layout, None)
|
||||
layout.label(text = 'Arc Rail')
|
||||
self.draw_rail_section_input(layout)
|
||||
self.draw_screw_rail_input(layout)
|
||||
layout.prop(self, "rail_screw_angle")
|
||||
layout.separator()
|
||||
layout.label(text = 'Rail Cap')
|
||||
self.draw_rail_cap_input(layout)
|
||||
|
||||
class BBP_OT_add_spiral_rail(SharedRailCapInputProperty, SharedScrewRailInputProperty, bpy.types.Operator):
|
||||
"""Add Spiral Rail"""
|
||||
bl_idname = "bbp.add_spiral_rail"
|
||||
bl_label = "Spiral Rail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
rail_screw_screw: bpy.props.FloatProperty(
|
||||
name = "Screw",
|
||||
description = "The increased height in each iteration. Minus height also is accepted.",
|
||||
default = c_SpiralRailScrew,
|
||||
unit = 'LENGTH'
|
||||
) # type: ignore
|
||||
|
||||
rail_screw_iterations: bpy.props.IntProperty(
|
||||
name = "Iterations",
|
||||
description = "Indicate how many layers of this spiral rail should be generated.",
|
||||
default = 1,
|
||||
min = 1,
|
||||
) # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_screw_rail(
|
||||
bm,
|
||||
False, c_DefaultRailRadius, c_DefaultRailSpan,
|
||||
self.general_get_rail_start_cap(), self.general_get_rail_end_cap(),
|
||||
360, self.rail_screw_screw, self.rail_screw_iterations,
|
||||
self.general_get_rail_screw_steps(), self.general_get_rail_screw_radius()
|
||||
)
|
||||
)
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text = 'Spiral Rail')
|
||||
self.draw_screw_rail_input(layout)
|
||||
layout.prop(self, "rail_screw_screw")
|
||||
layout.prop(self, "rail_screw_iterations")
|
||||
layout.separator()
|
||||
self.draw_screw_rail_input(layout, True)
|
||||
layout.label(text = 'Rail Cap')
|
||||
self.draw_rail_cap_input(layout)
|
||||
|
||||
class BBP_OT_add_side_spiral_rail(SharedRailSectionInputProperty, SharedRailCapInputProperty, SharedScrewRailInputProperty, bpy.types.Operator):
|
||||
"""Add Side Spiral Rail"""
|
||||
bl_idname = "bbp.add_side_spiral_rail"
|
||||
bl_label = "Side Spiral Rail"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
rail_screw_iterations: bpy.props.IntProperty(
|
||||
name = "Iterations",
|
||||
description = "Indicate how many layers of this spiral rail should be generated.",
|
||||
default = 2,
|
||||
# at least 2 ietrations can create 1 useful side spiral rail.
|
||||
# becuase side spiral rail is edge shared.
|
||||
min = 2,
|
||||
) # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
_rail_creator_wrapper(
|
||||
lambda bm: _create_screw_rail(
|
||||
bm,
|
||||
True, c_DefaultRailRadius, c_DefaultRailSpan,
|
||||
self.general_get_rail_start_cap(), self.general_get_rail_end_cap(),
|
||||
360, c_SideSpiralRailScrew, self.rail_screw_iterations,
|
||||
self.general_get_rail_screw_steps(), self.general_get_rail_screw_radius()
|
||||
)
|
||||
)
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text = 'Spiral Rail')
|
||||
self.draw_screw_rail_input(layout)
|
||||
layout.prop(self, "rail_screw_iterations")
|
||||
layout.separator()
|
||||
layout.label(text = 'Rail Cap')
|
||||
self.draw_rail_cap_input(layout)
|
||||
|
||||
#endregion
|
||||
|
||||
@ -333,6 +381,9 @@ def _bmesh_screw(
|
||||
start_verts: list[bmesh.types.BMVert], start_edges: list[bmesh.types.BMEdge],
|
||||
angle: float, steps: int, iterations: int,
|
||||
center: mathutils.Vector, screw_per_iteration: float) -> list[bmesh.types.BMEdge]:
|
||||
"""
|
||||
Hints: Angle is input as degree unit.
|
||||
"""
|
||||
# screw
|
||||
ret: dict[str, typing.Any] = bmesh.ops.spin(
|
||||
bm,
|
||||
@ -340,7 +391,7 @@ def _bmesh_screw(
|
||||
cent = center,
|
||||
axis = mathutils.Vector((0, 0, 1)), # default to +Z
|
||||
dvec = mathutils.Vector((0, 0, screw_per_iteration / steps)), # conv to step delta
|
||||
angle = angle * iterations,
|
||||
angle = math.radians(angle) * iterations,
|
||||
space = mathutils.Matrix.Identity(4),
|
||||
steps = steps * iterations,
|
||||
use_merge = False,
|
||||
@ -487,16 +538,29 @@ def _create_transition_section(
|
||||
def _create_straight_rail(
|
||||
bm: bmesh.types.BMesh,
|
||||
is_monorail: bool, rail_radius: float, rail_span: float,
|
||||
rail_length: float,
|
||||
rail_length: float, rail_angle: float,
|
||||
rail_start_cap: bool, rail_end_cap: bool) -> None:
|
||||
"""
|
||||
Add a straight rail.
|
||||
|
||||
The original point is same as `_add_rail_section()`.
|
||||
The start terminal of this straight will be placed in XZ panel.
|
||||
The expand direction is +Y.
|
||||
|
||||
If ordered is monorail, `rail_span` param will be ignored.
|
||||
|
||||
The rail angle is in degree unit and indicate how any angle this rail should rotated by its axis.
|
||||
It usually used to create side rail.
|
||||
"""
|
||||
# create section first
|
||||
_create_rail_section(bm, is_monorail, rail_radius, rail_span)
|
||||
_create_rail_section(
|
||||
bm, is_monorail, rail_radius, rail_span,
|
||||
mathutils.Matrix.LocRotScale(
|
||||
None,
|
||||
mathutils.Euler((0, math.radians(rail_angle), 0), 'XYZ'),
|
||||
None
|
||||
)
|
||||
)
|
||||
|
||||
# get start edges
|
||||
start_edges: list[bmesh.types.BMEdge] = bm.edges[:]
|
||||
@ -522,10 +586,14 @@ def _create_screw_rail(
|
||||
rail_screw_steps: int, rail_screw_radius: float) -> None:
|
||||
"""
|
||||
Add a screw rail.
|
||||
|
||||
The original point is same as `_add_rail_section()`.
|
||||
The start terminal of this straight will be placed in XZ panel.
|
||||
The expand direction is +Y.
|
||||
|
||||
If ordered is monorail, `rail_span` param will be ignored.
|
||||
|
||||
Angle is input as degree unit.
|
||||
"""
|
||||
# create section first
|
||||
_create_rail_section(bm, is_monorail, rail_radius, rail_span)
|
||||
@ -534,7 +602,7 @@ def _create_screw_rail(
|
||||
end_edges: list[bmesh.types.BMEdge] = _bmesh_screw(
|
||||
bm,
|
||||
bm.verts[:], start_edges,
|
||||
math.radians(rail_screw_angle),
|
||||
rail_screw_angle,
|
||||
rail_screw_steps, rail_screw_iterations,
|
||||
mathutils.Vector((rail_screw_radius, 0, 0)),
|
||||
rail_screw_screw
|
||||
@ -553,12 +621,22 @@ def _create_screw_rail(
|
||||
def register():
|
||||
bpy.utils.register_class(BBP_OT_add_rail_section)
|
||||
bpy.utils.register_class(BBP_OT_add_transition_section)
|
||||
|
||||
bpy.utils.register_class(BBP_OT_add_straight_rail)
|
||||
bpy.utils.register_class(BBP_OT_add_screw_rail)
|
||||
bpy.utils.register_class(BBP_OT_add_side_rail)
|
||||
|
||||
bpy.utils.register_class(BBP_OT_add_arc_rail)
|
||||
bpy.utils.register_class(BBP_OT_add_spiral_rail)
|
||||
bpy.utils.register_class(BBP_OT_add_side_spiral_rail)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(BBP_OT_add_screw_rail)
|
||||
bpy.utils.unregister_class(BBP_OT_add_side_spiral_rail)
|
||||
bpy.utils.unregister_class(BBP_OT_add_spiral_rail)
|
||||
bpy.utils.unregister_class(BBP_OT_add_arc_rail)
|
||||
|
||||
bpy.utils.unregister_class(BBP_OT_add_side_rail)
|
||||
bpy.utils.unregister_class(BBP_OT_add_straight_rail)
|
||||
|
||||
bpy.utils.unregister_class(BBP_OT_add_transition_section)
|
||||
bpy.utils.unregister_class(BBP_OT_add_rail_section)
|
||||
|
@ -73,14 +73,20 @@ class BBP_MT_AddRailMenu(bpy.types.Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.label(text = "Sections")
|
||||
layout.label(text = "Sections", icon = 'MESH_CIRCLE')
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_rail_section.bl_idname)
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_transition_section.bl_idname)
|
||||
|
||||
layout.separator()
|
||||
layout.label(text = "Rails")
|
||||
layout.label(text = "Straight Rails", icon = 'IPO_CONSTANT')
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_straight_rail.bl_idname)
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_screw_rail.bl_idname)
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_side_rail.bl_idname)
|
||||
|
||||
layout.separator()
|
||||
layout.label(text = "Curve Rails", icon = 'MOD_SCREW')
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_arc_rail.bl_idname)
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_spiral_rail.bl_idname)
|
||||
layout.operator(OP_ADDS_rail.BBP_OT_add_side_spiral_rail.bl_idname)
|
||||
|
||||
class BBP_MT_AddComponentsMenu(bpy.types.Menu):
|
||||
"""Add Ballance Components"""
|
||||
|
Loading…
Reference in New Issue
Block a user