摘要:有提供類似的功能,但這并不包含在里頭。條列清單或是切換視圖是非常容易的,你主要是要建立一個(gè)使用者介面讓使用者去選取他們想觀看的內(nèi)容。我使用了來確保當(dāng)前載入模型占用的內(nèi)存可以都被釋出。
此篇文章原作是 Autodesk ADN Philippe Leefsma,以下以我簡稱。
這有一個(gè)簡易的博客用來說明一個(gè)我剛加入 https://forge-rcdb.autodesk.io 的一個(gè)新功能,他主要是提供一個(gè)使用介面讓使用者可以在一個(gè)文檔(Forge Document)里不同的視圖(Forge Viewable)間快速的切換。A360 viewer有提供類似的功能,但這并不包含在 Forge Viewer 里頭。
在 Forge Document 里。條列 Viewable 清單或是切換視圖是非常容易的,你主要是要建立一個(gè)使用者介面讓使用者去選取他們想觀看的內(nèi)容。如果您不知道要怎么讓 Forge Model Derivative 服務(wù)幫您轉(zhuǎn)換多個(gè)視圖,請(qǐng)先看看這篇文章:為什么Revit模型有多個(gè)視圖,丟到 Forge 轉(zhuǎn)換后確只剩一個(gè)? (如何設(shè)定多個(gè)視圖)
接著讓我們來看看該怎么實(shí)作這個(gè)功能(我所有的代碼都有用到 ES6、async/await,UI的部份使用了 React):
一、從已轉(zhuǎn)換好的 URN 載入 Document:
///////////////////////////////////////////////////////// // Load a document from URN // ///////////////////////////////////////////////////////// static loadDocument (urn) { return new Promise((resolve, reject) => { const paramUrn = !urn.startsWith("urn:") ? "urn:" + urn : urn Autodesk.Viewing.Document.load(paramUrn, (doc) => { resolve (doc) }, (error) => { reject (error) }) }) }
二、從已載入的 Document 物件獲取所有 Viewable 清單:
///////////////////////////////////////////////////////// // Return viewables // ///////////////////////////////////////////////////////// static getViewableItems (doc, roles = ["3d", "2d"]) { const rootItem = doc.getRootItem() let items = [] const roleArray = roles ? (Array.isArray(roles) ? roles : [roles]) : [] roleArray.forEach((role) => { items = [ ...items, ...Autodesk.Viewing.Document.getSubItemsWithProperties( rootItem, { type: "geometry", role }, true) ] }) return items }
三、載入已選中的 Viewable:
首先,我門要把已載入的模型先卸載,下面的樣例是假設(shè)我們已經(jīng)載入了一個(gè)模型,現(xiàn)在使用者選擇了新的 Viewable
要 Forge Viewer 載入。我使用了 viewer.tearDown() 來確保當(dāng)前載入模型占用的內(nèi)存可以都被釋出。這個(gè)樣例也支持從 3D 模型切換到 2D 模型,或者是反過來;您可以忽略我代碼里使用到的 React 相關(guān)的代碼。
///////////////////////////////////////////////////////// // Load the selected viewable // ///////////////////////////////////////////////////////// onItemSelected (item) { const {activeItem} = this.react.getState() if (item.guid !== activeItem.guid) { this.viewer.tearDown() this.viewer.start() const path = this.viewerDocument.getViewablePath(item) this.viewer.loadModel(path) this.react.setState({ activeItem: item }) } }
完整的代碼如下所示,對(duì)這功能有興趣的朋友們可以通過這個(gè)網(wǎng)址 https://forge-rcdb.autodesk.i...,并載入 Viewable Selector 來體驗(yàn)。
///////////////////////////////////////////////////////// // Viewing.Extension.ViewableSelector // by Philippe Leefsma, November 2017 // ///////////////////////////////////////////////////////// import MultiModelExtensionBase from "Viewer.MultiModelExtensionBase" import "./Viewing.Extension.ViewableSelector.scss" import WidgetContainer from "WidgetContainer" import ReactTooltip from "react-tooltip" import ServiceManager from "SvcManager" import Toolkit from "Viewer.Toolkit" import ReactDOM from "react-dom" import Image from "Image" import Label from "Label" import React from "react" class ViewableSelectorExtension extends MultiModelExtensionBase { ///////////////////////////////////////////////////////// // Class constructor // ///////////////////////////////////////////////////////// constructor (viewer, options) { super (viewer, options) this.react = options.react } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// get className() { return "viewable-selector" } ///////////////////////////////////////////////////////// // Extension Id // ///////////////////////////////////////////////////////// static get ExtensionId() { return "Viewing.Extension.ViewableSelector" } ///////////////////////////////////////////////////////// // Load callback // ///////////////////////////////////////////////////////// load () { this.react.setState({ activeItem: null, items: [] }).then (async() => { const urn = this.options.model.urn this.viewerDocument = await this.options.loadDocument(urn) const items = await Toolkit.getViewableItems( this.viewerDocument) if (items.length > 1) { this.createButton() await this.react.setState({ activeItem: items[0], items: [items[0], items[1], items[2]] }) if (this.options.showPanel) { this.showPanel (true) } } }) console.log("Viewing.Extension.ViewableSelector loaded") return true } ///////////////////////////////////////////////////////// // Unload callback // ///////////////////////////////////////////////////////// unload () { this.react.popViewerPanel(this) console.log("Viewing.Extension.ViewableSelector unloaded") return true } ///////////////////////////////////////////////////////// // Load the selected viewable // ///////////////////////////////////////////////////////// onItemSelected (item) { const {activeItem} = this.react.getState() if (item.guid !== activeItem.guid) { this.viewer.tearDown() this.viewer.start() const path = this.viewerDocument.getViewablePath(item) this.viewer.loadModel(path) this.react.setState({ activeItem: item }) } } ///////////////////////////////////////////////////////// // Create a button to display the panel // ///////////////////////////////////////////////////////// createButton () { this.button = document.createElement("button") this.button.title = "This model has multiple views ..." this.button.className = "viewable-selector btn" this.button.innerHTML = "Views" this.button.onclick = () => { this.showPanel(true) } const span = document.createElement("span") span.className = "fa fa-list-ul" this.button.appendChild(span) this.viewer.container.appendChild(this.button) } ///////////////////////////////////////////////////////// // Show/Hide panel // ///////////////////////////////////////////////////////// showPanel (show) { if (show) { const {items} = this.react.getState() this.button.classList.add("active") const container = this.viewer.container const height = Math.min( container.offsetHeight - 110, (items.length + 1) * 78 + 55) this.react.pushViewerPanel(this, { maxHeight: height, draggable: false, maxWidth: 500, minWidth: 310, width: 310, top: 30, height }) } else { this.react.popViewerPanel(this.id).then(() => { this.button.classList.remove("active") }) } } ///////////////////////////////////////////////////////// // Render React panel content // ///////////////////////////////////////////////////////// renderContent () { const {activeItem, items} = this.react.getState() const urn = this.options.model.urn const apiUrl = this.options.apiUrl const domItems = items.map((item) => { const active = (item.guid === activeItem.guid) ? " active" :"" const query = `size=400&guid=${item.guid}` const src = `${apiUrl}/thumbnails/${urn}?${query}` return (this.onItemSelected(item)}>) }) return ( {domItems}) } ///////////////////////////////////////////////////////// // Render title // ///////////////////////////////////////////////////////// renderTitle () { return () } ///////////////////////////////////////////////////////// // Render main // ///////////////////////////////////////////////////////// render (opts) { return (this.renderTitle(opts.docked)} showTitle={opts.showTitle} className={this.className}> {this.renderContent()} ) } } Autodesk.Viewing.theExtensionManager.registerExtension( ViewableSelectorExtension.ExtensionId, ViewableSelectorExtension)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/89898.html
摘要:但模型載入程序并不是同步執(zhí)行的載入文檔和幾何等動(dòng)作在里都是異步的,我們沒辦法知道哪一個(gè)模型是第一個(gè)被完整載入,和下個(gè)一個(gè)完全載入的是誰而在一些應(yīng)用場景里是有可能需要在一個(gè)序列聚合多個(gè)模型。 showImg(https://segmentfault.com/img/bVVaPI?w=600&h=390); 此篇博客原著為 Autodesk ADN 的梁曉冬,以下以我簡稱。 我的同事創(chuàng)作了...
摘要:最近,我收到一個(gè)客戶的需求,希望可以把的相機(jī)狀態(tài)通過還原到里。因?yàn)闆]有直接的方法可以修改相機(jī)的值。的相機(jī)視角比的相機(jī)視角寬。調(diào)用以取得焦距。因此,裁剪區(qū)域的范圍計(jì)算為寬度視圖的相機(jī)焦距。高度常規(guī)相機(jī)片幅的比例。 最近,我收到一個(gè)客戶的需求,希望可以把Viewer的相機(jī)狀態(tài)通過Revit API還原到Revit里。所以我們來看看要如何實(shí)現(xiàn)這個(gè)要求。在開始之前,你要先知道一些有關(guān)于Revi...
最近一些Forge客戶都在詢問我同一個(gè)的問題,他們希望將Revit的網(wǎng)格呈現(xiàn)在viewer中,藉此讓我有機(jī)會(huì)來完成這件事,并將它記錄在本文章里,就讓我們開始吧! 在開始之前,有件事你必須先知道: 由于在Revit里格子線只能在2D視圖(例如平面圖、立面圖、表單等等)中顯示,并不會(huì)在3D視圖中被看見。因此,我們也無法在ForgeViewer的3D視圖中看到這些格子線,網(wǎng)格會(huì)在模型轉(zhuǎn)文件時(shí)被忽略。據(jù)我...
摘要:默認(rèn)情況下,是英文環(huán)境,調(diào)取的是的資源其實(shí)無需翻譯。但是,如前面提到的,語言包只是包含了部分常規(guī)字串的翻譯,如果遇到?jīng)]有包含的常規(guī)字串怎么辦呢例如,本例中的語言包并沒有對(duì),進(jìn)行翻譯,所以即使切換了語言,它們?nèi)耘f是英文。 注:本文是個(gè)人調(diào)試分析所得,非官方文檔,請(qǐng)酌情選用參考。文中分析的數(shù)據(jù)由https://extract.autodesk.io轉(zhuǎn)換下載而來。 談到信息本地化,個(gè)人覺得包...
摘要:現(xiàn)在讓我們修改這個(gè)示例讓他可以展示兩個(gè)同項(xiàng)目但不同版號(hào)的模型及。示例執(zhí)行結(jié)果如下這邊是這個(gè)比較模型的括展代碼英文原文 showImg(https://segmentfault.com/img/bVOmjp?w=1542&h=925); 熟悉 BIM360 Team 的朋友可能知道他有一個(gè)很牛的模型文檔版本比較的功能,但如果模型是放在 Google 云盤或是百度云盤上有可能做到嗎? Au...
閱讀 2529·2021-09-24 10:29
閱讀 3810·2021-09-22 15:46
閱讀 2580·2021-09-04 16:41
閱讀 2986·2019-08-30 15:53
閱讀 1265·2019-08-30 14:24
閱讀 3058·2019-08-30 13:19
閱讀 2174·2019-08-29 14:17
閱讀 3526·2019-08-29 12:55