Setting dynamic attributes to expressions?
-
I've been playing a bit with setting dynamic attributes to expressions.
I'm rather confused by the results. Here is a test plugin:# t1.rb - test code #1 # require 'sketchup' def t1 Sketchup.send_action('showRubyPanel;') sel = Sketchup.active_model.selection cd = sel[0].definition dict = 'dynamic_attributes' { 'str' => 'abc', 'num' => 42, 'exp' => '=num+1' }.each {|k,v| cd.set_attribute(dict, k, v) } da = cd.attribute_dictionaries[dict] da.each {|k, v| puts "k='#{k}', v='#{v}'" } end UI.menu('PlugIns').add_item('T1') { t1 }
When I select a component and run this plugin, the console prints:
k='exp', v='=num+1' k='num', v='42' k='str', v='abc'
If I then open up the Component Attributes window and re-select the component, I see my keys and values listed in the Custom section. However, this isn't exactly what I want.
Specifically, I'd like exp to show up as 43 when the =fx button is selected and =num+1 if it is not. Instead, it shows up as =num+1 in both modes.
However, if I then click on =fx, click in the exp text box, and hit return, I get the result I wanted. So, what do I have to do in the API to get this result?
-
On a related note, if I use an attribute name which contains an upper-case letter, the attribute is created, but the value is empty.
-
Rich,
You can set attributes and their formulas using the API, but it's not a documented process, unfortunately. Here's a kick start.
All of the attributes are stored inside an AttributeDictionary called dynamic_attributes, as you discovered. In addition to the attribute's value, there are a series of "meta attributes" that describe properties of the DC attribute. These start with underscores, and they must be defined to work properly with the DC plugin. (They attribute keys are all lowercase.)
Let's say you have an attribute called "FavoriteColor" that you manually create in the Component Attributes window. These are the attributes that the DC plugin would create if you made it end user editable (and therefore, these are the attributes your plugin would need to make to do it in Ruby code...)
favoritecolor = "Red" # The raw value of the att.
_favoritecolor_formula = "" # The formula, if set.
_favoritecolor_label = "FavoriteColor" # The "cased" name of the att
_favoritecolor_access = "TEXTBOX"access = "NONE" if consumers can't see or edit this attribute
= "VIEW" if consumers can see this attribute
= "TEXTBOX" if consumer can enter a value for this attribute
= "LIST" if consumers can select a value from a list
_favoritecolor_options = "Pink=pink&Red=255,0,0&Blue=blue" # url encoded list
_favoritecolor_units = "STRING"
_favoritecolor_formlabel = "Favorite Color"I wish I had complete documentation for all of this to share, but the best I can offer at the moment is a willingness to help. The best thing to do would be to use an attribute reading script to watch what attributes get set when you do things in the DC UI.
Here's a code snippet that demonstrates creating some new attributes on the Sang component...
UI.menu("Plugins").add_item('Make Sang Red') { # Assumes that sang is the 1st entity in model. sang = Sketchup.active_model.entities[0] sang_def = sang.definition # Override sang's shirt color to red. ("material" # is a special attribute that requires # you to set a formula to "take control" # over the default material the user has painted.) sang_def.set_attribute 'dynamic_attributes', 'material', 'red' sang_def.set_attribute 'dynamic_attributes', '_material_formula', '"red"' # Add a new configurable option to Sang. # (Any attribute that starts with an underscore # is a "meta attribute" that describes behavior.) sang_def.set_attribute 'dynamic_attributes', 'weight', '145' sang_def.set_attribute 'dynamic_attributes', '_weight_label', 'weight' sang_def.set_attribute 'dynamic_attributes', '_weight_formlabel', 'My Weight' sang_def.set_attribute 'dynamic_attributes', '_weight_units', 'STRING' sang_def.set_attribute 'dynamic_attributes', '_weight_access', 'TEXTBOX' # Change the description that shows # up in the configure box with a custom # formula. sang_def.set_attribute 'dynamic_attributes', '_description_formula', '"Sang is now red and weighs " & weight' # There is a global handle into the plugin that # allows you to make the same calls that the # plugin does, like so... dcs = $dc_observers.get_latest_class dcs.redraw_with_undo(sang) }
-
Scott, is there an overview anywhere of the methods we can use with DCs?
-
Thom,
There is not an overview. The internal methods were never intended to be an API, so mucking with them could lead to corrupted DCs. Go forth with caution.
If there are specific things you'd like to accomplish, let me know and I can try to share snippets.
-
Scott
I'm relatively new to SU so forgive my terminology if it's not quite right but this answer & one I got from another forum is helping me with a few things I'm trying to achieve in SU. I have added some custom attributes to the 'add attribute' drop down list in Component Attributes by modifying the component.js file so that I can add custom attribute lists to objects in a way thats quicker than typing them in. However this is only the first step in a series of things I'd like to be able to do & you express a willingness to help so it'd be appreciated if you could point me in the right direction with any of this:
- Is it possible to make the 'users can edit as a text box' a standard option for a custom attribute rather than having to select it?
- Is there any way of stopping an attribute value automatically being copied to all similar objects? I notice that when an attribute such as summary is edited on one object that the value is automatically copied to all however when you go to the next object this value can be over written without affecting the previous entry. I would like to stop the first part so that the value first entered only applies to one object without the need to overwrite it when I get to the next one.
- Is it possible to edit the same attribute on a selection of objects? Say I'd like to select three out of 6 objects and edit an enter the same value for these three & then select the next three out of the six & enter a different value.
Hopefully you will still see this even though it looks like the original posts were done a while ago.
smpfmc
-
@smpfmc said:
It'd be appreciated if you could point me in the right direction with any of this:
Hiya! I'll try my best.
@smpfmc said:
- Is it possible to make the 'users can edit as a text box' a standard option for a custom attribute rather than having to select it?
Not without some fairly-serious Ruby hacking. You could write a custom plugin that would watch for new attributes and set the appropriate attribute to designate them as text editable. Let me know if you're going to pursue this and I could point you in the right direction.
@smpfmc said:
- Is there any way of stopping an attribute value automatically being copied to all similar objects?
If you select the new objects and do a "Make Unique" on them, this will create a ComponentDefinition that is unique to that instance, and you can edit attributes without affecting the rest.
@smpfmc said:
- Is it possible to edit the same attribute on a selection of objects?
Yep. If you have components with attributes of exactly the same attribute names, and you select multiple components at once, the Component Options window will show you these for editing.
Hope that helps!
Cheers,
-Scott
-
I'm getting to like DCs.
Hum... With Ruby, Is it possible to copy the glued face (or the outline) of a selected component and paste-in-place outside the compo and make it visible ? -
You want the facecopy to intersect with the
glued_to
face ?This might work, untested.
<span class="syntaxdefault">def get_glued_bounds_facegroup</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">ci</span><span class="syntaxkeyword">)<br /></span><span class="syntaxcomment"># Arg; ci, a component instance<br /># Return nil if ci is not glued;<br /># or a group with new face you can explode.<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> return nil if ci</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">glued_to</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">nil</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> model </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">active_model<br /> cd </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> ci</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">definition<br /> db </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> cd</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">bounds<br /> </span><span class="syntaxcomment"># get pts in counter-clockwise order;<br /></span><span class="syntaxdefault"> pt0 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> db</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">corner</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># left front bottom<br /></span><span class="syntaxdefault"> pt1 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> db</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">corner</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># right front bottom<br /></span><span class="syntaxdefault"> pt2 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> db</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">corner</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># right back bottom<br /></span><span class="syntaxdefault"> pt3 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> db</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">corner</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># left back bottom<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># get transform of ci;<br /></span><span class="syntaxdefault"> tr </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> ci</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">transformation<br /> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> par </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> ci</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">parent<br /> ents </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> par</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities rescue model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_entities<br /> grp </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> ents</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group</span><span class="syntaxkeyword">()<br /></span><span class="syntaxdefault"> grp</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_face</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">pt0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">pt1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">pt2</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">pt3</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> grp</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">transform</span><span class="syntaxkeyword">!(</span><span class="syntaxdefault">tr</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault">end</span>
Advertisement