2023-12-09 17:42:03 +08:00
import bpy , mathutils
import math , typing
2023-12-07 21:28:23 +08:00
from . import UTIL_functions , UTIL_icons_manager , UTIL_naming_convension
from . import PROP_ballance_element , PROP_virtools_group
2023-12-06 17:16:31 +08:00
2023-12-09 17:42:03 +08:00
#region Param Help Classes
class ComponentSectorParam ( ) :
component_sector : bpy . props . IntProperty (
name = " Sector " ,
description = " Define which sector the object will be grouped in " ,
min = 1 , max = 999 ,
soft_min = 1 , soft_max = 8 ,
default = 1 ,
2024-02-11 17:11:05 +08:00
) # type: ignore
2023-12-09 17:42:03 +08:00
def general_get_component_sector ( self ) - > int :
return self . component_sector
def draw_component_sector_params ( self , layout : bpy . types . UILayout ) - > None :
layout . prop ( self , ' component_sector ' )
class ComponentCountParam ( ) :
component_count : bpy . props . IntProperty (
name = " Count " ,
description = " The count of components you want to generate " ,
min = 1 , max = 64 ,
soft_min = 1 , soft_max = 32 ,
default = 1 ,
2024-02-11 17:11:05 +08:00
) # type: ignore
2023-12-09 17:42:03 +08:00
def general_get_component_count ( self ) - > int :
return self . component_count
def draw_component_count_params ( self , layout : bpy . types . UILayout ) - > None :
layout . prop ( self , ' component_count ' )
#endregion
2023-12-07 21:28:23 +08:00
#region Help Classes & Functions
2023-12-06 17:16:31 +08:00
2023-12-07 21:28:23 +08:00
def _get_component_info ( comp_type : PROP_ballance_element . BallanceElementType , comp_sector : int ) - > UTIL_naming_convension . BallanceObjectInfo :
match ( comp_type ) :
2023-12-09 17:42:03 +08:00
# process for 2 special unique components
2023-12-07 21:28:23 +08:00
case PROP_ballance_element . BallanceElementType . PS_FourFlames :
return UTIL_naming_convension . BallanceObjectInfo . create_from_others ( UTIL_naming_convension . BallanceObjectType . LEVEL_START )
case PROP_ballance_element . BallanceElementType . PE_Balloon :
return UTIL_naming_convension . BallanceObjectInfo . create_from_others ( UTIL_naming_convension . BallanceObjectType . LEVEL_END )
# process naming convention required special components
case PROP_ballance_element . BallanceElementType . PC_TwoFlames :
return UTIL_naming_convension . BallanceObjectInfo . create_from_checkpoint ( comp_sector )
case PROP_ballance_element . BallanceElementType . PR_Resetpoint :
return UTIL_naming_convension . BallanceObjectInfo . create_from_resetpoint ( comp_sector )
# process for other components
case _ :
2023-12-09 17:42:03 +08:00
return UTIL_naming_convension . BallanceObjectInfo . create_from_component (
PROP_ballance_element . get_ballance_element_name ( comp_type ) ,
comp_sector
)
2023-12-07 21:28:23 +08:00
def _set_component_by_info ( obj : bpy . types . Object , info : UTIL_naming_convension . BallanceObjectInfo ) - > None :
# set component name and grouping it into virtools group at the same time
# set name first
if not UTIL_naming_convension . YYCToolchainConvention . set_to_object ( obj , info , None ) :
raise UTIL_functions . BBPException ( ' impossible fail to set component name. ' )
# set vt group next
if not UTIL_naming_convension . VirtoolsGroupConvention . set_to_object ( obj , info , None ) :
raise UTIL_functions . BBPException ( ' impossible fail to set component virtools groups. ' )
def _check_component_existance ( comp_type : PROP_ballance_element . BallanceElementType , comp_sector : int ) - > str | None :
"""
Check the existance of 4 special components name , PS , PE , PC , PR
These 4 components will have special name .
@return Return name if selected component is one of PS , PE , PC , PR and there already is a name conflict , otherwise None .
"""
# check component type requirements
match ( comp_type ) :
case PROP_ballance_element . BallanceElementType . PS_FourFlames | PROP_ballance_element . BallanceElementType . PE_Balloon | PROP_ballance_element . BallanceElementType . PC_TwoFlames | PROP_ballance_element . BallanceElementType . PR_Resetpoint :
pass # exit match and start check
case _ :
return None # return, do not check
# get info
comp_info : UTIL_naming_convension . BallanceObjectInfo = _get_component_info ( comp_type , comp_sector )
# get expected name
expect_name : str | None = UTIL_naming_convension . YYCToolchainConvention . set_to_name ( comp_info , None )
if expect_name is None :
raise UTIL_functions . BBPException ( ' impossible fail to get component name. ' )
# check expected name
if expect_name in bpy . data . objects : return expect_name
else : return None
2024-02-11 17:11:05 +08:00
class _GeneralComponentCreator ( ) :
2023-12-09 17:42:03 +08:00
"""
2024-02-11 17:11:05 +08:00
The assist class for general component creation function .
Because we need select all created component , thus we need collect all created object into a list .
This is the reason why we create this class .
2023-12-09 17:42:03 +08:00
"""
2024-02-11 17:11:05 +08:00
## The list storing all created component within this creation.
__mObjList : list [ bpy . types . Object ]
def __init__ ( self ) :
self . __mObjList = [ ]
def create_component ( self ,
comp_type : PROP_ballance_element . BallanceElementType ,
comp_sector : int ,
comp_count : int ,
comp_offset : typing . Callable [ [ int ] , mathutils . Matrix ]
) - > None :
"""
General component creation function .
@param comp_type [ in ] The component type created .
@param comp_sector [ in ] The sector param which passed to other functions . For non - sector component , pass any number .
@param comp_count [ in ] The count of created component . For single component creation , please pass 1.
@param comp_offset [ in ] The function pointer which receive 1 argument indicating the index of object which we want to get its offset .
You can pass ` lambda _ : mathutils . Matrix . Identity ( 4 ) ` to get zero offset for every items .
You can pass ` lambda _ : mathutils . Matrix ( xxx ) ` to get same offset for every items .
You can pass ` lambda i : mathutils . Matrix ( func ( i ) ) ` to get index based offset for each items .
The offset is the offset to the origin point , not the previous object .
@return The created component instance .
"""
# get element info first
ele_info : UTIL_naming_convension . BallanceObjectInfo = _get_component_info ( comp_type , comp_sector )
# create blc element context
with PROP_ballance_element . BallanceElementsHelper ( bpy . context . scene ) as creator :
# object creation counter
for i in range ( comp_count ) :
# get mesh from element context, and create with empty name first. we assign name later.
obj : bpy . types . Object = bpy . data . objects . new ( ' ' , creator . get_element ( comp_type ) )
# assign virtools group, object name by we gotten element info.
_set_component_by_info ( obj , ele_info )
# add into scene and move to cursor
UTIL_functions . add_into_scene_and_move_to_cursor ( obj )
# move with extra offset by calling offset getter
obj . matrix_world = obj . matrix_world @ comp_offset ( i )
# put into created object list
self . __mObjList . append ( obj )
def finish_component ( self ) - > None :
"""
Finish up component creation .
Just deselect all objects and select all created components .
"""
UTIL_functions . select_certain_objects ( tuple ( self . __mObjList ) )
2023-12-07 21:28:23 +08:00
#endregion
2023-12-06 17:16:31 +08:00
2023-12-09 17:42:03 +08:00
#region Noemal Component Adder
2023-12-15 21:57:50 +08:00
# element enum prop helper
def _get_component_icon_by_name ( elename : str ) :
icon : int | None = UTIL_icons_manager . get_component_icon ( elename )
if icon is None : return UTIL_icons_manager . get_empty_icon ( )
else : return icon
_g_EnumHelper_Component : UTIL_functions . EnumPropHelper = UTIL_functions . EnumPropHelper (
PROP_ballance_element . BallanceElementType ,
2023-12-16 22:27:31 +08:00
lambda x : str ( x . value ) ,
lambda x : PROP_ballance_element . BallanceElementType ( int ( x ) ) ,
2023-12-15 21:57:50 +08:00
lambda x : x . name ,
lambda x : ' ' ,
lambda x : _get_component_icon_by_name ( PROP_ballance_element . get_ballance_element_name ( x ) ) ,
)
2023-12-09 17:42:03 +08:00
class BBP_OT_add_component ( bpy . types . Operator , ComponentSectorParam ) :
2023-12-07 21:28:23 +08:00
""" Add Component """
2023-12-06 17:16:31 +08:00
bl_idname = " bbp.add_component "
2023-12-07 21:28:23 +08:00
bl_label = " Add Component "
2023-12-06 17:16:31 +08:00
bl_options = { ' UNDO ' }
2023-12-07 21:28:23 +08:00
component_type : bpy . props . EnumProperty (
2023-12-06 17:16:31 +08:00
name = " Type " ,
2023-12-07 21:28:23 +08:00
description = " This component type " ,
2023-12-15 21:57:50 +08:00
items = _g_EnumHelper_Component . generate_items ( ) ,
2024-02-11 17:11:05 +08:00
) # type: ignore
2023-12-06 17:16:31 +08:00
def invoke ( self , context , event ) :
wm = context . window_manager
return wm . invoke_props_dialog ( self )
def draw ( self , context ) :
layout = self . layout
2023-12-07 21:28:23 +08:00
# show type
layout . prop ( self , " component_type " )
2023-12-06 17:16:31 +08:00
2023-12-07 21:28:23 +08:00
# only show sector for non-PE/PS component
2023-12-15 21:57:50 +08:00
eletype : PROP_ballance_element . BallanceElementType = _g_EnumHelper_Component . get_selection ( self . component_type )
2023-12-07 21:28:23 +08:00
if eletype != PROP_ballance_element . BallanceElementType . PS_FourFlames and eletype != PROP_ballance_element . BallanceElementType . PE_Balloon :
2023-12-09 17:42:03 +08:00
self . draw_component_sector_params ( layout )
2023-12-07 21:28:23 +08:00
# check for some special components and show warning
2023-12-15 21:57:50 +08:00
elename : str | None = _check_component_existance ( _g_EnumHelper_Component . get_selection ( self . component_type ) , self . general_get_component_sector ( ) )
2023-12-07 21:28:23 +08:00
if elename is not None :
layout . label ( text = f ' Warning: { elename } already exist. ' )
2023-12-06 17:16:31 +08:00
def execute ( self , context ) :
2023-12-09 17:42:03 +08:00
# call general creator
2024-02-11 17:11:05 +08:00
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
2023-12-15 21:57:50 +08:00
_g_EnumHelper_Component . get_selection ( self . component_type ) ,
2023-12-09 17:42:03 +08:00
self . general_get_component_sector ( ) ,
1 , # only create one
lambda _ : mathutils . Matrix . Identity ( 4 )
)
2024-02-11 17:11:05 +08:00
creator . finish_component ( )
2023-12-06 17:16:31 +08:00
return { ' FINISHED ' }
2023-12-15 21:57:50 +08:00
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
2023-12-06 17:16:31 +08:00
for item in PROP_ballance_element . BallanceElementType :
2023-12-09 17:42:03 +08:00
item_name : str = PROP_ballance_element . get_ballance_element_name ( item )
2023-12-06 17:16:31 +08:00
cop = layout . operator (
2023-12-15 21:57:50 +08:00
BBP_OT_add_component . bl_idname , text = item_name ,
2023-12-14 18:03:03 +08:00
icon_value = UTIL_icons_manager . get_component_icon ( item_name )
2023-12-09 17:42:03 +08:00
)
2023-12-15 21:57:50 +08:00
cop . component_type = _g_EnumHelper_Component . to_selection ( item )
2023-12-06 17:16:31 +08:00
2023-12-09 17:42:03 +08:00
#endregion
#region Nong Comp Adder
class BBP_OT_add_nong_extra_point ( bpy . types . Operator , ComponentSectorParam , ComponentCountParam ) :
""" Add Nong Extra Point """
bl_idname = " bbp.add_nong_extra_point "
bl_label = " Nong Extra Point "
bl_options = { ' REGISTER ' , ' UNDO ' }
def draw ( self , context ) :
layout = self . layout
self . draw_component_sector_params ( layout )
self . draw_component_count_params ( layout )
def execute ( self , context ) :
# create objects and rotate it by a certain degree calculated by its index
# calc percent first
percent : float = 1.0 / self . general_get_component_count ( )
# create elements
2024-02-11 17:11:05 +08:00
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . BallanceElementType . P_Extra_Point ,
self . general_get_component_sector ( ) ,
self . general_get_component_count ( ) ,
lambda i : mathutils . Matrix . Rotation ( percent * i * math . pi * 2 , 4 , ' Z ' )
)
2024-02-11 17:11:05 +08:00
creator . finish_component ( )
2023-12-09 17:42:03 +08:00
return { ' FINISHED ' }
2023-12-15 21:57:50 +08:00
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
2023-12-09 17:42:03 +08:00
layout . operator (
BBP_OT_add_nong_extra_point . bl_idname ,
2023-12-14 18:03:03 +08:00
icon_value = UTIL_icons_manager . get_component_icon (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . get_ballance_element_name ( PROP_ballance_element . BallanceElementType . P_Extra_Point )
)
)
2023-12-25 15:04:22 +08:00
class BBP_OT_add_nong_ventilator ( bpy . types . Operator , ComponentSectorParam , ComponentCountParam ) :
""" Add Nong Ventilator """
bl_idname = " bbp.add_nong_ventilator "
bl_label = " Nong Ventilator "
bl_options = { ' REGISTER ' , ' UNDO ' }
ventilator_count_source : bpy . props . EnumProperty (
name = " Ventilator Count Source " ,
2024-02-11 17:11:05 +08:00
items = [
2023-12-25 15:04:22 +08:00
( ' DEFINED ' , " Predefined " , " Pre-defined ventilator count. " ) ,
( ' CUSTOM ' , " Custom " , " User specified ventilator count. " ) ,
2024-02-11 17:11:05 +08:00
] ,
) # type: ignore
2023-12-25 15:04:22 +08:00
preset_vetilator_count : bpy . props . EnumProperty (
name = " Preset Count " ,
description = " Pick preset ventilator count. " ,
2024-02-11 17:11:05 +08:00
items = [
2023-12-25 15:04:22 +08:00
# (token, display name, descriptions, icon, index)
( ' PAPER ' , ' Paper ' , ' The ventilator count (1) can push paper ball up. ' ) ,
( ' WOOD ' , ' Wood ' , ' The ventilator count (6) can push wood ball up. ' ) ,
( ' STONE ' , ' Stone ' , ' The ventilator count (32) can push stone ball up. ' ) ,
2024-02-11 17:11:05 +08:00
] ,
) # type: ignore
2023-12-25 15:04:22 +08:00
def draw ( self , context ) :
layout = self . layout
# draw sector settings
self . draw_component_sector_params ( layout )
# draw count settings by different source
layout . label ( text = ' Count ' )
layout . prop ( self , ' ventilator_count_source ' , expand = True )
if ( self . ventilator_count_source == ' CUSTOM ' ) :
self . draw_component_count_params ( layout )
else :
layout . prop ( self , ' preset_vetilator_count ' )
def execute ( self , context ) :
# get ventilator count
count : int = 0
if ( self . ventilator_count_source == ' CUSTOM ' ) :
count = self . general_get_component_count ( )
else :
match ( self . preset_vetilator_count ) :
case ' PAPER ' : count = 1
case ' WOOD ' : count = 6
case ' STONE ' : count = 32
case _ : raise UTIL_functions . BBPException ( ' invalid enumprop data ' )
# create elements without any move
2024-02-11 17:11:05 +08:00
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
2023-12-25 15:04:22 +08:00
PROP_ballance_element . BallanceElementType . P_Modul_18 ,
self . general_get_component_sector ( ) ,
count ,
lambda _ : mathutils . Matrix . Identity ( 4 )
)
2024-02-11 17:11:05 +08:00
creator . finish_component ( )
2023-12-25 15:04:22 +08:00
return { ' FINISHED ' }
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
layout . operator (
BBP_OT_add_nong_ventilator . bl_idname ,
icon_value = UTIL_icons_manager . get_component_icon (
PROP_ballance_element . get_ballance_element_name ( PROP_ballance_element . BallanceElementType . P_Modul_18 )
)
)
2023-12-09 17:42:03 +08:00
#endregion
#region Series Comp Adder
class BBP_OT_add_tilting_block_series ( bpy . types . Operator , ComponentSectorParam , ComponentCountParam ) :
""" Add Tilting Block Series """
bl_idname = " bbp.add_tilting_block_series "
bl_label = " Tilting Block Series "
bl_options = { ' REGISTER ' , ' UNDO ' }
component_span : bpy . props . FloatProperty (
name = " Span " ,
description = " The distance between each titling blocks " ,
min = 0.0 , max = 100.0 ,
soft_min = 0.0 , soft_max = 12.0 ,
default = 6.0022 ,
2024-02-11 17:11:05 +08:00
) # type: ignore
2023-12-09 17:42:03 +08:00
def draw ( self , context ) :
layout = self . layout
self . draw_component_sector_params ( layout )
self . draw_component_count_params ( layout )
layout . prop ( self , ' component_span ' )
def execute ( self , context ) :
# create objects and move it by delta
# get span first
span : float = self . component_span
# create elements
2024-02-11 17:11:05 +08:00
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . BallanceElementType . P_Modul_41 ,
self . general_get_component_sector ( ) ,
self . general_get_component_count ( ) ,
lambda i : mathutils . Matrix . Translation ( mathutils . Vector ( ( span * i , 0.0 , 0.0 ) ) ) # move with extra delta in x axis
)
2024-02-11 17:11:05 +08:00
creator . finish_component ( )
2023-12-09 17:42:03 +08:00
return { ' FINISHED ' }
2023-12-15 21:57:50 +08:00
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
2023-12-09 17:42:03 +08:00
layout . operator (
BBP_OT_add_tilting_block_series . bl_idname ,
2023-12-14 18:03:03 +08:00
icon_value = UTIL_icons_manager . get_component_icon (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . get_ballance_element_name ( PROP_ballance_element . BallanceElementType . P_Modul_41 )
)
)
2024-02-18 22:11:06 +08:00
class BBP_OT_add_swing_series ( bpy . types . Operator , ComponentSectorParam , ComponentCountParam ) :
""" Add Swing Series """
bl_idname = " bbp.add_swing_series "
bl_label = " Swing Series "
bl_options = { ' REGISTER ' , ' UNDO ' }
component_span : bpy . props . FloatProperty (
name = " Span " ,
description = " The distance between each swing " ,
min = 0.0 , max = 100.0 ,
soft_min = 0.0 , soft_max = 30.0 ,
default = 15.0 ,
) # type: ignore
staggered_swing : bpy . props . BoolProperty (
name = ' Staggered ' ,
description = ' Whether place Swing staggered. Staggered Swing accept any ball however Non-Staggered Swing only accept Wood and Paper ball. ' ,
default = True
) # type: ignore
def draw ( self , context ) :
layout = self . layout
self . draw_component_sector_params ( layout )
self . draw_component_count_params ( layout )
layout . prop ( self , ' component_span ' )
layout . prop ( self , ' staggered_swing ' )
def execute ( self , context ) :
# create objects and move it by delta
# get span first
span : float = self . component_span
staggered : bool = self . staggered_swing
# create elements
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
PROP_ballance_element . BallanceElementType . P_Modul_08 ,
self . general_get_component_sector ( ) ,
self . general_get_component_count ( ) ,
lambda i : mathutils . Matrix . LocRotScale (
# move with extra delta in x axis
mathutils . Vector ( ( span * i , 0.0 , 0.0 ) ) ,
# and rotate 90 degree for even one if staggered placement.
mathutils . Euler ( ( 0 , 0 , math . radians ( 180 ) if ( staggered and ( i % 2 == 0 ) ) else 0 ) ) ,
None
)
)
creator . finish_component ( )
return { ' FINISHED ' }
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
layout . operator (
BBP_OT_add_swing_series . bl_idname ,
icon_value = UTIL_icons_manager . get_component_icon (
PROP_ballance_element . get_ballance_element_name ( PROP_ballance_element . BallanceElementType . P_Modul_08 )
)
)
2023-12-09 17:42:03 +08:00
class BBP_OT_add_ventilator_series ( bpy . types . Operator , ComponentSectorParam , ComponentCountParam ) :
""" Add Ventilator Series """
bl_idname = " bbp.add_ventilator_series "
bl_label = " Ventilator Series "
bl_options = { ' REGISTER ' , ' UNDO ' }
component_translation : bpy . props . FloatVectorProperty (
name = " Delta Vector " ,
description = " The translation between each ventilators. You can use this property to implement vertical or horizontal ventilator series. Set all factors to zero can get Nong ventilator. " ,
size = 3 , subtype = ' TRANSLATION ' ,
min = 0.0 , max = 100.0 ,
soft_min = 0.0 , soft_max = 50.0 ,
default = ( 0.0 , 0.0 , 15.0 ) ,
2024-02-11 17:11:05 +08:00
) # type: ignore
2023-12-09 17:42:03 +08:00
def draw ( self , context ) :
layout = self . layout
self . draw_component_sector_params ( layout )
self . draw_component_count_params ( layout )
layout . prop ( self , ' component_translation ' )
def execute ( self , context ) :
# create objects and move it by delta
# get translation first
translation : mathutils . Vector = mathutils . Vector ( self . component_translation )
# create elements
2024-02-11 17:11:05 +08:00
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . BallanceElementType . P_Modul_18 ,
self . general_get_component_sector ( ) ,
self . general_get_component_count ( ) ,
lambda i : mathutils . Matrix . Translation ( i * translation ) # move with extra translation
)
2024-02-11 17:11:05 +08:00
creator . finish_component ( )
2023-12-09 17:42:03 +08:00
return { ' FINISHED ' }
2023-12-15 21:57:50 +08:00
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
2023-12-09 17:42:03 +08:00
layout . operator (
BBP_OT_add_ventilator_series . bl_idname ,
2023-12-14 18:03:03 +08:00
icon_value = UTIL_icons_manager . get_component_icon (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . get_ballance_element_name ( PROP_ballance_element . BallanceElementType . P_Modul_18 )
)
)
#endregion
#region Comp Pair Adder
class BBP_OT_add_sector_component_pair ( bpy . types . Operator , ComponentSectorParam ) :
""" Add Sector Pair, both check point and reset point. """
bl_idname = " bbp.add_sector_component_pair "
bl_label = " Sector Pair "
bl_options = { ' UNDO ' }
def __get_checkpoint ( self ) - > tuple [ PROP_ballance_element . BallanceElementType , int ] :
if self . general_get_component_sector ( ) == 1 :
return ( PROP_ballance_element . BallanceElementType . PS_FourFlames , 1 )
else :
# the sector of two flames should be `sector - 1` because first one was occupied by FourFlams
return ( PROP_ballance_element . BallanceElementType . PC_TwoFlames , self . general_get_component_sector ( ) - 1 )
def __get_resetpoint ( self ) - > tuple [ PROP_ballance_element . BallanceElementType , int ] :
# resetpoint's sector is just sector it self.
return ( PROP_ballance_element . BallanceElementType . PR_Resetpoint , self . general_get_component_sector ( ) )
def invoke ( self , context , event ) :
wm = context . window_manager
return wm . invoke_props_dialog ( self )
def draw ( self , context ) :
layout = self . layout
self . draw_component_sector_params ( layout )
# check checkpoint and resetpoint name conflict and show warnings
( checkp_ty , checkp_sector ) = self . __get_checkpoint ( )
elename : str | None = _check_component_existance ( checkp_ty , checkp_sector )
if elename is not None :
layout . label ( text = f ' Warning: { elename } already exist. ' )
( resetp_ty , resetp_sector ) = self . __get_resetpoint ( )
elename = _check_component_existance ( resetp_ty , resetp_sector )
if elename is not None :
layout . label ( text = f ' Warning: { elename } already exist. ' )
def execute ( self , context ) :
# create checkpoint and resetpoint individually in element context
# get type and sector data first
( checkp_ty , checkp_sector ) = self . __get_checkpoint ( )
( resetp_ty , resetp_sector ) = self . __get_resetpoint ( )
# calc resetpoint offset
# resetpoint need a extra offset between checkpoint
# but it is different in FourFlams and TwoFlams
resetp_offset : float
if checkp_ty == PROP_ballance_element . BallanceElementType . PS_FourFlames :
resetp_offset = 3.25
else :
resetp_offset = 2.0
# add elements
# create checkpoint
2024-02-11 17:11:05 +08:00
creator : _GeneralComponentCreator = _GeneralComponentCreator ( )
creator . create_component (
2023-12-09 17:42:03 +08:00
checkp_ty ,
checkp_sector ,
1 , # only create one
lambda _ : mathutils . Matrix . Identity ( 4 )
)
# create resetpoint
2024-02-11 17:11:05 +08:00
creator . create_component (
2023-12-09 17:42:03 +08:00
resetp_ty ,
resetp_sector ,
1 , # only create one
lambda _ : mathutils . Matrix . Translation ( mathutils . Vector ( ( 0.0 , 0.0 , resetp_offset ) ) ) # apply resetpoint offset
)
2024-02-11 17:11:05 +08:00
creator . finish_component ( )
2023-12-09 17:42:03 +08:00
return { ' FINISHED ' }
2023-12-15 21:57:50 +08:00
@staticmethod
def draw_blc_menu ( layout : bpy . types . UILayout ) :
2023-12-09 17:42:03 +08:00
layout . operator (
BBP_OT_add_sector_component_pair . bl_idname ,
2023-12-14 18:03:03 +08:00
icon_value = UTIL_icons_manager . get_component_icon (
2023-12-09 17:42:03 +08:00
PROP_ballance_element . get_ballance_element_name ( PROP_ballance_element . BallanceElementType . PR_Resetpoint )
)
)
#endregion
2024-02-12 11:42:09 +08:00
def register ( ) - > None :
2023-12-06 17:16:31 +08:00
bpy . utils . register_class ( BBP_OT_add_component )
2023-12-09 17:42:03 +08:00
bpy . utils . register_class ( BBP_OT_add_nong_extra_point )
2023-12-25 15:04:22 +08:00
bpy . utils . register_class ( BBP_OT_add_nong_ventilator )
2023-12-09 17:42:03 +08:00
bpy . utils . register_class ( BBP_OT_add_tilting_block_series )
2024-02-18 22:11:06 +08:00
bpy . utils . register_class ( BBP_OT_add_swing_series )
2023-12-09 17:42:03 +08:00
bpy . utils . register_class ( BBP_OT_add_ventilator_series )
bpy . utils . register_class ( BBP_OT_add_sector_component_pair )
2023-12-06 17:16:31 +08:00
2024-02-12 11:42:09 +08:00
def unregister ( ) - > None :
2023-12-09 17:42:03 +08:00
bpy . utils . unregister_class ( BBP_OT_add_sector_component_pair )
bpy . utils . unregister_class ( BBP_OT_add_ventilator_series )
2024-02-18 22:11:06 +08:00
bpy . utils . unregister_class ( BBP_OT_add_swing_series )
2023-12-09 17:42:03 +08:00
bpy . utils . unregister_class ( BBP_OT_add_tilting_block_series )
2023-12-25 15:04:22 +08:00
bpy . utils . unregister_class ( BBP_OT_add_nong_ventilator )
2023-12-09 17:42:03 +08:00
bpy . utils . unregister_class ( BBP_OT_add_nong_extra_point )
2023-12-06 17:16:31 +08:00
bpy . utils . unregister_class ( BBP_OT_add_component )