Sverchok / SverchokRedux

A reimplementation of Sverchok
GNU General Public License v3.0
4 stars 2 forks source link

Value Nodes #19

Open ly29 opened 8 years ago

ly29 commented 8 years ago

Special nodes that can only have an input value.

skarmavbild 2015-12-10 kl 10 28 51

The rationale is simply bookkeeping, these nodes are once that are treated as external data, that should be exposed in the user interface in a similar fashion to the Sverchok panel in the 3d View.

To keep the interface clean and small the value is exposed in the socket.

Todo:

ly29 commented 8 years ago

@zeffii I know you wanted this, I also wish the could be more minimal.

zeffii commented 8 years ago

yeah.. let me dig up the mockup: https://github.com/nortikin/sverchok/issues/506, I think perhaps the need is more aesthetic than functional, as the 3dview panel kind of provided a workable alternative..

minus the input socket: and a slider instead :) image

ly29 commented 8 years ago

Also the float and int properties have been mixed up above... Oops.

zeffii commented 8 years ago

Does it make sense to make it possible to hotswap float_in to int_in or reverse. Maybe the type would be a property of the socket and not the node..


[ node name                  ]
------------------------------
[   [  1.0         ][enum]   ] 0-------------- socket

where enum might be a short identifier, [i, f, f3, f4, str]

ly29 commented 8 years ago

It could go either way, either we have two nodes for that or we have the hot swap code that changes the socket. I keep all values in sockets named default_value, which is consistent both within the system and also with the rest of blender.

ly29 commented 8 years ago

So it would be hot swapping socket instances, not hard but is is worth it if the number of input cases rise? I am not certain.

zeffii commented 8 years ago

see my update that the previous comment

zeffii commented 8 years ago

enum names like that would be consistent with openGL too..

ly29 commented 8 years ago

This is how works now..

The node definitions:

from ..svtyping import ValueFloat, ValueInterger

def int_in() -> [("Value", ValueInterger)]:
    pass

int_in.label = "Int input"

def float_in() -> [("Value", ValueFloat)]:
    pass

float_int.label = "Float input"

SvRxFunc = [float_in, int_in]

The types of inputs and outputs are matched to the right socket type, not everything is totally automatic, nor is there any need for it, but things could be changed around.


class ValueSocketBase(SvRxSocketBase):
    def draw(self, context, layout, node, text):
        if self.is_output:
            layout.prop(self, "default_value", text=text)
        else:
            pass

class SvRxIntValueSocket(bpy.types.NodeSocket, ValueSocketBase):
    """ For use with input nodes"""

    default_value = IntProperty(update=execute_tree)

    def draw_color(self, context, node):
        return NUMBER_SOCKET

class SvRxFloatValueSocket(bpy.types.NodeSocket, ValueSocketBase):
    """For use with input nodes"""

    default_value = FloatProperty(update=execute_tree)

    def draw_color(self, context, node):
        return NUMBER_SOCKET
ly29 commented 8 years ago

I am totally open for changing how it works but keep the name default_value for the property would be nice.

zeffii commented 8 years ago

should be fine, default_value is generic to make sense for all kinds of types

ly29 commented 8 years ago

I imagine that something like this could work.

class SvRxIntValueSocket(bpy.types.NodeSocket, SvRxSocketBase):
    """ For use with input nodes"""

    int_value = IntProperty()
    float_value = FloatProperty()
    mode_enum = EnmuProperty(...) # name matching the name of the property

    @property
    def default_value(self):
        return getattr(self, self.mode_enum)

    @default_value.setter
    def default_value(self):
        setattr(self, self.mode_enum, value)

    def draw_color(self, context, node):
        return NUMBER_SOCKET

    def draw(self, context, layout, node, text):
        if self.is_output:
            layout.prop(self, self.mode_enum, text=text)
        else:
            pass
ly29 commented 8 years ago

Alternatively just hot swap the socket and relink.

It could work for float, vector, color, string and integer and similar simple types that can be exposed via the python properties.

zeffii commented 8 years ago

there more I see this, the more I think.. can this be done less disjoint?

from ..svtyping import ValueFloat, ValueInterger
from ..svdecorators import node_label

@node_label("int input")
def int_in() -> [("Value", ValueInterger)]:
    pass

i'd consider a node_label decorator if it doesn't change all the signatures of the function..

zeffii commented 8 years ago

tho this is not immediately important.

ly29 commented 8 years ago

It is a ui issue and choice more than an implementation issue like the generics I trying to play with now.

Re node label, that can be done, the decorator will just have to preserve the metadata.

ly29 commented 8 years ago

Perhaps a decorater like below for setting any value.

@node_func(label="Int Input")
def int_in() -> [("Value", ValueInterger)]:
    pass
zeffii commented 8 years ago

Something to think about later :) but a generic @node_func of-course :)

ly29 commented 8 years ago

That could also do something clever to remove the SvRxFunc = [int_input] requirement

zeffii commented 8 years ago

don't want to further derail the thread here. best start a specific node declaration thread ?

ly29 commented 8 years ago

20

zeffii commented 8 years ago

regarding

class SvRxIntValueSocket(bpy.types.NodeSocket, SvRxSocketBase):
    """ For use with input nodes"""

    int_value = IntProperty()
    float_value = FloatProperty()
    mode_enum = EnmuProperty(...) # name matching the name of the property

    @property
    def default_value(self):
        return getattr(self, self.mode_enum)

    @default_value.setter
    def default_value(self):
        setattr(self, self.mode_enum, value)

    def draw_color(self, context, node):
        return NUMBER_SOCKET

    def draw(self, context, layout, node, text):
        if self.is_output:
            layout.prop(self, self.mode_enum, text=text)
        else:
            pass

this

    @default_value.setter
    def default_value(self):
        setattr(self, self.mode_enum, value)

does that make it possible to do

some_socket.default_value = some_value

?

ly29 commented 8 years ago

Yes. Not that I have tested it. https://docs.python.org/3/library/functions.html#property

ly29 commented 8 years ago

A big issue with redirecting like that is that blender doesn't support it, if you want to expose the property in some external place you cannot use node.inputs[socket_name].default_value but have find out which one is used, which isn't that hard but still adds another layer of complexity. I my opinion it is better to swap the socket with reconnect or just straight up have different nodes. Uniform interface both ui and code wise, the complexity is internal to svrx.

nortikin commented 8 years ago

the example of one socket more convenient https://github.com/Sverchok/SverchokRedux/issues/19#issuecomment-163600573 here because it is really issue of UI. Simple switching. Maybe combine in this socket also some types of data that can be used as one socket. lists i.e.