Lab 3: material_t

Objectives

To construct a C-style object for storing surface material information and then parse an input file containing material definitions. The idea is to be able to parse that entry (material), and then to add each material read in onto a linked list, i.e., a list of materials.

To test whether this has been done successfully, write code to iterate through the lists to print out what was read in.

Note that because the material object uses drgb_t to represent pixel information, you will also need to write an interface (provided) and implementation of the drgb_t pixel data type.

Assignment

  1. Use the following material.h header file:
    
    #ifndef NAME_LEN
    #define NAME_LEN   16        // max length of entity names
    #endif
    
    #define MAT_COOKIE 32456123
    
    typedef struct material_type
    {
       int     cookie;
       char    name[NAME_LEN];
       drgb_t  ambient;
       drgb_t  diffuse;
       drgb_t  specular;
    }  material_t;
    
    void        material_init(FILE *in,list_t *list,int attrmax);
    void        material_load_attributes(FILE *in,material_t *mat);
    material_t* material_getbyname(list_t *list,char *name);
    void        material_print(material_t *mat,FILE *out);
    void        material_list_print(list_t *list,FILE *out);
    char*       material_getname(material_t *mat);
    void        material_getamb(material_t *mat,drgb_t dst);
    void        material_getdiff(material_t *mat,drgb_t dst);
    void        material_getspec(material_t *mat,drgb_t dst);
    	
  2. Write the corresponding material.c implementation file that provides the functionality the above Application Program Interface (API) specifies.
  3. Note that the material object expects a list_t pointer, the same singly-linked list that you developed in a previous lab.
  4. You code should be such that the following main.c file works unaltered:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <math.h>
    
    #include "vector.h"
    #include "pixel.h"
    #include "list.h"
    #include "material.h"
    
    int main()
    {
            list_t          *mats;
            material_t      *mat;
            char            entity[16];
            drgb_t          pix;
    
      // create a material list
      mats = list_init();
    
      // input should consist only of material definitions
      // but there can be any number of material defs in the file
      while(fscanf(stdin,"%s",entity) == 1) {
    
        // create material_t structure and read attributes
        material_init(stdin,mats,0);
    
        // this test is designed to ensure that list_add
        // pointed current to the material just loaded
        mat = (material_t *)list_get_data(mats);
        assert(mat->cookie == MAT_COOKIE);
        fprintf(stderr,"loaded %s \n",material_getname(mat));
      }
    
      // read them all in...now try to print them
      material_list_print(mats,stdout);
    
      // see if we can find the first in the list, get its ambient data
      mat = material_getbyname(mats,"blue");
      assert(mat->cookie == MAT_COOKIE);
      fprintf(stderr,"found %s \n",material_getname(mat));
      material_getamb(mat,pix);
      pix_print(stderr,"ambient is: ",pix);
    
      // see if we can find the last one, get its ambient data
      mat = material_getbyname(mats,"yellow");
      assert(mat->cookie == MAT_COOKIE);
      fprintf(stderr,"found %s \n",material_getname(mat));
      material_getamb(mat,pix);
      pix_print(stderr,"ambient is: ",pix);
    
      // see what happens if we try to find a non-existent element
      assert((mat = material_getbyname(mats,"chartreuse"))==NULL);
    
      fprintf(stderr,"deleting list\n");
      list_del(mats); 
      fprintf(stderr,"done.\n");
    
      return(0);
    }
    	
  5. The pixel.h header file is:
    // Two pixel value structures are used:
    // Computations are done in the double precision domain
    // where 0.0 means black and 1.0 means maximum intensity
    // The raytracing algorithm can DEFINITELY produce
    // pixel values that exceed 1.0 scale and then clamp
    // them before assigning them to irgb_types
    
    typedef double drgb_t[3];
    
    // The .ppm file requires the usual r-g-b values in the
    // range 0-255.  This structure maps one of them.
    
    typedef unsigned char irgb_t[3];
    
    void    pix_sum(drgb_t p1,drgb_t p2,drgb_t p3);
    void    pix_prod(drgb_t p1,drgb_t p2,drgb_t  p3);
    void    pix_scale(double s,drgb_t p1,drgb_t p2);
    void    pix_copy(drgb_t p1,drgb_t  p2);
    int     pix_read(FILE *in,drgb_t p1);
    void    pix_print(FILE *out,char *label,drgb_t pix);
    int     pix_nonzero(drgb_t pix);
    	
  6. Write the pixel.c implementation file for the pixel C-style object (similar to vec_t).
  7. Sample input:
    material blue
    {
       ambient 0 0 5
       diffuse 0 0 5
    }
    
    material green
    {
       ambient 0 6 0
       diffuse 0 7 0
      specular 1 1 1
    }
    
    material yellow
    {
       ambient 7 6 0
       diffuse 7 7 0
    }
    	
  8. Sample output:
    loaded blue 
    loaded green 
    loaded yellow 
    material blue
    {
       ambient 0 0 5
       diffuse 0 0 5
    }
    
    material green
    {
       ambient 0 6 0
       diffuse 0 7 0
      specular 1 1 1
    }
    
    material yellow
    {
       ambient 7 6 0
       diffuse 7 7 0
    }
    
    found blue 
    ambient is:  0 0 5
    found yellow 
    ambient is:  7 6 0
    	
  9. The program is run as:
    
    	./main < mat.txt
    	

Turn in

Turn in all of your code, in one tar.gz archive of your lab03/ directory, including:
  1. A README file containing
    1. Course id--section no
    2. Name
    3. Lab description
    4. Brief solution description (e.g., program design, description of algorithm, etc., however appropriate).
    5. Lessons learned, identified interesting features of your program
    6. Any special usage instructions
  2. Makefile
  3. source code (.h headers and .c source)
  4. object code (do a make clean before tar)

How to hand in

See submit notes.