DC -> Ruby and back again

Whenever I make a Dynamic Component, I feel very constrained… I wish I were just programming this in Ruby. Example, I needed a quadrant atan(), atan2() — it’s in Ruby, but not DC, so I had to create my own as a custom attribute. Or I need to compare different copies of a DC to compute something else. COPY is like being limited to a single index for loop. And attribute sharing is both limited (±1 level of inheritance) and opaque (random attributes are shared behind the scenes). Not to mention debugging, code organization, function encapsulation, etc.

So I can imagine a rich interface between the DC “porcelain” (esp. attribute editing and the interact tool) and a Ruby geometry plugin, including support for animate, etc. I understand from this discussion, that as of a couple years ago this simply wasn’t possible and other methods of user interaction were preferred by most plugin authors. Has this changed at all?

What’s a suitable workaround for wanting users to be able to use the “Interact” tool? Is there any callback possible from Interact to Ruby-land?

You can skip the DCs and you will get rid of quite a few bugs and UX issues.

I spent a few months deep into DC’s. I switch to ruby code and finally away from components and now use just groups.

Interestingly I can use Interact because I do write a few attributes that work with DC’s

Speed is up - errors are down - model size is down - I’m happy.

I did have to create a configuration that by default does NOT write the DC attributes. Otherwise the plugin fails Trimble testing.

Cool, sounds like you were able to link Ruby and DC’s Interact tool together. Could you provide a few more details on the attributes/techniques that made this possible? Were you also able to interface with the “Component Options” tool to allow setting parameters?

It is possible to activate the DCInteract tool, but clicking fires the action in “onClick” attributes, not your custom Ruby code. Perhaps a ToolsObserver's onToolStateChange can see when a click occurs, but I do not think what is clicked on. (EDIT hmmm… I think I remember that Rubytools don’t fire this callback. Only native tools?)

Knowing what the classname is, might allow you to subclass it. Then you might alias then override it’s onLButtonUp callback. You’d need to use Ruby inspection methods to find what the reference to the instance is, so you could do something with it. Then if you wanted to have the DC “onClick” function fire, you’d call the aliased method name (or just have a super statement from your overridden callback which calls the ancestor inherited method if your don’t alias it.)

I think you’d be better off and get doing what you want more quickly if you just code your own clicker tool using PickHelper#best_picked inside a tool’s onMouseMove callback. Then when the user clicks, the onLButtonUp callback fires and you can process the picked object.

It is not a tool. It is a dialog box displaying attributes of dictionaries named “dynamic_attributes” attached to the instance and it’s definition.

As I said in the linked thread, …

Because the Dynamic Components extension is not open source, so hacking code to manipulate DCs requires intimate knowledge of DCs and how all their attributes interact, very good knowledge of the SketchUp API and almost expert level at Ruby introspection and reflection. (Ie, there is no technical manual because DCs are supposed to be created in SketchUp Pro only with the DC extension itself.)

1 Like

Thanks. I take it by your quoting your 2 year old comments that the situation hasn’t changed. Really unfortunate that Trimble hasn’t reevaluated this since you wrote that, and given the community some hooks into the “standard” tools and config panels (which isn’t great, but at least is standard). It’s a big cognitive load for plugins all to have their own custom interfaces!

But it sounds like you could in fact use Component Options to set dictionary values, even animated ones interact is animating for you, read those in Ruby to draw geometry, etc. Will take a look.

It takes about that long just to get minor bugs fixed in the DC extension. I do not believe they have any plans to develop it further with more features.

Very complicated plugins need their own interface - I wouldn’t have it any other way.

You can organize information and disable sections that are not used. You can use context sensitive visual help. This plugin has over 600 images and over 500 parameters.

If you tried to build this with DC’s you would bring Sketchup down to its knees !!!

I would argue the cognitive load is significantly higher when building atop a code base with questionable quality, questionable design choices, and no API contract. Sure, the workload can be bigger from building everything properly, but the cognitive load and tech debt is lower when doing so.

These are both fair points for plugin authors, especially those who are are creating complex and widely distributed plugins. But there is another “market”, one that DC’s have tried (and largely failed) to fill — modelers who need unusual animated components with complicated geometry or motions, or custom but easily reconfigurable components (e.g. windows with unusual geometries). Stuff for which the DC toolbox is just far too limited and glitchy. In these case, reusing DC options-setting and interaction tool seems like harvesting low hanging fruit, especially if all the boilerplate for creating and interacting with DC’s programmatically can be abstracted away.

To see how far I could take this, I made a test example DC->Ruby->DC object, really just a toy model, that interactively builds (and unwinds) this contraption:

You can set the base cube size via the component Options panel, and click on it with the interact tool. It was more straightforward than expected. I just edit the dynamic_attributes dictionary, create a simple 0->1->0 animation and associated attribute (_touched), and attach an observer to this dictionary looking for attribute changes and interactions.

This uses very little of the actual DC functionality, other than the Options pane for setting parameters (here, the size of the base cube), and the Interact tool. I could easily see preferring something like this for building a psuedo-DC for things like the offset fan I was asking about earlier. Just far more flexibility for building and transforming new and existing geometry, especially if it gets built into an abstract class that handles much of the DC stuff for you. I still don’t have a good way of “loading” such a psuedo-DC other than in the Ruby console; would be grateful for suggestions.