简体   繁体   中英

How do I create and manipulate a Table property for an IFC object using Xbim?

I am working off of the basic example for amending data ( https://github.com/xBimTeam/XbimEssentials ). The only thing I'm changing is within the code below, where I want to add an IfcPropertyTableValue instead of an IfcPropertySingleValue.

This code runs, but in XbimXplorer under the object's properties, nothing's there - it's blank.

To make sure, the example code, as well as other property types do work and do show up in Xplorer under properties.

 var pSetRel = model.Instances.New<IfcRelDefinesByProperties>(r =>
                                {
                                    r.GlobalId = Guid.NewGuid();
                                    r.RelatingPropertyDefinition = model.Instances.New<IfcPropertySet>(pSet =>
                                    {
                                        pSet.Name = "Points";

                                        // FOR EACH POINT i :
                                        pSet.HasProperties.Add(model.Instances.New<IfcPropertyTableValue>(p =>
                                        {
                                            
                                            p.Name = "Points " + i;
                                            
                                            // FOR EACH COORDINATE x : 
                                            p.DefiningValues.Add(new IfcText(x));
                                            p.DefinedValues.Add(new IfcReal(-3.25));

                                        }));
                                    });
                                });

How can I make this work?

I have also tried using code to read the property, in case XbimXplorer just doesn't display tables. This code runs and prints zero lines (but works for other properties that are displayed in Xplorer):

// Try to read and print the new property
                    var nameObj = "my_object_name";
                    var checkObj = model.Instances.FirstOrDefault<IIfcBuildingElement>(d => d.Name == nameObj);
                    if (checkObj == null)
                    {
                        outputBox.AppendText(newLine + "Object: " + nameObj + " not found");
                    }
                    else
                    {
                        var properties = checkObj.IsDefinedBy
                            .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                            .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                            .OfType<IIfcPropertySingleValue>();
                        foreach (var property in properties)
                            outputBox.AppendText($"Property: {property.Name}, Value: {property.NominalValue}");
                    }

It would also be convenient if I could add several defining/defined value pairs at once, for instance like this (similar to normal C# lists):

IEnumerable<IfcValue> definingValues = new IfcText() {"x", "y", "z", "k"};
p.DefinedValues.AddRange(definingValues);

IEnumerable<IfcValue> definedValues = new IfcReal() {0.0, 1.6, -2.5, 3.33};
p.DefinedValues.AddRange(definedValues);

However, {"x", "y", "z", "k"} is then marked with the error Cannot initialize type 'IfcText' with a collection initializer because it does not implement 'System.Collections.IEnumerable' .

I don't think xbim Xplorer displays IfcPropertyTableValues . Probably because very few BIM tools currently output TableValues so I guess it never got implemented (and you'd need to establish how to display the table in the Xplorer view - do you nest a table in a property grid?).

If you look at the Xplorer code you'll see it only supports SingleValues, ComplexValues and EnumeratedValues. You might be able to use Complex Values as a collection of multiple IfcPropertySingleValues as a workaround.

In your 2nd code sample to output the values, you're filtering out any IfcPropertyTableValues with the .OfType<IIfcPropertySingleValue>() clause so you'll never see the output. Take a look at the IFC specs for SimpleProperties: https://standards.buildingsmart.org/IFC/RELEASE/IFC4_1/FINAL/HTML/link/ifcsimpleproperty.htm

On the last question you're initializing the array with the wrong syntax. Try something like this:

var labels = new Ifc4.MeasureResource.IfcText[] { "x", "y" };
p.DefiningValues.AddRange(labels.Cast<IIfcValue>()); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM