我有一个 IFC 格式的 BIM 模型,我想使用 Xbim 为模型中的每个对象添加一个新属性,比如成本。我正在构建一个 .NET 应用程序。以下代码运行良好,除了该属性还添加到楼层、建筑物和场地 - 我只想将其添加到不嵌套其他对象的最低级别对象。
首先,我尝试了各种方法来打印每个对象的“相关对象”,认为我可以过滤掉任何具有非空相关对象的对象。这让我看到了这个:
IfcRelDefinesByType.RelatedObjects ( http://docs.xbim.net/XbimDocs/html/7fb93e55-dcf7-f6da-0e08-f8b5a70accf2.htm ) 认为相关对象 ( https://standards.buildingsmart.org/IFC/RELEASE/IFC2x3 /FINAL/HTML/ifckernel/lexical/ifcreldecomposes.htm)将包含此信息。
但是我还没有设法从这个文档中实现工作代码。
这是我的代码:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xbim.Ifc;
using Xbim.Ifc2x3.Interfaces;
using Xbim.Ifc4.Kernel;
using Xbim.Ifc4.MeasureResource;
using Xbim.Ifc4.PropertyResource;
using Xbim.Ifc4.Interfaces;
using IIfcProject = Xbim.Ifc4.Interfaces.IIfcProject;
namespace MyPlugin0._1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
outputBox.AppendText("Plugin launched successfully");
}
private void button1_Click(object sender, EventArgs e)
{
// Setup the editor
var editor = new XbimEditorCredentials
{
ApplicationDevelopersName = "O",
ApplicationFullName = "MyPlugin",
ApplicationIdentifier = "99990100",
ApplicationVersion = "0.1",
EditorsFamilyName = "B",
EditorsGivenName = "O",
EditorsOrganisationName = "MyWorkplace"
};
// Choose an IFC file to work with
OpenFileDialog dialog = new OpenFileDialog();
dialog.ShowDialog();
string filename = dialog.FileName;
string newLine = Environment.NewLine;
// Check if the file is valid and continue
if (!filename.ToLower().EndsWith(".ifc"))
{
// Output error if the file is the wrong format
outputBox.AppendText(newLine + "Error: select an .ifc-file");
}
else
{
// Open the selected file (## Not sure what the response is to a corrupt/invalid .ifc-file)
using (var model = IfcStore.Open(filename, editor, 1.0))
{
// Output success when the file has been opened
string reversedName = Form1.ReversedString(filename);
int filenameShortLength = reversedName.IndexOf("\\");
string filenameShort = filename.Substring(filename.Length - filenameShortLength, filenameShortLength);
outputBox.AppendText(newLine + filenameShort + " opened successfully for editing");
////////////////////////////////////////////////////////////////////
// Get all the objects in the model ( ### lowest level only??? ###)
var objs = model.Instances.OfType<IfcObjectDefinition>();
////////////////////////////////////////////////////////////////////
// Create and store a new property
using (var txn = model.BeginTransaction("Store Costs"))
{
// Iterate over all the walls to initiate the Point Source property
foreach (var obj in objs)
{
// Create new property set to host properties
var pSetRel = model.Instances.New<IfcRelDefinesByProperties>(r =>
{
r.GlobalId = Guid.NewGuid();
r.RelatingPropertyDefinition = model.Instances.New<IfcPropertySet>(pSet =>
{
pSet.Name = "Economy";
pSet.HasProperties.Add(model.Instances.New<IfcPropertySingleValue>(p =>
{
p.Name = "Cost";
p.NominalValue = new IfcMonetaryMeasure(200.00); // Default Currency set on IfcProject
}));
});
});
// Add property to the object
pSetRel.RelatedObjects.Add(obj);
// Rename the object
outputBox.AppendText(newLine + "Cost property added to " + obj.Name);
obj.Name += "_withCost";
//outputBox.AppendText(newLine + obj.OwnerHistory.ToString());
}
// Commit changes to this model
txn.Commit();
};
// Save the changed model with a new name. Does not overwrite existing files but generates a unique name
string newFilename = filenameShort.Substring(0, filenameShort.Length - 4) + "_Modified.IFC";
int i = 1;
while (File.Exists(newFilename))
{
newFilename = filenameShort.Substring(0, filenameShort.Length - 4) + "_Modified(" + i.ToString() + ").IFC";
i += 1;
}
model.SaveAs(newFilename); // (!) Gets stored in the project folder > bin > Debug
outputBox.AppendText(newLine + newFilename + " has been saved");
};
}
}
// Reverse string-function
static string ReversedString(string text)
{
if (text == null) return null;
char[] array = text.ToCharArray();
Array.Reverse(array);
return new String(array);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}