// 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(); } }
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); }
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); }
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]; } } }
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; }
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()); } }
public void SelectProbe(ProbeIndex probe) { Probe = probe; Pairing.SelectProbe(probe.Template); CandidateEdges = ParameterSet.ClonePrototype(EdgeTablePrototype); }
public Grid() { TabEdg = new EdgeTable(); TabPos = new PosTable(); }
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; }
/// <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; }