Someone asked me how to get a hierarchical view of SketchUp models for costing/analysis/quantities. They have a lot (1000’s) of skp files that they want to inventory. I created a Ruby script to extract lots of SketchUp data to JSON for this purpose. I tried it on a directory containing 12 files, totaling 1 GB. It took 11 minutes and produced a 2GB output file.
Posting here in case this is useful to the rest of you.
# Edit these lines:
sketchup_file_dir='C:\Users\dan\Desktop\Source Models'
report_file='C:/Users/dan/Desktop/out.json'
sketchup_file_dir=sketchup_file_dir.gsub('\\','/')
report_file=report_file.gsub('\\','/')
require 'json'
skp_files = Dir.glob(File.join(sketchup_file_dir, '**.skp'))
def entities_recursive(entities, transform)
result = {
faces: [],
groups: [],
component_instances: []
}
entities.each {|entity|
if entity.is_a? Sketchup::Face
result[:faces].push({
material: entity.material && entity.material.name,
back_material: entity.back_material && entity.back_material.name,
area: entity.area(transform)
})
elsif entity.is_a? Sketchup::Group
result[:groups].push({
name: entity.name,
material: entity.material && entity.material.name,
entities: entities_recursive(entity.entities, transform * entity.transformation)
})
elsif entity.is_a? Sketchup::ComponentInstance
result[:component_instances].push({
name: entity.name,
material: entity.material && entity.material.name,
entities: entities_recursive(entity.definition.entities, transform * entity.transformation)
})
end
}
return result
end
total_report = []
open(report_file, 'w') { |f|
f.write('[')
need_comma = false
skp_files.each {|file|
if need_comma
f.write(',')
else
need_comma = true
end
if Sketchup.open_file(file)
model=Sketchup.active_model
model.start_operation('',true) # disable UI
model_report = {
filepath: file,
name: model.name,
definitions: [],
materials: [],
entities: entities_recursive(model.entities,Geom::Transformation.new())
}
model.definitions.each{ |d|
model_report[:definitions].push({
name: d.name,
number: d.count_used_instances
})
}
model.materials.each{ |m|
model_report[:materials].push({
name: m.name
})
}
model.abort_operation
else
model_report = {
filepath: file,
error: 'Could not open file'
}
end
f.write(JSON.pretty_generate(model_report))
Sketchup.active_model.close(true)
}
f.write(']')
}
print('done')