I need to find all the specified components in the model, the current method I am using iterates through all the entities and can cause slowdown, here is my code:
ent.each do |entity|
if entity.typename=="ComponentInstance"
if entity.description=="#{faceIds[i]}"
aa = entity.get_attribute "coordinate","allcoordinate"
finalInfo_renew[i]<<aa
end
end
end
Now that the model is built with components placed in the same layer, how can you quickly find all the components in a layer without having to traverse the entire model.
You don’t have to create more than one thread, if you made a mistake or you want to add something you can edit it, but its not necessary to create a new one it´s against the forum rules.
This should work. Change “Existente” by your target layer name.
model = Sketchup.active_model
desiredData = []
layerNameToMatch = 'Existente'
model.entities.grep(Sketchup::ComponentInstance).each do |entity|
desiredData.append(entity) if entity.layer == layerNameToMatch
end
all your components will be in “desiredData” array
Much better to use grep as @rtches suggesting. However:
layerNameToMatch is a String, Comparing it to Sketchup::Layerwill not give the desired result.
It should be like:
model = Sketchup.active_model
desiredData = []
layerToMatch = model.layers[ 'Existente' ]
model.entities.grep(Sketchup::ComponentInstance).each do |entity|
desiredData.append(entity) if entity.layer == layerToMatch
end
or ( but I guess, it is less effective because string comparison always slow)
model = Sketchup.active_model
desiredData = []
layerNameToMatch = 'Existente'
model.entities.grep(Sketchup::ComponentInstance).each do |entity|
desiredData.append(entity) if entity.layer.name == layerNameToMatch
end
My idea, contrary to Rafa, is not only the root entities but instances in the entire model will be considered.
Again wrong wording: entities are NOT “in a layer”! See: Class: Sketchup::Layer — SketchUp Ruby API Documentation By default, a SketchUp model has one layer, Layer 0 (Named “Untagged” in the UI since SketchUp 2020), which is the base layer. You can’t delete or rename Layer 0. Unlike certain other CAD software packages, entities associated with different layers in SketchUp still intersect with each other. (If you want collections of entities to not intersect, place them in Groups instead.)
You can find all entities where the layer of the entity is set to that layer which have a certain name.
for example, something like this:
def find_ents_by_layer( ents, layer_to_match )
ents.each{|ent|
next unless ent.respond_to?(:layer)
@ents_associated_to_layer<<ent if ent.layer == layer_to_match
if ent.is_a?(Sketchup::Group) || ent.is_a?(Sketchup::ComponentInstance)
ent.make_unique if ent.is_a?(Sketchup::Group)
definition = ent.definition
if !@used_defs.include?(definition)
find_ents_by_layer( definition.entities, layer_to_match )
@used_defs<<definition
end
end
}
end
def collect_ents_by_layer( layer_name )
model = Sketchup.active_model
entities = model.entities
layer_to_match = model.layers[layer_name]
@ents_associated_to_layer = []
@used_defs = []
find_ents_by_layer( entities, layer_to_match )
@ents_associated_to_layer
end
my_ents = collect_ents_by_layer( 'My_layername' )