-we know: page<>scene & layer<>tag .-
Based on @DanRathbun code and sWilliams idea I have made a dirty plugin for changing several properties of layers at once.
Some more background info
When I’m doing the opacity changes of the layer, in reality, I’m adding new layer with required opacity and “moving” all entities to that new layer and deleting the original layer, then renaming back to original name…Since I want to “inherit” the original visibility of the layers per page I have to store and restore these properties…
Now I’m facing some problems with the documented and real situation.
So, I made some study and concluded that the Ruby API documentation is not correct:
Specifically, this: Page#layers instance method
However, if you read another part of the documentation like:
Layer#page_behavior instance method
You may start to suspect what the situation is…
At first: If a user switched off to save layers visibility aka if page#use_hidden_layers?
is false
then page#layers
method returns nil
. NOT documented!
At secondly: Otherwise page#layers
method returns non-visible layers /array with zero or more layers objects/ but, wrongly documented! (You can use this ‘term’ only if page_behavior has not been ‘touched’.)
As my study is colluded: actually, it will return array containing these layers if layer page_behavior ‘flag query’ / LAYER_HIDDEN_BY_DEFAULT / different than default page visibility state (behavior) for that page. I hope this is the right wording and situation. (Note: My mother never talked to me in English.)
As an excuse the SU Ruby API documentation of layer#page_behavior
saying: “A page keeps a list of layers that do not have their default behavior.”
Here is the snippet what I have been used and improved during the study:
# -----------
# test in SU2019.3 (2020.02.22) @Dezmo
# I have 3 scenes and Layer0 Layer1 Layer2 in a model
# Layer2 for reference: it is hidden on all scenes and no any changes on it during test
# -----------
#
# This part is my "concluded" method to get if layer hidden or not on the page
def hidden_on_page?(layer, page)
# If a user switched off to save layers visibility aka
# if page#use_hidden_layers? is false then page#layers method returns nil (NOT documented!)
# else #layers method returns non-visible layers /array with zero or more layers objects/
# but (WRONGLY documented!) you can use this 'term' only if page_behavior has not been 'touched'.
# So: actually it will return array containing this layer if layer page_behavior 'flag query'
# / LAYER_HIDDEN_BY_DEFAULT / different than default page visibility state (behavior) for that page.
# Easy, isn't it? (Note: My mother never talked to me in English. ;-) )
# As an excuse the SU Ruby API documentation of layer#page_behavior saying:
# "A page keeps a list of layers that do not have their default behavior."
if page.use_hidden_layers?
return page.layers.include?(layer) == !hidden_by_default?(layer)
else
#this is the only visibility I can query if not stored in scene
return !layer.visible?
end
end
#check if somebody changed the default page_behavior
def hidden_by_default?(layer)
( layer.page_behavior & LAYER_HIDDEN_BY_DEFAULT ) == LAYER_HIDDEN_BY_DEFAULT
end
#Testing Get/set a layer's visibility / page behavior
#parameters:
# layer_name_or_index: the layer name or index what you want to test/query (default1) or nothing
# (I'm lazy) set: new page_behavior if you want to set ( 0, 1, 16, 17, 32, 33 ) or nothing
#prints out to console:
# the detailed page_behavior (five flags + integer)
# the result array or nil of page#layers method (for scene 0,1,2)
# my "concluded" (aka real) hidden state of layer on the page (for scene 0,1,2)
#usage e.g.: vis_behav or vis_behav 1 or vis_behav "Layer1", 1 ...etc.
def vis_behav(layer_name_or_index=1, set=false)
flags = [ LAYER_VISIBLE_BY_DEFAULT,
LAYER_HIDDEN_BY_DEFAULT,
LAYER_USES_DEFAULT_VISIBILITY_ON_NEW_PAGES,
LAYER_IS_VISIBLE_ON_NEW_PAGES,
LAYER_IS_HIDDEN_ON_NEW_PAGES
]
layers = Sketchup.active_model.layers
layer = layers[layer_name_or_index]
pages = Sketchup.active_model.pages
# during testing layer visibility changed manually on one scene
# this is just update that current page saving some clicks...
pages.selected_page.update if !set
# conditionally set page_behavior
layer.page_behavior = set if set
# update all pages to get effect of page_behavior
pages.each(&:update) if set
# if #use_hidden_layers? is false then #layers method returns nil !!
layers_hidden_onpage0 = (pages[0].layers)? pages[0].layers.map(&:name) : pages[0].layers
layers_hidden_onpage1 = (pages[1].layers)? pages[1].layers.map(&:name) : pages[1].layers
layers_hidden_onpage2 = (pages[2].layers)? pages[2].layers.map(&:name) : pages[2].layers
#query page_behavior
behavs = []
flags.each_with_index { |flag, i|
behavs[i] = (layer.page_behavior & flag ) == flag
}
#Just to see the integer
behavs<<layer.page_behavior
# printouts
puts "#{layer.name} page_behavior: #{behavs}"
puts
puts "layers_hidden_on page0 #{layers_hidden_onpage0}"
puts "#{layer.name} hidden_on page0 #{hidden_on_page?(layer, pages[0])}"
puts
puts "layers_hidden_on page1 #{layers_hidden_onpage1}"
puts "#{layer.name} hidden_on page1 #{hidden_on_page?(layer, pages[1])}"
puts
puts "layers_hidden_on page2 #{layers_hidden_onpage2}"
puts "#{layer.name} hidden_on page2 #{hidden_on_page?(layer, pages[2])}"
puts "-------------------------------------"
end
vis_behav
I leave the suggestion on how to change the documentation to those who are better in English and in Ruby.
Sure, there can be mistakes and possible improvements…
Of course, any comments or corrections are welcome.