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);
        }
Example #2
0
        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);
        }