nortikin / sverchok

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

Noodle and Brain Pattern #315

Closed enzyme69 closed 10 years ago

enzyme69 commented 10 years ago

I remember making Noodle pattern just by connecting lines across "sorted" vertices, but I am thinking to make brain pattern as well.. https://vimeo.com/100170928

Very curious.

enzyme69 commented 10 years ago

prtscr capture_10

This is the Sverchok "noddle" pattern so far.

I remember using Liero BTrace that does tracing in an interesting way. Let me see if I can still do this.

enzyme69 commented 10 years ago

Yes, it still work using Object Trace in BTrace Add-On.

It is connecting and tracing points by index, but I wonder why the result is different in Sverchok. Wonder what BTrace is doing in the background.

prtscr capture_11

enzyme69 commented 10 years ago

Sverchok vs BTrace tracing.

prtscr capture_13

What algorithm, do you think BTrace is using?

enzyme69 commented 10 years ago

You see... it's a nice algorithm!

prtscr capture_14

Wonder how BTrace does this?

enzyme69 commented 10 years ago

Gerardo (Liero) said

"make a list of vertices, then pick a random one to start with and find the nearest one, remove previous from list and so on, alway picking the one that's closer to the active vertex... that's one of my first scripts :p but btrace addon was put together by crazycourier"

So in the way, it is iteration that looks for nearest points.

Liero said, probably KDTree like. I thought about that too, but wonder why it does not give the result I expected. Maybe Sorted KDTree that only look for index next to it.

Hmmm.. brain....

ly29 commented 10 years ago

I think for this you have use script node for now since it is an iterative process.

ly29 commented 10 years ago

I am writing a kd tree script for this, some issues but having fun. v1

enzyme69 commented 10 years ago

Fantastic!

Once again recursive can be done with Scripted Node.

The BTrace often gives a strange jump between points, which creates a sudden unwanted line connection.

This one gives a nice effect whether Brain like or Noodle like.

zeffii commented 10 years ago

but wonder why it does not give the result I expected.

because what you expect kdtree nodes to do is not what they are aimed at. You can (as @ly29 points out) use kdtree module from mathutils in a SN script, to get good performance nearest neighbour finding. There are already 2 examples in the template folder.

edit: I see @ly29 having fun

ly29 commented 10 years ago

btrace

Okay now it working well, not optimized and so on. Just following the very simple description given above. Suzanne takes 0.01s I will probably get worse and worse the bigger the mesh. Plane is worst case for this kind of exercise, that can be done more clever with index manipulation but is a whole another game. Inputs:

import mathutils
import random
import collections
from itertools import islice
from mathutils import Vector

def sv_main(objs=[], seed=1, start=-1):

    # in boilerplate, could be less verbose
    in_sockets = [
        ['v', 'verts', objs],
        ['s', 'seed', seed],
        ['s', 'start', start]
    ]

    random.seed(seed)
    edge_out = []

    for verts in objs:
        if not verts:
            break

        size = len(verts)
        kd = mathutils.kdtree.KDTree(size)

        for i, v in enumerate(verts):
            kd.insert(v, i)
        kd.balance()
        if 0 < start and start < size:
            index = start
        else:
            index = random.randrange(size)
        vecs = None
        out = collections.OrderedDict({index:0})
        while len(out) < size:
            #print(round(len(out)/size,3))
            if (len(out) / size) < .90: 
                found_next = False
                n = 0
                step = 5
                while not found_next:
                    count = min(size, n+step)
                    for pt, n_i, dist in islice(kd.find_n(verts[index], count), n, count):
                        if not n_i in out:
                            out[n_i] = index
                            index = n_i
                            found_next = True
                            break
                    if n > size:
                        break
                    n += step
            else: #now we reduced the number of verts and the above gets very slow
                if not vecs:
                    total_set = set(range(size))
                    indx = total_set - set(out.keys())
                    vecs = {i:Vector(verts[i]) for i in indx}

                c_v = Vector(verts[index])
                dists = [((vecs[i]-c_v).length, i) for i in indx]
                pt, n_i = min(dists, key=lambda x:x[0])
                out[n_i] = index
                index = n_i
                indx.discard(index)

        out.popitem(last=False)
        edge_out.append([(j,k) for j,k in out.items()])

    out_sockets = [
        ['s', 'Edges', edge_out]
    ]

    return in_sockets, out_sockets
ly29 commented 10 years ago

It should skip ahead in the inner for loop instead of checking using again, best I guess using islice, updated now.

enzyme69 commented 10 years ago

@zeffii I see... that means there are a lot of KDtree that I don't know how it does yet. Interesting. Will need to investigate KDTree in SN then.

prtscr capture_18 prtscr capture_17 prtscr capture_16

Zef, the data out from Vertices and Edges SN does not work with Fill Face node, wonder why: https://www.dropbox.com/s/z9m5scnxoj63kyq/my_noodle_brain13.blend

And @ly29 just made another something!

And I just saw this is now possible. Which is kind of cool/ prtscr capture_20

ly29 commented 10 years ago

@enzyme69 That script has two issues with it's output that fillhole should correct for, it creates duplicate edges and produces unwrapped output.

enzyme69 commented 10 years ago

Ok, noticed that now.

enzyme69 commented 10 years ago

Alright, this is really nice! Studying the SN now.

@ly29 the Seed is doing nothing at the moment. The "Start" does something.

prtscr capture_22

ly29 commented 10 years ago

There was bug with seed, copy the script again. Start overrides seed if both are connected and start is a valid index.

zeffii commented 10 years ago

it's time I do a Curves version of (b)Mesh viewer

ly29 commented 10 years ago

It is also only used for the first point, otherwise the algorithm is quite stable since it is just based on distance, especially locally.

ly29 commented 10 years ago

Fix for fill holes is done. n=3 for fill, for fun. fill-holes

ly29 commented 10 years ago

Script in master now.

enzyme69 commented 10 years ago

( ^ __ ^ ) v

linus_btrace

This can be really cool effect. Especially when layered with animation.

I used to do this with many steps.

Thanks for solution.

Closed!

enzyme69 commented 10 years ago

prtscr capture_28

enzyme69 commented 10 years ago

Liero and ATOM: http://blenderartists.org/forum/showthread.php?331750-Fiber-Mesh-Emulation/page2

ly29 commented 10 years ago

Updated the script to speed up performance. Magnitude of 2 speed up. by switching to another method for the last 10%. Not tuned at all A 15k verts test setup, from 33s, to 0.8s

enzyme69 commented 10 years ago

Yes, in my case it was from nearly half hour to few seconds.

Then, from 8000 points, I tried 80000 points now. Leaving computer overnight.

ly29 commented 10 years ago

How long it takes depends on how the vertices are distributed in space.

enzyme69 commented 10 years ago

I see. These kind of algorithm making complex design is interesting.

What is next: snowflakes?


ly29 commented 10 years ago

test-screenshot KD Tree isn't the right answer on itself.

enzyme69 commented 10 years ago

Sorting it the right way gives a much better looking result actually. And faster too.

enzyme69 commented 10 years ago

prtscr capture_14 Linusy Magik.

enzyme69 commented 10 years ago

Actually Nikolaus of Local Guru is kind of doing lots of things that Sverchok would be perfect for. http://www.local-guru.net/blog/2012/5/19/blender-curve-experiments---curve-from-mesh