Esempio n. 1
0
        public static void BuildGrid(this IMeshBuilder meshBuilder, float cellWidth, float cellLength, int segmentCount)
        {
            //Loop through the rows:
            for (int i = 0; i <= segmentCount; i++)
            {
                //incremented values for the Z position and V coordinate:
                float z = cellLength * i;
                float v = (1.0f / segmentCount) * i;

                //Loop through the collumns:
                for (int j = 0; j <= segmentCount; j++)
                {
                    //incremented values for the X position and U coordinate:
                    float x = cellWidth * j;
                    float u = (1.0f / segmentCount) * j;

                    //The position offset for this quad:
                    Vector3 offset = new Vector3(x, 0f, z);

                    //build quads that share vertices:
                    Vector2 uv             = new Vector2(u, v);
                    bool    buildTriangles = i > 0 && j > 0;

                    BuildQuadForGrid(meshBuilder, offset, uv, buildTriangles, segmentCount + 1);
                }
            }
        }
Esempio n. 2
0
        public static (int[], int[]) FillPolygon(IMeshBuilder meshBuilder, IList <Vector3d> newPolygon, Vector3f normal)
        {
            if (meshBuilder == null || newPolygon == null)
            {
                return(null, null);
            }
            var triangulation = Geometry.Triangulate(newPolygon, normal);

            if (triangulation == null)
            {
                return(null, null);
            }
            //add vertices and triangles of basement to mesh
            var vertexToIndex    = new Dictionary <Vector3d, int>();
            var addedTriangles   = new int[triangulation.Count];
            int addedTriangleIdx = 0;

            foreach (var triangle in triangulation)
            {
                int a0 = AddDistinctVertex3d(meshBuilder, vertexToIndex, triangle[0], normal);
                int b0 = AddDistinctVertex3d(meshBuilder, vertexToIndex, triangle[1], normal);
                int c0 = AddDistinctVertex3d(meshBuilder, vertexToIndex, triangle[2], normal);

                addedTriangles[addedTriangleIdx] = meshBuilder.AppendTriangle(a0, b0, c0);
                addedTriangleIdx++;
            }
            int[] newVertices = vertexToIndex.Values.ToArray();
            return(newVertices, addedTriangles);
        }
Esempio n. 3
0
        public static void ExtrudeToCenter(this IMeshBuilder meshBuilder, IMeshSelection meshSelection)
        {
            var p = Vector3.zero;

            for (int i = 0; i < meshSelection.Count; i++)
            {
                p += meshBuilder.Vertices[meshSelection[i]];
            }
            p = p / meshSelection.Count;

            meshBuilder.Vertices.Add(p);
            meshBuilder.UVs.Add(Vector2.zero);
//            meshBuilder.Colors.Add(new Color(1f, 1f, 1f, 1f));

            for (int i = 0; i < meshSelection.Count - 1; i++)
            {
                var i1 = meshSelection[i];
                var i2 = meshBuilder.Vertices.Count - 1;
                var i3 = meshSelection[i + 1];
                meshBuilder.AddTriangle(i1, i2, i3);
            }

            // Add the final face.
            meshBuilder.AddTriangle(meshBuilder.Vertices.Count - 2, meshBuilder.Vertices.Count - 1, meshSelection[0]);
        }
Esempio n. 4
0
        public static void BuildFacade(this IMeshBuilder meshBuilder, float width, float height, float length, Vector3 anchor)
        {
            //build the walls:

            //calculate directional vectors for the walls:
            Vector3 upDir      = Vector3.up * height;
            Vector3 rightDir   = Vector3.right * width;
            Vector3 forwardDir = Vector3.forward * length;

            Vector3 farCorner  = upDir + rightDir + forwardDir;
            Vector3 nearCorner = Vector3.zero;

            //shift the pivot by the anchor.
            Vector3 pivotOffset = Vector3.Scale((rightDir + forwardDir + upDir), anchor);

            farCorner  -= pivotOffset;
            nearCorner -= pivotOffset;

            //build the quads for the walls:
            BuildQuad(meshBuilder, nearCorner, rightDir, upDir);
            BuildQuad(meshBuilder, nearCorner, upDir, forwardDir);

            BuildQuad(meshBuilder, farCorner, -upDir, -rightDir);
            BuildQuad(meshBuilder, farCorner, -forwardDir, -upDir);
        }
Esempio n. 5
0
        public static GameObject CreateGameObject(
            this IMeshBuilder meshBuilder,
            string name,
            Material material,
            bool meshCollider     = false,
            bool calculateNormals = true,
            bool calculateBounds  = true)
        {
            var go = new GameObject();

            if (!string.IsNullOrEmpty(name))
            {
                go.name = name;
            }
            var meshFilter   = go.AddComponent <MeshFilter>();
            var meshRenderer = go.AddComponent <MeshRenderer>();

            meshFilter.mesh       = meshBuilder.BuildMesh(calculateNormals, calculateBounds);
            meshRenderer.material = material;

            if (meshCollider)
            {
                go.AddComponent <MeshCollider>().sharedMesh = meshFilter.sharedMesh;
            }

            return(go);
        }
Esempio n. 6
0
        public static void BuildCube(this IMeshBuilder meshBuilder, float width, float height, float length, Vector3 anchor)
        {
            //calculate directional vectors for all 3 dimensions of the cube:
            Vector3 upDir      = Vector3.up * height;
            Vector3 rightDir   = Vector3.right * width;
            Vector3 forwardDir = Vector3.forward * length;

            //calculate the positions of two corners opposite each other on the cube:

            //positions that will place the pivot at the corner of the cube:
            Vector3 nearCorner = Vector3.zero;
            Vector3 farCorner  = upDir + rightDir + forwardDir;

            //shift the pivot by the anchor
            Vector3 pivotOffset = Vector3.Scale((rightDir + forwardDir + upDir), anchor);

            farCorner  -= pivotOffset;
            nearCorner -= pivotOffset;

            //build the 3 quads that originate from nearCorner:
            BuildQuad(meshBuilder, nearCorner, forwardDir, rightDir);
            BuildQuad(meshBuilder, nearCorner, rightDir, upDir);
            BuildQuad(meshBuilder, nearCorner, upDir, forwardDir);

            //build the 3 quads that originate from farCorner:
            BuildQuad(meshBuilder, farCorner, -rightDir, -forwardDir);
            BuildQuad(meshBuilder, farCorner, -upDir, -rightDir);
            BuildQuad(meshBuilder, farCorner, -forwardDir, -upDir);
        }
Esempio n. 7
0
        private int append_vertex(IMeshBuilder builder, Vector3d vtx, Vector3f norm, Vector3f cols, Vector2f uvs, bool bHaveNormals, bool bHaveColors, bool bHaveUVs)
        {
            if (bHaveNormals == false && bHaveColors == false && bHaveUVs == false)
            {
                return(builder.AppendVertex(vtx.x, vtx.y, vtx.z));
            }

            NewVertexInfo vinfo = new NewVertexInfo();

            vinfo.bHaveC = vinfo.bHaveN = vinfo.bHaveUV = false;
            vinfo.v      = vtx;
            if (bHaveNormals)
            {
                vinfo.bHaveN = true;
                vinfo.n      = norm;
            }
            if (bHaveColors)
            {
                vinfo.bHaveC = true;
                vinfo.c      = cols;
            }
            if (bHaveUVs)
            {
                vinfo.bHaveUV = true;
                vinfo.uv      = uvs;
            }

            return(builder.AppendVertex(vinfo));
        }
Esempio n. 8
0
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(AMF));
            AMF           amf;

            try {
                amf = (AMF)serializer.Deserialize(reader);
            } catch (Exception e) {
                return(new IOReadResult(IOCode.FileParsingError, $"XML parsing error: {e}"));
            }

            foreach (var @object in amf.objects)
            {
                foreach (var mesh in @object.meshes)
                {
                    int meshId = builder.AppendNewMesh(false, false, false, true);
                    var mapV   = new int[mesh.vertices.vertices.Length];
                    for (int k = 0; k < mesh.vertices.vertices.Length; ++k)
                    {
                        var coordinates = mesh.vertices.vertices[k].coordinates;
                        mapV[k] = builder.AppendVertex(coordinates.x, coordinates.y, coordinates.z);
                    }
                    for (int i = 0; i < mesh.volumes.Length; ++i)
                    {
                        for (int j = 0; j < mesh.volumes[i].triangles.Length; ++j)
                        {
                            var triangle = mesh.volumes[i].triangles[j];
                            builder.AppendTriangle(mapV[triangle.v1], mapV[triangle.v2], mapV[triangle.v3], i);
                        }
                    }
                }
            }

            return(IOReadResult.Ok);
        }
Esempio n. 9
0
 public static void AssignColors(this IMeshBuilder meshBuilder, int startIndex, int endIndex, Color color)
 {
     for (int i = 0; i < meshBuilder.Vertices.Count; i++)
     {
         meshBuilder.Colors[i] = color;
     }
 }
Esempio n. 10
0
        protected virtual void BuildMesh(STLSolid solid, IMeshBuilder builder)
        {
            if (RebuildStrategy == Strategy.AutoBestResult)
            {
                DMesh3 result = BuildMesh_Auto(solid);
                builder.AppendNewMesh(result);
            }
            else if (RebuildStrategy == Strategy.IdenticalVertexWeld)
            {
                DMesh3 result = BuildMesh_IdenticalWeld(solid);
                builder.AppendNewMesh(result);
            }
            else if (RebuildStrategy == Strategy.TolerantVertexWeld)
            {
                DMesh3 result = BuildMesh_TolerantWeld(solid, WeldTolerance);
                builder.AppendNewMesh(result);
            }
            else
            {
                BuildMesh_NoMerge(solid, builder);
            }

            if (WantPerTriAttribs && solid.TriAttribs != null && builder.SupportsMetaData)
            {
                builder.AppendMetaData(PerTriAttribMetadataName, solid.TriAttribs);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Read mesh file using options and builder. You must provide our own Builder
        /// here because the reader is not returned
        /// </summary>
        static public IOReadResult ReadFile(string sFilename, ReadOptions options, IMeshBuilder builder)
        {
            var reader = new StandardMeshReader();

            reader.MeshBuilder = builder;
            return(reader.Read(sFilename, options));
        }
Esempio n. 12
0
        public IOReadResult ReadFile(Stream stream, IMeshBuilder builder, ReadOptions options, ParsingMessagesHandler messages)
        {
            // detect binary STL
            BinaryReader binReader = new BinaryReader(stream);

            byte[] header    = binReader.ReadBytes(80);
            bool   bIsBinary = false;

            // if first 80 bytes contain non-text chars, probably a binary file
            if (Util.IsTextString(header) == false)
            {
                bIsBinary = true;
            }
            // if we don't see "solid" string in first 80 chars, probably binary
            if (bIsBinary == false)
            {
                string sText = System.Text.Encoding.ASCII.GetString(header);
                if (sText.Contains("solid") == false)
                {
                    bIsBinary = true;
                }
            }

            stream.Seek(0, SeekOrigin.Begin); // reset stream

            STLReader reader = new STLReader();

            reader.warningEvent += messages;
            IOReadResult result = (bIsBinary) ?
                                  reader.Read(new BinaryReader(stream), options, builder) :
                                  reader.Read(new StreamReader(stream), options, builder);

            return(result);
        }
Esempio n. 13
0
        public async Task <MeshData> BuildMeshData(Terrain terrain, IReadOnlyCollection <Texture2D> alphaMaps, MassiveGrassGrid.CellIndex index, Rect rect, MassiveGrassProfile profile)
        {
            var elements = await GenerateElements(terrain, rect, profile, index.hash % 50000);

            builder = builder ?? profile.CreateBuilder();
            return(await builder.BuildMeshData(terrain, alphaMaps, profile, elements));
        }
Esempio n. 14
0
        /// <summary>
        /// Builds a single quad based on a position offset and width and length vectors.
        /// </summary>
        /// <param name="meshBuilder">The mesh builder currently being added to.</param>
        /// <param name="offset">A position offset for the quad.</param>
        /// <param name="widthDir">The width vector of the quad.</param>
        /// <param name="lengthDir">The length vector of the quad.</param>
        public static void BuildQuad(this IMeshBuilder meshBuilder, Vector3 offset, Vector3 widthDir, Vector3 lengthDir)
        {
            Vector3 normal = Vector3.Cross(lengthDir, widthDir).normalized;

            meshBuilder.Vertices.Add(offset);
            meshBuilder.UVs.Add(new Vector2(0.0f, 0.0f));
            meshBuilder.Normals.Add(normal);

            meshBuilder.Vertices.Add(offset + lengthDir);
            meshBuilder.UVs.Add(new Vector2(0.0f, 1.0f));
            meshBuilder.Normals.Add(normal);

            meshBuilder.Vertices.Add(offset + lengthDir + widthDir);
            meshBuilder.UVs.Add(new Vector2(1.0f, 1.0f));
            meshBuilder.Normals.Add(normal);

            meshBuilder.Vertices.Add(offset + widthDir);
            meshBuilder.UVs.Add(new Vector2(1.0f, 0.0f));
            meshBuilder.Normals.Add(normal);

            //we don't know how many verts the meshBuilder is up to, but we only care about the four we just added:
            int baseIndex = meshBuilder.Vertices.Count - 4;

            meshBuilder.AddTriangle(baseIndex, baseIndex + 1, baseIndex + 2);
            meshBuilder.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 3);
        }
Esempio n. 15
0
        public IOReadResult ReadFile(Stream stream, IMeshBuilder builder, ReadOptions options, ParsingMessagesHandler messages)
        {
            // detect binary STL
            //BinaryReader binReader = new BinaryReader(stream);
            //byte[] header = binReader.ReadBytes(80);
            bool bIsBinary = Util.IsBinaryStream(stream, 500);

            // [RMS] Thingi10k includes some files w/ unicode string in ascii header...
            //   How can we detect this? can we check that each character is a character?
            //string sUTF8 = System.Text.Encoding.UTF8.GetString(header);
            //string sAscii = System.Text.Encoding.ASCII.GetString(header);
            //if (sUTF8.Contains("solid") == false && sAscii.Contains("solid") == false)
            //    bIsBinary = true;

            // if first 80 bytes contain non-text chars, probably a binary file
            //if (Util.IsTextString(header) == false)
            //    bIsBinary = true;
            //// if we don't see "solid" string in first 80 chars, probably binary
            //if (bIsBinary == false) {
            //    string sText = System.Text.Encoding.ASCII.GetString(header);
            //    if (sText.Contains("solid") == false)
            //        bIsBinary = true;
            //}

            stream.Seek(0, SeekOrigin.Begin);             // reset stream

            var reader = new STLReader();

            reader.warningEvent += messages;
            IOReadResult result = (bIsBinary) ?
                                  reader.Read(new BinaryReader(stream), options, builder) :
                                  reader.Read(new StreamReader(stream), options, builder);

            return(result);
        }
Esempio n. 16
0
        /// <summary>
        /// Builds a smooth surfaced grid with the origin in the bottom-left corner.
        /// </summary>
        /// <remarks>
        /// The grid is comprised of quads with no shared vertices, allowing flat shading.
        /// </remarks>
        /// <param name="meshBuilder">Mesh builder.</param>
        /// <param name="cellWidth">Cell width.</param>
        /// <param name="cellLength">Cell length.</param>
        /// <param name="segmentCount">Segment count.</param>
        /// <param name="heightFunc">Height func.</param>
        public static void BuildSmoothGrid(this IMeshBuilder meshBuilder, float cellWidth, float cellLength, int segmentCount, Func <int, int, float> heightFunc)
        {
            int baseIndex = 0;

            for (int i = 0; i < segmentCount; i++)
            {
                for (int j = 0; j < segmentCount; j++)
                {
                    var x = cellWidth * j;
                    var z = cellLength * i;

                    meshBuilder.Vertices.Add(new Vector3(x, heightFunc(j, i), z));
                    meshBuilder.Vertices.Add(new Vector3(x, heightFunc(j, i + 1), z + cellLength));
                    meshBuilder.Vertices.Add(new Vector3(x + cellWidth, heightFunc(j + 1, i + 1), z + cellLength));
                    meshBuilder.Vertices.Add(new Vector3(x + cellWidth, heightFunc(j + 1, i), z));

                    meshBuilder.Normals.Add(Vector3.up);
                    meshBuilder.Normals.Add(Vector3.up);
                    meshBuilder.Normals.Add(Vector3.up);
                    meshBuilder.Normals.Add(Vector3.up);

                    meshBuilder.AddTriangle(baseIndex, baseIndex + 1, baseIndex + 2);
                    meshBuilder.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 3);

                    baseIndex += 4;
                }
            }
        }
Esempio n. 17
0
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Model));
            Model         model;

            try {
                model = (Model)serializer.Deserialize(reader);
            } catch (Exception e) {
                return(new IOReadResult(IOCode.FileParsingError, $"XML parsing error: {e}"));
            }

            foreach (var @object in model.resources.objects)
            {
                var mesh   = @object.mesh;
                int meshId = builder.AppendNewMesh(false, false, false, true);
                var mapV   = new int[mesh.vertices.vertices.Length];
                for (int k = 0; k < mesh.vertices.vertices.Length; ++k)
                {
                    var vertex = mesh.vertices.vertices[k];
                    mapV[k] = builder.AppendVertex(vertex.x, vertex.y, vertex.z);
                }
                for (int j = 0; j < mesh.triangles.triangles.Length; ++j)
                {
                    var triangle = mesh.triangles.triangles[j];
                    builder.AppendTriangle(mapV[triangle.v1], mapV[triangle.v2], mapV[triangle.v3]);
                }
            }

            return(IOReadResult.Ok);
        }
Esempio n. 18
0
        public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder)
        {
            if (options.CustomFlags != null)
            {
                ParseArguments(options.CustomFlags);
            }

            /*byte[] header = */
            reader.ReadBytes(80);
            int totalTris = reader.ReadInt32();

            Objects = new List <STLSolid>();
            Objects.Add(new STLSolid());

            int    tri_size = 50;               // bytes
            IntPtr bufptr   = Marshal.AllocHGlobal(tri_size);
            var    tmp      = new stl_triangle();
            Type   tri_type = tmp.GetType();

            var tri_attribs = new DVector <short>();

            try
            {
                for (int i = 0; i < totalTris; ++i)
                {
                    byte[] tri_bytes = reader.ReadBytes(50);
                    if (tri_bytes.Length < 50)
                    {
                        break;
                    }

                    Marshal.Copy(tri_bytes, 0, bufptr, tri_size);
                    var tri = (stl_triangle)Marshal.PtrToStructure(bufptr, tri_type);

                    append_vertex(tri.ax, tri.ay, tri.az);
                    append_vertex(tri.bx, tri.by, tri.bz);
                    append_vertex(tri.cx, tri.cy, tri.cz);
                    tri_attribs.Add(tri.attrib);
                }
            }
            catch (Exception e)
            {
                return(new IOReadResult(IOCode.GenericReaderError, "exception: " + e.Message));
            }

            Marshal.FreeHGlobal(bufptr);

            if (Objects.Count == 1)
            {
                Objects[0].TriAttribs = tri_attribs;
            }

            foreach (STLSolid solid in Objects)
            {
                BuildMesh(solid, builder);
            }

            return(new IOReadResult(IOCode.Ok, ""));
        }
Esempio n. 19
0
        public IOReadResult ReadFile(Stream stream, IMeshBuilder builder, ReadOptions options, ParsingMessagesHandler messages)
        {
            var reader = new BinaryG3Reader();
            //reader.warningEvent += messages;
            IOReadResult result = reader.Read(new BinaryReader(stream), options, builder);

            return(result);
        }
Esempio n. 20
0
        public static void AssignRandomColorToVertices(this IMeshBuilder meshBuilder)
        {
            meshBuilder.AddMissingColors(Color.white);

            for (int i = 0; i < meshBuilder.Colors.Count; i++)
            {
                meshBuilder.Colors[i] = ColorHelper.RandomRGB();
            }
        }
Esempio n. 21
0
        public static void AssignColors(this IMeshBuilder meshBuilder, MeshBuilderAssignColorsDelegate colorFunc)
        {
            meshBuilder.Colors.Clear();

            for (int i = 0; i < meshBuilder.Vertices.Count; i++)
            {
                meshBuilder.AddColor(colorFunc(i, meshBuilder.Vertices[i]));
            }
        }
Esempio n. 22
0
        public static void AddMissingColors(this IMeshBuilder meshBuilder, Color color)
        {
            var numMissing = meshBuilder.Vertices.Count - meshBuilder.Colors.Count;

            for (int i = 0; i < numMissing; i++)
            {
                meshBuilder.Colors.Add(color);
            }
        }
Esempio n. 23
0
 unsafe int append_triangle(IMeshBuilder builder, Triangle t)
 {
     if (t.vIndices[0] < 0 || t.vIndices[1] < 0 || t.vIndices[2] < 0)
     {
         emit_warning(string.Format("[OBJReader] invalid triangle:  {0} {1} {2}",
                                    t.vIndices[0], t.vIndices[1], t.vIndices[2]));
         return(-1);
     }
     return(builder.AppendTriangle(t.vIndices[0], t.vIndices[1], t.vIndices[2]));
 }
 public IOReadResult ReadFile(string sFilename, IMeshBuilder builder, ReadOptions options, ParsingMessagesHandler messages)
 {
     try {
         using (FileStream stream = File.Open(sFilename, FileMode.Open, FileAccess.Read)) {
             return(ReadFile(stream, builder, options, messages));
         }
     } catch (Exception e) {
         return(new IOReadResult(IOCode.FileAccessError, "Could not open file " + sFilename + " for reading : " + e.Message));
     }
 }
Esempio n. 25
0
 int append_triangle(IMeshBuilder builder, Index3i tri)
 {
     if (tri.a < 0 || tri.b < 0 || tri.c < 0)
     {
         emit_warning(string.Format("[PLYReader] invalid triangle:  {0} {1} {2}",
                                    tri.a, tri.b, tri.c));
         return(-1);
     }
     return(builder.AppendTriangle(tri.a, tri.b, tri.c));
 }
Esempio n. 26
0
        public static IMeshSelection SelectAll(this IMeshBuilder meshBuilder)
        {
            var selection = new MeshSelection();

            for (int i = 0; i < meshBuilder.Vertices.Count; i++)
            {
                selection.Add(i);
            }

            return(selection);
        }
Esempio n. 27
0
        public static GameObject CreateGameObject(this IMeshBuilder meshBuilder, Material material)
        {
            var go           = new GameObject();
            var meshFilter   = go.AddComponent <MeshFilter>();
            var meshRenderer = go.AddComponent <MeshRenderer>();

            meshFilter.mesh       = meshBuilder.BuildMesh();
            meshRenderer.material = material;

            return(go);
        }
Esempio n. 28
0
 protected virtual void BuildMesh(STLSolid solid, IMeshBuilder builder)
 {
     if (RebuildStrategy == Strategy.IdenticalVertexWeld)
     {
         BuildMesh_IdenticalWeld(solid, builder);
     }
     else
     {
         BuildMesh_NoMerge(solid, builder);
     }
 }
Esempio n. 29
0
        /// <summary>
        /// Construct a MeshReader, optionally with default format handlers
        /// Initializes MeshBuilder to a DMesh3Builder
        /// </summary>
        public StandardMeshReader(bool bIncludeDefaultReaders = true)
        {
            Readers     = new List <MeshFormatReader>();
            MeshBuilder = new DMesh3Builder();

            if (bIncludeDefaultReaders)
            {
                Readers.Add(new OBJFormatReader());
                Readers.Add(new STLFormatReader());
                Readers.Add(new OFFFormatReader());
            }
        }
Esempio n. 30
0
 public static bool IsEmpty <TMaterial>(this IMeshBuilder <TMaterial> mesh)
 {
     if (mesh == null)
     {
         return(true);
     }
     if (mesh.Primitives.Count == 0)
     {
         return(true);
     }
     return(mesh.Primitives.All(prim => prim.IsEmpty()));
 }