xBimTeam / XbimEssentials

A .NET library to work with data in the IFC format. This is the core component of the Xbim Toolkit
https://xbimteam.github.io/
Other
477 stars 171 forks source link

Layers & Elements? #558

Closed mostl33 closed 1 month ago

mostl33 commented 3 months ago

Hi there,

first thanks for the awesome XBim libraries!

Is is possible to get all Layers (IfcPresentationLayerAssignment,...) from an IFC-File and their assigned entities (IfcWall, ...). I want to "render" a simple tree view with a layer based hierarchy. Basically I am struggeling to implement 2 basic functions: "get_all_layers()" & "get_all_layer_elements(layer)".

Thanks in advance & best regards,

ml

andyward commented 3 months ago

Hi @mostl33

What have you tried so far? Getting the layers should be a matter of model.Instances.OfType<IIfcPresentationLayerAssignment>(). Getting the products assigned it a bit more convoluted layers are often applied at lower level than the IfcProduct - it's the ShapeRepresentation (and their ProductRepresentations) that link to the end products (IfcWall etc).

Something like this should get you the basics:


using Xbim.Ifc;
using Xbim.Ifc4.Interfaces;

using var model = IfcStore.Open("SampleHouse4.ifc");

// Get Layers
var layers = model.Instances.OfType<IIfcPresentationLayerAssignment>();

foreach (var layer in layers)
{

    Console.WriteLine($"Layer: {layer.Name}");
    var layerItems = layer.AssignedItems;
    foreach(var layerItem in layerItems)
    {
        IEnumerable<IIfcProduct> items = GetItemsInLayer(layerItem);
        foreach(var item in items)
        {
            // TODO: Could group by Type, or IfcTypeObject as well
            Console.WriteLine($"  {item.ExpressType.Name} : {item.Name}");
        }
    }
}

// Get the set of products assigned to a layer item
IEnumerable<IIfcProduct> GetItemsInLayer(IIfcLayeredItem layerItem)
{
    return layerItem switch
    {
        IIfcRepresentation rep => GetProductsFromRepresentation(rep),
        IIfcRepresentationItem repItem => GetProductsFromRepresentationItem(repItem),

        _ => throw new NotImplementedException($"Unexpected LayerItem: {layerItem}"),
    };
}

IEnumerable<IIfcProduct> GetProductsFromRepresentation(IIfcRepresentation representation)
{
    return representation switch
    {
        IIfcShapeRepresentation rep => rep.OfProductRepresentation.OfType<IIfcProductDefinitionShape>().SelectMany(s => s.ShapeOfProduct),
        _ => throw new NotImplementedException($"Representation not implemented: {representation}")
    };

}

IEnumerable<IIfcProduct> GetProductsFromRepresentationItem(IIfcRepresentationItem representationItem)
{
    return representationItem switch
    {
        // TODO: edge cases like IfcMappedItems, IfcGeometricRepresentationItem
        _ => throw new NotImplementedException($"RepresentationItem not implemented: {representationItem}")
    };
}

e.g. image