xzz2021
发布于 2024-05-16 / 3 阅读
0
0

vue引入autodesk进行3d模型渲染

html文件引入css及js文件
<!-- head标签内引入css -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/style.min.css" type="text/css">
<!-- body标签内部引入js -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.min.js"></script>
所需要用到的方法,放同一文件方便调用

import axios from 'axios';

//  autodesk官网获取密匙   点头像 application 创建一个应用就会自动生成
const clientId = 'your clientid';
const clientSecret = 'your secret';

//  获取权限
export const getAccessToken = async () =>{
    const params = new URLSearchParams();
    params.append('client_id', clientId);
    params.append('client_secret', clientSecret);
    params.append('grant_type', 'client_credentials');
    params.append('scope', 'data:read data:write data:create bucket:create bucket:read');
  const response = await axios.post('https://developer.api.autodesk.com/authentication/v1/authenticate', params, {
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        });
        return response.data.access_token;
}

//  上传本地文件
export const  uploadFile = async  (bucketKey, file, accessToken)  => {
    const response = await axios.put(`https://developer.api.autodesk.com/oss/v2/buckets/${bucketKey}/objects/${file.name}`, file, {
      headers: {
        'Content-Type': 'application/octet-stream',
        'Authorization': `Bearer ${accessToken}`,
      },
    });
    return response.data;
  }

  //  创建存储库  理论上有创建 可以直接使用已有的库名
  export const createBucket = async ( accessToken) => {
    const response = await axios.post('https://developer.api.autodesk.com/oss/v2/buckets', {
      bucketKey: "xzz2022",
      policyKey: 'transient' // 或 'temporary' 或 'persistent',取决于你的需求
    }, {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json',
      },
    });
    return response.data;
  }

//  检查文件是否已转换成svf 
  export const checkTranslationStatus = async (urn, accessToken) => {
    const response = await axios.get(`https://developer.api.autodesk.com/modelderivative/v2/designdata/${urn}/manifest`, {
      headers: {
          'Authorization': `Bearer ${accessToken}`,
        },
    });
    return response.data.status === 'success';
  }
  //  所有上传文件到服务器之后  都需要主动请求一次进行文件转换 svf 从而autodesk才能渲染
 export  const  translateFile = async (urn, accessToken) => {
    const response = await fetch('https://developer.api.autodesk.com/modelderivative/v2/designdata/job', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`
      },
      body: JSON.stringify({
        input: {
          urn: urn
        },
        output: {
          formats: [{
            type: 'svf',
            views: ['2d', '3d']
          }]
        }
      })
    });
    const data = await response.json();
    return data;
  }
  export const encodeURN = (objectId) => {
  return btoa(objectId).replace(/=/g, ''); // Base64编码并去掉结尾的'='
}
生成vue组件
<template>
    <div id="forgeViewer" style="width: 60%; height: 50%;"></div>
  </template>
<script setup>
import { getAccessToken, createBucket, uploadFile, translateFile,  checkTranslationStatus, encodeURN } from './fnFile.js'
let accessToken, modelUrn;
// const modelUrn = ref('your_model_urn'); // 编码后的URN

const init = async (file) => {
     accessToken = await getAccessToken();
     const res = await uploadFile("xzz2022",file,  accessToken)
      console.log("🚀 ~ file: ForgeViewer.vue:29 ~ init ~ res:", res)
      // 获取并编码URN
  const urn = encodeURN(res.objectId);
  console.log("🚀 ~ file: ForgeViewer.vue:31 ~ init ~ urn:", urn)
  const rrr = await translateFile(urn, accessToken)  //  文件云端转换之后返回同一个urn
     console.log("🚀 ~ file: ForgeViewer.vue:34 ~ init ~ newUrn:", rrr)
     modelUrn = rrr.urn
     initializeViewer()
}
      const initializeViewer = async () =>{
        const options = {
          env: 'AutodeskProduction',
          accessToken: accessToken,
        };
  
        Autodesk.Viewing.Initializer(options, () => {
          const viewerDiv = document.getElementById('forgeViewer');
          const viewer = new Autodesk.Viewing.GuiViewer3D(viewerDiv);
          viewer.start();
          const documentId = `urn:${modelUrn}`;
        Autodesk.Viewing.Document.load(documentId, (doc) => {
            const viewables = doc.getRoot().getDefaultGeometry();
            viewer.loadDocumentNode(doc, viewables).then(i => {
              console.log("🚀 ~ file: ForgeViewer.vue:60 ~ viewer.loadDocumentNode ~ i:", i)
              console.log('Document loaded successfully');
            }).catch(error => {
              console.error('Failed to load document:', error);
            });
          }, (errorMsg) => {
            console.error('Failed to load document:', errorMsg);
          });
        });
      }

      defineExpose({init})
  </script>
  
  <style scoped>
  #forgeViewer {
    width: 100%;
    height: 100vh;
  }
  </style>
需要渲染的地方直接挂载组件, 调用组件ref.init(file),传入原始文件即可

待完善,后续补充...


评论