How to get all entities with the specific tag?

I want to know which entities will be affected after the hidden state of the tag is changed. What’s the fastest way to get it?

Perhaps:

entities_will_be_affected = entities.select{|e| 
  e.respond_to?(:layer) && e.layer == tag_in_question
}
2 Likes

Here is sample code to select entities on active tag only

module DeveloperName
  module TagSelection
    class Main
      def initialize
        model = Sketchup.active_model
        @selection = model.selection
        @entities = model.entities
        @active_layer = model.active_layer
        @tag_entities = []
      end

      def activate
        entites_on_active_tag
        puts @tag_entities

        @selection.add @tag_entities
        Sketchup.active_model.select_tool(nil)
      end

      def entites_on_active_tag
        @entities.each do |entity|
          next unless entity.layer == @active_layer

          @tag_entities << entity
        end
      end
      # # #
    end # class
    unless defined?(@loaded)
      UI.menu('Plugins').add_item('Select entities from active tag') do
        Sketchup.active_model.select_tool(DeveloperName::TagSelection::Main.new)
      end
      @loaded = true
    end
  end # extension submodule
end # developer namespace

Note: On the layer observer found HERE I can’t see an observer which activates when the tag is visibility is changed. :confused:

Will #onLayerChanged detect tag visibility change?

Considering, that the “recommended” active layer (tag) is “always” the Layer0 (Untagged), and the active layer(tag) visibility can not be changed, your example does not make too much sense in this topic context to me. :wink:

2 Likes

Thanks a lot. It seems I still have to traverse all the entities in model and in components, and check each one’s layer.

I was expecting a function like layer.used_entities to get the related entities after the layer changed.

1 Like

Just a remark:
Whether or not a particular element is “really” visible is affected not only by the associated “Tag” but also: by the folder containing the “Tag”, the element’s own visibility, the visibility of the element containing the element , and finally can be different scenes by scenes.

You may check the #drawing_element_visible? method, too.

4 Likes

Both onLayerChanged and onElementModified can detect tag visibility change.

2 Likes

Yes, drawing_element_visible is really helpful , but I need to support SketchUp 2017, so it’s not compatible.

1 Like

You mean which entities has that tag? Or do you want to take into account child entities of groups/components with that tag?

looks likes its supported since v 6…

It’s a “little” different than what we were talked about. :wink:

Alas, that’s not how layers/tags are implemented. Each entity can point to a single tag and thereby use its settings, but tags have no pointer the other way; they have no record of what entities are using them. So, traversing the entire model is the only way to find what uses a particular tag.

This one-way relationship is a deliberate aspect of how layers in SketchUp were originally conceived: they are consulted by the rendering engine as each entity is considered for drawing. Drawing inherently involves walking through all the entities. There has been a lot of discussion of other/additional semantics for tags. It seems likely that some other facility could be implemented at some point to serve these purposes.

2 Likes

The second one. I need to deal with the child entities. But also I think the first one is enough.I can look into each component if I need.

You’ll need to use a conditional branching statement to decide which code pattern to use.
In this situation you can use “duck-typing” as the conditional expression:

if model.respond_to?(:drawing_element_visible?)
  # use SU 2020+ code pattern
else
  # use pre-2020 code pattern
end

But there is also a quirk in that the Page#use_hidden_objects? query method was not implemented until SU 2020.1, despite the separation between hidden objects and primitives in the 2020.0 release.

We would expect that any user still on v2020 would have updated to the latest release in that version, but some user lag behind in updating. So code defensively.

2 Likes