Java插件IFC Tools Project(一)
这个插件主要由三部分组成:
(1) 每个 IFC 实体都有相对应的 Java 类。每个Java类都提供能够读取和设置对应 IFC 实体属性的方法,利用这些类的方法可以非常方便地读取和设置包括反转属性在内的所有属性。IFC 框架体系中所有实体的继承结构都体现到了相对应的 Java 类的继承结构。IFC 框架体系中所有定义类型和实体类型都映射为相应的接口。
(2)IFC 文件解析器,可以解析 IFC STEP 文件和IFC Zip 文件。
(3)核心 IFC 模型 IfcModel,用来读取 IFC 文件,操 作 IFC 模型中所 包 含 的 IFC 实 体,增 加 与 删 除 IFC实体。
下面主要介绍插件IFC Tools Project的使用。
使用IFC Java工具箱,可以完全访问基于IFC的BIM模型。 这意味着可以轻松读取,写入,修改或创建IFC文件。 该工具箱是用Java实现的。 而且,完全面向对象和早期绑定用于处理IFC实体。 具有其属性的对应Java类代表每个IFC实体。 从这个意义上讲,可以实例化并处理任何对象。
IFC Java工具箱支持在IFC方案中指定的所有实体的任何显式和逆属性。 尚不支持派生的属性,功能和规则。 交换IFC模型所支持的文件格式为:
STEP (according to ISO 10303-21), and
IFCZIP (according to buildingSMART implementer agreement CV-2x3-154).
1.工具箱版本
由于IFC方案的版本不同,我们提供了最新版本的IFC的工具箱:
IFC2X3 Java工具箱,用于访问和创建IFC2x3文件
IFC4 Java工具箱,用于访问和创建IFC4文件
此外,除了提供的IFC之外,我们还可以快速实施其他工具箱。
2. IFC JAVA工具箱的设计
IFC JAVA工具箱包含三个主要部分:
每个IFC实体的Java类,
用于读取IFC STEP文件的解析器,
以及用于访问所有可用的IFC对象的模型。
代表IFC实体的Java类提供用于获取和设置在相应IFC方案中指定的任何显式属性的访问方法。 只要指定,逆关系就会自动解析,并且可以类似于显式属性来读取。 此外,如果对模型或对象进行任何更改,则逆属性将保持一致。
在IFC方案中指定的继承结构是在Java类中建模的(例如,IfcWall是IfcProduct的实例)。 任何IFC实体的根接口都是ClassInterface。 通过各自的接口映射IFC方案中的选择类型和其他定义的类型。
解析器提供了读取IFC STEP文件和IFCZIP文件的方法。 但是,您不必过多地处理解析器。 这将在后台运行,您可以专注于实际任务。
工具箱的最后一部分包含一个中央模型,用于收集和访问创建的IFC对象。 它称为IfcModel并提供以下方法:
读取和写入IFC文件,
访问包含的IFC对象,以及
添加和删除IFC对象。
除了这三个主要部分,还有另一个部分,用于根据工业基础类(IFC)使用的称为GuidCompressor的算法来创建和压缩GUID。 这部分是由Jan Tulke开发。 该算法基于Jim Forester的C语言实现,该实现先前由Jeremy Tammik,Peter Muigg和Janos Maros实现。 它是开源的,可以在这里找到:
http://www.buildingsmart-tech.org/implementation/get-started/ifc-guid/ifc-guid-summary
3.读取IFC文件
IFC JAVA工具箱可以从实现java.io.InputStream的任何数据源(例如,文件系统中的本地文件,Web服务器上的远程文件或数据库中存储的文件)中读取IFC STEP文件和IFCZIP文件。 调用以下读取方法之一后,工具箱将加载IFC文件并初始化所描述的IFC实体。 这些对象可以使用IfcModel的方法进行访问和操作。 以下代码行演示了如何从不同的数据源读取IFC STEP文件:
//create a new instance of IfcModel
IfcModel ifcModel = new IfcModel();
//load an IFC STEP file from the file system
File stepFile = new File("C:\\myfile.ifc");
ifcModel.readStepFile(stepFile);
//... or load an IFC STEP file from a web server
URL stepURL = new URL("http://www.myifchomepage.com/myifcstepfile");
ifcModel.readStepFile(stepURL);
//... or load an IFC STEP file from any other data source,
//that implements java.io.InputStream (e.g. database connection)
InputStream stepStream = myDBconnection.getStepFile("1234");
ifcModel.readStepFile(stepStream);
类似读取IFCZIP文件:
//create a new instance of IfcModel
IfcModel ifcModel = new IfcModel();
//load an IFCZIP file from the file system
File ifczipFile = new File("C:\\myfile.ifczip");
ifcModel.readIfcZipFile(ifczipFile);
//... or load an IFCZIP file from a web server
URL ifczipURL = new URL("http://www.myifchomepage.com/myifczipfile");
ifcModel.readIfcZipFile(ifczipURL);
//... or load an IFCZIP file from any other data source,
//that implements java.io.InputStream (e.g. database connection)
InputStream ifczipStream = myDBconnection.getIfcZipFile("1234");
ifcModel.readIfcZipFile(ifczipStream);
4.写入IFC文件
IFC JAVA工具箱可以写入IFC STEP文件和IFCZIP文件。 如果要导出当前IfcModel的内容,请调用相应的写入方法之一。 以下代码行演示了如何将IFC STEP文件写入不同的数据接收器:
//write an IFC STEP file to the file system
File stepFile = new File("C:\\myfile.ifc");
ifcModel.writeStepfile(stepFile);
//... or write an IFC STEP file to a web server
URL stepURL = new URL("http://www.myifchomepage.com/myifcstepfile");
ifcModel.writeStepfile(stepURL);
//... or write an IFC STEP file to any other data sink,
//that implements java.io.OutputStream (e.g. database connection)
OutputStream stepStream = myDBconnection.getStepFile("1234");
ifcModel.writeStepfile(stepStream);
写入IFCZIP文件:
//write an IFCZIP file to the file system
File ifczipFile = new File("C:\\myfile.ifczip");
ifcModel.writeIfcZipFile(ifczipFile);
//... or write an IFCZIP file to a web server
URL ifczipURL = new URL("http://www.myifchomepage.com/myifczipfile");
ifcModel.writeIfcZipFile(ifczipURL);
//... or write an IFCZIP file to any other data sink,
//that implements java.io.OutputStream (e.g. database connection)
OutputStream ifczipStream = myDBconnection.getIfcZipFile("1234");
ifcModel.writeIfcZipFile(ifczipStream);
5.获取特定的IFC实体
加载IFC文件后,可能需要访问这些对象。 在IFC中,有一个根实体可以作为代码的起点,所谓的IfcProject代表任何分解树的根。 可以访问此实体,如下所示:
IfcProject ifcProject = ifcModel.getIfcProject();
如果要获取包含模型中包含的IFC实体的所有实例的集合,请调用:
Collection<ClassInterface> ifcObjects = ifcModel.getIfcObjects();
通常,您只需要特定类型的对象。 因此,可以调用IfcModel的getCollections(Class classType)方法。 它将返回具有指定类型的所有实例的集合。 这包括来自指定类型的子类型的实例(例如,IfcWall是IfcProduct的子类型):
//get all IfcWall instances contained in the model
Collection<IfcWall> walls = ifcModel.getCollection(IfcWall.class);
//get all IfcProduct instances contained in the model (includes all walls)
Collection<IfcProduct> products = ifcModel.getCollection(IfcProduct.class);
有时,按实体实例名称(即STEP行号)查找实体很有用。 您可以向模型询问特定的实例,也可以按其实例名称对所有对象进行排序,如下所示:
//get the object with the specified entity instance name
//(e.g. #123 in STEP physical file).
ClassInterface ifcObject = ifcModel.getIfcObjectByEntityInstanceName(123);
//get a map of all IFC entities sorted by their entity instance names
SortedMap<Integer, ClassInterface> ifcObjectMap =
ifcModel.getIfcObjectsSortedByEntityInstanceName();
IFC中的某些对象具有全局唯一ID(GUID)。 这些对象是IfcRoot的实例。 您可以要求模型使用特定的GUID来获取此类实体,如下所示:
//get the object with the specified GUID
IfcRoot ifcObject = ifcModel.getIfcObjectByID("23j$pkdXqHseOb00sJH0zG");
//multiple query: get the objects with the specified GUIDs
String[] ids = {"23j$pkdXqHseOb00", "56k3xydXqHseOb95", "49l5xydXqHokOb12"};
Collection<String> idList = Arrays.asList(ids);
Map<String, IfcRoot> ifcObjectsMap = ifcModel.getIfcObjectsByIDs(idList);
6.访问IFC实体的属性
对于IFC实体的每个显式属性,Java类中都有各自的get和set方法。 使用这些方法,您可以读取或修改此属性的值:
//read the product representation
IfcWall ifcWall = ...
IfcProductRepresentation representation = ifcWall.getRepresentation();
//set a new product representation
IfcProductRepresentation newRep = new IfcProductRepresentation();
newRep.setName(new IfcLabel(new STRING("myRepresentation", true)));
ifcWall.setRepresentation(newRep);
如果该属性是一个集合,那么还有其他方法可以向该集合中添加条目或从中删除条目:
IfcProductRepresentation representation = new IfcProductRepresentation();
IfcRepresentation rep1 = new IfcRepresentation();
//add a new representation to the product representation
representation.addRepresentations(rep1);
//or remove it
representation.removeRepresentations(rep1);
有时,有必要将实体强制转换为特定类型,以访问该类型的属性:
ClassInterface ifcObject = ...
if(ifcObject instanceof IfcWall)
{
//cast ifcObject to IfcWall
IfcWall ifcWall = (IfcWall) ifcObject;
IfcProductRepresentation representation = ifcWall.getRepresentation();
...
}
IFC实体的某些属性是可选的(请参阅IFC计划的官方文档)。 如果未指定这些属性,则它们在工具箱中将为null。 因此,您必须注意这些属性以避免NullPointerException的! 这意味着在继续执行代码之前,必须检查这些属性是否不为空:
if(ifcProject.getName() != null)
{
IfcLabel name = ifcProject.getName();
...
}
可以通过相应的get方法访问IFC实体的逆属性。 设置方法不是必需的,因为它们会自动解决。
SET<IfcRelDecomposes> ifcRelDecomposesSet = ifcProject.getIsDecomposedBy_Inverse();