子件转换集成说明

1. 概要说明

支持对以下3D零件、装配体进行轻量化转换:

  • Solidworks、Catia、Creo、NX 等主流CAD软件的零件、装配体格式。
  • STEP、IGS、X_T 等主流中性格式。

子件转换模式下:装配体进行子件转换后,每个子零件会单独生成轻量化文件。支持进行子零件的局部更新,单装配体的预览加载速度会慢于模型转换。适用于 PDM/PLM 等对模型文件版本进行管理、子零件频繁更新的业务系统。

2. 集成业务场景

2.1 文件结构

业务端原始模型文件是一个zip格式的压缩包。其文件结构如下图:

  • Lights:存放转换后的轻量化模型文件
  • Models:存放待转换的原始模型文件
  • Convert.json:与数据转换有关的参数信息

Convert.json 数据结构如下:

{
    "Light": "Lights",
    "Assembly": "Models\\asm0001.asm",
    "Models": [
        {
            "Name": "Models\\asm0001.asm",
            "Guid": "4C31EE9A8A544FDCA24A58D0411EA760",
            "Path": "4C31EE9A8A544FDCA24A58D0411EA760"
        }
    ]
}
字段 必填 描述
Light 存放轻量化文件的文件夹名称。首次转换时,其值为空;非首次转换时,其值默认为“Lights”。如果其值为空,则系统判断为首次转换。
Assembly 顶层装配文件在压缩包里的相对路径。
Models 装配体及其所有子装配和零件文件的相对路径及其Guid。Lights和输出文件夹里的轻量化文件以Guid命名
Guid 不一定非得是GUID,只要保证独一无二即可。
Path 轻量化文件的相对路径或轻量化文件的HTTP路径。如果为空,则默认同级目录Guid文件夹下路径。

2.2 首次转换

应用场景:装配体或零件首次独立转换时。

数据组织:Models 文件夹中存放原始模型文件,如下图。Lights 文件夹为空。

Convert.json 数据结构如下:

{
    "Assembly": "Models\\asm0001.asm",
    "Light": "",
    "Models": [
        {
            "Name": "Models\\asm0001.asm",
            "Guid": "4C31EE9A8A544FDCA24A58D0411EA760"
        },
        {
            "Name": "Models\\prt0001.prt",
            "Guid": "21ED1C58D5324C0C9BA4D43958336F35"
        },
        {
            "Name": "Models\\asm0002.asm",
            "Guid": "9FA1B25211B3412298A4C1692A248808"
        },
        {
            "Name": "Models\\prt0002.prt",
            "Guid": "2BB4CC323CC84E0B969A25A103C1083A"
        }
    ]
}

2.3 新增修改转换

2.3.1 新增未转换过的模型

应用场景:顶层装配asm0001.asm 下面新增子装配asm0002.asm.2 和 零件prt0003.prt.2 。新增的子装配和零件均没有被转换过,不存在轻量化数据。需要转换新增的子装配和零件,并更新顶层装配的轻量化文件。

数据组织:Models 文件夹中存放新增的模型文件,及更新后的顶层装配文件。 Lights 文件夹中存放顶层装配体的轻量化文件 4C31EE9A8A544FDCA24A58D0411EA760 。

Convert.json 数据如下:

{
    "Light": "Lights",
    "Assembly": "Models\\asm0001.asm",
    "Models": [
        {
            "Name": "Models\\asm0001.asm",
            "Guid": "4C31EE9A8A544FDCA24A58D0411EA760"
        },
        {
            "Name": "Models\\asm0002.asm.2",
            "Guid": "9FA1B25211B3412298A4C1692A248808"
        },
        {
            "Name": "Models\\prt0003.prt.2",
            "Guid": "4C31EE9A8A544FDCA24A58D0411EA772"
        }
    ]
}

2.3.2 新增已转换过的模型

应用场景:顶层装配asm0001.asm 下面新增子装配asm0002.asm.2 。新增的子装配已转换过,轻量化文件夹guid为9FA1B25211B3412298A4C1692A248808。数据转换时,不需要重新转换新增的子装配,只需要更新顶层装配的轻量化文件。

数据组织: Models 文件夹中存放新增子装配的原始模型文件,及更新后的顶层装配文件。 Lights 文件夹中存放顶层装配的轻量化文件 4C31EE9A8A544FDCA24A58D0411EA760 和 新增子装配的轻量化文件 9FA1B25211B3412298A4C1692A248808 。

Convert.json 数据如下:

{
    "Light": "Lights",
    "Assembly": "Models\\asm0001.asm",
    "Models": [
        {
            "Name": "Models\\asm0001.asm",
            "Guid": "4C31EE9A8A544FDCA24A58D0411EA760"
        },
        {
            "Name": "Models\\asm0002.asm.2",
            "Guid": "9FA1B25211B3412298A4C1692A248808"
        }
    ]
}

2.3.3 模型更新-其父装配未更新

应用场景:子装配体asm0002.asm.2 下面的零件 prt0003.prt.2 有更新, 而子装配asm0002.asm.2 没有更新。数据转换时,只转换有更新的零件。

数据组织:Models 文件夹中存放更新后的原始模型文件,Lights 文件夹存为空。

Convert.json 数据如下:

{
    "Assembly": "Models\\prt0003.prt.2",
    "Light": "",
    "Models": [
        {
            "Name": "Models\\prt0003.prt.2",
            "Guid": "4C31EE9A8A544FDCA24A58D0411EA772"
        }
    ]
}

2.3.4 模型更新-其父装配有更新

应用场景:子装配 asm0002.asm.2 下面的零件 prt0003.prt.2 有更新, 子装配asm0002.asm.2 也有更新。数据转换时,更新子装配和零件。

数据组织:Models 文件夹存放更新后的原始模型文件,Lights 文件夹存放子装配的轻量化文件 9FA1B25211B3412298A4C1692A248808 。

Convert.json 数据如下:

{
   "Light": "Lights",
    "Assembly": "Models\\asm0002.asm.2",
    "Models": [
      {
        "Name": "Models\\asm0002.asm.2",
        "Guid": "9FA1B25211B3412298A4C1692A248808"
      },
      {
        "Name": "Models\\prt0003.prt.2",
        "Guid": "4C31EE9A8A544FDCA24A58D0411EA772"
      }
    ]
}

2.3.5 零件删除

应用场景:子装配体asm0002.asm.2 下面的零件 prt0003.prt.2 被删除。数据转换时,只需要更新对应子装配体的轻量化文件。

数据组织:Models 文件夹存放子装配的原始模型文件,Lights 文件夹存放子装配的轻量化文件。

Convert.json 数据如下:

{
   "Light": "Lights",
    "Assembly": "Models\\asm0002.asm.2",
    "Models": [
        {
            "Name": "Models\\asm0002.asm.2",
            "Guid": "9FA1B25211B3412298A4C1692A248808"
        }
    ]
}

3. 接口调用

API接口调用

Java SDK接口调用

调用示例:

package com.newdim.demo;
import com.newdim.sdk.YunapiClient;
import com.newdim.sdk.models.*;
import org.json.JSONObject;

public class demo {

    public static void main(String[] args)  {
        //本地插入文件名
        String localFile = "F:\\temp\\model.zip";
        //轻量化文件下载保存路径文件夹
        String saveFile = "F:\\temp\\download";
        //初始化celient partnerID, secretKey,apiServer
        String partnerID = "xx";企业ID
        String secretKey = "xx";密钥
        String apiServer = "https://api.3dopen.cn";接口地址
        YunapiClient yunapiClient = new YunapiClient(partnerID,secretKey,apiServer);
      
        {   
          //单个子件转换任务
            InsertTaskBaseRequest insertTaskRequest = new InsertTaskBaseRequest();
	    InsertTaskResponse res = yunapiClient.InsertPartConverTaskLocalFile(localFile,insertTaskRequest);
            System.out.println(res.taskID);
            if(res.taskID > 0){
                try {
                    //查询任务
                    BaseTaskResponse info = yunapiClient.QueryTask(res.taskID);
                    while (info.getCode() == 1 && info.status < 2){
                        info = yunapiClient.QueryTask(res.taskID);
                        Thread.sleep(2*1000);
                    }
                    if(info.status == 2){ 
                        //下载轻量化数据
                        ResultStatus rs = yunapiClient.DownloadNdsFile(info.outputNdsFiles,saveFile);
                        System.out.println("下载code:"+rs.getCode() + " msg:" + rs.getMsg());
                    }
                }catch (Exception e) {
                    System.out.println("error:"+e.getMessage());
                }
            }
        }
}

C# SDK接口调用

调用示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YunApiSDK;
using YunApiSDK.Model.Request;

namespace YunApiSDKDemo
{
    public class YunApiTest
    {
        /// <summary>
        /// 基础流程
        /// </summary>
        /// <param name="yunapiClient"></param>
        /// <param name="callbackUrl"></param>
        /// <returns></returns>
        public async Task Test()
        {
			string partnerID = "xx";企业ID
			string secretKey = "xx";密钥
			string apiServer = "https://api.3dopen.cn";接口地址
			// 参数分别为门户网站中 开发接口-接口信息 中的企业ID、密钥、接口地址
			var yunapiClient = new YunApiClient(partnerID, secretKey, apiServer);
            var filePath = "F:\\model.zip";
            var fileInfo = new FileInfo(filePath);

            // 获取minio临时上传URL
            var tempUrlRes = await yunapiClient.GetPresignedUploadUrlAsync(new GetPresignedUrlRequest { FileName = fileInfo.Name });

            if (tempUrlRes.Status.Code != 1)
            {
                await Console.Out.WriteLineAsync(tempUrlRes.Status.Msg);
                return;
            }

            // 使用minio临时授权URL上传文件
            var uploadRes = await yunapiClient.UploadFileByNdsFileUrlAsync(tempUrlRes.Data.Url, filePath);

            // 回调接口地址,如果需要回调则配置,不需要则不配置,地址为实际业务中开发的回调接口地址,本例为YunApiSDKCallbackDemo中的测试接口
            // 插入任务
            var insertRes = await yunapiClient.InsertPartConvertAddTaskAsync(new InsertPartConvertAddTaskRequest  { InputNdsFile = tempUrlRes.Data.InputNdsFile, ReturnURL = "" });

            if (insertRes.Status.Code != 1)
            {
                await Console.Out.WriteLineAsync(insertRes.Status.Msg);
                return;
            }

            var taskState = 0;
            var outputDataUrl = string.Empty;
            // 此处使用while循环是为了得到轻量化文件下载地址,演示下载文件,实际情况可根据业务调整
            while (taskState < 2)
            {
                // 查询接口
                var queryRes = await yunapiClient.QueryTaskAsync(new QueryTaskRequest { TaskID = insertRes.Data.TaskID });
                if (queryRes?.Status?.Code != 1)
                {
                    break;
                }
                taskState = queryRes.Data?.Status ?? 5;
                outputDataUrl = queryRes.Data?.OutputNdsFiles;
            }

            // 此段是演示下载轻量化文件,可根据实际情况自行调整
            if (taskState == 2 && !string.IsNullOrEmpty(outputDataUrl))
            {
                var decodeUrl = Encoding.UTF8.GetString(Convert.FromBase64String(outputDataUrl));
                
                // 此处是获取url中的文件名,可根据自己实际业务情况,确定要保存的文件名
                Uri uri = new Uri(decodeUrl);
                string fileName = System.IO.Path.GetFileName(uri.LocalPath);

                // 简单使用,演示功能,最佳实践使用IHttpClientFactory.CreateClient()创建
                var httpClient = new HttpClient();
                using (HttpResponseMessage response = await httpClient.GetAsync(decodeUrl))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        using (var fileStream = await response.Content.ReadAsStreamAsync())
                        using (var outputFileStream = System.IO.File.Create(fileName))
                        {
                            await fileStream.CopyToAsync(outputFileStream);
                        }
                        Console.WriteLine("文件下载成功!");
                    }
                    else
                    {
                        Console.WriteLine("请求失败: " + response.ReasonPhrase);
                    }
                }
            }


        }
    }
}