pd-lua icon indicating copy to clipboard operation
pd-lua copied to clipboard

pdlua graphics

Open timothyschoen opened this issue 6 months ago • 3 comments

Hi Albert!

Today I started working on a basic graphics API for pdlua. The goal is a cross-flavour way to create GUI objects.

So far, this is going quite well: I'm able to do basic drawing in pd-vanilla and plugdata, using the same Lua code. It should be simple to port over to purr-data as well. It's also a much easier way to create GUI externals, no pd structs or tcl/tk knowledge required.

Screenshot 2023-12-20 at 03 28 56

~~This is very much WIP, not mergable yet.~~ Not anymore!

What works

  • plugdata:

    • [x] Drawing or filling rectangles/rounded rectangles/circles
    • [x] Graphics transforms
    • [x] Drawing vector paths
    • [x] Mouse interaction
    • [x] Correctly handles move/resize
    • [x] Drawing lines
    • [x] Drawing text
  • pure-data:

    • [x] Drawing or filling rectangles/rounded rectangles/circles
    • [x] Graphics transforms (kind of)
    • [x] Drawing vector paths
    • [x] Mouse interaction
    • [x] Correctly handles move/resize
    • [x] Drawing lines
    • [x] Drawing text
  • purr-data: Not implemented yet, I was hoping someone with more purr-data experience could help out with that ;)

The API

Example for draggable circle:

local example = pd.Class:new():register("example")

function example:initialize(sel, atoms)
    self.inlets = 1
    self.circle_x = 10
    self.circle_y = 10
    self.gui = 1
    return true
end

function example:mouse_drag(x, y)
    self.circle_x = x - 15
    self.circle_y = y - 15
    self:repaint() 
end

function example:paint()
    gfx.set_color(255, 0, 0, 1)
    gfx.fill_all()

    gfx.set_color(0, 255, 0, 1)
    gfx.fill_ellipse(self.circle_x, self.circle_y, 30, 30)
end

function example:in_1_bang()
    self:repaint()
end

As you can see, you can define a paint() function, where you have to do your painting. Then, you can call repaint() whenever repainting needs to happen. ~If you call gfx.initialize() in the constructor, it will switch the object from text to GUI mode, but this can be done in a better way probably~ EDIT: it now works by settings the self.gui flag.

The supported functions right now are:

-- Callbacks you can define
paint()
mouse_down(x, y)
mouse_up(x, y)
mouse_move(x, y)
mouse_drag(x, y)

-- Functions you can call in gfx namespace
set_size(w, h)
set_color(r, g, b, a=1.0)

fill_ellipse(x, y, w, h)
stroke_ellipse(x, y, w, h)

fill_rect(x, y, w, h)
stroke_rect(x, y, w, h, line_width)

fill_rounded_rect(x, y, w, h, corner_radius)
stroke_rounded_rect(x, y, w, h, corner_radius, line_width)

draw_line(x1, y1 x2, y2, line_width)
draw_text(text, x, y, w, fontsize)

start_path(x, y)
line_to(x, y)
quad_to(x1, y1, x2, y2)
cubic_to(x1, y1, x2, y2, x3, y3)
close_path()
stroke_path(line_width)
fill_path()

fill_all()

translate(tx, ty)
scale(sx, sy)
reset_transform()

timothyschoen avatar Dec 20 '23 02:12 timothyschoen

https://github.com/agraef/pd-lua/assets/44585538/aafa62ea-cc8a-4126-8030-366d939d8f7b

timothyschoen avatar Dec 20 '23 20:12 timothyschoen

https://github.com/agraef/pd-lua/assets/44585538/8b056d25-b58b-4de2-a8e7-f26304b87248

The API and implementations for plugdata and pure-data are done now. I'm gonna add some documentation, and then it's ready for merge.

That is, if you want to merge this. If not, I'll move it to a branch or something, NP either way. This project has existed for over a decade, so I can understand it if this rocks the boat too much.

timothyschoen avatar Dec 22 '23 20:12 timothyschoen

@agraef did you get a chance to look at this? It is now in an official PlugData release and we'd like to have an update of pdlua in deken as well so Vanilla users can have fun with this. cheers

porres avatar Jan 25 '24 15:01 porres

Working on some API improvements:

The paint() function now passes in an argument that represents the graphics context:

function example:paint(g)
    local width, height = self:get_size()

    g.set_color(255, 255, 255, 1)
    g.fill_all()

    g.set_color(0, 0, 0, 1)
    g.fill_ellipse(10, 10, 8, 8(
end

This means that drawing calls can no longer be made from outside the paint() function, which was illegal to do anyway.

Also, paths have their own state now:

    local p = path.start(10, 20)
    p:line_to(40, 100)
    p:line_to(130, 90)
    p:close()

    g.set_color(180, 244, 4)
    g.fill_path(p)

This means you can now also store paths, and it makes managing multiple paths more simple.

"set_size" has been moved from the "gfx" namespace (which is only for internal use now) to the pd object class itself. I've also added a get_size() function.

function example:initialize(sel, atoms)
    self.inlets = 1
    self.outlets = 1
    self.gui = 1
    self:set_size(150, 150)
    local width, height = self:get_size()
    
    return true
end

timothyschoen avatar Feb 23 '24 14:02 timothyschoen

Well, is this still WIP? Or is it finished now?

In any case, this looks rather intrusive, so I'd rather keep it in a separate branch for now.

agraef avatar Feb 26 '24 12:02 agraef

I don't see any actual drawing code in there. Where does that happen? Any chance that this version still works with Purr Data?

agraef avatar Feb 26 '24 12:02 agraef

The drawing code is here: https://github.com/agraef/pd-lua/blob/e7d530b866a24a1d5d30303c8e0337ee7b2dbf7d/pdlua_gfx.h

It's currently a big #if to implement drawing for plugdata and pd-vanilla. It should be pretty trivial to add purr-data compatible drawing commands here too I think, but I couldn't find any API documentation for this (maybe I should have looked better).

There is still one thing I need to fix, which is that graphics translations work a bit differently in pd-vanilla and plugdata when you apply multiple different translations in a row. Other than that, I think this is done.

Here's some demos:

3D oscilloscope (by ben-wes)

https://github.com/agraef/pd-lua/assets/44585538/c1f6220b-6ba5-4000-bd55-95c8c19529f9

Replacement for else/circle:

https://private-user-images.githubusercontent.com/44585538/307366653-99c4c38e-648f-4c9e-a9f6-9a59d3bea553.mov?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDg5NTg3MzEsIm5iZiI6MTcwODk1ODQzMSwicGF0aCI6Ii80NDU4NTUzOC8zMDczNjY2NTMtOTljNGMzOGUtNjQ4Zi00YzllLWE5ZjYtOWE1OWQzYmVhNTUzLm1vdj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAyMjYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMjI2VDE0NDAzMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTRjZmMwMWU2ZjBjNGRkZDNmMDliMTJiOTIwNDMwZDE2MzQ4MDAzOGMyYjQ5NTlhNjA4M2YxMzgwNDE2Y2RlY2UmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.CK8ztu5Z42f9Oak2B1_zDe_S2waAR6QL_Ebii0ryWBk

@porres and I would like to include this in ELSE either way, because this makes it a lot easier for us to write new graphics objects for ELSE:

  • It's easier to write/maintain GUIs than with C-coded externals or data structures
  • pdlua GUIs perform significantly better than data structures (from what I've tested at least)
  • There is no additional effort required to port GUIs to plugdata

We also had some other plans, like adding support for DSP and allowing you to write lua code directly into the [pdlua] object, both features inspired by [ofelia]. If this is too much change for an external this old, we can also create our own fork with a different name. Or we can merge it here, whatever you prefer.

timothyschoen avatar Feb 26 '24 15:02 timothyschoen

Stacking transforms being incorrect in pd-vanilla is fixed now too.

timothyschoen avatar Feb 26 '24 16:02 timothyschoen

yeah, this is in PlugData already and its staying and people are excited. I wouldn't need this for ELSE exactly. else/circle has an issue in PlugData and one way to deal with it would be to provide a coded object and I'd like that, I think it has advantages. But using this makes it easier and a quick short term solution.

Thing is, we also want and need this in Vanilla just so we can share stuff and of course I can have this in ELSE. Maybe a new object with a new name (just [lua]) and with all drastic changes that could even break. For one thing, I think ditching [pdluax] would be good, and I guess people would really like being able to do live coding in an object and having audio support for that and coded externals.

porres avatar Feb 26 '24 16:02 porres

@timothyschoen wrote:

It's currently a big #if to implement drawing for plugdata and pd-vanilla. It should be pretty trivial to add purr-data compatible drawing commands here too I think, but I couldn't find any API documentation for this (maybe I should have looked better).

Ah ok, I see. I think that the way forward would be to add some #if PURR_DATA conditionals for Purr Data with dummy implementations of all the graphics routines so that this version of pd-lua at least builds and runs inside Purr Data, even if the graphics won't work at present. Could you still add that? Then I could merge this into a testing branch, and put it out as a preview release for people to test -- and Alexandre could upload it to Deken for the vanilla users.

And yes, I'm afraid that it's going to be quite a bit of work to get the graphics actually working in Purr Data, but we could maybe put this on the agenda for a future Purr Data GSoC project, for instance. Also, I might have a look at it myself if I find the time, or find a good student with the necessary JS foo who wants to do this as a BSc or Master thesis.

@porres wrote:

yeah, this is in PlugData already and its staying and people are excited

No worries, I fully agree that this is a great addition! :) I can understand why people are excited about it. Gem is a big unwieldy beast with some cross-platform issues, and Pd/Pd-L2ork data structs are not exactly easy either. So a cross-flavor and cross-platform way to program basic graphics and custom guis with pd-lua would be great feature indeed.

agraef avatar Feb 26 '24 20:02 agraef

BTW, those demos look damn cool. :) Are the demo patches available somewhere? And is there a build of PlugData with the modified pd-lua that I can download somewhere? I'd really like to give this a whirl myself asap.

agraef avatar Feb 26 '24 20:02 agraef

@timothyschoen I just pulled your branch and built it on my Manjaro system, but after opening pdlua-help.pd in vanilla Pd (Pd version 0.54.1 straight from the Arch repos) it immediately segfaults when trying to open the pd graphics subpatch (which presumably loads hello-gui.pd_lua in the pdlua subdir). Here's the gdb backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78ba0b5 in realloc () from /usr/lib/libc.so.6
(gdb) bt
watchdog: signaling pd...

#0  0x00007ffff78ba0b5 in realloc () from /usr/lib/libc.so.6
#1  0x0000555555603539 in resizebytes (old=<optimized out>, oldsize=1, 
    newsize=12) at /usr/src/debug/pd/pure-data-0.54-1/src/m_memory.c:52
#2  0x00007ffff72fc5fa in start_path () from ./pdlua.pd_linux
#3  0x00007ffff7327d95 in luaD_precall () from ./pdlua.pd_linux
#4  0x00007ffff730c897 in luaV_execute () from ./pdlua.pd_linux
#5  0x00007ffff7329739 in f_call () from ./pdlua.pd_linux
#6  0x00007ffff7305ccc in luaD_rawrunprotected () from ./pdlua.pd_linux
#7  0x00007ffff733b94a in lua_pcallk () from ./pdlua.pd_linux
#8  0x00007ffff7302bae in pdlua_gfx_repaint () from ./pdlua.pd_linux
#9  0x00005555555b31c1 in canvas_map (x=0x5555557afce0, f=<optimized out>)
    at /usr/src/debug/pd/pure-data-0.54-1/src/g_canvas.c:801
#10 0x000055555560a6c1 in pd_typedmess (x=0x5555557afce0, s=<optimized out>, 
    argc=<optimized out>, argv=<optimized out>)
    at /usr/src/debug/pd/pure-data-0.54-1/src/m_class.c:1087
#11 0x000055555560b331 in binbuf_eval (x=<optimized out>, 
    target=0x55555579ab60, argc=<optimized out>, argv=<optimized out>)
    at /usr/src/debug/pd/pure-data-0.54-1/src/m_binbuf.c:764
#12 0x000055555561b63f in socketreceiver_read (x=0x555555757420, fd=24)
    at /usr/src/debug/pd/pure-data-0.54-1/src/s_inter.c:698
#13 0x00005555556110b4 in sys_domicrosleep (microsec=microsec@entry=0)
    at /usr/src/debug/pd/pure-data-0.54-1/src/s_inter.c:241
#14 0x0000555555613073 in sys_pollgui ()
    at /usr/src/debug/pd/pure-data-0.54-1/src/s_inter.c:1051
--Type <RET> for more, q to quit, c to continue without paging--
#15 0x0000555555618496 in m_pollingscheduler ()
    at /usr/src/debug/pd/pure-data-0.54-1/src/m_sched.c:348
#16 m_mainloop () at /usr/src/debug/pd/pure-data-0.54-1/src/m_sched.c:429
#17 0x00007ffff7843cd0 in ?? () from /usr/lib/libc.so.6
#18 0x00007ffff7843d8a in __libc_start_main () from /usr/lib/libc.so.6
#19 0x000055555556c0c5 in _start ()

Looks like a memory allocation issue to me. Can you reproduce this?

agraef avatar Feb 26 '24 21:02 agraef

@timothyschoen I just pulled your branch and built it on my Manjaro system, but after opening pdlua-help.pd in vanilla Pd (Pd version 0.54.1 straight from the Arch repos) it immediately segfaults when trying to open the pd graphics subpatch (which presumably loads hello-gui.pd_lua in the pdlua subdir). Here's the gdb backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78ba0b5 in realloc () from /usr/lib/libc.so.6
(gdb) bt
watchdog: signaling pd...

#0  0x00007ffff78ba0b5 in realloc () from /usr/lib/libc.so.6
#1  0x0000555555603539 in resizebytes (old=<optimized out>, oldsize=1, 
    newsize=12) at /usr/src/debug/pd/pure-data-0.54-1/src/m_memory.c:52
#2  0x00007ffff72fc5fa in start_path () from ./pdlua.pd_linux
#3  0x00007ffff7327d95 in luaD_precall () from ./pdlua.pd_linux
#4  0x00007ffff730c897 in luaV_execute () from ./pdlua.pd_linux
#5  0x00007ffff7329739 in f_call () from ./pdlua.pd_linux
#6  0x00007ffff7305ccc in luaD_rawrunprotected () from ./pdlua.pd_linux
#7  0x00007ffff733b94a in lua_pcallk () from ./pdlua.pd_linux
#8  0x00007ffff7302bae in pdlua_gfx_repaint () from ./pdlua.pd_linux
#9  0x00005555555b31c1 in canvas_map (x=0x5555557afce0, f=<optimized out>)
    at /usr/src/debug/pd/pure-data-0.54-1/src/g_canvas.c:801
#10 0x000055555560a6c1 in pd_typedmess (x=0x5555557afce0, s=<optimized out>, 
    argc=<optimized out>, argv=<optimized out>)
    at /usr/src/debug/pd/pure-data-0.54-1/src/m_class.c:1087
#11 0x000055555560b331 in binbuf_eval (x=<optimized out>, 
    target=0x55555579ab60, argc=<optimized out>, argv=<optimized out>)
    at /usr/src/debug/pd/pure-data-0.54-1/src/m_binbuf.c:764
#12 0x000055555561b63f in socketreceiver_read (x=0x555555757420, fd=24)
    at /usr/src/debug/pd/pure-data-0.54-1/src/s_inter.c:698
#13 0x00005555556110b4 in sys_domicrosleep (microsec=microsec@entry=0)
    at /usr/src/debug/pd/pure-data-0.54-1/src/s_inter.c:241
#14 0x0000555555613073 in sys_pollgui ()
    at /usr/src/debug/pd/pure-data-0.54-1/src/s_inter.c:1051
--Type <RET> for more, q to quit, c to continue without paging--
#15 0x0000555555618496 in m_pollingscheduler ()
    at /usr/src/debug/pd/pure-data-0.54-1/src/m_sched.c:348
#16 m_mainloop () at /usr/src/debug/pd/pure-data-0.54-1/src/m_sched.c:429
#17 0x00007ffff7843cd0 in ?? () from /usr/lib/libc.so.6
#18 0x00007ffff7843d8a in __libc_start_main () from /usr/lib/libc.so.6
#19 0x000055555556c0c5 in _start ()

Looks like a memory allocation issue to me. Can you reproduce this?

Seems plausible that there's a bug there, I recently modified the paths system. I haven't had this crash yet, but I bet it will come out if I turn on AddressSanitizer.

The 3d oscilloscope is by @ben-wes, I don't have it myself. He also made a .obj model loader with it, pretty insane!

Here's the circle slider

local circle = pd.Class:new():register("circle")

function circle:initialize(sel, atoms)
    self.slider_position_x = 75
    self.slider_position_y = 75
    self.inlets = 1
    self.outlets = 1
    self.gui = 1
    self:set_size(150, 150)
    return true
end

function circle:mouse_down(x, y)
    self.mouse_down_x = x;
    self.mouse_down_y = y;
    self.mouse_down_slider_x = self.slider_position_x;
    self.mouse_down_slider_y = self.slider_position_y;
end

function circle:mouse_drag(x, y)
    local width, height = self.get_size()

    local dx = x - self.mouse_down_x
    local dy = y - self.mouse_down_y

    local new_x = (self.mouse_down_slider_x + dx) - width / 2;
    local new_y = (self.mouse_down_slider_y + dy) - height / 2;

    local distance = math.sqrt(new_x^2 + new_y^2)
    local angle = math.atan(new_y, new_x)

    distance = math.max(0, math.min(width / 2, distance))

    self.slider_position_x = math.cos(angle) * distance + (width / 2)
    self.slider_position_y = math.sin(angle) * distance + (height / 2)

    self:outlet(1, "list", {self.slider_position_x / width, self.slider_position_y / height})
    self:repaint()
end

function circle:paint(g)
    local width, height = self:get_size()

    g.set_color(Colors.background)
    g.fill_all()

    g.set_color(Colors.foreground)
    g.fill_ellipse(self.slider_position_x - 4, self.slider_position_y - 4, 8, 8)

    g.stroke_ellipse(1, 1, width - 2, height - 2, 1)
    g.draw_line(width / 2, 0, width / 2, height, 1);
    g.draw_line(0, height / 2, width, height / 2, 1);

    g.draw_line(self.slider_position_x, self.slider_position_y, self.slider_position_x, height / 2, 2);
    g.draw_line(self.slider_position_x, self.slider_position_y, width / 2, self.slider_position_y, 2);
end

timothyschoen avatar Feb 26 '24 23:02 timothyschoen

And is there a build of PlugData with the modified pd-lua that I can download somewhere?

any nightly build (0.8.4) or even the latest stable release (0.8.3).

we could maybe put this on the agenda for a future Purr Data GSoC project, for instance.

if you don't mind me asking, what is the current situation of Purr Data development. It seems pretty quiet, nothing really happened in the last year (and no GSoC, huh?). I also realize most active developments did happen during summer, cause of GSoC, but I don't remember what happened in 2022. Also, the situation with Pd-L2ork is confusing, they have an independent development, and would a GSoC be able to attend both projects?

Anyway, I wonder if PlugData could also apply and get help for GSoC contributions, do you know anything about it @timothyschoen ?

porres avatar Feb 26 '24 23:02 porres

@agraef Turns out this is a platform specific difference. Calling realloc without allocating beforehand is allowed on macOS, but not on Linux.

Should be fixed with 2a62d4e

timothyschoen avatar Feb 27 '24 00:02 timothyschoen

attaching a current version of the oscilloscope (no guarantees concerning lua code quality!):

3d_osci_pdlua.zip

i admit that i switched to Gem for my visuals for now. but these projects here are absolutely incredible (pdlua and @timothyschoen's graphical extensions)! thank you so much for this!

the .obj loader was actually patched in vanilla pd (based on [text]) and i don't get it to run properly anymore right now. :/ but it used the same "engine" and drew lines for .obj lines and faces.

ben-wes avatar Feb 27 '24 00:02 ben-wes

My last big commit (promise!)

This brings signal processing support, for example:

local lua_sig = pd.Class:new():register("lua_sig")

function lua_sig:initialize(sel, atoms)
    self.inlets = {SIGNAL, DATA, DATA}
    self.outlets = {SIGNAL}
    self.phase = 0
    return true
end

-- dsp method is called when processing is about to start
function lua_sig:dsp(samplerate, blocksize)
    self.samplerate = samplerate
end

-- perform method gets called with a table for each signal inlet
-- you must return a table for each signal outlet
function lua_sig:perform(in1)
    local frequency = 220
    local amplitude = 0.5

    local angular_freq = 2 * math.pi * frequency / self.samplerate

    -- Loop through each sample index
    for i = 1, #in1 do
        in1[i] = amplitude * math.sin(self.phase)
        self.phase = self.phase + angular_freq
        if self.phase >= 2 * math.pi then
            self.phase = self.phase - 2 * math.pi
        end
    end

    return in1
end

This is backwards compatible: if you use inlets = 1, it will just create a data inlet. The source and API for this are pretty much directly stolen from ofelia.

timothyschoen avatar Feb 27 '24 02:02 timothyschoen

Turns out this is a platform specific difference. Calling realloc without allocating beforehand is allowed on macOS, but not on Linux.

Sure is (from man realloc):

If ptr is NULL, then the call is equivalent to malloc(size), for all values of size.

But you can clearly see that something fishy was going on in the gdb backtrace:

#1  0x0000555555603539 in resizebytes (old=<optimized out>, oldsize=1, 
    newsize=12) at /usr/src/debug/pd/pure-data-0.54-1/src/m_memory.c:52

Unfortunately, the old pointer value isn't shown in the backtrace, but the oldsize of 1 gives it away. So either there was some unitialized memory being passed there, or something is wrong with Pd's resizebytes() -- which I consider highly unlikely, given how old and well-tested this code is.

Anyway, your commit https://github.com/agraef/pd-lua/commit/2a62d4eb1e4a486f91d9959849e5d140a16d53c4 indeed seems to have fixed this bug, and the subpatch now opens correctly in vanilla Pd and appears to work alright (I still have to try the other examples).

However, the plugin still doesn't load in Purr Data, it shows the following error in the console (from libdir_loader, apparently):

error: ./pdlua.pd_linux: ./pdlua.pd_linux: undefined symbol: glist_getzoom

We still need to get this fixed before I can merge this. The solution would be, as I suggested earlier, to sprinkle the source with #if PURR_DATA and provide dummy implementations of all the graphic routines, so that pd-lua doesn't try to dl-link against vanilla Pd functions which don't exist in Purr Data. And also to avoid compile errors on Windows, when linking against Purr Data. Can you still do this, please?

Other than that, the PR looks fine to me, so I'm inclined to merge it, after I have given it some more thorough testing. Of course it would be good to include some more graphics examples in the distribution. And I'll need to update the tutorial to discuss the new features so that people know how to use them. Which should then be merged back into the version that you include with plugdata.

agraef avatar Feb 27 '24 06:02 agraef

This brings signal processing support

Wow. This is nice! I have been thinking about this myself some time ago, but shied away from it. ;-) This would certainly be useful to Purr Data users as well, so we really need to get this version working with Purr Data even if only for that feature.

image

agraef avatar Feb 27 '24 06:02 agraef

that was a sudden appearance of signal rate here - really cool! fyi ... i adapted this oscilloscope to this now and (maybe/hopefully) cleaned it up a bit.

could get variable size, sampling intervals and buffer size. but i'll leave it here like this for now:

image osci3d.pd_lua.zip

ben-wes avatar Feb 27 '24 10:02 ben-wes

that was a sudden appearance of signal rate here - really cool! fyi ... i adapted this oscilloscope to this now and (maybe/hopefully) cleaned it up a bit.

could get variable size, sampling intervals and buffer size. but i'll leave it here like this for now:

image osci3d.pd_lua.zip

Oh sweet, I had to apply a bit more data reduction to make it work inside plugdata, but really awesome!

timothyschoen avatar Feb 27 '24 12:02 timothyschoen

here's one little funny thing happening when dynamically resizing the canvas in vanilla Pd: the cords are not redrawn in this case: Screenshot 2024-02-27 at 23 02 41

ben-wes avatar Feb 27 '24 22:02 ben-wes

the cords are not redrawn in this case:

seems you need canvas_fixlinesfor

https://github.com/pure-data/pure-data/blob/0259d00373b9e6f3bc1d76eebc5b243283ca7063/src/g_canvas.h#L490

porres avatar Feb 28 '24 04:02 porres

that was a sudden appearance of signal rate here - really cool!

Yep, that was a pleasant surprise. :)

@ben-wes, thanks a bunch for this nice example! Can you also post the beefed-up version with all the extra messages on the last inlet?

agraef avatar Feb 28 '24 09:02 agraef

Can you also post the beefed-up version with all the extra messages on the last inlet?

sure! i put it here now: https://github.com/ben-wes/osci3d-

ben-wes avatar Feb 28 '24 10:02 ben-wes

Awesome! We should include that in the pd-lua examples somewhere, if you don't mind. I should also link to your repo in the tutorial, so that people know where to get the latest version.

seems you need canvas_fixlinesfor

Yes, that should probably be exposed in the graphics interface. @timothyschoen?

agraef avatar Feb 28 '24 10:02 agraef

Awesome! We should include that in the pd-lua examples somewhere, if you don't mind.

@agraef : sure, would be happy about it! i guess, i should add some checks for the messages then and limits to make it a bit less error prone. will do that ... but feel free to include it in any way you want.

ben-wes avatar Feb 28 '24 12:02 ben-wes

seems you need canvas_fixlinesfor

Yes, that should probably be exposed in the graphics interface. @timothyschoen?

My goal is to hide all the pd specific calls behind a more generic graphics interface. So instead of exposing fixlinesfor, I've added a call to canvas_fixlinesfor when the user calls set_size. That should fix it!

timothyschoen avatar Feb 28 '24 12:02 timothyschoen

@timothyschoen That did it! Works perfectly now:

osci3d

But maybe you could squash those 3 commits into one? No need to riddle the history with trivial fixes for editing blunders. Just sayin. :)

@ben-wes: I think that the Lua code is perfect right now as an example, it's more readable that way. But that shouldn't keep you from improving it, of course.

agraef avatar Feb 28 '24 12:02 agraef

@timothyschoen That did it! Works perfectly now:

osci3d osci3d

But maybe you could squash those 3 commits into one? No need to riddle the history with trivial fixes for editing blunders. Just sayin. :)

@ben-wes: I think that the Lua code is perfect right now as an example, it's more readable that way. But that shouldn't keep you from improving it, of course.

Good call, done

timothyschoen avatar Feb 28 '24 12:02 timothyschoen