Автоматический подсчет розеток и выключателей в SketchUp с помощью Ruby-скрипта
Если вы занимаетесь моделированием в SketchUp, особенно проектами с электрикой, то наверняка сталкивались с необходимостью подсчитывать розетки, выключатели и другие элементы. Ручной подсчет — это утомительно, особенно в больших моделях. Сегодня я расскажу, как автоматизировать этот процесс с помощью простого Ruby-скрипта, который работает прямо в консоли SketchUp
Этот скрипт полностью совместим с плагином Crafteelectric Tools, предназначенным для расстановки электрических элементов.
Либо вы можете использовать свои динамические компоненты с условием, что имена будут даваться определенным образом: имя розетки должно начинаться с "EM" и содержать в себе группу с именем "3D", касание которой скрипт и ищет для подсчета рамок.
Как запустить скрипт
Откройте SketchUp и загрузите вашу модель, созданную или дополненную с помощью Crafteelectric Tools.
Перейдите в меню "Window" > "Ruby Console" (или "Окно" > "Консоль Ruby" в русской версии).
Скопируйте и вставьте весь скрипт в консоль, затем нажмите Enter.
Скрипт обработает модель и выведет результаты в консоль.
m=Sketchup.active_model
def b(g,t)
bb=Geom::BoundingBox.new
8.times{|i|bb.add(g.bounds.corner(i).transform(t))}
bb
end
def c(e,p,p_t=IDENTITY,r=[])
e.each{|x|
if x.is_a?(Sketchup::ComponentInstance) && x.definition.name.start_with?(p)
r<<(p=="EM" ? [x, p_t*x.transformation] : x)
elsif x.is_a?(Sketchup::Group) || x.is_a?(Sketchup::ComponentInstance)
c((x.respond_to?(:entities) ? x.entities : x.definition.entities), p, p_t*x.transformation, r)
end
}
r
end
em=c(m.entities,"EM")
puts"Найдено EM-компонентов: #{em.size}"
p=em.combination(2).select{|(a,a_t),(b,b_t)|
ga=a.definition.entities.find{|x|x.is_a?(Sketchup::Group)&&x.name=="3D"}
gb=b.definition.entities.find{|x|x.is_a?(Sketchup::Group)&&x.name=="3D"}
ga && gb && b(ga,a_t).intersect(b(gb,b_t)).valid?
}
require'set'
g=[]
v=Set.new
adj=Hash.new{|h,k|h[k]=[]}
p.each{|a,b| adj[a[0]]<<b[0]; adj[b[0]]<<a[0]}
def d(n,a,v,g)
return if v.include?(n)
v<<n
g<<n
a[n].each{|x| d(x,a,v,g)}
end
em.each{|c,_| next if v.include?(c); x=[]; d(c,adj,v,x); g<<x}
class Array;def tally_by;each_with_object(Hash.new(0)){|i,h|h[yield(i)]+=1};end;end
fc=g.tally_by(&:size)
emc=em.tally_by{|c,_|c.definition.name[/^EM[^#]*/]}
ek=c(m.entities,"EK")
ekc=ek.tally_by{|c|c.definition.name[/^EK[^#]*/]}
eo=c(m.entities,"EO")
eoc=eo.tally_by{|c|c.definition.name[/^EO[^#]*/]}
puts"\n Количество рамок:", fc.sort.map{|s,c|" - Рамок на #{s}: #{c}"}
puts"\n Количество EM-компонентов:", emc.sort.map{|n,c|" - #{n}: #{c}"}
puts"\n Количество EK-коробок:", ekc.sort.map{|n,c|" - #{n}: #{c}"}
puts"\n Количество EO-компонентов:", eoc.sort.map{|n,c|" - #{n}: #{c}"}
Что делает скрипт
Поиск компонентов: Cканирует модель на наличие компонентов с префиксами "EM", "EK", "EO".
Группировка рамок: Для "EM" проверяет пересечения bounding box групп "3D" внутри компонентов, чтобы определить, какие элементы образуют рамки (например, одиночные, двойные и т.д.).
Подсчет: Выводит общее количество найденных "EM", а также детальную информацию по типам и размерам рамок, числу коробок "EK" и элементов "EO".
Найдено EM-компонентов: 15
Количество рамок:
- Рамок на 1: 5
- Рамок на 2: 3
- Рамок на 3: 2
Количество EM-компонентов:
- EM Розетка: 8
- EM Выключатель: 7
Количество EK-коробок:
- EK Коробка: 10
Количество EO-компонентов:
- EO Модуль: 4
В будущих обновлениях планируется улучшенная версия подсчета с более наглядным представлением данных. Реализовать это в текущем скрипте не могу, так как из скрипта нельзя получить доступ к плагину, что ограничивает дополнительные возможности.