实际工程场景中,往往需要将多个零件组装到同一个场景中形成装配体,以表达一些非常复杂的设计。

主流的CAD软件,都支持装配体功能,分形三维同样也具备支持装配体文件的能力。

对于复杂格式的装配体,也需要先将原文件转换成e3dx文件。为了保障装配体显示完整,建议先对所有零件文件执行转换,再对装配体文件执行转换。

待拿到所有零件和装配体文件转换得到的url以后,再调用openfiles 将所有文件加入场景中进行显示。

其中关键代码如下,高亮部分即需要加 parts 的 URL 添加在装配体文件中进行显示。

// 上传文件并转换,转换成功后打开文件
// 推荐等待零件全部上传成功并转换成功后再上传装配体, 不然显示时可能会出现零件丢失的情况
const onUploadAssembly = async () => {
  // 这里使用了原生的 file input 获取文件,也可以使用其他方式获取文件
  // 这里只使用第一个文件
  const file = document.getElementById("assembly-file").files[0];
  if (!file) {
    alert("请选择文件");
    return;
  }

  console.log("--- processing file ", file.filename, " ---");

  const { filename, uuid } = await uploadFile(file, (progress) => {
    document.getElementById(
      "assembly-status"
    ).innerText = `上传进度:${progress}%`;
  });

  document.getElementById("assembly-status").innerText =
    "上传成功,开始转换";

  // 轮询查询文件转换状态
  // 这里使用 Promise + setTimeout 实现轮询,也可以使用其他方式实现轮询
  let status = "pending";
  let url = "";
  while (status === "pending") {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    ({ status, url } = await pollingFileStatus(uuid));
  }

  if (status === "succeed") {
    document.getElementById("assembly-status").innerText = "转换成功";
    const currentFiles = [{ filename, url, assets: parts }];
    console.log(currentFiles);
    instance.openFiles(currentFiles);
  } else {
    document.getElementById("assembly-status").innerText = "转换失败";
  }
};

// 一次性上传需要显示的装配体引用的所有零件
const onUploadParts = async () => {
  const files = document.getElementById("part-file").files;
  if (!files) {
    alert("选择文件为空!");
    return;
  }

  for (let i = 0; i < files.length; i++) {
    console.log("--- processing file ", i.name, " ---");
    const file = files[i];
    const setStatus = (status) => {
      document.getElementById(
        "part-status"
      ).innerText = `文件:${file.name} 状态:${status}`;
    };
    const { filename, uuid } = await uploadFile(file, (progress) => {
      setStatus(`上传进度:${progress}%`);
    });

    setStatus("上传成功,开始转换");

    // 轮询查询文件转换状态
    // 这里使用 Promise + setTimeout 实现轮询,也可以使用其他方式实现轮询
    let status = "pending";
    let url = "";
    while (status === "pending") {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      ({ status, url } = await pollingFileStatus(uuid));
    }

    if (status === "succeed") {
      setStatus("转换成功");
      parts.push({ filename, url });
    } else {
      setStatus("转换失败");
    }
  }
};

完整示例

请参考Demos中的assembly-file.html



分形三维技术团队
3 声望1 粉丝

Fractal 3D 是一款易用的在线 3D CAD 可视化引擎,无需了解任何图形学以及各种文件格式相关细节即可使用。