Пример #1
0
        private static void calculateAndSetNormalForTri(ref TriangleFace triangleFace, Mesh mesh)
        {
            //if the normal list is empty for this mesh or null - set it to be the same size
            //as the list of verts. we'll generate on normal per vert.
            if (mesh.VertexNormalData == null || mesh.VertexNormalData.Count < 1)
            {
                mesh.VertexNormalData = Enumerable.Repeat(Vector3.Zero, mesh.VertexData.Count()).ToList();
            }

            var triVerts = triangleFace.vertIndexList.Select(ind => mesh.VertexData[ind - 1].ToVector3()).ToArray();
            var a        = triVerts[0];
            var b        = triVerts[1];
            var c        = triVerts[2];

            var calculatedNormal = Vector3.Normalize(Vector3.Cross((b - a), (c - a)));
            //temporarily we will add these normals to the normals array - we'll average them later.
            var inds = new List <int>();

            foreach (var vertIndex in triangleFace.vertIndexList)
            {
                mesh.VertexNormalData[vertIndex - 1] = calculatedNormal;
            }
            //copy the array.
            //TODO because this is a struct, it does not end up modifying the tris we set in mesh...
            //bad design.
            triangleFace.NormalIndexList = triangleFace.vertIndexList.ToArray();
        }
Пример #2
0
    public static (List <TriangleFace>, Dictionary <Vector3, List <TriangleFace> >) createTriangles(int[] triangles, Vector3[] vertices)
    {
        var mappedTriangles   = new List <TriangleFace>();
        var vertexToTriangles = new Dictionary <Vector3, List <TriangleFace> >();

        for (int i = 0; i < triangles.Length; i += 3)
        {
            var v1       = vertices[triangles[i]];
            var v2       = vertices[triangles[i + 1]];
            var v3       = vertices[triangles[i + 2]];
            var triangle = new TriangleFace(v1, v2, v3);

            mappedTriangles.Add(triangle);
            foreach (Vector3 v in new ArrayList()
            {
                v1, v2, v3
            })
            {
                List <TriangleFace> trianglesOfVertex;
                if (!vertexToTriangles.ContainsKey(v))
                {
                    trianglesOfVertex = new List <TriangleFace>();
                    vertexToTriangles.Add(v, trianglesOfVertex);
                }
                else
                {
                    trianglesOfVertex = vertexToTriangles[v];
                }
                trianglesOfVertex.Add(triangle);
            }
        }

        return(mappedTriangles, vertexToTriangles);
    }
 public void addAdjacent(TriangleFace adj)
 {
     if (this.isAdjacent(adj))
     {
         this.adjacent.Add(adj);
         adj.adjacent.Add(this);
     }
 }
Пример #4
0
        public static Vector3 BaryCoordinates2(int x, int y, TriangleFace triangle, Vector2[] vectors)
        {
            var pt1 = vectors[triangle.vertIndexList[0] - 1];
            var pt2 = vectors[triangle.vertIndexList[1] - 1];
            var pt3 = vectors[triangle.vertIndexList[2] - 1];

            return(BaryCoordinates2(x, y, pt1, pt2, pt3));
        }
Пример #5
0
        public OBJFile(FileStream stream)
        {
            this.vertices      = new List <VertexPosition>();
            this.triangleFaces = new List <TriangleFace>();
            this.quadFaces     = new List <QuadFace>();
            StreamReader reader = new StreamReader(stream);
            string       text   = reader.ReadToEnd();

            text = text.Replace("\r", "");
            text = text.Replace('.', ',');
            string[] lines = text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string line in lines)
            {
                string[] words = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                //if (words[0] == "v")
                //{
                //    float x = float.Parse(words[1]);
                //    float y = float.Parse(words[2]);
                //    float z = float.Parse(words[3]);
                //    VertexPosition coord = new VertexPosition(x, y, z);
                //    this.vertices.Add(coord);
                //}
                switch (words[0])
                {
                case "v":
                    float          x     = float.Parse(words[1]);
                    float          y     = float.Parse(words[2]);
                    float          z     = float.Parse(words[3]);
                    VertexPosition coord = new VertexPosition(x, y, z);
                    this.vertices.Add(coord);
                    break;

                case "f":
                    if (words.Length == 5)
                    {
                        int      a4    = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                        int      b4    = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                        int      c4    = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                        int      d4    = int.Parse(words[4].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                        QuadFace face4 = new QuadFace(a4, b4, c4, d4);
                        this.quadFaces.Add(face4);
                        break;
                    }
                    int          a    = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                    int          b    = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                    int          c    = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                    TriangleFace face = new TriangleFace(a, b, c);
                    this.triangleFaces.Add(face);
                    break;
                }
            }
            this.mesh               = new MeshBase();
            this.mesh.QuadFaces     = this.quadFaces;
            this.mesh.TriangleFaces = this.triangleFaces;
            this.mesh.Vertices      = this.vertices;
            string[] path = stream.Name.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
            this.mesh.Name = HeadFile.ReplaceExtention(path[path.Length - 1], "");
        }
Пример #6
0
 public OBJFile(FileStream stream)
 {
     this.vertices = new List<VertexPosition>();
     this.triangleFaces = new List<TriangleFace>();
     this.quadFaces = new List<QuadFace>();
     StreamReader reader = new StreamReader(stream);
     string text = reader.ReadToEnd();
     text = text.Replace("\r", "");
     text = text.Replace('.', ',');
     string[] lines = text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
     foreach (string line in lines)
     {
         string[] words = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
         //if (words[0] == "v")
         //{
         //    float x = float.Parse(words[1]);
         //    float y = float.Parse(words[2]);
         //    float z = float.Parse(words[3]);
         //    VertexPosition coord = new VertexPosition(x, y, z);
         //    this.vertices.Add(coord);
         //}
         switch (words[0])
         {
             case "v":
                 float x = float.Parse(words[1]);
                 float y = float.Parse(words[2]);
                 float z = float.Parse(words[3]);
                 VertexPosition coord = new VertexPosition(x, y, z);
                 this.vertices.Add(coord);
                 break;
             case "f":
                 if (words.Length == 5)
                 {
                     int a4 = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                     int b4 = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                     int c4 = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                     int d4 = int.Parse(words[4].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                     QuadFace face4 = new QuadFace(a4, b4, c4, d4);
                     this.quadFaces.Add(face4);
                     break;
                 }      
                 int a = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                 int b = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                 int c = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                 TriangleFace face = new TriangleFace(a, b, c);
                 this.triangleFaces.Add(face);
                 break;
         }
     }
     this.mesh = new MeshBase();
     this.mesh.QuadFaces = this.quadFaces;
     this.mesh.TriangleFaces = this.triangleFaces;
     this.mesh.Vertices = this.vertices;
     string[] path =  stream.Name.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
     this.mesh.Name = HeadFile.ReplaceExtention(path[path.Length - 1],"");
 }
Пример #7
0
        private static (Vector3, Vector3) calculateTangetSpaceForTri(TriangleFace triangleFace, Mesh mesh)
        {
            var triVerts = triangleFace.vertIndexList.Select(ind => mesh.VertexData[ind - 1].ToVector3()).ToArray();
            var uvs      = triangleFace.UVIndexList.Select(ind => mesh.VertexUVData[ind - 1]).ToArray();
            var normals  = triangleFace.NormalIndexList.Select(ind => mesh.VertexNormalData[ind - 1]).ToArray();


            var p0 = triVerts[0];
            var p1 = triVerts[1];
            var p2 = triVerts[2];

            var tex0 = uvs[0];
            var tex1 = uvs[1];
            var tex2 = uvs[2];

            var norm0 = normals[0];
            var norm1 = normals[1];
            var norm2 = normals[2];

            var q1 = Vector3.Subtract(p1, p0);
            var q2 = Vector3.Subtract(p2, p0);

            var temp1 = Vector2.Subtract(tex1, tex0);
            var temp2 = Vector2.Subtract(tex2, tex0);

            var s = new Vector2(temp1.X, temp2.X);
            var t = new Vector2(temp1.Y, temp2.Y);

            //TODO are uv coords incorrect?
            var recip = 1.0 / ((temp1.X * temp2.Y) - (temp1.Y * temp2.X));

            if (double.IsInfinity(recip))
            {
                recip = 1.0;
            }

            //these seem exactly the same...

            var udir = Vector3.Multiply((float)recip, Vector3.Subtract(Vector3.Multiply(temp2.Y, q1), (Vector3.Multiply(temp1.Y, q2))));
            var vdir = Vector3.Multiply((float)recip, Vector3.Subtract(Vector3.Multiply(temp1.X, q2), (Vector3.Multiply(temp2.X, q1))));

            //var udir = new Vector3((t.Y * q1.X - t.X * q2.X) * recip, (t.Y * q1.Y - t.X * q2.Y) * recip, (t.Y * q1.Z - t.X * q2.Z) * recip);
            //var vdir = new Vector3((s.X * q2.X - s.Y * q1.X) * recip, (s.X * q2.Y - s.Y * q1.Y) * recip, (s.X * q2.Z - s.Y * q1.Z) * recip);

            if (float.IsInfinity(udir.X) || float.IsInfinity(udir.Y) || float.IsInfinity(udir.Z) ||
                float.IsInfinity(vdir.X) || float.IsInfinity(vdir.Y) || float.IsInfinity(vdir.Z))
            {
                throw new ArgumentException();
            }

            return(udir, vdir);
        }
Пример #8
0
        public static bool pixelIsInsideTriangle(int x, int y, TriangleFace triangle, Vector3[] vectors)
        {
            var pt1 = vectors[triangle.vertIndexList[0] - 1];
            var pt2 = vectors[triangle.vertIndexList[1] - 1];
            var pt3 = vectors[triangle.vertIndexList[2] - 1];

            var barycenter = TriangleExtensions.BaryCoordinates2(x, y, pt1.ToVector2(), pt2.ToVector2(), pt3.ToVector2());

            //only in the triangle if coefs are all positive.

            if (barycenter.X < 0 || barycenter.X >= 1f || barycenter.Y < 0 || barycenter.Y >= 1f || barycenter.Z < 0 || barycenter.Z >= 1f)
            {
                return(false);
            }
            return(true);
        }
Пример #9
0
    public static List <TriangleFace> extractFaces(List <TriangleFace> faces, int numToExtract)
    {
        if (faces == null || numToExtract > faces.Count || numToExtract <= 0)
        {
            throw new Exception("The list of faces doesn't have enough faces to extract");
        }

        List <TriangleFace>    adjPoll        = new List <TriangleFace>();
        HashSet <TriangleFace> extractedFaces = new HashSet <TriangleFace>();

        TriangleFace face = faces[UnityEngine.Random.Range(0, faces.Count)];

        extractOneFace(faces, extractedFaces, adjPoll, face);

        for (int i = 1; i < numToExtract; i++)
        {
            bool foundOne = false;
            foreach (TriangleFace adj in adjPoll)
            {
                if (!extractedFaces.Contains(adj) && faces.Contains(adj))
                {
                    foundOne = true;
                    extractOneFace(faces, extractedFaces, adjPoll, adj);
                    Shuffle(adjPoll);
                    break;
                }
            }

            if (!foundOne)
            {
                throw new Exception("Wasn't able to find a connected");
            }
        }

        return(new List <TriangleFace>(extractedFaces));
    }
Пример #10
0
 static void extractOneFace(List <TriangleFace> allFaces, HashSet <TriangleFace> extractedFaces, List <TriangleFace> adjPoll, TriangleFace face)
 {
     extractedFaces.Add(face);
     allFaces.Remove(face);
     adjPoll.Remove(face);
     adjPoll.AddRange(face.adjacent);
 }
 public bool isAdjacent(TriangleFace adj)
 {
     return(adj != null && this.hasEqualVertices(adj.vertices, 2));
 }
        //
        // Steps Extrude
        //

        public static Surface Extrude(this Polyline curve, int steps, double height, double taper)
        {
            Vector3F normal = Vector3F.Undefined;

            taper = (taper < 0 ? -1f : 1f) - taper;

            if (curve.Points.Count < 2)
            {
                return(null);
            }

            if (steps < 2)
            {
                return(null);
            }

            steps = ((steps / 4) + ((steps % 4) != 0 ? 4 : 0)) * 4;

            if (curve.Points.Count > 2)
            {
                normal = Vector3F.CrossProduct(new Vector3F(curve.Points[0].Point, curve.Points[1].Point), new Vector3F(curve.Points[0].Point, curve.Points[2].Point));
            }

            if (normal.IsUndefined)
            {
                normal = new Vector3F(0, 0, -1);
            }

            normal = normal.Unit();

            Surface surface = new Surface();

            for (double i = 0; i <= 1; i = i + 1 / (double)steps)
            {
                surface.Points.Add(curve.GetParametricPoint(i));
            }

            int num = 0;

            Point3F sumBase   = new Point3F(0, 0, 0);
            Point3F sumHeight = new Point3F(0, 0, 0);

            for (double j = 0; j <= 1; j = j + 1 / (double)steps)
            {
                Point3F item = surface.Points[num];

                sumBase = sumBase.Add(item);

                item.X = (item.X * taper) + (normal.X * height);
                item.Y = (item.Y * taper) + (normal.Y * height);
                item.Z = item.Z + (normal.Z * height);

                sumHeight = sumHeight.Add(item);

                surface.Points.Add(item);

                num++;
            }

            sumBase.DivideBy(num);
            sumHeight.DivideBy(num);

            TriangleFace[] faces = new TriangleFace[(num + (curve.Closed ? 1 : 0)) * 2];

            int k;

            for (k = 0; k < num - 1; k++)
            {
                faces [k * 2]     = new TriangleFace(k, k + 1, k + num + 1);
                faces [k * 2 + 1] = new TriangleFace(k, k + num + 1, k + num);
            }

            if (curve.Closed)
            {
                faces [k * 2]     = new TriangleFace(num - 1, 0, num);
                faces [k * 2 + 1] = new TriangleFace(num - 1, num, 2 * num - 1);
            }

            surface.Faces = faces;

            return(surface);
        }
Пример #13
0
 public void VerticesAreNotSimilar()
 {
     Assert.False(TriangleFace.areVerticesEqual(new Vector3(2, 1, 1), new Vector3(1, 1, 1)));
 }
Пример #14
0
 public void VerticesAreSimilar()
 {
     Assert.True(TriangleFace.areVerticesEqual(new Vector3(1, 1, 1), new Vector3(1, 1, 1)));
 }
Пример #15
0
 public void Setup()
 {
     t1 = new TriangleFace(new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 1, 0));
     t2 = new TriangleFace(new Vector3(0, 0, 0), new Vector3(1, 1, 0), new Vector3(0, 1, 0));
     t3 = new TriangleFace(new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 2, 0));
 }