­

C#开发BIMFACE系列27 服务端API之获取模型数据12:获取构件分类树

  • 2019 年 10 月 3 日
  • 筆記

BIMFACE官方示例中,加载三维模型后,模型浏览器中左上角默认提供了“目录树”的功能,清晰地展示了模型的完整构成及上下级关系。

 本篇介绍如何获取单个模型的构件分类树信息。

请求地址:POST https://api.bimface.com/data/v2/files/{fileId}/tree

说明:单模型构件分类树, treeType 接受两个值:default 和 customized,默认为 default。 

          v参数用来区别 treeType 为 default 时返回树的格式, customized总是返回格式2.0的构件树。

参数:

v参数用来区别 treeType 为 default 时返回树的格式, customized总是返回格式2.0的构件树。

当 treeType 为”customized”时,desiredHierarchy 表示了筛选树的层次,可选值有building,systemType,specialty,floor,category,family,familyType,如:desiredHierarchy=specialty,systemtype。

customizedNodeKeys:用来指定筛选树每个维度用id或者是name作为唯一标识, 如”floor”:”id”。

请求2.0的默认分类树(floor, category, family, familyType)

请求 path(示例):https://api.bimface.com/data/v2/files/1211223382064960/tree?v=2.0

请求 header(示例):“Authorization: Bearer dc671840-bacc-4dc5-a134-97c1918d664b”

请求 body(示例):可以为空,不传递。

HTTP响应示例(200):

{      "code": "success",      "message": null,      "data": [          {              "actualName": "1F",              "data": null,              "elementCount": 18,              "id": "694",              "items": [                  {                      "actualName": "栏杆扶手",                      "data": null,                      "elementCount": 18,                      "id": "-2000126",                      "items": [                          {                              "actualName": "栏杆扶手",                              "data": null,                              "elementCount": 18,                              "id": "",                              "items": [                                  {                                      "actualName": "栏杆",                                      "data": null,                                      "elementCount": 1,                                      "id": null,                                      "items": [],                                      "name": "栏杆",                                      "type": "familyType"                                  }                              ],                              "name": "栏杆扶手",                              "type": "family"                          }                      ],                      "name": "栏杆扶手",                      "type": "category"                  }              ],              "name": "1F",              "type": "floor"          }      ]  }

返回的结果结构比较复杂,封装成对应的C#类如下:

/// <summary>  ///  获取单个模型的构件分类树(2.0的默认分类树 floor, category, family, familyType)返回的结果类(默认模式)  /// </summary>  [Serializable]  public class SingleModelTree : GeneralResponse<List<TreeItem>>  {    }

调用的 TreeItem 类

[Serializable]  public class TreeItem  {      /// <summary>      ///  项的名称      /// </summary>      [JsonProperty("actualName")]      public string ActualName { get; set; }        [JsonProperty("data")]      public string Data { get; set; }        [JsonProperty("elementCount")]      public int? ElementCount { get; set; }        [JsonProperty("id")]      public string Id { get; set; }        [JsonProperty("items")]      public TreeItem[] Items { get; set; }        [JsonProperty("name")]      public string Name { get; set; }        /// <summary>      ///  例如:familyType、family、category      /// </summary>      [JsonProperty("type")]      public string Type { get; set; }        /// <summary>返回表示当前对象的字符串。</summary>      /// <returns>表示当前对象的字符串。</returns>      public override string ToString()      {          return String.Format("[actualName={0}, data={1}, elementCount={2}, id={3}, items={4}, name={5}, type={6}]",                               ActualName, Data, ElementCount, Id, Items.ToStringLine(), Name, Type);      }  }

请注意 TreeItem 类中的 public TreeItem[] Items { get; set; } 属性,类型是该类本身。属于递归引用。

Newtonsoft.Json.dll 默认支持递归引用类的序列化与反序列化。

C#实现方法:

 1 /// <summary>   2 ///  获取单个模型中构件的默认分类树   3 /// </summary>   4 /// <param name="accessToken">【必填】令牌</param>   5 /// <param name="fileId">【必填】代表该单模型的文件ID</param>   6 /// <param name="v">【非必填】用来区别treeType为default时返回树的格式</param>   7 /// <param name="request">【非必填】其他过滤参数类对象</param>   8 /// <returns></returns>   9 public virtual SingleModelTree GetSingleModelTreeByDefault(string accessToken, long fileId, string v = "2.0", FileTreeRequestBody request = null)  10 {  11     //return GetSingleModelTree(accessToken, fileId, TreeType.Default, v, request);  12     /* 单模型构件分类树,  13       (1)treeType 接受两个值:default 和 customized,默认为 default。  14       (2)v 参数用来区别 treeType 为 default 时返回树的格式, customized 总是返回格式2.0的构件树。  15       (3)当 treeType 为"customized"时,FileTreeRequestBody 类的 desiredHierarchy 属性 表示了筛选树的层次,可选值有building,systemType,specialty,floor,category,family,familyType,  16           如:desiredHierarchy=specialty,systemtype。  17             customizedNodeKeys: 用来指定筛选树每个维度用id或者是name作为唯一标识, 如"floor":"id"  18     */  19  20     // POST https://api.bimface.com/data/v2/files/{fileId}/tree  21     string url = string.Format(BimfaceConstants.API_HOST + "/data/v2/files/{0}/tree?treeType=default", fileId);  22  23     if (!string.IsNullOrWhiteSpace(v))  24     {  25         url = url + "&v=" + v;  26     }  27  28     string data = string.Empty;  29     if (request != null)  30     {  31         data = request.SerializeToJson();  32     }  33  34     BimFaceHttpHeaders headers = new BimFaceHttpHeaders();  35     headers.AddOAuth2Header(accessToken);  36  37     try  38     {  39         SingleModelTree response;  40  41         HttpManager httpManager = new HttpManager(headers);  42         HttpResult httpResult = httpManager.Post(url, data);  43         if (httpResult.Status == HttpResult.STATUS_SUCCESS)  44         {  45             response = httpResult.Text.DeserializeJsonToObject<SingleModelTree>();  46         }  47         else  48         {  49             response = new SingleModelTree  50             {  51                 Message = httpResult.RefText  52             };  53         }  54  55         return response;  56     }  57     catch (Exception ex)  58     {  59         throw new Exception("[获取单个模型中构件的默认分类树]发生异常!", ex);  60     }  61 }

其中调用到的 httpManager.Post() 方法,请参考《C# HTTP系列》

测试:

在BIMFACE的控制台中可以看到我们上传的文件列表,模型状态均为转换成功。

使用“A4.rvt”为例测试上述方法。

完整的分类树为

success    [    {      "actualName": "标高 1",      "data": null,      "elementCount": 4,      "id": "311",      "items": [        {          "actualName": "",          "data": null,          "elementCount": 4,          "id": "-2000011",          "items": [            {              "actualName": "基本墙",              "data": null,              "elementCount": 4,              "id": "",              "items": [                {                  "actualName": "常规 - 200mm",                  "data": null,                  "elementCount": 4,                  "id": "398",                  "items": [],                  "name": "常规 - 200mm",                  "type": "familyType"                }              ],              "name": "基本墙",              "type": "family"            }          ],          "name": "",          "type": "category"        }      ],      "name": "标高 1",      "type": "floor"    }  ]

测试代码如下:

// 获取构件分类树(默认)  protected void btnGetSingleModelTreeByDefault_Click(object sender, EventArgs e)  {      long fileId = txtFileID.Text.Trim().ToLong();      FileConvertApi api = new FileConvertApi();      SingleModelTree response = api.GetSingleModelTreeByDefault(txtAccessToken.Text, fileId);        txtResult.Text = response.Code.ToString2()                     + Environment.NewLine                     + response.Message.ToString2()                     + Environment.NewLine                     + response.Data.ToStringLine();  }

 

请求自定义树(floor, category, family, familyType)

请求 path(示例):https://api.bimface.com/data/v2/files/1211223382064960/tree?v=2.0&treeType=customized

请求 header(示例):“Authorization: Bearer dc671840-bacc-4dc5-a134-97c1918d664b”

请求 body(示例):

{      "desiredHierarchy": [          "category",          "family"      ],      "customizedNodeKeys": {          "category": "name"      }  }

请求体不能为 NULL ,必须传递值。 否则请求失败,提示 system.error.  customized tree request body is null

HTTP响应示例(200):

{      "code": "success",      "message": null,      "data": {          "items": [              {                  "actualName": "专用设备",                  "data": null,                  "elementCount": 6,                  "id": "-2001350",                  "items": [                      {                          "actualName": "投影仪-基于天花板 3D",                          "data": null,                          "elementCount": 3,                          "id": "",                          "items": [                            ],                          "name": "投影仪-基于天花板 3D",                          "type": "family"                      },                      {                          "actualName": "投影屏幕-基于天花板 3D",                          "data": null,                          "elementCount": 3,                          "id": "",                          "items": [                            ],                          "name": "投影屏幕-基于天花板 3D",                          "type": "family"                      }                  ],                  "name": "卫浴装置",                  "type": "category"              }          ],          "root": "category"      }  }

返回的结果结构比较复杂,封装成对应的C#类如下:

/// <summary>  ///  获取单个模型的构件分类树(自定义树floor, category, family, familyType)返回的结果类  /// </summary>  [Serializable]  public class SingleModelTreeByCustomized : GeneralResponse<SingleModelTreeByCustomized>  {      [JsonProperty("root")]      public string Root { get; set; }        [JsonProperty("items")]      public TreeItem[] Items { get; set; }        /// <summary>返回表示当前对象的字符串。</summary>      /// <returns>表示当前对象的字符串。</returns>      public override string ToString()      {          return String.Format("[root={0}, items={1}]",                               Root, Items.ToStringLine());      }  }

C#实现方法:

 1 /// <summary>   2 ///  获取单个模型中构件的自定义分类树   3 /// </summary>   4 /// <param name="accessToken">【必填】令牌</param>   5 /// <param name="fileId">【必填】代表该单模型的文件ID</param>   6 /// <param name="v">【非必填】用来区别treeType为default时返回树的格式</param>   7 /// <param name="request">【非必填】其他过滤参数类对象</param>   8 /// <returns></returns>   9 public virtual SingleModelTreeByCustomized GetSingleModelTreeByCustomized(string accessToken, long fileId, string v = "2.0", FileTreeRequestBody request = null)  10 {  11     //return GetSingleModelTree(accessToken, fileId, TreeType.Default, v, request);  12     /* 单模型构件分类树,  13       (1)treeType 接受两个值:default 和 customized,默认为 default。  14       (2)v 参数用来区别 treeType 为 default 时返回树的格式, customized 总是返回格式2.0的构件树。  15       (3)当 treeType 为"customized"时,FileTreeRequestBody 类的 desiredHierarchy 属性 表示了筛选树的层次,可选值有building,systemType,specialty,floor,category,family,familyType,  16           如:desiredHierarchy=specialty,systemtype。  17             customizedNodeKeys: 用来指定筛选树每个维度用id或者是name作为唯一标识, 如"floor":"id"  18     */  19  20     // POST https://api.bimface.com/data/v2/files/{fileId}/tree  21     string url = string.Format(BimfaceConstants.API_HOST + "/data/v2/files/{0}/tree?treeType=customized", fileId);  22  23     if (!string.IsNullOrWhiteSpace(v))  24     {  25         url = url + "&v=" + v;  26     }  27  28     string data = string.Empty;  29     if (request != null)  30     {  31         data = request.SerializeToJson();  32     }  33  34     BimFaceHttpHeaders headers = new BimFaceHttpHeaders();  35     headers.AddOAuth2Header(accessToken);  36  37     try  38     {  39         SingleModelTreeByCustomized response;  40  41         HttpManager httpManager = new HttpManager(headers);  42         HttpResult httpResult = httpManager.Post(url, data);  43         if (httpResult.Status == HttpResult.STATUS_SUCCESS)  44         {  45             response = httpResult.Text.DeserializeJsonToObject<SingleModelTreeByCustomized>();  46         }  47         else  48         {  49             response = new SingleModelTreeByCustomized  50             {  51                 Message = httpResult.RefText  52             };  53         }  54  55         return response;  56     }  57     catch (Exception ex)  58     {  59         throw new Exception("[获取单个模型中构件的自定义分类树]发生异常!", ex);  60     }  61 }

测试:

同样使用“A4.rvt”为例测试上述方法。

 完整的分类树为

success    [root=单体,   items=[actualName=,          data=,          elementCount=4,          id=0,          items=[actualName=,                 data=,                 elementCount=4,                 id=0,                 items=[actualName=,                       data=,                       elementCount=4,                       id=0,                       items=[actualName=标高 1,                              data=,                              elementCount=4,                              id=311,                              items=[actualName=墙,                                     data=,                                     elementCount=4,                                     id=-2000011,                                     items=[actualName=基本墙,                                            data=,                                            elementCount=4,                                            id=,                                            items=[actualName=常规 - 200mm,                                                   data=,                                                   elementCount=4,                                                   id=398,                                                   items=,                                                   name=常规 - 200mm,                                                   type=familyType                                                  ],                                            name=基本墙,                                            type=family                                           ],                                     name=墙,                                     type=category                                    ],                              name=标高 1,                              type=floor                             ],                       name=未设专业,                       type=specialty                      ],                  name=未设系统类型,                  type=systemType                 ],          name=未设单体,          type=building         ]  ]

界面上的筛选树的层次是过滤条件,主要用于筛选 type 属性。

测试代码如下:

// 获取构件分类树(自定义)  protected void btnGetSingleModelTreeByCustomized_Click(object sender, EventArgs e)  {      long fileId = txtFileID.Text.Trim().ToLong();        List<string> lstDesiredHierarchy = new List<string>();      if (chkTreeBuilding.Checked)      {          lstDesiredHierarchy.Add("building");      }      if (chkTreeSystemType.Checked)      {          lstDesiredHierarchy.Add("systemType");      }      if (chkTreeSpecialty.Checked)      {          lstDesiredHierarchy.Add("specialty");      }      if (chkTreeFloor.Checked)      {          lstDesiredHierarchy.Add("floor");      }      if (chkTreeCategory.Checked)      {          lstDesiredHierarchy.Add("category");      }      if (chkTreeFamily.Checked)      {          lstDesiredHierarchy.Add("family");      }      if (chkTreeFamilyType.Checked)      {          lstDesiredHierarchy.Add("familyType");      }        FileTreeRequestBody request = new FileTreeRequestBody();      request.DesiredHierarchy = lstDesiredHierarchy.ToArray();// new[] { "building", "systemType", "specialty", "floor", "category", "family", "familyType" };      request.CustomizedNodeKeys = new Dictionary<string, string> { { "category", "name" } };        FileConvertApi api = new FileConvertApi();      SingleModelTreeByCustomized response = api.GetSingleModelTreeByCustomized(txtAccessToken.Text, fileId, "2.0", request);        txtResult.Text = response.Code.ToString2()                     + Environment.NewLine                     + response.Message.ToString2()                     + Environment.NewLine                     + response.Data;  }