Sort components as on screen

Greetings! Is there any way to get a list of components as they are placed on the screen.

Below is the code with which.

mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
ent.each do |e|

I get the list and what comes in response

It looks like this on screen.

Is there any method to get the components in the same order or not? I can think of something to work with coordinates, take a calculation from 0 and read components there. But this seems to be obviously not the right option.

It isn’t clear to me what you mean by “the same order”. If you mean sorted by name then the answer is simply to sort them using the appropriate Ruby sort function. If you mean sorted based on some kind of spatial ordering, you will have to geometrically define what that means, bearing in mind that visual ordering will change as you orbit the model and that:

  • In 3d, two completely separate components might overlap in any direction you choose. for instance, move one of your cubes back in the green direction and then back in the red direction and it mayl overlap both red and green with the one in front.
  • In SketchUp, component instances can overlap without merging.

Some thoughts on the code snippet you provided:

  • All code, including one-shot snippets, should be wrapped in a module so that its variables are not global. You don’t know whether some other sloppy coder has other uses for mod, ent, and sel that might collide with yours. In this specific case the risk is pretty low, but one should follow good practices always so as not to forget at some point.

  • You want a list of components, but you start with all entities in the model. In general, that could contain things other than components, such as loose edges and faces, images, dimensions, labels, … If you really want only ComponentInstances, you must use the grep function to extract just them from the model contents:

comps = ent.grep(Sketchup::ComponentInstance)

If you also want Groups, you will need to do a second grep to gather them. Note that grep is a compiled function and is much faster than any way you could try to isolate desired entities within a loop over ent.

  • since you don’t use it, it isn’t clear why you bother to set “sel” to the current selection.

The code above is an example and is not the one used in the plugin, of course I take everything into account as you described above. It serves to understand how I get the list and what I get in the output.

So my thoughts are correct thanks for the confirmation.

Sort instances based upon distance from ORIGIN

comps = ent.grep(Sketchup::ComponentInstance)
sorted = comps.sort { |a,b| 
  ao = a.transformation.origin
  bo = b.transformation.origin
  ORIGIN.distance(ao) <=> ORIGIN.distance(bo)
1 Like