Example #1
0
void	ft_impact(t_draw_suite *val, t_ray *ray, t_tool *t)
{
	val->impact->o = vectoradd(ray->o,
	vectorscale(val->curobject->dist, ray->d));
	find_normal(val->impact, val->curobject);
	vectornorm(val->impact->d);
	init_color(t, val->curobject->color, val->final_color);
	val->curlight = t->l_lights;
	while (val->curlight)
	{
		val->lightray->o = vectorcopy(val->curlight->o);
		val->lightray->d = vectorsub(val->impact->o, val->lightray->o);
		vectornorm(val->lightray->d);
		if ((val->curobject2 = intersection(t->l_objects,
						val->lightray)) && val->curobject2 == val->curobject)
			ft_impact2(val);
		val->curlight = val->curlight->next;
	}
}
Example #2
0
void process(void)
{

    /*--------------------------------------------------------------------------*/
    /*                              INITIALISE                                  */

    /*--------------------------------------------------------------------------*/


    DCELL *row_in,		/* Buffer large enough to hold `wsize'  */
     *row_out = NULL,		/* raster rows. When GRASS reads in a   */
	/* raster row, each element is of type  */
	/* DCELL        */
	*window_ptr,		/* Stores local terrain window.         */
	centre;			/* Elevation of central cell in window. */

    CELL *featrow_out = NULL;	/* store features in CELL */

    struct Cell_head region;	/* Structure to hold region information */

    int nrows,			/* Will store the current number of     */
      ncols,			/* rows and columns in the raster.      */
      row, col,			/* Counts through each row and column   */
	/* of the input raster.                 */
      wind_row,			/* Counts through each row and column   */
      wind_col,			/* of the local neighbourhood window.   */
     *index_ptr;		/* Row permutation vector for LU decomp. */

    double **normal_ptr,	/* Cross-products matrix.               */
     *obs_ptr,			/* Observed vector.                     */
      temp;			/* Unused */

    double *weight_ptr;		/* Weighting matrix for observed values. */


    /*--------------------------------------------------------------------------*/
    /*                     GET RASTER AND WINDOW DETAILS                        */

    /*--------------------------------------------------------------------------*/

    G_get_window(&region);	/* Fill out the region structure (the   */
    /* geographical limits etc.)            */

    nrows = Rast_window_rows();	/* Find out the number of rows and      */
    ncols = Rast_window_cols();	/* columns of the raster.               */


    if ((region.ew_res / region.ns_res >= 1.01) ||	/* If EW and NS resolns are    */
	(region.ns_res / region.ew_res >= 1.01)) {	/* >1% different, warn user.      */
	G_warning(_("E-W and N-S grid resolutions are different. Taking average."));
	resoln = (region.ns_res + region.ew_res) / 2;
    }
    else
	resoln = region.ns_res;


    /*--------------------------------------------------------------------------*/
    /*              RESERVE MEMORY TO HOLD Z VALUES AND MATRICES                */

    /*--------------------------------------------------------------------------*/

    row_in = (DCELL *) G_malloc(ncols * sizeof(DCELL) * wsize);
    /* Reserve `wsize' rows of memory.      */

    if (mparam != FEATURE)
	row_out = Rast_allocate_buf(DCELL_TYPE);	/* Initialise output row buffer.     */
    else
	featrow_out = Rast_allocate_buf(CELL_TYPE);	/* Initialise output row buffer.  */

    window_ptr = (DCELL *) G_malloc(SQR(wsize) * sizeof(DCELL));
    /* Reserve enough memory for local wind. */

    weight_ptr = (double *)G_malloc(SQR(wsize) * sizeof(double));
    /* Reserve enough memory weights matrix. */

    normal_ptr = dmatrix(0, 5, 0, 5);	/* Allocate memory for 6*6 matrix       */
    index_ptr = ivector(0, 5);	/* and for 1D vector holding indices    */
    obs_ptr = dvector(0, 5);	/* and for 1D vector holding observed z */


    /* ---------------------------------------------------------------- */
    /* -            CALCULATE LEAST SQUARES COEFFICIENTS              - */
    /* ---------------------------------------------------------------- */

    /*--- Calculate weighting matrix. ---*/

    find_weight(weight_ptr);

    /* Initial coefficients need only be found once since they are 
       constant for any given window size. The only element that 
       changes is the observed vector (RHS of normal equations). */

    /*--- Find normal equations in matrix form. ---*/

    find_normal(normal_ptr, weight_ptr);


    /*--- Apply LU decomposition to normal equations. ---*/

    if (constrained) {
	G_ludcmp(normal_ptr, 5, index_ptr, &temp);
	/* To constrain the quadtratic 
	   through the central cell, ignore 
	   the calculations involving the
	   coefficient f. Since these are 
	   all in the last row and column of
	   the matrix, simply redimension.   */
	/* disp_matrix(normal_ptr,obs_ptr,obs_ptr,5);
	 */
    }

    else {
	G_ludcmp(normal_ptr, 6, index_ptr, &temp);
	/* disp_matrix(normal_ptr,obs_ptr,obs_ptr,6);
	 */
    }


    /*--------------------------------------------------------------------------*/
    /*          PROCESS INPUT RASTER AND WRITE OUT RASTER LINE BY LINE          */

    /*--------------------------------------------------------------------------*/

    if (mparam != FEATURE)
	for (wind_row = 0; wind_row < EDGE; wind_row++)
	    Rast_put_row(fd_out, row_out, DCELL_TYPE);	/* Write out the edge cells as NULL.    */
    else
	for (wind_row = 0; wind_row < EDGE; wind_row++)
	    Rast_put_row(fd_out, featrow_out, CELL_TYPE);	/* Write out the edge cells as NULL.    */

    for (wind_row = 0; wind_row < wsize - 1; wind_row++)
	Rast_get_row(fd_in, row_in + (wind_row * ncols), wind_row,
			 DCELL_TYPE);
    /* Read in enough of the first rows to  */
    /* allow window to be examined.         */

    for (row = EDGE; row < (nrows - EDGE); row++) {
	G_percent(row + 1, nrows - EDGE, 2);

	Rast_get_row(fd_in, row_in + ((wsize - 1) * ncols), row + EDGE,
			 DCELL_TYPE);

	for (col = EDGE; col < (ncols - EDGE); col++) {
	    /* Find central z value */
	    centre = *(row_in + EDGE * ncols + col);

	    for (wind_row = 0; wind_row < wsize; wind_row++)
		for (wind_col = 0; wind_col < wsize; wind_col++)

		    /* Express all window values relative   */
		    /* to the central elevation.            */
		    *(window_ptr + (wind_row * wsize) + wind_col) =
			*(row_in + (wind_row * ncols) + col + wind_col -
			  EDGE) - centre;


	    /*--- Use LU back substitution to solve normal equations. ---*/
	    find_obs(window_ptr, obs_ptr, weight_ptr);

	    /*      disp_wind(window_ptr); 
	       disp_matrix(normal_ptr,obs_ptr,obs_ptr,6);
	     */

	    if (constrained) {
		G_lubksb(normal_ptr, 5, index_ptr, obs_ptr);
		/*
		   disp_matrix(normal_ptr,obs_ptr,obs_ptr,5);
		 */
	    }

	    else {
		G_lubksb(normal_ptr, 6, index_ptr, obs_ptr);
		/*      
		   disp_matrix(normal_ptr,obs_ptr,obs_ptr,6);
		 */

	    }

	    /*--- Calculate terrain parameter based on quad. coefficients. ---*/
	    if (mparam == FEATURE)
		*(featrow_out + col) = (CELL) feature(obs_ptr);
	    else
		*(row_out + col) = param(mparam, obs_ptr);

	    if (mparam == ELEV)
		*(row_out + col) += centre;	/* Add central elevation back */
	}

	if (mparam != FEATURE)
	    Rast_put_row(fd_out, row_out, DCELL_TYPE);	/* Write the row buffer to the output   */
	/* raster.                              */
	else			/* write FEATURE to CELL */
	    Rast_put_row(fd_out, featrow_out, CELL_TYPE);	/* Write the row buffer to the output       */
	/* raster.                              */

	/* 'Shuffle' rows down one, and read in */
	/*  one new row.                        */
	for (wind_row = 0; wind_row < wsize - 1; wind_row++)
	    for (col = 0; col < ncols; col++)
		*(row_in + (wind_row * ncols) + col) =
		    *(row_in + ((wind_row + 1) * ncols) + col);
    }

    for (wind_row = 0; wind_row < EDGE; wind_row++) {
	if (mparam != FEATURE)
	    Rast_put_row(fd_out, row_out, DCELL_TYPE);	/* Write out the edge cells as NULL. */
	else
	    Rast_put_row(fd_out, featrow_out, CELL_TYPE);	/* Write out the edge cells as NULL. */
    }

    /*--------------------------------------------------------------------------*/
    /*     FREE MEMORY USED TO STORE RASTER ROWS, LOCAL WINDOW AND MATRICES     */

    /*--------------------------------------------------------------------------*/

    G_free(row_in);
    if (mparam != FEATURE)
	G_free(row_out);
    else
	G_free(featrow_out);

    G_free(window_ptr);
    free_dmatrix(normal_ptr, 0, 5, 0, 5);
    free_dvector(obs_ptr, 0, 5);
    free_ivector(index_ptr, 0, 5);
}
Example #3
0
int
main(
	int argc,
	char ** argv
)
{
	double inset_distance = 5;
	double hole_radius = 1.15;
	const char * input_file = NULL;
	const char * output_file = NULL;
	int show_model = 0;
	int option_index = 0;

	while (1)
	{
		const int c = getopt_long(
			argc,
			argv,
			"vmI:r:i:O:",
			long_options,
			&option_index
		);
		if (c == -1)
			break;
		switch(c)
		{
		case 'm': show_model = 1; break;
		case 'v': verbose++; break;
		case 'i': inset_distance = atof(optarg); break;
		case 'r': hole_radius = atof(optarg); break;
		case 'I': input_file = optarg; break;
		case 'O': output_file = optarg; break;
		case 'h': case '?':
			usage(stdout);
			return 0;
		default:
			usage(stderr);
			return -1;
		}
	}

	int input_fd;
	if (!input_file)
	{
		fprintf(stderr, "Input STL must be specified\n");
		return -1;
	} else {
		input_fd = open(input_file, O_RDONLY);
		if (input_fd < 0)
		{
			perror(input_file);
			return -1;
		}
	}

	if (!output_file)
	{
		output_file = "stdout";
		output = stdout;
	} else {
		output = fopen(output_file, "w");
		if (!output)
		{
			perror(output_file);
			return -1;
		}
	}

	stl_3d_t * const stl = stl_3d_parse(input_fd);
	if (!stl)
	{
		fprintf(stderr, "%s: Unable to parse STL\n", input_file);
		return EXIT_FAILURE;
	}
	close(input_fd);


	if (verbose)
		fprintf(stderr,
			"%s: %d faces, %d vertex\n",
			input_file,
			stl->num_face,
			stl->num_vertex
		);

	fprintf(output, "module model() {\n"
		"render() difference() {\n"
	 	"import(\"%s\");\n",
		input_file
	);
	//printf("%%model();\n");

	int * const face_used
		= calloc(sizeof(*face_used), stl->num_face);
	const stl_vertex_t ** const vertex_list
		= calloc(sizeof(*vertex_list), stl->num_vertex);

	// for face, generate the set of coplanar points that go with it
	// and "drill" holes in the model for those corners.
	for (int i = 0 ; i < stl->num_face ; i++)
	{
		if (face_used[i])
			continue;

		const stl_face_t * const f = &stl->face[i];
		const int vertex_count = stl_trace_face(
			stl,
			f,
			vertex_list,
			face_used,
			0
		);

		refframe_t ref;
		refframe_init(
			&ref,
			f->vertex[0]->p,
			f->vertex[1]->p,
			f->vertex[2]->p
		);

		// replace the origin with the actual origin
		//ref.origin.p[0] = 0;
		//ref.origin.p[1] = 0;
		//ref.origin.p[2] = 0;

		fprintf(output, "translate([%f,%f,%f])",
			f->vertex[0]->p.p[0],
			f->vertex[0]->p.p[1],
			f->vertex[0]->p.p[2]
		);
			
		print_multmatrix(&ref, 0);
		fprintf(output, "{\n");

		// generate a bolt hole for each non-copolanar corner
		for (int j = 0 ; j < vertex_count ; j++)
		{
			double x, y;
			refframe_inset(
				&ref,
				inset_distance,
				&x,
				&y,
				vertex_list[(j+0) % vertex_count]->p,
				vertex_list[(j+1) % vertex_count]->p,
				vertex_list[(j+2) % vertex_count]->p
			);

			fprintf(output, "translate([%f,%f,0]) cylinder(r=%f, h=%f, center=true);\n",
				x,
				y,
				hole_radius,
				10.0
			);
		}

		fprintf(output, "}\n");
	}

	fprintf(output, "}\n}\n");

	if (show_model)
		fprintf(output, "model();\n");


	// For each vertex, extract a small region around the corner
	const int div = sqrt(stl->num_vertex);
	const double spacing = 32;

	for(int i = 0 ; i < stl->num_vertex ; i++)
	{
		const stl_vertex_t * const v = &stl->vertex[i];
		const v3_t origin = v->p;

		v3_t avg = {{ 0, 0, 0}};
		find_normal(stl, v, inset_distance, &avg);

		if (!show_model)
		{
			fprintf(output, "translate([%f,%f,20])", (i/div)*spacing, (i%div)*spacing);
			fprintf(output, "render() intersection()");
		}

		fprintf(output, "{\n");

		//printf("%%\n");
		if (!show_model)
		{
			print_normal(&avg, show_model);
			fprintf(output, "translate([%f,%f,%f])", 
				-origin.p[0], -origin.p[1], -origin.p[2]);
			fprintf(output, "model();\n");
			fprintf(output, "translate([0,0,-20]) cylinder(r=15,h=20);\n");
		} else {
			fprintf(output, "translate([%f,%f,%f])", 
				origin.p[0], origin.p[1], origin.p[2]);
			print_normal(&avg, show_model);
			fprintf(output, "%%translate([0,0,-20]) cylinder(r=15,h=20);\n");
		}

		//avg = v3_norm(avg);

		fprintf(output, "}\n");
	}

	return 0;
}
Example #4
0
void
tess_test_polygon(GLUtriangulatorObj * tobj)
{
   tess_polygon *polygon = tobj->current_polygon;

   /* any vertices defined? */
   if (polygon->vertex_cnt < 3) {
      free_current_polygon(polygon);
      return;
   }
   /* wrap pointers */
   polygon->last_vertex->next = polygon->vertices;
   polygon->vertices->previous = polygon->last_vertex;
   /* determine the normal */
   if (find_normal(tobj) == GLU_ERROR)
      return;
   /* compare the normals of previously defined contours and this one */
   /* first contour define ? */
   if (tobj->contours == NULL) {
      tobj->A = polygon->A;
      tobj->B = polygon->B;
      tobj->C = polygon->C;
      tobj->D = polygon->D;
      /* determine the best projection to use */
      if (fabs(polygon->A) > fabs(polygon->B))
	 if (fabs(polygon->A) > fabs(polygon->C))
	    tobj->projection = OYZ;
	 else
	    tobj->projection = OXY;
      else if (fabs(polygon->B) > fabs(polygon->C))
	 tobj->projection = OXZ;
      else
	 tobj->projection = OXY;
   }
   else {
      GLdouble a[3], b[3];
      tess_vertex *vertex = polygon->vertices;

      a[0] = tobj->A;
      a[1] = tobj->B;
      a[2] = tobj->C;
      b[0] = polygon->A;
      b[1] = polygon->B;
      b[2] = polygon->C;

      /* compare the normals */
      if (fabs(a[1] * b[2] - a[2] * b[1]) > EPSILON ||
	  fabs(a[2] * b[0] - a[0] * b[2]) > EPSILON ||
	  fabs(a[0] * b[1] - a[1] * b[0]) > EPSILON) {
	 /* not coplanar */
	 tess_call_user_error(tobj, GLU_TESS_ERROR9);
	 return;
      }
      /* the normals are parallel - test for plane equation */
      if (fabs(a[0] * vertex->location[0] + a[1] * vertex->location[1] +
	       a[2] * vertex->location[2] + tobj->D) > EPSILON) {
	 /* not the same plane */
	 tess_call_user_error(tobj, GLU_TESS_ERROR9);
	 return;
      }
   }
   prepare_projection_info(tobj);
   if (verify_edge_vertex_intersections(tobj) == GLU_ERROR)
      return;
   if (test_for_overlapping_contours(tobj) == GLU_ERROR)
      return;
   if (store_polygon_as_contour(tobj) == GLU_ERROR)
      return;
}