source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vrippack-0.31/src/plytools/plybound.c @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 8.6 KB
Line 
1/*
2
3Scale and translate a PLY object so that it fits within a given bounding box.
4
5Greg Turk, August 1994
6
7*/
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <malloc.h>
13#include <ply.h>
14
15
16/* user's vertex and face definitions for a polygonal object */
17
18typedef struct Vertex {
19  float x,y,z;
20  void *other_props;       /* other properties */
21} Vertex;
22
23char *elem_names[] = { /* list of the kinds of elements in the user's object */
24  "vertex", "face"
25};
26
27PlyProperty vert_props[] = { /* list of property information for a vertex */
28  {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0},
29  {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0},
30  {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0},
31};
32
33
34/*** the PLY object ***/
35
36int nverts;
37Vertex **vlist;
38PlyOtherElems *other_elements = NULL;
39PlyOtherProp *vert_other;
40int nelems;
41char **elist;
42int num_comments;
43char **comments;
44int num_obj_info;
45char **obj_info;
46int file_type;
47
48static float xcenter = 0;
49static float ycenter = 0;
50static float zcenter = 0;
51
52static float box_size = 2;
53
54static int print_only = 0;  /* print out info, but don't transform */
55static int use_mass = 0;    /* use center of mass instead of geometric center */
56
57void usage(char *progname);
58void write_file();
59void read_file(FILE *inFile);
60void transform();
61
62
63/******************************************************************************
64Transform a PLY file.
65******************************************************************************/
66
67int
68main(int argc, char *argv[])
69{
70  int i,j;
71  char *s;
72  char *progname;
73  FILE *inFile = stdin;
74
75  progname = argv[0];
76
77  /* Parse -flags */
78  while (--argc > 0 && (*++argv)[0]=='-') {
79    for (s = argv[0]+1; *s; s++)
80      switch (*s) {
81        case 'm':
82          use_mass = 1 - use_mass;
83          break;
84        case 'p':
85          print_only = 1 - print_only;
86          break;
87        case 'b':
88          if (argc < 2) {
89            usage(progname);
90          }
91          box_size = atof (*++argv);
92          argc -= 1;
93          break;
94        case 'c':
95          if (argc < 4) {
96            usage(progname);
97          }
98          xcenter = atof (*++argv);
99          ycenter = atof (*++argv);
100          zcenter = atof (*++argv);
101          argc -= 3;
102          break;
103        default:
104          usage (progname);
105          exit (-1);
106          break;
107      }
108  }
109
110   /* optional input file (if not, read stdin ) */
111   if (argc > 0 && *argv[0] != '-') {
112       inFile = fopen(argv[0], "r");
113       if (inFile == NULL) {
114           fprintf(stderr, "Error: Couldn't open input file %s\n", argv[0]);
115           usage(progname);
116           exit(-1);
117       }
118       argc --;
119       argv ++;
120   } 
121
122   /* Check no extra args */
123   if (argc > 0) {
124     fprintf(stderr, "Error: Unhandled arg: %s\n", argv[0]);
125     usage(progname);
126     exit(-1);
127   }
128
129  read_file(inFile);
130
131  transform();
132
133  if (!print_only)
134    write_file();
135}
136
137
138/******************************************************************************
139Print out usage information.
140******************************************************************************/
141
142void
143usage(char *progname)
144{
145  fprintf (stderr, "usage: %s [flags] [in.ply] > out.ply\n", progname);
146  fprintf (stderr, "   or: %s [flags] < in.ply > out.ply\n", progname);
147  fprintf (stderr, "       -b box_size (default = 2)\n");
148  fprintf (stderr, "       -c xcenter ycenter zcenter (default is origin)\n");
149  fprintf (stderr, "       -m (use mass center instead of geometric center)\n");
150  fprintf (stderr, "       -p (only print information)\n");
151  exit(-1);
152}
153
154
155/******************************************************************************
156Transform the PLY object.
157******************************************************************************/
158
159void
160transform()
161{
162  int i;
163  Vertex *vert;
164  float xmin,ymin,zmin;
165  float xmax,ymax,zmax;
166  float xdiff,ydiff,zdiff;
167  float diff;
168  float scale;
169  float xt,yt,zt;
170  float xc,yc,zc;
171  float xsum,ysum,zsum;
172
173  if (nverts == 0)
174    return;
175
176  vert = vlist[0];
177
178  xmin = vert->x;
179  ymin = vert->y;
180  zmin = vert->z;
181
182  xmax = vert->x;
183  ymax = vert->y;
184  zmax = vert->z;
185
186  xsum = ysum = zsum = 0;
187
188#define MIN(a,b) ((a < b) ? (a) : (b))
189#define MAX(a,b) ((a > b) ? (a) : (b))
190
191  /* find minimum and maximum extent of vertices */
192
193  for (i = 0; i < nverts; i++) {
194
195    vert = vlist[i];
196
197    xmin = MIN (vert->x, xmin);
198    ymin = MIN (vert->y, ymin);
199    zmin = MIN (vert->z, zmin);
200
201    xmax = MAX (vert->x, xmax);
202    ymax = MAX (vert->y, ymax);
203    zmax = MAX (vert->z, zmax);
204
205    xsum += vert->x;
206    ysum += vert->y;
207    zsum += vert->z;
208  }
209
210  xdiff = xmax - xmin;
211  ydiff = ymax - ymin;
212  zdiff = zmax - zmin;
213
214  diff = MAX (xdiff, MAX (ydiff, zdiff));
215  scale = box_size / diff;
216
217  if (print_only) {
218    fprintf (stderr, "\n");
219    fprintf (stderr, "xmin xmax: %g %g\n", xmin, xmax);
220    fprintf (stderr, "ymin ymax: %g %g\n", ymin, ymax);
221    fprintf (stderr, "zmin zmax: %g %g\n", zmin, zmax);
222    fprintf (stderr, "geometric center = %g %g %g\n",
223             0.5 * (xmin + xmax), 0.5 * (ymin + ymax), 0.5 * (zmin + zmax));
224    fprintf (stderr, "center of mass   = %g %g %g\n",
225             xsum / nverts, ysum / nverts, zsum / nverts);
226    fprintf (stderr, "maximum side length = %g\n", diff);
227    fprintf (stderr, "\n");
228    return;
229  }
230
231  /* compute center of object, either geometric or mass center */
232
233  if (use_mass) {
234    xc = xsum / nverts;
235    yc = ysum / nverts;
236    zc = zsum / nverts;
237  }
238  else {
239    xc = 0.5 * (xmin + xmax);
240    yc = 0.5 * (ymin + ymax);
241    zc = 0.5 * (zmin + zmax);
242  }
243
244  xt = xcenter - scale * xc;
245  yt = ycenter - scale * yc;
246  zt = zcenter - scale * zc;
247
248  /* scale and translate vertices to fit into bounding box, */
249  /* and also center the object */
250
251  for (i = 0; i < nverts; i++) {
252    vert = vlist[i];
253    vert->x = xt + vert->x * scale;
254    vert->y = yt + vert->y * scale;
255    vert->z = zt + vert->z * scale;
256  }
257}
258
259
260/******************************************************************************
261Read in the PLY file from standard in.
262******************************************************************************/
263
264void
265read_file(FILE *inFile)
266{
267  int i,j,k;
268  PlyFile *ply;
269  int nprops;
270  int num_elems;
271  PlyProperty **plist;
272  char *elem_name;
273  float version;
274
275
276  /*** Read in the original PLY object ***/
277
278
279  ply  = ply_read (inFile, &nelems, &elist);
280  ply_get_info (ply, &version, &file_type);
281
282  for (i = 0; i < nelems; i++) {
283
284    /* get the description of the first element */
285    elem_name = elist[i];
286    plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);
287
288    if (equal_strings ("vertex", elem_name)) {
289
290      /* create a vertex list to hold all the vertices */
291      vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems);
292      nverts = num_elems;
293
294      /* set up for getting vertex elements */
295
296      ply_get_property (ply, elem_name, &vert_props[0]);
297      ply_get_property (ply, elem_name, &vert_props[1]);
298      ply_get_property (ply, elem_name, &vert_props[2]);
299      vert_other = ply_get_other_properties (ply, elem_name,
300                     offsetof(Vertex,other_props));
301
302      /* grab all the vertex elements */
303      for (j = 0; j < num_elems; j++) {
304        vlist[j] = (Vertex *) malloc (sizeof (Vertex));
305        ply_get_element (ply, (void *) vlist[j]);
306      }
307    }
308    else
309      other_elements = ply_get_other_element (ply, elem_name, num_elems);
310  }
311
312  comments = ply_get_comments (ply, &num_comments);
313  obj_info = ply_get_obj_info (ply, &num_obj_info);
314
315  ply_close (ply);
316}
317
318
319/******************************************************************************
320Write out the PLY file to standard out.
321******************************************************************************/
322
323void
324write_file()
325{
326  int i,j,k;
327  PlyFile *ply;
328  int num_elems;
329  char *elem_name;
330
331  /*** Write out the transformed PLY object ***/
332
333
334  ply = ply_write (stdout, nelems, elist, file_type);
335
336
337  /* describe what properties go into the vertex and face elements */
338
339  ply_element_count (ply, "vertex", nverts);
340  ply_describe_property (ply, "vertex", &vert_props[0]);
341  ply_describe_property (ply, "vertex", &vert_props[1]);
342  ply_describe_property (ply, "vertex", &vert_props[2]);
343  ply_describe_other_properties (ply, vert_other, offsetof(Vertex,other_props));
344
345  ply_describe_other_elements (ply, other_elements);
346
347  for (i = 0; i < num_comments; i++)
348    ply_put_comment (ply, comments[i]);
349
350  for (i = 0; i < num_obj_info; i++)
351    ply_put_obj_info (ply, obj_info[i]);
352
353  ply_header_complete (ply);
354
355  /* set up and write the vertex elements */
356  ply_put_element_setup (ply, "vertex");
357  for (i = 0; i < nverts; i++)
358    ply_put_element (ply, (void *) vlist[i]);
359
360  ply_put_other_elements (ply);
361
362  /* close the PLY file */
363  ply_close (ply);
364}
365
Note: See TracBrowser for help on using the repository browser.