Attributes in Sketchup - Probably a stupid question
-
Hello,
For some reason, I can't retrieve attributes associated to a component. I have the following:
def fdarm
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
$entity = sel[0]
UI.messagebox($entity.get_attribute('Test', 'price').to_f)
end
fdarmIt returns "0.0". I select a component that has the value 3 for the attribute price in the dict "test".
What am I doing wrong?
Thanks
Frank
-
Hi Frank!
I don't know, but could it be, that get_attribute() is case sensitive? You are writing "test" but 'Test' in your UI.messagebox?!
Just an idea...
-
I tried that. I create dict and name without capital letter, same thing. I am not sure if get_attribute is case sensitive, but I have another problem somewhere.
-
I tried everything in lower case...the problem stays. Seems to simple...but just can't get thru this.
-
Try using the Ruby Console for testing:
Sketchup.active_model.selection[0].get_attribute('test', 'price', -666.666)
If the selected object does not have that dictionary OR if it does then NOT that key you get -666.666 [unless the value IS -666.666 ]
Any dictionary name IS probably always going to be 'case sensitive' so 'test' and 'Test' are two separate dictionaries, as are the names of keys, like 'price' and 'Price'...Another way to do this is to get the object's dictionary and then its keys/values...
Sketchup.active_model.selection[0].attribute_dictionary["test"].each_pair{|k,v|p k;p v;puts}
You'll get an error if there's no dictionary!
Otherwise the keys/values are listed, so at least you know what to test forTo get all of the selected object's dictionaries as a list use:
Sketchup.active_model.selection[0].attribute_dictionaries.each{|d|p d.name}
This testing regime is much easier that writing a whole block of code that breaks, and then trying to find which individual part is bust... at least if you get this part working you can use that with some confidence...
-
This is driving me a little nuts...
It does not appear to be a case sensitive issue. I had this right.The first test returns -666.66 (and I confirm...this is not the value )
The second test returns an error (and I confirm, I see the dict "Test" in the attribute manager)
The third test returns and error Error: #<NoMethodError: undefined method `each' for nil:NilClass> . This one...I am not sure what to think of.I know I am doing something stupid, just don't know what yet. Maybe the attribute manager plugin I use is wrong. Also, I use the free version of Sketchup.
-
@fdarma said:
I know I am doing something stupid, just don't know what yet. Maybe the attribute manager plugin I use is wrong. Also, I use the free version of Sketchup.
There is a big difference between a component's definition and an instance of that definition, which is instantiated into the model.
If you have attached the dictionary to the component definition, then attempting to access it via ANY one of it's instances, you must do:
ent.definition.get_attribute('Test', 'price').to_f
Otherwise, if you want each instance to have it's own dictionary, then you must be sure that you are attaching your dictionary to an instance, not the definition.
Also do not use global $vars. If you are inside a method, you can simply use a local var.
If you are within a custom class or module, you can use an @var or @@var.UI message boxes are bad for debugging, because if you do not get the argument to produce a valid string, the
UI.messsagebox
method will itself sometimes fail silently.Instead, use the Ruby Console (as TIG said,) and output debug strings using the
puts()
method. -
The results of the test show me that the selected object has NOT got any attribute_dictionaries, let alone one named 'test'.
As Dan says... if you have added the attributes to a component-definition the selected component-instance will NOT have them.
Theinstance.definition.get_attribute()
will get them because you are looking in the right place, so try this revised code to reveal if this is the case...
Sketchup.active_model.selection[0].definition.get_attribute('test', 'price', -666.666)
and to show all
Sketchup.active_model.selection[0].definition.attribute_dictionary["test"].each_pair{|k,v|p k;p v;puts}
and all dictionaries attached to the definition [in case it's 'Test' NOT 'test']
Sketchup.active_model.selection[0].definition.attribute_dictionaries.each{|d|p d.name}
-
Boom! You got it.
Well, I have no idea that such an instance definition existed. I guess it allows to control many components at the same time.
Also, I have no idea why the "sketchupattributemanager" plugin attaches the attributes to the component definition and not the component itself. But I found another plugin by Rick Wislon that attaches and retrieve at the "right" place...Is there a plugin out there that manages component attributes, creates reports, ectc?
Thanks a lot for your help. I'll start reading about instance definition to make sure I understand what this is.
Also, thanks for your advise on debugging and syntax. I'll do just that.
-
@fdarma said:
Well, I have no idea that such an instance definition existed.
On that topic, a detailed breakdown of how instances and definitions work in SketchUp: http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/
If you are fresh to SketchUp plugins I recommend you also check out this: http://www.thomthom.net/thoughts/2012/01/golden-rules-of-sketchup-plugin-development/
Advertisement