/* * Allocate an Element and store a duplicate of the data pointed to by * obj in the Element. Modules do not get duplicated. The function needs * to handle each type of object separately in a case statement. */ Element *element_init(ObjectType type, void *obj){ Element *e = malloc(sizeof(Element)); if(!e){ printf("malloc failed in element_init\n"); return NULL; } e->type = type; e->next = NULL; switch (e->type) { case ObjNone: printf("ObjNone not implemented in element_init\n"); break; case ObjLine: line_copy(&(e->obj.line), (Line*)obj); break; case ObjPoint: point_copy(&(e->obj.point), (Point*)obj); break; case ObjPolyline: polyline_init(&(e->obj.polyline)); polyline_copy(&(e->obj.polyline), (Polyline*)obj); break; case ObjPolygon: polygon_init(&(e->obj.polygon)); polygon_copy(&(e->obj.polygon), (Polygon*)obj); break; case ObjIdentity: break; case ObjMatrix: matrix_copy(&(e->obj.matrix), (Matrix*)obj); break; case ObjColor: case ObjBodyColor: case ObjSurfaceColor: color_copy(&(e->obj.color), (Color*)obj); break; case ObjSurfaceCoeff: e->obj.coeff = *(float*)obj; break; case ObjLight: printf("ObjLight not implemented in element_init\n"); break; case ObjModule: e->obj.module = obj; break; default: printf("ObjectType %d is not handled in element_init\n",type); } return e; }
static void mystify_init(){ back = ttk_makecol(BLACK); new_color(); rc = r; gc = g; bc = b; aa = 1; paused = 0; sleep_time = 3; fifo_init(&polygons); polygon_move_init(&move); polygon_init(&leading_polygon); }
void view_rotate_circle(Polygon* poly_vrp, Point* center, int sides, double scale, double thetax, double thetay, double thetaz){ if(NULL != poly_vrp){ //make a unit circle of "sides" number fo sides and store the points in the poly_vrp int i; double x, z; polygon_init(poly_vrp); Point p[sides]; Matrix LTM; matrix_identity(<M); matrix_scale(<M, scale, scale, scale); matrix_rotateX(<M, cos(thetax*M_PI/180), sin(thetax*M_PI/180)); matrix_rotateY(<M, cos(thetay*M_PI/180), sin(thetay*M_PI/180)); matrix_rotateZ(<M, cos(thetaz*M_PI/180), sin(thetaz*M_PI/180)); matrix_translate(<M, center->val[0], center->val[1], center->val[2]); for(i=0; i<sides; i++){ x = cos( i * M_PI * 2.0 / sides ); z = sin( i * M_PI * 2.0 / sides ); point_set3D(&p[i], x, 0.1, z); } polygon_set(poly_vrp, sides, &p[0]); matrix_xformPolygon(<M, poly_vrp); } }
int main(int argc, char *argv[]) { const int rows = 1000; const int cols = 1000; View3D view; Matrix vtm; Polygon side[4]; Polygon tpoly; Point tv[3]; Point v[4]; Color color[4]; Image *src; char filename[100]; double x; int i; // set some colors Color_set( &color[0], 0, 0, 1 ); Color_set( &color[1], 0, 1, 0 ); Color_set( &color[2], 1, 0, 0 ); Color_set( &color[3], 1, 0, 1 ); // initialize polygons for(i=0;i<4;i++) { polygon_init( &side[i] ); } // corners of a cube, centered at (0, 0, 0) point_set3D( &v[0], 0, 1, 0 ); point_set3D( &v[1], 1, -1, 0); point_set3D( &v[2], -1, -1, 0 ); point_set3D( &v[3], 0, 0, 1 ); //base of the pyramid polygon_set(&side[3], 3, &(v[0])); //side1 point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[3]); polygon_set(&side[0], 3, tv); //side2 point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[1]); point_copy(&tv[2], &v[3]); polygon_set(&side[1], 3, tv); //side3 point_copy(&tv[0], &v[1]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[3]); polygon_set(&side[2], 3, tv); point_set3D( &(view.vrp), 1, 0, 0); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 0, 1 ); view.d = 1; // focal length view.du = 2; view.dv = view.du * (float)rows / cols; view.f = 0; // front clip plane view.b = 4; // back clip plane view.screenx = cols; view.screeny = rows; matrix_setView3D( &vtm, &view ); // use a temprary polygon to transform stuff polygon_init( &tpoly ); printf("Drawing pyramid\n"); x = -2; int j; for (j=0; j<50; j++){ // create image src = image_create( rows, cols ); point_set3D(&(view.vrp), x , 2, 0.5); vector_set( &(view.vpn), -x, -2, -0.5); matrix_setView3D(&vtm, &view); i=0; for(i=0;i<4;i++) { polygon_copy( &tpoly, &side[i] ); matrix_xformPolygon( &vtm, &tpoly ); // normalize by homogeneous coordinate before drawing polygon_normalize( &tpoly ); polygon_draw( &tpoly, src, color[i] ); //polygon_print( &tpoly, stdout ); } printf("Writing image\n"); sprintf(filename, "pyramid_%04d.ppm", j); image_write( src, filename); free(src); if(j<25){ x += 0.08; }else{ x -= 0.08; } } printf("Making the .gif file...\n"); system("convert -delay 10 pyramid_*.ppm ../images/ext1.gif"); system("rm -f pyramid*"); return(0); }
int plugin_main(void) { int action; int sleep_time=DEFAULT_WAIT_TIME; int nb_wanted_polygons=DEFAULT_NB_POLYGONS; int i; struct polygon_fifo polygons[NB_SCREENS]; struct polygon_move move[NB_SCREENS]; /* This describes the movement of the leading polygon, the others just follow */ struct polygon leading_polygon[NB_SCREENS]; FOR_NB_SCREENS(i) { #ifdef HAVE_LCD_COLOR struct screen *display = rb->screens[i]; if (display->is_color) display->set_background(LCD_BLACK); #endif fifo_init(&polygons[i]); polygon_move_init(&move[i]); polygon_init(&leading_polygon[i], rb->screens[i]); } #ifdef HAVE_LCD_COLOR struct line_color color; color_init(&color); #endif while (true) { FOR_NB_SCREENS(i) { struct screen * display=rb->screens[i]; if(polygons[i].nb_items>nb_wanted_polygons) { /* We have too many polygons, we must drop some of them */ fifo_pop(&polygons[i]); } if(nb_wanted_polygons==polygons[i].nb_items) { /* We have the good number of polygons, we can safely drop the last one to add the new one later */ fifo_pop(&polygons[i]); } fifo_push(&polygons[i], &leading_polygon[i]); /* * Then we update the leading polygon for the next round acording to * current move (the move may be altered in case of sreen border * collision) */ polygon_update(&leading_polygon[i], display, &move[i]); /* Now the drawing part */ #ifdef HAVE_LCD_COLOR color_apply(&color, display); #endif display->clear_display(); polygons_draw(&polygons[i], display); display->update(); } #ifdef HAVE_LCD_COLOR color_change(&color); #endif /* Speed handling*/ if (sleep_time<0)/* full speed */ rb->yield(); else rb->sleep(sleep_time); action = pluginlib_getaction(TIMEOUT_NOBLOCK, plugin_contexts, ARRAYLEN(plugin_contexts)); switch(action) { case DEMYSTIFY_QUIT: cleanup(NULL); return PLUGIN_OK; case DEMYSTIFY_ADD_POLYGON: case DEMYSTIFY_ADD_POLYGON_REPEAT: if(nb_wanted_polygons<MAX_POLYGONS) ++nb_wanted_polygons; break; case DEMYSTIFY_REMOVE_POLYGON: case DEMYSTIFY_REMOVE_POLYGON_REPEAT: if(nb_wanted_polygons>MIN_POLYGONS) --nb_wanted_polygons; break; case DEMYSTIFY_INCREASE_SPEED: case DEMYSTIFY_INCREASE_SPEED_REPEAT: if(sleep_time>=0) --sleep_time; break; case DEMYSTIFY_DECREASE_SPEED: case DEMYSTIFY_DECREASE_SPEED_REPEAT: ++sleep_time; break; default: if (rb->default_event_handler_ex(action, cleanup, NULL) == SYS_USB_CONNECTED) return PLUGIN_USB_CONNECTED; break; } } }
int main (int argc, char *argv[]) { int i; /* init application: * - make program name available for error handlers * - evaluate special options * - initialize toplevel shell and resources * - create an empty PCB with default symbols * - initialize all other widgets * - update screen and get size of drawing area * - evaluate command-line arguments * - register 'call on exit()' function */ setbuf (stdout, 0); InitPaths (argv[0]); #ifdef LOCALEDIR bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); textdomain(GETTEXT_PACKAGE); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); setlocale(LC_ALL,""); #endif srand ( time(NULL) ); /* Set seed for rand() */ initialize_units(); polygon_init (); hid_init (); hid_load_settings (); program_name = argv[0]; program_basename = strrchr (program_name, PCB_DIR_SEPARATOR_C); if (program_basename) { program_directory = strdup (program_name); *strrchr (program_directory, PCB_DIR_SEPARATOR_C) = 0; program_basename++; } else { program_directory = "."; program_basename = program_name; } Progname = program_basename; /* Print usage or version if requested. Then exit. */ if (argc > 1 && (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "-?") == 0 || strcmp (argv[1], "--help") == 0)) usage (); if (argc > 1 && strcmp (argv[1], "-V") == 0) print_version (); /* Export pcb from command line if requested. */ if (argc > 1 && strcmp (argv[1], "-p") == 0) { exporter = gui = hid_find_printer (); argc--; argv++; } else if (argc > 2 && strcmp (argv[1], "-x") == 0) { exporter = gui = hid_find_exporter (argv[2]); argc -= 2; argv += 2; } /* Otherwise start GUI. */ else if (argc > 2 && strcmp (argv[1], "--gui") == 0) { gui = hid_find_gui (argv[2]); if (gui == NULL) { Message("Can't find the gui requested.\n"); exit(1); } argc -= 2; argv += 2; } else { const char **g; gui = NULL; for(g = try_gui_hids; (*g != NULL) && (gui == NULL); g++) { gui = hid_find_gui (*g); } /* try anything */ if (gui == NULL) { Message("Warning: can't find any of the preferred GUIs, falling back to anything available...\n"); gui = hid_find_gui (NULL); } } /* Exit with error if GUI failed to start. */ if (!gui) exit (1); /* Initialize actions only when the gui is already known so only the right one is registered (there can be only one GUI). */ #include "action_list.h" /* Set up layers. */ for (i = 0; i < MAX_LAYER; i++) { char buf[20]; sprintf (buf, "signal%d", i + 1); Settings.DefaultLayerName[i] = strdup (buf); Settings.LayerColor[i] = "#c49350"; Settings.LayerSelectedColor[i] = "#00ffff"; } gui->parse_arguments (&argc, &argv); if (show_help || (argc > 1 && argv[1][0] == '-')) usage (); if (show_version) print_version (); if (show_defaults) print_defaults (); if (show_copyright) copyright (); settings_post_process (); if (show_actions) { print_actions (); exit (0); } if (do_dump_actions) { extern void dump_actions (void); dump_actions (); exit (0); } set_fontfile(); /* Create a new PCB object in memory */ PCB = CreateNewPCB (); if (PCB == NULL) { Message("Can't load the default pcb (%s) for creating an empty layout\n", Settings.DefaultPcbFile); exit(1); } /* Add silk layers to newly created PCB */ CreateNewPCBPost (PCB, 1); if (argc > 1) command_line_pcb = argv[1]; ResetStackAndVisibility (); if (gui->gui) InitCrosshair (); InitHandler (); InitBuffers (); SetMode (ARROW_MODE); if (command_line_pcb) { /* keep filename even if initial load command failed; * file might not exist */ if (LoadPCB (command_line_pcb)) PCB->Filename = strdup (command_line_pcb); } if (Settings.InitialLayerStack && Settings.InitialLayerStack[0]) { LayerStringToLayerStack (Settings.InitialLayerStack); } /* This must be called before any other atexit functions * are registered, as it configures an atexit function to * clean up and free various items of allocated memory, * and must be the last last atexit function to run. */ leaky_init (); /* Register a function to be called when the program terminates. * This makes sure that data is saved even if LEX/YACC routines * abort the program. * If the OS doesn't have at least one of them, * the critical sections will be handled by parse_l.l */ atexit (EmergencySave); /* read the library file and display it if it's not empty */ if (!ReadLibraryContents () && Library.MenuN) hid_action ("LibraryChanged"); #ifdef HAVE_LIBSTROKE stroke_init (); #endif if (Settings.ScriptFilename) { Message (_("Executing startup script file %s\n"), Settings.ScriptFilename); hid_actionl ("ExecuteFile", Settings.ScriptFilename, NULL); } if (Settings.ActionString) { Message (_("Executing startup action %s\n"), Settings.ActionString); hid_parse_actions (Settings.ActionString); } if (gui->printer || gui->exporter) { // Workaround to fix batch output for non-C locales setlocale(LC_NUMERIC,"C"); gui->do_export (0); exit (0); } #if HAVE_DBUS pcb_dbus_setup(); #endif EnableAutosave (); #ifdef DEBUG printf ("Settings.FontPath = \"%s\"\n", Settings.FontPath); printf ("Settings.ElementPath = \"%s\"\n", Settings.ElementPath); printf ("Settings.LibrarySearchPaths = \"%s\"\n", Settings.LibrarySearchPaths); printf ("Settings.LibraryShell = \"%s\"\n", Settings.LibraryShell); printf ("Settings.MakeProgram = \"%s\"\n", UNKNOWN (Settings.MakeProgram)); printf ("Settings.GnetlistProgram = \"%s\"\n", UNKNOWN (Settings.GnetlistProgram)); #endif buildin_init(); gui->do_export (0); #if HAVE_DBUS pcb_dbus_finish(); #endif return (0); }
int main(int argc, char *argv[]) { const int rows = 180; const int cols = 320; const int nFrames = 100; View3D view; Matrix vtm; Polygon side[6]; Polygon tpoly; Point tv[4]; Point v[8]; Color color[6]; Image *src; int i, t; char filename[256]; // set some colors color_set( &color[0], 0, 0, 1 ); color_set( &color[1], 0, 1, 0 ); color_set( &color[2], 1, 0, 0 ); color_set( &color[3], 1, 0, 1 ); color_set( &color[4], 0, 1, 1 ); color_set( &color[5], 1, 1, 0 ); for(t=0;t<nFrames;t++) { // initialize polygons for(i=0;i<6;i++) { polygon_init( &side[i] ); } // corners of a cube, centered at (0, 0, 0) point_set1( &v[0], -1, -1, -1 ); point_set1( &v[1], 1, -1, -1 ); point_set1( &v[2], 1, 1, -1 ); point_set1( &v[3], -1, 1, -1 ); point_set1( &v[4], -1, -1, 1 ); point_set1( &v[5], 1, -1, 1 ); point_set1( &v[6], 1, 1, 1 ); point_set1( &v[7], -1, 1, 1 ); // front side polygon_set( &side[0], 4, &(v[0]) ); // back side polygon_set( &side[1], 4, &(v[4]) ); // top side point_copy( &tv[0], &v[2] ); point_copy( &tv[1], &v[3] ); point_copy( &tv[2], &v[7] ); point_copy( &tv[3], &v[6] ); polygon_set( &side[2], 4, tv ); // bottom side point_copy( &tv[0], &v[0] ); point_copy( &tv[1], &v[1] ); point_copy( &tv[2], &v[5] ); point_copy( &tv[3], &v[4] ); polygon_set( &side[3], 4, tv ); // left side point_copy( &tv[0], &v[0] ); point_copy( &tv[1], &v[3] ); point_copy( &tv[2], &v[7] ); point_copy( &tv[3], &v[4] ); polygon_set( &side[4], 4, tv ); // right side point_copy( &tv[0], &v[1] ); point_copy( &tv[1], &v[2] ); point_copy( &tv[2], &v[6] ); point_copy( &tv[3], &v[5] ); polygon_set( &side[5], 4, tv ); // grab command line argument to determine viewpoint // and set up the view structure /*if( argc > 1 ) { float alpha = atof( argv[1] ); if( alpha < 0.0 || alpha > 1.0 ) alpha = 0.0; point_set1( &(view.vrp), 3*alpha, 2*alpha, -2*alpha - (1.0-alpha)*3 ); } else { point_set1( &(view.vrp), 3, 2, -2 ); } */ float alpha = abs(t - (0.5*nFrames)) / (0.5*nFrames); point_set1( &(view.vrp), 3*alpha, 2*alpha, -2*alpha - (1.0-alpha)*3 ); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 1, 0 ); view.d = 1; // focal length view.du = 2; view.dv = view.du * (float)rows / cols; view.f = 0; // front clip plane view.b = 4; // back clip plane view.screenx = cols; view.screeny = rows; matrix_setView3D( &vtm, &view ); // create image src = image_create( rows, cols ); // use a temprary polygon to transform stuff polygon_init( &tpoly ); //printf("Drawing Polygons\n"); for(i=0;i<6;i++) { polygon_copy( &tpoly, &side[i] ); matrix_xformPolygon( &vtm, &tpoly ); // normalize by homogeneous coordinate before drawing polygon_normalize( &tpoly ); polygon_draw( &tpoly, src, color[i] ); //polygon_print( &tpoly, stdout ); } sprintf(filename, "frame-%04d.ppm", t ); image_write( src, filename ); /*printf("Writing image\n"); image_write( src, "cube.ppm" );*/ } system("convert frame-*.ppm cube.gif"); system("rm frame-*.ppm"); return(0); }
/* * Sourced from coursework file test6b.c (Bruce Maxwell) */ void module_cone( Module *mod, int sides, int fill, int size, float x, float y, float z) { Polygon p; Point xtop, xbot; Element *e; Line l; double x1, x2, z1, z2; int i; if(!mod){ printf("Null md passed to module_cylinder\n"); return; } // set cone parameters module_scale(mod, (int)size, (int)size, (int)size); module_translate(mod, (float)x, (float)y, (float)z); printf("parameters set\n"); polygon_init( &p ); point_set3D( &xtop, 0, 1.0, 0.0 ); point_set3D( &xbot, 0, 0.0, 0.0 ); if (fill == 1){ // make a fan for the top and bottom sides // and quadrilaterals for the sides for(i=0;i<sides;i++) { Point pt[6]; x1 = cos( i * M_PI * 2.0 / sides ); z1 = sin( i * M_PI * 2.0 / sides ); x2 = cos( ( (i+1)%sides ) * M_PI * 2.0 / sides ); z2 = sin( ( (i+1)%sides ) * M_PI * 2.0 / sides ); point_copy( &pt[0], &xbot ); point_set3D( &pt[1], x1, 0.0, z1 ); point_set3D( &pt[2], x2, 0.0, z2 ); polygon_set( &p, 3, pt ); e = element_init(ObjPolygon, &p); module_insert(mod, e); point_set3D( &pt[3], x1, 0.0, z1 ); point_set3D( &pt[4], x2, 0.0, z2 ); point_copy( &pt[5], &xtop); polygon_set( &p, 3, &pt[3] ); e = element_init(ObjPolygon, &p); module_insert(mod, e); } } else{ // make a fan for the top and bottom sides // and quadrilaterals for the sides for(i=0;i<sides;i++) { Point pt[8]; x1 = cos( i * M_PI * 2.0 / sides ); z1 = sin( i * M_PI * 2.0 / sides ); x2 = cos( ( (i+1)%sides ) * M_PI * 2.0 / sides ); z2 = sin( ( (i+1)%sides ) * M_PI * 2.0 / sides ); point_copy( &pt[0], &xbot ); point_set3D( &pt[1], x1, 0.0, z1 ); point_set3D( &pt[2], x2, 0.0, z2 ); line_set( &l, pt[0], pt[1] ); e = element_init(ObjLine, &l); module_insert(mod, e); line_set( &l, pt[1], pt[2] ); e = element_init(ObjLine, &l); module_insert(mod, e); line_set( &l, pt[2], pt[0]); e = element_init(ObjLine, &l); module_insert(mod, e); point_set3D( &pt[3], x1, 0.0, z1 ); point_set3D( &pt[4], x2, 0.0, z2 ); point_set3D( &pt[5], x2, 1.0, z2 ); point_set3D( &pt[6], x1, 1.0, z1 ); point_copy( &pt[7], &xtop); line_set( &l, pt[0], pt[7] ); e = element_init(ObjLine, &l); module_insert(mod, e); line_set( &l, pt[1], pt[7] ); e = element_init(ObjLine, &l); module_insert(mod, e); line_set( &l, pt[2], pt[7]); e = element_init(ObjLine, &l); module_insert(mod, e); line_set( &l, pt[3], pt[7]); e = element_init(ObjLine, &l); module_insert(mod, e); } } polygon_clear( &p ); }
/* * insert a pyramid into the module */ void module_pyramid(Module *md, int solid, float size, float x, float y, float z){ if(!md){ printf("Null md passed to module_pyramid\n"); return; } Polygon side; Point tv[3]; Point v[5]; Line l; Element *e; int i; polygon_init(&side); // corners of the pyramid point_set3D(&v[0], -1, -1, -1 ); point_set3D(&v[1], 1, -1, -1 ); point_set3D(&v[2], 1, -1, 1 ); point_set3D(&v[3], -1, -1, 1 ); point_set3D(&v[4], 0, 0, 0); //printf("points created\n"); // set pyramid parameters module_scale(md, (int)size, (int)size, (int)size); module_translate(md, (float)x, (float)y, (float)z); //printf("parameters set\n"); if (solid == 0){ // add only lines // foundation for(i=0;i<3;i++){ line_set( &l, v[i], v[i+1] ); e = element_init(ObjLine, &l); module_insert(md, e); } line_set( &l, v[3], v[0] ); e = element_init(ObjLine, &l); module_insert(md, e); // connecting lines line_set( &l, v[4], v[0] ); e = element_init(ObjLine, &l); module_insert(md, e); line_set( &l, v[1], v[4] ); e = element_init(ObjLine, &l); module_insert(md, e); line_set( &l, v[2], v[4] ); e = element_init(ObjLine, &l); module_insert(md, e); line_set( &l, v[3], v[4] ); e = element_init(ObjLine, &l); module_insert(md, e); //printf("successfully passed to module\n"); } else{ // front side point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[1]); point_copy(&tv[2], &v[4]); polygon_set(&side, 3, tv); e = element_init(ObjPolygon, &side); module_insert(md, e); // back side point_copy(&tv[0], &v[3]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[4]); polygon_set(&side, 3, tv); e = element_init(ObjPolygon, &side); module_insert(md, e); // bottom side polygon_set(&side, 4, &(v[0])); e = element_init(ObjPolygon, &side); module_insert(md, e); // left side point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[3]); point_copy(&tv[2], &v[4]); polygon_set(&side, 3, tv); e = element_init(ObjPolygon, &side); module_insert(md, e); // right side point_copy(&tv[0], &v[1]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[4]); polygon_set(&side, 3, tv); e = element_init(ObjPolygon, &side); module_insert(md, e); //printf("successfully passed to module\n"); } polygon_clear(&side); }
/* * Adds a unit cube, axis-aligned and centered on zero to the Module. * If solid is zero, add only lines. If solid is non-zero, use polygons. * Make sure each polygon has surface normals defined for it. */ void module_cube(Module *md, int solid){ if(!md){ printf("Null md passed to module_cube\n"); return; } Element *e; Polygon p; Point v[8]; Point tv[4]; Line l; int i; // initialize polygon polygon_init( &p ); // corners of a cube, centered at (0, 0, 0) point_set3D( &v[0], -0.5, -0.5, -0.5 ); point_set3D( &v[1], 0.5, -0.5, -0.5 ); point_set3D( &v[2], 0.5, 0.5, -0.5 ); point_set3D( &v[3], -0.5, 0.5, -0.5 ); point_set3D( &v[4], -0.5, -0.5, 0.5 ); point_set3D( &v[5], 0.5, -0.5, 0.5 ); point_set3D( &v[6], 0.5, 0.5, 0.5 ); point_set3D( &v[7], -0.5, 0.5, 0.5 ); if(solid == 0){ // add only lines ( 12 of them ) // front face lines for(i=0;i<3;i++){ line_set( &l, v[i], v[i+1] ); e = element_init(ObjLine, &l); module_insert(md, e); } line_set( &l, v[3], v[0] ); e = element_init(ObjLine, &l); module_insert(md, e); // back face lines for(i=4;i<7;i++){ line_set( &l, v[i], v[i+1] ); e = element_init(ObjLine, &l); module_insert(md, e); } line_set( &l, v[7], v[4] ); e = element_init(ObjLine, &l); module_insert(md, e); // connecting lines line_set( &l, v[2], v[6] ); e = element_init(ObjLine, &l); module_insert(md, e); line_set( &l, v[3], v[7] ); e = element_init(ObjLine, &l); module_insert(md, e); line_set( &l, v[0], v[4] ); e = element_init(ObjLine, &l); module_insert(md, e); line_set( &l, v[1], v[5] ); e = element_init(ObjLine, &l); module_insert(md, e); } else{ // use polygons ( 6 of them ) // front side polygon_set( &p, 4, &(v[0]) ); e = element_init(ObjPolygon, &p); module_insert(md, e); // back side polygon_set( &p, 4, &(v[4]) ); e = element_init(ObjPolygon, &p); module_insert(md, e); // top side point_copy( &tv[0], &v[2] ); point_copy( &tv[1], &v[3] ); point_copy( &tv[2], &v[7] ); point_copy( &tv[3], &v[6] ); polygon_set( &p, 4, tv ); e = element_init(ObjPolygon, &p); module_insert(md, e); // bottom side point_copy( &tv[0], &v[0] ); point_copy( &tv[1], &v[1] ); point_copy( &tv[2], &v[5] ); point_copy( &tv[3], &v[4] ); polygon_set( &p, 4, tv ); e = element_init(ObjPolygon, &p); module_insert(md, e); // left side point_copy( &tv[0], &v[0] ); point_copy( &tv[1], &v[3] ); point_copy( &tv[2], &v[7] ); point_copy( &tv[3], &v[4] ); polygon_set( &p, 4, tv ); e = element_init(ObjPolygon, &p); module_insert(md, e); // right side point_copy( &tv[0], &v[1] ); point_copy( &tv[1], &v[2] ); point_copy( &tv[2], &v[6] ); point_copy( &tv[3], &v[5] ); polygon_set( &p, 4, tv ); e = element_init(ObjPolygon, &p); module_insert(md, e); } // clean up polygon_clear(&p); }
int readPLY(char filename[], int *nPolygons, Polygon **plist, Color **clist, int estNormals) { char buffer[256]; Point *vertex; Vector *normal; // Point *texture; Color *color; Polygon *p; int numPoly; int numVertex; int vertexProp = 0; int faceProp = 0; ply_property *vertexproplist = NULL; ply_property *vertexproptail = NULL; ply_property *faceproplist = NULL; ply_property *faceproptail = NULL; int nv; int vid[MaxVertices]; int i, j; Color tcolor; // first line ought to be "ply" // format ought to be "ascii 1.0" // comment lines are ignored // element creates an element structure and specifies how many // vertex is meaningful // float32 is %f // uint8 is %c // int32 is %d // x, y, z, nx, ny, nz, s, t, red, green, blue all have meaning // element face is meaningful // property list means # of elements, followed by type // vertex_indices means make polygons out of them // end_header means the first element type starts int doneWithHeader = 0; FILE *fp = fopen(filename, "r"); if(fp) { // check if it's a .ply file fscanf(fp, "%s", buffer); if(strcmp(buffer, "ply")) { printf("%s doesn't look like a .ply file\n", filename); fclose(fp); return(-1); } while(!doneWithHeader) { fscanf(fp, "%s", buffer); switch(buffer[0]) { case 'f': // format statement for(;fgetc(fp) != '\n';); break; case 'c': // comment for(;fgetc(fp) != '\n';); break; case 'p': // property statement { ply_property *prop = malloc(sizeof(ply_property)); prop->listCardType = type_none; prop->listDataType = type_none; prop->next = NULL; fscanf(fp, "%s", buffer); // get the data type prop->type = plyType(buffer); if(prop->type == type_list) { fscanf(fp, "%s", buffer); // get the first data type prop->listCardType = plyType(buffer); fscanf(fp, "%s", buffer); // get the first data type prop->listDataType = plyType(buffer); } else if(prop->type == type_none) { printf("Unrecognized property type %s", buffer); fclose(fp); return(-1); } printf("Read property type %d\n", prop->type); fscanf(fp, "%s", prop->name); printf("Read property name %s\n", prop->name); // add the property entry to the list if(vertexProp) { if(vertexproplist == NULL) { vertexproplist = prop; vertexproptail = prop; } else { vertexproptail->next = prop; vertexproptail = prop; } } else if(faceProp) { if(faceproplist == NULL) { faceproplist = prop; faceproptail = prop; } else { faceproptail->next = prop; faceproptail = prop; } } } break; case 'e': if(!strcmp(buffer, "end_header")) { doneWithHeader = 1; break; } // otherwise it's an element statement fscanf(fp, "%s", buffer); if(!strcmp(buffer, "vertex")) { printf("Read element vertex\n"); vertexProp = 1; faceProp = 0; fscanf(fp, "%d", &numVertex); } else if(!strcmp(buffer, "face")) { printf("Read element face\n"); faceProp = 1; vertexProp = 0; fscanf(fp, "%d", &numPoly); } break; default: // don't know what to do with it for(;fgetc(fp) != '\n';); break; } } // finished with the header vertex = malloc(sizeof(Point) * numVertex); normal = malloc(sizeof(Vector) * numVertex); // texture color = malloc(sizeof(Color) * numVertex); // apparently not written by Blender // read the vertices for(i=0;i<numVertex;i++) { for(j=0;j<3;j++) fscanf(fp, "%lf", &(vertex[i].val[j])); vertex[i].val[3] = 1.0; for(j=0;j<3;j++) fscanf(fp, "%lf", &(normal[i].val[j])); normal[i].val[3] = 0.0; for(j=0;j<2;j++) fscanf(fp, "%*lf"); for(j=0;j<3;j++) { fscanf(fp, "%f", &(color[i].rgb[j])); color[i].rgb[j] /= 255.0; } } p = malloc(sizeof(Polygon) * numPoly); *clist = malloc(sizeof(Color) * numPoly); // read the faces and build the polygons for(i=0;i<numPoly;i++) { polygon_init(&(p[i])); // read in the vertex indices nv = 0; fscanf(fp, "%d", &nv); if(nv > MaxVertices) { printf("Number of vertices is greater than MaxVertices (%d), terminating\n", nv); exit(-1); } for(j=0;j<nv;j++) { fscanf(fp, "%d", &(vid[j])); } // assign the polygon vertices and surface normals // not setting vertexWorld right now, because no Phong shading p[i].numVertex = nv; p[i].zBuffer = 1; p[i].normal = malloc(sizeof(Vector)*nv); p[i].vertex = malloc(sizeof(Point)*nv); tcolor.rgb[0] = tcolor.rgb[1] = tcolor.rgb[2] = 0.0; // printf("%d: ", nv); for(j=0;j<nv;j++) { // printf("%d ", vid[j]); p[i].vertex[j] = vertex[vid[j]]; if(!estNormals) { p[i].normal[j] = normal[vid[j]]; } tcolor.rgb[0] += color[vid[j]].rgb[0]; tcolor.rgb[1] += color[vid[j]].rgb[1]; tcolor.rgb[2] += color[vid[j]].rgb[2]; } tcolor.rgb[0] /= (float)nv; tcolor.rgb[1] /= (float)nv; tcolor.rgb[2] /= (float)nv; if(estNormals) { Vector tx, ty, tn; tx.val[0] = p[i].vertex[0].val[0] - p[i].vertex[1].val[0]; tx.val[1] = p[i].vertex[0].val[1] - p[i].vertex[1].val[1]; tx.val[2] = p[i].vertex[0].val[2] - p[i].vertex[1].val[2]; ty.val[0] = p[i].vertex[2].val[0] - p[i].vertex[1].val[0]; ty.val[1] = p[i].vertex[2].val[1] - p[i].vertex[1].val[1]; ty.val[2] = p[i].vertex[2].val[2] - p[i].vertex[1].val[2]; vector_cross(&tx, &ty, &tn); vector_normalize(&tn); for(j=0;j<nv;j++) p[i].normal[j] = tn; } printf("(%.2f %.2f %.2f)\n", tcolor.rgb[0], tcolor.rgb[1], tcolor.rgb[2]); (*clist)[i] = tcolor; } *nPolygons = numPoly; *plist = p; free(vertex); free(normal); // free(texture); free(color); { ply_property *q; while(vertexproplist != NULL) { q = (ply_property *)vertexproplist->next; free(vertexproplist); vertexproplist = q; } while(faceproplist != NULL) { q = (ply_property *)faceproplist->next; free(faceproplist); faceproplist = q; } } fclose(fp); } else { printf("Unable to open %s\n", filename); return(-1); } return(0); }
// makes 3 X-wing fighters in a loose formation int main(int argc, char *argv[]) { int i, j; //loop variables Image *src; Module* wall; Module* ray; Module* ray2; Module *scene1; Module* scene2; Polygon p; Line l; Point point[4]; Point point2[2]; View3D view; Matrix vtm, gtm; DrawState *ds; char filename[100]; Color Flame = { { 1.0, 0.7, 0.2 } }; Color Red = { { 1.0, 0.2, 0.1 } }; Color Grey = { { 0.745, 0.745, 0.745} }; Color Blue = {{0.117647, 0.564706, 1}}; // Color Grey = {{1, 1, 1}}; // set up the view point_set3D( &(view.vrp), 4, 4, 4 ); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 1, 0 ); view.d = 1; view.du = 1.6; view.dv = 0.9; view.f = 1; view.b = 50; view.screenx = 640; view.screeny = 360; matrix_setView3D( &vtm, &view ); matrix_identity( >m ); // //wall wall = module_create(); module_color(wall, &Red); polygon_init(&p); point_set3D(&point[0], 1,1,2); point_set3D(&point[1], 1,0,2); point_set3D(&point[2], 0,0,2); point_set3D(&point[3], 0,1,2); polygon_set(&p, 4, &point[0]); module_polygon(wall, &p); //ray ray = module_create(); module_color(ray, &Blue); for(i=0; i< 5; i++){ point_set3D(&point2[0], -1+0.01*i, -1, 1); point_set3D(&point2[1], 1+0.01*i, 1, 1); line_set(&l, point2[0], point2[1]); module_line(ray, &l); } //ray2 ray2 = module_create(); module_color(ray2, &Red); for(i=0; i< 5; i++){ point_set3D(&point2[0], -1+0.01*i, 1, -1); point_set3D(&point2[1], 1+0.01*i, -1, -1); line_set(&l, point2[0], point2[1]); // line_zBuffer(&l, 0); module_line(ray2, &l); } //scene // scene = module_create(); // module_module(scene, wall); // module_module(scene, ray); // module_module(scene, ray2); // module_module(scene, wall); for(i=0; i< 36; i++){ //scene scene1 = module_create(); scene2 = module_create(); module_rotateZ(scene1, cos(i*10 * M_PI/180), sin(i*10 * M_PI/180)); module_scale( scene1, 3, 1, 2 ); module_color( scene1, &Blue ); module_cube( scene1, 1); module_scale(scene2, 0.5, 0.5, 0.5); module_cylinder(scene2, 30); // create the image and drawstate src = image_create( 360, 640 ); ds = drawstate_create(); drawstate_setAlpha(ds, 1); ds->shade = ShadeDepth; // draw into the scene // module_draw( scene1, &vtm, >m, ds, src ); drawstate_setAlpha(ds, 1 ); module_draw( scene1, &vtm, >m, ds, src ); // write out the scene sprintf(filename, "frame_%.2d.ppm", i); image_write( src, filename ); module_delete( scene1); } //free the polygon data // polygon_clear( &p ); // free the modules // module_delete( scene); // module_delete( wall ); // free the drawstate free(ds); // free the image image_free( src ); return(0); }
obj_t *triangle_init(FILE *fp, char *objClass) { /****variables****/ obj_t *polygon; plane_t *planePtr; polygon_t *polygonPtr; triple_t orientation; double edgelen; triple_t projected; triple_t planenorm; triple_t tempedge; /****variables****/ // Create a polygon for the triangle polygon = polygon_init(fp, objClass); // Create pointers for convenience planePtr = (plane_t *) polygon->typeData; polygonPtr = (polygon_t *) planePtr->priv; planenorm = tl_unitvec3(&planePtr->normal); // Create array of edges and initiate it polygonPtr->edges = (edge_t *) malloc(3 * sizeof(edge_t)); polygonPtr->numEdges = 3; polygonPtr->edges[0].point = planePtr->point; // Retrieve first orientation and length from file gettriple(fp, &orientation); getdouble(fp, &edgelen); // Unitize orientation and normal to the plane that forms the triangle orientation = tl_unitvec3(&orientation); // Project orientation on the plane and unitize projected = tl_project3(&planenorm, &orientation); projected = tl_unitvec3(&projected); // Scale projected by the length of the edge projected = tl_scale3(&projected, edgelen); // Calculate the second point polygonPtr->edges[1].point = tl_sum3(&polygonPtr->edges[0].point, &projected); // Retrieve next orientation and length from file gettriple(fp, &orientation); getdouble(fp, &edgelen); // Unitize the orientation orientation = tl_unitvec3(&orientation); // Project orientation on the plane and unitize projected = tl_project3(&planenorm, &orientation); projected = tl_unitvec3(&projected); // Scale projected by the length of the edge projected = tl_scale3(&projected, edgelen); // Calculate the last point polygonPtr->edges[2].point = tl_sum3(&polygonPtr->edges[0].point, &projected); // Calculate the direction vectors for each edge and store them tempedge = tl_diff3(&polygonPtr->edges[1].point, &polygonPtr->edges[0].point); polygonPtr->edges[0].edgeDir = tl_unitvec3(&tempedge); tempedge = tl_diff3(&polygonPtr->edges[2].point, &polygonPtr->edges[1].point); polygonPtr->edges[1].edgeDir = tl_unitvec3(&tempedge); tempedge = tl_diff3(&polygonPtr->edges[0].point, &polygonPtr->edges[2].point); polygonPtr->edges[2].edgeDir = tl_unitvec3(&tempedge); // Return newly created triangle return polygon; }