示例#1
0
 public IXbimGeometryObjectSet CreateSurfaceModel(IIfcTriangulatedFaceSet shell, ILogger logger)
 {
     using (new Tracer(LogHelper.CurrentFunctionName(), this._logger, shell))
     {
         return(_engine.CreateSurfaceModel(shell, logger));
     }
 }
示例#2
0
 public IXbimSolid CreateSolid(IIfcTriangulatedFaceSet shell, ILogger logger)
 {
     using (new Tracer(LogHelper.CurrentFunctionName(), this._logger, shell))
     {
         return(_engine.CreateSolid(shell, logger));
     }
 }
示例#3
0
        private XbimTriangulatedMesh Triangulate(IIfcTriangulatedFaceSet triangulation)
        {
            var faceId           = 0;
            var entityLabel      = triangulation.EntityLabel;
            var precision        = (float)triangulation.Model.ModelFactors.Precision;
            var faceCount        = triangulation.CoordIndex.Count();
            var triangulatedMesh = new XbimTriangulatedMesh(faceCount, precision);
            //add all the vertices in to the mesh
            var vertices = new List <int>(triangulation.Coordinates.CoordList.Count());

            foreach (var coord in triangulation.Coordinates.CoordList)
            {
                var tpl = coord.AsTriplet <IfcLengthMeasure>();
                var v   = new Vec3(tpl.A, tpl.B, tpl.C);
                var idx = triangulatedMesh.AddVertex(v);
                vertices.Add(idx);
            }
            foreach (var triangleFace in triangulation.CoordIndex)
            {
                var tpl = triangleFace.AsTriplet <IfcPositiveInteger>();
                triangulatedMesh.AddTriangle(vertices[(int)tpl.A - 1], vertices[(int)tpl.B - 1], vertices[(int)tpl.C - 1], faceId);
            }
            triangulatedMesh.UnifyFaceOrientation(entityLabel);
            return(triangulatedMesh);
        }
示例#4
0
 public XbimShapeGeometry Mesh(IIfcTriangulatedFaceSet triangulation)
 {
     if (_geometryType == XbimGeometryType.PolyhedronBinary)
     {
         return(MeshPolyhedronBinary(triangulation));
     }
     if (_geometryType == XbimGeometryType.Polyhedron)
     {
         return(MeshPolyhedronText(triangulation));
     }
     throw new Exception("Illegal Geometry type, " + _geometryType);
 }
示例#5
0
        /// <summary>
        /// returns the manual texture map
        /// </summary>
        /// <returns></returns>
        public IEnumerable <Point> GetTextureMap(IEnumerable <Point3D> vertices, IEnumerable <Vector3D> normals, IEnumerable <int> triangles)
        {
            IIfcTriangulatedFaceSet faceSet = _ifcTextMap.MappedTo as IIfcTriangulatedFaceSet;

            Point[] result = new Point[_numberOfVertices];
            Parallel.For(0, _ifcTextMap.TexCoordIndex.Count, (triangleIdx) =>
            {
                var texCoordTriangle = _ifcTextMap.TexCoordIndex[triangleIdx];
                for (int verticeIdx = 0; verticeIdx < texCoordTriangle.Count; verticeIdx++)
                {
                    int texCoordIdx   = (int)texCoordTriangle[verticeIdx] - 1;                //ifc indexing is one based
                    int verticeRefIdx = (int)faceSet.CoordIndex[triangleIdx][verticeIdx] - 1; //ifc indexing is one based

                    result[verticeRefIdx] = new Point(_ifcTextMap.TexCoords.TexCoordsList[texCoordIdx][0], _ifcTextMap.TexCoords.TexCoordsList[texCoordIdx][1]);
                }
            });

            return(result);
        }
示例#6
0
        private XbimShapeGeometry MeshPolyhedronBinary(IIfcTriangulatedFaceSet triangulation)
        {
            XbimShapeGeometry shapeGeometry = new XbimShapeGeometry();

            shapeGeometry.Format = XbimGeometryType.PolyhedronBinary;

            using (var ms = new MemoryStream(0x4000))
                using (var binaryWriter = new BinaryWriter(ms))
                {
                    // Prepare the header
                    uint verticesCount = (uint)triangulation.Coordinates.CoordList.Count();
                    uint triangleCount = (uint)triangulation.CoordIndex.Count();
                    uint facesCount    = 1;//at the moment just write one face for all triangles, may change to support styed faces in future
                    shapeGeometry.BoundingBox = XbimRect3D.Empty;

                    //Write out the header
                    binaryWriter.Write((byte)1); //stream format version
                    // ReSharper disable once RedundantCast

                    //now write out the faces
                    if (triangulation.Normals.Any()) //we have normals so obey them
                    {
                        List <IEnumerable <IfcPositiveInteger> > normalIndex = new List <IEnumerable <IfcPositiveInteger> >();
                        bool hasPnIndex = triangulation.PnIndex.Any();
                        if (hasPnIndex)
                        {
                            if (triangulation.PnIndex is List <IItemSet <IfcPositiveInteger> > ) //the list of triplets has not been flattened
                            {
                                foreach (var item in triangulation.PnIndex as List <IItemSet <IfcPositiveInteger> > )
                                {
                                    normalIndex.Add(item);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < triangulation.PnIndex.Count; i += 3)
                                {
                                    var item = new List <IfcPositiveInteger>()
                                    {
                                        triangulation.PnIndex[i], triangulation.PnIndex[i + 1], triangulation.PnIndex[i + 2]
                                    };
                                    normalIndex.Add(item);
                                }
                            }
                        }
                        else
                        {
                            foreach (var item in triangulation.CoordIndex)
                            {
                                normalIndex.Add(item);
                            }
                        }
                        binaryWriter.Write(verticesCount); //number of vertices
                        binaryWriter.Write(triangleCount); //number of triangles

                        XbimRect3D bb = XbimRect3D.Empty;
                        // use first point as a local origin for large coordinates. It doesn't matter if
                        // we use min, max or centroid for this.
                        var origin  = triangulation.Coordinates?.CoordList.FirstOrDefault()?.AsTriplet() ?? new XbimTriplet <IfcLengthMeasure>();
                        var isLarge = IsLarge(origin.A) || IsLarge(origin.B) || IsLarge(origin.C);
                        if (isLarge)
                        {
                            shapeGeometry.LocalShapeDisplacement = new XbimVector3D(origin.A, origin.B, origin.C);
                        }

                        var points = isLarge ?
                                     triangulation.Coordinates.CoordList.Select(c => c.AsTriplet()).Select(t => new XbimTriplet <IfcLengthMeasure> {
                            A = t.A - origin.A, B = t.B - origin.B, C = t.C - origin.C
                        }) :
                                     triangulation.Coordinates.CoordList.Select(c => c.AsTriplet());
                        foreach (var pt in points)
                        {
                            binaryWriter.Write((float)pt.A);
                            binaryWriter.Write((float)pt.B);
                            binaryWriter.Write((float)pt.C);

                            var rect = new XbimRect3D(pt.A, pt.B, pt.C, 0, 0, 0);
                            bb.Union(rect);
                        }

                        binaryWriter.Write(facesCount);

                        shapeGeometry.BoundingBox = bb;
                        Int32 numTrianglesInFace = triangulation.CoordIndex.Count();
                        binaryWriter.Write(-numTrianglesInFace); //not a planar face so make negative
                        var packedNormals = new List <XbimPackedNormal>(triangulation.Normals.Count());
                        foreach (var normal in triangulation.Normals)
                        {
                            var tpl = normal.AsTriplet <IfcParameterValue>();
                            packedNormals.Add(new XbimPackedNormal(tpl.A, tpl.B, tpl.C));
                        }



                        int triangleIndex = 0;

                        foreach (var triangle in triangulation.CoordIndex)
                        {
                            var triangleTpl     = triangle.AsTriplet();
                            var normalsIndexTpl = normalIndex[triangleIndex].AsTriplet();


                            WriteIndex(binaryWriter, (uint)triangleTpl.A - 1, (uint)verticesCount);
                            packedNormals[(int)normalsIndexTpl.A - 1].Write(binaryWriter);

                            WriteIndex(binaryWriter, (uint)triangleTpl.B - 1, (uint)verticesCount);
                            packedNormals[(int)normalsIndexTpl.B - 1].Write(binaryWriter);

                            WriteIndex(binaryWriter, (uint)triangleTpl.C - 1, (uint)verticesCount);
                            packedNormals[(int)normalsIndexTpl.C - 1].Write(binaryWriter);
                            triangleIndex++;
                        }
                    }
                    else //we need to calculate normals to get a better surface fit
                    {
                        var triangulatedMesh = Triangulate(triangulation);
                        shapeGeometry.BoundingBox = triangulatedMesh.BoundingBox;
                        verticesCount             = triangulatedMesh.VertexCount;
                        triangleCount             = triangulatedMesh.TriangleCount;

                        binaryWriter.Write(verticesCount); //number of vertices
                        binaryWriter.Write(triangleCount); //number of triangles

                        // use minimum bbox as a local origin
                        var origin  = triangulatedMesh.BoundingBox.Min;
                        var isLarge = IsLarge(origin.X) || IsLarge(origin.Y) || IsLarge(origin.Z);

                        var vertices = isLarge ?
                                       triangulatedMesh.Vertices.Select(v => new Vec3(v.X - origin.X, v.Y - origin.Y, v.Z - origin.Z)) :
                                       triangulatedMesh.Vertices;
                        foreach (var vert in vertices)
                        {
                            binaryWriter.Write((float)vert.X);
                            binaryWriter.Write((float)vert.Y);
                            binaryWriter.Write((float)vert.Z);
                        }

                        if (isLarge)
                        {
                            var bb = triangulatedMesh.BoundingBox;
                            shapeGeometry.BoundingBox            = new XbimRect3D(bb.X - origin.X, bb.Y = origin.Y, bb.Z - origin.Z, bb.SizeX, bb.SizeY, bb.SizeZ);
                            shapeGeometry.LocalShapeDisplacement = new XbimVector3D(origin.X, origin.Y, origin.Z);
                        }

                        facesCount = (uint)triangulatedMesh.Faces.Count;
                        binaryWriter.Write((UInt32)facesCount);
                        foreach (var faceGroup in triangulatedMesh.Faces)
                        {
                            var numTrianglesInFace = faceGroup.Value.Count;
                            //we need to fix this
                            var planar = (ushort.MaxValue != faceGroup.Key); //we have a mesh of faces that all have the same normals at their vertices
                            if (!planar)
                            {
                                numTrianglesInFace *= -1;      //set flag to say multiple normals
                            }
                            // ReSharper disable once RedundantCast
                            binaryWriter.Write((Int32)numTrianglesInFace);

                            bool first = true;
                            foreach (var triangle in faceGroup.Value)
                            {
                                if (planar && first)
                                {
                                    triangle[0].PackedNormal.Write(binaryWriter);
                                    first = false;
                                }
                                WriteIndex(binaryWriter, (uint)triangle[0].StartVertexIndex, verticesCount);
                                if (!planar)
                                {
                                    triangle[0].PackedNormal.Write(binaryWriter);
                                }

                                WriteIndex(binaryWriter, (uint)triangle[0].NextEdge.StartVertexIndex, verticesCount);
                                if (!planar)
                                {
                                    triangle[0].NextEdge.PackedNormal.Write(binaryWriter);
                                }

                                WriteIndex(binaryWriter, (uint)triangle[0].NextEdge.NextEdge.StartVertexIndex, verticesCount);
                                if (!planar)
                                {
                                    triangle[0].NextEdge.NextEdge.PackedNormal.Write(binaryWriter);
                                }
                            }
                        }
                    }
                    binaryWriter.Flush();
                    ((IXbimShapeGeometryData)shapeGeometry).ShapeData = ms.ToArray();
                }
            return(shapeGeometry);
        }
示例#7
0
 private XbimShapeGeometry MeshPolyhedronText(IIfcTriangulatedFaceSet triangulation)
 {
     throw new NotImplementedException();
 }
        private XbimShapeGeometry MeshPolyhedronBinary(IIfcTriangulatedFaceSet triangulation)
        {
            XbimShapeGeometry shapeGeometry = new XbimShapeGeometry();

            shapeGeometry.Format = XbimGeometryType.PolyhedronBinary;

            using (var ms = new MemoryStream(0x4000))
                using (var binaryWriter = new BinaryWriter(ms))
                {
                    // Prepare the header
                    uint verticesCount = (uint)triangulation.Coordinates.CoordList.Count();
                    uint triangleCount = (uint)triangulation.CoordIndex.Count();
                    uint facesCount    = 1;//at the moment just write one face for all triangles, may change to support styed faces in future
                    shapeGeometry.BoundingBox = XbimRect3D.Empty;

                    //Write out the header
                    binaryWriter.Write((byte)1); //stream format version
                    // ReSharper disable once RedundantCast

                    //now write out the faces
                    if (triangulation.Normals.Any()) //we have normals so obey them
                    {
                        List <IEnumerable <IfcPositiveInteger> > normalIndex = new List <IEnumerable <IfcPositiveInteger> >();
                        bool hasPnIndex = triangulation.PnIndex.Any();
                        if (hasPnIndex)
                        {
                            if (triangulation.PnIndex is List <IItemSet <IfcPositiveInteger> > ) //the list of triplets has not been flattened
                            {
                                foreach (var item in triangulation.PnIndex as List <IItemSet <IfcPositiveInteger> > )
                                {
                                    normalIndex.Add(item);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < triangulation.PnIndex.Count; i += 3)
                                {
                                    var item = new List <IfcPositiveInteger>()
                                    {
                                        triangulation.PnIndex[i], triangulation.PnIndex[i + 1], triangulation.PnIndex[i + 2]
                                    };
                                    normalIndex.Add(item);
                                }
                            }
                        }
                        else
                        {
                            foreach (var item in triangulation.CoordIndex)
                            {
                                normalIndex.Add(item);
                            }
                        }
                        binaryWriter.Write(verticesCount); //number of vertices
                        binaryWriter.Write(triangleCount); //number of triangles

                        XbimRect3D bb = XbimRect3D.Empty;
                        foreach (var coordList in triangulation.Coordinates.CoordList)
                        {
                            var pt = coordList.AsTriplet();
                            binaryWriter.Write((float)pt.A);
                            binaryWriter.Write((float)pt.B);
                            binaryWriter.Write((float)pt.C);
                            var rect = new XbimRect3D(pt.A, pt.B, pt.C, 0, 0, 0);
                            bb.Union(rect);
                        }

                        binaryWriter.Write(facesCount);

                        shapeGeometry.BoundingBox = bb;
                        Int32 numTrianglesInFace = triangulation.CoordIndex.Count();
                        binaryWriter.Write(-numTrianglesInFace); //not a planar face so make negative
                        var packedNormals = new List <XbimPackedNormal>(triangulation.Normals.Count());
                        foreach (var normal in triangulation.Normals)
                        {
                            var tpl = normal.AsTriplet <IfcParameterValue>();
                            packedNormals.Add(new XbimPackedNormal(tpl.A, tpl.B, tpl.C));
                        }



                        int triangleIndex = 0;

                        foreach (var triangle in triangulation.CoordIndex)
                        {
                            var triangleTpl     = triangle.AsTriplet();
                            var normalsIndexTpl = normalIndex[triangleIndex].AsTriplet();


                            WriteIndex(binaryWriter, (uint)triangleTpl.A - 1, (uint)verticesCount);
                            packedNormals[(int)normalsIndexTpl.A - 1].Write(binaryWriter);

                            WriteIndex(binaryWriter, (uint)triangleTpl.B - 1, (uint)verticesCount);
                            packedNormals[(int)normalsIndexTpl.B - 1].Write(binaryWriter);

                            WriteIndex(binaryWriter, (uint)triangleTpl.C - 1, (uint)verticesCount);
                            packedNormals[(int)normalsIndexTpl.C - 1].Write(binaryWriter);
                            triangleIndex++;
                        }
                    }
                    else //we need to calculate normals to get a better surface fit
                    {
                        var triangulatedMesh = Triangulate(triangulation);
                        shapeGeometry.BoundingBox = triangulatedMesh.BoundingBox;
                        verticesCount             = triangulatedMesh.VertexCount;
                        triangleCount             = triangulatedMesh.TriangleCount;

                        binaryWriter.Write(verticesCount); //number of vertices
                        binaryWriter.Write(triangleCount); //number of triangles

                        foreach (var vert in triangulatedMesh.Vertices)
                        {
                            binaryWriter.Write((float)vert.X);
                            binaryWriter.Write((float)vert.Y);
                            binaryWriter.Write((float)vert.Z);
                        }
                        facesCount = (uint)triangulatedMesh.Faces.Count;
                        binaryWriter.Write((UInt32)facesCount);
                        foreach (var faceGroup in triangulatedMesh.Faces)
                        {
                            var numTrianglesInFace = faceGroup.Value.Count;
                            //we need to fix this
                            var planar = (ushort.MaxValue != faceGroup.Key); //we have a mesh of faces that all have the same normals at their vertices
                            if (!planar)
                            {
                                numTrianglesInFace *= -1;      //set flag to say multiple normals
                            }
                            // ReSharper disable once RedundantCast
                            binaryWriter.Write((Int32)numTrianglesInFace);

                            bool first = true;
                            foreach (var triangle in faceGroup.Value)
                            {
                                if (planar && first)
                                {
                                    triangle[0].PackedNormal.Write(binaryWriter);
                                    first = false;
                                }
                                WriteIndex(binaryWriter, (uint)triangle[0].StartVertexIndex, verticesCount);
                                if (!planar)
                                {
                                    triangle[0].PackedNormal.Write(binaryWriter);
                                }

                                WriteIndex(binaryWriter, (uint)triangle[0].NextEdge.StartVertexIndex, verticesCount);
                                if (!planar)
                                {
                                    triangle[0].NextEdge.PackedNormal.Write(binaryWriter);
                                }

                                WriteIndex(binaryWriter, (uint)triangle[0].NextEdge.NextEdge.StartVertexIndex, verticesCount);
                                if (!planar)
                                {
                                    triangle[0].NextEdge.NextEdge.PackedNormal.Write(binaryWriter);
                                }
                            }
                        }
                    }
                    binaryWriter.Flush();
                    ((IXbimShapeGeometryData)shapeGeometry).ShapeData = ms.ToArray();
                }
            return(shapeGeometry);
        }
示例#9
0
 public IXbimGeometryObjectSet CreateSurfaceModel(IIfcTriangulatedFaceSet shell)
 {
     return(_engine.CreateSurfaceModel(shell));
 }