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

Ifc element color? #525

Closed seghier closed 9 months ago

seghier commented 9 months ago

Hello When i load ifc file how can i get the color of each element? this don't give me any color

 else if (o is IIfcSurfaceStyle surfaceStyle)
    {
        var surfaceColor = new List<string>();
        foreach (var style in surfaceStyle.Styles)
        {
            if (style is IfcSurfaceStyleRendering surfaceStyleRendering)
            {
                var color = surfaceStyleRendering.SurfaceColour as IfcColourRgb;
                if (color != null)
                {
                    surfaceColor.Add($"R:{color.Red}, G:{color.Green}, B:{color.Blue}");
                }
            }
        }
        newRow["SurfaceColor"] = surfaceColor.Any() ? string.Join(", ", surfaceColor) : "N/A";
    }
private void PrintHierarchy(IIfcObjectDefinition o, int level, DataTable resultTable)
{
    var newRow = resultTable.NewRow();
    newRow["Level"] = level;
    newRow["Name"] = o.Name;
    newRow["Type"] = o.GetType().Name;

    // Check if the object is an IIfcObject and cast it to access its properties
    if (o is IIfcObject obj)
    {
        newRow["Guid"] = obj.GlobalId.ToString();
        newRow["Material"] = GetPropertyValue(obj, "Material");
        newRow["EntityLabel"] = obj.EntityLabel.ToString();
        newRow["Description"] = GetPropertyValue(obj, "Description");

        List<string> attributes = new List<string>
        {
            obj.EntityLabel.ToString(),
            o.Name,
            obj.GlobalId.ToString(),
            o.GetType().Name
        };
        objectAttributes.Add(attributes);

    }
    else if (o is IIfcSurfaceStyle surfaceStyle)
    {
        var surfaceColor = new List<string>();
        foreach (var style in surfaceStyle.Styles)
        {
            if (style is IfcSurfaceStyleRendering surfaceStyleRendering)
            {
                var color = surfaceStyleRendering.SurfaceColour as IfcColourRgb;
                if (color != null)
                {
                    surfaceColor.Add($"R:{color.Red}, G:{color.Green}, B:{color.Blue}");
                }
            }
        }
        newRow["SurfaceColor"] = surfaceColor.Any() ? string.Join(", ", surfaceColor) : "N/A";
    }

    else
    {
        newRow["Guid"] = "N/A";
        newRow["Material"] = "N/A";
        newRow["EntityLabel"] = "N/A";
        newRow["Description"] = "N/A";
        newRow["SurfaceColor"] = "N/A";
        //newRow["OwnerHistory"] = "N/A";
    }

    resultTable.Rows.Add(newRow);

    var spatialElement = o as IIfcSpatialStructureElement;
    if (spatialElement != null)
    {
        foreach (var containedElement in spatialElement.ContainsElements)
        {
            foreach (var element in containedElement.RelatedElements)
            {
                PrintHierarchy(element, level + 1, resultTable);
            }
        }
    }

    foreach (var item in o.IsDecomposedBy.SelectMany(r => r.RelatedObjects))
    {
        PrintHierarchy(item, level + 1, resultTable);
    }
}
seghier commented 9 months ago

Is the answer so difficult from xbim team?

andyward commented 9 months ago
  1. You asked the question 24 hours ago on a Saturday. It's a weekend and people have lives... you seem to think it's unreasonable people don't give up their spare time for free to answer your questions? 😠
  2. You're not making it easy for anyone as you're providing an incomplete example
  3. What you want to achieve isn't as simple as you may think

Fistly elements in IFC don't have "a color". They have representations, and those representations may have representationsItems that are styled with one or more colors. Think about an IfcWindow which may have both a Frame element in one color and a set of glass panes with a different (transparent) color. See https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD1/HTML/link/ifcstyleditem.htm

Secondly the sample code you've provided is all wrong for what you want to do. It hierarchically descends the Spatial Hierarchy (Building->Storey->Space) and then lists elements in those spatial elements. But it doesn't get into the representation of those elements so you'll never get a IfcSurfaceStyle (Not least because IfcSurfaceStyle is not derived from IfcObjectDefinition), so if (o is IIfcSurfaceStyle surfaceStyle) will never be satisfied.

Before you start copy and pasting code I really recommend exploring some simple models with XbimXplorer so you can better understand how IFC works, as the Xbim .net code is just a direct implementation of BuildingSMART IFC.

seghier commented 9 months ago

Take is easy, if you can't answer don't waste my time please, or don't answer at all. Before copy paste links take a breath.