@Jona I'm sorry for the delay. I think creating a new abstraction for every connection makes sense.
I'm not sure what would be the best way to detect the cord selection yet. an invisible rectangle around the line could work.
I will try to create a simplest demo this week. I'm not sure yet how hard/easy it would be though.
And here's the guide to build the external on Windows.
- Open OF/addons/ofxOfelia/Win32External/ofelia.vcxproj with Visual Studio and build the solution.
- Copy the .dll binaries from OF/addons/ofxOfelia/Win32External/bin into the externals directory.
Let me know if you have questions or if something doesn't work well. Thanks!
@Jona I think you would need to store the connection state of modules as creation arguments just like how you store position of modules. Since now you can dynamically change creation arguments of abstraction using [ofSetCanvasArgs], it is possible to store as many data as you want per module.
So for example, one module can store 6 arguments that are xpos, ypos, myID, myOutletIndex, targetID, targetInletIndex.
And I'm not sure yet if cord connections should be done with dynamic patching. If you do dynamic connections, you need to track the ID(or creation order) of each abstraction in a canvas whenever creation/deletion happens. I think this can be tracked using a [ofLoadFloat] on a main patch which is basically dynamically resizable float array.
Other solution might be to use send/receive to create connections. Then you don't need to track the pd's internal canvas IDs and use custom IDs which may or may not make the work easier.
I agree that creating connections is pretty tricky but I think there should be a possible solution.
I will think about it a bit more deeply next week.
@Jona It's really impressive and seems to work pretty well! (except when dragging on the interface section while it's overlapped with other)
And it would be nice if you do dynamic patching on a separate pd patch. then it would be possible to save/load these patches independently. (just like how Pd basically works.)
Anyways, congrats for finding the solution! Looks like it's at least "theoretically" possible to create a Reaktor-like modular environment using ofelia.
@Jona Hi, I don't know how to dynamically create objects with semicolons but actually you don't need to use semicolons to create the [ofLoadPath2d] object.
The reason semicolons are commonly used in ofelia is for a better readability. And it is completely optional, except when using [ofExpr] or [ofDefine] where semicolons are used to separate multiple equations.
You can just create the object [ofLoadPath2d @path5 rect 580 30] without using the semicolons.
You can read the documentation about this from either [ofWindow] or [ofelia] object's help file.
Please find the [pd common_traits] subpatch on the top right section in the help file.
@ingox Hi, I think ofelia currently can't run on Debian Stretch. (Sorry I should've documented it somewhere)
ofelia uses openFrameworks 0.9.8 which is the latest stable released version but this version seems to be not compatible with the Debian Stretch. It seems there's a problem with the Poco library that OF 0.9.8 uses when compiled on Debian Stretch.
The good news is that the stable version of openFrameworks 0.10.0 is almost(99%) ready to be released.
I'm planning to update ofelia to use openFrameworks 0.10.0 after the stable release then it will be possible to run ofelia on Debian Stretch and Raspbian Stretch without the issue. (hopefully)
@deframmentazione-geometrica In your current patch, the right [timer] will always output 0 on startup because you're measuring time between 2 [loadbang] objects. Therefore [random] will generate the same sequence since it is always seeded with 0.
If what you want is having different sequences whenever you reopen the patch, you can just not seed the [random] at all. But still, it will generate the same sequences whenever you restart pd and then open the patch.
@Jona Nice work! I just made the following changes to ofelia. (Not uploaded to Deken yet.)
- renamed [ofGetDollarArgs] to [ofGetCanvasArgs]
- added [ofSetCanvasArgs] and [ofRemoveCanvas]
The new [ofGetCanvasArgs] and [ofSetCanvasArgs] allow you to get/set the creation arguments of the subpatch or abstraction. So I renamed it to "canvas args" because it also works with the subpatches too. And with [ofRemoveCanvas], you can remove the subpatch or abstraction by sending 'bang' to the object.
Using these objects, you'll be able to dynamically create/change arguments/remove abstractions more easily. You can do this on a separate empty pd patch so you can save/open patches for your modules.
I'm planning to upload v1.0.8 binary in a week or two with a few more updates.
But you can download and build the external yourself using the lastest master branch from https://github.com/cuinjune/ofxOfelia.
Or just let me know if you want me to quickly build and send you the current v1.0.8 external file for Windows.
@Jona Nice trick! I think you should also save the render order btw.
And interesting to see the patch cords demo.
I will consider adding the object that can change abstraction's arguments. It can be called something like [ofSetDollarArgs] I think.
I will inform you if I make any progress.
Hi, ofelia v1.0.7 is now available.
This version includes GLSL shader loader.
GLSL is a C/C++ similar high level programming language for several parts of the graphic card. With GLSL you can code short programs called shaders which are executed on the GPU.
Please try out the examples in the "ofelia/examples/shader" directory.
You can see the full list of shader objects from "ofelia/help-intro.pd".
- added primMode argument to cone, cylinder, plane, sphere mesh command
- added ofShader related objects and help files
- added shader examples to the "examples/shader" directory
- added draggableShapes example to the "examples/input" directory
- Video player and grabber
- SVG loader
- GUI abstractions
More info about ofelia: https://github.com/cuinjune/ofxOfelia
@Jona Looks great! Yes it should be possible. But I think you would need to replace [ofTouchListener] with [_locRcv]s to listen to the event from the main patch so the module interface can listen to the mouse click according to the render order. (Just like how it's done with draggableShapes example)
[_locRcv] should be used one level lower from the main patch. This is to use main patch's local variable name and still communicate with other abstractions. Also note if you use [ofMouseListener], it will not handle multitouch on mobile devices. (it will respond to one finger at a time) That's why I used [ofTouchListener] in pdgui abstraction. But if you're targeting desktop only, [ofMouseListener] is enough and easier to handle.
If you really want to build the modular environment using multiple modules, I suggest you first consider how each module should work commonly and try to first build a minimal module that only has common attributes. (e.g. window bar, interface section, render order..) Then it would be easier to maintain and to create other module later on since you only need to add the non-common part on top of your minimal module.
I think creating such large system requires thorough planning and clear idea of how things should work in the first place otherwise it is likely that you will continuously face many unexpected problems and have to rework many times.
P.S.: You probably know this but your patch currently uses left audio channel only.
You will be able to dynamically create shapes(modules) through this approach although I'm not sure how to save position of the modules and how to delete the abstraction dynamically in vanilla pd. Anyways, I hope this helps!
@cuinjune Hi I quickly created an example patch that may be helpful to you.
It's a simple example of dragging around different shapes.
The shape that shows up more front will have a higher priority for selection.
You will also see some comments I wrote on the patch.
I hope this helps and let me know if you have any questions.
Note: although I used [ofGetLastRenderOrder] in subpatches, It's not necessary in this case since the lastly created [ofHead] will be rendered later(front) anyway if multiple [ofHead]s use the same render order.
@Jona Hi, nice work! Do you want to make the dragged object to appear on top or do you want to make the object that appears on top first draggable? Or maybe both?
What should happen when you drag the overlapped area of 2 or more objects?
I think it's possible to do it by changing rendering order of [ofHead] and there are [ofGetFirstRenderOrder] and [ofGetLastRenderOrder] which can be used to make specific drawing to appear on the background or foreground.
@Jona Hi, I just added the feature to [numbox] as it didn't sound too difficult to implement one. numbox.pd
Thank you for your suggestion. I will add this change officially once it seems to be working stably. Let me know if you find any problem using it.
It is not possible(and won't be anytime soon) to continue the audio stream while resizing the window. What you can do instead is using the hotkey Ctrl -/+ which also resizes the window.
Creating draggable and patchable synth modules sounds very interesting although it will be a huge amount of work. Maybe you're thinking something like a Nord Modular or a Reaktor? I also once thought about creating a patchable environment in ofelia via dynamic patching. But there will be so many problems to solve like how to accurately keep track of objects and connections, how to deal with patch saving and loading and so on.. But I'm still keen on finding the good solution.
It will be a lot easier if you allow users to create a limited number of modules so you don't have to dynamically create/destroy modules and each module can have its own unique ID so you can make a connection using it. And even easier if you have a fixed number of modules like Korg MS-20 since you only need to deal with connections of patch cords and parameters of the module. And the easiest would be to create something like a groovebox or a synth which has a fixed internal connection and all you need is to handle the existing parameters.
Thanks for reminding me this. I will think about the ways to create patchable environment again soon. (although there's no guarantee of finding the solution)