Learn Forge 系列:Forge 云端自动化设计服务 - 网络app部分

上一篇文章中,咱们讲解了Forge Design Automation的基本原理和样例代码的插件部分。本文继续前篇,当插件包准备就绪后,转向forgesample,基本框架流程是:html

1 . app的Configure首先检测本地可用的bundle压缩包,即上篇文章编译好的结果。选择压缩包,并选择云端Forge执行的引擎。显然,Revit插件的要Revit引擎。注意选择合适的版本前端

图片描述

2 . 点击【Create/Update】,app将从本地上传bundle压缩包到服务端,再经过Forge的云端自动化服务端口建立自动化App,提交插件包,建立Activity。全部这些准备好后,您的Forge帐户中就含有了对应的Activity,而Activity链接到自动化App,知道使用哪一个插件执行接下来的任务。git

/// <summary>
        /// 建立云端自动化app,上载插件bundle
        /// </summary>
        [HttpPost]
        [Route("api/forge/designautomation/appbundles")]
        public async Task<IActionResult> CreateAppBundle([FromBody]JObject appBundleSpecs)
        {
        //......
/// <summary>
        /// 建立 activity
        /// </summary>
        [HttpPost]
        [Route("api/forge/designautomation/activities")]
        public async Task<IActionResult> CreateActivity([FromBody]JObject activitySpecs)
        {
         //......

3 . 退出Configure窗口,程序会经过云端自动化服务获取Activity列表。在【Existing activities】选择到须要的Activitygithub

/// <summary>
        /// 获取该Forge帐户下全部可用Activity列表
        /// </summary>
        [HttpGet]
        [Route("api/forge/designautomation/activities")]
        public async Task<List<string>> GetDefinedActivities()
        {
             Page<string> activities = await _designAutomation.GetActivitiesAsync();
            //......

4 . 【Input File】选择到本地的Revit文件,可以使用本例samples文件夹下提供的样例文件。 json

5 . 输入须要改变的长和宽,点击[Start Workitem]. 将执行StartWorkitemsegmentfault

[HttpPost]
        [Route("api/forge/designautomation/workitems")]
        public async Task<IActionResult> StartWorkitem([FromForm]StartWorkitemInput input)
        {
**StartWorkitem**首先把本地Revit上传到后端,并经过Forge的Data Management API将文件传到某个bucket,和咱们一般为了测试Forge Viewer上传文件到bucket同样。由于Forge的云端自动化服务的输入文件只能从云存储而来,因此此案例利用Forge的bucket存储。您也能够改造为从其它数据存储。

``后端

//....
        // 确保bucket存在,不然建立之
        try
        {
            PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey, null, PostBucketsPayload.PolicyKeyEnum.Transient);
            await buckets.CreateBucketAsync(bucketPayload, "US");
        }
        catch { }; 
         
         //.......
        //上载文件到bucket
        using (StreamReader streamReader = new StreamReader(fileSavePath))
            await objects.UploadObjectAsync(bucketKey, inputFileNameOSS, (int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream");
        System.IO.File.Delete(fileSavePath);
当这些准备好之后,配置云端自动化WorkItem的参数:

   1) 输入参数:一个是原始Revit文件,经过配置access token来拿到
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
                {
                    Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, inputFileNameOSS),
                    Headers = new Dictionary<string, string>()
                     {
                         { "Authorization", "Bearer " + oauth.access_token }
                     }
                };
    ```

2) 须要更改的几何数据(长宽),经过配置一个json文件。长宽从客户端提交的输入而来。api

dynamic inputJson = new JObject();
            inputJson.Width = widthParam;
            inputJson.Height = heigthParam;
            XrefTreeArgument inputJsonArgument = new XrefTreeArgument()
            {
                Url = "data:application/json, " + ((JObject)inputJson).ToString(Formatting.None).Replace("\"", "'")
            };
3) 再配置更新后的Revit文件放置的位置,一样,本例将把结果文件放回到bucket中。一样,须要access token。


```
        string outputFileNameOSS = string.Format("{0}_output_{1}", 
                                        DateTime.Now.ToString("yyyyMMddhhmmss"), 
                                        Path.GetFileName(input.inputFile.FileName));  
                    XrefTreeArgument outputFileArgument = new XrefTreeArgument()
                    {
                        Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}",     
                                            bucketKey, outputFileNameOSS),
                        Verb = Verb.Put,
                        Headers = new Dictionary<string, string>()
                           {
                               {"Authorization", "Bearer " + oauth.access_token }
                           }
                    };
```

4) 最后就是提交任务WorkItem,传入前面配置好的参数,开启云端自动化的过程。
string callbackUrl = string.Format("{0}/api/forge/callback/designautomation?id={1}&outputFileName={2}", 
                             OAuthController.GetAppSetting("FORGE_WEBHOOK_URL"), browerConnectionId, 
                             outputFileNameOSS);
            WorkItem workItemSpec = new WorkItem()
            {
                ActivityId = activityName,
                Arguments = new Dictionary<string, IArgument>()
                {
                    { "inputFile", inputFileArgument },
                    { "inputJson",  inputJsonArgument },
                    { "outputFile", outputFileArgument },
                    //回调函数
                    { "onComplete", new XrefTreeArgument { Verb = Verb.Post, Url = callbackUrl } }
                }
            };
            WorkItemStatus workItemStatus = await _designAutomation.CreateWorkItemsAsync(workItemSpec);

云端自动化开启后,须要一个过程才结束,能够经过主动查询来获取状态,而本例采起回调函数的方式,即onComplete。当WorkItem结束后,不管什么状况,都自动通知callbackUrl, 带上WorkItem执行的日志(log)文件内容。而callbackUrl定义以下:浏览器

[HttpPost]
        [Route("/api/forge/callback/designautomation")]
        public async Task<IActionResult> OnCallback(string id, string outputFileName, [FromBody]dynamic body)
        {

因为默认是本地测试(localhost),回调函数要获得响应,采起了ngrok作重定向。网络

但这只是通知了网络应用的后端,但怎么自动通知前端浏览器呢?本例采用了SignalR. SignalR 是一个ASP .NET 下的类库,能够在ASP .NET 的Web项目中实现实时通讯。此部份内容略过,请查阅本例的先后端相关代码。

当WorkItem成功执行,结果文件导出到Forge的bucket,还会提供一个签名下载url,出如今客户端面板,用户就能把更改后的文件下载来查看了。

图片描述

运行forgesample,按照Readme要求填写Forge的client id,client secret,本网络应用的host,以及用于获取Design Automation回调结果状态的ngrok 重定向连接。本文就再也不赘述了。

本例能够做为研究其它方案的模板框架,只须要对前端用户界面作必定修改,提供核心插件模块,易于调试和诊断Forge云端自动化全过程。

相关文章
相关标签/搜索