Drawingelement#visible? seems to return inconsistent results

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?

Visible test.skp (72.7 KB)

No.
There, in the Outliner the coresponding group is just grayed out. If you look closer, you do have same :eye: symbol as before but not black but gray.
gr_l_vis

If you turning off the associated tag (layer) you have to look for the visibility of the layer.

Sketchup.active_model.entities.select{|ent| ent.layer.visible?}

or examine both

Sketchup.active_model.entities.select{|ent| 
  ent.visible? && ent.layer.visible?
}

In other words, the following code …

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

1 Like

:thinking:
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 (?)

The #get_drawingelement_visibility method is used to get the visibility of a drawing element on a particular page.

The #layers method retrieves layers that don’t use their default visibility on this page.

The #layer_folders method retrieves the hidden layer folders associated with a page.

etc… :blush:

1 Like

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?

Visible test.skp (71.4 KB)

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…

Yes.

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.

I was going to mention this in the bug report but I don’t get the same behavior (on 2022):

mod = Sketchup.active_model
group = mod.entities.add_group
path = Sketchup::InstancePath.new([group])
path.valid?

returns true

# valid?

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 )

The issue is that the #leaf instance_method returns nil

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.

BTW. Dan already reported this issue in other aspect: Sketchup::Model#drawing_element_visible? TypeError message is not quite correct · Issue #570 · SketchUp/api-issue-tracker · GitHub

Yes, but you see the response that I got ?

Yes, I saw it. :disappointed_relieved:
Hope this time we get more serious attention.