Variable values in attribute dictionaries
-
I'm fairly new with Ruby so I was wondering if someone could possibly point out what I'm doing wrong in this snippet of code.
I'm trying to assign an incrementing variable as the value in my attribute dictionary for all the entities in my array. I'd like for the value to be different for each entity, but they will share the same attribute dictionary and key.
selection = Sketchup.active_model.selection
i = 0
selection.each { |entity| entity.set_attribute('Bubble','ID',i)
i += 1
}This is what I've come up with so far, but the output is all wonky. IE the first entity in the outliner window is assigned the value 2 when it should be 0. Second entity three and so on. I've tried some while/until loops as well but I haven't been able to get them to work with this. Any help is appreciated!
-
@ssunderland said:
I'm fairly new with Ruby so I was wondering if someone could possibly point out what I'm doing wrong in this snippet of code.
I'm trying to assign an incrementing variable as the value in my attribute dictionary for all the entities in my array. I'd like for the value to be different for each entity, but they will share the same attribute dictionary and key.
selection = Sketchup.active_model.selection
i = 0
selection.each { |entity| entity.set_attribute('Bubble','ID',i)
i += 1
}This is what I've come up with so far, but the output is all wonky. IE the first entity in the outliner window is assigned the value 2 when it should be 0. Second entity three and so on. I've tried some while/until loops as well but I haven't been able to get them to work with this. Any help is appreciated!
That's because you can never be sure of the order of entities in a selection. You would think that they would appear in the order they were created but that is not the case as this little demo will illustrate. The second edge drawn somehow is the first entity in the selection.
-
Thanks for the fast reply. That is interesting..is there a better way to accomplish what I'm trying to do? Possibly in place of using the entities in the selection? Definition maybe, or group them first?
-
@ssunderland said:
Thanks for the fast reply. That is interesting..is there a better way to accomplish what I'm trying to do? Possibly in place of using the entities in the selection? Definition maybe, or group them first?
Placing the entities in a group as they are created seems to work. I created a group of 10 edges then selected the group and added attributes to the group entities. Selecting existing entities and grouping them is no different that just working with the selection.
mod = Sketchup.active_model ent = mod.active_entities sel = mod.selection vue = mod.active_view grp = sel.first i = 0 grp.entities.each {|entity| entity.set_attribute('Bubble','ID',i); i += 1 }
-
That would work if I was drawing the entities in the model. I didn't mention it earlier but they are entities that are imported in a DWG.
n=0
i=0Sketchup.active_model.selection[n].set_attribute("Bubble","id",i); n+=1; i+=1
Would something like that work to select them one at a time in order? So the edges aren't mixed up in the selection?
-
@ssunderland said:
That would work if I was drawing the entities in the model. I didn't mention it earlier but they are entities that are imported in a DWG.
n=0
i=0Sketchup.active_model.selection[n].set_attribute("Bubble","id",i); n+=1; i+=1
Would something like that work to select them one at a time in order? So the edges aren't mixed up in the selection?
No I don't think so because it still depends on the order of the entities in the selection.
-
Also, as objects are edited and they intersect, SketchUp will destroy and create new objects. So if editing is done sometime after you "mark" the objects, some of them may go away, and new objects created that do not have your dictionary ids.
Dictionary Names. It is unwise to use a simple word like "Bubble". You should approach dictionary naming like you would your plugin sub-module namespace. Say, your toplevel author namespace module, that you have chosen
SSU
and the plugin sub-module asBubbler
, then it is smart to name the dictionary after the plugin sub-module qualifying identifier, but replacing the::
scope operator with an underscore "".
So "SSU_Bubbler" for theSSU::Bubbler
plugin module. IF you need more than one dictionary, then the former becomes a prefix, and you add "" and some meaningful suffix. -
@ssunderland said:
` n=0
i=0Sketchup.active_model.selection[n].set_attribute("Bubble","id",i); n+=1; i+=1`
You are missing some basic knowledge of Ruby.
Most of the API collection classes have the library moduleEnumerable
mixed into them.
http://ruby-doc.org/core-2.0.0/Enumerable.htmlIt is usually safer (to avoid fencepost errors, etc.) to use the built-in block form iterator methods.
Sketchup.active_model.selection.each_with_index {|ent,idx| ent.set_attribute("SSU_Bubble","id",idx) }
If you want to process in reverse order, make an array copy of the selection, using
to_a
and theArray#reverse
method:Sketchup.active_model.selection.to_a.reverse.each_with_index {|ent,idx| ent.set_attribute("SSU_Bubble","id",idx) }
However, there is one major rule. Do not delete collection members while iterating the collection. The loop will lose it's place, and strange results occur. In that case, always iterate an array copy of the collection, if your loop must remove or add collection members. This is most often seen while modifying
Entities
collections.
Advertisement