Получаем данные модели здания с помощью Model Derivative API
Model Derivative API позволяет получать данные AEC (Architecture, Engineering, Construction) - модели здания из файла Revit-а, такие как уровни, оси, виды, стадии, связанные документы и т.д. Forge Viewer также предоставляет соответствующие методы.
Model Derivative API получает общие данные исходной модели - дерево иерархии элементов, свойства объектов, их геометрию. В большинстве случаев, этих данных достаточно при работе с Forge Viewer. В то время как в файле Revit есть специфичная для модели здания информация, которую зачастую хочется интегрировать в приложение, такая как виды, оси, уровни, стадии, связанные документы и т.д.
У нас уже есть несколько решений подобных проблем:
- Уровень по имени узла - решение ищет узлы в дереве модели с именем level, и изолирует объекты с одинаковым значением уровня
- Оси сетки на основе обобщённых моделей - решение создает обобщённые модели для визуализации осей сетки в Forge Viewer
С определенного релиза, Model Derivative API имеет возможность получать данные AEC, а Forge Viewer предоставляет соответствующие методы. Эти данные не доступны в кэше по умолчанию после загрузки модели во Viewer. Соответственно, первый шаг - вызвать метод downloadAecModelData документа viewer-а, далее методом getAecModelData получить необходимую информацию, примерно следующего вида:
Большая часть данных вполне понятна по именам в схеме.
grids: вся информация об осях сетки основного и связанных документов. Свойство document каждой оси сетки показывает, в какой модели содержится эта ось. Одна ось может иметь множество сегментов, каждый сегмент содержит начальную и конечную точку. Похоже, что пока нет признака, определяющего, на каком уровне расположена ось, все оси находятся в одной плоскости.
levelOccluderIds: id всех перекрытий и потолков. К сожалению, не показывает, какие id к каким уровням относятся.
Levels: все доступные уровни. Показывает высоту уровней относительно базовой точки проекта, height здесь - расстояние до следующего уровня, name - имя уровня. Так же показывает, является ли этаж уровнем земли или нет.
Phases: Все непустые стадии проекта, т.е. стадии, которые присутствуют в элементах проекта Revit.
Viewports: все видовые экраны листов, включая данные камер, секущих плоскостей, guid-ов листов, на которых они размещены и т.д. Массив cameraOrientation содержит данные ориентации камеры array[0]-array[2] - направление камеры (forward direction vector), array[3]-array[5] - направление вверх (camera up vector), array[6]-array[8] - координаты позиции камеры. viewportPosition - массив, содержащий информацию о расположении видового экрана на листе. array[0]-array[2] - нижний левый угол видового экрана, array[3]-array[5] - его правый верхний угол.
Код ниже отрисовывает линию сетки, круг и текст с помощью Three.js:
- //первый этап: загружаем AEC-данные методом downloadAecModelData
- function onDocumentLoadSuccess(doc) {
- var viewables = viewerApp1.bubble.search({'type':'geometry'});
- if (viewables.length === 0) {
- console.error('Document contains no viewables.');
- return;
- }
- // загрузка данные AEC
- doc.downloadAecModelData()
- //....
- }
Extension для создания текста оси сетки:
- import { Font, TextGeometry} from './threejs-full-es6/builds/Three.es.js'
- import FontJson from './helvetiker_bold.typeface.json'
- export default class TextExtension
- extends Autodesk.Viewing.Extension {
- /////////////////////////////////////////////////////////
- // Adds a color material to the viewer
- //
- /////////////////////////////////////////////////////////
- constructor (viewer, options) {
- super()
- this.viewer = viewer
- }
- load () {
- return true
- }
- unload () {
- return true
- }
- /////////////////////////////////////////////////////////
- // Adds a color material to the viewer
- //
- /////////////////////////////////////////////////////////
- createColorMaterial (color) {
- const material = new THREE.MeshPhongMaterial({
- specular: new THREE.Color(color),
- side: THREE.DoubleSide,
- reflectivity: 0.0,
- color
- })
- const materials = this.viewer.impl.getMaterials()
- materials.addMaterial(
- color.toString(),
- material,
- true)
- return material
- }
- /////////////////////////////////////////////////////////
- // Wraps TextGeometry object and adds a new mesh to
- // the scene
- /////////////////////////////////////////////////////////
- createText (params) {
- params.font = new Font(FontJson)
- const geometry = new TextGeometry(params.text,params)
- const material = this.createColorMaterial(
- params.color)
- const text = new THREE.Mesh(
- geometry , material)
- text.position.set(
- params.position.x,
- params.position.y,
- params.position.z)
- this.viewer.impl.scene.add(text)
- this.viewer.impl.sceneUpdated(true)
- }
- }
- Autodesk.Viewing.theExtensionManager.registerExtension(
- ' ', TextExtension)
Отрисовываем оси сетки:
- import './Viewing.Extension.Text'
- // ...
- viewer.loadExtension('Viewing.Extension.Text').then((extension) => {
- drawGrid()
- })
- function drawGrid(){
- //get AEC data from the document
- const aecdata = viewer.model.getDocumentNode().getAecModelData()
- //get grids data
- const grids = aecdata.grids
- const linesMaterial = new THREE.LineBasicMaterial({
- color: 0xff0000,
- linewidth: 2
- })
- const circleMaterial = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
- //draw each grid one by one
- grids.forEach(grid => {
- //label
- const lable = grid.label
- const segments = grid.segments
- //draw each segment one by one
- segments.forEach(seg=>{
- //start point
- const start = seg.points.start
- //end point
- const end = seg.points.end
- //grid line
- const lineGeo = new THREE.Geometry ()
- lineGeo.vertices.push (new THREE.Vector3 ( start[0], start[1], start[2]))
- lineGeo.vertices.push (new THREE.Vector3 ( end[0], end[1], end[2]))
- const line = new THREE.Line (lineGeo,linesMaterial)
- NOP_VIEWER.impl.scene.add(line)
- //grid circle
- var circleGeo = new THREE.CircleGeometry( 3, 32 );
- var circle = new THREE.Mesh( circleGeo, circleMaterial );
- viewer.impl.scene.add(circle)
- //transform the circle to the position of max point of bounding box of this grid.
- circle.position.set(grid.boundingBox[3]-1,grid.boundingBox[4],0 );
- //get extension of drawing text
- let textExt= NOP_VIEWER.getExtension('Viewing.Extension.Text')
- //draw text
- textExt.createText({
- //intensionally to adjust the position of the text
- //will need to improve to make it more elegant
- position: {x: grid.boundingBox[3]-1, y: grid.boundingBox[4], z: 0},
- bevelEnabled: true,
- curveSegments: 24,
- bevelThickness: 0.1,
- color: 0x00ffff,
- text: grid.label,
- bevelSize: 0.1,
- height: 0.01,
- size: 2
- })
- })
- })
- viewer.impl.sceneUpdated(true)
- }
Результат выполнения метода показан на картинке в начале статьи
Источник: https://forge.autodesk.com/blog/consume-aec-data-which-are-model-derivative-api
Обсуждение: http://adn-cis.org/forum/index.php?topic=
Опубликовано 27.06.2019