IOS UIWebView中Autodesk Forge Viewer无法获取2D元素包围盒
Let's break down why your code works smoothly in desktop browsers but returns infinite bounding boxes in iOS UIWebView, plus actionable fixes to resolve the issue.
First, here's your code for reference:
function find2DBounds(fragList, fragId, dbId, bc) { const mesh = fragList.getVizmesh(fragId); const vbr = new Autodesk.Viewing.Private.VertexBufferReader(mesh.geometry); vbr.enumGeomsForObject(dbId, bc); } function get2DBounds(dbId, model) { const it = model.getData().instanceTree; const fragList = model.getFragmentList(); let bounds = new THREE.Box3(); let bc = new Autodesk.Viewing.Private.BoundsCallback(bounds); const dbId2fragId = model.getData().fragments.dbId2fragId; const fragIds = dbId2fragId[dbId]; if (Array.isArray(fragIds)) { for (let i = 0; i < fragIds.length; i++) { find2DBounds(fragList, fragIds[i], dbId, bc); } } else if (typeof fragIds === 'number') { find2DBounds(fragList, fragIds, dbId, bc); } return bc.bounds; } var model = this.viewer.model; var modelData = model.getData(); var itree = modelData.instanceTree; itree.enumNodeChildren( itree.getRootId(), function(dbId) { // Here you go const bondingBox = get2DBounds(dbId, viewer.model); } )
Why This Fails in UIWebView
Your code relies heavily on undocumented private Autodesk Viewer APIs (Autodesk.Viewing.Private.VertexBufferReader and Autodesk.Viewing.Private.BoundsCallback). These APIs aren't designed for cross-environment consistency, and UIWebView—being an older, more restricted web engine—handles them poorly.
Other contributing factors:
- UIWebView uses an outdated WebKit engine that processes vertex buffer data differently than modern desktop browsers.
- Your code may execute before the model's fragment data finishes loading in the mobile environment, leaving bounds uninitialized (which default to infinite values).
Fixes to Resolve the Issue
1. Switch to Public Viewer APIs (Most Reliable)
Autodesk provides an official, supported method to retrieve node bounding boxes that works across all platforms. Replace your entire get2DBounds function with this simplified version:
function get2DBounds(dbId, model) { const boundingBox = new THREE.Box3(); model.getData().instanceTree.getNodeBox(dbId, boundingBox); return boundingBox; }
This avoids private APIs entirely and leverages the viewer's built-in logic for accurate bounds retrieval.
2. Wait for the Model to Fully Load
Mobile web views often load model geometry slower than desktop browsers. Ensure your bounding box logic runs only after the viewer has finished loading all geometry:
// Trigger logic only after all geometry is loaded viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function() { const model = viewer.model; const itree = model.getData().instanceTree; itree.enumNodeChildren(itree.getRootId(), function(dbId) { const boundingBox = get2DBounds(dbId, model); // Process your bounding box here }); });
3. Migrate from UIWebView to WKWebView
UIWebView has been deprecated by Apple since iOS 12 and suffers from numerous performance and compatibility issues. WKWebView uses a modern WebKit engine that aligns much closer with desktop browser behavior. Updating your iOS app to use WKWebView will likely fix this problem (and many others) automatically.
4. Debug If You Must Stick with UIWebView
If migration isn't an option right now, add debug logs to pinpoint where the process breaks. Use Safari's Web Inspector to view these logs on your iOS device:
function find2DBounds(fragList, fragId, dbId, bc) { const mesh = fragList.getVizmesh(fragId); console.log(`Mesh geometry for frag ${fragId}:`, !!mesh.geometry); const vbr = new Autodesk.Viewing.Private.VertexBufferReader(mesh.geometry); console.log(`VertexBufferReader created:`, !!vbr); vbr.enumGeomsForObject(dbId, bc); console.log(`Bounds after processing frag ${fragId}:`, bc.bounds.toString()); }
Look for missing geometry or uninitialized readers—these will highlight the exact failure point.
内容的提问来源于stack exchange,提问作者Amit Mandal

