0

I am looking for a way to get the absolute vertices from an IfcWall. Most Parsers only give the relative placement. How do I dissolve the relation to other elements and make the coordinates absolute? The BimServer API provides transformation matrices but the output is either near 0 or near infinity on some values.

Is there a parser which provides an easy way of getting the coordinates of the Walls or any other Ifc elements with geometry. Or are my approaches wrong?

My approach: GeometryGymIfc & apstex ifcopentools

        IfcProject project = db.Project;
        IfcSpatialElement rootElement = project.RootElement;
        List<IfcWall> elements = project.Extract<IfcWall>();
        List<Wall> walls = new List<Wall>();
        List<IfcFacetedBrep> breps = new List<IfcFacetedBrep>();
        foreach (IfcWall element in elements)
        {
            IfcProductRepresentation representation = element.Representation;
            if (representation is null)
            {
                continue;
            }
            foreach (IfcRepresentation rep in representation.Representations)
            {
                IfcShapeRepresentation sr = rep as IfcShapeRepresentation;
                if (sr is null)
                {
                    continue;
                }
                foreach (IfcRepresentationItem item in sr.Items)
                {
                    IfcFacetedBrep fb = item as IfcFacetedBrep;
                    if (fb is null)
                    {
                        continue;
                    }
                    foreach (IfcFace face in fb.Outer.CfsFaces)
                    {
                        foreach (IfcFaceBound facebound in face.Bounds)
                        {
                            IfcLoop loop = facebound.Bound;
                            if (loop is IfcPolyloop == false)
                            {
                                continue;
                            }
                            foreach (IfcCartesianPoint point in ((IfcPolyloop)loop).Polygon)
                            {
                                walls.Add(new Wall(point.Coordinates.Item1, point.Coordinates.Item2, point.Coordinates.Item3));
                            }
                        }
                    }
                }
            }
        }

BIMSERVER:

        List<IfcWall> products = model.getAll(IfcWall.class);
        wall = new Wall[products.size()];
        for (IfcWall product : products) {
            if (product.getGeometry() != null) {
                //  Transformation Matrix
                double[] transformationMatrix = new double[product.getGeometry().getTransformation().length / 8];
                ByteBuffer tbuffer = ByteBuffer.wrap(product.getGeometry().getTransformation());
                tbuffer.order(ByteOrder.LITTLE_ENDIAN);
                DoubleBuffer dtbuffer = tbuffer.asDoubleBuffer();
                dtbuffer.get(transformationMatrix);
                for (int i = 0; i < 16; i++) {
                    System.out.println("transformationMatrix " + dtbuffer.get(i));
                }

                //  Coordinate matrix
                double[] coordinateMatrix = new double[product.getGeometry().getData().getVertices().length / 8];
                ByteBuffer cbuffer = ByteBuffer.wrap(product.getGeometry().getData().getVertices());
                cbuffer.order(ByteOrder.LITTLE_ENDIAN);
                DoubleBuffer dcbuffer = cbuffer.asDoubleBuffer();
                dcbuffer.get(coordinateMatrix);
                for (int i = 0; i < 16; i++) {
                    System.out.println("coordinateMatrix " + dcbuffer.get(i));
                }
                //Transformation
                transformationMatrix = Matrix.changeOrientation(transformationMatrix);
                Transform3D transform = new Transform3D(transformationMatrix);
                int count = 0;
                List<double[]> plist = new ArrayList<>();
                for (int i = 2; i < coordinateMatrix.length; i = i + 3) {
                    Point3d p = new Point3d(coordinateMatrix[i - 2], coordinateMatrix[i - 1], coordinateMatrix[i]);
                    transform.transform(p);
                    double[] parray = {p.x, p.y, p.z};
                    plist.add(parray);
                    count++;
                    if (count == 12) count = 0;
                }

                wall[wallcount] = new Wall(GuidCompressor.uncompressGuidString(product.getGlobalId()), product.getGlobalId(), product.getName(), plist);
                wallcount++;
            }
        }
Dakson
  • 75
  • 1
  • 7
  • I haven't worked with those two tools. I have used IfcOpenShell and IfcPlusPlus/IfcQuery. They both usually have some classes which are some sort of geometry conversion tool, which will give you an iterator returning converted and placed geometry (which sound like what you want). – Loebl Aug 08 '18 at 21:42
  • Yes that is exactly what I want. Can you further elaborate how you use Ifc++ with ifcopenshell. I have only tried the exe and read a bit of code from them but they don't provide an accessible API do they? – Dakson Aug 09 '18 at 11:28
  • IfcOpenShell and Ifc++ are separate projects. You need to choose one, mixing them won't do you good. IfcOpenShell has C++ and python bindings, Ifc++ is C++ only. Ifc++ is also lacking a bit of public documentation regarding its usage - you need to look at the viewer source code to figure its usage out. – Loebl Aug 09 '18 at 11:51

0 Answers0