部门现在在做一个BIM三维建模项目,工作内容除了建模本身,还涉及到模型的编码。按照常规的生产流程,无论建模还是编码都需要人工手动来完成,十分耗费工时,这个时候开发工具来提升效率就显示很有必要。由于之前没有这方面的积累,所以经过多方面的学习和测试,积攒下来了很多东西,不仅涉及自动编码,也涉及自动建模,后面都会以写博客的形式都将其记录下来。
按照整个生产流程,应该先从自动建模开始,但最近刚好在弄属性,印象比较深刻,就先从属性开始写起,这过程涉及到C#、FME、Bentley的一些相关知识,今天先从C#开始。说到C#,由于接触时间短,并且一直本着用到什么就学什么,学到够用就停止的原则,难免会有一些地方存在错误或实现方式较Low的现象,所以非常欢迎大家指正错误,共同进步。
到什么山头唱什么歌,本次BIM建模项目,所有的属性最终都存储于json文件中,所以不管是做编码的质检、修改、自动赋值等一系列功能都离不开对json文件的操作,所以先搞明白json文件的内部存储结构就显得很有必要。json文件是什么,语法是怎样的,网上有很多资料可以看,我这里就不多说了,直接进入到本次json文件的内部存储结构。
首先给大家看一下本次项目Json文件存储数据的结构:
(图1)
为了大家方便观看,这里用Xmind弄了结构图
(图2)
这里大概解释一下,attributes作为根节点,所有模型的信息以图1红框框起来的部分为一个模型整体存入attributes内。大致了解了层级结构,我们后面的操作中就能要什么拿什么。
操作json文件用到了Newtonsoft.Json.dll文件,直接在引用里面,管理Nut包搜索安装Newtonsoft.Json,下载好后直接引用。
(图3)
需要说明的是,类名和类中的属性名必须与json文件里面的属性名一致才能正确的映射。但实际json属性名中存在空格或者特殊字符却比较普遍,定义类和类中的属性名时无法一致。
通过查找资料,目前类中的属性名包含空格或特殊字符,以“元素 ID”为例,可以通过在上面添加[JsonProperty(PropertyName = "元素 ID")]来解决。
(图4)
但类名中包含空格暂时没有搜到解决办法。
(图5)
因为这就做不了了吗?当然不,我们有别的方法来解决这个问题。在定义类和属性时,先直接先删掉空格和特殊字符,按照json的层级,需要什么属性就定义什么属性,这里我将后续工具涉及到的所有属性都进行了定义,代码如下:
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
namespace Attribute
{
public class 单元
{
public string 层 { get; set; }
public string 元素ID { get; set; }
public string 范围下限 { get; set; }
}
public class BRep单元
{
public string 层 { get; set; }
public string 元素ID { get; set; }
public string 范围下限 { get; set; }
}
public class 网格
{
public string 层 { get; set; }
public string 元素ID { get; set; }
public string 范围下限 { get; set; }
}
public class 参数化实体曲面
{
public string 层 { get; set; }
public string 元素ID { get; set; }
public string 范围下限 { get; set; }
}
public class 共享单元实例
{
public string 层 { get; set; }
public string 元素ID { get; set; }
public string 范围下限 { get; set; }
}
public class System
{
public 单元 单元 { get; set; }
public BRep单元 BRep单元 { get; set; }
public 网格 网格 { get; set; }
public 参数化实体曲面 参数化实体曲面 { get; set; }
public 共享单元实例 共享单元实例 { get; set; }
}
public class 编码
{
public string 构件码 { get; set; }
public string 设施码 { get; set; }
public string 顺序码 { get; set; }
}
public class 定位信息
{
public string 起点桩号 { get; set; }
public string 终点桩号 { get; set; }
public string 相对位置 { get; set; }
}
public class 施工信息
{
public string 长度 { get; set; }
public string 宽度 { get; set; }
public string 厚度 { get; set; }
}
public class 设计信息
{
public string 长度 { get; set; }
public string 宽度 { get; set; }
public string 厚度 { get; set; }
}
public class 身份信息
{
public string 模型元素名称 { get; set; }
public string 构件标识码 { get; set; }
}
public class PLATFORM
{
public string SIMID { get; set; }
public string code { get; set; }
}
public class Custom
{
public 编码 编码 { get; set; }
public 定位信息 定位信息 { get; set; }
public 施工信息 施工信息 { get; set; }
public 设计信息 设计信息 { get; set; }
public 身份信息 身份信息 { get; set; }
public PLATFORM PLATFORM { get; set; }
}
public class Attribute
{
public System system { get; set; }
public Custom custom { get; set; }
}
public class AttributesItem
{
public string guid { get; set; }
public string code { get; set; }
public string elementid { get; set; }
public Attribute attribute { get; set; }
}
public class Root
{
public List<AttributesItem> attributes { get; set; }
}
}
当定义好类以后,在映射json属性前,先对json文件进行预处理,采用字符串替换的方式,让json文件里的属性名与类名和类中的属性名一致。当然,使用批量替换的前提一定是不能因此引入别的错误,代码如下:
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
namespace Json
{
internal class Program
{
static void Main(string[] args)
{
//json文件路径
string pathInput = @"D:\工作\Attribute\attributes-0.json";
string json = File.ReadAllText(pathInput);
//预处理格式类型
json = json.Replace("BRep 单元", "BRep单元").Replace("参数化实体/曲面", "参数化实体曲面");
//预处理字段
json = json.Replace("元素 ID", "元素ID");
Root cc = JsonConvert.DeserializeObject<Root>(json);
}
}
}
通过断点调试可以看到,你自己定义的所有属性都已存入cc中,遍历cc提取即可。
(图6)
最后,感谢大家的观看,如果有哪里有疑问或错误需要指正,欢迎发私信和我沟通。