public List <FaceWE> FlipEdge(EdgeWE e) { List <FaceWE> f = new List <FaceWE>(); FaceWE lf = e.LeftFace; FaceWE rf = e.RightFace; VertexWE v1 = e.Vertex1; VertexWE v2 = e.Vertex2; VertexWE rv = null; VertexWE lv = null; List <VertexWE> rfvertices = GetFaceVertices(rf); List <VertexWE> lfvertices = GetFaceVertices(lf); for (int i = 0; i < rfvertices.Count; i++) { if (!Equals(v1, rfvertices[i]) && !Equals(v2, rfvertices[i])) { rv = rfvertices[i]; } if (!Equals(v1, lfvertices[i]) && !Equals(v2, lfvertices[i])) { lv = lfvertices[i]; } } RemoveFace(rf); RemoveFace(lf); f.Add(AddFace(rv, lv, v1)); f.Add(AddFace(rv, lv, v2)); return(f); }
public List <FaceWE> AddVertex(FaceWE f, VertexWE v) { List <VertexWE> vertices = GetFaceVertices(f); List <FaceWE> faces = new List <FaceWE>(); RemoveFace(f); faces.Add(AddFace(vertices[0], v, vertices[1])); faces.Add(AddFace(vertices[1], v, vertices[2])); faces.Add(AddFace(vertices[2], v, vertices[0])); return(faces); }
public void Continue() { while (pointlist.Count > 0) { VertexWE v = wingededge.AddVertex(pointlist[0].x, pointlist[0].y, pointlist[0].z); pointlist.RemoveAt(0); FaceWE currentFace = wingededge.PointInTriangle(v); List <FaceWE> newFaces = wingededge.AddVertex(currentFace, v); } CheckEdge(wingededge); List <FaceWE> faceToRemove = new List <FaceWE>(); for (int i = wingededge.Faces.Count - 1; i >= 0; i--) { if (wingededge.IsFaceBorder(wingededge.Faces[i])) { faceToRemove.Add(wingededge.Faces[i]); } } for (int i = 0; i < faceToRemove.Count; i++) { wingededge.RemoveFace(faceToRemove[i]); } List <Vector3> VoronoiVertices = new List <Vector3>(); for (int i = 0; i < wingededge.Faces.Count; i++) { List <VertexWE> vertices = wingededge.GetFaceVertices(wingededge.Faces[i]); wingededge.Faces[i].FaceCircumcenter = CalculateCircumscribedCircumference(vertices[0], vertices[1], vertices[2]); } GrahamScan(); TriangulatorGenerator meshGen = GetComponent <TriangulatorGenerator>(); meshGen.GenerateMesh(wingededge); }
public List <VertexWE> GetFaceVertices(FaceWE f) { bool v1founded, v2founded; List <VertexWE> vertices = new List <VertexWE>(); for (int i = 0; i < f.Edges.Count; i++) { v1founded = false; v2founded = false; VertexWE v1 = f.Edges[i].Vertex1; VertexWE v2 = f.Edges[i].Vertex2; if (f.Edges[i].LeftFace == f) { v1 = f.Edges[i].Vertex2; v2 = f.Edges[i].Vertex1; } for (int j = 0; j < vertices.Count; j++) { if (vertices[j].id == v1.id) { v1founded = true; } if (vertices[j].id == v2.id) { v2founded = true; } } if (!v1founded) { vertices.Add(v1); } if (!v2founded) { vertices.Add(v2); } } return(vertices); }
public void RemoveFace(FaceWE f) { foreach (EdgeWE e in f.Edges) { if (Equals(e.RightFace, f)) { e.RightFace = null; } if (Equals(e.LeftFace, f)) { e.LeftFace = null; } if (e.LeftFace == null && e.RightFace == null) { e.Vertex1.Edges.Remove(e); e.Vertex2.Edges.Remove(e); Edges.Remove(e); } } Faces.Remove(f); }
public bool IsFaceBorder(FaceWE f) { foreach (EdgeWE e in f.Edges) { if (e.LeftFace == null || e.RightFace == null) { return(true); } } List <VertexWE> v = GetFaceVertices(f); foreach (VertexWE vertex in v) { foreach (EdgeWE e in vertex.Edges) { if (e.LeftFace == null || e.RightFace == null) { return(true); } } } return(false); }
public void DelaunayIncremental() { List <Entity> p = new List <Entity>(); List <Entity> currentPoints = new List <Entity>(); p.AddRange(Points); WingedEdgeMesh mesh = new WingedEdgeMesh(); // We start by making a first triangle mesh.AddVertex(-2.0f, -1.0f, 0.0f); mesh.AddVertex(-2.0f, 5.0f, 0.0f); mesh.AddVertex(2.0f, -1.0f, 0.0f); mesh.AddFace(mesh.Vertices[0], mesh.Vertices[1], mesh.Vertices[2]); // Now, we're going to triangulate vertex per vertex // We get back 1 vertex from the set of vertices, we look for the triangle containing it, then, // we subdivide it in 3 triangles. We then check that every new triangle is Delaunay. If not, we flip/switchover the // opposite edge of the new vertex while (p.Count > 0) { // We start by extracting a point from the set of vertices Entity point = p[0]; p.RemoveAt(0); FaceWE f = null; int findex = 0; // Looking for the triangle that contains the dot for (int i = 0; i < mesh.Faces.Count; i++) { FaceWE currentFace = mesh.Faces[i]; List <VertexWE> vertices = mesh.GetFaceVertices(currentFace); bool isIn = Troll3D.TRaycast.PointInTriangle(vertices[0].Position, vertices[1].Position, vertices[2].Position, point.transform_.position_); if (isIn) { f = currentFace; findex = i; } } // In theory, we should have get back a triangle that contains the vertex. We're now going to divide that // in 3 triangles using the current vertex List <FaceWE> faces = mesh.AddVertex(f, point.transform_.position_.X, point.transform_.position_.Y, point.transform_.position_.Z); // Now we must check that the triangles we found are Delaunay. Meaning that the // circumscribed circle of the triangle must contains only points of the triangle. // Checking the faces created for (int i = 0; i < faces.Count; i++) { InspectEdge(faces[i].Edges, mesh); } } //Removing mesh thing used for triangulation List <FaceWE> faceToRemove = new List <FaceWE>(); for (int i = mesh.Faces.Count - 1; i >= 0; i--) { if (mesh.IsFaceBorder(mesh.Faces[i])) { faceToRemove.Add(mesh.Faces[i]); } } for (int i = 0; i < faceToRemove.Count; i++) { mesh.RemoveFace(faceToRemove[i]); } for (int i = 0; i < CircleCenter.Count; i++) { Scene.CurrentScene.RemoveRenderable(( MeshRenderer )CircleCenter[i].GetComponent(ComponentType.MeshRenderer)); } if (DisplayCenters) { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); for (int i = 0; i < mesh.Faces.Count; i++) { List <VertexWE> vertices = mesh.GetFaceVertices(mesh.Faces[i]); Vector3 circleCenter = GetCircleCenter(vertices[0].Position, vertices[1].Position, vertices[2].Position); float radius = GetCircleRadius(vertices[0].Position, vertices[1].Position, vertices[2].Position, circleCenter); AddCircleCenter(circleCenter.X, circleCenter.Y, radius); } } else { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); } if (mesh.MakeMesh() != null) { meshRenderer.model_ = mesh.MakeMesh(); meshRenderer.SetFillMode(SharpDX.Direct3D11.FillMode.Wireframe); meshRenderer.material_.SetMainColor(1.0f, 0.0f, 0.0f, 1.0f); } else { } if (DisplayVoronoi) { BuildVoronoi(mesh); } else { CleanVoronoi(); } }
public FaceWE AddFace(VertexWE a, VertexWE b, VertexWE c) { if (!FaceAlreadyExist(a, b, c)) { if (!IsClockwise(a, b, c)) { VertexWE aux = a; a = b; b = aux; } FaceWE f = ScriptableObject.CreateInstance("FaceWE") as FaceWE; EdgeWE e1 = EdgeAlreadyExist(a, b); EdgeWE e2 = EdgeAlreadyExist(b, c); EdgeWE e3 = EdgeAlreadyExist(c, a); if (e1 == null) { EdgeWE aux1 = ScriptableObject.CreateInstance("EdgeWE") as EdgeWE; aux1.Init(a, b); a.Edges.Add(aux1); b.Edges.Add(aux1); Edges.Add(aux1); f.Edges.Add(aux1); aux1.RightFace = f; } else { if (e1.RightFace == null) { e1.RightFace = f; } else { e1.LeftFace = f; } f.Edges.Add(e1); } if (e2 == null) { EdgeWE aux2 = ScriptableObject.CreateInstance("EdgeWE") as EdgeWE; aux2.Init(b, c); b.Edges.Add(aux2); c.Edges.Add(aux2); Edges.Add(aux2); aux2.RightFace = f; f.Edges.Add(aux2); } else { if (e2.RightFace == null) { e2.RightFace = f; } else { e2.LeftFace = f; } f.Edges.Add(e2); } if (e3 == null) { EdgeWE aux3 = ScriptableObject.CreateInstance("EdgeWE") as EdgeWE; aux3.Init(c, a); c.Edges.Add(aux3); a.Edges.Add(aux3); Edges.Add(aux3); aux3.RightFace = f; f.Edges.Add(aux3); } else { if (e3.RightFace == null) { e3.RightFace = f; } else { e3.LeftFace = f; } f.Edges.Add(e3); } Faces.Add(f); return(f); } return(null); }
/// <summary> /// Implémentation de l'algorithme de triangulation de Delaunay incremental /// </summary> public void DelaunayIncremental() { List <Entity> p = new List <Entity>(); List <Entity> currentPoints = new List <Entity>(); p.AddRange(Points); WingedEdgeMesh mesh = new WingedEdgeMesh(); // On commence par créer un big triangle capable de contenir tout les autres mesh.AddVertex(-2.0f, -1.0f, 0.0f); mesh.AddVertex(-2.0f, 5.0f, 0.0f); mesh.AddVertex(2.0f, -1.0f, 0.0f); mesh.AddFace(mesh.Vertices[0], mesh.Vertices[1], mesh.Vertices[2]); // Maintenant, on va trianguler point par point // On récupère un point de l'ensemble de point, on cherche le triangle qui le contient, // puis, on subdivise en 3 triangles. On vérifie ensuite que chacun des triangles crée est // Delaunay, si ce n'est pas le cas, on flip l'arrête "opposé" au sommet rajouté while (p.Count > 0) { // On commence par extraire le point Entity point = p[0]; p.RemoveAt(0); FaceWE f = null; int findex = 0; // On cherche le triangle qui contient le point for (int i = 0; i < mesh.Faces.Count; i++) { FaceWE currentFace = mesh.Faces[i]; List <VertexWE> vertices = mesh.GetFaceVertices(currentFace); bool isIn = Troll3D.TRaycast.PointInTriangle(vertices[0].Position, vertices[1].Position, vertices[2].Position, point.transform_.position_); if (isIn) { f = currentFace; findex = i; } } // En théorie, on a récupéré le triangle qui contient le point, on va désormais diviser // ce triangle en 3 en utilisant le point actuel List <FaceWE> faces = mesh.AddVertex(f, point.transform_.position_.X, point.transform_.position_.Y, point.transform_.position_.Z); // Maintenant, on doit vérifier que les triangles obtenus sont delaunay, c'est à dire // que le cercle circonscrit au triangle ne contienne que des points du triangle // On inspecte les faces crées for (int i = 0; i < faces.Count; i++) { InspectEdge(faces[i].Edges, mesh); } } // Je retire les parties du maillage qui sont utilisé pour construire la triangulation List <FaceWE> faceToRemove = new List <FaceWE>(); for (int i = mesh.Faces.Count - 1; i >= 0; i--) { if (mesh.IsFaceBorder(mesh.Faces[i])) { faceToRemove.Add(mesh.Faces[i]); } } for (int i = 0; i < faceToRemove.Count; i++) { mesh.RemoveFace(faceToRemove[i]); } for (int i = 0; i < CircleCenter.Count; i++) { Scene.CurrentScene.RemoveRenderable(( MeshRenderer )CircleCenter[i].GetComponent(ComponentType.MeshRenderer)); } if (DisplayCenters) { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); for (int i = 0; i < mesh.Faces.Count; i++) { List <VertexWE> vertices = mesh.GetFaceVertices(mesh.Faces[i]); Vector3 circleCenter = GetCircleCenter(vertices[0].Position, vertices[1].Position, vertices[2].Position); float radius = GetCircleRadius(vertices[0].Position, vertices[1].Position, vertices[2].Position, circleCenter); AddCircleCenter(circleCenter.X, circleCenter.Y, radius); } } else { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); } if (mesh.MakeMesh() != null) { meshRenderer.model_ = mesh.MakeMesh(); meshRenderer.SetFillMode(SharpDX.Direct3D11.FillMode.Wireframe); meshRenderer.material_.SetMainColor(1.0f, 0.0f, 0.0f, 1.0f); } else { } if (DisplayVoronoi) { BuildVoronoi(mesh); } else { CleanVoronoi(); } }