ЧПУ в хоббийной мастерской (часть 3)



    Изначально, планировал ограничиться двумя постами (раз, два) про мои ЧПУшные эксперименты. Но, тема оказалась многим интересной, поэтому, немного ее еще пораскрываю. В этом посте пойдет речь про написание самодельного софта для управления любительским ЧПУ.

    Предисловие


    Не знаю, удалось ли кого-то мотивировать первыми постами, но некоторые комментарии мне самому дали хорошую пищу для размышлений. Отдельная благодарность @evilruff за фото его лаборатории и за видео с классным корейцем. После просмотра того и другого мой бардачёк в подвале перестал казаться таким уж уютным.

    Собравшись с силами, на выходных навел что-то отдаленно напоминающее порядок и сделал, наконец, 2 вещи которые собирался сделать еще пол-года назад.

    Во-первых, заменил кусок фанеры который выполнял роль жертвенного стола. Этой фанерой я пользовался с момента покупки станка, прикручивая саморезами к ней заготовки и сооружая всякие безумные конструкции из палок и клиньев. Все для того, чтобы деталь не отправилась в непредсказуемый полет при фрезеровке.

    Может кому пригодится лайфхак: новый стол сделал из пластиковой террасной доски (продается в Кастораме):



    Доски болтами прикрутил прямо к алюминиевому родному столу. Бонусом получились удобные пазы для фиксаторов заготовки и быстрого монтажа присадочного стола. На все про все ушло пара часов и ~1100р.

    И во-вторых, наконец, написал более-менее юзабильный софт для управления нестандартными функциями ЧПУ. Про это и будет основной рассказ.

    Постановка задачи


    G-code для операций, которые описаны во второй части простейший. Тем не менее, сам процесс наладки нельзя назвать быстрым.

    Как это происходило


    Например, для присадки нужно было: зная ширину панели посчитать сколько должно быть отверстий, рассчитать точное расстояние между ними, создать файл, написать g-code, загрузить его в Mach3. Все это занимает, в лучшем случае, минут 15 — 20. В этом свете, преимущества цифрового станка значительно меркнут по сравнению с ручным инструментом, которым за это же время можно навертеть целую кучу дырок.

    Что хотелось получить


    В случае той-же присадки, хотелось получить программу, где в очень простом интерфейсе я бы вводил ширину и толщину панели и нажав кнопку запускал процесс сверления нужного количества присадочных отверстий на одинаковом расстоянии друг от друга.

    Поиск решения


    Первое что пришло в голову было написание автономной программы, которая напрямую бы взаимодействовала с параллельным портом. Беглый гуглинг показал, что задача записи в lpt вполне решаемая, но черт, как известно, прячется в деталях. При дальнейшем изучении вопроса я понял, что застрять тут можно всерьез и надолго. К тому же, такое решение было бы не гибким: для другого станка, например с USB, оно не работало бы.

    Оставался вариант разобраться с SDK Mach3. В процессе сбора информации про создание mach-плагинов я натолкнулся на интересное решение. В нем описывалось как используя OLE-механизмы можно дергать Mach3 из стороннего приложения. Я не эксперт в технологиях Microsoft, но после просмотра по диагонали мануала по SDK Mach3, если я правильно уловил основную идею, никакой серебренной пули не существует, плагины используют те же публичные методы COM-объектов Mach3. Перекраивать интерфейс Mach3 я не собирался, таким образом, разница для пользователя между плагином и standalon приложением получалась только в том, что плагин доступен из меню Mach3, а приложение — через иконку на рабочем столе XP.

    Отдельное приложение мне показалось предпочтительней. В этом случае, теоретически, я мог сразу после загрузки компьютера запускать свою программу, которая паровозом загружала бы Mach3 (вместо того, чтобы сначала грузить Mach3 и потом копаться в его меню для запуска плагина).

    Берем в руки шашку


    Последний раз нативное десктопное приложение для Windows мне приходилось писать году, эдак, в 2006 и было оно на Delphi. С тех пор веб-технологии с их Линуксом окончательно поглотили меня. Поэтому, сейчас особых предпочтений на каком языке ваять windows-программу у меня не было. Найденный простенький пример был написан на C#, этот язык и был выбран в качестве подопытного кролика.

    Я не буду здесь выкладывать весь код получившегося приложения (при желании можете его найти на github по ссылке внизу поста). Поясню основные вещи. Все эксперименты я проделывал на виртуалке с WinXP SP3, VS 2003 и Mach3 Version R3.043.062. Для тех кто считает, что лучше один раз увидеть ссылка на ролик в Youtube по которому разбирался я. Ниже расшифровка основных моментов.

    Подготовка


    1. Чтобы Visual Studio нормально подхватила компонент Mach3 нужно чтобы он корректно был прописан в реестре. Для этого качаем файл Mach3Registry.reg
    2. Запускаем Mach3Registry.reg
    3. Запускаем VS, создаем проект оконного приложения на C#
    4. В блоке Solution Explorer правый клик по References, в меню выбираем Add Reference. В открывшимся окне нажимаем Browse и ищем Mach3.exe



      Если все правильно, в списке References должна появиться строка, кто бы мог подумать, Mach4...
    5. 5. Далее рисуем UI, вешаем обработчики, реализуем алгоритмы...

    Взаимодействие с Mach3


    Подключаем нужные библиотеки, объявляем переменные (Form1.cs)

    ...
    using System.Runtime.InteropServices;
    using Mach4; // Подключаем компонент Mach
    
    namespace Cnc
    {
        public class Form1 : System.Windows.Forms.Form
        {
            private IMach4 _mach;   
            private IMyScriptObject _mInst;
            ...
    
            // получение ссылки на запущенный экземпляр Mach3
            private void GetMachInstance() 
            {
                try 
                {
                    _mach = (IMach4) Marshal.GetActiveObject("Mach4.Document");
                    _mInst = (IMyScriptObject) _mach.GetScriptDispatch();
                } 
                catch 
                {
                    _mach = null;
                    _mInst = null;
                }
            }
    ...
    

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

    GetMachInstance(); // 
    if(_mInst != null) 
    {
        _mInst.DoOEMButton(1003); // Нажатие на кнопку Stop в Mach3
        _mInst.Code("G00 X100"); // Выполнение G-code
        _mInst.GetOEMDRO(800); // Получить текущее значение координаты X
    }
    

    Коды кнопок и значений параметров можно посмотреть в вики: OEM_DROs и OEM_Buttons (Wiki у них подглючивает, значения параметров в таблице не выводится, я смотрел на вкладке «View source»).

    Первая версия программы работала так: по установленным параметрам генерировался g-code который покадрово (т.е. построчно) выполнялся методом _mInst.Code. И это было моей ошибкой. В отладочной среде на виртуалке все прекрасно работало. В Mach3 бежали правильные цифры в координатах. Но при переносе на станочный компьютер возникли проблемы. Каретка перемещалась правильно, но шпиндель не включался.

    Похоже, что управление роутером и шпинделем в Mach работает в разных потоках. Получалась ситуация, что команды перемещений (G...) выполнялись последовательно как они поступали в метод _mInst.Code в одном потоке, а команды управления шпинделем (M3, M5), не зависимо от первых, выполнялись в другом потоке. В результате, шпиндель включался (M3) и тут же выключался (M5), при этом перемещение каретки шло своим чередом.

    Я пробовал разные варианты, подключал задержки, пробовал загнать весь управляющий g-code в одну строку и отправлять одним куском в _mInst.Code. В результате, остановился на решении «в лоб»: просто загоняю сгенерированный код в файл, этот файл программно открываю в Mach3 и там же программно нажимаю кнопку «Старт». Фрагмент работающего кода:

    _mInst.LoadFile("C:\\tmp\\gcode.txt");
    System.Threading.Thread.Sleep(2000);
    _mInst.DoOEMButton(1000);
    

    Пауза между загрузкой файла и нажатием кнопки нужна для того, что бы Mach успел открыть файл. Возможно, есть какой-то более изящный способ. Если кто знает, напишите в комментариях.

    Дополнительным бонусом такого решения получилось то, что теперь можно в интерфейсе Mach наблюдать визуализацию процесса обработки.

    Что в итоге получилось


    Далее, в двух словах о получившемся приложении. Отдельно расскажу о UI для каждой операции.

    Раскрой




    Тут все достаточно прозрачно. Параметр S нужен для компенсации размера L если заготовка закреплена не в нулевой точке по Х (или по Y при распиле вдоль).

    Присадка


    Для присадки возможны 2 конфигурации оснастки. Первая с болгаркой для сверления торцевых отверстий. И вторая с обычным шпинделем для сверления в плоскости щита (почему-то я назвал ее «Присадка фронтальная»).

    Присадка торцевая




    При торцевой присадке важно точно выставить ноль в правом нижнем углу заготовки (у меня там находится угол бокового упора и стола). Со сверлом по дереву это сделать не сложно — там есть острый наконечник которым и надо попасть в этот угол. Закрепляя заготовку на столе я просто упираю ее в сверло.


    Не меняя оснастку тем же способом я делаю ответные отверстия закрепляя заготовку вертикально:


    Параметр X нужен для того, чтобы соединять панели разной ширины (например, когда нижняя и верхняя панели шкафа шире боковых на толщину дверей).

    Присадка фронтальная




    Оснастка для фронтальной — это обычный шпиндель. Этот вид присадки используется когда нужно насверлить отверстий в горизонтальной поверхности не только по краям но и где-то посередине. Например, если в шкафе несколько отделений и кроме боковых стенок есть внутренние. Если длина панели больше длины станка, присадку можно сделать в 2 подхода с разворотом детали на 180 градусов. В этом случае, так же пригодится параметр X.

    Токарная обработка




    Для меня основной сложностью при подготовке g-code с токарной траекторией было не переборщить с максимальной глубиной погружения диска. Дело в том, что на выходе из Inkscape получается одна линия и точение происходит в один проход. Из-за этого, мне приходилось делать отдельный код для цилиндрования заготовки и только после этого запускался основной проход создающий форму. И были некоторые ограничения на эту форму. В частности, нужно было следить, чтобы траектория не уходила слишком глубоко. Я старался не выходить за рамки 10 — 15мм от уровня первоначального цилиндра.

    Все перечисленные проблемы удалось решить в новой программе. Работает это так: загружаем «сырой» g-code полученный из Inkscape, задаем размер стороны бруска заготовки и указываем максимальную глубину обработки за 1 проход (чем тверже деревяшка, тем меньше эта глубина). На базе исходного g-code и параметров программка посчитает безопасную траекторию и отправит ее в ЧПУ.

    Планы на будущее


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

    Ссылки


    Mach3Registry.reg
    Mach3 SDK и другие программы
    Репозиторий проекта на Github (заранее прошу прощения у шарповиков за архитектурные косяки — это моя первая программа на С#).
    Поделиться публикацией

    Комментарии 32

      +2
      Просто шикарно!
        +1
        Хорошую вещь ты сделал, и руководство отличное.
        Сохраню себе всё это, появиться место, тоже хочу собрать ЧПУ, очень нужная вещь.
          +1
          Спасибо за подобный пост. Если что могу помочь в области обработке, а также с выводом уп. Для mach3 есть довольно много постпроцессоров в solidcam, которые просто редактируются под ваши нужды. Также в solidcam есть опция «шаблоны» позволяет автоматизировать однотипные операции.
            +1
            Вообще, в Mach3 есть как минимум три (!) встроенных инструмента специально для этих задач.
            1. Скринсет это способ представления Mach3. Такой скринсет делается в визуальном редакторе за несколько минут, можно добавить на него свои поля для ввода данных, кнопочки, чекбоксы и набор подпрограмм, он будет выглядеть так же, будет собирать данные из полей и текущего состояния станка и генерировать на выходе g-code или напрямую управлять станком.
            2. Wizard-ы — то же самое, только собранное в отдельный инструмент.
            3. Teach wizard
            У любого из этих способов есть доступ к внутреннему состоянию станка — то есть программа может менять свое поведение в зависимости от текущего инструмента или позиции станка, например. В Mach4 вообще реализован полноценный событийный механизм, и можно написать свое приложение внутри контроллера.
              0
              Маловато доступной информации, хотя, возможно, я не там искал. Напишите, по возможности, пост на эту тему. Я сделал как мне привычнее, но, скорее всего, есть более простые варианты. Хотя, и этот способ я бы не назвал сложным)
                0
                Mill Wizard — это оно? Однако, $75 за лицензию…
                  0
                  Насчет скринсетов посмотрел информацию. Может кому пригодится, тут можно скачать редактор экрана. С виду там ничего сложного, но если нужно что-то кроме кастомного экрана mach3, все-равно придется разбираться с его макросами на VB.
                    0
                    Это проще чем кажется! Посмотрите две pdf:
                    Mach3_V3.x_Macro_Prog_Ref.pdf
                    VBScript_Commands.pdf
                    Скорее всего Вам будет достаточно четырех функций на все случаи в жизни:
                    GetOEMDRO(), GetUserDRO(), SetUserDRO() и разумеется Code()
                      0
                      Да, все то же самое, что в варианте с моей программой на шарпе. Разница только в том, в чем форму рисовать — в VS или в специализированном редакторе. Мне кажется, в универсальной IDE, все-таки, возможностей побольше. Пусть каждый выбирает, что ему больше нравится. По-моему, мы описали все возможные направления кастомизации mach :)
                  0
                  Что-то мне кажется в Linux CNC это все сделать в разы проще. А цикл глубокого сверления уже стандартно есть во всех нормальных чпу. В Linux cnc это G83
                    0
                    А тут-то чего сложного? 3 строки кода для общения с железкой, остальное обычные формы и немного математики…
                    В Linux cnc это G83

                    Думаю, это не функция cnc linux, скорее всего, это зависит от контроллера. В моем стоит дешевый китаец, некоторые не самые продвинутые коды он не понимает. Например, игнорирует компенсацию диаметра фрезы.
                      0
                      Да там нет никакого контроллера. В простейшем случае программа выдаёт сигналы управляющие двигателями через параллельный порт. Очень удивлён что есть ЧПУ не умеющие делать компенсацию диаметра инструмента. Это вообще одна из базовых функций. Но тут надо понимать что есть компенсация на диаметр инструмента и отдельно есть компенсация на износ инструмента. Все дополнительные коды M и G реализуются в виде макросов/скриптов, юзер может сам наделать нужных ему циклов. Насколько помню, в mach язык похожий на basic. Есть папочка в которой лежат эти макросы. И файл с именем G83 для цикла глубокого сверления там уже должен быть готовый. И ваши проблемы с токарной обработкой из этой же оперы. Должен быть готовый макрос которому задаёшь профиль а он за несколько проходов съедает лишний материал перед заданным профилем. Например как тут image Я не специалист по китайским дешёвым чпу и возможно поэтому мне не понятны ваши проблемы.
                        0

                        Ну, как бы, заголовок поста не подразумевает чего-то промышленного. В дешёвых любительских девайсах много нюансов над которыми профи будет смеяться. Например, мне приходится вручную выставлять прямой угол между x и y, пришлось даже специальное приспособление придумывать. В области софта та же ситуация: не все профессиональные приемы тут работают.

                          0
                          > есть ЧПУ не умеющие делать компенсацию диаметра инструмента

                          Если вы специалист по дорогим ЧПУ, то должны понимать задача компенсации G40 G41 в общем виде вообще никак не решается на стороне контроллера, а должна решаться на стороне CAM, у контроллера просто недостаточно данных для этого.

                          Я нарисовал пример — красным оригинальный контур, синим и зеленым — пути полученные разными значениями компенсации G41. Можно увидеть что синий путь разбит на два несвязных пути. Что должен в таком случае сделать контроллер?

                          Если ваше предложение — перестроить порядок выполнения путей, то вы создаете непредсказуемый контроллер, который рано или поздно кого-нибудь искалечит.

                          Если ваше предложение — игнорировать это и заехать инструментом в деталь, то вы делаете предсказуемый контроллер, который на финишной обработке предсказуемо заедет в деталь, сломает фрезу, и тоже может искалечить кого-нибудь.

                            0
                            Я не большой специалист по дорогим ЧПУ. И не очень представляю что вы имеете ввиду под названием «контроллер». Китайцы понаделали много разных «контроллеров», которые понимают G код, но они все убогие и кроме самых необходимых G0 G1 и ещё нескольких ничего не умеют. Может вы считаете их за ЧПУ. Я их вообще не рассматриваю. Вполне полноценные ЧПУ из любительских это mach3 да Linux CNC. Даже простые ЧПУ умеют делать компенсацию на диаметр инструмента. Программист задаёт контур детали а траекторию инструмента рассчитывает ЧПУ. Диаметр инструмента задан в таблице инструментов конкретного станка. Другой вариант траекторию инструмента расчитывает CAM программа, с учётом таблицы инструментов в этой программе. В этом случае программа годится только для конкретного станка с конкретным инструментом. При смене инструмента надо переделывать всю программу. А если нужна точность то придётся учитывать реальный диаметр инструмента с учётом износа. Каждый раз перевыпускать программу из САМ не интересно. Конечно для китайских станков которые пилят фанеру и дерево это всё не актуально.
                              0
                              Зачем нужна компенсация на ширину инструмента в контроллере, вопрос не стоит вообще, ответ и так очевиден. Я пытаюсь рассказать, почему в ЧПУ контроллерах ее не делают. А если делают, то только на jet cutting, где вылевшая 7-кг фреза не прилетит оператору в голову, пробьет ее насквозь, и воткнется по хвостовик в бетонную стену, а кто будет её вытаскивать?

                              Бездумное применение этой функции ведет к неопределенному поведению контроллера, такой контроллер просто опасен.

                              Я привел простой пример контура выше, а с тех пор как я разрабатывал CAM, у меня есть специальная папка для таких примеров. На некоторых даже крутые CAM программы генерируют странное поведение. Мой любимый пример — внешне совершенно безобидная буква из кельтского алфавита, типа Й, на которой ломаются контроллеры, пытаясь компенсировать её на ширину инструмента. Вы же не хотите чтобы при попытке вырезать совершенно обычный контур вас задавил двухтонный портал внезапно поехавший не туда?

                              Прибавьте к этому что нормальная компенсация на ширину требует полной загрузки shape в память. А что контроллер будет делать если ему встретится один Shape из двух частей по 2 гигабайта каждый? Многопроцессорный десктоп с навороченным CAM считает такие файлы по часу, что тут сможет stand-alone контроллер с его процессором?

                              У меня сейчас на складе лежит штук 15 разных разных ЧПУ контроллеров — и китайских, и американских, и европейских, и австралийских контроллеров (там есть и которые я помогал разрабатывать). Еще больше, под 100 разных других контроллеров приходилось настраивать, ценой до нескольких тысяч долларов. Некоторые ужасные, какие-то удачные, некоторыми я восхищаюсь. В одних есть компенсация, в других нет. Но никто не ставит компенсацию просто потому что так хочется. Пользователь может ввести точку не в том месте для инструмента и ему отрежет руки, а кто за это будет отвечать?

                              В примере Mach3 который вы привели выше, компенсация на ширину инструмента работает не так как вы думаете. И даже такая инвалидная реализация G41 связана кучей ограничений, и запретов на выполнение целого списка G кодов — чтобы никого не убило.
                                0
                                Вы говорите про какие-то контроллеры. Я так понимаю речь про маленькие коробочки с хилым процессором внутри, которая читает G-code, например с флэшки и двигает шаговики. Их понаделали сотни разных кто на что горазд и каждая работает как вздумается её создателям. Я про них ничего не скажу. Я говорил про полноценные ЧПУ, те что по старой традиции называют стойкой ЧПУ. Мач и линукс снс вполне можно отнести к полноценным системам. Таблица инструментов и компенсация радиуса инструмента одни из базовых функций любой ЧПУ.
                                  0
                                  Да пожалуйста — я могу привести три примера моих любимых контроллеров:

                                  Edge Connect / Phoenix один из самых удачных контроллеров в мире от крупной международной компании, и в нем нет компенсации на ширину. Черная коробочка с хилым процессором? Да. Стоит больше $3000 без экрана и всей остальной электроники «стойки ЧПУ»? Да. Компенсация на инструмент? Нет.

                                  Masso. Гениям которые сделали эту оранжевую коробочку за $600, я бы пожал руку. Но компенсации на ширину здесь нет тоже.

                                  Противоположный пример — GRBL/mini стоимостью $1. Компенсация G41? Нет.

                                  Добавление компенсации на инструмент тянет за собой усложнение логики контроллера в десятки раз, и хуже того: UB, неопределенное поведение, когда никто, даже автор, не может сказать что сделает контроллер в этом месте. Там же где эта функция есть, большая часть документации должна быть посвящена именно объяснению поведения контроллера в тех или иных пограничных ситуациях и отказу от ответственности.

                                  Это интересно что вы приводите в пример Mach3, но вы сами-то ожидаете от него устойчивости? предсказуемости? Непредсказуемыми флуктуациями, волей случая программа оказалась популярна в двух странах мира — в Штатах и в России, и больше нигде в мире.
                                    0
                                    Мне не нравятся эти контроллеры из-за их функциональной убогости. Сколько бы они ни стоили. Не вижу смысла в их применении. Разве что на станке под единственную операцию где оператор мартышка и страшно его подпускать к компьютеру. И мач тоже не нравится. Совсем другое дело полноценные ЧПУ. Всякие сименсы фануки и прочее. А если это дорого то есть Linux CNC.
                        0
                        Согласен. Почему ТС — линуксовод судя по информации выше не поставил сразу linuxcnc?
                        Переход на линукс поднял мне максимальную скорость перемещений почти в 2 раза и убрал пропуски шагов. Правда давно это уже было.
                          0
                          Я в первом посте написал про причину. Там проблема была не с линуксом, а с моим пониманием темы ЧПУ в целом на тот момент. После тех экспериментов, по-моему, у меня портал немного кривой (про угол между x и y я писал выше).
                            0
                            Возможно потому что у него китайский станок, а китайцы любят mach. И любят изобретать велосипеды. Кривые, но зато свои. Я когда-то первый станок делал с mach. Но когда попробовал Linux CNC понял что mach мне больше не нужен.
                              0
                              Я не являюсь адептом какой-то определенной ОС. По работе у меня все проекты на линуксе, но инструменты разработки (IDE), на мой вкус, лучше в винде. Поэтому, на компе винда с VS, для тестов — виртуалка с убунтой или центосом. То же с хобби — на линуксе импортированный родной конфиг не заработал и быстро разобраться в причинах не получилось — время дороже, поставил xp и mach. Увижу необходимость переехать на линукс, перееду. Пока mach устраивает, а дальше будет видно…
                                0
                                Там дело не в линуксе или винде. Изначально Linux CNC очень гибкая система, из которой можно сделать что угодно. Вполне возможно управление настоящими металлообрабатывающими станками где серводвигатели и оптические линейки для обратной связи, куча гидравлики и пневматики для управления которыми нужен PLC. В Mach3 такое устанешь делать. А если весь станок это три шаговых движка да шпиндель, через LPT, то без разницы что использовать. Пока не захочется сделать из этого что-то не очень стандартное.
                                  0
                                  Ну так мы и обсуждаем гаражный ЧПУ. Понятно, что для производственного оборудования должны применяться совсем другие подходы. Как минимум, тут нужно соответствующее образование. Хоббийными же проектами занимаются люди, типа меня, зачастую, профессионально никак не связанные с производством. Для нас важны 2 вещи — время и деньги. И того и другого, как правило, на хобби остается не много, соответственно, ищем что подешевле и как побыстрее :)
                                    0
                                    Да хоть хоббийный хоть какой станок. Пока не выходите за рамки стандартных 3-х осей проблем нет. А как надо автоматически расчитать координаты отверстий или болгарку вместо шпинделя прикрутили так и начинаются танцы с бубном. И хорошо когда ЧПУ не ограничивает вас в ваших фантазиях.
                                      0
                                      Ну я не вижу особых проблем подвигать портал туда-сюда командами G1 вместо цикла сверления или написать строчку кода на С с математикой 3го класса…
                          +1
                          Как насчет того, чтобы объединить усилия?
                            0

                            С мобильника не смог зайти на сайт, чуть позже гляну с ноута. Вы делаете cad-систему?

                              0
                              Да, делаю CAD систему
                              0
                              Выглядит круто. Кривых Безье пока нет? Я правильно понимаю, Вы хотите на выходе получить что-то типа онлайн фрикад?
                                0
                                Ну как раз над ними работаю. Ну freecad сложно получить, да и незачем. Хочу что-то менее хардкороное для DIY — с поддержкой редактирования STL для 3д печати или CNC. Хотя пока не очень понимаю, куда двигаться.

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое