[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46223] branches/soc-2011-tomato/intern/ raskter/raskter.c: Tomato: update raskter library to newer version from Pete Larbell

Sergey Sharybin sergey.vfx at gmail.com
Thu May 3 09:32:26 CEST 2012


Revision: 46223
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46223
Author:   nazgul
Date:     2012-05-03 07:32:26 +0000 (Thu, 03 May 2012)
Log Message:
-----------
Tomato: update raskter library to newer version from Pete Larbell

Modified Paths:
--------------
    branches/soc-2011-tomato/intern/raskter/raskter.c

Modified: branches/soc-2011-tomato/intern/raskter/raskter.c
===================================================================
--- branches/soc-2011-tomato/intern/raskter/raskter.c	2012-05-03 06:57:30 UTC (rev 46222)
+++ branches/soc-2011-tomato/intern/raskter/raskter.c	2012-05-03 07:32:26 UTC (rev 46223)
@@ -31,8 +31,11 @@
 #include <malloc.h>
 #include "raskter.h"
 
-#define R_XCHG(a,b)	t=a;a=b;b=t;
+// from BLI_utildefines.h
+#define MIN2(x,y)               ( (x)<(y) ? (x) : (y) )
+#define MAX2(x,y)               ( (x)>(y) ? (x) : (y) )
 
+
 struct e_status {
 	int x;
 	int ybeg;
@@ -69,7 +72,7 @@
 	int yend;
 	int dx;
 	int dy;
-	int t;
+	int temp_pos;
 	int xdist;
 	struct e_status *e_new;
 	struct e_status *next_edge;
@@ -80,36 +83,58 @@
 	all_edges = NULL;
 	// loop all verts
 	for(i = 0; i < num_verts; i++) {
+		// determine beginnings and endings of edges, linking last vertex to first vertex
 		xbeg = v[i].x;
 		ybeg = v[i].y;
-		// determine starts and ends of edges, linking last vertex to first vertex
-		if(i == 0) {
+		if(i) {
+			// we're not at the last vert, so end of the edge is the previous vertex
+			xend = v[i-1].x;
+			yend = v[i-1].y;
+		} else {
+			// we're at the first vertex, so the "end" of this edge is the last vertex
 			xend = v[num_verts-1].x;
 			yend = v[num_verts-1].y;
-		} else {
-			xend = v[i-1].x;
-			yend = v[i-1].y;
 		}
 		// make sure our edges are facing the correct direction
 		if(ybeg > yend) {
-			R_XCHG(xbeg, xend);
-			R_XCHG(ybeg, yend);
+			// flip the Xs
+			temp_pos = xbeg;
+			xbeg = xend;
+			xend = temp_pos;
+			// flip the Ys
+			temp_pos = ybeg;
+			ybeg = yend;
+			yend = temp_pos;
 		}
-		// create the edge and determine it's slope (for incremental line drawing)
-		if((dy = yend - ybeg) != 0) {
+
+		// calculate y delta
+		dy = yend - ybeg;
+		// dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :)
+		if(dy) {
+			// create the edge and determine it's slope (for incremental line drawing)
 			e_new = open_edge++;
-			e_new->xdir = ((dx = xend - xbeg) > 0) ? 1 : -1;
-			xdist = (dx > 0) ? dx : -dx;
+
+			// calculate x delta
+			dx = xend - xbeg;
+			if(dx > 0){
+				e_new->xdir = 1;
+				xdist = dx;
+			}else{
+				e_new->xdir = -1;
+				xdist = -dx;
+			}
+
 			e_new->x = xbeg;
 			e_new->ybeg = ybeg;
 			e_new->num = dy;
 			e_new->drift_dec = dy;
+
+			// calculate deltas for incremental drawing
 			if(dx >= 0) {
 				e_new->drift = 0;
 			} else {
 				e_new->drift = -dy + 1;
 			}
-			// calculate deltas for drawing
 			if(dy >= xdist) {
 				e_new->drift_inc = xdist;
 				e_new->xshift = 0;
@@ -121,7 +146,7 @@
 			// link in all the edges, in sorted order
 			for(;;) {
 				next_edge = *next_edge_ref;
-				if((next_edge == NULL) || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) {
+				if(!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) {
 					e_new->e_next = next_edge;
 					*next_edge_ref = e_new;
 					break;
@@ -197,7 +222,7 @@
 	  TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here.
 			Will get changed once DEM code gets in.
 	 */
-	for(y_curr = (all_edges->ybeg > 0 ? all_edges->ybeg : 0); ((all_edges != NULL) || (possible_edges != NULL)) && (y_curr < rb.sizey); y_curr++) {
+	for(y_curr = MAX2(all_edges->ybeg,0); (all_edges || possible_edges) && (y_curr < rb.sizey); y_curr++) {
 
 		/*
 		  Link any edges that start on the current scan line into the list of
@@ -214,19 +239,19 @@
 
 		  At each iteration, make sure we still have a non-NULL edge.
 		 */
-		for(edgec = &possible_edges; (all_edges != NULL) && (all_edges->ybeg == y_curr);) {
+		for(edgec = &possible_edges; all_edges && (all_edges->ybeg == y_curr);) {
 			x_curr = all_edges->x;                                // Set current X position.
-			for(;;) {                                       // Start looping edges. Will break when edges run out.
-				e_curr = *edgec;                            // Set up a current edge pointer.
-				if((e_curr == NULL) || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span,
+			for(;;) {                                             // Start looping edges. Will break when edges run out.
+				e_curr = *edgec;                                  // Set up a current edge pointer.
+				if(!e_curr || (e_curr->x >= x_curr)) {            // If we have an no edge, or we need to skip some X-span,
 					e_temp = all_edges->e_next;                   // set a temp "next" edge to test.
 					*edgec = all_edges;                           // Add this edge to the list to be scanned.
 					all_edges->e_next = e_curr;                   // Set up the next edge.
 					edgec = &all_edges->e_next;                   // Set our list to the next edge's location in memory.
 					all_edges = e_temp;                           // Skip the NULL or bad X edge, set pointer to next edge.
-					break;                                  // Stop looping edges (since we ran out or hit empty X span.
+					break;                                        // Stop looping edges (since we ran out or hit empty X span.
 				} else {
-					edgec = &e_curr->e_next;                // Set the pointer to the edge list the "next" edge.
+					edgec = &e_curr->e_next;                      // Set the pointer to the edge list the "next" edge.
 				}
 			}
 		}
@@ -248,7 +273,7 @@
 		  At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge
 		  we will eventually hit a NULL when the list runs out.
 		 */
-		for(e_curr = possible_edges; e_curr != NULL; e_curr = e_curr->e_next) {
+		for(e_curr = possible_edges; e_curr; e_curr = e_curr->e_next) {
 			/*
 			  Calculate a span of pixels to fill on the current scan line.
 
@@ -263,9 +288,12 @@
 			  TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor,
 					but for now it is done here until the DEM code comes in.
 			*/
-			cpxl = spxl + (e_curr->x > 0 ? e_curr->x : 0);
+			// set up xmin and xmax bounds on this scan line
+			cpxl = spxl + MAX2(e_curr->x,0);
 			e_curr = e_curr->e_next;
-			mpxl = spxl + (e_curr->x < rb.sizex ? e_curr->x : rb.sizex) - 1;
+			mpxl = spxl + MIN2(e_curr->x,rb.sizex) - 1;
+
+			// draw the pixels.
 			for(; cpxl <= mpxl; *cpxl++ = 1.0f);
 		}
 
@@ -278,8 +306,8 @@
 		  polygons, we dont have fractional positions, so we only move in x-direction
 		  when needed to get all the way to the next pixel over...
 		 */
-		for(edgec = &possible_edges; (e_curr = *edgec) != NULL;) {
-			if((--(e_curr->num)) == 0) {
+		for(edgec = &possible_edges; (e_curr = *edgec);) {
+			if(!(--(e_curr->num))) {
 				*edgec = e_curr->e_next;
 			} else {
 				e_curr->x += e_curr->xshift;
@@ -298,29 +326,39 @@
 		  pass, then we know we need to sort by x, so then cycle through edges again and perform
 		  the sort.-
 		 */
-		if(possible_edges != NULL) {
-			for(edgec = &possible_edges; (e_curr = *edgec)->e_next != NULL;) {
+		if(possible_edges) {
+			for(edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
+				// if the current edge hits scan line at greater X than the next edge, we need to exchange the edges
 				if(e_curr->x > e_curr->e_next->x) {
+					*edgec = e_curr->e_next;
+					// exchange the pointers
 					e_temp = e_curr->e_next->e_next;
-					*edgec = e_curr->e_next;
 					e_curr->e_next->e_next = e_curr;
 					e_curr->e_next = e_temp;
+					// set flag that we had at least one switch
 					swixd = 1;
 				}
-				edgec = &(*edgec)->e_next;
 			}
-			for(; swixd;) {
+			// if we did have a switch, look for more (there will more if there was one)
+			for(;;) {
+				// reset exchange flag so it's only set if we encounter another one
 				swixd = 0;
-				for(edgec = &possible_edges; (e_curr = *edgec)->e_next != NULL;) {
+				for(edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
+					// again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag
 					if(e_curr->x > e_curr->e_next->x) {
+						*edgec = e_curr->e_next;
+						// exchange the pointers
 						e_temp = e_curr->e_next->e_next;
-						*edgec = e_curr->e_next;
 						e_curr->e_next->e_next = e_curr;
 						e_curr->e_next = e_temp;
+						// flip the exchanged flag
 						swixd = 1;
 					}
-					edgec = &(*edgec)->e_next;
 				}
+				// if we had no exchanges, we're done reshuffling the pointers
+				if(!swixd) {
+					break;
+				}
 			}
 		}
 	}
@@ -365,3 +403,4 @@
 	free(ply);                                   // Free the memory allocated for the integer coordinate table.
 	return(i);                                   // Return the value returned by the rasterizer.
 }
+




More information about the Bf-blender-cvs mailing list