コード例 #1
0
        // add light itd
        private static void FillPolygon(DirectBitmap bitmap, IList <Vertex> screenVertices, Vector3 cameraPos, Material material, IList <Light> lights, DirectBitmap texture, DirectBitmap normalMap)
        {
            EdgeTable edgeTable = new EdgeTable();

            for (int i = 0; i < screenVertices.Count - 1; ++i)
            {
                edgeTable.AddEdge(screenVertices[i], screenVertices[i + 1], PerspectiveCorrection);
            }
            edgeTable.AddEdge(screenVertices[screenVertices.Count - 1], screenVertices[0], PerspectiveCorrection);

            ActiveEdgeTable activeEdgeTable = new ActiveEdgeTable();
            int             y = edgeTable.FirstIndex;

            while (!activeEdgeTable.Empty || edgeTable.Count > 0)
            {
                activeEdgeTable.AddEdges(edgeTable[y]);

                var ranges = activeEdgeTable.GetFillRanges();
                foreach (var range in ranges)
                {
                    FillPixelsInRange(bitmap, y, range, cameraPos, material, lights, texture, normalMap);
                }

                y++;
                activeEdgeTable.RemoveEdges(y);
                activeEdgeTable.Increase();
            }
        }
コード例 #2
0
        public void EdgeTable_Diagonal()
        {
            var table = new EdgeTable(10, 10);

            table.Add(new Edge(1, new PointF(0, 0), new PointF(10, 5), Color.Red));

            var edges = table[0];

            Assert.AreEqual(1, edges.Count);
            Assert.AreEqual(0, edges[0].FromX);
            Assert.AreEqual(2, edges[0].Width);
        }
コード例 #3
0
        public void EdgeTable_VerticalAligned()
        {
            var table = new EdgeTable(10, 10);

            table.Add(new Edge(1, new PointF(2f, 0), new PointF(2f, 10), Color.Red));

            var edges = table[5];

            Assert.AreEqual(1, edges.Count);
            Assert.AreEqual(2, edges[0].FromX);
            Assert.AreEqual(0, edges[0].Width);
        }
コード例 #4
0
    private static void InitializeNativeEdgeTable()
    {
        NativeEdgeTable = new NativeArray <float3>(EdgeTable.Length, Allocator.Persistent);
        int rows = EdgeTable.GetLength(0);
        int cols = EdgeTable.GetLength(1);

        for (int row = 0; row < rows; row++)
        {
            for (int col = 0; col < cols; col++)
            {
                NativeEdgeTable[row * cols + col] = EdgeTable[row, col];
            }
        }
    }
コード例 #5
0
        public void EdgeTableFill(Color?color, bool del = false)
        {
            EdgeTable    activeEdgeTable = new EdgeTable();
            List <Point> vertices        = new List <Point>();

            for (int i = 0; i < Vertices.Count - 1; i++)
            {
                vertices.Add(Vertices[i]);
            }

            List <int> indexList = Enumerable.Range(0, vertices.Count).OrderBy(x => vertices[x].Y).ToList();
            int        tmpIndex = 0;
            int        beg = indexList[0];
            int        yMin = (int)vertices.Min(x => x.Y), yMax = (int)vertices.Max(x => x.Y);

            while (yMin < yMax)
            {
                if (vertices[beg].Y == yMin)
                {
                    if (vertices[(beg + 1) % vertices.Count].Y > vertices[beg].Y)
                    {
                        activeEdgeTable.Buckets.Add(new EdgeBucket(vertices[beg], vertices[(beg + 1 + vertices.Count) % vertices.Count]));
                    }
                    if (vertices[(beg - 1 + vertices.Count) % vertices.Count].Y > vertices[beg].Y)
                    {
                        activeEdgeTable.Buckets.Add(new EdgeBucket(vertices[beg], vertices[(beg - 1 + vertices.Count) % vertices.Count]));
                    }
                    beg = indexList[++tmpIndex];
                }

                activeEdgeTable.Buckets = activeEdgeTable.Buckets.OrderBy(x => x.XOfYMin).ToList();
                for (int i = 0; i < activeEdgeTable.Buckets.Count - 1; i++)
                {
                    EdgeBucket start = activeEdgeTable.Buckets[i], end = activeEdgeTable.Buckets[i + 1];
                    MainWindow.DrawLine((int)start.XOfYMin, yMin, (int)end.XOfYMin, yMin, 1, color == null ? ColorPoly : (Color)color, del);
                }
                yMin++;
                activeEdgeTable.RemoveElems(yMin);
                activeEdgeTable.Increment();
            }
            IsFilled  = true;
            FillColor = (Color)color;
        }
コード例 #6
0
ファイル: ScanConverter.cs プロジェクト: SylarLi/SoftPipeline
    public int[][] ConvexFill(int[][] points)
    {
        // edge table
        EdgeTable et = new EdgeTable();
        int       topx1 = -1, topx2 = -1, topy = -1;

        for (int pIndex = 0, len = points.GetLength(0); pIndex < len; pIndex++)
        {
            int[] p1 = points[pIndex];
            int[] p2 = points[pIndex + 1 >= len ? 0 : pIndex + 1];
            if (p1[1] != p2[1])
            {
                int      yMin = 0;
                EdgeNode node = new EdgeNode();
                if (p1[1] > p2[1])
                {
                    yMin      = p2[1];
                    node.yMax = p1[1];
                    node.xMin = p2[0];
                }
                else
                {
                    yMin      = p1[1];
                    node.yMax = p2[1];
                    node.xMin = p1[0];
                }
                node.m = (float)(p1[0] - p2[0]) / (p1[1] - p2[1]);
                et.AddNode(yMin, node);
            }
            else
            {
                // 记录top horizontal edge
                // 这种简单判断topEdge的方式只对Convex有效
                if (p1[1] > topy)
                {
                    topy = p1[1];
                    if (p1[0] > p2[0])
                    {
                        topx1 = p2[0];
                        topx2 = p1[0];
                    }
                    else
                    {
                        topx1 = p1[0];
                        topx2 = p2[0];
                    }
                }
                if (pIndex == len - 1 &&
                    topy < points[1][1])
                {
                    topy = -1;
                }
            }
        }

        // active edge table
        EdgeBucket aet = new EdgeBucket();

        if (et.Count == 0)
        {
            return(null);
        }
        else
        {
            // loop
            Queue <int[]> result = new Queue <int[]>();
            while (et.Count > 0 || aet.Count > 0)
            {
                if (aet.Count == 0)
                {
                    aet.yMin = et[0].yMin;
                    et[0].ForEach((EdgeNode each) => aet.AddNode(each));
                    et.RemoveAt(0);
                }
                else
                {
                    if (et.Count > 0 &&
                        aet.yMin == et[0].yMin)
                    {
                        et[0].ForEach((EdgeNode each) => aet.AddNode(each));
                        et.RemoveAt(0);
                    }
                }
                for (int aIndex = aet.Count - 1; aIndex >= 0; aIndex--)
                {
                    if (aet[aIndex].yMax <= aet.yMin)
                    {
                        aet.RemoveAt(aIndex);
                    }
                }
                for (int aIndex = 0; aIndex < aet.Count; aIndex++)
                {
                    if (aIndex % 2 == 0 &&
                        aIndex < aet.Count - 1)
                    {
                        float left  = aet[aIndex].xMin;
                        float right = aet[aIndex + 1].xMin;
                        if (topy == -1 || aet.yMin != topy || left >= topx2 || right <= topx1)
                        {
                            // 以上判断是为了排除top horizontal edge
                            int ileft  = MathS.Floor(left);
                            int iright = MathS.Floor(right);
                            for (int ixMin = ileft; ixMin <= iright; ixMin += 1)
                            {
                                if (ixMin >= left && ixMin < right)
                                {
                                    // 以上判断是为了排除像素点刚好在rightEdge的情况
                                    result.Enqueue(new int[] { ixMin, aet.yMin });
                                }
                            }
                        }
                        aet[aIndex].xMin     += aet[aIndex].m;
                        aet[aIndex + 1].xMin += aet[aIndex + 1].m;
                        if (aet[aIndex].xMin > aet[aIndex + 1].xMin)
                        {
                            EdgeNode temp = aet[aIndex];
                            aet[aIndex]     = aet[aIndex + 1];
                            aet[aIndex + 1] = temp;
                        }
                    }
                }
                aet.yMin += 1;
            }
            return(result.ToArray());
        }
    }
コード例 #7
0
 public void SelectProbe(ProbeIndex probe)
 {
     Probe = probe;
     Pairing.SelectProbe(probe.Template);
     CandidateEdges = ParameterSet.ClonePrototype(EdgeTablePrototype);
 }
コード例 #8
0
ファイル: surface.cs プロジェクト: andrey-nashi/cs-svis
 public Grid()
 {
     TabEdg = new EdgeTable();
     TabPos = new PosTable();
 }
コード例 #9
0
ファイル: Clipper.cs プロジェクト: dmoonfire/gpc-cil
        private static EdgeTable build_lmt( LmtTable lmt_table, 
			ScanBeamTreeEntries sbte,
			IPoly p, 
			int type, //poly type SUBJ/CLIP
			OperationType op)
        {
            /* Create the entire input polygon edge table in one go */
            EdgeTable edge_table = new EdgeTable();

            for ( int c= 0; c < p.InnerPolygonCount; c++)
            {
                IPoly ip = p.GetInnerPoly(c);
                if( !ip.IsContributing(0) )
                {
                    /* Ignore the non-contributing contour */
                    ip.SetContributing(0, true);
                }
                else
                {
                    /* Perform contour optimisation */
                    int num_vertices= 0;
                    int e_index = 0 ;
                    edge_table = new EdgeTable();
                    for ( int i= 0; i < ip.PointCount; i++)
                    {
                        if( OPTIMAL(ip, i) )
                        {
                            double x = ip.GetX(i);
                            double y = ip.GetY(i);
                            edge_table.addNode( x, y );

                            /* Record vertex in the scanbeam table */
                            add_to_sbtree( sbte, ip.GetY(i) );

                            num_vertices++;
                        }
                    }

                    /* Do the contour forward pass */
                    for ( int min= 0; min < num_vertices; min++)
                    {
                        /* If a forward local minimum... */
                        if( edge_table.FWD_MIN( min ) )
                        {
                            /* Search for the next local maximum... */
                            int num_edges = 1;
                            int max = NEXT_INDEX( min, num_vertices );
                            while( edge_table.NOT_FMAX( max ) )
                            {
                                num_edges++;
                                max = NEXT_INDEX( max, num_vertices );
                            }

                            /* Build the next edge list */
                            int v = min;
                            EdgeNode e = edge_table.getNode( e_index );
                            e.bstate[BELOW] = BundleState.UNBUNDLED;
                            e.bundle[BELOW, CLIP] = 0;
                            e.bundle[BELOW, SUBJ] = 0;

                            for ( int i= 0; i < num_edges; i++)
                            {
                                EdgeNode ei = edge_table.getNode( e_index+i );
                                EdgeNode ev = edge_table.getNode( v );

                                ei.xb    = ev.vertex.X;
                                ei.bot.X = ev.vertex.X;
                                ei.bot.Y = ev.vertex.Y;

                                v = NEXT_INDEX(v, num_vertices);
                                ev = edge_table.getNode( v );

                                ei.top.X= ev.vertex.X;
                                ei.top.Y= ev.vertex.Y;
                                ei.dx= (ev.vertex.X - ei.bot.X) / (ei.top.Y - ei.bot.Y);
                                ei.type = type;
                                ei.outp[ABOVE] = null ;
                                ei.outp[BELOW] = null;
                                ei.next = null;
                                ei.prev = null;
                                ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index+i+1) : null;
                                ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index+i-1) : null ;
                                ei.next_bound = null ;
                                ei.bside[CLIP] = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
                                ei.bside[SUBJ] = LEFT ;
                            }
                            insert_bound( bound_list(lmt_table, edge_table.getNode(min).vertex.Y), e);
            #if DEBUG
                                Console.WriteLine("fwd");
                                lmt_table.print();
            #endif
                            e_index += num_edges;
                        }
                    }

                    /* Do the contour reverse pass */
                    for ( int min= 0; min < num_vertices; min++)
                    {
                        /* If a reverse local minimum... */
                        if ( edge_table.REV_MIN( min ) )
                        {
                            /* Search for the previous local maximum... */
                            int num_edges= 1;
                            int max = PREV_INDEX(min, num_vertices);
                            while( edge_table.NOT_RMAX( max ) )
                            {
                                num_edges++;
                                max = PREV_INDEX(max, num_vertices);
                            }

                            /* Build the previous edge list */
                            int v = min;
                            EdgeNode e = edge_table.getNode( e_index );
                            e.bstate[BELOW] = BundleState.UNBUNDLED;
                            e.bundle[BELOW, CLIP] = 0;
                            e.bundle[BELOW, SUBJ] = 0;

                            for (int i= 0; i < num_edges; i++)
                            {
                                EdgeNode ei = edge_table.getNode( e_index+i );
                                EdgeNode ev = edge_table.getNode( v );

                                ei.xb    = ev.vertex.X;
                                ei.bot.X = ev.vertex.X;
                                ei.bot.Y = ev.vertex.Y;

                                v= PREV_INDEX(v, num_vertices);
                                ev = edge_table.getNode( v );

                                ei.top.X = ev.vertex.X;
                                ei.top.Y = ev.vertex.Y;
                                ei.dx = (ev.vertex.X - ei.bot.X) / (ei.top.Y - ei.bot.Y);
                                ei.type = type;
                                ei.outp[ABOVE] = null;
                                ei.outp[BELOW] = null;
                                ei.next = null ;
                                ei.prev = null;
                                ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index+i+1) : null;
                                ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index+i-1) : null ;
                                ei.next_bound = null ;
                                ei.bside[CLIP] = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
                                ei.bside[SUBJ] = LEFT;
                            }
                            insert_bound( bound_list(lmt_table, edge_table.getNode(min).vertex.Y), e);
            #if DEBUG
                                Console.WriteLine("rev");
                                lmt_table.print();
            #endif
                            e_index+= num_edges;
                        }
                    }
                }
            }
            return edge_table;
        }
コード例 #10
0
 /// <summary>
 /// Creates a new instance of <see cref="Bitmap"/>.
 /// </summary>
 /// <param name="width">Width of the drawing canvas in pixels.</param>
 /// <param name="height"></param>
 public Bitmap(int width, int height)
 {
     this.edges  = new EdgeTable(width, height);
     this.width  = width;
     this.height = height;
 }