All entities in the model?
-
Hi all!
I have a problem... 'Sketchup.active_model.entities' does not return all entities in the drawing... Sub entities (inside groups and component instances) are not included.Is there a simple and reliable method that can return an array of all entities in the current model ???
Thank you! -
SU lists it's entities as a kind of tree, as you've seen. The list of entities can contain groups, which in turn have there own entity lists, etc. If you want a "flat" list, I think you have to do it yourself by crawling the tree and copying the entities into another list. However this can be pretty time consuming if you have a big scene.
-
Think of Sketchup.active_model.entities as the "root directory" in your file system, but for Sketchup objects.
If you created 5 objects in your root directory, you would have 5 files (ignoring the . and .. entries).
Same with Sketchup, if you drew a square face, you would have 5 objects (4 edges and a face).If you created a subdirectory off of your root, and move all the files into it, your root would now only show a single entry (a subdirectory, ignoring the . and .. files).
Same with Sketchup. If you selected the whole face and its edges, and grouped them, Sketchup.active_model.entities would now only contain one item - the Group. You have to drill into the Group to gets it's objects, (group.entities) just like you can cd into the subdirectory from the root to get to the files below.
Now, Sketchup.active_model.active_entities is just a bit different yet. A lot of times, .entities an .active_entities hold the same set of obejcts. This occurs when you are simply viewing the model, at the top level, when doing nothing special. However, once you double click a Group or Component, and you are in EDIT mode for that G or C, now .active_entities will have changed to only give you a view of the "subdirectory files", or, in more proper terms, only the objects that are housed within that G or C.
This is about a basic a picture as I can draw for the hierarchical model that we're talking about.
Todd
-
Wouldn't crawling the entities of .active_model.entities and then the instance definition do the trick? That way you don't have to crawl through nested objects, just run over them once.
(I'm not sure here, but there is a definition for each group? Or is it just for groups which have copies?)
-
You need to "mine" into the groups and any component instance definitions.
I have made some "miners" - e.g. ComponentReporter...
First you pick up loose geometry etc and then compo instances [get that instance's definitions contents] and any groups' contents etc... looping back through each until all are done... grouped groups, groups of compos etc...
Good luck...
-
Traversing component instances seem unnecessary. You get all component definitions from .active_model.definitions. No point going over the several instances of the same definition. Or is there some gotcha's I've missed?
-
Just checked. And it seem to works for groups as well.
def all_entities model = Sketchup.active_model # All loose geometry model.entities.each { |e| yield e } # All group/component geometry geometry model.definitions.each { |definition| definition.entities.each { |e| yield e } } end
You can then do this to make all entities' material red:
all_entities { |e| e.material = 'red' }
-
Thomas, what if a definition exists in the DefinitionList but does not have an instance in the model? Do you still want its entities? I guess it depends of what the use of the collection is.
-
Hi all,
Thomas, thats a nice use of yield inside blocks ... I wasn't aware of that possibility in Ruby!
And Jim seems to be right, component definitions often exist although not instantiated (e.g. that default man in the corner).
And, though Matthieu did not specifically asked for that, I can imagine, that he also is interested in the actual transformations (final placement and scale) of every component instance. At least I would be interested in that information.
But, maybe, the transformation thingy opens a "can of worms"?
best regards, Georg
-
Wow very interesting answers!!!
So, no native ruby method can return this list...@unknownuser said:
Thomas, thats a nice use of yield inside blocks ... I wasn't aware of that possibility in Ruby!
+1 !! And I don't understand... Yield function is very strange... Bref.
Thomthom, your function doesn't work if I want to have a list contains all used component instances in the model.Thank you all for these answers!
-
hm... wonder if we can get an extra function to the code block on this forum so they could be expanded to they don't wrap or scroll.
-
Yes, my code snipped won't give you the entities' relationships to each other. Then you have to travel the tree. I'm working on a plugin at the moment that does that. But group and component transformations gives me headache...
If you need a flat list of all entities, and only those used in the model, this should work:
def all_entities_in_model model = Sketchup.active_model # All loose geometry model.entities.each { |e| yield e } # All group/component geometry model.definitions.each { |definition| if definition.count_instances > 0 definition.entities.each { |e| yield e } end } end
And this method should yield a list of all instances used. (excludes group instances)
def all_used_instances model = Sketchup.active_model # All used component instances model.definitions.each { |definition| if !definition.group? && !definition.image? && definition.count_instances > 0 definition.instances.each { |i| yield i } end } end
Usage:
all_used_instances { |i| i.material = 'red' }
If you want it as an array:
def get_all_used_instances model = Sketchup.active_model used_instances = [] # All used component instances model.definitions.each { |definition| if !definition.group? && !definition.image? && definition.count_instances > 0 used_instances += definition.instances end } return used_instances end
my_array = get_all_used_instances
-
@jim said:
Thomas, what if a definition exists in the DefinitionList but does not have an instance in the model? Do you still want its entities? I guess it depends of what the use of the collection is.
Use ComponentDefinition#instances:Sketchup.active_model.definitions.each do |d| if inss = d.instances # line is correct! inss.each do |ins| # ... end end end
azuby
Advertisement