with the iteration patch from the ofelia doc folder as a starting point i made a little grid. its useless yet and i am sure it can be optimized, but slowly i get an idea from the lua language and open frameworks. quite a different way of using pure data
ofelia2_grid3.pd
-
ofelia test grid
-
@Jona That looks cool! I will try that soon.
-
@cuinjune thanks.
next i will try to store the grid values (x, y/id, color/toggle state) into a table/array. just discovered that its possible to create "matrices" with tables in lua. which could be nice for that.
do you think it makes more sense to use open frameworks or lua arrays/tables fore storing open frameworks data in ofelia?
edit: with print everything works like expected, need to learn whats the difference between return and print. funny (and useful) that lua prints into the pd console. is it also possible to return lists? thats something i am used from pure data...
just a test.
ofelia_array_matrix.pdfunction ofelia.float(f); local matrix = {}; for i = 1, 10 do; matrix[i] = {}; for j = 1, 10 do; matrix[i][j] = i*j; end; end; print(table.unpack(matrix[f])); return table.unpack(matrix[f]); end;
-
hi @cuinjune, finally i managed to save the grid values into a matrix. i have one define object for drawing, one for defining and initializing the shared local variables, and one for the mouse events. i dont know if that makes sense, but it works for now. do you know if its possible to update the grid only if there is a change? perhaps fbo could be a good solution https://forum.openframeworks.cc/t/draw-once-permanently-instead-of-every-frame/9137 ? or this discussion could point me into the right direction: https://forum.openframeworks.cc/t/best-way-to-draw-an-array-of-objects/20652/40. because at the moment it iterates the grid every frame which is fine for smaller grids, but can get slow at a certain gridsize...
ofelia2_grid_with_matrix.pd
-
next step
ofelia2_grid_with_matrix2.pd
-
until now i created the matrix like that:
mt = {} -- create the matrix for i=1,N do mt[i] = {} -- create a new row for j=1,M do mt[i][j] = 0 end end
in this version i create the matrix like that:
mt = {} -- create the matrix for i=1,N do for j=1,M do mt[i*M + j] = 0 end end
because it seems easier to access and to write to (i am not sure, but at least it works...).
i found the information about matrices and multi-dimensional arrays here: https://www.lua.org/pil/11.2.html -
@Jona Nice work! I used fbo based on your first patch to reduce overhead.
ofelia2_grid4.pd -
@cuinjune thats a great improvement. like 10 times more efficient on my computer than without fbo. i was trying to use fbo too, but didnt manage to make it work with ofelia 2 (looked for open frameworks and ofelia 1.0.8 fbo examples and also already used it in 1.0.8(with your help)). my mistake was basically that i tried to call allocate, end, begin and draw like the other objects: "of.Fbo."..."" and i see other improvements too. thanks a lot, very useful now it should be easy for me to implement the other features again...
-
i tried to optimize the patch. i dont think its perfect, but much more efficient than before.
somehow it seems to slow down a little bit with a lot of cells although the cpu load is still below 50 percent.
every drawing except the background is done with fbo now, i tried just to update the fbos when its necessary. so there is one fbo for the lines, one for the "raster", one for the toggled cells and one for the yellow/red play position.
Ofelia2_GridX.pd
-
i added some new features and optimized the patch as far as i am able for now.
mainly matrix transformations but also a pattern save mechanism which makes use of pd class.
i think it would make sense to combine some of the functions into one define object, i am sure there is still some redundant code.
and perhaps it can be more efficient, but i tried my best and its fast enough for my needs.
be careful with invertMatrix if you have sound, it can get loud (its only midi out).
@cuinjune I found one thing: I can toggle the define objects that are toggled from the pure data interface(except delete_matrix) only if they are connected with a cord, and not with send and receive. And thanks angain for the help with the patch
Ofelia2_GridX.pd
-
i updated the patch and put all of the grid transform functions into one define object. i think its more structured, on the other side it makes perhaps sense to have smaller objects to find errors more easily and organize the patch visually? i also got rid of the red rectangles so i dont need the step position fbo anymore which makes a big difference in performance. @cuinjune my problem now is that pure data crashes when i save or copy a grid that is bigger than 32x32. do you know the reason for that?
-
@Jona Hi, Can you post your patch that crashes? It could be calling graphics related classes or methods in the patch startup before window is created.
-
@cuinjune hi. of course, here is the patch: Ofelia2_GridX.pd
i meant save or copy the grid (with the toggles at the bottom of the interface), not the patch. that happens in the [pd pattern] subpatch, perhaps it has to do with pd class? -
@Jona I just tried your patch on macOS and Windows but it didn't crash when I copy/paste/save the grid. Please try to find out exactly when/where the crash happens and let me know.
By the way, I don't have [list-drip] and [list-idx] on my computer.
I think you can embed these abstractions as subpatches if you want to make your patch work on vanilla pd. -
@Cuinjune thanks for checking the patch. it crashes on my computer if the grid has more than ~1100 cells, except it is 1 * y or x * 1. i also tried to reinstall ofelia and pure data, but still. i wonder if anyone else can reproduce the crash? good idea with the abstractions, i updated it in the post above, its now vanilla (except ofelia).
-
@Jona Hi I could confirm that your patch crashes when I increase the size of the grid.
And I found out what is causing the crash.
I actually limited the size of the elements to 1000 when outputting a lua table through pd's outlet.
I thought this will only be a problem when users use more than 1000 userdata elements but now looking at my code, it is also problematic when using other types as elements.(e.g. number, string..)Anyways, I can easily fix this so it no longer have a limit.
I will fix this and upload 2.0.4 version to Deken by the end of this week and will let you know.Thank you.
-
@Jona Hi I'm sorry for the little delay. I fixed bugs including the one you posted on the github repo and uploaded on Deken. You will be able to find v2.0.4 shortly. Now your patch won't crash. I also added the "onset" parameter to Array getter and setter functions like you suggested. Please check out "examples/pd/misc" example. Thank you so much for your contributions to Ofelia. Please let me know whenever you find problems or have suggestions.
P.S: Raspberry Pi version is not yet uploaded to Deken. I will upload it tomorrow. (just in case RPi users read this today)
-
@Cuinjune thanks a lot for the update
inspired by the conway implementation from @weightless https://forum.pdpatchrepo.info/topic/10916/conway-s-game-of-life-implementation-with-data-structures i tried to implement the conway algorhithm. if you select the first preset and click the conway toggle you can see an example.
Ofelia2_GridXConway.pd
it works inside the grid, but i cant figure out the upper and lower border logic yet. i think it is a disadvantage of the one dimensional table for this case, perhaps a 2 dimensional table would make things easier? or i just dont get the logic it could be more difficult to implement the existing functions (like shift or shuffle) into the 2 dimensional table, that was quite easy with the one dimensional table. @weightless also used "2 dimensional arrays" (the [text] object) in his conway patch. something like this: https://github.com/syntruth/Lua-Grid sounds great for the grid logic, but still to complex for me to understand... -
@Jona Cool work! I'm sorry I don't know much about the conway algorithm so I don't think I can help you. I may be able to help you if you simplify your question and post a patch that shows your problem.
-
@Cuinjune no problem and thanks, i think i can figure that out by myself. i will try.
These are the conway (game of life) rules:
For a space that is 'populated': Each cell with one or no neighbors dies, as if by solitude. Each cell with four or more neighbors dies, as if by overpopulation. Each cell with two or three neighbors survives.
For a space that is 'empty' or 'unpopulated' Each cell with three neighbors becomes populated.and here i found a very basic example that is easy for me to understand, so i do not need the grid abstraction that i posted above (although it could be useful for further experiments):
function Evolve( cell ) local m = #cell local cell2 = {} for i = 1, m do cell2[i] = {} for j = 1, m do cell2[i][j] = cell[i][j] end end for i = 1, m do for j = 1, m do local count if cell2[i][j] == 0 then count = 0 else count = -1 end for x = -1, 1 do for y = -1, 1 do if i+x >= 1 and i+x <= m and j+y >= 1 and j+y <= m and cell2[i+x][j+y] == 1 then count = count + 1 end end end if count < 2 or count > 3 then cell[i][j] = 0 end if count == 3 then cell[i][j] = 1 end end end return cell end
https://rosettacode.org/wiki/Conway's_Game_of_Life#Lua
i still think that i need to use a 2 dimensional table like this for conway (like they did in the conway examples that i found too):
mt = {} -- create the matrix for i=1,N do mt[i] = {} -- create a new row for j=1,M do mt[i][j] = 0 end end
-
@Cuinjune the conway implementation does work now (with and without borders). to achieve that i changed the 1-dimensional table into a 2-dimensional table. because of that i could not figure out yet how to make "shift" work again (except "shift up", which already works), but i will find a solution. the second issue is (again) saving the grid, because pd seems to crash when i return a 2-dimensional table (even without setting the pd [array]).
here is a minimal example of my issue: return_2dim_table.pd
i also wonder if it makes more sense to save a 2-dimensional lua table into a [text] object (which seems kind of an equivalent) or an [array] object. if i save into [array] i have to flatten the lua table before saving and "de"flatten before i load it back into the lua table. or get and set the array/table line by line. basically my main question is: what is the best way to save and recall a 2-dimensional lua table in pure data? everything else does work (and i think better than before).
i also put the matrix transformation functions (shift, invert and so on...) into single ofelia define objects (again), because i think it is better for keeping track of the code.
Ofelia2_GridXMatrix.pd
another issue that i found is that sending a bang into ofelia.bang does not work sometimes while a directly connected bang does work (the "Invert" bang in ofelia2_gridxmatrix.pd for example). which is not really a problem because there are easy workarounds, just wanted to mention it.
i really appreciate all the possibilities of the ofelia library, and i think i just scratched the surface....
edit: everything besides saving works again.