Is there a way to find any hidden objects in the model

Hi,

I am trying to write a method that would tell me if there is any hidden object in the model.

def self.is_any_object_or_geometry_hidden?(entities, path = [])
        entities.each { |entity|
          entity_path = path + [entity]
          if(entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group))
            return(is_any_object_or_geometry_hidden?(entity.definition.entities, entity_path))
          end
          return true if !entity.model.drawing_element_visible?(entity_path)
        }
        return false
      end

and I am calling it with is_any_object_or_geometry_hidden?(Sketchup.active_model.entities)

Even though I have hidden objects in the model the method is always returning false.
What am I doing wrong? or better is there any other way to know if there is any hidden object in the model(instead of this recursive method)?

Instead of searching through the model’s entities, why not search the model.definitions, you can limit the search to just .group? and .image? and by implication any component definitions themselves.
once you have a collection of definitions use definition.instances to test if any of those definition’s instances are .visible?
That way you reduce the search considerably…
As well as .visible? you can also test for .locked? and then any instance‚Äôs assigned tag [layer] that might be ‚Äėoff‚Äô too‚Ķ

1 Like

NOTE

The Sketchup::Model.html#drawing_element_visible? method is currently bugged !

API Issue 764 : Sketchup::Model#drawing_element_visible? will not accept leaf of type Group

It currently will accept only primitives elements.

a. The #each iterator generally always returns the collection object it is called upon.

b. When you need to ‚Äúshort-circuit‚ÄĚ the iteration the break keyword is used. So (if using the #each iterator,) you will need to keep a separate result reference. Ie ‚Ķ

# Issue 764 Workaround
def self.is_any_object_or_geometry_hidden?(entities, path = [])
  #
  result = false
  #
  entities.each { |entity|
    entity_path = path + [entity]
    if entity.is_a?(Sketchup::ComponentInstance) ||
    entity.is_a?(Sketchup::Group)
      if is_any_object_or_geometry_hidden?(
        entity.definition.entities, entity_path
      )
        result = true
        break
      end
    else
      if !entity.model.drawing_element_visible?(entity_path)
        result = true
        break
      end
    end
  }
  #
  return result
end

… and …

# When Issue 754 is fixed
def self.is_any_object_or_geometry_hidden?(entities, path = [])
  #
  result = false
  #
  entities.each { |entity|
    entity_path = path + [entity]
    if !entity.model.drawing_element_visible?(entity_path)
      result = true
      break
    end
    if entity.is_a?(Sketchup::ComponentInstance) ||
    entity.is_a?(Sketchup::Group)
      if is_any_object_or_geometry_hidden?(
        entity.definition.entities, entity_path
      )
        result = true
        break
      end
    end
  }
  #
  return result
end

c. Since the Enumerable module is mixed into the Sketchup::Entities collection class, instead of using the #each iterator, you can use the #any? iterator method …

# Issue 764 Workaround
def self.is_any_object_or_geometry_hidden?(entities, path = [])
  #
  entities.any? { |entity|
    entity_path = path + [entity]
    if entity.is_a?(Sketchup::ComponentInstance) ||
    entity.is_a?(Sketchup::Group)
      break true if is_any_object_or_geometry_hidden?(
        entity.definition.entities, entity_path
      )
    else
      break true if !entity.model.drawing_element_visible?(entity_path)
    end
    #
    false # default return for the block
  }
  #
end

… and …

# When Issue 764 is fixed
def self.is_any_object_or_geometry_hidden?(entities, path = [])
  #
  entities.any? { |entity|
    entity_path = path + [entity]
    break true if !entity.model.drawing_element_visible?(entity_path)
    if entity.is_a?(Sketchup::ComponentInstance) ||
    entity.is_a?(Sketchup::Group)
      break true if is_any_object_or_geometry_hidden?(
        entity.definition.entities, entity_path
      )
    end
    #
    false # default return for the block
  }
  #
end

However, this pattern does not take into account if the Hide Objects or Hide Geometry rendering options have been set true by the user. It only checks the entity’s hidden? property, … not whether it is currently displayed.