Looping all entities
-
I'm a bit puzzled.
Sketchup.active_model.entities.each{|e|e.erase! if e.valid?}
works but doesn't delete all entitiesSketchup.active_model.entities.to_a.each{|e|e.erase! if e.valid?}
works and deletes all entitiesNow, does this mean that to loop all entities in a model i always have to put them in an array first?
I never have run into any problems before using the first method.Additionaly
f=0 Sketchup.active_model.entities.each{|ent| f+=1 Sketchup.active_model.selection.clear Sketchup.active_model.selection.add ent ent.erase! } puts freturns 4095 (on a 11200 entities model)
whilef=0 Sketchup.active_model.entities.each{|ent| f+=1 Sketchup.active_model.selection.clear Sketchup.active_model.selection.add ent #ent.erase! } puts freturns 11200 (on a 11200 entities model)
I must be missing something essential here...

-
A few points:
- Bulk operations are much faster than single operations.
<span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">erase_entities</span><span class="syntaxkeyword">( </span><span class="syntaxdefault">array_of_entities </span><span class="syntaxkeyword">) </span><span class="syntaxdefault"></span>Is faster than
<span class="syntaxdefault"></span><span class="syntaxkeyword">for </span><span class="syntaxdefault">entity in array_of_entities<br /> e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">erase</span><span class="syntaxkeyword">!<br /></span><span class="syntaxdefault">end</span>But when you want to clear the entire Enitites collection you can just use
<span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">clear</span><span class="syntaxkeyword">! </span><span class="syntaxdefault"></span>- Never iterate the Entities collection directly when you modify it.
<span class="syntaxdefault"></span><span class="syntaxkeyword">for </span><span class="syntaxdefault">entity in model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities<br /> e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">erase</span><span class="syntaxkeyword">!<br /></span><span class="syntaxdefault">end</span>This will make some entities be skipped as you are modifying the Entities object you iterate.
Instead make an array copy of the entities:
<span class="syntaxdefault"></span><span class="syntaxkeyword">for </span><span class="syntaxdefault">entity in model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_a<br /> e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">erase</span><span class="syntaxkeyword">!<br /></span><span class="syntaxdefault">end</span>This will not skip any entities.
Model.entitiesdoes not contain every entity in the model - only the root of the model hierarchy. Entities in Groups and Components are stored in the definitions inmodel.defintions.
But if you want to empty the whole model,model.entities.clear!is still the easiest.
http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/
-
@pout said:
went wrong
What went wrong? Examples?
@pout said:
So I can assume that Sketchup.active_model.entities.each{|e|
...
}
can always be incorrect even when just checking for something?No, just when you modify it. If you just read states and properties there should be no problems.
@pout said:
On point 1, what would be faster
The second - using
.erase_entities. -
ThomThom
Thanks for the fast reply!
I did the test on a single box (not a group nor instance) and even then it went wrong
So I can assume that Sketchup.active_model.entities.each{|e|
...
}
can always be incorrect even when just checking for something (eg. check if the current entity has a certain value in it's attribute dictionary)?On point 1, what would be faster
Sketchup.active_model.entities.to_a.each{|e| check=e.get_attribute'x','y' if check==1 e.erase! end }or
test=[] Sketchup.active_model.entities.to_a.each{|e| check=e.get_attribute'x','y' if check==1 test<<e end } model.entities.erase_entities(test) -
@thomthom said:
What went wrong? Examples?
It goes wrong caused by the fact that the entities object is edited while executing the loop. So as you stated.


@thomthom said:
No, just when you modify it. If you just read states and properties there should be no problems.
Modify (like in push pull) or only when the entity is deleted?
@thomthom said:
The second - using
.erase_entities.In the second case I could use Sketchup.active_model.entities.each (without the to_a) Correct? And if so would that be faster then with to_a?
Thx again!
-
@pout said:
It goes wrong caused by the fact that the entities object is edited while executing the loop. So as you stated.
Yes, this is where you need to use
to_a.@pout said:
Modify (like in push pull) or only when the entity is deleted?
Anything that adds or removed entities to the collection.
@pout said:
Correct? And if so would that be faster then with to_a?
That won't be of much difference. What makes a difference is using bulk methods that affect multiple entities in one operation over methods that affect only one entity at a time.
-
Excellent information.
Thank you ThomThom, much appreciated!
Advertisement