If a simple SketchUp model is built with 2 groups of geometry, and tag a is assigned one and tag b to the other, and if the following code is run:
Sketchup.active_model.entities.select(&:visible?)
An array of two Groups is returned (expected).
If the visibility one of the groups is turned off in Outliner, an array of one group is returned (expected).
If the visibility of one of the tags is turned off in Tags, an array of two groups is returned (unexpected). Note that turning of the visibility of the tag in Tags also turns off the visibility of the corresponding group in Outliner. Can someone help me with an explanation?
… is selecting Drawingelement objects based upon the inverse return value of their boolean hidden property and nothing more. (The visible? method documentation description is a bit misleading.)
Whether you actually see elements in the model view also must take into account whether their assigned layer (tag) or any of this layer’s ancestor layer folders are set to be visible. Also, if any of an element’s ancestral geometric collections that it is contained within or the layers they use (including layer folders) are set hidden, then the element also will not be shown (even though the element’s individual visible property is true.)
There are also 2 rendering options that control whether you see hidden objects (groups and component instances) or hidden geometry (primitives like faces and edges) as dotted outlines.
So you need to go about this task in another way. See:
Continuing Dan’s line of thought, we can go even deeper into the complexity of visibility …
E.g. if (or do) we want to consider whether the object in question is visible on other than currently selected scene (?)
I have added a tag folder to my simple example model. I understand that I would need to traverse the entire graph and provide a longer instance_path array for a more complex model, but in this case, if the following code is run:
mod = Sketchup.active_model
mod.entities.select{|ent|
p ent
mod.drawing_element_visible?([ent])
}
an error is returned:
=>
#<Sketchup::Group:0x00000262a0154668>
"Leaf must be a type of Sketchup::Drawingelement (Line 4)"
Is the leaf not the last (and in this case only) element in the instance_path array? And is a Group not a Drawingelement?
You are right. The example in the #drawing_element_visible? method documentation resulting the same error.
It seams eider the documentation is erroneous or the method itself cannot handle the group or component instance in the root of the model.
As I see, the method is looking for the leaf of the InstancePath, however the InstancePath of the root instance does not contains the optional leaf entity…
You have apparently found a bug. In testing on both 2021 and 2022 I cannot form a valid Sketchup::InstancePath object that has a group as it’s leaf. This also effects passing a coercible array to the method in question.
There are already a number of issues open with this method and the Sketchup::InstancePath class in the API Bug Tracker.
Please file a bug report with a link back to this topic.
An instance path is valid if it has at least one element and consist of groups and instances with exception of the leaf which can be any entity. This method doesn’t check if the path can actually be looked up in the model.
I think the this method will not give a right information here. (or also erroneous )
mod = Sketchup.active_model
group = mod.entities.add_group
path = Sketchup::InstancePath.new([group])
path.leaf
=> nil
Beside that this is not documented, according to the error message above, the #drawing_element_visible? method is “looking for” a leaf.
But, it seams, that proper InstancePath can not be constructed (at least for this method) if the group/instance is on a root of the model.
The hidden_entities method only gives entities at the root, so the “planches toit” group is not in the table of hidden entities, and get_drawingelement_visibility for the component “planche toit terrasse” return “true”
So, we are forced to go through the entire tree of entities to find out if an element is visible or not.
but it’s very heavy to do this in a loop to test the visibility of each entity
One solution I found was to rebuild an array of all hidden entities in the active page (only group and component) and use a function that use this array to know if an entity is visible or not
here the code to rebuild $hiddenIdentities array
def getAllHiddenEntities
$hiddenEntities = []
listHiddenEntities(Sketchup.active_model.entities)
end
def listHiddenEntities(entities, visible = true)
entities.each { | ent |
if ent.is_a?(Sketchup::ComponentInstance) || ent.is_a?(Sketchup::Group)
if !ent.visible? || !visible
setHiddenEntity(ent)
end
end
if ent.is_a?(Sketchup::Group)
listHiddenEntities(ent.entities, ent.visible? & visible)
end
}
end
def setHiddenEntity (entite)
if !$hiddenEntities.include?(entite)
$hiddenEntities.push(entite)
end
end
and when you want to know if a group or a component is visible or not: (sorry is not very elegant, i’m beginner in ruby)
def entityActive?(ent)
if($hiddenEntities && $hiddenEntities.include?(ent))
res = false
else
res = true
end
return(res);
end
i have also this error : Error: #<ArgumentError: Leaf must be a type of Sketchup::Drawingelement>
in this project the the group “comp” testRuby.skp (293.6 KB)
i get the error with this code
def test(entities, path = [])
entities.each { | ent |
if(ent.is_a?(Sketchup::Drawingelement))
puts "its a drawing element #{ent.class.to_s} " # even when it's a Sketchup::group
vis = ent.model.drawing_element_visible?(path + [ent])
end
if ent.is_a?(Sketchup::Group)
test(ent.entities, path + [ent])
end
}
end
test(Sketchup.active_model.entities)
it would seem that a sketchup::group is considered as a drawing element ? puts display : its a drawing element Sketchup::Group []
I don’t know all the subtilities of sketchup yet, I needed to create a material array with for each its list of visible components, so I made a loop starting from the defintionList, its maybe a mistake because with this kind of loop, I couldn’t know the path of a defintion and its entities
The best solution I found was to build a array of hidden elements, and then I can use this array to know the visibility of an element without knowing its path in the hierarchy
I continued to do research to better understand the problem, and with this code (on the project sketchup of my previous post)
def test(entities, path = [])
entities.each { | ent |
if(ent.is_a?(Sketchup::Drawingelement))
pa = Sketchup::InstancePath.new(path + [ent])
puts "its a drawing element #{ent.class.to_s} " + getName(ent) + " valid = #{pa.valid?} leaf = #{pa.leaf.to_s} root = " + getName(pa.root) # even when it's a Sketchup::group
#vis = ent.model.drawing_element_visible?(pa)
end
if ent.is_a?(Sketchup::Group)
test(ent.entities, path + [ent])
end
if ent.is_a?(Sketchup::ComponentInstance)
test(ent.definition.entities, path + [ent])
end
}
end
def getName(entity, id = "")
cm = entity.class.to_s.gsub("Sketchup::", "")
if(cm != "Group" && entity.respond_to?(:definition))
entity = entity.definition
end
if(entity.respond_to?(:name) && entity.name)
name = "#{cm}_#{entity.name}"
else
if(entity.respond_to?(:entityID) && entity.entityID != nil)
name = "#{cm}_entityID_#{entity.entityID}"
else
name = "#{cm}_id_#{id}"
end
end
return(name)
end
I get this result:
test(Sketchup.active_model.entities)
its a drawing element Sketchup::Group Group_comp valid = true leaf = root = Group_comp
its a drawing element Sketchup::Group Group_comp 1 2 valid = true leaf = root = Group_comp
its a drawing element Sketchup::ComponentInstance ComponentInstance_comp 2 valid = true leaf = root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_144 valid = true leaf = #<Sketchup::Edge:0x000000001dc59eb0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_145 valid = true leaf = #<Sketchup::Edge:0x000000001dc59438> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_146 valid = true leaf = #<Sketchup::Edge:0x000000001dc58bc8> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_147 valid = true leaf = #<Sketchup::Edge:0x000000001dc58128> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_148 valid = true leaf = #<Sketchup::Edge:0x000000001dc57598> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_149 valid = true leaf = #<Sketchup::Edge:0x000000001dc56710> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_150 valid = true leaf = #<Sketchup::Edge:0x000000001dc551d0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_151 valid = true leaf = #<Sketchup::Edge:0x000000001dc54348> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_152 valid = true leaf = #<Sketchup::Edge:0x000000001dc50db0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_153 valid = true leaf = #<Sketchup::Edge:0x000000001dc50220> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_154 valid = true leaf = #<Sketchup::Edge:0x000000001dc9df48> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_155 valid = true leaf = #<Sketchup::Edge:0x000000001dc9ca08> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_156 valid = true leaf = #<Sketchup::Face:0x000000001dc9ba18> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_162 valid = true leaf = #<Sketchup::Face:0x000000001dc989a8> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_168 valid = true leaf = #<Sketchup::Face:0x000000001dc97c38> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_174 valid = true leaf = #<Sketchup::Face:0x000000001dc96cc0> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_180 valid = true leaf = #<Sketchup::Face:0x000000001dc95e38> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_186 valid = true leaf = #<Sketchup::Face:0x000000001dc95320> root = Group_comp
its a drawing element Sketchup::ComponentInstance ComponentInstance_comp 1 valid = true leaf = root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_76 valid = true leaf = #<Sketchup::Edge:0x000000001dc93d68> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_77 valid = true leaf = #<Sketchup::Edge:0x000000001dc934d0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_78 valid = true leaf = #<Sketchup::Edge:0x000000001dc92e90> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_79 valid = true leaf = #<Sketchup::Edge:0x000000001dc92558> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_80 valid = true leaf = #<Sketchup::Edge:0x000000001dc91e00> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_81 valid = true leaf = #<Sketchup::Edge:0x000000001dc918d8> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_82 valid = true leaf = #<Sketchup::Edge:0x000000001dc91248> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_83 valid = true leaf = #<Sketchup::Edge:0x000000001dc90848> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_84 valid = true leaf = #<Sketchup::Edge:0x000000001dc90050> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_85 valid = true leaf = #<Sketchup::Edge:0x000000001da1e100> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_86 valid = true leaf = #<Sketchup::Edge:0x000000001da1c878> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_87 valid = true leaf = #<Sketchup::Edge:0x000000001da1abe0> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_88 valid = true leaf = #<Sketchup::Face:0x000000001da18930> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_94 valid = true leaf = #<Sketchup::Face:0x000000001da16fb8> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_100 valid = true leaf = #<Sketchup::Face:0x000000001da16720> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_106 valid = true leaf = #<Sketchup::Face:0x000000001da16158> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_112 valid = true leaf = #<Sketchup::Face:0x000000001da15960> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_118 valid = true leaf = #<Sketchup::Face:0x000000001da15230> root = Group_comp
its a drawing element Sketchup::Group Group_comp 3 4 valid = true leaf = root = Group_comp
its a drawing element Sketchup::ComponentInstance ComponentInstance_comp 3 valid = true leaf = root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_212 valid = true leaf = #<Sketchup::Edge:0x000000001da13f70> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_213 valid = true leaf = #<Sketchup::Edge:0x000000001da138e0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_214 valid = true leaf = #<Sketchup::Edge:0x000000001da120f8> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_215 valid = true leaf = #<Sketchup::Edge:0x000000001da11a90> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_216 valid = true leaf = #<Sketchup::Edge:0x000000001da111f8> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_217 valid = true leaf = #<Sketchup::Edge:0x000000001da106e0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_218 valid = true leaf = #<Sketchup::Edge:0x000000001d9cfd70> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_219 valid = true leaf = #<Sketchup::Edge:0x000000001d9cf528> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_220 valid = true leaf = #<Sketchup::Edge:0x000000001d9ceb50> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_221 valid = true leaf = #<Sketchup::Edge:0x000000001d9cdf98> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_222 valid = true leaf = #<Sketchup::Edge:0x000000001d9cd688> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_223 valid = true leaf = #<Sketchup::Edge:0x000000001d9ccdf0> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_224 valid = true leaf = #<Sketchup::Face:0x000000001d9cc648> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_230 valid = true leaf = #<Sketchup::Face:0x000000001d9cbe78> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_236 valid = true leaf = #<Sketchup::Face:0x000000001d9cb3b0> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_242 valid = true leaf = #<Sketchup::Face:0x000000001d9ca640> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_248 valid = true leaf = #<Sketchup::Face:0x000000001d9c8278> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_254 valid = true leaf = #<Sketchup::Face:0x000000001d9c6a18> root = Group_comp
its a drawing element Sketchup::ComponentInstance ComponentInstance_comp 4 valid = true leaf = root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_280 valid = true leaf = #<Sketchup::Edge:0x000000001d9c4718> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_281 valid = true leaf = #<Sketchup::Edge:0x000000001d9c3638> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_282 valid = true leaf = #<Sketchup::Edge:0x000000001d9c2c38> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_283 valid = true leaf = #<Sketchup::Edge:0x000000001d9c1e28> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_284 valid = true leaf = #<Sketchup::Edge:0x000000001d9c17e8> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_285 valid = true leaf = #<Sketchup::Edge:0x000000001d9c11f8> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_286 valid = true leaf = #<Sketchup::Edge:0x000000001d9c0c08> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_287 valid = true leaf = #<Sketchup::Edge:0x000000001d9c05a0> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_288 valid = true leaf = #<Sketchup::Edge:0x0000000021ddfc90> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_289 valid = true leaf = #<Sketchup::Edge:0x0000000021ddf768> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_290 valid = true leaf = #<Sketchup::Edge:0x0000000021ddf290> root = Group_comp
its a drawing element Sketchup::Edge Edge_entityID_291 valid = true leaf = #<Sketchup::Edge:0x0000000021ddee30> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_292 valid = true leaf = #<Sketchup::Face:0x0000000021dde868> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_298 valid = true leaf = #<Sketchup::Face:0x0000000021dde408> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_304 valid = true leaf = #<Sketchup::Face:0x0000000021dddf30> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_310 valid = true leaf = #<Sketchup::Face:0x0000000021dddad0> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_316 valid = true leaf = #<Sketchup::Face:0x0000000021ddd5f8> root = Group_comp
its a drawing element Sketchup::Face Face_entityID_322 valid = true leaf = #<Sketchup::Face:0x0000000021ddd198> root = Group_comp
leaf method on a instancePath return nil when the last item is a group or a component
that’s probably why we have this error Leaf must be a type of Sketchup::Drawingelement