本篇将使用基本的代码示例来表示如何使用xBIM。我们将介绍持久存储的四个基本功能,即 CRUD(创建,检索,更新和删除)。以下示例通常适用于IFC4,但您也可以使用IFC2x3。实际上大多数代码都是IFC版本不可知的,因为它使用的IFC4接口也适用于IFC2x3。用于开发这些示例的示例数据可以在此处下载 。
 
一、创建
  以下示例将创建没有任何几何体的简单IFC模型。如您所见,IfcStore需要一个XbimEditorCredentials表示当前应用程序和用户的配置对象,并使用它来维护OwnerHistory根实体。这是一项要求,可以更轻松地处理创建合规IFC模型所需的众多方面之一。此IFC未定义任何模型视图定义(MVD), 因此除了WHERE规则和所需属性之外没有其他限制。您应始终设置编辑器凭据并使用应用程序的首字母和当前用户填写它。
  XbimEditorCredentials editor = new XbimEditorCredentials
{
ApplicationDevelopersName = "NJQY", //应用开发商名称
ApplicationFullName = "SparkDigitalReview", //应用程序名称
ApplicationIdentifier = "NJQYf43a-faa7-4a49-b06d-4cb21f81d220", //应用程序标示符,通过Guid来表示
ApplicationVersion = "4.0", //个人信息
EditorsFamilyName = "Zhang",
EditorsGivenName = "ChuanNing",
EditorsOrganisationName = "bim"
};

IModel xBIM中的所有实现都是 IDisposable 这样的,你应该总是在这样的 using 语句中使用它们

 using (var model = IfcStore.Create(editor, IfcSchemaVersion.Ifc4, XbimStoreType.InMemoryModel))
{
//...do something with the model
}

如果要在模型中创建或修改任何内容,则必须使用事务。这些也应该在 using 语句中使用,因此它们具有适当的范围,以便在发生某些情况时进行最终回滚操作。您必须明确提交事务以保留更改。事务不能嵌套,因此当时总是只有一个事务。

 using (var txn = model.BeginTransaction("Hello Wall"))
{
//....do something in the scope of this transaction
txn.Commit()
}

所有与实体相关的操作都可通过IModel.Instances。这是您在模型中获取,更改和创建新实体的访问点。要创建任何新对象,请使用此模板化函数。您始终必须指定要创建的非抽象类型。这是在xBIM中构建的,如果不这样,就会出现编译时错误。每个模型都是特定于模式的,因此它是IFC2x3或IFC4或其他特定模式。IfcStore使它更容易,因为它可以打开两个IFC版本,并会告诉你它是什么,但是当你想要创建数据时,请确保你不要搞砸你的using陈述。如果您尝试使用初始化为IFC2x3的模型创建IFC4实体,则会抛出运行时异常。

 var newWall = mode.Instances.New<IfcWall>();

除了使用此功能之外,无法以任何其他方式创建新实体。您将在上面的代码中看到,此函数使用可选的类型化对象初始值设定项来设置对象的值。没有必要使用它们,但我个人喜欢它,因为我可以看到结果实体的结构。

使用所有这些基本部件,我们可以建造第一面墙。这面墙没有任何几何形状,因此大多数IFC观众都不会向您展示任何东西。但这只是一个基本的例子。这是完整的代码:

 var editor = new XbimEditorCredentials
{
ApplicationDevelopersName = "xBIM Team",
ApplicationFullName = "xBIM Toolkit",
ApplicationIdentifier = "xBIM",
ApplicationVersion = "4.0",
EditorsFamilyName = "Santini Aichel",
EditorsGivenName = "Johann Blasius",
EditorsOrganisationName = "Independent Architecture"
};
using (var model = IfcStore.Create(editor, IfcSchemaVersion.Ifc4, XbimStoreType.InMemoryModel))
{
using (var txn = model.BeginTransaction("Hello Wall"))
{
// 创建模型前应该先创建项目
var project = model.Instances.New<IfcProject>(p => p.Name = "Basic Creation");
// 定义基本的单位  SIUnitsUK 为英制单位 
project.Initialize(ProjectUnits.SIUnitsUK); // 创建简单的对象并使用lambda初始值设定名称
var wall = model.Instances.New<IfcWall>(w => w.Name = "The very first wall"); // 设置一些基本的属性
model.Instances.New<IfcRelDefinesByProperties>(rel => {
rel.RelatedObjects.Add(wall);
rel.RelatingPropertyDefinition = model.Instances.New<IfcPropertySet>(pset => {
pset.Name = "Basic set of properties";
pset.HasProperties.AddRange(new[] {
model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "Text property";
p.NominalValue = new IfcText("Any arbitrary text you like");
}),
model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "Length property";
p.NominalValue = new IfcLengthMeasure(56.0);
}),
model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "Number property";
p.NominalValue = new IfcNumericMeasure(789.2);
}),
model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "Logical property";
p.NominalValue = new IfcLogical(true);
})
});
});
}); txn.Commit();
}
model.SaveAs("BasicWall.ifc");
}

IFC 文件格式如下(Revit 自带示例转换 rac_advanced_sample_project.ifc)

ISO--;
HEADER;
FILE_DESCRIPTION ((''), '2;1');
FILE_NAME ('', '2016-10-27T13:14:43', (''), (''), 'Xbim File Processor version 3.2.0.0', 'Xbim version 3.2.0.0', '');
FILE_SCHEMA (('IFC4'));
ENDSEC;
DATA;
#=IFCPROJECT('2t0OftVsP8UBH3rtAB$yJv',#,'Basic Creation',$,$,$,$,(#,#),#);
#=IFCOWNERHISTORY(#,#,$,.ADDED.,$,$,$,);
#=IFCPERSON($,'Santini Aichel','Johann Blasius',$,$,$,$,$);
#=IFCORGANIZATION($,'Independent Architecture',$,$,$);
#=IFCPERSONANDORGANIZATION(#,#,$);
#=IFCORGANIZATION($,'xBIM Team',$,$,$);
#=IFCAPPLICATION(#,$,'xBIM Toolkit','xBIM');
#=IFCUNITASSIGNMENT((#,#,#,#,#,#,#,#,#));
#=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#=IFCSIUNIT(*,.SOLIDANGLEUNIT.,$,.STERADIAN.);
#=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#=IFCSIUNIT(*,.MASSUNIT.,$,.GRAM.);
#=IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.);
#=IFCSIUNIT(*,.THERMODYNAMICTEMPERATUREUNIT.,$,.DEGREE_CELSIUS.);
#=IFCSIUNIT(*,.LUMINOUSINTENSITYUNIT.,$,.LUMEN.);
#=IFCCARTESIANPOINT((.,.,.));
#=IFCAXIS2PLACEMENT3D(#,$,$);
#=IFCGEOMETRICREPRESENTATIONCONTEXT('Building Model','Model',,.E-,#,$);
#=IFCCARTESIANPOINT((.,.));
#=IFCAXIS2PLACEMENT2D(#,$);
#=IFCGEOMETRICREPRESENTATIONCONTEXT('Building Plan View','Plan',,.E-,#,$);
#=IFCWALL('1YTVCro6L0$OJQL2X7wICY',#,'The very first wall',$,$,$,$,$,$);
#=IFCPROPERTYSINGLEVALUE('Text property',$,IFCTEXT('Any arbitrary text you like'),$);
#=IFCPROPERTYSINGLEVALUE('Length property',$,IFCLENGTHMEASURE(.),$);
#=IFCPROPERTYSINGLEVALUE('Number property',$,IFCNUMERICMEASURE(789.2),$);
#=IFCPROPERTYSINGLEVALUE('Logical property',$,IFCLOGICAL(.T.),$);
#=IFCPROPERTYSET('2u_olyjv13oRt0GvSVSxHS',#,'Basic set of properties',$,(#,#,#,#));
#=IFCRELDEFINESBYPROPERTIES('3I5GuvWn95PRXcxoFGfJAL',#,$,$,(#),#);
ENDSEC;
END-ISO--;
 
二、查询
  从模型中检索数据非常简单,它 IModel.Instances 再次用于访问我们需要的所有实体。 
 var firstWall = mode.Instances.FirtsOrDefault<IfcWall>();
var allWalls = model.Instances.OfType<IfcWall>();
var specificWall = model.Instances.Where<IfcWall>(w => w.Name == "Brick wall");

您可以看到,所有这些函数都是模板化的,所以它们使用对象的类型作为第一级过滤器。如果你知道你想要的类型,你应该总是指定它来提高性能。对于所有的搜索查询,您也可以使用接口来检索实体。我们在IFC2x3实体上实现了IFC4接口,这意味着您可以用一个代码库查询IFC2x3和IFC4 。

以下示例只需要这些使用:

using System;
using System.Linq;
using Xbim.Ifc;
using Xbim.Ifc4.Interfaces;

如果您对实体的结构感兴趣,建议浏览 buildingSMART ,它的前身是国际数据互用联盟(IAI-International Alliance of Interoperability) 教程网站。

 const string fileName = "SampleHouse.ifc";
using (var model = IfcStore.Open(fileName))
{
// 获得IFC 文件中的所有门(使用IfcDoor的IFC4接口,这将对IFC2x3和IFC4都有效)
var allDoors = model.Instances.OfType<IIfcDoor>();
// 只获得具有定义的IIfcTypeObject的门
var someDoors = model.Instances.Where<IIfcDoor>(d => d.IsTypedBy.Any());
// 获取单个门 以Id 查询
var id = "2AswZfru1AdAiKfEdrNPnu";
var theDoor = model.Instances.FirstOrDefault<IIfcDoor>(d => d.GlobalId == id);
Console.WriteLine($"Door ID: {theDoor.GlobalId}, Name: {theDoor.Name}");
// 获取这个门的所有属性
var properties = theDoor.IsDefinedBy
.Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
.SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
.OfType<IIfcPropertySingleValue>();
foreach (var property in properties)
Console.WriteLine($"Property: {property.Name}, Value: {property.NominalValue}");
}

控制台输出属性信息

Door ID: 3cUkl32yn9qRSPvBJVyWYp, Name: Doors_ExtDbl_Flush:1810x2110mm:
Property: IsExternal, Value: true
Property: Reference, Value: 1810x2110mm
Property: Level, Value: Level: Ground Floor
Property: Sill Height, Value:
Property: Area, Value: 4.9462127188431
Property: Volume, Value: 0.193819981582386
Property: Mark, Value:
Property: Category, Value: Doors
Property: Family, Value: Doors_ExtDbl_Flush: 1810x2110mm
Property: Family and Type, Value: Doors_ExtDbl_Flush: 1810x2110mm
Property: Head Height, Value:
Property: Host Id, Value: Basic Wall: Wall-Ext_102Bwk-75Ins-100LBlk-12P
Property: Type, Value: Doors_ExtDbl_Flush: 1810x2110mm
Property: Type Id, Value: Doors_ExtDbl_Flush: 1810x2110mm
Property: Phase Created, Value: New Construction
三、修改
  修改与新增、查询比较类似。注意事务必须是开放的,并且应该被包含在using语句中,否则模型将在您创建或更改任何对象时抛出异常。
const string fileName = "SampleHouse.ifc";
var editor = new XbimEditorCredentials
{
ApplicationDevelopersName = "xBIM Team",
ApplicationFullName = "xBIM Toolkit",
ApplicationIdentifier = "xBIM",
ApplicationVersion = "4.0",
EditorsFamilyName = "Santini Aichel",
EditorsGivenName = "Johann Blasius",
EditorsOrganisationName = "Independent Architecture"
}; using (var model = IfcStore.Open(fileName, editor, true))
{
// 根据ID 在模型中查询对应的门
var id = "3cUkl32yn9qRSPvBJVyWYp";
var theDoor = model.Instances.FirstOrDefault<IfcDoor>(d => d.GlobalId == id);
// 修改事务
using (var txn = model.BeginTransaction("Doors modification"))
{
// 创建具有两个属性的新属性集
var pSetRel = model.Instances.New<IfcRelDefinesByProperties>(r =>
{
r.GlobalId = Guid.NewGuid();
r.RelatingPropertyDefinition = model.Instances.New<IfcPropertySet>(pSet =>
{
pSet.Name = "New property set";
// 所有的集合被初始化
pSet.HasProperties.Add(model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "First property";
p.NominalValue = new IfcLabel("First value");
}));
pSet.HasProperties.Add(model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "Second property";
p.NominalValue = new IfcLengthMeasure(156.5);
}));
});
});
// 修改门的名称
theDoor.Name += "_checked";
// 添加属性
pSetRel.RelatedObjects.Add(theDoor);
// 提交修改事务
txn.Commit();
}
}
四、删除
  删除是模型中最复杂的操作,首先要知道的是,它只能在MemoryModel (内存模式)(2016年10月)中完全实现。之所以这么复杂,是因为IFC 格式的数据模型非常复杂,并不是层次结构或方向图。所以我们的delete实现只能确保模型中没有对象引用你删除的对象,所以模型保持一致。但它不会自动删除任何引用它的对象或引用它。有程序员或用户可以选择。但是,用于删除的底层基础设施可以非常简单地使用: 
 using (var model = IfcStore.Open(fileName))
{
// 获取模型中得一个门
var id = "3cUkl32yn9qRSPvBJVyWYp"; // 使用模型ID
var theDoor = model.Instances.FirstOrDefault<IIfcDoor>(d => d.GlobalId == id);
// 打开事务
using (var txn = model.BeginTransaction("Delete the door"))
{
//删除门
model.Delete(theDoor);
//提交修改
txn.Commit();
}
}
 

xBIM 基础03 基本模型操作的更多相关文章

  1. xBIM 基本的模型操作

    目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...

  2. 基础DOM和CSS操作(一)

    DOM简介 DOM是一种文档对象模型,方便开发者对HTML结构元素内容进行展示和修改.在JavaScript中,DOM不但内容庞大繁杂,而且我们开发的过程中需要考虑更多的兼容性.扩展性.在jQuery ...

  3. 第一百六十六节,jQuery,基础 DOM 和 CSS 操作,元素内容,元素属性,css和class,元素宽度高度、偏移、滚动条

    jQuery,基础 DOM 和 CSS 操作,元素内容,元素属性,css和class,元素宽度高度.偏移.滚动条 学习要点: 1.DOM 简介 2.设置元素及内容 3.元素属性操作 4.元素样式操作 ...

  4. xBIM 基础01 简介

    系列目录    [已更新最新开发文章,点击查看详细]  一.xBIM 简介 BIM(Building Information Modelling)建筑信息模型,xBIM(eXtensible Buil ...

  5. 086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结

    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结 本文知识点:面向对象基础(类和对象)总结 说明 ...

  6. day33-线程基础03

    线程基础03 6.用户线程和守护线程 用户线程:也叫工作线程,当线程的任务执行完或者通知方法结束.平时用到的普通线程均是用户线程,当在Java程序中创建一个线程,它就被称为用户线程 守护线程(Daem ...

  7. vue.js初级入门之最基础的双向绑定操作

    首先在页面引入vue.js以及其他需要用到的或者可能要用到的插件(这里我多引用了bootstrap和jquery) 引用的时候需要注意文件的路径,准备工作这样基本就完成了,下面正式开始入门. vue. ...

  8. javaSE基础03

    javaSE基础03 生活中常见的进制:十进制(0-9).星期(七进制(0-6)).时间(十二进制(0-11)).二十四进制(0-23) 进制之间的转换: 十进制转为二进制: 将十进制除以2,直到商为 ...

  9. javascript基础03

    javascript基础03 1. 算术运算符 后增量/后减量运算符 ++ ,-- 比较运算符 ( >, <, >=, <=, ==, !=,===,!== ) 逻辑运算符( ...

随机推荐

  1. [POJ 1316] 树上的询问

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1316 [算法] 点分治 由于边权较大,笔者在计算时使用了STL-set 注意当询问为 ...

  2. BZOJ 2212线段树的合并

    借鉴(抄)了一下题解-- 线段树合并的裸题吧- //By SiriusRen #include <cstdio> #include <cstring> #include < ...

  3. Spark RDD概念学习系列之transformation操作

    不多说,直接上干货! transformation操作 惰性求值 (1)RDD 的转化操作都是惰性求值的.这意味着在被调用行动操作之前Spark不会开始计算. (2)读取数据到RDD的操作也是惰性的. ...

  4. IE8不支持响应式设计解决方法

    下载并引入 respond.js 即可 为了针对IE8应用这段脚本,需要针对IE8的条件注释 <!--[if lt IE 9]> --- <! [endif]--> 为了不让并 ...

  5. ViewPager滑动到最后一页再向左滑动进入主界面

    在OnPageChangeListener中的onPageScrolled方法里判断 @Override public void onPageScrolled(int arg0, float arg1 ...

  6. asp.net中Server.MapPath的使用

    http://www.studyofnet.com/news/184.html   本文导读:Server.MapPath()的全名是System.Web.HttpContext.Current.Se ...

  7. swfupload组件上传文件

    前段时间做文件上传用的是H5的一个插件,由于浏览器的兼容性不好,所以又换了一个Flash版本的上传文件插件,感觉这个上传插件的使用方式跟H5的差不多,有些雷同.不过,由于后续浏览不再支持Flash(略 ...

  8. 原生js简易日历效果实现

    这里我们将用原生js实现简易的日历,原理和之前的原生js选项卡差不多,不过也有些区别: 首先html代码: <div class="container"> <di ...

  9. vue中slot的用法案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. day06-2 基本运算符(解压缩)

    目录 运算符 算数运算符 比较运算符 赋值运算符 逻辑运算符 运算规则 成员运算符 身份运算符 Python运算符优先级 链式赋值(必考) 交叉赋值(必考) 解压缩(必考) 运算符 算数运算符 进行算 ...