Sketchup::InstancePath.leaf give nil result when last item is a group or a component
and drawing_element_visible? has the error Leaf must be a type of Sketchup::Drawingelement when last item of instancePath is a group or a component for the same reason
with this code
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
and this simple sketchup project (i can't upload a sketchup project here)
i have 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
=> #<Sketchup::Entities:0x0000000021dda8d0>
leaf is always empty when group or component is the last item of instancePath
I commented this line #vis = ent.model.drawing_element_visible?(pa) , otherwise I always had this error
Leaf must be a type of Sketchup::Drawingelement
as leaf return nil, this is perhaps the reason why we have this error with
ent.model.drawing_element_visible?(pa)
when the last item of the instancePath is a group or a component
also the documentation https://ruby.sketchup.com/Sketchup/Model.html#drawing_element_visible%3F-instance_method is wrong
module Example
def self.instance?(entity)
entity.is_a?([Sketchup](https://ruby.sketchup.com/Sketchup.html)::[ComponentInstance](https://ruby.sketchup.com/Sketchup/ComponentInstance.html)) || entity.is_a?([Sketchup](https://ruby.sketchup.com/Sketchup.html)::[Group](https://ruby.sketchup.com/Sketchup/Group.html))
end
# Walk the visible entities in the model, taking into account
# "DrawHiddenGeometry" and "DrawHiddenObjects" rendering options.
def self.walk(entities, transformation = [IDENTITY](https://ruby.sketchup.com/top-level-namespace.html#IDENTITY-constant), path = [], &block)
entities.each { |entity|
entity_path = path + [entity]
next unless entity.model.drawing_element_visible?(entity_path)
block.call(entity, transformation, path)
if instance?(entity)
child_entities = entity.definition.entities
child_transformation = transformation * entity.transformation
walk(child_entities, child_transformation, entity_path, &block)
end
}
end
end
model = [Sketchup](https://ruby.sketchup.com/Sketchup.html).[active_model](https://ruby.sketchup.com/Sketchup.html#active_model-class_method)
Example.walk(model.entities) do |entity, transformation, path|
# Do something to every visible entity in the model...
end
before entity.model.drawing_element_visible?(entity_path) you have to test if the leaf of instancePath is nil or not
A leaf is a drawing element that is not a containers (group / component). That's per design. Whether that was the best choice is a different matter, but if we change this now it might break existing extensions. But we can at least improve documentation.
Btw, avoid string comparison of class names when checking types - it quickly becomes a bottleneck.
# instead of:
if(cm != "Group" && entity.respond_to?(:definition))
entity = entity.definition
end
# prefer type checking:
if entity.is_a?(Sketchup::Group) && entity.respond_to?(:definition)
entity = entity.definition
end
Thank you thomthom
A leaf is a drawing element that is not a containers (group / component). That's per design. Whether that was the best choice is a different matter, but if we change this now it might break existing extensions. But we can at least improve documentation.
Yes you have to change the documentation for leaf instance method :
The leaf of an instance path is the last element which can be any entity that can be represented in the model. This is normally a Drawingelement, but could be a Vertex. An instance can also be a leaf.
because it's seem that "group" or "component" are also Drawingelement.
group.is_a?(Sketchup::Drawingelement) or component.is_a?(Sketchup::Drawingelement) return true
There si also a problem with the use of drawing_element_visible?(entity_path) you have to correct the documentation (this fabulous documentation very well done 👍 👍 👍 ) but also the example "Traversing every visible entity in the model".
Btw, avoid string comparison of class names when checking types - it quickly becomes a bottleneck.
Yes you're absolutely right, i'm total beginner in ruby sletchup and this getName function was only used to display the name of a group or component on the sketchup ruby console, I had to indicate it here so that everyone can run the code I gave
I also ran into this issue and it caused a bit of unnecessary pain and suffering. Please update the documentation for the leaf instance method. Thank you.