diff --git a/nodes/__init__.py b/nodes/__init__.py index 604ba5b..f9ed9d4 100644 --- a/nodes/__init__.py +++ b/nodes/__init__.py @@ -4,6 +4,7 @@ from .debug import NODE_CLASS_MAPPINGS as ncm0, NODE_DISPLAY_NAME_MAPPINGS as nd from .entangled import NODE_CLASS_MAPPINGS as ncm1, NODE_DISPLAY_NAME_MAPPINGS as ndnm1 from .schedule import NODE_CLASS_MAPPINGS as ncm2, NODE_DISPLAY_NAME_MAPPINGS as ndnm2 from .sinusoidal import NODE_CLASS_MAPPINGS as ncm3, NODE_DISPLAY_NAME_MAPPINGS as ndnm3 +from .pgroup import NODE_CLASS_MAPPINGS as ncm4, NODE_DISPLAY_NAME_MAPPINGS as ndnm4 # there's probably a cleaner, more-dummy-proof way to do this. @@ -12,10 +13,12 @@ NODE_CLASS_MAPPINGS.update(ncm0) NODE_CLASS_MAPPINGS.update(ncm1) NODE_CLASS_MAPPINGS.update(ncm2) NODE_CLASS_MAPPINGS.update(ncm3) +NODE_CLASS_MAPPINGS.update(ncm4) NODE_DISPLAY_NAME_MAPPINGS.update(ndnm0) NODE_DISPLAY_NAME_MAPPINGS.update(ndnm1) NODE_DISPLAY_NAME_MAPPINGS.update(ndnm2) NODE_DISPLAY_NAME_MAPPINGS.update(ndnm3) +NODE_DISPLAY_NAME_MAPPINGS.update(ndnm4) __all__ =["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] \ No newline at end of file diff --git a/nodes/core.py b/nodes/core.py index d9272a1..0d42ade 100644 --- a/nodes/core.py +++ b/nodes/core.py @@ -248,6 +248,42 @@ class KfConditioningAddx10: return [((cond_t_out, cond_d_out),)] #((cond_t_out, cond_d_out),) + +class KfConditioningAddx10_alt: + CATEGORY = CATEGORY + FUNCTION = "main" + RETURN_TYPES = ("CONDITIONING",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "cond_0": ("CONDITIONING",{"forceInput": True,}), + }, + "optional": { + "cond_1": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_2": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_3": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_4": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_5": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_6": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_7": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_8": ("CONDITIONING",{"forceInput": True, "default": 0}), + "cond_9": ("CONDITIONING",{"forceInput": True, "default": 0}), + }, + } + + def main(self, cond_0, **kwargs): + ((cond_t_out, cond_d_out),) = deepcopy(cond_0) + for v in kwargs.values(): + if v not in (0, None): + ((cond_t,cond_d),) = v + cond_t, cond_d = deepcopy(cond_t), deepcopy(cond_d) + cond_t_out = cond_t_out + cond_t + cond_d_out["pooled_output"] = cond_d_out["pooled_output"] + cond_d["pooled_output"] + return [((cond_t_out, cond_d_out),)] #((cond_t_out, cond_d_out),) + + # class KfCurveInverse: # CATEGORY = CATEGORY # FUNCTION = "main" @@ -270,7 +306,7 @@ class KfConditioningAddx10: # return (curve,) -def plot_curve(curve, n): +def plot_curve(curve, n, is_pgroup=False): """ """ @@ -313,7 +349,8 @@ def plot_curve(curve, n): kfy = [curve[x] for x in kfx] plt.scatter(kfx, kfy, color=line[0].get_color()) - if isinstance(curve, kf.ParameterGroup): + #if isinstance(curve, kf.ParameterGroup): # type collision with kf.Composition + if is_pgroup: for c in curve.parameters.values(): draw_curve(c) else: @@ -360,7 +397,7 @@ class KfCurveDraw: } def main(self, curve, n): - img_tensor = plot_curve(curve, n) + img_tensor = plot_curve(curve, n, is_pgroup=False) return (img_tensor,) class KfPGroupDraw: @@ -378,7 +415,7 @@ class KfPGroupDraw: } def main(self, parameter_group, n): - img_tensor = plot_curve(parameter_group, n) + img_tensor = plot_curve(parameter_group, n, is_pgroup=True) return (img_tensor,) ########################################### @@ -429,7 +466,7 @@ class KfCurvesAddx10: }, } - def main(self, curve_0, curve_1, curve_2, curve_3, curve_4, curve_5, curve_6, curve_7, curve_8, curve_9): + def main(self, curve_0=0, curve_1=0, curve_2=0, curve_3=0, curve_4=0, curve_5=0, curve_6=0, curve_7=0, curve_8=0, curve_9=0): #curve_1 = deepcopy(curve_1) #curve_2 = deepcopy(curve_2) #return (curve_1 + curve_2, ) @@ -499,15 +536,15 @@ class KfCurvesMultiplyx10: "curve_0": ("KEYFRAMED_CURVE",{"forceInput": True,}), }, "optional": { - "curve_1": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_2": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_3": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_4": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_5": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_6": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_7": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_8": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), - "curve_9": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 0}), + "curve_1": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_2": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_3": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_4": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_5": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_6": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_7": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_8": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), + "curve_9": ("KEYFRAMED_CURVE",{"forceInput": True, "default": 1}), }, } @@ -570,148 +607,6 @@ class KfCurveConstant: ################################################################## -### TODO: Working with parameter groups - -# add curve(s) to parameter group -## inputs: pgroup, curve -## returns pgroup -## if pgroup not provided, new one created - -class KfAddCurveToPGroup: - CATEGORY = CATEGORY - FUNCTION = "main" - #RETURN_TYPES = ("KEYFRAMED_CURVE",) - RETURN_TYPES = ("PARAMETER_GROUP",) - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "curve": ("KEYFRAMED_CURVE",{"forceInput": True,}), - }, - "optional": { - "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), - }, - } - - def main(self, curve, parameter_group=None): - curve = deepcopy(curve) - if parameter_group is None: - #parameter_group = kf.ParameterGroup({curve.label:curve}) - parameter_group = kf.ParameterGroup([curve]) - else: - parameter_group = deepcopy(parameter_group) - parameter_group.parameters[curve.label] = curve - return (parameter_group,) - -class KfAddCurveToPGroupx10: - CATEGORY = CATEGORY - FUNCTION = "main" - #RETURN_TYPES = ("KEYFRAMED_CURVE",) - RETURN_TYPES = ("PARAMETER_GROUP",) - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "curve0": ("KEYFRAMED_CURVE",{"forceInput": True,}), - }, - "optional": { - "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), - "curve1": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve2": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve3": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve4": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve5": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve6": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve7": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve8": ("KEYFRAMED_CURVE",{"forceInput": True,}), - "curve9": ("KEYFRAMED_CURVE",{"forceInput": True,}), - }, - } - - def main(self, parameter_group=None, **kwargs): - if parameter_group is None: - #parameter_group = kf.ParameterGroup({curve.label:curve}) - parameter_group = kf.ParameterGroup(kwargs) - else: - parameter_group = deepcopy(parameter_group) - for curve in parameter_group.values(): - parameter_group.parameters[curve.label] = curve - return (parameter_group,) - - -class KfGetCurveFromPGroup: - CATEGORY = CATEGORY - FUNCTION = "main" - RETURN_TYPES = ("KEYFRAMED_CURVE",) - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "curve_label": ("STRING",{"default": "My Curve",}), - "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), - }, - } - - def main(self, curve_label, parameter_group): - curve = parameter_group.parameters[curve_label] - return (deepcopy(curve),) - - -# get curve from parameter group -## inputs: pgroup, label -## returns curve - -# extract a time slice from the parameter group - - -################################################################## - -# Curve vs. PGroup Arithmetic - -class KfPGroupCurveAdd: - CATEGORY = CATEGORY - FUNCTION = "main" - RETURN_TYPES = ("PARAMETER_GROUP",) - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), - "curve": ("KEYFRAMED_CURVE",{"forceInput": True,}), - }, - } - - def main(self, parameter_group, curve): - parameter_group = deepcopy(parameter_group) - curve = deepcopy(curve) - return (parameter_group + curve, ) - - -class KfPGroupCurveMultiply: - CATEGORY = CATEGORY - FUNCTION = "main" - RETURN_TYPES = ("PARAMETER_GROUP",) - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), - "curve": ("KEYFRAMED_CURVE",{"forceInput": True,}), - }, - } - - def main(self, parameter_group, curve): - parameter_group = deepcopy(parameter_group) - curve = deepcopy(curve) - return (parameter_group * curve, ) - -################################################################## - # KfScheduleConditions: # """ @@ -741,18 +636,14 @@ NODE_CLASS_MAPPINGS = { "KfApplyCurveToCond": KfApplyCurveToCond, "KfConditioningAdd": KfConditioningAdd, ####################################### - "KfAddCurveToPGroup": KfAddCurveToPGroup, - "KfGetCurveFromPGroup": KfGetCurveFromPGroup, - "KfAddCurveToPGroupx10": KfAddCurveToPGroupx10, - ####################################### - "KfPGroupCurveAdd":KfPGroupCurveAdd, - "KfPGroupCurveMultiply":KfPGroupCurveMultiply, + "KfCurveDraw": KfCurveDraw, + "KfPGroupDraw": KfPGroupDraw, + "KfSetCurveLabel":KfSetCurveLabel, ####################################### #"KfCurveToAcnLatentKeyframe": KfCurveToAcnLatentKeyframe, ####################################### #"KfCurveInverse": KfCurveInverse, - "KfCurveDraw": KfCurveDraw, - "KfPGroupDraw": KfPGroupDraw, + "KfCurvesAdd": KfCurvesAdd, "KfCurvesSubtract": KfCurvesSubtract, "KfCurvesMultiply": KfCurvesMultiply, diff --git a/nodes/pgroup.py b/nodes/pgroup.py new file mode 100644 index 0000000..41bee83 --- /dev/null +++ b/nodes/pgroup.py @@ -0,0 +1,211 @@ +import keyframed as kf +import logging +from copy import deepcopy + +logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') +logger = logging.getLogger(__name__) + + +CATEGORY = "keyframed/parameter group" + + +class KfAddCurveToPGroup: + CATEGORY = CATEGORY + FUNCTION = "main" + #RETURN_TYPES = ("KEYFRAMED_CURVE",) + RETURN_TYPES = ("PARAMETER_GROUP",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "curve": ("KEYFRAMED_CURVE",{"forceInput": True,}), + }, + "optional": { + "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), + }, + } + + def main(self, curve, parameter_group=None): + curve = deepcopy(curve) + if parameter_group is None: + #parameter_group = kf.ParameterGroup({curve.label:curve}) + parameter_group = kf.ParameterGroup([curve]) + else: + parameter_group = deepcopy(parameter_group) + parameter_group.parameters[curve.label] = curve + return (parameter_group,) + +class KfAddCurveToPGroupx10: + CATEGORY = CATEGORY + FUNCTION = "main" + #RETURN_TYPES = ("KEYFRAMED_CURVE",) + RETURN_TYPES = ("PARAMETER_GROUP",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "curve0": ("KEYFRAMED_CURVE",{"forceInput": True,}), + }, + "optional": { + "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), + "curve1": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve2": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve3": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve4": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve5": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve6": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve7": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve8": ("KEYFRAMED_CURVE",{"forceInput": True,}), + "curve9": ("KEYFRAMED_CURVE",{"forceInput": True,}), + }, + } + + def main(self, parameter_group=None, **kwargs): + if parameter_group is None: + #parameter_group = kf.ParameterGroup({curve.label:curve}) + parameter_group = kf.ParameterGroup(kwargs) + else: + parameter_group = deepcopy(parameter_group) + for curve in parameter_group.values(): + parameter_group.parameters[curve.label] = curve + return (parameter_group,) + + +class KfGetCurveFromPGroup: + CATEGORY = CATEGORY + FUNCTION = "main" + RETURN_TYPES = ("KEYFRAMED_CURVE",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "curve_label": ("STRING",{"default": "My Curve",}), + "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), + }, + } + + def main(self, curve_label, parameter_group): + curve = parameter_group.parameters[curve_label] + return (deepcopy(curve),) + + +################################################################## + +# PGroup Arithmetic + +class KfPGroupCurveAdd: + CATEGORY = CATEGORY + FUNCTION = "main" + RETURN_TYPES = ("PARAMETER_GROUP",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), + "curve": ("KEYFRAMED_CURVE",{"forceInput": True,}), + }, + } + + def main(self, parameter_group, curve): + parameter_group = deepcopy(parameter_group) + curve = deepcopy(curve) + return (parameter_group + curve, ) + + +class KfPGroupCurveMultiply: + CATEGORY = CATEGORY + FUNCTION = "main" + RETURN_TYPES = ("PARAMETER_GROUP",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), + "curve": ("KEYFRAMED_CURVE",{"forceInput": True,}), + }, + } + + def main(self, parameter_group, curve): + parameter_group = deepcopy(parameter_group) + curve = deepcopy(curve) + return (parameter_group * curve, ) + + +# not behaving as expected :( + +class KfPGroupSum: + #CATEGORY = CATEGORY + CATEGORY = "keyframed/experimental" + FUNCTION = "main" + RETURN_TYPES = ("KEYFRAMED_CURVE",) + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), + }, + } + + def main(self, parameter_group): + parameter_group = deepcopy(parameter_group) + #curve = kf.Composition(parameter_group, reduction='sum') + #curve = sum(parameter_group.parameters.values()) + outv = kf.Curve(0) + for curve in parameter_group.parameters.values(): + outv += curve + return (outv,) + #return (curve,) + + +class KfPGroupProd: + pass +# CATEGORY = CATEGORY +# FUNCTION = "main" +# RETURN_TYPES = ("KEYFRAMED_CURVE",) + +# @classmethod +# def INPUT_TYPES(s): +# return { +# "required": { +# "parameter_group": ("PARAMETER_GROUP",{"forceInput": True,}), +# }, +# } + +# def main(self, parameter_group): +# parameter_group = deepcopy(parameter_group) +# curve = kf.Composition(parameter_group, reduction='prod') +# return (curve,) + +################################################################## + +NODE_CLASS_MAPPINGS = { + #"KfCurveDraw": KfCurveDraw, + #"KfPGroupDraw": KfPGroupDraw, + #"KfSetCurveLabel":KfSetCurveLabel, + "KfAddCurveToPGroup": KfAddCurveToPGroup, + "KfGetCurveFromPGroup": KfGetCurveFromPGroup, + "KfAddCurveToPGroupx10": KfAddCurveToPGroupx10, + "KfPGroupCurveAdd":KfPGroupCurveAdd, + "KfPGroupCurveMultiply":KfPGroupCurveMultiply, + "KfPGroupSum": KfPGroupSum, + "KfPGroupProd": KfPGroupProd, +} + +# A dictionary that contains the friendly/humanly readable titles for the nodes +NODE_DISPLAY_NAME_MAPPINGS = { + #"KfSetCurveLabel": "Set Curve Label", + "KfAddCurveToPGroup": "Add Curve To Parameter Group", + "KfGetCurveFromPGroup": "Get Curve From Parameter Group", + "KfAddCurveToPGroupx10": "Add Curve To Parameter Group (x10)", + "KfPGroupCurveAdd": "Parameter Group + Curve (addition)", + "KfPGroupCurveMultiply": "Parameter Group * Curve (multiply)", + "KfPGroupSum": "Sum Over Parameter Group", + "KfPGroupProd": "Product Over Parameter Group", +} \ No newline at end of file