Skip to content

XbimGeometry producing flipped triangles #96

@Kuraperunat

Description

@Kuraperunat

Here's yet another case of trying to create triangulated meshes using Xbim. It's working perfectly except for some, seemingly random ifc objects the triangle indices are always flipped. I've tried looking at all the existing code and fiddled around with the parameters and the transformations but I can't figure out what's causing it.

Here's an example of the issue: https://i.imgur.com/GrwMAv9.jpg
On the left you see a mesh generated by another program, and on the right you see the result of Xbim. The triangle indices of Xbim are flipped (e.g. 0,1,2 is for some reason 2,1,0). This happens with many different ifc files and in seemingly totally random places.

Here's the relevant part of my code where I triangulate the model.

using (var model = IfcStore.Open(path)) {

    var ctx = new Xbim3DModelContext(model);
    ctx.CreateContext();

    using (var geomRead = model.GeometryStore.BeginRead()) {

        var scale = model.ModelFactors.OneMetre;

        var prodIds = new HashSet<int>();
        foreach (var product in model.Instances.OfType<IIfcProduct>()) {
            if (product is IIfcFeatureElement) continue;
            prodIds.Add(product.EntityLabel);
        }

        var toIgnore = new short[4];
        toIgnore[0] = model.Metadata.ExpressTypeId("IFCOPENINGELEMENT");
        toIgnore[1] = model.Metadata.ExpressTypeId("IFCPROJECTIONELEMENT");
        if (model.IfcSchemaVersion == Xbim.Common.Step21.IfcSchemaVersion.Ifc4) {
            toIgnore[2] = model.Metadata.ExpressTypeId("IFCVOIDINGFEATURE");
            toIgnore[3] = model.Metadata.ExpressTypeId("IFCSURFACEFEATURE");
        }

        foreach (var geometry in geomRead.ShapeGeometries) {

            if (geometry.ShapeData.Length <= 0) //no geometry to display so don't write out any products for it
                continue;
            var instances = geomRead.ShapeInstancesOfGeometry(geometry.ShapeLabel);

            var xbimShapeInstances = instances.Where(
                si => !toIgnore.Contains(si.IfcTypeId) &&
                si.RepresentationType ==
                XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded &&
                prodIds.Contains(si.IfcProductLabel)).ToList();

            if (!xbimShapeInstances.Any()) continue;

            XbimShapeTriangulation tr;
            using (var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData))
                using (var br = new BinaryReader(ms))
                    tr = br.ReadShapeTriangulation();

            foreach (IXbimShapeInstanceData xbimShapeInstance in xbimShapeInstances) {

                var styleId = xbimShapeInstance.StyleLabel > 0
                    ? xbimShapeInstance.StyleLabel
                    : xbimShapeInstance.IfcTypeId * -1;

                var instanceTransform = ((XbimShapeInstance)xbimShapeInstance).Transformation;
                var trTransformed = tr.Transform(instanceTransform);

                var offset = vertices.Count;

                for (int k = 0; k < trTransformed.Vertices.Count; k++) {
                    var v = trTransformed.Vertices[k];
                    vertices.Add(new Vector3((float)(v.X / scale), (float)(v.Y / scale), (float)(v.Z / scale)));
                }

                for (int k = 0; k < trTransformed.Faces.Count; k++) {
                    var face = trTransformed.Faces[k];
                    var indices = face.Indices;
                    for (int z = 0; z < indices.Count; z += 3) {
                        int t0 = indices[z + 0], t1 = indices[z + 1], t2 = indices[z + 2];
                        triangles.Add(offset + t0);
                        triangles.Add(offset + t1);
                        triangles.Add(offset + t2);
                    }
                }
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed bug - system not working as intended

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions