Hello,
After nobody here liked my extension ideas i decided how hard can it be. Well its pretty hard. I’m trying to get all the vertices in my model (global position not component origin positions). I thought it would be a simple task and its really become a nightmare. I keep rewriting the code. it works but its far too slow. Can anyone show me how to write it so that it can get them in a reasonable time. heres the fastest version I have so far. Thanks
def self.collect_all_vertices
model = Sketchup.active_model
puts "Collecting all vertices from the model..."
# Step 1: Find all top-level component instances and free-floating faces/edges
top_level_instances = model.active_entities.grep(Sketchup::ComponentInstance)
free_floating_entities = model.active_entities.grep(Sketchup::Face) + model.active_entities.grep(Sketchup::Edge)
# Step 2: Get a unique list of component definitions from top-level instances
top_level_definitions = top_level_instances.map(&:definition).uniq
puts "Found #{top_level_definitions.size} unique top-level component definitions."
# Step 3: Build a complete template vertex dictionary for each top-level definition
definition_templates = {}
build_definition_template = lambda do |definition, parent_transformation = Geom::Transformation.new, depth = 0|
template_vertices = {}
puts " Building template for definition: #{definition.name} at level #{depth}"
definition.entities.each do |entity|
if entity.is_a?(Sketchup::Face) || entity.is_a?(Sketchup::Edge)
entity.vertices.each do |vertex|
vt = (parent_transformation * vertex.position)
key = "#{vt.x},#{vt.y},#{vt.z}"
template_vertices[key] = vt
end
elsif entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group)
sub_transformation = parent_transformation * entity.transformation
puts " Subcomponent: #{entity.definition.name} at level #{depth + 1}"
sub_vertices = build_definition_template.call(entity.definition, sub_transformation, depth + 1)
template_vertices.merge!(sub_vertices)
end
end
puts " Template for #{definition.name} finished. Total vertices at this level: #{template_vertices.size}"
template_vertices
end
top_level_definitions.each_with_index do |definition, idx|
puts "Building template for top-level definition #{idx + 1}/#{top_level_definitions.size}..."
definition_templates[definition] = build_definition_template.call(definition)
end
# Step 4: Process free-floating faces and edges
vertices = {}
free_floating_entities.each do |entity|
if entity.is_a?(Sketchup::Face) || entity.is_a?(Sketchup::Edge)
entity.vertices.each do |vertex|
key = "#{vertex.position.x},#{vertex.position.y},#{vertex.position.z}"
vertices[key] = vertex.position
end
end
end
# Step 5: Apply template vertices to all top-level component instances
puts "Applying templates to top-level instances..."
top_level_instances.each_with_index do |instance, idx|
transformation = instance.transformation
template_vertices = definition_templates[instance.definition]
template_vertices.each_value do |v|
vt = transformation * v
key = "#{vt.x},#{vt.y},#{vt.z}"
vertices[key] = vt
end
puts " Instance #{idx + 1}/#{top_level_instances.size}: #{instance.definition.name} - #{template_vertices.size} vertices"
end
# Step 6: Convert vertices dictionary to array
unique_vertices = vertices.values
puts "Found #{unique_vertices.size} unique vertices."
unique_vertices
end