-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reaction Diffusion script. #1734
Comments
This implementation (both versions) doesn't really offer a convenient way to do that. It initializes a 2d matrix of What you would need to do is comment out the random value assignments, and instead add an input for a set of vectors, and convert the content of vectors to something that can be represented as a you will need to write code, or it won't happen. |
here is Reaction Diffusion (2) script for snlite """
in steps s d=500 n=2
in seed s d=14 n=2
out verts_out v
"""
def setup():
import random
import numpy as np
class DiffReact2():
verts = []
params = []
params.append((0.16, 0.08, 0.035, 0.065)) # Bacteria 1
params.append((0.14, 0.06, 0.035, 0.065)) # Bacteria 2
params.append((0.16, 0.08, 0.060, 0.062)) # Coral
params.append((0.19, 0.05, 0.060, 0.062)) # Fingerprint
params.append((0.10, 0.10, 0.018, 0.050)) # Spirals
params.append((0.12, 0.08, 0.020, 0.050)) # Spirals Dense
params.append((0.10, 0.16, 0.020, 0.050)) # Spirals Fast
params.append((0.16, 0.08, 0.020, 0.055)) # Unstable
params.append((0.16, 0.08, 0.050, 0.065)) # Worms 1
params.append((0.16, 0.08, 0.054, 0.063)) # Worms 2
params.append((0.16, 0.08, 0.035, 0.060)) # Zebrafish
def __init__(self, np, steps=500, seed=4):
n = 256
imgx = n
imgy = n
random.seed(seed)
(Du, Dv, F, k) = random.choice(self.params)
Z = np.zeros((n+2, n+2), [('U', np.double), ('V', np.double)])
U, V = Z['U'], Z['V']
u, v = U[1:-1, 1:-1], V[1:-1, 1:-1]
r = 20
u[...] = 1.0
U[n/2-r:n/2 + r, n/2-r:n/2 + r] = 0.50
V[n/2-r:n/2 + r, n/2-r:n/2 + r] = 0.25
u += 0.05 * np.random.random((n, n))
v += 0.05 * np.random.random((n, n))
######### loop start ############
p = 0
for i in range(steps):
Lu = ( U[0:-2,1:-1] +
U[1:-1,0:-2] - 4*U[1:-1,1:-1] + U[1:-1,2:] +
U[2: ,1:-1] )
Lv = ( V[0:-2,1:-1] +
V[1:-1,0:-2] - 4*V[1:-1,1:-1] + V[1:-1,2:] +
V[2: ,1:-1] )
uvv = u*v*v
u += (Du*Lu - uvv + F*(1-u))
v += (Dv*Lv + uvv - (F+k)*v)
pn = 100 * (i + 1) / steps # percent completed
if pn != p:
p = pn
print("%" + str(p).zfill(2))
######### loop end ############
add_vert = self.verts.append
vMin=V.min(); vMax=V.max()
for iy in range(imgy):
for ix in range(imgx):
w = V[iy, ix]
c = int(255 * (w - vMin) / (vMax - vMin))
if c > 190:
add_vert((ix/40, iy/40, 0))
label = "Du=" + str(Du) + " Dv=" + str(Dv) + " F=" + str(F) + " k=" + str(k)
print(label)
GK = DiffReact2(np, steps, seed)
verts_out.append(GK.verts)
|
Thanks @zeffii for the SNLite update. Just wondering with the steps and seed, it does not seem to update the data unless I hit "Reload" button. Is this by design? Also as I keep hitting reload, as the steps number get higher, it get slower and slower. |
Think about why steps influences processing time. Yeah it only works once per load reload.. by design. |
Will meditate and come back. |
1200 frames slightly modified script """
in steps s d=1200 n=2
in seed s d=14 n=2
in framenum s d=0 n=2
out verts_out v
"""
def setup():
import random
import numpy as np
class DiffReact2():
verts = []
params = []
params.append((0.16, 0.08, 0.035, 0.065)) # Bacteria 1
params.append((0.14, 0.06, 0.035, 0.065)) # Bacteria 2
params.append((0.16, 0.08, 0.060, 0.062)) # Coral
params.append((0.19, 0.05, 0.060, 0.062)) # Fingerprint
params.append((0.10, 0.10, 0.018, 0.050)) # Spirals
params.append((0.12, 0.08, 0.020, 0.050)) # Spirals Dense
params.append((0.10, 0.16, 0.020, 0.050)) # Spirals Fast
params.append((0.16, 0.08, 0.020, 0.055)) # Unstable
params.append((0.16, 0.08, 0.050, 0.065)) # Worms 1
params.append((0.16, 0.08, 0.054, 0.063)) # Worms 2
params.append((0.16, 0.08, 0.035, 0.060)) # Zebrafish
def __init__(self, np, steps=500, seed=24):
self.frame_storage = {}
self.n = n = 256
self.imgx = n
self.imgy = n
random.seed(seed)
(Du, Dv, F, k) = random.choice(self.params)
Z = np.zeros((n+2, n+2), [('U', np.double), ('V', np.double)])
U, V = Z['U'], Z['V']
u, v = U[1:-1, 1:-1], V[1:-1, 1:-1]
r = 20
u[...] = 1.0
U[n/2-r:n/2 + r, n/2-r:n/2 + r] = 0.50
V[n/2-r:n/2 + r, n/2-r:n/2 + r] = 0.25
u += 0.05 * np.random.random((n, n))
v += 0.05 * np.random.random((n, n))
######### loop start ############
p = 0
for i in range(steps):
Lu = ( U[0:-2,1:-1] +
U[1:-1,0:-2] - 4*U[1:-1,1:-1] + U[1:-1,2:] +
U[2: ,1:-1] )
Lv = ( V[0:-2,1:-1] +
V[1:-1,0:-2] - 4*V[1:-1,1:-1] + V[1:-1,2:] +
V[2: ,1:-1] )
uvv = u*v*v
u += (Du*Lu - uvv + F*(1-u))
v += (Dv*Lv + uvv - (F+k)*v)
subverts = []
add_vert = subverts.append
vMin=V.min(); vMax=V.max()
for iy in range(self.imgy):
for ix in range(self.imgx):
w = V[iy, ix]
c = int(255 * (w - vMin) / (vMax - vMin))
if c > 190:
add_vert((ix/40, iy/40, 0))
self.store_frame(i, data=subverts)
pn = int(100 * (i + 1) / steps) # percent completed
if pn != p:
p = pn
print("%" + str(p).zfill(2))
######### loop end ############
# label = "Du=" + str(Du) + " Dv=" + str(Dv) + " F=" + str(F) + " k=" + str(k)
# print(label)
def get_frame(self, number):
return self.frame_storage.get(number)
def store_frame(self, framestep, data):
self.frame_storage[framestep] = data
GK = DiffReact2(np, steps, seed)
verts = GK.get_frame(framenum)
verts_out.append(verts)
|
@zeffii I am revisiting this again to try it with "Marching Cubes" setup of @kalwalt ... but your latest SNL does not give any output,. except an error Unexpected error: <class 'TypeError'>
on line: 38
Traceback (most recent call last):
File "C:\Users\zeffi\Desktop\scripts\addons_contrib\sverchok\nodes\generator\script1_lite.py", line 390, in process_script
self.inject_state(locals())
File "C:\Users\zeffi\Desktop\scripts\addons_contrib\sverchok\nodes\generator\script1_lite.py", line 357, in inject_state
setup_locals = local_variables.get('setup')()
TypeError: slice indices must be integers or None or have an __index__ method |
i don't know. it worked at one point :) |
i wish there was a more graphical way to see the changes over time in In that... we strip out all the working code of the script, and see if the imports still work. |
that looks like this.. """
in steps s d=500 n=2
in seed s d=14 n=2
out verts_out v
"""
def setup():
import random
import numpy as np
class DiffReact2():
verts = []
params = []
params.append((0.16, 0.08, 0.035, 0.065)) # Bacteria 1
params.append((0.14, 0.06, 0.035, 0.065)) # Bacteria 2
params.append((0.16, 0.08, 0.054, 0.063)) # Worms 2
params.append((0.16, 0.08, 0.035, 0.060)) # Zebrafish
def __init__(self, np, steps=500, seed=4):
random.seed(seed)
f = random.choice(self.params)
print(f)
m = np.random.random((4, 4))
print(m)
self.verts = [[0,0,0], [0,0,1], [0,0,2]]
GK = DiffReact2(np, steps, seed)
verts_out.append(GK.verts) and the output to console.
this means the mechanism works.. but numpy has changed in someway... i think |
this means that the part I was worried might be broken is, in-fact, still functional. The next step is to look at just the numpy code. |
it's this line ( On Line 36 ) but you have to add a number of lines because setup doesn't begin until 8, that makes .. line 44.
|
boiling it down to
|
because |
this does execute import random
import numpy as np
n = 256
seed = 20
random.seed(seed)
Z = np.zeros((n+2, n+2), [('U', np.double), ('V', np.double)])
U, V = Z['U'], Z['V']
u, v = U[1:-1, 1:-1], V[1:-1, 1:-1]
r = 20
ndiv2 = int(n/2)
u[...] = 1.0
U[ndiv2-r:ndiv2 + r, ndiv2-r:ndiv2 + r] = 0.50
V[ndiv2-r:ndiv2 + r, ndiv2-r:ndiv2 + r] = 0.25 |
it appears from |
if you recall the error message says it.. TypeError: slice indices must be integers or None or have an __index__ method |
Hmm.. I did copy paste the numpy from outside into Blender. |
So reloading the SNL prints out some kind of interesting values, but the output to Sverchok is integer? |
https://gist.github.com/zeffii/4270f3f23e694c4b360b1bc7cb9c22f0 (this is a script only.. not a layout) click on that. look at it. look at the tab that says "revisions" and see the change that needed to be made to the code. Now it will run in old and new numpy versions. Never mind the other scripts for RD that i made. |
@zeffii Thanks Zeff for updating this script. What I found interesting is that with this SNL you did some calculation and there is this nice 0%-100% processing indicator... and then the node stops updating, only updates frame and it was then interactive. |
@enzyme69 yes, first the node calculates all the states for the given number of frames, and stores them all inside a dict. one state for each frame. Then after all calcs completed you can feed it a frame and it will do a lookup on the dict, and get the state for that frame number. The upside of this is that you can calculate all frames for a given size+seed once, and scrub through them (interactively). The downside is that you wait once, a long time, to process everything first. The seed is also static per "master calculation". (it doesn't make much sense to have a dynamic seed for something that grows from an initial state) it's not super fast, if we ever moved stuff to compiled C/C++ these would be the kinds of things that would be prime candidates. |
essentially this caches all frames first. ( like baking an animation ) The other uncached approach is less interactive because it first must calculate all states from frame 0 each time. meaning.. if you are at frame 90 and you jump to frame 91, first a dumb approach would have to calculate all frames between 0 and 90, to be able to move to frame 91. because you can't get frame 90 without first.. at some point calculating all in between frames, it makes sense to cache them anyway. A smart person would implement an algorithm that progressively caches all the states/frames that it has visited, giving better interactivity between small frame jumps and all previously seen frames. Because i'm not excited about it, that person won't be me. |
@zeffii is the "data caching" something you made for SNL? Or is it Blender thing? I noticed that it does cache well, however there is occassional stutter when played back or scrubbed back and forth. Not sure why. I was looking at your RD script and you did this "frame_storage" is this something you invented?
|
those two functions just get and set data for a key (which happens to be unique per keyframe number). I hardly invented this. this is what caching is. the occasional stutter is to be expected, this is not intended to be realtime...or boast great performance. It was just me showing what could be done using the |
Sorry for jumping in, but just inspired by @zeffii 's code and SNLite 'setup' feature (, sorry I once miss-spelled 'zeffi'). These are 3d and run-on-mesh version, originated from the 2d script. One major difference is using C code with ctypes load_library (Python-only versions are also included, but very slow...). I hope recent numba integration will work well, and these might be some benefit for future developments.😀 |
Awesome @asahidari !! |
sorry i did not see this earlier. it's super cool :) also nice to see the other examples using C code in snlite. i've only now started to dig into numba a little. mind blowing stuff. (and your stuff is too!) |
I stumbled into this RD Script Node by Zeffii:
https://gist.github.com/zeffii/9e156f0d37977fd1b0ca3c65d0ddc611
If I am not wrong, this is similar to Processing one shown by Shiffman. I need to rewatch the video.
I am curious on how we can provide our own points (maybe using Grease Pencil) to start with.
The text was updated successfully, but these errors were encountered: