Мои мысли и проекты
Расширение (плагин) SketchUp для проектирования мебели программистом

При расчете стоимости новой кухни цена оказалась такой большой, что я решил сделать её сам так как это обойдется в два раза дешевле. Для тренировки решил сделать для себя рабочий стол. Достаточно быстро пришло понимание: чтобы сделать хорошую вещь нужно сделать 3D модель. Это позволит на этапе проектирования посмотреть как будет выглядеть мебель и продумать как в дальнейшем будет происходить сборка. Так как 3D моделированием я не занимаюсь, то начал искать программу попроще. И самая простая что нашел SketchUp. При создании модели постоянно приходилось править модель из-за постоянно изменявшихся размеров. И после третьего изменения появилась идея - сделать параметризированную модель, чтобы она сама генерировалась с нужными размерами. SketchUp поддерживает скрипты на языке Ruby и эта статья о том что получилось.

Решение достаточно простое - создаю некоторый API, который позволяет создавать 3D объекты листов ЛПСД с нужными параметрами. Из этих объектов компануется готовая модель а также в отдельный файл выгружаются размеры листов для передачи их в центр распила. В результате эксплуатации добавил ещё возможность указывать кромки для листов. Данный плагин был использован для проектирования более десятка различных изделий из ЛДСП. С каждым новым проектом плагин дорабатывался и модифицировался, улучшалось удобство и совершенствовалось API. В качестве примера последний проект - стол-тумба. Вот так она выглядит в модели

Красные - это 2 м кромки, фиолетовый - кромки 0.4 мм. Нижние полки не до конца, так как там батарея отопления у стены. Столешница отстает от стены на 4 см чтобы тепло от батарее отопления поднималось вверх и обогревало стену (вообще делать мебель самому очень удобно - можно сделать под свои размеры). вот так выглядит код для её генерации

# Толщина фанеры
$weght = 16.0
# Зазор между ящиком и задней стенкой
$zazor = 5.0
# Отступ от краев для ящика
$dWidth = 26.0

#
$width = 770
$offsetStena = 40
$dStoledhnica = 20
$height = 2500 - 150 - 900
$depthLeft = 600
$depthRight = $depthLeft - 175
$jshikHeight = 200
$heightPlanka = 300
$heightJshik = 190
$heightJshikOffset = 10
# Функция точки входа
def object3D_main()
	# Загрузить библиотеки
	Shasoft::Object3D::loadLibrary()
	# Установить толщину ЛДСП
	Shasoft::Object3D::LDSP::setWeght($weght)
	# Создать модель
	stenaLeft = Shasoft::Object3D::LDSP::create($height-$weght,$depthLeft,"2 0 0 1").name("Левая стена").rotateY(-90)
	stenaRight = Shasoft::Object3D::LDSP::create($height-$weght,$depthLeft,"2 0 0 1").name("Правая стена").rotateY(-90).moveX($width-$weght)
	stoleshnica = Shasoft::Object3D::LDSP::create($width,$depthLeft+$dStoledhnica-$offsetStena,"2 2 1 2").name("Столешница").move(-$weght,-$dStoledhnica,$height-$weght)
	polka1 = Shasoft::Object3D::LDSP::create($width-$weght*2,$depthRight,"2 0 0 0").name("Полка 1").moveZ(400)
	polka2 = Shasoft::Object3D::LDSP::create($width-$weght*2,$depthRight-$weght,"2 0 0 0").name("Полка 2").moveZ(600)
	polka3 = Shasoft::Object3D::LDSP::create($width-$weght*2,$depthLeft-$offsetStena,"2 0 0 0").name("Полка 3").moveZ(800+$heightJshik+$heightJshikOffset+10-$weght-5)
	pereborka1 = Shasoft::Object3D::LDSP::create($width-$weght*2,$heightPlanka).name("Переборка").rotateX(90).moveY($depthRight).moveZ(400+$weght)
	# Верхний ящик
	jshik1box = Shasoft::Object3D::LDSP::create_box($width-$weght*2-$dWidth,$depthLeft-$zazor-$offsetStena,$heightJshik,"Верхний ящик",1).moveX($dWidth/2).moveZ($height-$heightJshik-$heightJshikOffset-$weght)
	jshik1Fasad = Shasoft::Object3D::LDSP::create($width,200,"2 2 2 2").rotateX(90).moveX(-$weght).moveZ($height-$heightJshik-$heightJshikOffset-$weght-5).name("Фасад ящика 1")
	jshik1 = Shasoft::Object3D::create(jshik1box,jshik1Fasad)
	# Нижний ящик
	jshik2box = Shasoft::Object3D::LDSP::create_box($width-$weght*2-$dWidth,$depthLeft-$zazor-$offsetStena,$heightJshik-$weght-5,"Нижний ящик",1).moveX($dWidth/2).moveZ($height-$heightJshik-$heightJshikOffset-$weght)
	jshik2Fasad = Shasoft::Object3D::LDSP::create($width,200,"2 2 2 2").rotateX(90).moveX(-$weght).moveZ($height-$heightJshik-$heightJshikOffset-$weght-5).name("Фасад ящика 2")
	jshik2 = Shasoft::Object3D::create(jshik2box,jshik2Fasad).moveZ(-$height+800+$heightJshik+$heightJshikOffset+$weght+10)
	# Двери
	widthDver = $width/2-5
	dver1 = Shasoft::Object3D::LDSP::create(widthDver,800-5-10,"2 2 2 2").rotateX(90).moveZ(5).moveX(-$weght).name("Дверь 1")
	dver2 = dver1.copy.moveX($width-widthDver).name("Дверь 2")
	# 
	for i in 0..5
		Shasoft::Object3D::LDSP::create(467,247,"0 2 0 0").name("Полка в шкаф").moveX(-600).moveZ(i*50)
	end
	for i in 0..2
		Shasoft::Object3D::LDSP::create(467,640,"0 2 0 0").name("Полка в шкаф 2").moveX(-600-600).moveZ(i*50)
	end
	#
	Shasoft::Object3D::LDSP::write_csv( File.dirname(__FILE__)+"/main.csv" )
	#Shasoft::Object3D::LDSP::write_csv_cut( File.dirname(__FILE__)+"/cut.csv" )
	#Shasoft::Object3D::show()
end

Установка

Скачиваем файл Object3D.rbz Запускаем SketchUp Открываем Диспечер расширений (Окно/Диспечер расширений) Жмем кнопку "Установить расширение" и выбираем скаченный файл Object3D.rbz После этого плагин запрашивает директорию где будут храниться проекты. Т.е. выводится окно "Укажите директорию с проектами" и требуется указать папку где вы будете хранить ваши проекты.

В результате у нас появляется наше расширение

Использование

Переходим в папку которую мы указали для хранения проектов. Эту папку можно изменить в меню плагина

Создаем в папке директорию с названием нашего проекта. В моем случае это "Шкафчик в зал". Затем заходим в созданную директорию и создаем файл main.rb в котором создаем функцию точки входа

# Функция точки входа
def object3D_main()
 ... # код для генерации модели
end

Перезапускаем SketchUp и в меню плагина у вас появится пункт с названием созданной вами папки. Теперь вы выборе этого пункта будет происходить следующее:

  • очистка консоли Ruby
  • удаление всех элементов в текущем проекте
  • загрузка файла main.rb из указанной директории
  • вызов функции object3D_main

В функции object3D_main нужно сделать генерацию вашей модели. Можно скопировать в файл main.rb код который я приводил выше и тогда у вас сгенерируется мой шкафчик.

API

Файл "core.rb"

Каждая функция возвращает объект Shasoft::Object3D::Object3D который содержит методы для перемещения объекта и его поворота

  • Функция name() - установка имени объекта. Не стоит им пренебрегать. При сборке может сильно помочь :)
  • Функции объекта moveX, moveY, moveZ позволяют перемещать объект по соответствующим осям.
  • Функция move(x,y,z) позволяет переместить объект сразу по трем осям
  • Функции объекта rotateX, rotateY, rotateZ позволяют вращать объект вокруг соответствующих осей.
  • Есть функции псевдонимы moveRed, moveGreen, moveBlue, rotateRed, rotateGreen, rotateBlue где оси X(red), Y(green), Z(blue) названы по их цвету в SketchUp. Может кому-то так будет удобнее. Каждая функция возвращает указатель на сам обхект. Это позволяет делать цепочку вызовов
# Повернем объект на 90 градусов вокруг оси X и  переместим по оси Y на 100 мм
obj.rotateX(90).moveY(100)
  • Функция объекта set(dict,key,value) позволяет установить значение атрибута. dict - имя словаря, key - имя атрибута, value - значение

  • Функция объекта get(dict,key,value=nil) позволяет получить значение атрибута. dict - имя словаря, key - имя атрибута, value - значение

  • Метод copy позволяет получить копию объекта (хотя работает не очень стабильно :))

  • Метод group позволяет получить стандартный объект SketchUp::Group

Определен метод для создания объекта. В качестве параметров можно передавать список объектов Shasoft::Object3D::Object3D или SketchUp::Group. Если список параметров пустой, то будет создана новая группа

# Создать объект со списком дочерних объектов
Shasoft::Object3D::create(*args)

Также есть функция которая позволяет получить список объектов (Skechup::Group). Можно задать имя словаря и будут возвращены только объекты, у которых такой словарь присутствует. В частности именно так я отделяю объекты лист ЛПСД от других. При создании я устанавливаю словарь LDSP по которому потом и фильтрую все объекты сцены.

# Получить список объектов
# dict - имя словаря
Shasoft::Object3D::get(dict=nil)

Файл "2D_weght"

# Создать 3D объект выдавливания
# pts - список точек в координатной плоскости x,y
# weght - толщина(высота)
Shasoft::Object3D::create_pushpull(pts,weght)

# Создать плоскую поверхность с заданной толщиной
# lX - размер по X
# lY - размер по Y
# weght - толщина
Shasoft::Object3D::create_plane(lX,lY,weght)

Файл "ldsp.rb"

# Получить текущую толщину
Shasoft::Object3D::LDSP::weght

# Установить толщину
Shasoft::Object3D::LDSP::setWeght(weght)
# Получить текущий материал ЛДСП
Shasoft::Object3D::LDSP::material

# Установить материал ЛДСП
Shasoft::Object3D::LDSP::setMaterial(material)

# Создать лист ЛДСП
# width - ширина (по X)
# depth - глубина (по Y)
# kromka - кромка [X ближний, Y левый, X дальний, Y правый], 0 - нет кромки, 1 - кромка 0.4 мм, 2 - кромка 2 мм
Shasoft::Object3D::LDSP::create(width,depth,kromka="0 0 0 0")

Вспомогательная функция для создания выдвижных ящиков

# Создать ящик
# width - ширина
# depth - глубина
# height - высота
# name - имя
# is_kromka - 1/0 кромить верх 2 мм кромкой
Shasoft::Object3D::LDSP::create_box(width,depth,height,name,is_kromka)

результат работы

# Записать размеры в файл CSV
Shasoft::Object3D::LDSP::write_csv(filepath)

в результате будет сгенерирован следующий csv файл со следующими колонками

  • A - Ширина
  • B - Глубина
  • C Количество деталей
  • D - кромки в формате Д-длинная сторона, К-короткая сторона. Именно в таком их записывают в той конторе в которой я заказываю распил деталей. Возможно это стандарт.
  • E - кромки в том формате в котором вы их задавили при генерации
  • F - Название всех деталей. Это полезно при сборке

В заключении

Проектирование и сборка мебели самому - это экономия денег где-то в 2 раза. А также возможность втиснуть ваше индивидуальное мебельное изделие в любую нестандартную дырку в квартире. Я обычно собираю мебеоь на конфирматах 7x50 из ЛДСП 16 мм

При наличии сверла для конфирматов
(и небольшого навыка) сборка занимает не так много времени.

Единственный минус - в это можно втянуться. После рабочего стола я уже собрал: кухню, несколько клеток (для одной и той же птицы), полки (навесные и напольные), тумбы и столы. В общем "захламил" в квартире все неиспользуемые места.

Ссылка для скачивания расширения

0

Комментарии

Чтобы оставлять комментарии войдите на сайт. Вы можете сделать это через социальную сеть