예제 #1
0
파일: mesh2d.c 프로젝트: mox601/grafica
int open_ply(const char* filename)
{
	/* bounding box */
	int I;
	struct triangle_t* t,**cursor;
	float x1=+1e18f,x2=-1e18f;
	float y1=+1e18f,y2=-1e18f;
	float z1=+1e18f,z2=-1e18f;

	PlyProperty vert_prop[3]={
		{    "x", Float32, Float32,  0, 0, 0, 0, 0},
		{    "y", Float32, Float32,  4, 0, 0, 0, 0},
		{    "z", Float32, Float32,  8, 0, 0, 0, 0}
	};

	PlyProperty   face_prop	={"vertex_indices", Int32, Int32, 4,PLY_LIST, Int32, Int32, 0};

	PlyProperty** props=NULL;
	int numvertices,numproperties,numtriangles,numstrips,numfaces;
	int clockwise;
	struct {int nverts,*verts;} face;
	int h,k;
	float maxdim;
	PlyFile* ply=0;

	FILE* file = fopen( filename, "rb" );

	if (!file)
		return 0;

	ply = read_ply(file);

	if (!ply)
	{
		fclose(file);
		return 0;
	}

	cursor=&(mesh.triangles);

	props = get_element_description_ply(ply, "vertex", &numvertices, &numproperties);
	
	mesh.vertices=(struct vertex_t*)malloc(sizeof(struct vertex_t)*numvertices);
	mesh.numvertices=numvertices;

	get_element_setup_ply(ply, "vertex", 3,vert_prop);
	
	for( k=0;k<numvertices; ++k) 
	{
		struct vertex_t* v=mesh.vertices+k;
		get_element_ply( ply, (void*)v);
		
		x1=min2(x1,v->x);x2=max2(x2,v->x);
		y1=min2(y1,v->y);y2=max2(y2,v->y);
		z1=min2(z1,v->z);z2=max2(z2,v->z);
	}

	/* normalize to unit box to [-1,+1],[-1,+1],[-1,+1] mantaining proportions */
	maxdim=max2(x2-x1,y2-y1);
	maxdim=max2(maxdim,z2-z1);

	for( k=0;k<numvertices; ++k) 
	{
		struct vertex_t* v=mesh.vertices+k;
		v->x=2*((v->x-x1)/maxdim-0.5f);
		v->y=2*((v->y-y1)/maxdim-0.5f);
		v->z=2*((v->z-z1)/maxdim-0.5f);
	}

	numtriangles=0;

	if (props = get_element_description_ply( ply, "face", &numfaces, &numproperties))
	{
		get_element_setup_ply( ply, "face", 1, &face_prop);
		
		for(h=0; h<numfaces; h++ ) 
		{
			get_element_ply( ply, (void*)&face);
						
			for(k=2; k<face.nverts;++k) 
			{
				t=(struct triangle_t*)malloc(sizeof(struct triangle_t));
				t->i0=face.verts[0  ];
				t->i1=face.verts[k-1];
				t->i2=face.verts[k  ];

				t->next=0;
				(*cursor)=t;
				cursor=&(t->next);
			}
			
			free(face.verts);
		}
	}
	else
	{
		props = get_element_description_ply( ply, "tristrips", &numstrips, &numproperties);
		
		get_element_setup_ply(ply,"tristrips",1,&face_prop);

		for(k=0; k<numstrips;++k ) 
		{
			get_element_ply( ply, (void*)&face);
			clockwise=1;

			for (I=2;I< face.nverts; I++) 
			{
				if (face.verts[I] == -1) 
					{
						I += 2;
						clockwise = 1;
				}
				else 
				{			
					t=(struct triangle_t*)malloc(sizeof(struct triangle_t));
					
					t->i0=face.verts[I-2];
					t->i1=face.verts[I-1];
					t->i2=face.verts[I  ];

					if (!clockwise) swap_int(t->i1,t->i2);

					t->next=0;
					(*cursor)=t;
					cursor=&(t->next);
					clockwise = 1-clockwise;
				}
			}
			
			free(face.verts);
		}
	}
	
	//close_ply( ply );
	fclose(file);

	set_normals();
	return 1; /* ok */
}
예제 #2
0
main(int argc, char *argv[])
{
  int i,j,k;
  PlyFile *in_ply;
  PlyFile *out_ply;
  int nelems;
  char **elist;
  int file_type;
  float version;
  int nprops;
  int num_elems;
  PlyProperty **plist;
  PlyProperty **plist_copy;
  PlyProperty *prop;
  char *elem_name;
  char *data;
  int offset;
  int *offset_list;
  int **lists;
  int *list_count;
  char **list_ptr;
  int verbose_flag = 0;

#ifndef WRITE_ASCII
#ifndef WRITE_BINARY

  fprintf (stderr, "'%s' compiled incorrectly.\n", argv[0]);
  fprintf (stderr,
           "Must have WRITE_ASCII or WRITE_BINARY defined during compile.\n");
  exit (-1);

#endif
#endif

  /* maybe print out help message */

#ifdef WRITE_ASCII
  if (argc > 2 || (argc == 2 && !equal_strings (argv[1], "-p"))) {
    fprintf (stderr, "usage: %s [flags] <infile >outfile\n", argv[0]);
    fprintf (stderr, "          -p (print element labels)\n");
    exit (0);
  }
#endif

#ifdef WRITE_BINARY
  if (argc > 1) {
    fprintf (stderr, "usage: %s <infile >outfile\n", argv[0]);
    exit (0);
  }
#endif

  if (argc == 2 && equal_strings (argv[1], "-p"))
    verbose_flag = 1;

  /* open the input and output files */

  in_ply  = read_ply (stdin);
  elist = get_element_list_ply (in_ply, &nelems);

#ifdef WRITE_ASCII
  out_ply = write_ply (stdout, nelems, elist, PLY_ASCII);
#endif

#ifdef WRITE_BINARY
  out_ply = write_ply (stdout, nelems, elist, PLY_BINARY_BE);
#endif

  /* allocate space for various lists that keep track of the elements */

  plist_copy = (PlyProperty **) malloc (sizeof (PlyProperty *) * nelems);
  offset_list = (int *) malloc (sizeof (int) * nelems);
  lists = (int **) malloc (sizeof (int *) * nelems);
  list_count = (int *) malloc (sizeof (int));

  /* go through each kind of element that we learned is in the file */
  /* and come up with a list that has offsets for all properties */

  for (i = 0; i < nelems; i++) {

    /* get the description of the element */
    elem_name = elist[i];
    plist = get_element_description_ply(in_ply, elem_name, &num_elems, &nprops);

    /* make room for a list of the lists in an element, so that */
    /* we can later easily free up the space created by malloc'ed lists */

    list_count[i] = 0;
    lists[i] = (int *) malloc (sizeof (int) * nprops);

    /* set up pointers into data */

    offset = 0;
    for (j = 0; j < nprops; j++) {
      plist[j]->offset = offset;
      offset += 8;
      if (plist[j]->is_list) {
        plist[j]->count_offset = offset;
        lists[i][list_count[i]] = offset - 8;
        list_count[i]++;
        offset += 8;
      }
    }

    offset_list[i] = offset;

    /* copy the property list */

    plist_copy[i] = (PlyProperty *) malloc (sizeof (PlyProperty) * nprops);
    prop = plist_copy[i];

    for (j = 0; j < nprops; j++) {
      prop->name = plist[j]->name;
      prop->external_type = plist[j]->external_type;
      prop->internal_type = plist[j]->external_type;
      prop->offset = plist[j]->offset;
      prop->is_list = plist[j]->is_list;
      prop->count_external = plist[j]->count_external;
      prop->count_internal = plist[j]->count_external;
      prop->count_offset = plist[j]->count_offset;
      prop++;
    }

    element_layout_ply (out_ply, elem_name, num_elems, nprops, plist_copy[i]);
  }

  /* copy the comments and obj_info */

  copy_comments_ply (out_ply, in_ply);
  copy_obj_info_ply (out_ply, in_ply);

  /* finish the header for the output file */
  header_complete_ply (out_ply);

  /* copy all the element information */

  for (i = 0; i < nelems; i++) {

    /* get the description of the element */
    elem_name = elist[i];
    plist = get_element_description_ply(in_ply, elem_name, &num_elems, &nprops);

    /* allocate space for an element */
    data = (char *) malloc (8 * offset_list[i]);

    /* set up for getting elements */
    get_element_setup_ply (in_ply, elem_name, nprops, plist_copy[i]);
    put_element_setup_ply (out_ply, elem_name);

    /* possibly print out name of element */
    if (verbose_flag)
      fprintf (out_ply->fp, "%s:\n", elem_name);

    /* copy all the elements */

    if (list_count[i]) {
      /* need to free the lists */
      for (j = 0; j < num_elems; j++) {
        get_element_ply (in_ply, (void *) data);
        put_element_ply (out_ply, (void *) data);
        for (k = 0; k < list_count[i]; k++) {
          list_ptr = (char **) (data + lists[i][k]);
          free (*list_ptr);
        }
      }
    }
    else {
      /* no lists */
      for (j = 0; j < num_elems; j++) {
        get_element_ply (in_ply, (void *) data);
        put_element_ply (out_ply, (void *) data);
      }
    }

  }

  /* close the PLY files */

  close_ply (in_ply);
  close_ply (out_ply);
}