Example #1
0
/**
 * Raster the color triangle to the screen.  Points are in
 * NDC coordinates (converted to screen coordinates).
 *
 * colors correspond to the respective points.
 */
void raster_triangle(point *a, point *b, point *c, color ca,
		color cb, color cc, int xres, int yres, color** grid,
		float** depth_grid) {
	point screen_a = NDC_to_screen(a, xres, yres);
	point screen_b = NDC_to_screen(b, xres, yres);
	point screen_c = NDC_to_screen(c, xres, yres);

	float x_min = min_x(&screen_a, &screen_b, &screen_c);
	float x_max = max_x(&screen_a, &screen_b, &screen_c);
	float y_min = min_y(&screen_a, &screen_b, &screen_c);
	float y_max = max_y(&screen_a, &screen_b, &screen_c);

	x_max = x_max > xres ? xres : x_max;
	y_max = y_max > yres ? yres : y_max;

	for (int x = x_min; x < x_max; x++) {
		for (int y = y_min; y < y_max; y++) {
			point curr_point = create_point(x, y, 0);
			float alpha = compute_alpha(&screen_a, &screen_b, &screen_c, &curr_point);
			float beta = compute_beta(&screen_a, &screen_b, &screen_c, &curr_point);
			float gamma = compute_gamma(&screen_a, &screen_b, &screen_c, &curr_point);
			curr_point.z = alpha * screen_a.z + beta * screen_b.z + gamma * screen_c.z;

			if (valid_parameters(alpha, beta, gamma) && depth_grid[x][y] > curr_point.z) {
				color col = compute_color(ca, cb, cc, alpha, beta, gamma);
				grid[x][y].r = col.r;
				grid[x][y].g = col.g;
				grid[x][y].b = col.b;

				depth_grid[x][y] = curr_point.z;
			}
		}
	}
}
Example #2
0
/**
 * Also has depth buffering and ignores points where normals point away
 *
 * Points a, b, c are in NDC
 */
void raster_triangle_Phong(point *a, point *b, point *c,
		point *world_a, point *world_b, point *world_c,
		point *normal_a, point *normal_b, point *normal_c,
		object_copy *obj, vector<light> *lights, camera *CAM,
		int xres, int yres, color** grid, float** depth_grid,
		MatrixXd *perspective, MatrixXd *inv_cam) {

	point screen_a = NDC_to_screen(a, xres, yres);
	point screen_b = NDC_to_screen(b, xres, yres);
	point screen_c = NDC_to_screen(c, xres, yres);

	float x_min = min_x(&screen_a, &screen_b, &screen_c);
	float x_max = max_x(&screen_a, &screen_b, &screen_c);
	float y_min = min_y(&screen_a, &screen_b, &screen_c);
	float y_max = max_y(&screen_a, &screen_b, &screen_c);

	x_max = x_max > xres ? xres : x_max;
	y_max = y_max > yres ? yres : y_max;
	x_min = x_min < 0 ? 0 : x_min;
	y_min = y_min < 0 ? 0 : y_min;

	// TODO: compute colors by normals

	for (int x = x_min; x < x_max; x++) {
		for (int y = y_min; y < y_max; y++) {
			// get alpha/beta/gamma
			point curr_point = create_point(x, y, 0);
			float alpha = compute_alpha(&screen_a, &screen_b, &screen_c, &curr_point);
			float beta = compute_beta(&screen_a, &screen_b, &screen_c, &curr_point);
			float gamma = compute_gamma(&screen_a, &screen_b, &screen_c, &curr_point);
			curr_point.z = alpha * screen_a.z + beta * screen_b.z + gamma * screen_c.z;

			// compute interpolated point (in world view) and normal for the point
			point normal = (*normal_a) * alpha + (*normal_b) * beta + (*normal_c) * gamma;
			point coordinate = (*world_a) * alpha + (*world_b) * beta + (*world_c) * gamma;
			point ndc_coordinate = to_NDC(&coordinate, perspective, inv_cam);

			if (is_in_box(&ndc_coordinate) && valid_parameters(alpha, beta, gamma)
					&& depth_grid[x][y] > curr_point.z) {
				color col = lighting(&coordinate, &normal, obj, lights, CAM);
				grid[x][y].r = col.r;
				grid[x][y].g = col.g;
				grid[x][y].b = col.b;

				depth_grid[x][y] = curr_point.z;
			}
		}
	}
}
Example #3
0
int main(int argc, char *argv[]) {
    /* local variable declarations */
    //int           i,
    int surface_num_stream = 0;
    int subsurface_num_stream = 0;
    int surface_num_patches = 0;
    int subsurface_num_patches = 0;
    FILE *out1, *out2;
    int basinid, tmp, maxr, maxc;
    double cell, width;
    int pst_flag;
    int f_flag; /**< boolean value determining whether route_roads_to_patches should be called */
    int fl_flag;
    int fh_flag;
    int vflag;
    int s_flag;
    int r_flag;
    int slp_flag; /**< Slope flag, values defined in main.h */
    int sc_flag; /**< Stream connectivity flag, values defined in main.h */
    //int           st_flag,
    int sewer_flag; /**< Sewer flag, boolean indicating whether sewer map is present */
    int singleFlowtable_flag; /**< boolean indicating if a single flow table is to produce or
    							   if separate surface and sub-surface tables are to be produced */
    int roofs_flag; /**< Roofs flag, was a roofs raster specified at the command line? */
    int d_flag, dbg_flag;
    double scale_trans, scale_dem;
    char input_prefix[MAXS];
    char output_suffix[MAXS];

    /* filenames for each image and file */
    char name[MAXS], name2[MAXS];
    char* rnflna;
    char* rnslope;
    char* fntemplate;
    char rnbasin[MAXS];
    char rnhill[MAXS];
    char rnzone[MAXS];
    char rnpatch[MAXS];
    char* rndem;
    char* rnroads;
    char* rnimpervious;
    char* rnstream;
    char* rnsewers;
    char* rnroofs;
        
    /* set pointers for images */
    double *dem;
    int *patch;
    float *slope;
    int *hill;
    int *zone;
    int *stream;
    int *roads;
    int *impervious;
    int *sewers;
    double *flna;
    double* roofs;

    bool success = true;
    
    //float          *ehr;
    //float          *whr;

    PatchTable_t *surfacePatchTable = NULL;
    PatchTable_t *subsurfacePatchTable = NULL;
    struct flow_struct* surface_flow_table = NULL;
    struct flow_struct* subsurface_flow_table = NULL;
        
    d_flag = FALSE; /**< debuf flag                                  */
    vflag = FALSE; /**< verbose flag                                         */
    fl_flag = FALSE; /**< roads to lowest flna                       */
    fh_flag = FALSE; /**< roads to highest flna              */
    s_flag = FALSE; /**< printing stats flag                         */
    r_flag = FALSE; /**< road stats flag                             */
    sc_flag = STREAM_CONNECTIVITY_RANDOM; /**< stream connectivity flag              */
    slp_flag = SLOPE_STANDARD; /**< slope use flag                   */
    //st_flag  = 0;         /**< scaling stream side patches         */
    sewer_flag = FALSE; /**< route through a sewer network (NOT YET IMPLEMENTED) */
    roofs_flag = FALSE;
    singleFlowtable_flag = TRUE; /**< Generate a single combined surface and sub-surface
    								  flow table unless a surface feature dataset is provided
    								  e.g. roofs */
    dbg_flag = FALSE; /**< debugging flag, set to not remove temp files */
    scale_trans = 1.0;
    scale_dem = 1.0; /**< scaling for dem values        */
    pst_flag = FALSE; /**< print stream table flag            */
    cell = DEFAULT_CELL_RESOLUTION; /**< default resolution of DEM          */
    width = DEFAULT_ROAD_WIDTH; /**< default road width            */
    basinid = DEFAULT_BASIN_ID;

    // GRASS init
    G_gisinit(argv[0]);

    // GRASS module header
    struct GModule* module;
    module = G_define_module();
    module->keywords = "RHESSys";
    module->description = "Creates a flowpaths file for input into RHESSys";

    // GRASS arguments
    struct Flag* debug_flag = G_define_flag();
    debug_flag->key = 'g';
    debug_flag->description = "Enable printouts during compuation of flowpaths";

    struct Flag* lowest_flna_flag = G_define_flag();
    lowest_flna_flag->key = 'l';
    lowest_flna_flag->description = "Roads to lowest flna interval";

    struct Flag* highest_flna_flag = G_define_flag();
    highest_flna_flag->key = 'h';
    highest_flna_flag->description = "Roads to highest flna interval";

    struct Flag* drainage_stats_flag = G_define_flag();
    drainage_stats_flag->key = 'd';
    drainage_stats_flag->description = "Print drainage statistics";

    struct Flag* road_drainage_stats_flag = G_define_flag();
    road_drainage_stats_flag->key = 'r';
    road_drainage_stats_flag->description = "Road flag for drainage statistics";

    struct Option* stream_connectivity_opt = G_define_option();
    stream_connectivity_opt->key = "streamcon";
    stream_connectivity_opt->type = TYPE_STRING;
    stream_connectivity_opt->required = NO;
    stream_connectivity_opt->description =
        "Stream connectivity type: [random(default), internal, none]";
    stream_connectivity_opt->multiple = NO;

    struct Option* scale_dem_opt = G_define_option();
    scale_dem_opt->key = "scaledem";
    scale_dem_opt->type = TYPE_DOUBLE;
    scale_dem_opt->required = NO;
    scale_dem_opt->description = "DEM scaling factor";

    struct Option* cell_size = G_define_option();
    cell_size->key = "cellsize";
    cell_size->type = TYPE_DOUBLE;
    cell_size->required = YES;
    cell_size->description = "cell size [Default 10m]";

    struct Option* scale_stream_trans = G_define_option();
    scale_stream_trans->key = "scaletrans";
    scale_stream_trans->type = TYPE_DOUBLE;
    scale_stream_trans->required = NO;
    scale_stream_trans->description =
        "Scaleing factor for streamside transmissivity";

    struct Flag* use_sewer_flag = G_define_flag();
    use_sewer_flag->key = 's';
    use_sewer_flag->description = "Use a sewer image to route water from roads";

    struct Flag* print_stream_table_flag = G_define_flag();
    print_stream_table_flag->key = 'p';
    print_stream_table_flag->description = "Print stream table";

    struct Option* road_width_opt = G_define_option();
    road_width_opt->key = "roadwidth";
    road_width_opt->type = TYPE_DOUBLE;
    road_width_opt->required = NO;
    road_width_opt->description = "Road width(m). [Default 5m]";

    struct Option* slope_use_opt = G_define_option();
    slope_use_opt->key = "slopeuse";
    slope_use_opt->type = TYPE_STRING;
    slope_use_opt->required = NO;
    slope_use_opt->description =
        "Change the use of slope in the compuation of gamma [standard(default), internal, max]";

    struct Option* basin_id_opt = G_define_option();
    basin_id_opt->key = "basinid";
    basin_id_opt->type = TYPE_INTEGER;
    basin_id_opt->required = NO;
    basin_id_opt->description = "Basin ID";

    struct Option* output_name_opt = G_define_option();
    output_name_opt->key = "output";
    output_name_opt->type = TYPE_STRING;
    output_name_opt->required = YES;
    output_name_opt->description = "Output name";

    // Arguments that specify the names of required raster maps
    struct Option* stream_raster_opt = G_define_option();
    stream_raster_opt->key = "stream";
    stream_raster_opt->type = TYPE_STRING;
    stream_raster_opt->required = YES;
    stream_raster_opt->description = "stream";

    struct Option* road_raster_opt = G_define_option();
    road_raster_opt->key = "road";
    road_raster_opt->type = TYPE_STRING;
    road_raster_opt->required = YES;
    road_raster_opt->description = "road";

    struct Option* impervious_raster_opt = G_define_option();
    impervious_raster_opt->key = "impervious";
    impervious_raster_opt->type = TYPE_STRING;
    impervious_raster_opt->required = NO;
    impervious_raster_opt->description = "impervious";

    struct Option* dem_raster_opt = G_define_option();
    dem_raster_opt->key = "dem";
    dem_raster_opt->type = TYPE_STRING;
    dem_raster_opt->required = YES;
    dem_raster_opt->description = "dem";

    struct Option* slope_raster_opt = G_define_option();
    slope_raster_opt->key = "slope";
    slope_raster_opt->type = TYPE_STRING;
    slope_raster_opt->required = YES;
    slope_raster_opt->description = "slope";

    struct Option* template_opt = G_define_option();
    template_opt->key = "template";
    template_opt->type = TYPE_STRING;
    template_opt->required = YES;
    template_opt->description =
        "RHESSys template file from which to extract the basin, hill, zone, and patch GRASS rasters";

    struct Option* flna_raster_opt = G_define_option();
    flna_raster_opt->key = "flna";
    flna_raster_opt->type = TYPE_STRING;
    flna_raster_opt->required = NO;
    flna_raster_opt->description = "FLNA map";

    struct Option* sewers_raster_opt = G_define_option();
    sewers_raster_opt->key = "sewer";
    sewers_raster_opt->type = TYPE_STRING;
    sewers_raster_opt->required = NO;
    sewers_raster_opt->description = "Sewer map";

    struct Option* roof_opt = G_define_option();
    roof_opt->key = "roof";
    roof_opt->type = TYPE_STRING;
    roof_opt->required = NO;
    roof_opt->description = "Roof map";
        
    // Parse GRASS arguments
    if (G_parser(argc, argv)) exit(EXIT_FAILURE);

    // Get values from GRASS arguments
    dbg_flag = debug_flag->answer;
    fl_flag = lowest_flna_flag->answer;
    fh_flag = highest_flna_flag->answer;
    if (fl_flag || fh_flag) {
        f_flag = TRUE;
    } else {
        f_flag = FALSE;
    }
    s_flag = drainage_stats_flag->answer;
    r_flag = road_drainage_stats_flag->answer;

    if (stream_connectivity_opt->answer != NULL ) {
        // Default is 1, random connectivity. See sc_flag declaration for setting default.
        if (strcmp("random", stream_connectivity_opt->answer) == 0) {
            sc_flag = STREAM_CONNECTIVITY_RANDOM;
        } else if (strcmp("internal", stream_connectivity_opt->answer) == 0) {
            sc_flag = STREAM_CONNECTIVITY_INTERNAL;
        } else if (strcmp("none", stream_connectivity_opt->answer) == 0) {
            sc_flag = STREAM_CONNECTIVITY_NONE;
        } else {
            G_fatal_error("\"%s\" is not a valid argument to stream",
                          stream_connectivity_opt->answer);
        }
    }

    if (scale_dem_opt->answer != NULL ) {
        // Default is set at declaration, only modify if set
        if (sscanf(scale_dem_opt->answer, "%lf", &scale_dem) != 1) {
            G_fatal_error("Error setting the scale dem value");
        }
    }

    if (cell_size->answer != NULL ) {
        // Default is set at declaration, only modify if set
        if (sscanf(cell_size->answer, "%lf", &cell) != 1) {
            G_fatal_error("Error setting the cell size value");
        }
    }

    if (scale_stream_trans->answer != NULL ) {
        // Default is set at declaration, only modify if set
        if (sscanf(scale_stream_trans->answer, "%lf", &scale_trans) != 1) {
            G_fatal_error("Error setting the scale trans value");
        }
    }

    sewer_flag = use_sewer_flag->answer;
    pst_flag = print_stream_table_flag->answer;

    if (road_width_opt->answer != NULL ) {
        // Default is set at declaration
        if (sscanf(road_width_opt->answer, "%lf", &width) != 1) {
            G_fatal_error("Error setting the road width value");
        }
    }

    if (slope_use_opt->answer != NULL ) {
        if (strcmp("standard", slope_use_opt->answer) == 0) {
            slp_flag = SLOPE_STANDARD;
        } else if (strcmp("internal", slope_use_opt->answer) == 0) {
            slp_flag = SLOPE_INTERNAL;
        } else if (strcmp("max", slope_use_opt->answer) == 0) {
            slp_flag = SLOPE_MAX;
        } else {
            G_fatal_error("\"%s\" is not a valid argument to slopeuse",
                          slope_use_opt->answer);
        }
    }

    if (basin_id_opt->answer != NULL ) {
        // Default set at declaration
        if (sscanf(basin_id_opt->answer, "%d", &basinid) != 1) {
            G_fatal_error("Error setting the basin ID value");
        }
    }

    // Name for output files, default to template file name
    // Input prefix is left over from pre-grass version.
    strcpy(input_prefix, output_name_opt->answer);
    strcpy(output_suffix, ".flow");

    if (flna_raster_opt->answer != NULL ) {
        rnflna = flna_raster_opt->answer;
    }

    if (sewers_raster_opt->answer != NULL ) {
        rnsewers = sewers_raster_opt->answer;
    }

    // Right now, the only trigger for generating separate surface and subsurface flow tables
    // is if the user provides a roof connectivity layer
    if ( roof_opt->answer != NULL ) {
    	if ( impervious_raster_opt->answer == NULL ) {
    		G_fatal_error("Impervious raster must be specified when roof connectivity raster is specified");
    	}
    	singleFlowtable_flag = FALSE;
    	roofs_flag = TRUE;
    }

    // Need to implement verbose
    rndem = dem_raster_opt->answer;
    fntemplate = template_opt->answer;
    rnroads = road_raster_opt->answer;
    rnimpervious = impervious_raster_opt->answer;
    rnstream = stream_raster_opt->answer;
    rnslope = slope_raster_opt->answer;
    rnroofs = roof_opt->answer;
        
    printf("Create_flowpaths.C\n\n");

    // Read in the names of the basin, hill, zone, and patch maps from the
    // template file.
    FILE* template_fp = fopen(fntemplate, "r");
    if (template_fp == NULL ) {
        G_fatal_error("Can not open template file <%s>", fntemplate);
    }

    char template_buffer[MAXS];
    char first[MAXS];
    char second[MAXS];

    printf("Reading template file %s\n", fntemplate);

    while (fgets(template_buffer, sizeof(template_buffer), template_fp)
           != NULL ) {
        sscanf(template_buffer, "%s %s", first, second);

        // Check if the token is anything we are looking for
        if (strcmp("_basin", first) == 0) {
            strcpy(rnbasin, second);
            printf("Basin: %s\n", rnbasin);
        } else if (strcmp("_hillslope", first) == 0) {
            strcpy(rnhill, second);
            printf("Hillslope: %s\n", rnhill);
        } else if (strcmp("_zone", first) == 0) {
            strcpy(rnzone, second);
            printf("Zone: %s\n", rnzone);
        } else if (strcmp("_patch", first) == 0) {
            strcpy(rnpatch, second);
            printf("Patch: %s\n", rnpatch);
        }
    }
    fclose(template_fp);

    /* open some diagnostic output files */

    strcpy(name, input_prefix);
    strcat(name, ".build");
    if ((out1 = fopen(name, "w")) == NULL ) {
        printf("cannot open build file\n");
        exit(EXIT_FAILURE);
    }

    strcpy(name2, input_prefix);
    strcat(name2, ".pit");
    if ((out2 = fopen(name2, "w")) == NULL ) {
        printf("cannot open pit file\n");
        exit(EXIT_FAILURE);
    }

    /* allocate and input map images */
    // figure out what's happening with maxr, maxc, possible raster
    // size mismatch
    struct Cell_head dem_header;
    dem = (double*) raster2array(rndem, &dem_header, &maxr, &maxc, DCELL_TYPE);

    struct Cell_head patch_header;
    patch = (int*) raster2array(rnpatch, &patch_header, NULL, NULL, CELL_TYPE);

    // Get cell size based off of that in the patchmap
    // Does not assume pixels are square, instead takes the root of their
    // square.
    /* cell = sqrt(patch_header.ew_res * patch_header.ns_res); */

    printf("\n cell resolution is %lf ", cell);

    struct Cell_head zone_header;
    zone = (int*) raster2array(rnzone, &zone_header, NULL, NULL, CELL_TYPE);

    struct Cell_head hill_header;
    hill = (int*) raster2array(rnhill, &hill_header, NULL, NULL, CELL_TYPE);

    struct Cell_head stream_header;
    stream = (int*) raster2array(rnstream, &stream_header, NULL, NULL,
                                 CELL_TYPE);

    if ((STREAM_CONNECTIVITY_RANDOM == sc_flag)
        || (SLOPE_STANDARD != slp_flag)) {
        struct Cell_head slope_header;
        slope = (float*) raster2array(rnslope, &slope_header, NULL, NULL,
                                      FCELL_TYPE);
    }

    struct Cell_head roads_header;
    roads = (int*) raster2array(rnroads, &roads_header, NULL, NULL, CELL_TYPE);
        
    // Added to support roof raster map - hcj
    if (roofs_flag) {
    	int roofsRows, roofsCols;
    	struct Cell_head roofs_header;
    	roofs = (double*) raster2array(rnroofs, &roofs_header, NULL, NULL, DCELL_TYPE);

    	struct Cell_head impervious_header;
    	impervious = (int*) raster2array(rnimpervious, &impervious_header, NULL, NULL, CELL_TYPE);
    }

    if (sewer_flag) {
        struct Cell_head sewers_header;
        sewers = (int*) raster2array(rnsewers, &sewers_header, NULL, NULL,
                                     CELL_TYPE);
    }

    if (f_flag) {
        struct Cell_head flna_header;
        flna = (double*) raster2array(rnflna, &flna_header, NULL, NULL,
                                      DCELL_TYPE);
    } else
        flna = NULL;

    /* allocate patch tables */
    // Use relatively large tables, some users may need to make the table larger
    // for very large numbers of patches (>100k) to improve performance (table size is currently static)
    if (!singleFlowtable_flag) {
    	surfacePatchTable = allocatePatchHashTable(PATCH_HASH_TABLE_DEFAULT_SIZE);
    }
    subsurfacePatchTable = allocatePatchHashTable(PATCH_HASH_TABLE_DEFAULT_SIZE);


    /* allocate flow table */
    if (!singleFlowtable_flag) {
		surface_flow_table = (struct flow_struct *) calloc((maxr * maxc),
														   sizeof(struct flow_struct));
    }
    subsurface_flow_table = (struct flow_struct *) calloc((maxr * maxc),
                                                          sizeof(struct flow_struct));

    if (!singleFlowtable_flag) {
		printf("\n Building surface flow table");
		surface_num_patches = build_flow_table(surface_flow_table, surfacePatchTable, dem, slope, hill, zone, patch,
											   stream, roads, sewers, roofs, flna, out1, maxr, maxc, f_flag, sc_flag,
											   sewer_flag, slp_flag, cell, scale_dem, true);

		printf("\n Building subsurface flow table");
    } else {
    	printf("\n Building flow table");
    }
    subsurface_num_patches = build_flow_table(subsurface_flow_table, subsurfacePatchTable, dem, slope, hill, zone, patch,
                                              stream, roads, sewers, roofs, flna, out1, maxr, maxc, f_flag, sc_flag,
                                              sewer_flag, slp_flag, cell, scale_dem, false);
        
    fclose(out1);

    // Do some verification for debugging purposes
    // success = verify_num_adjacent(surface_flow_table, surface_num_patches);
    
    // Short circuit roof patches to the nearest road patches
    if (roofs_flag) {
    	printf("\n Route roofs to roads");
    	success = route_roofs_to_roads(surface_flow_table, surface_num_patches, surfacePatchTable, roofs, impervious, stream, patch, hill, zone, maxr, maxc);
    }

    // Do some verification for debugging purposes
    // success = verify_num_adjacent(surface_flow_table, surface_num_patches);
    
    // Normalize roof patches
    if (roofs_flag) {
    	printf("\n Normalizing roof patches");
    	success = normalize_roof_patches(surface_flow_table, surface_num_patches);
    }

    if (!singleFlowtable_flag) {
		/* processes patches - computing means and neighbour slopes and gammas */
		printf("\n Computing surface gamma");
		surface_num_stream = compute_gamma(surface_flow_table, surface_num_patches, surfacePatchTable, out2, scale_trans, cell,
										   sc_flag, slp_flag, d_flag, true);

		printf("\n Computing subsurface gamma");
    } else {
    	printf("\n Computing gamma");
    }
    subsurface_num_stream = compute_gamma(subsurface_flow_table, subsurface_num_patches, subsurfacePatchTable, out2, scale_trans, cell,
                                          sc_flag, slp_flag, d_flag, false);

    /* remove pits and re-order patches appropriately */
    if (!singleFlowtable_flag) {
		printf("\n Removing surface pits");
		remove_pits(surface_flow_table, surface_num_patches, sc_flag, slp_flag, cell, out2);

		printf("\n Removing subsurface pits");
    } else {
    	printf("\n Removing pits");
    }
    remove_pits(subsurface_flow_table, subsurface_num_patches, sc_flag, slp_flag, cell, out2);

    /* add roads */
    if (!singleFlowtable_flag) {
		printf("\n Adding roads to surface");
		add_roads(surface_flow_table, surface_num_patches, out2, cell);

		printf("\n Adding roads to subsurface");
    } else {
    	printf("\n Adding roads");
    }
    add_roads(subsurface_flow_table, subsurface_num_patches, out2, cell);

    /* find_receiving patch for flna options */
    if (!singleFlowtable_flag) {
    	if (f_flag) route_roads_to_patches(surface_flow_table, surface_num_patches, fl_flag);
    }
    if (f_flag) route_roads_to_patches(subsurface_flow_table, subsurface_num_patches, fl_flag);

    if (!singleFlowtable_flag) {
		printf("\n Computing surface upslope area");
		tmp = compute_upslope_area(surface_flow_table, surface_num_patches, out2, r_flag, cell);

		printf("\n Computing subsurface upslope area");
    } else {
    	printf("\n Computing upslope area");
    }
    tmp = compute_upslope_area(subsurface_flow_table, subsurface_num_patches, out2, r_flag, cell);

    if (s_flag) {
        if (!singleFlowtable_flag) {
        	printf("\n Printing surface drainage stats");
        	print_drain_stats(surface_num_patches, surface_flow_table);
        	tmp = compute_dist_from_road(surface_flow_table, surface_num_patches, out2, cell);
        	tmp = compute_drainage_density(surface_flow_table, surface_num_patches, cell);

        	printf("\n Printing subsurface drainage stats");
        } else {
        	printf("\n Printing drainage stats");
        }
        print_drain_stats(subsurface_num_patches, subsurface_flow_table);
        tmp = compute_dist_from_road(subsurface_flow_table, subsurface_num_patches, out2, cell);
        tmp = compute_drainage_density(subsurface_flow_table, subsurface_num_patches, cell);
    }

    if (!singleFlowtable_flag) {
		printf("\n Printing surface flowtable");
		strncpy(output_suffix, "_surface.flow", MAXS);
		print_flow_table(surface_num_patches, surface_flow_table, sc_flag, slp_flag, cell,
						 scale_trans, input_prefix, output_suffix, width);

		printf("\n Printing subsurface flowtable");
		strncpy(output_suffix, "_subsurface.flow", MAXS);
    } else {
    	printf("\n Printing flowtable");
    	strncpy(output_suffix, ".flow", MAXS);
    }
    print_flow_table(subsurface_num_patches, subsurface_flow_table, sc_flag, slp_flag, cell,
                     scale_trans, input_prefix, output_suffix, width);

    /* Print stream table */
    // SHOULD THIS ONLY BE DONE FOR THE SURFACE FLOW TABLE IF THERE ARE TWO FLOW TABLES? bcm
    if (pst_flag) {
    	if (!singleFlowtable_flag) {
			printf("\n Printing surface stream table");
			strncpy(output_suffix, "_surface.flow", MAXS);
			print_stream_table(surface_num_patches, surface_num_stream, surface_flow_table, sc_flag,
							   slp_flag, cell, scale_trans, input_prefix, output_suffix, width,
							   basinid);

			printf("\n Printing subsurface stream table");
			strncpy(output_suffix, "_subsurface.flow", MAXS);
    	} else {
    		printf("\n Printing  stream table");
    		strncpy(output_suffix, ".flow", MAXS);
    	}
        print_stream_table(subsurface_num_patches, subsurface_num_stream, subsurface_flow_table, sc_flag,
                           slp_flag, cell, scale_trans, input_prefix, output_suffix, width,
                           basinid);
    }

    fclose(out2);

    // Remove temporary files
    char buildfn[MAXS];
    char gammafn[MAXS];
    char pitfn[MAXS];
    strcpy(buildfn, input_prefix);
    strcpy(gammafn, input_prefix);
    strcpy(pitfn, input_prefix);
    strcat(buildfn, ".build");
    strcat(gammafn, ".gamma");
    strcat(pitfn, ".pit");

    if (!dbg_flag) { // Do not clean up temp files if debugging is enabled
        printf("\n Cleaning up temporary files");
        if (remove(buildfn) != 0)
            printf("\n Unable to remove .build temp file");
        if (remove(gammafn) != 0)
            printf("\n Unable to remove .gamma temp file");
        if (remove(pitfn) != 0)
            printf("\n Unable to remove .pit temp file");
        if (remove("RoofGeometries.txt") != 0) {
        	printf("\n Unable to remove RoofGeometry temp file");
        }
    }

    if (!singleFlowtable_flag) {
    	freePatchHashTable(surfacePatchTable);
    }
    freePatchHashTable(subsurfacePatchTable);

    printf("\n Finished Createflowpaths \n\n");
    return (EXIT_SUCCESS);
} /* end main.c */