最近被revit的外部扩展存储搞得死去活来,作为日后再次使用的预防针,此处随手留下印记,以作警示。

首先我们知道外部扩展存储ExtensibleStorage是revit提供给revit二次开发人员用于存储外部数据的接口,这使得很多公司可以在rvt文件中存储其自定义的数据。

对,这东西看上去很美好,但是!!

存储的过程十分的诡异,具体怎么诡异呢,我以自身经历举个例子。

(我也想弄成本地文件,但revit的这个存储功能的隐蔽性和二次开发的原因,导致用扩展存储比常规数据存储方案更优,比如减少io操作啦诸如此类)

这两天遇到一个需求,公司本身已经有很多自身的数据了,但因各种理由需要将其存入revit中供其他模块调用,起初看了一下叶先生的相关博客了解到了如何使用,具体不赘述,链接如下

https://blog.csdn.net/joexiongjin/article/details/7776552

看上去很简单,好的,那我们开始吧。

首先要存储数据,需要建立视图Schema,而schema与构件绑定使用entity,entity里面要存储数据要定义域field,再在field中确定存储的数值类型type。嗯,看着挺麻烦不过问题不大,和类定义很像。

entity可以理解为存储类,field就是类的变量,二field需要确定类型,和类定义没区别,甚至schema可以简单的理解为命名空间,也就是类的上一级(这里不搞太复杂,毕竟不喜欢b乎大佬们那种术语满天飞装得飞起)。

而每一个guid固定一个schema,使用get,set来存取数据,到这里是不是觉得ok了?

接下来,实际使用的时候,鬼畜的事情来了!

首先,简单的数据存储一般是没问题的,比如存一些用户信息等,最开始由于存储的都是string,bool,int这一类的数据(对你没看错,我说的就是几个常用的数据类型),所以还没觉得有什么,无非就是guid的管理比较麻烦。但是!

以上我可没提到过浮点数,对没错!唯独浮点数类型的例外(float,double:喵喵喵???)

最近做revit内置属性窗用于设置自定义数据,于是碰到了这样一种属性“地下比例”,它是一个0~1的浮点数。于是乎按照之前的理解存了一个double类型的field,数值的区间限制在外部的getset中处理,这些不难我就不贴代码了,跟着叶老师的代码抄作业都能抄明白。

编好之后试运行,选择构件,revit里鸦雀无声,属性窗纹丝不动(老子就是不出数据,来打我呀!)

随手套个TryCatch是个好习惯,我错了。。。

再次运行,打开调试模式,跳到断点里查看以下错误信息???

Autodesk.Revit.Exceptions.InvalidOperationException: Units are required for field FieldTest1 at Autodesk.Revit.DB.ExtensibleStorage.SchemaBuilder.Finish() …

提示说我们的定义域需要个单位,这什么鬼???叶老师没说还需要单位啊。

图中也可以看到,field的定义里也没有重载函数,那么是什么情况呢?翻了一下FieldBuilder的函数,于是呢

对没错,添加完field之后,利用fieldBuilder还需要指定一下unittype,这个unittype是什么呢?其实就是我们业务中经常使用到的单位,跳转到枚举类里看一下就能明白,无非就是质量单位、长度单位等等,但是。。。

 public enum UnitType
{
UT_Undefined = -,
UT_Custom = -,
UT_Length = ,
UT_Area = ,
UT_Volume = ,
UT_Angle = ,
UT_Number = ,
UT_SheetLength = ,
UT_SiteAngle = ,
UT_HVAC_Density = ,
UT_HVAC_Energy = ,
UT_HVAC_Friction = ,
UT_HVAC_Power = ,
UT_HVAC_Power_Density = ,
UT_HVAC_Pressure = ,
UT_HVAC_Temperature = ,
UT_HVAC_Velocity = ,
UT_HVAC_Airflow = ,
UT_HVAC_DuctSize = ,
UT_HVAC_CrossSection = ,
UT_HVAC_HeatGain = ,
UT_Electrical_Current = ,
UT_Electrical_Potential = ,
UT_Electrical_Frequency = ,
UT_Electrical_Illuminance = ,
UT_Electrical_Luminous_Flux = ,
UT_Electrical_Power = ,
UT_HVAC_Roughness = ,
UT_Force = ,
UT_LinearForce = ,
UT_AreaForce = ,
UT_Moment = ,
UT_ForceScale = ,
UT_LinearForceScale = ,
UT_AreaForceScale = ,
UT_MomentScale = ,
UT_Electrical_Apparent_Power = ,
UT_Electrical_Power_Density = ,
UT_Piping_Density = ,
UT_Piping_Flow = ,
UT_Piping_Friction = ,
UT_Piping_Pressure = ,
UT_Piping_Temperature = ,
UT_Piping_Velocity = ,
UT_Piping_Viscosity = ,
UT_PipeSize = ,
UT_Piping_Roughness = ,
UT_Stress = ,
UT_UnitWeight = ,
UT_ThermalExpansion = ,
UT_LinearMoment = ,
UT_LinearMomentScale = ,
UT_ForcePerLength = ,
UT_ForceLengthPerAngle = ,
UT_LinearForcePerLength = ,
UT_LinearForceLengthPerAngle = ,
UT_AreaForcePerLength = ,
UT_Piping_Volume = ,
UT_HVAC_Viscosity = ,
UT_HVAC_CoefficientOfHeatTransfer = ,
UT_HVAC_Airflow_Density = ,
UT_Slope = ,
UT_HVAC_Cooling_Load = ,
UT_HVAC_Cooling_Load_Divided_By_Area = ,
UT_HVAC_Cooling_Load_Divided_By_Volume = ,
UT_HVAC_Heating_Load = ,
UT_HVAC_Heating_Load_Divided_By_Area = ,
UT_HVAC_Heating_Load_Divided_By_Volume = ,
UT_HVAC_Airflow_Divided_By_Volume = ,
UT_HVAC_Airflow_Divided_By_Cooling_Load = ,
UT_HVAC_Area_Divided_By_Cooling_Load = ,
UT_WireSize = ,
UT_HVAC_Slope = ,
UT_Piping_Slope = ,
UT_Currency = ,
UT_Electrical_Efficacy = ,
UT_Electrical_Wattage = ,
UT_Color_Temperature = ,
UT_DecSheetLength = ,
UT_Electrical_Luminous_Intensity = ,
UT_Electrical_Luminance = ,
UT_HVAC_Area_Divided_By_Heating_Load = ,
UT_HVAC_Factor = ,
UT_Electrical_Temperature = ,
UT_Electrical_CableTraySize = ,
UT_Electrical_ConduitSize = ,
UT_Reinforcement_Volume = ,
UT_Reinforcement_Length = ,
UT_Electrical_Demand_Factor = ,
UT_HVAC_DuctInsulationThickness = ,
UT_HVAC_DuctLiningThickness = ,
UT_PipeInsulationThickness = ,
UT_HVAC_ThermalResistance = ,
UT_HVAC_ThermalMass = ,
UT_Acceleration = ,
UT_Bar_Diameter = ,
UT_Crack_Width = ,
UT_Displacement_Deflection = ,
UT_Energy = ,
UT_Structural_Frequency = ,
UT_Mass = ,
UT_Mass_per_Unit_Length = ,
UT_Moment_of_Inertia = ,
UT_Surface_Area = ,
UT_Period = ,
UT_Pulsation = ,
UT_Reinforcement_Area = ,
UT_Reinforcement_Area_per_Unit_Length = ,
UT_Reinforcement_Cover = ,
UT_Reinforcement_Spacing = ,
UT_Rotation = ,
UT_Section_Area = ,
UT_Section_Dimension = ,
UT_Section_Modulus = ,
UT_Section_Property = ,
UT_Structural_Velocity = ,
UT_Warping_Constant = ,
UT_Weight = ,
UT_Weight_per_Unit_Length = ,
UT_HVAC_ThermalConductivity = ,
UT_HVAC_SpecificHeat = ,
UT_HVAC_SpecificHeatOfVaporization = ,
UT_HVAC_Permeability = ,
UT_Electrical_Resistivity = ,
UT_MassDensity = ,
UT_MassPerUnitArea = ,
UT_Pipe_Dimension = ,
UT_PipeMass = ,
UT_PipeMassPerUnitLength =
}

这么多枚举实际上和我要存储的数据基本不沾边,UT_Number看上去很美好但其实质是整数类型,还好有个custom可以解决问题,剩下的都可以不用管了。

然而,设置了单位之后,再跑一下下,哎?怎么还是没反应?

TryCatch大法好。。。

Autodesk.Revit.Exceptions.ArgumentException: The displayUnits value is not compatible with the field description. …

这次是displayUnits,按句子直接意思就是说“嘿,屌丝,你丫的存储的数值与你定义的不是一个玩意儿!”

红果果的嘲讽。。。

我定了什么呢?double类型,存储的时候输入的也是个double数值,反复查了n遍代码也没什么不同,然后想起了unittype,custom顾名思义自定义类型,但是这个displayunits又在哪里设置呢?

网上查了,群里大佬们也问过,么得反应!这东西要么少有人用,要么懒得发帖子,行吧,好歹最终还是让我找到了相关文章,不过是全英文的。

https://spiderinnet.typepad.com/blog/2012/07/revit-api-vbnet-extensible-storage-xyz-type-data.html?no_prefetch=1

具体就不翻译了,没英语基础的用谷歌机翻也能看懂,大意就是说这东西存的时候,唯独double类型及其相关的数据(实际上基本浮点数类型都要算),或者部分复杂的数据在创建field时需要单独指定单位类型(UnitType),而在存的时候又要指定配套的DisplayUnitType,最鬼畜的是,取数据的时候也要指定DisplayUnitType(我以后只存字符串行不,revit大哥Orz.....)

于是乎,在对数据的定义,存储和取数据三个地方都设定好单位类型之后,我终于搞定了!!!

个人建议,如果非要使用外部扩展存储数据的话,尽量不存浮点类型的数据,实在不行用字符串存,取出来之后转换一下都比直接存方便,至于autodesk那帮大佬为何把这东西这么设定,咱也不敢说,咱也不敢问QAQ

关于revit的外部扩展存储的更多相关文章

  1. External Configuration Store Pattern 外部配置存储模式

    Move configuration information out of the application deployment package to a centralized location. ...

  2. webpack打包优化之外部扩展externals的实际应用

    目录 前言 externals定义 用法 string array object function regex 实际案例 打包时间 打包之后包的大小 浏览器加载 需要注意 参考 前言 使用vue-cl ...

  3. hyper-v 用户无法再 创建外部配置存储 0x80070005

    windows server 2008R2 刚安装的hyper-v 重启过. 修改配置文件到d:\Hyper-V目录下, hyper-V 创建 服务器遇到错误 操作失败 创建外部配置存储:一般性拒绝访 ...

  4. MySql 扩展存储引擎

    MySql 扩展存储引擎 下面介绍几个列式存储引擎(都有两个版本:社区版.商业版): 一:TokuDB TokuDB 是一个高性能.支持事务处理的 MySQL 和 MariaDB 的存储引擎.Toku ...

  5. android之外部文件存储和读取

    这次借用上次读写内部存储的代码,只是对将更换文件的读写路径即可.这里需要对获取SDcard的读写权限. 一.AndroidManifest.xml 这里增加了对外部存储设备的读写权限 <?xml ...

  6. Jdk和Jre目录和三个lib目录说明----外部扩展jar包servlet,mysql,oracle等

    以下文章转载自a personal blog:For Future,因为昨天下午在cmd模式下编译servlet失败,后来在网上找到这篇文章帮我解决了该问题,我觉得挺值得收藏的,并且这篇文章对&quo ...

  7. jetty+mongodb 配置session外部数据库存储

    monbgodb简介 主页 http://www.mongodb.org/ oschina.net 介绍页 http://www.oschina.net/p/mongodb MongoDB是一个介于关 ...

  8. 【Android】14.2 外部文件存储和读取

    分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 1.基本概念 内部存储的私有可用存储空间一般都不会很大,对于容量比较大的文件,例如视频等,应该将其存储在外部存储设 ...

  9. 基于stm32f4的ucGUI通过外部flash存储汉字库显示任意英文字符和汉字组合(控件可用)

    在做一个用到ucGUI的项目的时候要用到不定的汉字和英文字符,但是ucGUI本身又不支持读取芯片外部flash的字库来显示,于是查了下资料,如下: http://www.cnblogs.com/hik ...

随机推荐

  1. poj 3601Tower of Hanoi

    Tower of Hanoi Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 1895   Accepted: 646 De ...

  2. mysql-python安装

    操作系统:ubuntu16.04-gnome 首先要安装mysql数据 sudo apt install mysql-server 我们使用pip进行安装第三方模块 系统python版本为2.7.12 ...

  3. 2002年NOIP普及组复赛题解

    题目涉及算法: 级数求和:入门题: 选数:搜索: 产生数:搜索.高精度: 过河卒:动态规划. 级数求和 题目链接:https://www.luogu.org/problemnew/show/P1035 ...

  4. Group_concat介绍与例子

    进公司做的第一个项目就是做一个订单追踪查询,里里外外连接了十一个表,作为公司菜鸡的我麻了爪. 其中有一个需求就是对于多行的数据在一行显示,原谅我才疏学浅 无奈下找到了项目组长  在那学来了这个利器 ( ...

  5. P1111 朋友关系判定

    题目描述 有n个人和m对关系,这n个人的编号从1到n. 而m对关系中,每对关系都包含两个人的编号A和B(1<=A,B<=n),用于表示A和B是好友关系. 如果两个数A和B不在好友关系中,则 ...

  6. poj 3275 "Ranking the Cows"(DFS or Floyd+bitset<>)

    传送门 题意: 农场主 FJ 有 n 头奶牛,现在给你 m 对关系(x,y)表示奶牛x的产奶速率高于奶牛y: FJ 想按照奶牛的产奶速率由高到低排列这些奶牛,但是这 m 对关系可能不能精确确定这 n ...

  7. Linux 内核PCI去除一个驱动

    去除一个驱动是一个非常容易的动作. 对于一个 PCI 驱动, 驱动调用 pci_unregister_driver 函数. 这个函数只调用驱动核心函数 driver_unregister, 使用 一个 ...

  8. js算法(2)

    1寻找一个数组中最多的那个数 (1)利用数组 function findMostNum(arr){ var temp1=[];//存放去重的数字 var temp2=[];//存放各个数字的个数 va ...

  9. win10安装Keras报错处理

    本机已经安装好TensorFlow安装Keras的过程中遇到了些问题,解决后做一下记录: 1.Keras与TensorFlow的关系 Keras默认以TensorFlow为后端,同时可选以Theano ...

  10. sklearn各种分类器简单使用

    sklearn中有很多经典分类器,使用非常简单:1.导入数据 2.导入模型 3.fit--->predict 下面的示例为在iris数据集上用各种分类器进行分类: #用各种方式在iris数据集上 ...