Forge Viewer: Перевод координат листов моделей AEC в координаты 3D видов
При работе с AEC (architecture, engineering, construction) моделями у разработчиков приложений Forge Viewer переодически появляется задача преобразования координат из системы координат листов в координаты 3D видов или наоборот. Давайте посмотрим, как мы можем это реализовать.
В прошлом году мой коллега Xiaodon рассказал в своей статье (примечание: см. перевод на нашем сайте), как получать специфичную для моделей AEC информацию (например такую, как уровни, оси, виды, стадии и т.д.) с помощью сервиса Forge Model Derivative. В принципе, при преобразовании AEC-моделей, вся эта информация становится доступна в отдельном JSON файле:
Скорее всего, Вы уже видели немало расширений Forge Viewer-а, использующих её, например:
- Autodesk.AEC.LevelsExtension - позволяет показывать или, наоборот, скрыть уровни модели здания
- Autodesk.AEC.Minimap3DExtension - при включенном инструменте "От первого лица" показывает Ваше положение на мини-карте
Такие расширения используют объект Autodesk.AEC.AecModelData, содержащий описанные выше метаданные и предоставляющий множество методов для работы с ними, например:
- Autodesk.AEC.AecModelData.findViewportsOnSheet(sheet) - находит viewport-ы на листах (области просмотра, т.е., например, виды планов, разрезов, размещенные на листах). Из манифеста модели, который загружает метод Autodesk.Viewing.Document.load можно получить список доступных для просмотра видов моделей, т.е. 3D-виды, 2D-виды и листы. Параметр sheet должен принимать как раз последние, т.е. листы
- Autodesk.AEC.AecModelData.get2DTo3DMatrix(viewport, sheetUnitScale) - вычисляет матрицу THREE.Matrix4 преобразования из 2D-координат viewport-а листа в 3D-координаты модели
- Autodesk.AEC.AecModelData.get3DTo2DMatrix(viewport, sheetUnitScale) - вычисляет матрицу THREE.Matrix4 преобразования из 3D-координат модели в 2D-координаты viewport-а листа
- Autodesk.AEC.AecModelData.findViewportAtPoint(sheet, point, filter) - находит viewport по заданным 2D-координатам на листе
Теперь рассмотрим, как мы можем использовать эти функции в нашем коде:
Шаг 1: Подготовка
Вспомогательные функции Autodesk.AEC.AecModelData не включены в Forge Viewer. Чтобы их использовать, можно загрузить одно из расширений, указанных выше, например:
- const config = {
- extensions: ['Autodesk.AEC.LevelsExtension']
- };
- let viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('preview'), config);
Шаг 2: Загрузка AEC метаданных
Нужно явно в коде указать, что нам необходимо загрузить метаданные. Это можно сделать с помощью функции Autodesk.Viewing.Document.getAecModelData:
- function loadModel(viewer, urn, guid) {
- function onDocumentLoadSuccess(doc) {
- // Асинхронный запрос получения метаданных. После их загрузки они будут доступны в свойстве `aec_model_data` объекта `doc`
- Autodesk.Viewing.Document.getAecModelData(doc.getRoot())
- .then(aec => console.log('AEC metadata', aec));
- // Запускаем загрузку модели
- viewer.loadDocumentNode(doc, doc.getRoot().findByGuid(guid))
- }
- function onDocumentLoadFailure(code, message) {
- console.error('Could not load document.', message);
- }
- Autodesk.Viewing.Document.load('urn:' + urn, onDocumentLoadSuccess, onDocumentLoadFailure);
- }
Шаг 3: Поиск viewport-а по заданным 2D-координатам
Используем метод Autodesk.AEC.AecModelData.findViewportAtPoint, чтобы найти viewport по заданным 2D-координатам, например, полученным с помощью метода Viewer3D.hitTest
- const viewport = Autodesk.AEC.AecModelData.findViewportAtPoint(model2d, new THREE.Vector2(sheetPos.x, sheetPos.y));
Шаг 4: Получаем преобразование координат из системы координат viewport-а в систему координат 3D-модели
Получим матрицу преобразования THREE.Matrix4 с помощью метода Autodesk.AEC.AecModelData.get2DTo3DMatrix:
- const sheetUnitScale = sheetModel.getUnitScale();
- const matrix = Autodesk.AEC.AecModelData.get2DTo3DMatrix(viewport, sheetUnitScale);
С помощью этой матрицы можно преобразовывать координаты. Обратите внимание, что у 3D-модели может быть дополнительно задано смещение, которое следует принять во внимание:
- const globalOffset = model.getData().globalOffset;
- const worldCoords = sheetCoords.clone().applyMatrix4(matrix).sub(globalOffset);
Полный код примера доступен по адресу: https://github.com/petrbroz/forge-viewer-samples/blob/master/public/aec-mapping-2d-to-3d.html
Посмотреть как это работает можно здесь: https://forge-viewer-samples.herokuapp.com/aec-mapping-2d-to-3d.html
Источник: https://forge.autodesk.com/blog/mapping-between-sheets-and-3d-views-aec-models
Опубликовано 31.10.2020