/* * Program to generate a simple model designed for finding an edge in a * model. The paradigm is, you run this and mergemodel it with the * original model; the result then has the relevant lines marked with * arrowheadish triangles. * * Usage: * $0 x1 y1 z1 x2 y2 z2 size r g b * where one end of the segment to be called out is (x1,y1,z1) and the * other is (x2,y2,z2). size is the point-to-back size of the * arrowheads; their aspect ratio is fixed, with the back end being * 10% of the length. r, g, and b are an RGB triple (floating point * 0-1) of the colour of the material to be generated. * * Each triangle is generated twice, once facing each way, so it's sure * to be visible even with backface removal turned on. * * The resulting model appears on stdout. */ #include #include #include #include extern const char *__progname; #include "3d.h" #include "model.h" static PT3 e1; static PT3 e2; static double size; static double r; static double g; static double b; static MODEL *m; static XYZ pt3_to_xyz(PT3 p) { return((XYZ){.x=p.x,.y=p.y,.z=p.z}); } static PT3 xyz_to_pt3(XYZ p) { return((PT3){.x=p.x,.y=p.y,.z=p.z}); } static double double_arg(const char *arg, const char *what) { char *ep; double v; v = strtod(arg,&ep); if (ep == arg) { fprintf(stderr,"%s: %s: no number found for %s\n",__progname,arg,what); exit(1); } if (*ep) { fprintf(stderr,"%s: %s: junk after %s\n",__progname,arg,what); exit(1); } return(v); } static void gen_triangle(POINT *p, PT3 back, PT3 side, int mx) { PT3 tip; PT3 h1; PT3 h2; POINT *p1; POINT *p2; LOCATION *l1; LOCATION *l2; TRIANGLE *t; tip = xyz_to_pt3(get_location(m,p->loc)->l); back = smul3(size,back); side = smul3(size*.1,side); h1 = add3(tip,add3(back,side)); h2 = add3(tip,sub3(back,side)); l1 = get_location(m,new_location(m)); l1->l = pt3_to_xyz(h1); p1 = get_point(m,new_point(m)); p1->loc = l1->inx; p1->type = PT_CORNER; l2 = get_location(m,new_location(m)); l2->l = pt3_to_xyz(h2); p2 = get_point(m,new_point(m)); p2->loc = l2->inx; p2->type = PT_CORNER; t = get_triangle(m,new_triangle(m)); t->material = mx; t->corner[0] = p->inx; t->corner[1] = p1->inx; t->corner[2] = p2->inx; t = get_triangle(m,new_triangle(m)); t->material = mx; t->corner[0] = p->inx; t->corner[1] = p2->inx; t->corner[2] = p1->inx; } int main(int, char **); int main(int ac, char **av) { PT3 v; PT3 x1; PT3 x2; MATERIAL *s; LOCATION *l; POINT *p; OBJECT *o; double d; int i; if (ac != 11) { fprintf(stderr,"Usage: %s x1 y1 z2 x2 y2 z2 size r g b\n",__progname); exit(1); } e1.x = double_arg(av[1],"endpoint 1 X"); e1.y = double_arg(av[2],"endpoint 1 Y"); e1.z = double_arg(av[3],"endpoint 1 Z"); e2.x = double_arg(av[4],"endpoint 2 X"); e2.y = double_arg(av[5],"endpoint 2 Y"); e2.z = double_arg(av[6],"endpoint 2 Z"); size = double_arg(av[7],"size"); if (size < 0) { fprintf(stderr,"%s: size %g out of range\n",__progname,size); exit(1); } r = double_arg(av[8],"red value"); g = double_arg(av[9],"green value"); b = double_arg(av[10],"blue value"); if ((r < 0) || (r > 1) || (g < 0) || (g > 1) || (b < 0) || (b > 1)) { fprintf(stderr,"%s: RGB triple (%g,%g,%g) out of range\n",__progname,r,g,b); exit(1); } v = unit3(sub3(e2,e1)); d = fabs(v.x); x1 = (PT3){.x=1,.y=0,.z=0}; if (fabs(v.y) < d) { d = fabs(v.y); x1 = (PT3){.x=0,.y=1,.z=0}; } if (fabs(v.z) < d) { d = fabs(v.z); x1 = (PT3){.x=0,.y=0,.z=1}; } x1 = unit3(sub3(x1,smul3(dot3(v,x1),v))); x2 = cross(v,x1); m = new_model(); s = get_material(m,new_material(m)); s->name = strdup("arrows"); s->selflum = (RGB){.r=r,.g=g,.b=b}; s->reflect = (RGB){0,0,0}; s->spec_exp = 1; s->spec_mul = 0; l = get_location(m,new_location(m)); l->l = pt3_to_xyz(e1); p = get_point(m,new_point(m)); p->loc = l->inx; p->type = PT_CORNER; gen_triangle(p,smul3(-1,v),x1,s->inx); gen_triangle(p,smul3(-1,v),x2,s->inx); gen_triangle(p,x1,x2,s->inx); gen_triangle(p,x2,x1,s->inx); gen_triangle(p,smul3(-1,x1),x2,s->inx); gen_triangle(p,smul3(-1,x2),x1,s->inx); l = get_location(m,new_location(m)); l->l = pt3_to_xyz(e2); p = get_point(m,new_point(m)); p->loc = l->inx; p->type = PT_CORNER; gen_triangle(p,v,x1,s->inx); gen_triangle(p,v,x2,s->inx); gen_triangle(p,x1,x2,s->inx); gen_triangle(p,x2,x1,s->inx); gen_triangle(p,smul3(-1,x1),x2,s->inx); gen_triangle(p,smul3(-1,x2),x1,s->inx); o = get_object(m,new_object(m)); o->ntriangles = n_triangles(m); o->triangles = malloc(o->ntriangles*sizeof(int)); for (i=o->ntriangles;i>=0;i--) o->triangles[i] = i; save_model(m,stdout); free_model(m); exit(0); }