diff --git a/api/static/input_options.py b/api/static/input_options.py new file mode 100644 index 0000000..aff4ac6 --- /dev/null +++ b/api/static/input_options.py @@ -0,0 +1,62 @@ +import enum + +class SubtypeInt(enum.Enum): + NONE = 'None' + PERCENTAGE = 'Percentage' + FACTOR = 'Factor' + +class SubtypeFloat(enum.Enum): + NONE = 'None' + PERCENTAGE = 'Percentage' + FACTOR = 'Factor' + ANGLE = 'Angle' + TIME = 'Time (Scene Relative)' + TIME_ABSOLUTE = 'Time (Absolute)' + DISTANCE = 'Distance' + +class InputOptions: + """Input options parent class""" + +class IntOptions(InputOptions): + MAX = 2147483647 + MIN = -MAX -1 + + def __init__( + self, + default: int | None = None, + min: int | None = None, + max: int | None = None, + subtype: SubtypeInt | None = None, + name: str | None = None, + tooltip: str = None, + hide_in_modifier: bool = None, + ): + self.default_value = default + self.min_value = min + self.max_value = max + self.bl_subtype_label = subtype.value if subtype != None else None + self.name = name + self.description = tooltip + self.hide_in_modifier = hide_in_modifier + +class FloatOptions(InputOptions): + MAX = float('inf') + MIN = float('-inf') + + def __init__( + self, + default: float | None = None, + min: float | None = None, + max: float | None = None, + subtype: SubtypeFloat | None = None, + name: str | None = None, + tooltip: str = None, + hide_in_modifier: bool = None, + ): + self.default_value = default + self.min_value = min + self.max_value = max + self.bl_subtype_label = subtype.value if subtype != None else None + self.name = name + self.description = tooltip + self.hide_in_modifier = hide_in_modifier \ No newline at end of file diff --git a/api/tree.py b/api/tree.py index cad1c4c..3e79563 100644 --- a/api/tree.py +++ b/api/tree.py @@ -11,6 +11,7 @@ from .static.attribute import * from .static.curve import * from .static.expression import * from .static.input_group import * +from .static.input_options import * from .static.repeat import * from .static.sample_mode import * from .static.simulation import * @@ -106,10 +107,13 @@ def tree(name): node_inputs = get_node_inputs(node_group) for i, arg in enumerate(inputs.items()): - if hasattr(arg[1][0], 'input_options') and arg[1][0].input_options.name != None: - input_name = arg[1][0].input_options.name + if (arg[1][1] != inspect.Parameter.empty + and (isinstance(arg[1][1], IntOptions) or isinstance(arg[1][1], FloatOptions)) + and arg[1][1].name != None): + input_name = arg[1][1].name else: input_name = arg[0].replace('_', ' ').title() + if len(node_inputs) > i: node_inputs[i].name = input_name node_input = node_inputs[i] @@ -118,26 +122,39 @@ def tree(name): node_input = node_group.interface.new_socket(socket_type=arg[1][0].socket_type, name=input_name, in_out='INPUT') else: node_input = node_group.inputs.new(arg[1][0].socket_type, input_name) + if arg[1][1] != inspect.Parameter.empty: - node_input.default_value = arg[1][1] - if hasattr(arg[1][0], 'input_options'): - input_options = arg[1][0].input_options - input_options.process(node_input.type) - node_input.min_value = input_options.min_value - node_input.max_value = input_options.max_value - # node_input.bl_subtype_label = input_options.bl_subtype_label # DOES NOT WORK. Do e nee to change a UI property like this: ui_property(object, "property-name", expand=False, text="New Label") - node_input.description = input_options.description - node_input.hide_in_modifier = input_options.hide_in_modifier - else: - # reset all options to defaults ??????? - pass - # input_options = InputOptions() - # input_options.process(node_input.type) - # node_input.min_value = input_options.min_value - # node_input.max_value = input_options.max_value - # node_input.bl_subtype_label = input_options.bl_subtype_label - # node_input.description = input_options.description - # node_input.hide_in_modifier = input_options.hide_in_modifier + if (isinstance(arg[1][1], IntOptions) or isinstance(arg[1][1], FloatOptions)) : + if arg[1][1].default_value != None: + node_input.default_value = arg[1][1].default_value + if arg[1][1].min_value != None: + node_input.min_value = arg[1][1].min_value + elif isinstance(arg[1][1], IntOptions): + node_input.min_value = IntOptions.MIN + elif isinstance(arg[1][1], FloatOptions): + node_input.min_value = FloatOptions.MIN + if arg[1][1].max_value != None: + node_input.max_value = arg[1][1].max_value + elif isinstance(arg[1][1], IntOptions): + node_input.max_value = IntOptions.MAX + elif isinstance(arg[1][1], FloatOptions): + node_input.max_value = FloatOptions.MAX + if arg[1][1].bl_subtype_label != None: + # node_input.bl_subtype_label = arg[1][1].bl_subtype_label # broken + # TODO: run operator to change this + pass + if arg[1][1].description != None: + node_input.description = arg[1][1].description + if arg[1][1].hide_in_modifier != None: + node_input.hide_in_modifier = arg[1][1].hide_in_modifier + else: + node_input.default_value = arg[1][1] + if isinstance(arg[1][1], int): + node_input.min_value = IntOptions.MIN + node_input.max_value = IntOptions.MAX + elif isinstance(arg[1][1], float): + node_input.min_value = FloatOptions.MIN + node_input.max_value = FloatOptions.MAX if arg[1][2] is not None: if arg[1][2] not in builder_inputs: diff --git a/api/types.py b/api/types.py index 3a02153..4f577c8 100644 --- a/api/types.py +++ b/api/types.py @@ -6,71 +6,6 @@ from .state import State from .static.sample_mode import SampleMode import geometry_script -INT_MAX = 2147483647 -INT_MIN = -INT_MAX -1 - -class SubtypeInt(enum.Enum): - NONE = 'None' - PERCENTAGE = 'Percentage' - FACTOR = 'Factor' - -class SubtypeFloat(enum.Enum): - NONE = 'None' - PERCENTAGE = 'Percentage' - FACTOR = 'Factor' - ANGLE = 'Angle' - TIME = 'Time (Scene Relative)' - TIME_ABSOLUTE = 'Time (Absolute)' - DISTANCE = 'Distance' - -class InputOptions: - min_value: int | float - max_value: int | float - bl_subtype_label: str - name: str - description: str - hide_in_modifier: bool - - def __init__( - self, - min: int | float | None = None, - max: int | float | None = None, - subtype: SubtypeInt | SubtypeFloat | None = None, - name: str | None = None, - tooltip: str = '', - hide_in_modifier: bool = False - ): - self.min_value = min - self.max_value = max - self.bl_subtype_label = subtype.value if subtype != None else None - self.name = name - self.description = tooltip - self.hide_in_modifier = hide_in_modifier - - def process(self, node_input_type: str): - if node_input_type == 'INT': - if self.min_value != None and self.max_value == None: - self.max_value = INT_MAX - if self.max_value != None and self.min_value == None: - self.min_value = INT_MIN - if isinstance(self.min_value, float): - self.min_value = int(self.min_value) - if isinstance(self.max_value, float): - self.max_value = int(self.max_value) - if self.bl_subtype_label == None: - self.bl_subtype_label = SubtypeInt.NONE - elif node_input_type == 'VALUE': - if self.min_value != None and self.max_value == None: - self.max_value = float('inf') - if self.max_value != None and self.min_value == None: - self.min_value = float('-inf') - if isinstance(self.min_value, int): - self.min_value = float(self.min_value) - if isinstance(self.max_value, int): - self.max_value = float(self.max_value) - if self.bl_subtype_label == None: - self.bl_subtype_label = SubtypeFloat.NONE - def map_case_name(i): return ('_' if not i.identifier[0].isalpha() else '') + i.identifier.replace(' ', '_').upper() @@ -94,37 +29,7 @@ def socket_class_to_data_type(socket_class_name): case _: return socket_class_name -# The base class all exposed socket types conform to. -class _TypeMeta(type): - def __getitem__(self, args): - input_options = None - if isinstance(args, int) or isinstance(args, float): - input_options = InputOptions(min=args) - elif isinstance(args, tuple): - tuple_args = {} - if isinstance(args[0], int) or isinstance(args[0], float): - tuple_args['min'] = args[0] - if len(args) > 1 and (isinstance(args[1], int) or isinstance(args[1], float)): - tuple_args['max'] = args[1] - if len(tuple_args) > 0: - input_options = InputOptions(**tuple_args) - elif isinstance(args, slice): - slice_args = {} - if isinstance(args.start, int) or isinstance(args.start, float): - slice_args['min'] = args.start - if isinstance(args.stop, int) or isinstance(args.stop, float): - slice_args['max'] = args.stop - if len(slice_args) > 0: - input_options = InputOptions(**slice_args) - elif isinstance(args, InputOptions): - input_options = args - - if input_options != None: - setattr(self, 'input_options', input_options) - - return self - -class Type(metaclass=_TypeMeta): +class Type: socket_type: str def __init__(self, socket: bpy.types.NodeSocket = None, value = None):