Example #1
0
        public void Start()
        {
            Setup();

            var sw = Stopwatch.StartNew();
            model = ModelFactory.CreateTestObject();
            //model = ModelFactory.CreateFromFile("bunny.ply", 1000);
            model.FillColor = Color.Gray.ToArgb();
            model.LineColor = Color.Red.ToArgb();
            model.CalculateColors();

            //model = ModelFactory.CreateFromFile(@"C:\Users\Ruud\Desktop\Armadillo2.ply", 5);
            //model = ModelFactory.CreateFromFile(@"g:\Data\Projects\3D\3dconverter\models\horseasc.ply", 1000);
            //model = ModelFactory.CreateFromFile(@"g:\Data\Projects\3D\3dconverter\models\ateneav.ply", 0.1);
            //model = ModelFactory.CreateFromFile(@"g:\Data\Projects\3D\3dconverter\models\pots.ply", 1);
            //model = ModelFactory.CreateFromFile(@"g:\Data\Projects\3D\3dconverter\models\balls.ply", 1);
            Logger.Value("model load", sw.ElapsedMilliseconds);

            timerUpdate.Enabled = true;
        }
        public static Model CreateTestObject()
        {
            var model = new Model();
            model.Rotation = new Vector3(0, 0, 0);

            model.AddVertex(-100, 100, -100, 1);    // 0
            model.AddVertex(100, 100, -100, 0.9);   // 1
            model.AddVertex(-100, -100, -100, 0.8); // 2
            model.AddVertex(-100, 100, 100, 0.7);   // 3
            model.AddVertex(100, 100, 100, 0.6);    // 4
            model.AddVertex(-100, -100, 100, 0.5);  // 5
            model.AddVertex(100, -100, -100, 0.4);  // 6
            model.AddVertex(100, -100, 100, 0.3);   // 7
            model.AddVertex(0, 150, 0, 0.2);        // 8
            model.AddVertex(0, -50, 0, 0.1);        // 9

            model.AddTriangle(0, 1, 2);
            model.AddTriangle(1, 6, 2);
            model.AddTriangle(1, 4, 6);
            model.AddTriangle(4, 7, 6);
            model.AddTriangle(4, 3, 7);
            model.AddTriangle(3, 5, 7);
            model.AddTriangle(3, 0, 5);
            model.AddTriangle(0, 2, 5);

            model.AddTriangle(0, 8, 1);
            model.AddTriangle(1, 8, 4);
            model.AddTriangle(4, 8, 3);
            model.AddTriangle(3, 8, 0);

            model.AddTriangle(6, 9, 2);
            model.AddTriangle(2, 9, 5);
            model.AddTriangle(5, 9, 7);
            model.AddTriangle(7, 9, 6);

            model.CenterModel();

            return model;
        }
        public static Model CreateCube()
        {
            var model = new Model();
            model.Rotation = new Vector3(0, 0, 0); //new Vector3(81, 358, 351);

            model.AddVertex(-100, 100, -100);   // 0
            model.AddVertex(100, 100, -100);    // 1
            model.AddVertex(-100, -100, -100);  // 2
            model.AddVertex(-100, 100, 100);    // 3
            model.AddVertex(100, 100, 100);     // 4
            model.AddVertex(-100, -100, 100);   // 5
            model.AddVertex(100, -100, -100);   // 6
            model.AddVertex(100, -100, 100);    // 7

            //int? fillColor1 = Color.FromArgb(140, 140, 140).ToArgb();
            //int? fillColor2 = Color.FromArgb(120, 120, 120).ToArgb();
            //int? fillColor3 = Color.FromArgb(100, 100, 100).ToArgb();
            //int borderColor = Color.Red.ToArgb();

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[0],
            //    model.Vertices[1],
            //    model.Vertices[2],
            //    borderColor, fillColor1));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[1],
            //    model.Vertices[6],
            //    model.Vertices[2],
            //    borderColor, fillColor1));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[1],
            //    model.Vertices[4],
            //    model.Vertices[6],
            //    borderColor, fillColor2));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[4],
            //    model.Vertices[7],
            //    model.Vertices[6],
            //    borderColor, fillColor2));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[4],
            //    model.Vertices[3],
            //    model.Vertices[7],
            //    borderColor, fillColor1));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[3],
            //    model.Vertices[5],
            //    model.Vertices[7],
            //    borderColor, fillColor1));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[3],
            //    model.Vertices[0],
            //    model.Vertices[5],
            //    borderColor, fillColor2));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[0],
            //    model.Vertices[2],
            //    model.Vertices[5],
            //    borderColor, fillColor2));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[3],
            //    model.Vertices[4],
            //    model.Vertices[0],
            //    borderColor, fillColor3));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[4],
            //    model.Vertices[1],
            //    model.Vertices[0],
            //    borderColor, fillColor3));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[2],
            //    model.Vertices[6],
            //    model.Vertices[5],
            //    borderColor, fillColor3));

            //model.Triangles.Add(new Triangle(
            //    model.Vertices[6],
            //    model.Vertices[7],
            //    model.Vertices[5],
            //    borderColor, fillColor3));

            //model.CenterModel();

            return model;
        }
        /// <summary>
        /// Create model from PLY ascii file
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="scalar"></param>
        /// <returns></returns>
        public static Model CreateFromFile(string filename, double scalar = 1)
        {
            var model = new Model();

            string filepath = Path.Combine(Application.StartupPath, "Resources", filename);
            var lines = File.ReadLines(filepath);

            int readmode = 0;       // 0=header, 1=vertices, 2=triangles, 3=done
            int vertexcount = 0;
            int trianglecount = 0;

            int readvertices = 0;
            int readtriangles = 0;

            int bcolor = Color.Red.ToArgb();
            int? fcolor = Color.Gray.ToArgb();

            foreach (string line in lines)
            {
                if (readmode == 0)
                {
                    if (line.StartsWith("element vertex"))
                    {
                        string rev = ReverseString(line.Trim());
                        string value = ReverseString(rev.Substring(0, rev.IndexOf(" ")));
                        vertexcount = Convert.ToInt32(value);
                    }

                    if (line.StartsWith("element face"))
                    {
                        string rev = ReverseString(line.Trim());
                        string value = ReverseString(rev.Substring(0, rev.IndexOf(" ")));
                        trianglecount = Convert.ToInt32(value);
                    }

                    if (line.StartsWith("end_header"))
                    {
                        readmode = 1;
                        continue;
                    }
                }

                if (readmode == 1)
                {
                    double[] values = line.Trim().Split(' ').Select(x => Math.Round(Convert.ToDouble(x) * scalar)).ToArray();
                    model.AddVertex(values[0], values[1], values[2], (values.Length >= 5) ? (values[4] / scalar) * 2 : 1);

                    if (++readvertices >= vertexcount)
                    {
                        readmode = 2;
                        continue;
                    }
                }

                if (readmode == 2)
                {
                    int[] values = line.Trim().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
                    model.AddTriangle(values[1], values[2], values[3]);

                    if (++readtriangles >= trianglecount)
                    {
                        readmode = 3;
                        continue;
                    }
                }
            }

            model.CenterModel();

            return model;
        }
        /// <summary>
        /// Draw a (filled) triangle to the framebuffer
        /// </summary>
        /// <remarks>http://www-users.mat.uni.torun.pl/~wrona/3d_tutor/tri_fillers.html</remarks>
        /// <param name="vertices"></param>
        /// <param name="color"></param>
        /// <param name="fill"></param>
        public void DrawTriangle(Model model, Triangle triangle)
        {
            Vertex[] sortedv = new Vertex[3];
            triangle.Vertices.CopyTo(sortedv, 0);

            Array.Sort(sortedv, delegate(Vertex v1, Vertex v2)
            {
                return v1.Projected.Y.CompareTo(v2.Projected.Y);
            });

            Vector3 a = sortedv[0].Projected;
            Vector3 b = sortedv[1].Projected;
            Vector3 c = sortedv[2].Projected;

            double dx1 = (b.Y - a.Y > 0) ? (double)(b.X - a.X) / (double)(b.Y - a.Y) : 0;
            double dx2 = (c.Y - a.Y > 0) ? (double)(c.X - a.X) / (double)(c.Y - a.Y) : 0;
            double dx3 = (c.Y - b.Y > 0) ? (double)(c.X - b.X) / (double)(c.Y - b.Y) : 0;

            double ex = (double)a.X;
            double sx = (double)a.X;
            double sy = (double)a.Y;

            for (; sy <= b.Y; sy++, sx += dx1, ex += dx2)
            {
                DrawTriangleScanline(sx, ex, sy, model.LineColor, triangle.ShadedFillColor);
            }

            sx = b.X;

            for (; sy <= c.Y; sy++, sx += dx3, ex += dx2)
            {
                DrawTriangleScanline(sx, ex, sy, model.LineColor, triangle.ShadedFillColor);
            }
        }
        /// <summary>
        /// Draw a mesh model after it has been processed (transformed and projected)
        /// </summary>
        /// <param name="model"></param>
        public void DrawModel(Model model)
        {
            //foreach (Vertex v in model.Vertices)
            //{
            //    DrawPixel(v.Projected, Color.Red.ToArgb());
            //}

            int c = 0;

            foreach (Triangle t in model.Triangles.Where(x => !x.IsBackFaced))
            {
                DrawTriangle(model, t);
                c++;
            }

            Logger.Value("triangles drawn", c);
        }