Can you store Entities as attributes?
-
My question is pretty simple: does anyone know if Entities (specifically, Groups) can be stored as attributes within other Entities?
I ask because the following code
test = layer.set_attribute("layerData", "nodeValueGroup", nvg) puts "set correctly" unless test == nil test2 = layer.get_attribute("layerData", "nodeValueGroup") puts "it's not there" if test == nil
will return
set correctly it's not there
when given a non-nil "nvg", which strikes me as strange. Any help would be greatly appreciated!
Josh
-
Whoops, just realized I put in the code example correctly. It should actually read:
test = layer.set_attribute("layerData", "nodeValueGroup", nvg) puts "set correctly" unless test == nil test2 = layer.get_attribute("layerData", "nodeValueGroup") puts "it's not there" if test2 == nil
-
Attributes can be nil, boolean[true/false], integer[1,2], float[1.2,3.4], string["1234"] or an array [1, "a", 1.2] of any/all of those etc... BUT not things like raw binary code or 'entities'...
Because entities and their id's change with each new session you could give the group an enduring attribute [e.g. a gui or a time-stamp] and look for that within the model.definitions [instances == group?] to find the one group - alternatively for that session only you could get that group's 'id', make it an attribute and then look for that later ? It's possible to link two or more objects by giving them the same 'gui' and matching attributes etc... -
Thanks a lot for reply -- that is good to know.
I need to be able to identify the group in question across sessions. If possible, I'd like to find a way to do this that doesn't involve iterating through all of my model's entities and checking for an attribute. I'm interested in the idea you mention about looking within model.definitions, but I'm going to have to admit that I don't know exactly what you're talking about. Could you possibly explain it a little further?
Thanks a lot for your help!
Josh
-
Attach an attribute to your Group's definition so you can recognize it. Then attach an attribute to the group instance itself.
You can then iterate the model.definitions to look for the definition with your identifying attribute. Once you have found that you can check that definition's instances. (groups can in fact have multiple instances.)
-
Note, there is a bug in Sketchup that makes SU some times return the incorrect definition for a group: http://forums.sketchucation.com/viewtopic.php?f=180&t=19765
-
So: are Groups essentially "internal" Components? How come this:
Sketchup.active_model.definitions[0].class
will return "Sketchup::ComponentDefinition" when Sketchup.active_model.definitions[0] is a group?
What was confusing me is that I thought model.definitions would return a DefinitionList object listing only the model's Components (as defined in the typical sense, ie outside .skm files inserted into the model).
-
Internally Groups and Images are also components. Just variants.
Images have definitions because you can place the same image multiple times in the model.
Same thing with groups, when you copy a group, SU adds another instance of the group's definition. But SU treats them as special and automatically makes them unique when you edit them. (!) Note: when modifying a group via the Ruby API groups are not automatically made unique. This is an old known bug.So when you iterate the definitions list you need to check the
.group?
and.image?
methods to filter out Images and Groups. If you ran over all definitions blindly and processed all definitions you end up processing Images. (Because Images can be accessed like that I managed to make a script that let you control the opacity of Images in the model. Something you can't do normally via the SU UI.) -
I typed this as thomthom did his - I'll publish it anyway
Groups and Component-instances [and Images] are 'almost' the same thing
Both of them share a 'definition' - accessible throughmodel.definitions
.
The items that appear in the 'Component Browser' are all 'Components' and these can have any number of 'instances' placed in the model - all referring back to that original definition...
A Group is meant to be a unique instances of its definition - but, because of some shortcomings in the way Sketchup currently works, it is possible to construe things so that in some circumstances you have more than one 'instance' of the same definition but it is actually a 'group' - that should always be 'unique'.
When you copy a component the copy quite rightly still refers to the the original's definition - if you use 'make_unique' on it it duplicates the definition and splits it off as it's own new definition at that point: but when you copy a group that copy should have a new definition automatically to maintain that group's 'uniqueness' - sometimes it fails...
Groups have some different properties - e.g. you can select it as a 'group' and do things directly to its entities, whereas if it were a component you would need to call its definition first and then get thats entities etc... -
The
group.definition
is a missing method.
However,group.entities.parent
should normally return the group's definition...
There's a possible glitch - thomthom [I think] made this 'catch all' which makes sure there is no error -class Sketchup;;Group # Some times the group.entities.parent refer to the wrong definition. This method checks for this error and locates the correct parent definition. def real_parent if self.entities.parent.instances.include?(self) return self.entities.parent else Sketchup.active_model.definitions.each{|definition| return definition if definition.instances.include?(self) } end return nil # Should not happen. end end
group.read_parent
then certainly returns the group's definition -
Ah ha -- I am starting to understand, thanks a lot!
I have one more question for you: thomthom suggested that I "attach an attribute to your Group's definition so you can recognize it" -- I'm wondering the best way to access the Group's definition. I can't seem to find a method within the Group class or any of its parents that returns an object's definition. Is model.definitions the only way to do this?
-
Awesome -- just stuck that into my code and it seems to be working great. Many thanks to both of you for your help.
Josh
Advertisement