ADN Open CIS
Сообщество программистов Autodesk в СНГ

31/10/2020

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. Чтобы их использовать, можно загрузить одно из расширений, указанных выше, например:

Код - JavaScript: [Выделить]
  1. const config = {
  2.     extensions: ['Autodesk.AEC.LevelsExtension']
  3. };
  4. let viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('preview'), config);

Шаг 2: Загрузка AEC метаданных

Нужно явно в коде указать, что нам необходимо загрузить метаданные. Это можно сделать с помощью функции Autodesk.Viewing.Document.getAecModelData:

Код - JavaScript: [Выделить]
  1. function loadModel(viewer, urn, guid) {
  2.     function onDocumentLoadSuccess(doc) {
  3.         // Асинхронный запрос получения метаданных. После их загрузки они будут доступны в свойстве `aec_model_data` объекта `doc`
  4.         Autodesk.Viewing.Document.getAecModelData(doc.getRoot())
  5.             .then(aec => console.log('AEC metadata', aec));
  6.         // Запускаем загрузку модели
  7.         viewer.loadDocumentNode(doc, doc.getRoot().findByGuid(guid))
  8.     }
  9.     function onDocumentLoadFailure(code, message) {
  10.         console.error('Could not load document.', message);
  11.     }
  12.     Autodesk.Viewing.Document.load('urn:' + urn, onDocumentLoadSuccess, onDocumentLoadFailure);
  13. }

Примечание: Если метаданные не были загружены, возможно, они не были созданы сервисом Model Derivative, можно проверить, существуют ли эти данные в манифесте модели, нужно искать по свойству "role" равному "Autodesk.AEC.ModelData". Если этих данных нет в манифесте, стоит попробовать запустить трансляцию заново, возможно, сохранив перед этим исходную модель в более новой версии приложения, в котором она разрабатывалась.

Шаг 3: Поиск viewport-а по заданным 2D-координатам

Используем метод Autodesk.AEC.AecModelData.findViewportAtPoint, чтобы найти viewport по заданным 2D-координатам, например, полученным с помощью метода Viewer3D.hitTest

Код - JavaScript: [Выделить]
  1. const viewport = Autodesk.AEC.AecModelData.findViewportAtPoint(model2d, new THREE.Vector2(sheetPos.x, sheetPos.y));

Шаг 4: Получаем преобразование координат из системы координат viewport-а в систему координат 3D-модели

Получим матрицу преобразования THREE.Matrix4 с помощью метода Autodesk.AEC.AecModelData.get2DTo3DMatrix:

Код - JavaScript: [Выделить]
  1. const sheetUnitScale = sheetModel.getUnitScale();
  2. const matrix = Autodesk.AEC.AecModelData.get2DTo3DMatrix(viewport, sheetUnitScale);

С помощью этой матрицы можно преобразовывать координаты. Обратите внимание, что у 3D-модели может быть дополнительно задано смещение, которое следует принять во внимание:

Код - JavaScript: [Выделить]
  1. const globalOffset = model.getData().globalOffset;
  2. 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