private static void ProcessTerminalVertex(Mesh <WavefrontVertex, EdgeBase, WavefrontFace> wavefrontMesh, IDictionary <VertexBase, List <WavefrontVertex> > wavefrontVertices, TVertex figureVertex) { // 1. Create two wavefront vertices at ±135° from the incident figure edge // 1a. Locate the figure edge // 1b. Determine the direction of the figure edge away from the vertex Direction2D figureEdgeDirection = new Direction2D(3, 4); // TODO: Temporary - need direction from the terminal vertex along the edge Direction2D direction1 = AffineTransformation2D.Rotation(Angle.DegreesToRadians(+135.0)).Transform(figureEdgeDirection); Vector2D vector1 = new Vector2D(direction1, Constants.Sqrt2); WavefrontVertex wavefrontVertex1 = new WavefrontVertex(figureVertex, vector1); InsertWavefrontVertex(wavefrontMesh, wavefrontVertices, wavefrontVertex1); Direction2D direction2 = AffineTransformation2D.Rotation(Angle.DegreesToRadians(-135.0)).Transform(figureEdgeDirection); Vector2D vector2 = new Vector2D(direction2, Constants.Sqrt2); WavefrontVertex wavefrontVertex2 = new WavefrontVertex(figureVertex, vector2); InsertWavefrontVertex(wavefrontMesh, wavefrontVertices, wavefrontVertex2); // 2. Label the incoming figureEdge (wavefront precursors) with the two vertices at the correct end // 3. Label all of the incoming triangulation edge (spoke precursors) with the first wavefront vertex // 4. Create wavefront edge between the two wavefront vertices // 5. Identify the quadrilateral based by the edge created in step 4 // 6. Split this quadrilateral by inserting a new edge from the second // of the two wavefront vertices. throw new NotImplementedException(); }
//材质 //public static Material mat = new Material(new Color(0, 0, 0.1f), 0.1f, new Color(0.3f, 0.3f, 0.3f), new Color(1, 1, 1), 99); public static WavefrontObject ToWavefrontObject() { WavefrontObject obj = new WavefrontObject(); for (int i = 0; i < CubeTestData.pointList.Length; ++i) { Vector3 point = CubeTestData.pointList[i]; obj.Positions.Add(point); } for (int i = 0; i < CubeTestData.normals.Length; ++i) { Vector3 normal = CubeTestData.normals[i]; obj.Normals.Add(normal); } for (int i = 0; i < CubeTestData.uvs.Length; ++i) { Vector2 uv = CubeTestData.uvs[i]; obj.Texcoords.Add(uv); } for (int i = 0; i < CubeTestData.vertColors.Length; ++i) { Vector4 color = new Vector4(CubeTestData.vertColors[i], 1); obj.Colors.Add(color); } //处理三角形 WavefrontFaceGroup faceGroup = new WavefrontFaceGroup(); obj.Groups.Add(faceGroup); for (int i = 0; i + 2 < CubeTestData.indexs.Length; i += 3) { WavefrontFace face = new WavefrontFace(); faceGroup.Faces.Add(face); int index0 = i; int index1 = i + 1; int index2 = i + 2; int p0 = CubeTestData.indexs[i]; int p1 = CubeTestData.indexs[i + 1]; int p2 = CubeTestData.indexs[i + 2]; WavefrontVertex v0 = new WavefrontVertex(p0 + 1, index0 + 1, index0 + 1); WavefrontVertex v1 = new WavefrontVertex(p1 + 1, index1 + 1, index1 + 1); WavefrontVertex v2 = new WavefrontVertex(p2 + 1, index2 + 1, index2 + 1); v0.Color = index0 + 1; v1.Color = index1 + 1; v2.Color = index2 + 1; face.Vertices.Add(v0); face.Vertices.Add(v1); face.Vertices.Add(v2); } return(obj); }
private void Skeletonize() { // Duplicate the figure, but convert the types of vertices and edges // and maintain a mapping from the triangulation vertices to the wavefront vertices. var wavefrontMesh = new Mesh <WavefrontVertex, EdgeBase, WavefrontFace>(); var wavefrontVertices = new Dictionary <VertexBase, List <WavefrontVertex> >(); foreach (TVertex v in figure.Vertices) { WavefrontVertex wavefrontVertex = new WavefrontVertex(v, new Vector2D()); wavefrontMesh.Add(wavefrontVertex); if (!wavefrontVertices.ContainsKey(v)) { wavefrontVertices.Add(v, new List <WavefrontVertex>()); } wavefrontVertices[v].Add(wavefrontVertex); } // Now insert the edges from the figure foreach (TEdge e in figure.Edges) { WavefrontVertex from = wavefrontVertices[e.Source].First(); WavefrontVertex to = wavefrontVertices[e.Target].First(); wavefrontMesh.AddEdge(from, to, new FigureEdge()); } // Triangulate the figure. All new edges inserted during the triangulation // are to be SpokeEdges. TODO: What about bounding-box edges? Algorithms.TriangulatePlanarSubdivision <WavefrontVertex, EdgeBase, WavefrontFace, TriangulationEdge>(wavefrontMesh, true); // Build the wavefront triangulation // - insert additional zero size triangles at the terminals of the figure // - split each edge of the figure along its length so that otherwise adjacent // triangles do not share an edge foreach (TVertex figureVertex in figure.Vertices) { // TODO: Ensure we pass the right vertex to the functions here if (figureVertex.Degree >= 2) { ProcessNonTerminalVertex(wavefrontMesh, wavefrontVertices, figureVertex); } else if (figureVertex.Degree == 1) { ProcessTerminalVertex(wavefrontMesh, wavefrontVertices, figureVertex); } } }
private static void LabelSpokePrecursorEdge(TVertex figureVertex, WavefrontVertex wavefrontVertex, Half current) { Debug.Assert(current.Edge is TriangulationEdge); var triangulationEdge = current.Edge as TriangulationEdge; if (triangulationEdge.Source == figureVertex) { // Outgoing edge triangulationEdge.SourceWavefrontVertex = wavefrontVertex; } else { // Incoming edge Debug.Assert(triangulationEdge.Target == figureVertex); triangulationEdge.TargetWavefrontVertex = wavefrontVertex; } }
/// <summary> /// Process a non-terminal vertex (a vertex that has two or more connected edges) /// /// </summary> /// <param name="wavefrontMesh"></param> /// <param name="wavefrontVertices"></param> /// <param name="figureVertex"></param> private static void ProcessNonTerminalVertex(Mesh <WavefrontVertex, EdgeBase, WavefrontFace> wavefrontMesh, Dictionary <VertexBase, List <WavefrontVertex> > wavefrontVertices, TVertex figureVertex) { // Each vertex of v of G of degree d >= 2 is duplicated into d wavefront vertices. // Iterate over successive pairs of outgoing half-edges from this figureVertex // This iterates in an anticlockwise direction around the vertex foreach (Pair <Half, Half> figureEdgeHalves in figureVertex.HalfEdges .Where(e => e.Edge is FigureEdge) .Wrap() .SuccessivePairs()) { WavefrontVertex wavefrontVertex = BisectingWavefrontVertex(figureEdgeHalves, figureVertex); InsertWavefrontVertex(wavefrontMesh, wavefrontVertices, wavefrontVertex); LabelWavefrontPrecursorEdges(figureVertex, figureEdgeHalves, wavefrontVertex); LabelInterveningSpokePrecursorEdges(figureVertex, figureEdgeHalves, wavefrontVertex); } }
public static Vertex FromWavefrontVertex(WavefrontObject obj, WavefrontVertex v) { Vertex vertex = new Vertex(); vertex.position = new Vector4(obj.Positions[v.Position - 1], 1f); if (v.Normal > 0) { vertex.normal = new Vector4(obj.Normals[v.Normal - 1], 0f); } vertex.texcoord = obj.Texcoords[v.Texcoord - 1]; if (v.Color >= 0 && v.Color < obj.Colors.Count) { vertex.color = obj.Colors[v.Color - 1]; } else { vertex.color = Vector4.One; } return(vertex); }
private static void InsertWavefrontVertex(Mesh <WavefrontVertex, EdgeBase, WavefrontFace> wavefrontMesh, IDictionary <VertexBase, List <WavefrontVertex> > wavefrontVertices, WavefrontVertex wavefrontVertex) { wavefrontMesh.Add(wavefrontVertex); TVertex figureVertex = wavefrontVertex.GraphVertex; if (!wavefrontVertices.ContainsKey(figureVertex)) { wavefrontVertices.Add(figureVertex, new List <WavefrontVertex>()); } wavefrontVertices[figureVertex].Add(wavefrontVertex); }
/// Iterate through all the half edges between figureEdgeHalves.First and /// figureEdgeHalves.Second (exclusive), all of which will be TriangulationEdges</summary> /// and mark them up with the wavefrontVertex reference. /// <param name="figureVertex"></param> /// <param name="figureEdgeHalves"></param> /// <param name="wavefrontVertex"></param> private static void LabelInterveningSpokePrecursorEdges(TVertex figureVertex, Pair <Half, Half> figureEdgeHalves, WavefrontVertex wavefrontVertex) { Half current = NextOutgoingHalf(figureEdgeHalves.First); while (current != figureEdgeHalves.Second) { LabelSpokePrecursorEdge(figureVertex, wavefrontVertex, current); current = NextOutgoingHalf(current); } }
/// <summary> /// Set the references to the the new wavefront vertex on the trailing edge /// </summary> /// <param name="figureVertex"></param> /// <param name="figureEdgeHalves"></param> /// <param name="wavefrontVertex"></param> private static void LabelWavefrontPrecursorEdges(TVertex figureVertex, Pair <Half, Half> figureEdgeHalves, WavefrontVertex wavefrontVertex) { FigureEdge trailingEdge = (figureEdgeHalves.First.Edge as FigureEdge); if (trailingEdge.Source == figureVertex) { // Outgoing edge trailingEdge.SourceLeftVertex = wavefrontVertex; } else { // Incoming edge Debug.Assert(trailingEdge.Target == figureVertex); trailingEdge.TargetRightVertex = wavefrontVertex; } // Set the references to the new wavefront vertex on the leading edge FigureEdge leadingEdge = (figureEdgeHalves.Second.Edge as FigureEdge); if (leadingEdge.Source == figureVertex) { // Outgoing edge leadingEdge.SourceRightVertex = wavefrontVertex; } else { // Incoming edge Debug.Assert(leadingEdge.Target == figureVertex); leadingEdge.TargetLeftVertex = wavefrontVertex; } }