Selecting Specific Entity, Group or Component (By Name)


#1

Not sure if it is on the ruby end or if can be done in c. Is there a way to find a specific component in a model by its definition?

Also this is from the ruby api. If [0] assumes the first entity, is there a way to get the last added entity or component?

# Assumes that the board group is the first entity in the model.
board = Sketchup.active_model.entities[0]

How can I search for an in-model component (on Mac)?
Traversing through Entities in a Group
#2

you can use -1 by that I mean

entities[-1] 

john


#3
Sketchup.active_model.entities[-1]

is the last added entity in the model’s entities collection.

Sketchup.active_model.active_entities[-1]

is the last added entity in the current context’s collection.

Sketchup.active_model.definitions[-1]

is the last added definition [which you must remember might be a component, group or image].

[0] is a synonym of .first in the list.
[-1] is for .last in the list.
You count forwards in the list thus:
[1] for the second in the list etc.
and backwards in the list thus:
[-2] for the last but one etc.


#4

Thank you for your help.


#5

Can you search for components by name?


#6

[quote=“ecw, post:5, topic:11469, full:true”]
Can you search for components by name?
[/quote] Of course…

componame="MyLovelyComponent"
compo = Sketchup.active_model.definitions[componame]
if compo
  puts "#{componame} found: doing something else..."
  ### do something with 'compo' definition
else
  puts "#{componame} does NOT exist!"
  return
end

Can I suggest you install and read the code in many of the available ‘free’ Plugins.
They are usually not encrypted and will include many of the SketchUp API methods you seek…
Do not copy them verbatim, but use them to inform your own ideas…


#7

See: Sketchup::DefinitionList.[]

Because you are asking about filtering and searching, (and the API docs do not actually say so,…) I’ll assume you do not know that most SketchUp API collection classes mix in the Ruby Enumerable library.

So say that wasn’t exactly the definition name that you wanted to find, but one of a certain definition’s instances.

Using the definition list subscript method, you get the definition reference, then use one of the Enumerable search methods to find the exact instance by either guid or instance name (which can be different from, but based upon, it’s definition’s name.)

dlist = Sketchup.active_model.definitions
cdef = dlist["PocketDoor"]
if cdef # test for nil (not found)
  if !cdef.instances.empty?
    obj = cdef.instances.find {|i| i.name == "PocketDoor - Master Bath" }
  else
    obj = nil
  end
end

EDIT: (Adding this note on zooming to a found object, because of a post in another thread.)

Once the object is found, to zoom extents around the entity use:

Sketchup.active_model.active_view.zoom(obj) unless obj.nil?

ADD: For how to find a group instance by name, see this post further down the thread.


Locating Components Within the Model
Is there an extension to instantly access deeply nested geometry?
RUBY: how to change a DC attrribute value of an instance
Explode components in the IFC up to a certain level
Dynamic component count to text file
Dynamic component count to text file
Traversing through Entities in a Group
Anyone know of a plugin or plugins that will do Search and Replace on layer and/or component names?
Adding labels to specific faces of a model
Learning to make a plugin/extension
#8

As @DanRathbun explained…
There are TWO names for what you might term a ‘Component’.
The name of the Component-Definition itself as displayed in the Components Browser, in Entity Info, also and available via model.definitions[...] - and the name of a Component-Instance - also seen in Entity Info.
A definition might have several instances - each can have its own instance-name, while the definition itself has one name.
Dan’s code extracts the instance names, which have a certain name…


#9

It actually finds the first match only,… to return all matches use find_all, instead of find.


#10

So it’s
instance name versus instance names
:innocent:


#11

This tips are same for Groups? Like search a especific group and rotate them.


#12

Very similar for groups, because groups are disguised components.
That means they have definitions. And their definitions have a separate name attribute, than the group instances.

But there are a few quirks. The group.description method is an wrapper for group.definition.description. (So like a component instance, they share their definition’s description attribute.)

So to find groups through the definition list, we need to filter out the definitions for images and normal components.

dlist = Sketchup.active_model.definitions
grps = dlist.find_all {|d| d.group? }
return if grps.empty? # test for empty array (not found)
  
gdef = grps.find {|d| d.name == "PocketDoor" }
if gdef # test for nil (not found)
  if !gdef.instances.empty?
    gdef.instances.find {|i| i.name == "PocketDoor - Master Bath" }
  else
    nil
  end
end

OK?

But you can also simplify the code by combining boolean arguments in the find and find_all blocks, and other test expressions:

dlist = Sketchup.active_model.definitions
gdef = dlist.find {|d| d.group? && d.name == "PocketDoor" }
if gdef && !gdef.instances.empty?
  gdef.instances.find {|i| i.name == "PocketDoor - Master Bath" }
else
  return nil
end

The find iterator will return nil if no match is found. (But be careful, as the find_all iterator always returns an array, so it will be an empty array if no matches are found.)

So to wrap it up in a method:

def find_group_by_name(
  definition_name = "Group#1",
  instance_name   = ""
)
  #
  if !definition_name.is_a?(String) || !instance_name.is_a?(String)
    raise(TypeError,"String arguments required.",caller)
  end
  #
  dlist = Sketchup.active_model.definitions
  gdef = dlist.find {|d| d.group? && d.name == definition_name }
  if gdef && !gdef.instances.empty?
    gdef.instances.find {|i| i.name == instance_name }
  else
    return nil
  end
  #
end ###

Anyone know of a plugin or plugins that will do Search and Replace on layer and/or component names?
Traversing through Entities in a Group
MOving objects and sticky connections between them-can it be done with Ruby?
Group.to_component method is not working correctly
Selecting Groups by Name