摘要:可能有許多原因你想在里加入自訂義的線型,例如顯示線框幾何視覺化包圍箱或者其他你想帶給使用者的視覺回饋。下面是我傳寫的一個例子,他可以在選重構件后在場景里用自定義線型描繪它的包圍箱,在線示例可以參考這里
這篇文章的原著是 Autodesk AND 的 Philippe Leefsma,以下以我簡稱。
可能有許多原因你想在 Viewer 里加入自訂義的線型,例如顯示線框(Wireframe)幾何、視覺化包圍箱(Bounding Box)或者其他你想帶給使用者的視覺回饋。基本上這有三種方式來做到這件事,讓我們來看看到底要怎么做,首先我們要先產生一個線型幾何,其代碼入下所示:
const geometry = new THREE.Geometry () geometry.vertices.push (new THREE.Vector3 ( 0, 0, 0)) geometry.vertices.push (new THREE.Vector3 (10, 10, 10)) var linesMaterial = new THREE.LineBasicMaterial ({ color: new THREE.Color (0xFF0000), transparent: true, depthWrite: false, depthTest: true, linewidth: 10, opacity: 1.0 }) var lines = new THREE.Line (geometry, linesMaterial, THREE.LinePieces)
下一步我們來看看要怎么將這個線型加入到 Viewer 的場景里(scene):
一、將線型加到 viewer.impl.scene:
//1 - 第一種方法 viewer.impl.scene.add (lines) viewer.impl.invalidate (true)
但這個方法并不是一個靠譜的方法,因為他只能在 FireFox 里正常運作,在我的 Chrome 上是沒有作用的。。。所以讓我們看看下一個方法。
二、將線型加到 viewer.impl.scene:
//2 - 第二種方法 viewer.impl.sceneAfter.add (lines) viewer.impl.invalidate (true)
這個方法比前一個好多了,他可以在多個瀏覽器上正常執行,但當你透過修改了構件的可視性后(執行了孤立顯示或隱藏等動作),所有的線型都會跟著構件一起消失,我想這是應該是 Viewer 內部的著色器(Shader)和渲染(Rendering)設置造成的。
三、產生 Viewer Overlay 場景,并將線型加入 Overlay 場景:
//3 - 第三種方法 viewer.impl.createOverlayScene ( "myOverlay", linesMaterial) viewer.impl.addOverlay ( "myOverlay", lines) viewer.impl.invalidate (true)
經測試這個方法非常的靠譜,他可以在多個瀏覽器上正確執行,并且不受構件可視性的影響。但你不一定要使用第三個方法,你可以根據你的需求選擇適合你應用場景的方法。
下面是我傳寫的一個例子 Viewing.Extension.BoundingBox,他可以在選重構件后在 Viewer 場景里用自定義線型描繪它的包圍箱,在線示例可以參考這里:
///////////////////////////////////////////////////////////////// // BoundingBox Viewer Extension // By Philippe Leefsma, Autodesk Inc, August 2017 // ///////////////////////////////////////////////////////////////// import MultiModelExtensionBase from "Viewer.MultiModelExtensionBase" import Toolkit from "Viewer.Toolkit" class BoundingBoxExtension extends MultiModelExtensionBase { ///////////////////////////////////////////////////////// // Class constructor // ///////////////////////////////////////////////////////// constructor (viewer, options) { super (viewer, options) this.onContextMenu = this.onContextMenu.bind(this) this.linesMaterial = this.createMaterial(0x0000FF) this.lineGroups = [] } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// createMaterial (color = 0x000000, opacity = 1.0) { return new THREE.LineBasicMaterial({ color: new THREE.Color(color), transparent: true, depthWrite: false, depthTest: true, linewidth: 10, opacity }) } ///////////////////////////////////////////////////////// // Load callback // ///////////////////////////////////////////////////////// load () { this.viewer.loadDynamicExtension( "Viewing.Extension.ContextMenu").then( (ctxMenuExtension) => { ctxMenuExtension.addHandler( this.onContextMenu) }) console.log("Viewing.Extension.BoundingBox loaded") return true } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// get className() { return "bounding-box" } ///////////////////////////////////////////////////////// // Extension Id // ///////////////////////////////////////////////////////// static get ExtensionId () { return "Viewing.Extension.BoundingBox" } ///////////////////////////////////////////////////////// // Unload callback // ///////////////////////////////////////////////////////// unload () { console.log("Viewing.Extension.BoundingBox unloaded") super.unload () return true } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// onModelRootLoaded () { this.options.loader.show (false) this.viewer.impl.createOverlayScene ( "boundingBox", this.linesMaterial) } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// async onSelection (event) { if (event.selections.length) { const selection = event.selections[0] const model = this.viewer.activeModel || this.viewer.model this.selectedDbId = selection.dbIdArray[0] const bbox = await Toolkit.getWorldBoundingBox( model, this.selectedDbId) this.drawBox(bbox) } } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// drawBox (bbox) { const geometry = new THREE.Geometry() const { min, max } = bbox geometry.vertices.push(new THREE.Vector3(min.x, min.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, min.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, min.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, min.y, max.z)) geometry.vertices.push(new THREE.Vector3(max.x, min.y, max.z)) geometry.vertices.push(new THREE.Vector3(min.x, min.y, max.z)) geometry.vertices.push(new THREE.Vector3(min.x, min.y, max.z)) geometry.vertices.push(new THREE.Vector3(min.x, min.y, min.z)) geometry.vertices.push(new THREE.Vector3(min.x, max.y, max.z)) geometry.vertices.push(new THREE.Vector3(max.x, max.y, max.z)) geometry.vertices.push(new THREE.Vector3(max.x, max.y, max.z)) geometry.vertices.push(new THREE.Vector3(max.x, max.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, max.y, min.z)) geometry.vertices.push(new THREE.Vector3(min.x, max.y, min.z)) geometry.vertices.push(new THREE.Vector3(min.x, max.y, min.z)) geometry.vertices.push(new THREE.Vector3(min.x, max.y, max.z)) geometry.vertices.push(new THREE.Vector3(min.x, min.y, min.z)) geometry.vertices.push(new THREE.Vector3(min.x, max.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, min.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, max.y, min.z)) geometry.vertices.push(new THREE.Vector3(max.x, min.y, max.z)) geometry.vertices.push(new THREE.Vector3(max.x, max.y, max.z)) geometry.vertices.push(new THREE.Vector3(min.x, min.y, max.z)) geometry.vertices.push(new THREE.Vector3(min.x, max.y, max.z)) const lines = new THREE.Line(geometry, this.linesMaterial, THREE.LinePieces) this.lineGroups.push(lines) this.viewer.impl.addOverlay("boundingBox", lines) this.viewer.impl.invalidate( true, true, true) } ///////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////// onContextMenu (event) { const model = this.viewer.activeModel || this.viewer.model event.menu.forEach((entry) => { const title = entry.title.toLowerCase() switch (title) { case "isolate": entry.target = () => { Toolkit.isolateFull( this.viewer, this.selectedDbId, model) } break case "hide selected": entry.target = () => { Toolkit.hide( this.viewer, this.selectedDbId, model) } break case "show all objects": entry.target = () => { Toolkit.isolateFull( this.viewer, [], model) this.viewer.fitToView() } break default: break } }) const instanceTree = model.getData().instanceTree const dbId = event.dbId || (instanceTree ? instanceTree.getRootId() : -1) if (dbId > -1) { event.menu.push({ title: "Clear All BoundingBoxes", target: () => { this.lineGroups.forEach((lines) => { this.viewer.impl.removeOverlay("boundingBox", lines) }) this.viewer.impl.invalidate( true, true, true) this.lineGroups = [] } }) } } } Autodesk.Viewing.theExtensionManager.registerExtension ( BoundingBoxExtension.ExtensionId, BoundingBoxExtension) export default "Viewing.Extension.BoundingBox"
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91850.html
摘要:最近有的小伙伴們都在詢問要怎么在里顯示自訂義屬性,要做到這個是挺容易的。在來我們透過繼承來創建自個的屬性面板使用的語法,部份代碼來自的無法從服務器獲取屬性透過撰寫括展讓自定義屬性窗取代自帶的以上希望對各為小伙伴有幫助參考 最近有 Autodesk Forge 的小伙伴們都在詢問要怎么在 Viewer 里顯示自訂義屬性,要做到這個是挺容易的。目前有兩種方式可以做到這個效果,一種是直接添加...
摘要:在官方釋出版的同時發布了新版本的,這個面版已被整個重新改寫,這次更新也加入一些新的交互行為,下面我們將會稍作解釋。 這禮拜的小技巧是關于如何以不加入太多的 JavaScript 的方式自訂義 ModelStructurePanel 的交互行為,這個小技巧受到這篇問與答的啟發:Prevent zoom in Forge viewer when clicking in Model Brow...
摘要:前陣子有些圈的朋友們都在詢問同一個問題要怎么在的自帶右鍵菜單上添加自定義項目或是只顯示自訂義項目以下將針對在自帶右鍵菜單上添加自定義項目和只顯示自訂義項目的右鍵菜單進行說明。 前陣子有些 Autodesk Forge 圈的朋友們都在詢問同一個問題『要怎么在 Viewer 的自帶右鍵菜單上添加自定義項目或是只顯示自訂義項目』~ 以下將針對『在自帶右鍵菜單上添加自定義項目』和『只顯示自訂義...
摘要:對于大多數的模型文檔都可以透過服務提取轉換在里渲染構件外觀時所需的材質及貼圖。所以我們可以透過它遍歷所有材質,找出我們想隱藏貼圖的那些材質,將它的顏色設置為灰色,同時也可以透過它將隱藏貼圖的材質回復。 這篇文章來自 Autodesk ADN 的梁曉冬,以下以我簡稱。 對于大多數的模型文檔都可以透過 Autodesk Forge Model Derivative 服務提取、轉換在 Vie...
摘要:但很不幸的,新功能要加入里頭這件事對于開發團隊而言絕非一件易事,是需要一些時間來完成的這篇文章將帶領大家用最少的工作量將上的新功能拿來上使用。在這個案例里頭,我們可以只將和其他相依文檔引入例如。 showImg(https://segmentfault.com/img/bV25af?w=1311&h=696); 對于 Forge Viewer 比較熟悉的朋友可能知道 Forge Vie...
閱讀 1611·2023-04-25 16:29
閱讀 949·2021-11-15 11:38
閱讀 2285·2021-09-23 11:45
閱讀 1410·2021-09-22 16:03
閱讀 2532·2019-08-30 15:54
閱讀 1198·2019-08-30 10:53
閱讀 2599·2019-08-29 15:24
閱讀 1095·2019-08-26 12:25