nortikin / sverchok

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

Vector in node, fullList to have a deepcopy alternative. #1984

Closed Durman closed 6 years ago

Durman commented 6 years ago

2017-12-28_14-36-41

zeffii commented 6 years ago

Im not certain this is wrong, you should also show the textbased output,

zeffii commented 6 years ago

it's interesting however, that it's not symmetrical.. if you look at Vector In's source, maybe you can pinpoint why this is. Probably elements are extended to be as long as the first element, unless the current element is longer than the first or previous element.

https://github.com/nortikin/sverchok/blob/5dbf7d806ddfac75f4b4779868dce7a891fe1295/nodes/vector/vector_in.py#L72-L92

Durman commented 6 years ago

After first cycle For, Y and Z coordinate are filled and have 5 elements. :/

2017-12-29_10-14-18

zeffii commented 6 years ago

but is it wrong or unexpected or undesired.

Durman commented 6 years ago

@zeffii

but is it wrong or unexpected or undesired.

Of course it is wrong. Look: 2017-12-29_22-18-45

        for i in range(max_obj):

            max_v = max(map(len, (X_[i], Y_[i], Z_[i])))
            print('Y_ -', Y_)
            fullList(X_[i], max_v)
            fullList(Y_[i], max_v)
            fullList(Z_[i], max_v)
            series_vec.append(list(zip(X_[i], Y_[i], Z_[i])))

We can see here that fullList(Y_[i], max_v) didn't fill values for item object but do it for all objects.

Durman commented 6 years ago

@zeffii fullList function can work with nested lists correctly?

zeffii commented 6 years ago

i've had a few beers :) i don't know what to think about this. 🍻

see implementation:

https://github.com/nortikin/sverchok/blob/69058d106528a671a74394751b12ed6911dabe1c/data_structure.py#L151-L157

Durman commented 6 years ago

@zeffii I understood what is wrong. When we use fullList first time it create references on the last object, than when we use fullList second time we change one object but all objects are changed. Simple example:

from sverchok.data_structure import fullList
data = [[0]]
fullList(data,2)
fullList(data[0],2)
print(data)

We expected to see [[0,0],[0]], but:

2017-12-29_22-58-30

zeffii commented 6 years ago

yes, both objects inside data are the same object.. (by id... and by value)

data = [[0]]
fullList(data,2)
fullList(data[0],2)
print(data)

for obj in data:
    print(id(obj))  # <---- this is the same value, both times.
zeffii commented 6 years ago

unlike in this example, where both objects will be a different id

item_one = [0, 34]
item_two = [30, 0]
data = [item_one, item_two]

print(id(data[0]))
print(id(data[1]))
zeffii commented 6 years ago

something like

# from sverchok.data_structure import fullList

def fullList(l, count):
     import copy
     """extends list l so len is at least count if needed with the 
     last element of l""" 
     d = count - len(l) 
     if d > 0: 
         l.extend([copy.deepcopy(l[-1])] * d) 
     return 

data = [[0]]
fullList(data,2)
for obj in data:
    print(id(obj))
fullList(data[0],2)
for obj in data:
    print(id(obj))

makes

[[0, 0], [0]]
zeffii commented 6 years ago

and we might do something like this:

for upper_register in lists:
    max_len = ...
    a = fullList_deep_copy(.....)  # <--- deep copy is important here..
    ...
    for lower_register in lists:
        max_len = ...
        a = fullList(.....)
        ...

we also have a parameter in socket.sv_get(deepcopy=True), that would be an alternative option.

But whatever we do, consider that any change would need to be in an MK2, some people might be relying on the old behaviour ( which I think too, is probably incorrect...)

zeffii commented 6 years ago

@Durman I welcome you to propose an alternative algorithm that does output the desired data. add a BoolProperty in the class definition, and reference it in draw_buttons_ext and in process.


class ...

    advanced_mode = BoolProperty(name='advanced deep copy')

    ...

    def draw_buttons_ext(self, context, layout):
        layout.row().prop(self, 'advanced_mode')

    def process(self):

        ...
        if self.advanced_mode:
            ... new code
        else:
            ... original code
Durman commented 6 years ago

@zeffii Yes, I'll do it soon.

zeffii commented 6 years ago

closing issue. cause established. we can continue talk in the PR https://github.com/nortikin/sverchok/pull/2019

should push soon.