public void BuildTriangles(MeshData data) { var numPoints = data.Vertices.Count; var numEdges = data.Edges.Count; data.Triangles.Capacity = numPoints * 3; var events = WorkBufferPool.Get <Event>(); if (events.NewForClass == null) { events.NewForClass = () => new Event(); } //Create point events for (var i = 0; i < numPoints; ++i) { var e = events.Push(); e.A = data.Vertices[i]; e.B = Vector2.zero; e.Type = EventType.Point; e.Index = i; } //Create edge events for (var i = 0; i < numEdges; ++i) { var edge = data.Edges[i]; var a = data.Vertices[edge.x]; var b = data.Vertices[edge.y]; if (a.x < b.x) { { var e = events.Push(); e.A = a; e.B = b; e.Type = EventType.Start; e.Index = i; } { var e = events.Push(); e.A = b; e.B = a; e.Type = EventType.End; e.Index = i; } } else if (a.x > b.x) { { var e = events.Push(); e.A = b; e.B = a; e.Type = EventType.Start; e.Index = i; } { var e = events.Push(); e.A = a; e.B = b; e.Type = EventType.End; e.Index = i; } } } //Sort events WorkBuffer <Event> .Sort(events); if (Verbose) { DumpEvents(events); } //Initialize hull var minX = events.Data[0].A.x - 1f; var hulls = WorkBufferPool.Get <PartialHull>(); if (hulls.NewForClass == null) { hulls.NewForClass = () => new PartialHull(); } var h = hulls.Push(); h.A = new Vector2(minX, 1f); h.B = new Vector2(minX, 0f); h.Index = -1; h.LowerIds.Clear(); h.UpperIds.Clear(); //Process events in order var numEvents = events.UsedSize; for (var i = 0; i < numEvents; ++i) { var e = events.Data[i]; if (Verbose) { Debug.Log(""); Debug.Log(i); DumpEvent(e); } switch (e.Type) { case EventType.Point: AddPoint(data.Triangles, hulls, data.Vertices, e.A, e.Index); break; case EventType.Start: SplitHulls(hulls, e); break; case EventType.End: MergeHulls(hulls, e); break; } if (Verbose) { Debug.Log(""); } } WorkBufferPool.Release(ref hulls); WorkBufferPool.Release(ref events); }
private FaceIndex IndexCells(Triangles triangles) { var zero = 0; var fals = false; var index = new FaceIndex(WorkBufferPool); triangles.Fill(index.Cells); //First get cells and canonicalize var cells = index.Cells; var nc = cells.UsedSize; var cellsData = cells.Data; for (var i = 0; i < nc; ++i) { var c = cellsData[i]; var x = c.x; var y = c.y; var z = c.z; if (y < z) { if (y < x) { c.x = y; c.y = z; c.z = x; cellsData[i] = c; } } else if (z < x) { c.x = z; c.y = x; c.z = y; cellsData[i] = c; } } WorkBuffer <Int3> .Sort(cells); //Initialize flag array var flags = index.Flags; flags.Fill(ref zero, nc); //Build neighbor index, initialize queues var active = index.Active; var next = index.Next; var neighbor = index.Neighbor; var constraint = index.Constraint; var boundary = index.Boundary; neighbor.Fill(ref zero, nc * 3); constraint.Fill(ref fals, nc * 3); var flagsData = flags.Data; var neighborData = neighbor.Data; var constraintData = constraint.Data; for (var i = 0; i < nc; ++i) { var c = cellsData[i]; for (var j = 0; j < 3; ++j) { var x = 0; var y = 0; switch (j) { case 0: x = c.x; y = c.y; break; case 1: x = c.y; y = c.z; break; case 2: x = c.z; y = c.x; break; } var a = neighborData[3 * i + j] = Locate(cells, y, x, triangles.Opposite(y, x)); var b = constraintData[3 * i + j] = triangles.IsConstraint(x, y); if (a < 0) { if (b) { next.Push(ref i); } else { active.Push(ref i); flagsData[i] = 1; } if (Infinity) { var v = new Int3(y, x, -1); boundary.Push(ref v); } } } } return(index); }