ADSK Forge Viewer 将我的 3D DWG 显示为仅 2D

Posted

技术标签:

【中文标题】ADSK Forge Viewer 将我的 3D DWG 显示为仅 2D【英文标题】:ADSK Forge Viewer displays my 3D DWG as only 2D 【发布时间】:2020-07-22 15:28:32 【问题描述】:

我正在创建一个 Web 应用程序并使用 Forge 查看器来显示我的模型,但是当我上传 3D DWG 模型并将其转换为 svf 以供查看时,我只能看到 2D。它是 3D DWG 模型,但查看器仅将其显示为 2D 模型。 viewer.html 代码中是否缺少我的东西?我似乎找不到错误在哪里。

viewer.html(来自 github 上的示例项目)

<!DOCTYPE html>
<html>

<head>
  <title>Autodesk Forge: 3D Viewer App Sample</title>

  <meta http-equiv="cache-control" content="max-age=0" />
  <meta http-equiv="cache-control" content="no-cache" />
  <meta http-equiv="expires" content="0" />
  <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
  <meta http-equiv="pragma" content="no-cache" />
  <!-- Third Party package -->
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <!-- Autodesk Forge Viewer files (IMPORTANT) -->
  <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css"
    type="text/css" />
  <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
  <style>
    /** Just simple CSS styling to make this page a little nicer **/
    body 
      margin: 0;
      padding: 0;
    
  </style>
</head>

<body>
  <!-- The Viewer will be instantiated here -->
  <div id="MyViewerDiv"></div>
  <!-- Custom script -->
  <script>
    var viewer;
    var options = 
      env: "AutodeskProduction",
      api: "derivativeV2", // TODO: for models uploaded to EMEA change this option to 'derivativeV2_EU'
      getAccessToken: getForgeToken
    ;
    var documentId = "urn:" + getUrlParameter("urn");
    console.log(documentId);

    // Run this when the page is loaded
    Autodesk.Viewing.Initializer(options, function onInitialized() 
      // Find the element where the 3d viewer will live.
      var htmlElement = document.getElementById("MyViewerDiv");
      if (htmlElement) 
        // Create and start the viewer in that element
        viewer = new Autodesk.Viewing.GuiViewer3D(htmlElement);
        viewer.start();
        // Load the document into the viewer.
        Autodesk.Viewing.Document.load(
          documentId,
          onDocumentLoadSuccess,
          onDocumentLoadFailure
        );
      
    );

    /**
     * Autodesk.Viewing.Document.load() success callback.
     * Proceeds with model initialization.
     */
    function onDocumentLoadSuccess(doc) 
      // Load the default viewable geometry into the viewer.
      // Using the doc, we have access to the root BubbleNode,
      // which references the root node of a graph that wraps each object from the Manifest JSON.
      var viewable = doc.getRoot().getDefaultGeometry();
      if (viewable) 
        viewer
          .loadDocumentNode(doc, viewable)
          .then(function (result) 
            console.log("Viewable Loaded!");
          )
          .catch(function (err) 
            console.log("Viewable failed to load.");
            console.log(err);
          );
      
    

    /**
     * Autodesk.Viewing.Document.load() failure callback.
     */
    function onDocumentLoadFailure(viewerErrorCode) 
      console.error(
        "onDocumentLoadFailure() - errorCode: " + viewerErrorCode
      );
      jQuery("#MyViewerDiv").html(
        "<p>Translation in progress... Please try refreshing the page.</p>"
      );
    

    // Get Query string from URL,
    // we will use this to get the value of 'urn' from URL
    function getUrlParameter(name) 
      console.log("Made it here 2");
      console.log(name);
      name = name.replace(/[[]/, "\\[").replace(/[\]]/, "\\]");
      var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
      var results = regex.exec(location.search);
      return results === null
        ? ""
        : decodeURIComponent(results[1].replace(/\+/g, " "));
    

    // Get public access token for read only,
    // using ajax to access route /api/forge/oauth/public in the background
    function getForgeToken(callback) 
      console.log("Made it here");
      jQuery.ajax(
        url: "/api/forge/oauth2/public",
        success: function (res) 
          callback(res.access_token, res.expires_in);
        
      );
    
  </script>
</body>

</html>

要翻译并发送到查看器的节点 JS 代码

const express = require("express");
const Axios = require("axios");
const bodyParser = require("body-parser");
const cors = require("cors");
let config = require("./config");
let mainFunc = require("./BP-s3oss");

//Express Server
let app = express();
// let router = express.Router();

app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(express.static(__dirname + "/www"));


app.get("/api/s3Data/:bucket", async (req, res) => 
  let bucket = req.params.bucket;
  let object = decodeURIComponent(req.query.object);


  //Log to console
  console.log(config.forge.forge_bucket + " " + object);

  //Comment KWard: Add in Error check if unsuccessful

  try 
    //Main Function
    let main = await mainFunc(bucket, object);

    //Initialize Process
    res.redirect("/api/forge/s3toOSS/" + config.forge.forge_bucket + "/" + encodeURIComponent(object));

   catch (error) 
    res.status(500).send('Something bad Happened!');
  

);

//Start Express Server on Port 3000
app.set("port", 3000);
var server = app.listen(app.get("port"), function () 
  console.log("Server listening on port " + server.address().port);
);

//-------------------------------------------------------------------
// Configuration for your Forge account
// Initialize the 2-legged OAuth2 client, and
// set specific scopes
//-------------------------------------------------------------------
var FORGE_CLIENT_ID = config.forgecredentials.client_id;
var FORGE_CLIENT_SECRET = config.forgecredentials.client_secret;
var access_token = "";
var scopes = "data:read data:write data:create bucket:create bucket:read";
const querystring = require("querystring");

//Route /AWStoFORGE/OSS
app.get("/api/forge/s3toOSS/:bucket/:object", async (req, res) => 
  let bucket = req.params.bucket;
  let object = req.params.object;

  console.log(bucket + " " + object);

  res.redirect("/api/forge/oauth" + "/" + encodeURIComponent(object));
);

// Route /api/forge/oauth
app.get("/api/forge/oauth/:object", function (req, res) 
  let objectKey = req.params.object;
  Axios(
    method: "POST",
    url: "https://developer.api.autodesk.com/authentication/v1/authenticate",
    headers: 
      "content-type": "application/x-www-form-urlencoded"
    ,
    data: querystring.stringify(
      client_id: FORGE_CLIENT_ID,
      client_secret: FORGE_CLIENT_SECRET,
      grant_type: "client_credentials",
      scope: scopes
    )
  )
    .then(function (response) 
      // Success
      access_token = response.data.access_token;
      console.log("Successful Authentication");
      res.redirect(
        "/api/forge/datamanagement/bucket/getobject" + "/" + encodeURIComponent(objectKey)
      );
    )
    .catch(function (error) 
      // Failed
      console.log(error);
      res.send("Failed to authenticate");
    );
);

// Route /api/forge/oauth2/public
app.get("/api/forge/oauth2/public", function (req, res) 
  // Limit public token to Viewer read only
  Axios(
    method: "POST",
    url: "https://developer.api.autodesk.com/authentication/v1/authenticate",
    headers: 
      "content-type": "application/x-www-form-urlencoded"
    ,
    data: querystring.stringify(
      client_id: FORGE_CLIENT_ID,
      client_secret: FORGE_CLIENT_SECRET,
      grant_type: "client_credentials",
      scope: "viewables:read"
    )
  )
    .then(function (response) 
      // Successs
      res.json(
        access_token: response.data.access_token,
        expires_in: response.data.expires_in
      );
    )
    .catch(function (error) 
      // Failed
      console.log(error);
      res.status(500).json(error);
    );
);

const bucketKey = config.forge.forge_bucket;

const policyKey = "persistent"; // Never Expires

// For converting the source into a Base64-Encoded string
var Buffer = require("buffer").Buffer;
String.prototype.toBase64 = function () 
  // Buffer is part of Node.js to enable interaction with octet streams in TCP streams,
  // file system operations, and other contexts.
  return new Buffer(this).toString("base64");
;

app.get("/api/forge/datamanagement/bucket/getobject/:objectKey", function (
  req,
  res
) 
  let objectVal = req.params.objectKey;
  console.log(bucketKey);
  console.log(objectVal);
  Axios(
    method: "GET",
    url:
      "https://developer.api.autodesk.com/oss/v2/buckets/" +
      encodeURIComponent(bucketKey) +
      "/objects/" +
      encodeURIComponent(objectVal) +
      "/details",
    maxContentLength: 104857780,
    headers: 
      Authorization: "Bearer " + access_token,
      "content-type": "application/json"
    
  )
    .then(function (response) 
      //Success
      console.log("Object Retrieved from Forge OSS");
      var urn = response.data.objectId.toBase64();
      res.redirect("/api/forge/modelderivative/" + encodeURIComponent(urn));
    )
    .catch(function (error) 
      //Failed
      console.log(error);
      res.send("Failed to get objectId from OSS.");
    );
);

// Route /api/forge/modelderivative
app.get("/api/forge/modelderivative/:urn", function (req, res) 
  var decodeURN = decodeURIComponent(req.params.urn)
  var urn = decodeURN;
  var format_type = "svf";
  var format_views = ["2d", "3d"];
  // console.log(urn);
  Axios(
    method: "POST",
    url: "https://developer.api.autodesk.com/modelderivative/v2/designdata/job",
    headers: 
      "content-type": "application/json",
      Authorization: "Bearer " + access_token
    ,
    data: JSON.stringify(
      input: 
        urn: urn
      ,
      output: 
        formats: [
          
            type: format_type,
            views: format_views
          
        ]
      
    )
  )
    .then(function (response) 
      // Success
      console.log("Redirected to Viewer HTML");
      res.redirect("/viewer.html?urn=" + urn);
      // res.send(urn);
    )
    .catch(function (error) 
      // Failed
      console.log(error);
      res.send("Error at Model Derivative job.");
    );
);

【问题讨论】:

【参考方案1】:

检查模型的默认视图是否是您在加载默认视图时看到的 2D 视图:

 var viewable = doc.getRoot().getDefaultGeometry();

您可以通过DocumentBrowser 扩展加载特定视图:

const viewer = new Autodesk.Viewing.GuiViewer3D(document.body.children[0],extensions:['Autodesk.DocumentBrowser'])
Autodesk.Viewing.Document.load('urn:urn', doc=> 
viewer.start()
viewer.loadDocumentNode(doc,doc.getRoot().getDefaultGeometry())
//…

或指定查询以在文档中查找可查看的(例如 3D 的)并加载它:

Autodesk.Viewing.Document.load('urn:urn', doc=> 

const viewable = doc.getRoot().search('role':'3d')[0] //name of viewable for instance
viewer.start()
viewer.loadDocumentNode(doc,viewable)
//...

【讨论】:

这两个选项都成功了,谢谢!!我决定使用扩展选项,因为它使您能够在保存的视图之间切换。【参考方案2】:

在此添加更多信息...

如果要在文档浏览器扩展中检索视图列表,这里有两种方法...

使用DOC 对象

let myViews = viewer.model.getDocumentNode().search('role':'3d', type:'view');
// returns, 5 views in an array

// change the camera view to view #2
viewer.setView(myViews[1]); 

// print out the name of the view
console.log( myViews[1].name() );  

> "3D_RF_AC1"

使用Extension

let ext = viewer.getExtension("Autodesk.DocumentBrowser");

let myViews = ext.geometries[0].children.filter( i => 
  return(i.data.camera)
)

// change the camera view to view #2
viewer.setView( myViews[1] ); 

// print out the name of the view
console.log( myViews[1].name() );  

> "3D_RF_AC1"

【讨论】:

以上是关于ADSK Forge Viewer 将我的 3D DWG 显示为仅 2D的主要内容,如果未能解决你的问题,请参考以下文章

Forge Viewer 中的个人工具栏按钮未出现

来自外部数据库的 Autodesk Forge Viewer 放置点

如何在 Autodesk Forge Viewer 中嵌入 pdf?

Autodesk Forge Viewer 7.24.0 未加载模型

将更改保存到Forge Autodesk Viewer

Forge Viewer:如何将任意客户点转换为世界点