1 | |
---|
2 | // |
---|
3 | // plymerge.cc -- David Koller (dk@cs.stanford.edu), 8/17/98 |
---|
4 | // |
---|
5 | // This program takes a list of .ply files, and outputs to stdout |
---|
6 | // a .ply file representing the merged geometry. Note that only |
---|
7 | // vertex x,y,z and face connectivity information is preserved; |
---|
8 | // other attributes are dropped. |
---|
9 | // |
---|
10 | // Redundant/shared vertices and faces are not combined; other |
---|
11 | // programs such as "plyshared" exist for doing this. |
---|
12 | // |
---|
13 | |
---|
14 | #include <stdio.h> |
---|
15 | #include <stdlib.h> |
---|
16 | #include <ply.h> |
---|
17 | |
---|
18 | |
---|
19 | typedef struct { |
---|
20 | float x,y,z; |
---|
21 | void *other_props; |
---|
22 | } Vertex; |
---|
23 | |
---|
24 | typedef struct { |
---|
25 | unsigned char nverts; |
---|
26 | int *verts; |
---|
27 | void *other_props; |
---|
28 | } Face; |
---|
29 | |
---|
30 | typedef Vertex *VertArray; |
---|
31 | typedef Face *FaceArray; |
---|
32 | |
---|
33 | PlyProperty vert_props[] = { |
---|
34 | {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0}, |
---|
35 | {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0}, |
---|
36 | {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0}, |
---|
37 | }; |
---|
38 | |
---|
39 | PlyProperty face_props[] = { |
---|
40 | {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts), |
---|
41 | 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)}, |
---|
42 | }; |
---|
43 | |
---|
44 | |
---|
45 | // Variables for the PLY object |
---|
46 | int *numVerts; |
---|
47 | Vertex **verts; |
---|
48 | int *numFaces; |
---|
49 | Face **faces; |
---|
50 | int numFiles; |
---|
51 | int numTotalVerts; |
---|
52 | int numTotalFaces; |
---|
53 | PlyOtherProp *vert_other; |
---|
54 | PlyOtherProp *face_other; |
---|
55 | PlyOtherElems *other_elements; |
---|
56 | |
---|
57 | |
---|
58 | /////////////////////////////////////////////////////////////////////// |
---|
59 | |
---|
60 | |
---|
61 | void ReadPlyFile(FILE *plyfile, int index) |
---|
62 | { |
---|
63 | PlyFile *ply; |
---|
64 | float version; |
---|
65 | int i,j; |
---|
66 | char *elem_name; |
---|
67 | int num_elems; |
---|
68 | int nprops; |
---|
69 | int nelems; |
---|
70 | int file_type; |
---|
71 | char **elist; |
---|
72 | |
---|
73 | ply = ply_read (plyfile, &nelems, &elist); |
---|
74 | ply_get_info (ply, &version, &file_type); |
---|
75 | |
---|
76 | for (i=0; i<nelems; ++i) { |
---|
77 | |
---|
78 | elem_name = elist[i]; |
---|
79 | ply_get_element_description (ply, elem_name, &num_elems, &nprops); |
---|
80 | |
---|
81 | if (equal_strings ("vertex", elem_name)) { |
---|
82 | |
---|
83 | numVerts[index] = num_elems; |
---|
84 | verts[index] = new Vertex[num_elems]; |
---|
85 | |
---|
86 | ply_get_property (ply, elem_name, &vert_props[0]); |
---|
87 | ply_get_property (ply, elem_name, &vert_props[1]); |
---|
88 | ply_get_property (ply, elem_name, &vert_props[2]); |
---|
89 | vert_other = ply_get_other_properties (ply, elem_name, |
---|
90 | offsetof(Vertex,other_props)); |
---|
91 | |
---|
92 | for (j=0; j<num_elems; ++j) |
---|
93 | ply_get_element (ply, (void *) &verts[index][j]); |
---|
94 | } |
---|
95 | |
---|
96 | else if (equal_strings ("face", elem_name)) { |
---|
97 | |
---|
98 | numFaces[index] = num_elems; |
---|
99 | faces[index] = new Face[num_elems]; |
---|
100 | |
---|
101 | ply_get_property (ply, elem_name, &face_props[0]); |
---|
102 | face_other = ply_get_other_properties (ply, elem_name, |
---|
103 | offsetof(Face,other_props)); |
---|
104 | |
---|
105 | for (j=0; j<num_elems; ++j) |
---|
106 | ply_get_element (ply, (void *) &faces[index][j]); |
---|
107 | } |
---|
108 | |
---|
109 | else |
---|
110 | other_elements=ply_get_other_element(ply, elem_name, num_elems); |
---|
111 | } |
---|
112 | |
---|
113 | ply_close (ply); |
---|
114 | } |
---|
115 | |
---|
116 | |
---|
117 | void WritePlyFile() |
---|
118 | { |
---|
119 | PlyFile *ply; |
---|
120 | int i, n; |
---|
121 | char *elist[] = {"vertex", "face"}; |
---|
122 | |
---|
123 | ply = ply_write (stdout, 2, elist, PLY_BINARY_BE); |
---|
124 | |
---|
125 | ply_element_count (ply, "vertex", numTotalVerts); |
---|
126 | ply_describe_property (ply, "vertex", &vert_props[0]); |
---|
127 | ply_describe_property (ply, "vertex", &vert_props[1]); |
---|
128 | ply_describe_property (ply, "vertex", &vert_props[2]); |
---|
129 | ply_describe_other_properties(ply,vert_other,offsetof(Vertex,other_props)); |
---|
130 | |
---|
131 | ply_element_count (ply, "face", numTotalFaces); |
---|
132 | ply_describe_property (ply, "face", &face_props[0]); |
---|
133 | ply_describe_other_properties(ply,face_other,offsetof(Face,other_props)); |
---|
134 | |
---|
135 | ply_describe_other_elements (ply, other_elements); |
---|
136 | |
---|
137 | ply_header_complete (ply); |
---|
138 | |
---|
139 | ply_put_element_setup (ply, "vertex"); |
---|
140 | for (n=0; n<numFiles; ++n) |
---|
141 | for (i = 0; i < numVerts[n]; i++) |
---|
142 | ply_put_element (ply, (void *) &verts[n][i]); |
---|
143 | |
---|
144 | ply_put_element_setup (ply, "face"); |
---|
145 | for (n=0; n<numFiles; ++n) |
---|
146 | for (i = 0; i < numFaces[n]; i++) |
---|
147 | ply_put_element (ply, (void *) &faces[n][i]); |
---|
148 | |
---|
149 | ply_put_other_elements (ply); |
---|
150 | |
---|
151 | ply_close (ply); |
---|
152 | } |
---|
153 | |
---|
154 | |
---|
155 | int |
---|
156 | main(int argc, char *argv[]) |
---|
157 | { |
---|
158 | int i, j, k; |
---|
159 | FILE *f; |
---|
160 | |
---|
161 | numFiles = argc - 1; |
---|
162 | |
---|
163 | numVerts = new int[numFiles]; |
---|
164 | verts = new VertArray[numFiles]; |
---|
165 | numFaces = new int[numFiles]; |
---|
166 | faces = new FaceArray[numFiles]; |
---|
167 | |
---|
168 | numTotalVerts = 0; |
---|
169 | numTotalFaces = 0; |
---|
170 | |
---|
171 | for (i=0; i<numFiles; ++i) { |
---|
172 | |
---|
173 | f = fopen(argv[i+1], "r"); |
---|
174 | if (!f) { |
---|
175 | fprintf(stderr, "Unable to open file (argv[%d])\n", i+1); |
---|
176 | exit(-1); |
---|
177 | } |
---|
178 | |
---|
179 | ReadPlyFile(f, i); |
---|
180 | |
---|
181 | // Offset the vertex indices of the new faces just read in |
---|
182 | |
---|
183 | for (j=0; j<numFaces[i]; ++j) |
---|
184 | for (k=0; k<faces[i][j].nverts; ++k) |
---|
185 | faces[i][j].verts[k] += numTotalVerts; |
---|
186 | |
---|
187 | numTotalVerts += numVerts[i]; |
---|
188 | numTotalFaces += numFaces[i]; |
---|
189 | |
---|
190 | fclose(f); |
---|
191 | } |
---|
192 | |
---|
193 | WritePlyFile(); |
---|
194 | } |
---|
195 | |
---|