Dragon3DGraff_Blog — Creating 3D Editor

TertiusAxis

Создание стен. Часть 1. Создание эквидистант.

Для построения стен заданной толщины по заданной полилинии необходимо определение эквидистант к этой линии. Основной задачей построения эквидистант является нахождения точек в углах линии – пересечений эквидистант. Для каждой точки полилинии определяем внутреннюю и внешнюю точку эквидистанты и добавляем их в соответствующие массивы Определение внутренней точки происходит следующим образом Первое – определяем вектора, компланарные линиям, выходящим из данной точки, для это производим вычитание векторов вершин и нормализуем им для получение единичного вектора. второе – определяем угол между ними точка эквидистанты всегда лежит на биссектрисе угла, поэтому угол делим пополам затем определяем гипотенузу в треугольнике, образованном половиной толщины стены и полилинией. Обозначим ее bisectorLength получим вектор, выходящий из вершины в точку b поворотом вектора leftSide на угол alfa все, что нам остается – это перенести точку B  по полученному вектору. Для этого умножим его на скаляр – длину полученного отрезка bisectorLength и произведём сложение вектора вершины угла и полученного вектора. построение конечных точек незамкнутых линий осуществляет подобным образом, только угол всегда одинаков const angle = 3 * Math.PI / 4; Обработка конечных точек полилинии происходит следующим образом Полный код можно увидеть здесь https://jsfiddle.net/Dragon3DGraff/w5pufk04/10/

Читать далее

Серверная часть. Регистрация и авторизация

Для дальнейшего развития редактора необходимо создание серверной части приложения. Для разработки серверной части я использовал Node.js, Express и базу данных MongoDB. Первым шагом реализации стало создание регистрации и авторизации на сайте. Реализация довольно проста. Стартовый файл подключает middlewares и подключается к базе данных.  Создал роуты с эндпойнтами /register’, ‘/login’ и ‘/logout’/. Для проверки правильности заполнения полей формы использую библиотеку ‘express-validator’, она добавляется в роутер как middleware. Для шифрования пароля использовал библиотеку ‘bcryptjs’, для создания токена библиотеку ‘jsonwebtoken’. Токен на клиенте храню в cookies, с флагом “ httpOnly ”, чтобы не было доступа к нему из Javascript. При загрузке приложения выполняется проверка, зарегистрирован ли пользователь. Полностью серверную часть можно посмотреть на https://github.com/Dragon3DGraff/TertiusAxis_server

Читать далее

Draggable menu (React)

Меню, созданное React, я отделил от основного меню. Для разнообразия сделал там три кнопки, переключающими отображение разного содержимого в одном окне. Первое, что мне было интересно сделать это перемещение окна. Для этого я создал div в виде полосы в верхней части окна. При нажатии на неё активируется Drag Mode, при отпускании клавиши мыши над всем окном Matcap режим отключается. Функция enableDragMode переключает state и устанавливает точку, в который произошел клик При переключении режима в useEffect добавляется или удаляется listener на событие движения мыши: При перемещении мыши с зажатой левой клавишей происходит изменение координат div.  Так же добавлены проверки, чтобы div не мог двигаться дальше краев окна. Полный код компонента Matcap.js

Читать далее

Matcap menu using React

Однажды я закинул ссылку на свой блог в одну из групп на Facebook, посвященной Three.js. Один из комментаторов сказал мне, что было бы круто, если бы я добавил в редактор Matcap. И я решил – а почему бы и нет.  Но данный пост посвящен больше использованию React нежели созданию Matcap, так как материал Matcab реализован в Three.js и вся задача сводится к тому, чтобы применить этот материал и назначить изображение. Прежде я старался использовать только Vanilla JS, так как проект учебный. Но и по этой же причине я решил попробовать применить React для части интерфейса, так как изучение React (или какого-то другого из трех китов фронтенда) является неотъемлемой частью обучения web-программиста. Мне было интересно именно внедрить React в существующий проект, самому настроить Webpack, что вполне у меня получилось, конечно, не без преодоления трудностей — при установке React из npm почему-то удалились все модули, которые у меня были установлены до этого, Webpack начал ругаться и проект перестал собираться. Для связи событий между меню React и редактором мне понадобился state-менеджер. Я умышленно пока не использую готовые решения типа Redux, так как хочу написать сам и понять, как это работает. Нашел урок в интернете и написал свой EventEmitter: Затем создал класс State, тоже

Читать далее

Легкая сборка (threejs)

Последние два месяца не было времени заниматься разработкой редактора, так как был приглашен в качестве разработчика компанией «Пермская деревянная игрушка» https://dolodom.com/, которая занимается изготовлением различных изделий из фанеры. Для сборки и визуализации макетов они развивают собственный редактор, созданный на базе стандартного редактора three.js. Сборка макета происходила примерно так, как на этом видео https://www.youtube.com/watch?v=yTAZi-5-EfA. Есть привязка по вершинам сетки, что удобно. Я предложил несколько усовершенствовать процесс сборки и сделать его более простым для пользователя. Вначале я хотел сделать просто выравнивание плоскости шипа по плоскости паза (и реализовал это). Но мы решили, что это тоже не так удобно и решили попробовать сделать инструмент, наиболее приближенный к реальности. А в реальности у нас шип вставляется в паз. То есть нужно определить, что является пазом, а что шипом. С учетом того, что геометрия формируется в Blender на стороне сервера из кривых, импортированных из векторных редакторов, в качестве исходных данных мы имеем мэш с двумя типами материала – лицевая сторона и торец. То есть никакой информации о том, что является шипом или пазом нет, только набор точек и треугольников. Для реализации инструмента мной был написан алгоритм анализа мэша. Во-первых, нужно было упростить модели для расчетов. Для этого все грани торца (лицевая часть отбрасывается, так как

Читать далее

Редактирование сетки: треугольники

Реализовал изменение сетки объекта перемещением грани. Но данное решение очень ресурсоёмкое, Это видно, когда в объекте довольно много треугольников. Причиной этому является то, что я создаю вспомогательный треугольник для каждого треугольника объекта, и при движении треугольника все их удаляю и создаю заново. В качестве решения решил делать вспомогательный треугольник только для того треугольника, который собираюсь двигать. Сейчас для этого реализовал создание такого треугольника при движении мыши. Так будет подсвечиваться треугольник, который можно выбрать

Читать далее

Редактирование сетки: вершины

Сегодня сделал, пожалуй, самый значимый для себя функционал. Мне было очень интересно сделать возможность редактирования сетки объекта. Пока реализовано только перемещение вершин по одной. На реализацию у меня ушло 2 дня, и еще больше на обдумывание и теоретическую подготовку. Редактирование реализовано для BufferGeometry. Сначала в места вершин расставляю маленькие сферы Так как координаты вершин хранятся в буфере, представляющем собой массив значений с шагом 3: [ x1, y1, z1, x2, y2, z2 … xn, yn, zn ], нужно получить координаты точек в виде векторов Но точки повторяются. Например, для куба (8 вершин)  — 24 точки, по 3 точки на вершину (одна точка для одной грани) Получим массив координат вершин: В каждую вершину помещаем сферу Редактирование геометрии я сделал статическим методом. Передаю в него объект, номер вершины, которая изменятся и её положение Теперь нужно сделать обратную процедуру. Находим в каких позициях массива points содержатся координаты вершин Меняем значение положения вершины и меняем массив points Который в свою очередь меняет значения в буфере объекта Изменение происходит  на событие

Читать далее

Выделение нескольких объектов, клонирование

Реализовано выделение нескольких объектов. При этом центр выделения устанавливается в геометрическом центре масс, так называемом барицентре, который определяется следующим образом Барицентр определяется сложением векторов положения точек, входящих с группу и делится на количество точек. Для реализации множественного выделения создана группа в объекте currentselection и добавлена в сцену момент инициализации сцены Для инициализации множественного выделения нужно удерживать нажатой клавишу Ctrl. Сначала проверяем, выделен ли какой-то объект. Если выделен, то добавляем его в группу multiselection. Создаем массив из объектов, входящих в группу multiselection и проверяем, есть выделяемый объект в этой группе. Если нет — то добавляем его в группу, если да — то удаляем его из выделения: Возвращаем все объекты из группы в сцену ,чтобы установить новое положение группы, переместив его в геометрический центр масс. Для этого определяем положение всех объектов выделения Возвращаем все объекты из сцены в группу При этом используем метод .attach, который, в отличие от .add, добавляет объекты в группу с учетом мировых координат. То есть, если у объекта координаты ( 0, 0, 0 ), а у группы ( 10, 10 , 10 ), то .add добавит в точку размещения группы, то есть в ( 10, 10 , 10 ), а .attach оставит объект в точке ( 0, 0,

Читать далее

Saving, Loading and Manipulating.

Доработал функцию сохранения сцены. Файл сцены, созданной в редакторе TertiusAxis, имеет расширение «.trxs». Сейчас это текстовый файл с данными в виде массива с элементами в формате JSON, представляющими собой объекты сцены. Сохраняются только объекты, созданные пользователем. Для этого осуществляется проверка элементов массива children сцены, в которых  userData = true. По этому же принципу сделана очистка сцены в модуле TA_Scene: Сохранение файла вынесено в отдельную функцию Добавлена функция «Merge with scene from disk», которая добавляет в существующую сцену объекты из другой сцены. При загрузке сцены проверяется только расширение файла “.trsx”, но в будущем, когда формат файла изменится, будет проверяться структура файла. Вся сцена может быть экспортирована в GLtf формат Реализовал функциональность кнопок манипуляции объектом: перемещения, вращения, масштабирования и перетаскивания, подключив соответствующие модули библиотеки three.js. Реализовано клонирование объекта нажатием на клавишу “с”, а также выбором соответствующего пункта меню вкладки Edit. При этом геометрия клонов независима, а материал один и тот же, то есть, меняя цвет одного объекта  — меняется цвет у всех. TODO: — Сделать выделение нескольких объектов и манипулирование ими, а так же клонирование всех выделенных объектов. Для этого в объекте currentSelection создать поле multiselect: new Group() и добавлять выделяемые объекты в группу. — реализовать или использовать существующую библиотеку по отслеживанию

Читать далее