public void ExportMesh(MeshGraph mg)
        {
            StreamWriter rd = File.CreateText(FileName);

            rd.WriteLine("g CubeSharp_Model");

            foreach (MeshVertex v in mg.Vertices)
            {
                rd.WriteLine("v " + v.Position.X + " " +
                             v.Position.Y + " " + v.Position.Z);
            }

            foreach (MeshFacet f in mg.Facets)
            {
                var n = f.Normal;

                rd.Write("vn ");
                rd.Write(n[0] + " " + n[1] + " " + n[2]);
                rd.WriteLine();

                rd.Write("f ");
                foreach (MeshVertex v in f.Vertices)
                {
                    rd.Write(v.Index + 1);
                    rd.Write("//");
                    rd.Write(f.Index + 1); // vn actually
                    rd.Write(" ");
                }
                rd.WriteLine();
            }

            rd.Close();
        }
        public override void AddMeshGraphUpon(
            ref MeshGraph mg, bool selected = true)
        {
            float l = Length / 2, w = Width / 2, h = Height / 2;

            MeshVertex[] vs = new MeshVertex[8];
            vs[0] = mg.AddVertex(l, h, w);
            vs[1] = mg.AddVertex(l, h, -w);
            vs[2] = mg.AddVertex(l, -h, w);
            vs[3] = mg.AddVertex(l, -h, -w);
            vs[4] = mg.AddVertex(-l, h, w);
            vs[5] = mg.AddVertex(-l, h, -w);
            vs[6] = mg.AddVertex(-l, -h, w);
            vs[7] = mg.AddVertex(-l, -h, -w);

            mg.AddFacet(vs[2], vs[3], vs[1], vs[0]);
            mg.AddFacet(vs[4], vs[5], vs[7], vs[6]);
            mg.AddFacet(vs[1], vs[5], vs[4], vs[0]);
            mg.AddFacet(vs[2], vs[6], vs[7], vs[3]);
            mg.AddFacet(vs[0], vs[4], vs[6], vs[2]);
            mg.AddFacet(vs[3], vs[7], vs[5], vs[1]);

            if (selected)
            {
                foreach (MeshVertex v in vs)
                {
                    SelectAdjacency(v);
                }
            }
        }
        MeshFacet ParseFacet(String s, MeshGraph mg)
        {
            String[] items = s.Trim().Split(' ')
                             .Select(x => x.Trim())
                             .Where(x => x.Length > 0).ToArray();

            List <int> nums = new List <int>();

            foreach (String i in items)
            {
                String[] snums = i.Split('/');
                nums.Add(int.Parse(snums[0]));
            }

            var vs = nums.Select(n => vertices[n - 1]).ToArray();

            try {
                return(mg.AddFacet(vs));
            } catch (Exception) {
                try {
                    return(mg.AddFacet(vs.Reverse().ToArray()));
                } catch (Exception e2) {
                    Console.WriteLine(e2.Message);
                    Console.WriteLine(e2.StackTrace);
                }
            }

            return(null);
        }
        public override void AddMeshGraphUpon(
            ref MeshGraph mg, bool selected = true)
        {
            StreamReader rd = File.OpenText(FileName);

            vertices    = new List <MeshVertex>();
            accum_point = new Vector3(0, 0, 0);

            while (!rd.EndOfStream)
            {
                String s = rd.ReadLine();

                if (s.StartsWith("v "))
                {
                    ParseVertex(s.Substring(2), mg);
                }

                if (s.StartsWith("f "))
                {
                    ParseFacet(s.Substring(2), mg);
                }
            }

            foreach (MeshVertex v in vertices)
            {
                SelectAdjacency(v);
            }
        }
        MeshVertex ParseVertex(String s, MeshGraph mg)
        {
            Vector3 pos = new Vector3(0, 0, 0);

            String[] nums = s.Trim().Split(' ')
                            .Select(x => x.Trim())
                            .Where(x => x.Length > 0).ToArray();

            if (nums.Length < 3)
            {
                throw new Exception("Bad vertex format");
            }
            pos[0] = float.Parse(nums[0]);
            pos[1] = float.Parse(nums[1]);
            pos[2] = float.Parse(nums[2]);

            if (nums.Length == 4)
            {
                pos /= float.Parse(nums[3]);
            }

            accum_point += pos;

            MeshVertex mv = mg.AddVertex(pos);

            vertices.Add(mv);
            return(mv);
        }
        public MeshGraph GenerateMeshGraph()
        {
            MeshGraph mg = new MeshGraph();

            AddMeshGraphUpon(ref mg, false);
            return(mg);
        }
        protected TransformerRenderer(ObjectType t)
        {
            SetSource(vertex_shader_source, "", fragment_shader_source);

            type = (int)t;
            axis = new MeshGraph();

            axisColors    = new Vector4[3];
            axisColors[0] = new Vector4(1, 0, 0, 1);
            axisColors[1] = new Vector4(0, 1, 0, 1);
            axisColors[2] = new Vector4(0, 0, 1, 1);
        }
        public MeshGraph Clone()
        {
            MeshGraph mg = new MeshGraph();

            mg.triangles = this.triangles;

            foreach (MeshVertex v in vertices)
            {
                MeshVertex new_v = new MeshVertex(v.Position);
                new_v.SetGraphInfo(mg, mg.vertices.Count);
                mg.vertices.Add(new_v);
            }

            foreach (MeshEdge e in edges)
            {
                MeshEdge new_e = new MeshEdge(mg.Eqv(e.V1), mg.Eqv(e.V2));
                new_e.SetGraphInfo(mg, mg.edges.Count);
                mg.edges.Add(new_e);
            }

            foreach (MeshFacet f in facets)
            {
                MeshFacet new_f = new MeshFacet();
                foreach (MeshVertex v in f.vertices)
                {
                    new_f.vertices.Add(mg.Eqv(v));
                }
                new_f.SetGraphInfo(mg, mg.facets.Count);
                mg.facets.Add(new_f);
            }

            // Maintain adjacency cache
            foreach (MeshEdge e in mg.edges)
            {
                MeshEdge old_e = this.Eqv(e);
                e.f1 = mg.Eqv(old_e.f1);
                e.f2 = mg.Eqv(old_e.f2);
            }

            foreach (MeshVertex v in mg.vertices)
            {
                MeshVertex old_v = this.Eqv(v);
                foreach (var entry in old_v.adjacency)
                {
                    v.adjacency.Add(mg.Eqv(entry.Key), mg.Eqv(entry.Value));
                }
            }

            return(mg);
        }
        public override void AddMeshGraphUpon(
            ref MeshGraph mg, bool selected = true)
        {
            MeshVertex vorg   = mg.AddVertex(0, 0, 0);
            MeshVertex vhead  = mg.AddVertex(0, 0, Length);
            MeshVertex vhead1 = mg.AddVertex(HeadSize / 8, HeadSize / 8, Length - HeadSize);
            MeshVertex vhead2 = mg.AddVertex(-HeadSize / 8, HeadSize / 8, Length - HeadSize);
            MeshVertex vhead3 = mg.AddVertex(-HeadSize / 8, -HeadSize / 8, Length - HeadSize);
            MeshVertex vhead4 = mg.AddVertex(HeadSize / 8, -HeadSize / 8, Length - HeadSize);

            mg.AddEdge(vorg, vhead);
            mg.AddFacet(vhead1, vhead2, vhead);
            mg.AddFacet(vhead2, vhead3, vhead);
            mg.AddFacet(vhead3, vhead4, vhead);
            mg.AddFacet(vhead4, vhead1, vhead);
        }
        public override void AddMeshGraphUpon(
            ref MeshGraph mg, bool selected = true)
        {
            MeshVertex[,] vs = new MeshVertex[VSubdivision - 1, USubdivision];
            for (int v = 1; v < VSubdivision; v++)
            {
                for (int u = 0; u < USubdivision; u++)
                {
                    double a = Math.PI * 2 * u / USubdivision;
                    double b = -Math.PI * v / VSubdivision + Math.PI / 2;
                    vs[v - 1, u] = mg.AddVertex(
                        (float)(Radius * Math.Cos(a) * Math.Cos(b)),
                        (float)(Radius * Math.Sin(b)),
                        -(float)(Radius * Math.Sin(a) * Math.Cos(b)));
                }
            }

            for (int v = 0; v < VSubdivision - 2; v++)
            {
                for (int u = 0; u < USubdivision; u++)
                {
                    mg.AddFacet(vs[v, u], vs[v + 1, u],
                                vs[v + 1, (u + 1) % USubdivision], vs[v, (u + 1) % USubdivision]);
                }
            }

            MeshVertex top = mg.AddVertex(0, Radius, 0),
                       btm = mg.AddVertex(0, -Radius, 0);

            for (int u = 0; u < USubdivision; u++)
            {
                mg.AddFacet(top, vs[0, u], vs[0, (u + 1) % USubdivision]);
                mg.AddFacet(vs[VSubdivision - 2, (u + 1) % USubdivision],
                            vs[VSubdivision - 2, u], btm);
            }

            foreach (MeshVertex v in vs)
            {
                SelectAdjacency(v);
            }
            SelectAdjacency(top);
            SelectAdjacency(btm);
        }
        public SelectionBoxRenderer()
        {
            SetSource(vertex_shader_source, "", fragment_shader_source);

            plane = new MeshGraph();
            var v1 = plane.AddVertex(0, 0, 0);
            var v2 = plane.AddVertex(0, 1, 0);
            var v3 = plane.AddVertex(1, 1, 0);
            var v4 = plane.AddVertex(1, 0, 0);

            plane.AddFacet(v1, v2, v3, v4);
            plane.FacetData.UpdateData();

            line = new MeshGraph();
            var l1 = line.AddVertex(0, 0, 0);
            var l2 = line.AddVertex(1, 1, 0);

            line.AddEdge(l1, l2);
            line.EdgeData.UpdateData();
        }
        public GridRenderer()
        {
            SetSource(vertex_shader_source, "", fragment_shader_source);

            grid = new MeshGraph();
            for (int i = -50; i < 50; i++)
            {
                MeshVertex v1 = grid.AddVertex(i, 0, -50);
                MeshVertex v2 = grid.AddVertex(i, 0, 50);
                grid.AddEdge(v1, v2);
            }

            for (int i = -50; i < 50; i++)
            {
                MeshVertex v1 = grid.AddVertex(-50, 0, i);
                MeshVertex v2 = grid.AddVertex(50, 0, i);
                grid.AddEdge(v1, v2);
            }

            grid.EdgeData.UpdateData();
        }
        private void CubeSharp_Load(object sender, EventArgs e)
        {
            Console.WriteLine(GL.GetString(StringName.Version));

            wfrdr = new WireframeRenderer();
            srdr  = new ShadedRenderer();
            crdr  = new ObjectMapRenderer();
            grdr  = new GridRenderer();
            tcrdr = new TranslationTransformerRenderer();
            scrdr = new ScalingTransformerRenderer();
            rcrdr = new RotationTransformerRenderer();
            sbrdr = new SelectionBoxRenderer();

            Model      = new BoxMeshFactory().GenerateMeshGraph();
            MainCamera = new Camera();
            obj_map    = new RenderTarget(PixelType.Float, Viewport);

            Model.EdgeData.UpdateData();
            Model.VertexData.UpdateData();
            Model.FacetData.UpdateData();
            MainCamera.Tf.RotateY(-Math.PI / 6);
            MainCamera.Tf.RotateX(-Math.PI / 6);
            MainCamera.Tf.Translate(0, 0, 5);

            wfrdr.Camera = MainCamera;
            wfrdr.Model  = Model;
            srdr.Camera  = MainCamera;
            srdr.Model   = Model;
            crdr.Camera  = MainCamera;
            crdr.Model   = Model;
            grdr.Camera  = MainCamera;
            tcrdr.Camera = MainCamera;
            tcrdr.Model  = Model;
            scrdr.Camera = MainCamera;
            scrdr.Model  = Model;
            rcrdr.Camera = MainCamera;
            rcrdr.Model  = Model;

            CubeSharp_Resize(null, null);
        }
        public override void AddMeshGraphUpon(
            ref MeshGraph mg, bool selected = true)
        {
            MeshVertex[,] vs = new MeshVertex[USubdivision + 1, VSubdivision + 1];

            for (int i = 0; i <= VSubdivision; i++)
            {
                for (int j = 0; j <= USubdivision; j++)
                {
                    vs[i, j] = mg.AddVertex(Size * j / USubdivision - Size / 2,
                                            0, -Size * i / VSubdivision - Size / 2);
                }
            }

            for (int i = 0; i < VSubdivision; i++)
            {
                for (int j = 0; j < USubdivision; j++)
                {
                    mg.AddFacet(vs[i, j], vs[i, j + 1], vs[i + 1, j + 1], vs[i + 1, j]);
                }
            }
        }
        public override void AddMeshGraphUpon(
            ref MeshGraph mg, bool selected = true)
        {
            MeshVertex[] topf = new MeshVertex[Subdivision];
            MeshVertex[] btmf = new MeshVertex[Subdivision];

            for (int i = 0; i < Subdivision; i++)
            {
                double a = Math.PI * 2 * i / Subdivision;
                topf[i] = mg.AddVertex(Radius * (float)Math.Cos(a),
                                       Height / 2, -Radius * (float)Math.Sin(a));
                btmf[i] = mg.AddVertex(Radius * (float)Math.Cos(a),
                                       -Height / 2, -Radius * (float)Math.Sin(a));
            }

            mg.AddFacet(topf);
            mg.AddFacet(btmf.Reverse().ToArray());

            for (int i = 0; i < Subdivision; i++)
            {
                mg.AddFacet(topf[i], btmf[i],
                            btmf[(i + 1) % Subdivision], topf[(i + 1) % Subdivision]);
            }
        }
        public void CreateTriangle()
        {
            MeshVertex v1 = new MeshVertex(1, 0, 1);
            MeshVertex v2 = new MeshVertex(2, 1, 0);
            MeshVertex v3 = new MeshVertex(1, 3, 1);

            MeshGraph mg = new MeshGraph();

            mg.AddVertex(v1);
            mg.AddVertex(v2);
            mg.AddVertex(v3);

            MeshEdge  e1 = mg.AddEdge(v1, v2);
            MeshEdge  e2 = mg.AddEdge(v3, v2);
            MeshFacet f  = mg.AddFacet(v1, v2, v3);

            CollectionAssert.Contains(mg.Vertices, v1);
            CollectionAssert.Contains(mg.Vertices, v2);
            CollectionAssert.Contains(mg.Vertices, v3);
            Assert.AreEqual(v1.EdgeConnecting(v2), v2.EdgeConnecting(v1), "", e1);
            Assert.AreEqual(v3.EdgeConnecting(v2), v2.EdgeConnecting(v3), "", e2);

            CollectionAssert.Contains(mg.Edges, v1.EdgeConnecting(v2));
            CollectionAssert.Contains(mg.Edges, v2.EdgeConnecting(v3));
            CollectionAssert.Contains(mg.Edges, v3.EdgeConnecting(v1));
            CollectionAssert.Contains(e1.AdjacencyFacets, f);
            CollectionAssert.Contains(e1.Endpoints, v1);

            CollectionAssert.Contains(f.Vertices, v1);
            CollectionAssert.Contains(f.Vertices, v2);
            CollectionAssert.Contains(f.Vertices, v3);
            CollectionAssert.Contains(f.Edges, v1.EdgeConnecting(v2));
            CollectionAssert.Contains(f.Edges, v2.EdgeConnecting(v3));
            CollectionAssert.Contains(f.Edges, v3.EdgeConnecting(v1));

            {   // Remove the facet
                MeshGraph rm  = mg.Clone();
                MeshFacet rmf = rm.Eqv(f);
                rm.RemoveFacet(rmf);

                CollectionAssert.DoesNotContain(rm.Facets, rmf);
                CollectionAssert.DoesNotContain(
                    rm.Eqv(e1).AdjacencyFacets, rmf);
                CollectionAssert.DoesNotContain(
                    rm.Eqv(e2).AdjacencyFacets, rmf);
            }

            {   // Remove an edge
                MeshGraph rm  = mg.Clone();
                MeshEdge  rme = rm.Eqv(e1);
                MeshFacet rmf = rm.Eqv(f);
                rm.RemoveEdge(rme);

                CollectionAssert.DoesNotContain(rm.Edges, rme);
                CollectionAssert.DoesNotContain(rm.Facets, rmf);
                CollectionAssert.DoesNotContain(
                    rme.AdjacencyFacets, rmf);
                CollectionAssert.DoesNotContain(
                    rm.Eqv(e2).AdjacencyFacets, rmf);
            }

            {   // Remove an vertex
                MeshGraph  rm   = mg.Clone();
                MeshVertex rmv  = rm.Eqv(v2);
                MeshEdge   rme1 = rm.Eqv(v2.EdgeConnecting(rm.Eqv(v1)));
                MeshEdge   rme2 = rm.Eqv(v2.EdgeConnecting(rm.Eqv(v3)));
                MeshFacet  rmf  = rm.Eqv(f);
                rm.RemoveVertex(rmv);

                CollectionAssert.DoesNotContain(rm.Vertices, rmv);
                CollectionAssert.DoesNotContain(rm.Edges, rme1);
                CollectionAssert.DoesNotContain(rm.Edges, rme2);
                CollectionAssert.DoesNotContain(rm.Facets, rmf);

                Assert.AreEqual(rmv.Edges.Count, 0);
                foreach (var v in rm.Vertices)
                {
                    Assert.AreEqual(v.Edges.Count, 1);
                }
            }
        }
 public MeshFacetData(MeshGraph mg) : this()
 {
     Mesh = mg;
 }
 internal void SetGraphInfo(MeshGraph g, int i)
 {
     index  = i;
     parent = g;
 }
 public MeshVertexData(MeshGraph mg) : this()
 {
     Mesh = mg;
 }
 public MeshEdgeData(MeshGraph mg) : this()
 {
     Mesh = mg;
 }
 public MeshFacetDataWithNormal(MeshGraph mg) : this()
 {
     Mesh = mg;
 }
 public abstract void AddMeshGraphUpon(
     ref MeshGraph mg, bool selected = true);