예제 #1
0
 public void AddVertex(double x, double y, ShapePath.FlagsAndCommand cmd)
 {
     m_status = StrokeMath.status_e.initial;
     if (ShapePath.is_move_to(cmd))
     {
         m_src_vertices.modify_last(new VertexDistance(x, y));
     }
     else
     {
         if (ShapePath.is_vertex(cmd))
         {
             m_src_vertices.add(new VertexDistance(x, y));
         }
         else
         {
             if (ShapePath.is_end_poly(cmd))
             {
                 m_closed = (ShapePath.get_close_flag(cmd) == ShapePath.FlagsAndCommand.FlagClose);
                 if (m_orientation == ShapePath.FlagsAndCommand.FlagNone)
                 {
                     m_orientation = ShapePath.get_orientation(cmd);
                 }
             }
         }
     }
 }
예제 #2
0
        // Arrange the orientation of a polygon, all polygons in a path,
        // or in all paths. After calling arrange_orientations() or
        // arrange_orientations_all_paths(), all the polygons will have
        // the same orientation, i.e. path_flags_cw or path_flags_ccw
        //--------------------------------------------------------------------
        public int arrange_polygon_orientation(int start, ShapePath.FlagsAndCommand orientation)
        {
            if (orientation == ShapePath.FlagsAndCommand.FlagNone)
            {
                return(start);
            }

            // Skip all non-vertices at the beginning
            while (start < vertices.total_vertices() &&
                   !ShapePath.is_vertex(vertices.command(start)))
            {
                ++start;
            }

            // Skip all insignificant move_to
            while (start + 1 < vertices.total_vertices() &&
                   ShapePath.is_move_to(vertices.command(start)) &&
                   ShapePath.is_move_to(vertices.command(start + 1)))
            {
                ++start;
            }

            // Find the last vertex
            int end = start + 1;

            while (end < vertices.total_vertices() &&
                   !ShapePath.is_next_poly(vertices.command(end)))
            {
                ++end;
            }

            if (end - start > 2)
            {
                if (perceive_polygon_orientation(start, end) != orientation)
                {
                    // Invert polygon, set orientation flag, and skip all end_poly
                    invert_polygon(start, end);
                    ShapePath.FlagsAndCommand PathAndFlags;
                    while (end < vertices.total_vertices() &&
                           ShapePath.is_end_poly(PathAndFlags = vertices.command(end)))
                    {
                        vertices.modify_command(end++, PathAndFlags | orientation);                        // Path.set_orientation(cmd, orientation));
                    }
                }
            }
            return(end);
        }
예제 #3
0
        public ShapePath.FlagsAndCommand vertex(out double x, out double y)
        {
            x = 0;
            y = 0;
            ShapePath.FlagsAndCommand command = ShapePath.FlagsAndCommand.CommandStop;
            bool done = false;

            while (!done)
            {
                switch (m_status)
                {
                case status.initial:
                    markers.remove_all();
                    m_last_cmd = VertexSource.vertex(out m_start_x, out m_start_y);
                    m_status   = status.accumulate;
                    goto case status.accumulate;

                case status.accumulate:
                    if (ShapePath.is_stop(m_last_cmd))
                    {
                        return(ShapePath.FlagsAndCommand.CommandStop);
                    }

                    generator.RemoveAll();
                    generator.AddVertex(m_start_x, m_start_y, ShapePath.FlagsAndCommand.CommandMoveTo);
                    markers.add_vertex(m_start_x, m_start_y, ShapePath.FlagsAndCommand.CommandMoveTo);

                    for (; ;)
                    {
                        command = VertexSource.vertex(out x, out y);
                        //DebugFile.Print("x=" + x.ToString() + " y=" + y.ToString() + "\n");
                        if (ShapePath.is_vertex(command))
                        {
                            m_last_cmd = command;
                            if (ShapePath.is_move_to(command))
                            {
                                m_start_x = x;
                                m_start_y = y;
                                break;
                            }
                            generator.AddVertex(x, y, command);
                            markers.add_vertex(x, y, ShapePath.FlagsAndCommand.CommandLineTo);
                        }
                        else
                        {
                            if (ShapePath.is_stop(command))
                            {
                                m_last_cmd = ShapePath.FlagsAndCommand.CommandStop;
                                break;
                            }
                            if (ShapePath.is_end_poly(command))
                            {
                                generator.AddVertex(x, y, command);
                                break;
                            }
                        }
                    }
                    generator.Rewind(0);
                    m_status = status.generate;
                    goto case status.generate;

                case status.generate:
                    command = generator.Vertex(ref x, ref y);
                    //DebugFile.Print("x=" + x.ToString() + " y=" + y.ToString() + "\n");
                    if (ShapePath.is_stop(command))
                    {
                        m_status = status.accumulate;
                        break;
                    }
                    done = true;
                    break;
                }
            }
            return(command);
        }
예제 #4
0
        private List <Vertex> TesselateLines(List <Vector2> points, Pen p)
        {
            List <ContourVertex> vecs = new List <ContourVertex>();
            List <Vertex>        ret  = new List <Vertex>();

            if (points.Count < 2)
            {
                return(ret);
            }
            var co = color(p.Color);

            MatterHackers.Agg.VertexSource.PathStorage ps = new MatterHackers.Agg.VertexSource.PathStorage();
            ps.remove_all();
            ps.MoveTo(points[0].X, points[0].Y);

            for (int i = 1; i < points.Count; i++)
            {
                ps.LineTo(points[i].X, points[i].Y);
            }
            ps.end_poly();

            MatterHackers.Agg.VertexSource.Stroke str = new MatterHackers.Agg.VertexSource.Stroke(ps, p.Width);
            switch (p.Join)
            {
            case LineJoin.Round:
                str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Round);
                str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Round);

                break;

            case LineJoin.Miter:
                str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Miter);
                str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Miter);
                str.inner_miter_limit(p.MiterLimit);
                str.miter_limit(p.MiterLimit);
                break;
            }
            switch (p.Cap)
            {
            case LineCaps.Butt:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Butt);
                break;

            case LineCaps.Round:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Round);
                break;

            case LineCaps.Square:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Square);
                break;
            }
            str.rewind(0);
            double x, y;

            LibTessDotNet.Tess t = new LibTessDotNet.Tess();

            ShapePath.FlagsAndCommand cmd;
            do
            {
                cmd = str.vertex(out x, out y);
                if (ShapePath.is_vertex(cmd))
                {
                    vecs.Add(new ContourVertex()
                    {
                        Position = new Vec3()
                        {
                            X = (float)x, Y = (float)y
                        }
                    });
                }
                if (ShapePath.is_end_poly(cmd))
                {
                    t.AddContour(vecs.ToArray());
                    vecs.Clear();
                }
            } while (!ShapePath.is_stop(cmd));

            /*
             * foreach (var v in vertices)
             * {
             * if (!ShapePath.is_close(v.command) && !ShapePath.is_stop(v.command))
             * vecs.Add(new Vector2((float)v.position.x, (float)v.position.y));
             * }*/
            if (vecs.Count != 0)
            {
                t.AddContour(vecs.ToArray());
            }
            t.Tessellate(LibTessDotNet.WindingRule.NonZero, LibTessDotNet.ElementType.Polygons, 3);
            for (var i = 0; i < t.ElementCount; i++)
            {
                for (var tri = 0; tri < 3; tri++)
                {
                    var v = t.Vertices[t.Elements[(i * 3) + tri]].Position;
                    ret.Add(new Vertex(v.X, v.Y, co));
                }
            }
            return(ret);
        }