nortikin / sverchok

Sverchok
http://nortikin.github.io/sverchok/
GNU General Public License v3.0
2.24k stars 233 forks source link

groups in IO/json per #782 #810

Closed zeffii closed 8 years ago

zeffii commented 8 years ago

per https://github.com/nortikin/sverchok/issues/803

this is a topic in it's own right..

I feel like doing something experimental with the serialization. Failing that then I guestimate that the current IOjson code only needs minimal massaging to hold groups.

ly29 commented 8 years ago

I am not certain I agree, not that name uniqueness wouldn't be sane (*), but I think that using the index when saving sockets is the right way.

I think the right way is create a a way to lock the node update function so that is doesn't create sockets but can take a fixed set and create them, avoiding the issue right instead.

(*) Having dictionaries without ensuring uniqueness of keys is not sane at all, but it is as it is in blender.

zeffii commented 8 years ago

update_list ideally contain something like

dict( 
    from_node=from_node.name, 
    from_socket=(socket.name, socket.index), 
    to_node=to_node.name, 
    to_socket=(socket.name, socket.index)
)

I suggest the name uniqueness then merely as an interim solution, which will be insignificant to remove at a later stage when update_lists include indices.

I don't see how this relates to the problem of dupli-name sockets:

I think the right way is create a a way to lock the node update function so that is doesn't create sockets but can take a fixed set and create them, avoiding the issue right instead.

(I think it's fine to have a def auto_add_sockets(templates) I think that's what the code is suggesting

but it is early and i've only had half a cup of coffee :)

zeffii commented 8 years ago

edited answer.

ly29 commented 8 years ago
name_to_idx = {name: idx for idx, name in enumerate(chain(update_lists))}
links =[(l.from_node.name, l.from_socket.index, l.to_node.name, l.to_socket.index) for l in ng.links]
def get_key(l)
    name, _, _, socket_idx = l
    return name_to_idx[name], socket_idx
links.sort(key=get_key)

Something like this above would replace this. https://github.com/nortikin/sverchok/blob/iojson_monads/utils/sv_IO_panel_tools.py#L296-L306

And also the following would be needed for the socket.index part. This function could be moved to somewhere else.

def get_socket_index(socket):
    try:
        return socket.index
    # for reroutes, since they don't have .index property/attribute
    except AttributeError:
        return 0

https://github.com/nortikin/sverchok/blob/master/utils/monad.py#L256-L261

Having them fixed, especially for the GroupInputs, removes the constraint to connect them in order of sockets. I thinks this is the only node that has dynamic count of outputs, which isn't controlled by number or inputs or a setting.

zeffii commented 8 years ago

i'll make an auto_generate_sockets(templates) for the GroupInputs, and start offloading other work to nodes..

ly29 commented 8 years ago

skarmavbild 2016-08-31 kl 09 56 55 Just to be clear about what kind of situations might cause problems.

zeffii commented 8 years ago

stashing:

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            puts = node.node_kind
            node_dict[puts] = []
            for s in getattr(node, puts):
                if not s.bl_idname == 'SvDummySocket':
                    node_dict[puts].append([s.name, s.bl_idname])

repopulate

    elif node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
        kind = node.node_kind
        socket_kinds = node_ref.get(kind)
        sockets = getattr(node, kind)
        sockets.remove(sockets[0]) # remove dummy, it will be added anyway. during the final update
        for idx, (s, stype) in enumerate(socket_kinds):
            print('add', s, stype, 'to', node.name)
            sockets.new(stype, s)
            # sockets.move(-1, idx)  # not needed now

i'm doing some extra work, but it's just a loop over the inputs/outputs

zeffii commented 8 years ago

image

zeffii commented 8 years ago

SocketAcquisition should take a further two functions then..

def stashing(self):
    socket_kinds = []
    for s in getattr(self, self.node_kind):
        if not s.bl_idname == 'SvDummySocket':
            socket_kinds.append([s.name, s.bl_idname])
    return socket_kinds

def repopulate(self, socket_kinds):
    sockets = getattr(self, self.node_kind)
    sockets.remove(sockets[0]) # remove dummy, it will be added anyway. during the final update
    for idx, (s, stype) in enumerate(socket_kinds):
        # print('add', s, stype, 'to', self.name)
        sockets.new(stype, s)

then in the iojson..somewhat offloaded..

# stash
    if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
        node_dict[node.node_kind] = node.stashing()

# repopulate
    elif node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
        socket_kinds = node_ref.get(node.node_kind)
        node.repopulate(socket_kinds)
zeffii commented 8 years ago

https://github.com/nortikin/sverchok/commit/b493bdfbf309886980d5e78ffcbd1e1fd4e35911

This phase is nearing completion, but I fully expect bugs to be present. Of course the issue of socket name dupes remains untouched.

zeffii commented 8 years ago

regarding this: https://github.com/nortikin/sverchok/issues/810#issuecomment-243684540

does this effect only the reroute node? There's a couple of important minutiae that i'm glossing over, maybe best if you deal with those since you seem to have a better grasp of them. Else I will eventually get around to it, if they bug me enough.

zeffii commented 8 years ago

btw :)

keyboard

i refuse to type that one more time.

ly29 commented 8 years ago

A million times yes!

Regarding those tiny annoying details I will try to find corner cases and deal with them. As far as I know reroute is the only node in sverchok node trees that doesn't use sverchok sockets.

zeffii commented 8 years ago

The rewriting function is in this addon.. but am considering make a far lighter version of it..

can we subclass the reroute node?

ly29 commented 8 years ago

I don't think it is possible to subclass it. We do have some code capable of replacing the sockets though.

zeffii commented 8 years ago

as per : https://github.com/nortikin/sverchok/commit/84db7392d70c885f8be48fb482b0380bec774be5

The scenario where the monad already exists in the current layout is not handled correctly.

zeffii commented 8 years ago

should be as simple as the suggested fix.

zeffii commented 8 years ago

but possibly it isn't.. but can't investigate now

def add_groups(groups_to_import):
    '''
    return the dictionary that tracks which groups got renamed due to conflicts
    '''
    group_name_remap = {}
    for name in groups_to_import:
        group_ng = bpy.data.node_groups.new(name, 'SverchGroupTreeType')
        if group_ng.name != name:
            group_name_remap[name] = group_ng.name
        import_tree(group_ng, '', groups_to_import[name])
    return group_name_remap