2015-10-04 21 views
0

我想在C#中實現循環細分算法。 http://www.cs.cmu.edu/afs/cs/academic/class/15462-s13/www/lec_slides/project2_slides.pdfC#和OpenTK中的循環細分

我該如何跟蹤我發現新頂點的所有邊緣。這是我的代碼來加載線框的Json文件。我創建了一個新的類細分來細分網格,但由於存在錯誤,它不起作用。任何人都可以拋開一些光線,我怎麼細分網格。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using OpenTK; 
using OpenTK.Graphics; 
using OpenTK.Graphics.OpenGL; 
using System.IO; 
using Newtonsoft.Json; 

namespace MonkeySubdivision 
{ 
    public partial class Form1 : Form 
    {  
    Mesh[] meshes0;  
    Mesh[] meshes1; 
    Mesh[] meshes2; 

    bool loaded = false; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 
    private void display() 
    { 

     if (!loaded) 
      return; 
     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 
     GL.Viewport(0, 0, Width, Height); 
     Matrix4 world = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY); 
     GL.MatrixMode(MatrixMode.Modelview); 
     GL.LoadMatrix(ref world); 
     GL.LoadIdentity(); 
     GL.Translate(-0.1f, -0.4f, -5.5f); 
     meshes0 = LoadJson(); 
     meshes1 = Subdivision.subdivsion(meshes0); 

     // Subdivide the mesh depending on the numeric value 

      if (numericUpDown1.Value == 1) 
      { 
     // meshes1 = Subdivision.subdivsion(meshes0); 
      Console.Write("Inside 1st subdivision"); 
      Console.WriteLine("This should be displayed"); 
      meshes0 = meshes1; 
      } 
     if (numericUpDown1.Value == 2) 
     { 
      Console.Write("Inside 2nd subdivision"); 
     } 
     if (numericUpDown1.Value == 3) 
     { 
      Console.Write("Inside 3rd subdivision"); 
     } 
     if (numericUpDown1.Value == 4) 
     { 
      Console.Write("Inside 4th subdivision"); 
     } 
     if (numericUpDown1.Value == 5) 
     { 
      Console.Write("Inside 5th subdivision"); 
     } 

     int vertcount = getnumvertices(meshes0); 
     label2.Text = vertcount.ToString(); 
     int facecount = getnumfaces(meshes0); 
     label4.Text = facecount.ToString(); 


     // Code To Display the triangles on screen 
     foreach (Mesh mesh in meshes0) 
     { 
      foreach (var face in mesh.Faces) 
      {     
       GL.Begin(PrimitiveType.Triangles); 
       GL.Color3(Color.Yellow); 
       GL.Vertex3(mesh.Vertices[face.A]); 
       GL.Vertex3(mesh.Vertices[face.B]); 
       GL.Vertex3(mesh.Vertices[face.C]); 
       GL.End(); 
      } 

      GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); 
      GL.PolygonMode(MaterialFace.Back, PolygonMode.Line); 
      GL.Flush(); 
      glControl1.SwapBuffers(); 
     } 
    } 

    //Number of faces in a Mesh 
    private int getnumfaces(Mesh[] meshsub) 
    { 
     int count = 0; 
     foreach (Mesh mesh in meshsub) 
     { 
      foreach (var face in mesh.Faces) 
       count = count + 1; 
     } 
     return count; 

    } 

    //Number of vertices in a Mesh 
    private int getnumvertices(Mesh[] meshsub) 
    { 
     int count = 0; 
     foreach (Mesh mesh in meshsub) 
     { 
      foreach (var face in mesh.Vertices) 
       count = count + 1; 
     } 
     return count; 
    } 




    private void glControl1_Resize(object sender, EventArgs e) 
    { 
     GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height); 

     Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI/4, Width/(float)Height, 1.0f, 64.0f); 

     GL.MatrixMode(MatrixMode.Projection); 

     GL.LoadMatrix(ref projection); 
     SetupViewport(); 
     glControl1.Invalidate(); 

    } 
    private void glControl1_Paint(object sender, PaintEventArgs e) 
    { 

     display(); 

    } 

    private void glControl1_Load(object sender, EventArgs e) 
    { 
     loaded = true; 
     GL.ClearColor(Color.Black); 
     GL.ShadeModel(ShadingModel.Smooth); 
     GL.ClearColor(Color.Black); 
     GL.ClearDepth(1.0f); 
     GL.Enable(EnableCap.DepthTest); 
     GL.DepthFunc(DepthFunction.Lequal); 
     GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); 
     SetupViewport(); 
     Application.Idle += Application_Idle; // press TAB twice after += 
    } 
    void Application_Idle(object sender, EventArgs e) 
    { 
     // no guard needed -- we hooked into the event in Load handler 
     while (glControl1.IsIdle) 
     { 
      display(); 
      SetupViewport(); 
     } 
    } 
    private void SetupViewport() 
    { 
     int w = glControl1.Width; 
     int h = glControl1.Height; 
     GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height); 

     Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI/4, w/(float)h, 1.0f, 64.0f); 

     GL.MatrixMode(MatrixMode.Projection); 

     GL.LoadMatrix(ref projection); 

     GL.Viewport(0, 0, w, h); // Use all of the glControl painting area 
    } 

    // JSON file parser 
    private Mesh[] LoadJson() 
    { 
     var meshes = new List<Mesh>(); 
     using (StreamReader r = new StreamReader("cube.babylon")) 
     { 
      string json = r.ReadToEnd(); 
      dynamic jsonObject = JsonConvert.DeserializeObject(json); 

      for (var meshIndex = 0; meshIndex < jsonObject.meshes.Count; meshIndex++) 
      { 
       var verticesArray = jsonObject.meshes[meshIndex].vertices; 
       // Faces 
       var indicesArray = jsonObject.meshes[meshIndex].indices; 

       var uvCount = jsonObject.meshes[meshIndex].uvCount.Value; 
       var verticesStep = 1; 

       // Depending of the number of texture's coordinates per vertex 
       // we're jumping in the vertices array by 6, 8 & 10 windows frame 
       switch ((int)uvCount) 
       { 
        case 0: 
         verticesStep = 6; 
         break; 
        case 1: 
         verticesStep = 8; 
         break; 
        case 2: 
         verticesStep = 10; 
         break; 
       } 
       // the number of interesting vertices information for us 
       var verticesCount = verticesArray.Count/verticesStep; 
       // number of faces is logically the size of the array divided by 3 (A, B, C) 
       var facesCount = indicesArray.Count/3; 
       var mesh = new Mesh(jsonObject.meshes[meshIndex].name.Value, verticesCount, facesCount); 

       // Filling the Vertices array of our mesh first 
       for (var index = 0; index < verticesCount; index++) 
       { 
        var x = (float)verticesArray[index * verticesStep].Value; 
        var y = (float)verticesArray[index * verticesStep + 1].Value; 
        var z = (float)verticesArray[index * verticesStep + 2].Value; 
        mesh.Vertices[index] = new Vector3(x, y, z); 
       } 

       // Then filling the Faces array 
       for (var index = 0; index < facesCount; index++) 
       { 
        var a = (int)indicesArray[index * 3].Value; 
        var b = (int)indicesArray[index * 3 + 1].Value; 
        var c = (int)indicesArray[index * 3 + 2].Value; 
        mesh.Faces[index] = new Face { A = a, B = b, C = c }; 
       } 
       // Getting the position you've set in Blender 
       var position = jsonObject.meshes[meshIndex].position; 
       mesh.Position = new Vector3((float)position[0].Value, (float)position[1].Value, (float)position[2].Value); 
       meshes.Add(mesh); 
      } 
      return meshes.ToArray(); 

     } 
    } 
    private void Form1_Load(object sender, EventArgs e) 
    { 
     glControl1.Resize += new EventHandler(glControl1_Resize); 
     meshes0 = LoadJson(); 
     meshes1 = Subdivision.subdivsion(meshes0); 

    } 

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) 
    {   

    } 


    } 
} 

細分函數將採用網格,然後根據循環細分算法細分網格。

using OpenTK; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Collections; 

namespace MonkeySubdivision 
{ 
class Subdivision 
{ 
    public static Mesh[] subdivsion(Mesh[] meshsub) 
    { 
     var meshes = new List<Mesh>(); 
     //Vertices of a mesh 
     //Hashtable edges = new Hashtable(); 


     int verticescount = getnumvertices(meshsub); 
     Console.WriteLine(verticescount); 
     int facecount = getnumfaces(meshsub); 
     int edgecount = verticescount + facecount - 2; 
     int newvercount = verticescount + edgecount; 
     int newfacecount = facecount * 4; 
     Vector3[] NewVertices = new Vector3[newvercount]; 
     var meshnew = new Mesh("subdmesh", newvercount, newfacecount); 


     foreach (Mesh mesh in meshsub) 
     { 

      //for (var j = 0; j < verticescount; j++) 
      //{ 
      // Console.WriteLine(mesh.Vertices[j]); 
      // NewVertices[j] = mesh.Vertices[j]; 
      //} 



      foreach (Mesh mesh2 in meshsub) 
      { 
       //for (var index = 0; index < facecount; index++) 
       //{ 
       // foreach (var faces in mesh.Faces) 
       // { 
       //  meshnew.Faces[index] = mesh.Faces[index]; 
       // } 
       //} 
       int i = 0; 
       foreach (var face in mesh.Faces) 
       { 
        var P0 = face.A; 
        var P1 = face.B; 
        var P2 = face.C; 
        Console.WriteLine("Faces"); 
        Console.WriteLine(P0); 
        Console.WriteLine(P1); 
        Console.WriteLine(P2); 

        NewVertices[i] = getfourthvert(P0, P1, P2, meshsub); 
        NewVertices[i + 1 ] = getfourthvert(P1, P2, P0, meshsub); 
        NewVertices[i + 2] = getfourthvert(P2, P0, P1,meshsub); 
        i = i + 3; 





        for (var index = verticescount; index < newvercount; index++) 
        { 
         meshnew.Vertices[index] = NewVertices[index]; 
        } 
        /*   for(var index = facecount; index < newfacecount; index++) 
          { 
           var a = face.A; 
           var b = (int)indicesArray[index * 3 + 1].Value; 
           var c = (int)indicesArray[index * 3 + 2].Value; 
           mesh.Faces[index] = new Face { A = a, B = b, C = c }; 
          }*/ 


        meshes.Add(meshnew); 
       } 


       int n = 6; 
       double num = (3.0 + 2.0 * Math.Cos(2.0 * Math.PI/n)); 
       double beta = 1.0/n * (5.0/8.0 - num * num/64.0); 

      } 
      } 
      return meshes.ToArray(); 
     } 


    private static int getnumfaces(Mesh[] meshsub) 
    { 
     int count = 0; 
     foreach (Mesh mesh in meshsub) 
     { 
      foreach (var face in mesh.Faces) 
       count = count + 1; 
     } 
     return count; 

    } 

    private static int getnumvertices(Mesh[] meshsub) 
    { 
     int count = 0; 
     foreach (Mesh mesh in meshsub) 
     { 
      foreach (var vert in mesh.Vertices) 
       count = count + 1; 
     } 
     return count; 
    } 

    private static Vector3 getfourthvert(int X0, int X1, int X2, Mesh[] meshsub) 
    { 
     int X3; 
     Vector3 V4 = new Vector3(0, 0, 0); 
     foreach (Mesh mesh in meshsub) 
      { 

      foreach (var face2 in mesh.Faces) 
      { 
       var V0 = mesh.Vertices[X0]; 
       var V1 = mesh.Vertices[X1]; 
       var V2 = mesh.Vertices[X2]; 
       var V3 = mesh.Vertices[0]; 

       if ((X0 == face2.A) && (X1 == face2.B)) 
       { 
        var temp = face2.C; 

        if (temp != X2) 
        { 
         X3 = temp; 
         V3 = mesh.Vertices[X3]; 
         V4 = (3 * V0 + 3 * V1 + V2 + V3)/8; 
        } 

       } 

      } 

     } 

     Console.WriteLine(V4); 
     return V4; 
    } 



} 
} 
+1

這是很多代碼。我建議幫助我們通過[將其縮減爲一個最小但完整的問題示例]來幫助您(https://stackoverflow.com/help/mcve)。 –

+0

是的...我複製了完整的代碼以便清楚理解....但主要部分是循環細分。我無法實現循環細分。 –

回答

0

您需要一個Mesh類,它可以包含三個指向其他網格的鏈接。您也可以保留所有網格的列表,但應該是靜態的。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Drawing; 

namespace WindowsFormsApplication1 
{ 

    public class Mesh 
    { 
     static List<Mesh> meshes { get; set; } 
     static List<PolyGon> polygons { get; set; } 
    } 
    public class PolyGon 
    { 
     List<Edge> edges { get; set; } 
    } 
    public class Edge 
    { 
     List<PointF> points { get; set; } //two points 
     List<PolyGon> parents { get; set; } // two parents 
    } 
} 
​ 
+0

我有一個類Mesh,但問題是細分網格。我有一個網格必須作爲輸入給細分函數。這個細分函數將執行完整的循環細分。我正在面臨細分網格的問題。您能否介紹一下如何細分網格。 –

+0

我更新了我的答案。我通常從編寫代碼之前開始定義數據結構。數據結構是類。你有兩條邊和兩個父母。父母是一個多邊形。多邊形有n條邊。 – jdweng