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…
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.