File: | src/limn/io.c |
Location: | line 1091, column 3 |
Description: | Value stored to 'got' is never read |
1 | /* |
2 | Teem: Tools to process and visualize scientific data and images . |
3 | Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago |
4 | Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann |
5 | Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Lesser General Public License |
9 | (LGPL) as published by the Free Software Foundation; either |
10 | version 2.1 of the License, or (at your option) any later version. |
11 | The terms of redistributing and/or modifying this software also |
12 | include exceptions to the LGPL that facilitate static linking. |
13 | |
14 | This library is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | Lesser General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Lesser General Public License |
20 | along with this library; if not, write to Free Software Foundation, Inc., |
21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | */ |
23 | |
24 | |
25 | #include "limn.h" |
26 | |
27 | int |
28 | limnObjectDescribe(FILE *file, const limnObject *obj) { |
29 | limnFace *face; unsigned int si, fii; |
30 | limnEdge *edge; unsigned int eii; |
31 | limnVertex *vert; unsigned int vii; |
32 | limnPart *part; unsigned int partIdx; |
33 | limnLook *look; |
34 | |
35 | fprintf(file, "parts: %d\n", obj->partNum); |
36 | for (partIdx=0; partIdx<obj->partNum; partIdx++) { |
37 | part = obj->part[partIdx]; |
38 | fprintf(file, "part %d | verts: %d ========\n", partIdx, part->vertIdxNum); |
39 | for (vii=0; vii<part->vertIdxNum; vii++) { |
40 | vert = obj->vert + part->vertIdx[vii]; |
41 | fprintf(file, "part %d | %d(%d): w=(%g,%g,%g)\n", |
42 | partIdx, vii, part->vertIdx[vii], |
43 | vert->world[0], vert->world[1], vert->world[2]); |
44 | /* vert->view[0], vert->view[1], vert->view[2]); */ |
45 | /* vert->screen[0], vert->screen[1], vert->screen[2]); */ |
46 | } |
47 | fprintf(file, "part %d | edges: %d ========\n", partIdx, part->edgeIdxNum); |
48 | for (eii=0; eii<part->edgeIdxNum; eii++) { |
49 | edge = obj->edge + part->edgeIdx[eii]; |
50 | fprintf(file, "part %d==%d | %d(%d): " |
51 | "vert(%d,%d), face(%d,%d)\n", |
52 | partIdx, edge->partIdx, eii, part->edgeIdx[eii], |
53 | edge->vertIdx[0], edge->vertIdx[1], |
54 | edge->faceIdx[0], edge->faceIdx[1]); |
55 | } |
56 | fprintf(file, "part %d | faces: %d ========\n", partIdx, part->faceIdxNum); |
57 | for (fii=0; fii<part->faceIdxNum; fii++) { |
58 | face = obj->face + part->faceIdx[fii]; |
59 | fprintf(file, "part %d==%d | %d(%d): [", |
60 | partIdx, face->partIdx, fii, part->faceIdx[fii]); |
61 | for (si=0; si<face->sideNum; si++) { |
62 | fprintf(file, "%d", face->vertIdx[si]); |
63 | if (si < face->sideNum-1) { |
64 | fprintf(file, ","); |
65 | } |
66 | } |
67 | fprintf(file, "]; wn = (%g,%g,%g) |%g|", face->worldNormal[0], |
68 | face->worldNormal[1], face->worldNormal[2], |
69 | ELL_3V_LEN(face->worldNormal)(sqrt((((face->worldNormal))[0]*((face->worldNormal))[0 ] + ((face->worldNormal))[1]*((face->worldNormal))[1] + ((face->worldNormal))[2]*((face->worldNormal))[2])))); |
70 | look = obj->look + face->lookIdx; |
71 | fprintf(file, "; RGB=(%g,%g,%g)", |
72 | look->rgba[0], look->rgba[1], look->rgba[2]); |
73 | fprintf(file, "\n"); |
74 | } |
75 | } |
76 | |
77 | return 0; |
78 | } |
79 | |
80 | int |
81 | limnObjectWriteOFF(FILE *file, const limnObject *obj) { |
82 | static const char me[]="limnObjectWriteOFF"; |
83 | unsigned int si; |
84 | limnVertex *vert; unsigned int vii; |
85 | limnFace *face; unsigned int fii; |
86 | limnPart *part; unsigned int partIdx; |
87 | |
88 | if (!( obj && file )) { |
89 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
90 | return 1; |
91 | } |
92 | fprintf(file, "OFF # created by Teem/limn\n"); |
93 | fprintf(file, "%d %d %d\n", obj->vertNum, obj->faceNum, obj->edgeNum); |
94 | |
95 | /* write vertices */ |
96 | for (partIdx=0; partIdx<obj->partNum; partIdx++) { |
97 | fprintf(file, "### LIMN BEGIN PART %d\n", partIdx); |
98 | part = obj->part[partIdx]; |
99 | for (vii=0; vii<part->vertIdxNum; vii++) { |
100 | vert = obj->vert + part->vertIdx[vii]; |
101 | fprintf(file, "%g %g %g", |
102 | vert->world[0]/vert->world[3], |
103 | vert->world[1]/vert->world[3], |
104 | vert->world[2]/vert->world[3]); |
105 | /* verts no longer have a lookIdx |
106 | if (vert->lookIdx) { |
107 | fprintf(file, " %g %g %g", |
108 | obj->look[vert->lookIdx].rgba[0], |
109 | obj->look[vert->lookIdx].rgba[1], |
110 | obj->look[vert->lookIdx].rgba[2]); |
111 | } |
112 | */ |
113 | fprintf(file, "\n"); |
114 | } |
115 | } |
116 | |
117 | /* write faces */ |
118 | for (partIdx=0; partIdx<obj->partNum; partIdx++) { |
119 | fprintf(file, "### LIMN BEGIN PART %d\n", partIdx); |
120 | part = obj->part[partIdx]; |
121 | for (fii=0; fii<part->faceIdxNum; fii++) { |
122 | face = obj->face + part->faceIdx[fii]; |
123 | fprintf(file, "%d", face->sideNum); |
124 | for (si=0; si<face->sideNum; si++) { |
125 | fprintf(file, " %d", face->vertIdx[si]); |
126 | } |
127 | if (face->lookIdx) { |
128 | fprintf(file, " %g %g %g", |
129 | obj->look[face->lookIdx].rgba[0], |
130 | obj->look[face->lookIdx].rgba[1], |
131 | obj->look[face->lookIdx].rgba[2]); |
132 | } |
133 | fprintf(file, "\n"); |
134 | } |
135 | } |
136 | |
137 | return 0; |
138 | } |
139 | |
140 | int |
141 | limnPolyDataWriteIV(FILE *file, const limnPolyData *pld) { |
142 | static const char me[]="limnPolyDataWriteIV"; |
143 | unsigned int primIdx, xyzwIdx, rgbaIdx, normIdx, bitFlag, |
144 | baseVertIdx; |
145 | int haveStrips, haveTris, haveElse; |
146 | double xyz[3], norm[3], len; |
147 | |
148 | if (!(file && pld)) { |
149 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
150 | return 1; |
151 | } |
152 | haveStrips = haveTris = haveElse = AIR_FALSE0; |
153 | for (primIdx=0; primIdx<pld->primNum; primIdx++) { |
154 | int isTri, isStrip, isElse; |
155 | isTri = limnPrimitiveTriangles == pld->type[primIdx]; |
156 | isStrip = limnPrimitiveTriangleStrip == pld->type[primIdx]; |
157 | isElse = !(isTri || isStrip); |
158 | haveTris |= isTri; |
159 | haveStrips |= isStrip; |
160 | haveElse |= isElse; |
161 | if (isElse) { |
162 | biffAddf(LIMNlimnBiffKey, |
163 | "%s: sorry, can only have %s or %s prims (prim[%u] is %s)", |
164 | me, airEnumStr(limnPrimitive, limnPrimitiveTriangles), |
165 | airEnumStr(limnPrimitive, limnPrimitiveTriangleStrip), |
166 | primIdx, airEnumStr(limnPrimitive, pld->type[primIdx])); |
167 | return 1; |
168 | } |
169 | } |
170 | if (haveStrips && 1 != pld->primNum) { |
171 | biffAddf(LIMNlimnBiffKey, "%s: sorry, can only have a single triangle strip", me); |
172 | return 1; |
173 | } |
174 | |
175 | fprintf(file, "#Inventor V2.0 ascii\n"); |
176 | fprintf(file, "# written by Teem/limn\n\n"); |
177 | fprintf(file, "Separator {\n"); |
178 | fprintf(file, " Coordinate3 {\n"); |
179 | fprintf(file, " point [\n"); |
180 | if (haveStrips) { |
181 | unsigned int vii; |
182 | for (vii=0; vii<pld->icnt[0]; vii++) { |
183 | xyzwIdx = (pld->indx)[vii]; |
184 | ELL_34V_HOMOG(xyz, pld->xyzw + 4*xyzwIdx)((xyz)[0] = (pld->xyzw + 4*xyzwIdx)[0]/(pld->xyzw + 4*xyzwIdx )[3], (xyz)[1] = (pld->xyzw + 4*xyzwIdx)[1]/(pld->xyzw + 4*xyzwIdx)[3], (xyz)[2] = (pld->xyzw + 4*xyzwIdx)[2]/(pld ->xyzw + 4*xyzwIdx)[3]); |
185 | fprintf(file, " %g %g %g%s\n", |
186 | xyz[0], xyz[1], xyz[2], |
187 | vii < pld->icnt[0]-1 ? "," : ""); |
188 | } |
189 | } else { |
190 | for (xyzwIdx=0; xyzwIdx<pld->xyzwNum; xyzwIdx++) { |
191 | ELL_34V_HOMOG(xyz, pld->xyzw + 4*xyzwIdx)((xyz)[0] = (pld->xyzw + 4*xyzwIdx)[0]/(pld->xyzw + 4*xyzwIdx )[3], (xyz)[1] = (pld->xyzw + 4*xyzwIdx)[1]/(pld->xyzw + 4*xyzwIdx)[3], (xyz)[2] = (pld->xyzw + 4*xyzwIdx)[2]/(pld ->xyzw + 4*xyzwIdx)[3]); |
192 | fprintf(file, " %g %g %g%s\n", |
193 | xyz[0], xyz[1], xyz[2], |
194 | xyzwIdx < pld->xyzwNum-1 ? "," : ""); |
195 | } |
196 | } |
197 | fprintf(file, " ]\n"); |
198 | fprintf(file, " }\n"); |
199 | |
200 | bitFlag = limnPolyDataInfoBitFlag(pld); |
201 | if (bitFlag & (1 << limnPolyDataInfoNorm)) { |
202 | fprintf(file, " NormalBinding { value PER_VERTEX_INDEXED }\n"); |
203 | fprintf(file, " Normal {\n"); |
204 | fprintf(file, " vector [\n"); |
205 | if (haveStrips) { |
206 | unsigned int vii; |
207 | for (vii=0; vii<pld->icnt[0]; vii++) { |
208 | normIdx = (pld->indx)[vii]; |
209 | ELL_3V_SET(norm,((norm)[0] = (pld->norm[0 + 3*normIdx]), (norm)[1] = (pld-> norm[1 + 3*normIdx]), (norm)[2] = (pld->norm[2 + 3*normIdx ])) |
210 | pld->norm[0 + 3*normIdx],((norm)[0] = (pld->norm[0 + 3*normIdx]), (norm)[1] = (pld-> norm[1 + 3*normIdx]), (norm)[2] = (pld->norm[2 + 3*normIdx ])) |
211 | pld->norm[1 + 3*normIdx],((norm)[0] = (pld->norm[0 + 3*normIdx]), (norm)[1] = (pld-> norm[1 + 3*normIdx]), (norm)[2] = (pld->norm[2 + 3*normIdx ])) |
212 | pld->norm[2 + 3*normIdx])((norm)[0] = (pld->norm[0 + 3*normIdx]), (norm)[1] = (pld-> norm[1 + 3*normIdx]), (norm)[2] = (pld->norm[2 + 3*normIdx ])); |
213 | ELL_3V_NORM(norm, norm, len)(len = (sqrt((((norm))[0]*((norm))[0] + ((norm))[1]*((norm))[ 1] + ((norm))[2]*((norm))[2]))), ((norm)[0] = (1.0/len)*(norm )[0], (norm)[1] = (1.0/len)*(norm)[1], (norm)[2] = (1.0/len)* (norm)[2])); |
214 | fprintf(file, " %g %g %g%s\n", norm[0], norm[1], norm[2], |
215 | vii < pld->icnt[0]-1 ? "," : ""); |
216 | } |
217 | } else { |
218 | for (normIdx=0; normIdx<pld->normNum; normIdx++) { |
219 | fprintf(file, " %g %g %g%s\n", |
220 | pld->norm[0 + 3*normIdx], |
221 | pld->norm[1 + 3*normIdx], |
222 | pld->norm[2 + 3*normIdx], |
223 | normIdx < pld->normNum-1 ? "," : ""); |
224 | } |
225 | } |
226 | fprintf(file, " ]\n"); |
227 | fprintf(file, " }\n"); |
228 | } |
229 | if (!haveStrips) { |
230 | if (bitFlag & (1 << limnPolyDataInfoRGBA)) { |
231 | fprintf(file, " MaterialBinding { value PER_VERTEX_INDEXED }\n"); |
232 | fprintf(file, " Material {\n"); |
233 | fprintf(file, " diffuseColor [\n"); |
234 | for (rgbaIdx=0; rgbaIdx<pld->rgbaNum; rgbaIdx++) { |
235 | fprintf(file, " %g %g %g%s\n", |
236 | pld->rgba[0 + 4*rgbaIdx]/255.0, |
237 | pld->rgba[1 + 4*rgbaIdx]/255.0, |
238 | pld->rgba[2 + 4*rgbaIdx]/255.0, |
239 | rgbaIdx < pld->rgbaNum-1 ? "," : ""); |
240 | } |
241 | fprintf(file, " ]\n"); |
242 | fprintf(file, " }\n"); |
243 | } |
244 | } |
245 | |
246 | if (haveStrips) { |
247 | fprintf(file, " TriangleStripSet {\n"); |
248 | fprintf(file, " numVertices %u\n", pld->icnt[0]); |
249 | fprintf(file, " }\n"); |
250 | } else { |
251 | fprintf(file, " IndexedFaceSet {\n"); |
252 | fprintf(file, " coordIndex [\n"); |
253 | |
254 | baseVertIdx = 0; |
255 | for (primIdx=0; primIdx<pld->primNum; primIdx++) { |
256 | unsigned int triIdx, triNum, *indx3; |
257 | triNum = pld->icnt[primIdx]/3; |
258 | for (triIdx=0; triIdx<triNum; triIdx++) { |
259 | indx3 = pld->indx + baseVertIdx + 3*triIdx; |
260 | fprintf(file, " %u, %u, %u, -1%s\n", |
261 | indx3[0], indx3[1], indx3[2], |
262 | triIdx < triNum-1 ? "," : ""); |
263 | } |
264 | baseVertIdx += 3*triNum; |
265 | } |
266 | fprintf(file, " ]\n"); |
267 | fprintf(file, " }\n"); |
268 | } |
269 | |
270 | fprintf(file, "}\n"); |
271 | |
272 | return 0; |
273 | } |
274 | |
275 | int |
276 | limnObjectReadOFF(limnObject *obj, FILE *file) { |
277 | static const char me[]="limnObjectReadOFF"; |
278 | double vert[6]; |
279 | char line[AIR_STRLEN_LARGE(512+1)]; /* HEY: bad Gordon */ |
280 | int lineCount, lookIdx, partIdx, idxTmp, faceNum, faceGot, got; |
281 | unsigned int vertGot,vertNum; |
282 | unsigned int ibuff[1024]; /* HEY: bad Gordon */ |
283 | float fbuff[1024]; /* HEY: bad bad Gordon */ |
284 | float lastRGB[3]={-1,-1,-1}; int lastLook; |
285 | unsigned int lret; |
286 | |
287 | int *vertBase; |
288 | airArray *vertBaseArr, *mop; |
289 | airPtrPtrUnion appu; |
290 | |
291 | if (!( obj && file )) { |
292 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
293 | return 1; |
294 | } |
295 | vertBase = NULL((void*)0); |
296 | appu.i = &vertBase; |
297 | vertBaseArr = airArrayNew(appu.v, NULL((void*)0), sizeof(int), 128); |
298 | mop = airMopNew(); |
299 | airMopAdd(mop, vertBaseArr, (airMopper)airArrayNuke, airMopAlways); |
300 | got = 0; |
301 | lineCount = 0; |
302 | do { |
303 | if (!airOneLine(file, line, AIR_STRLEN_LARGE(512+1))) { |
304 | biffAddf(LIMNlimnBiffKey, "%s: hit EOF before getting #vert #face #edge line", me); |
305 | airMopError(mop); return 1; |
306 | } |
307 | lineCount++; |
308 | got = airParseStrUI(ibuff, line, AIR_WHITESPACE" \t\n\r\v\f", 3); |
309 | } while (3 != got); |
310 | vertNum = ibuff[0]; |
311 | faceNum = ibuff[1]; |
312 | |
313 | /* read all vertex information */ |
314 | lastLook = -1; |
315 | partIdx = limnObjectPartAdd(obj); |
316 | vertGot = 0; |
317 | airArrayLenIncr(vertBaseArr, 1); |
318 | vertBase[partIdx] = vertGot; |
319 | while (vertGot < vertNum) { |
320 | do { |
321 | lret = airOneLine(file, line, AIR_STRLEN_LARGE(512+1)); |
322 | lineCount++; |
323 | } while (1 == lret); |
324 | if (!lret) { |
325 | biffAddf(LIMNlimnBiffKey, |
326 | "%s: (near line %d) hit EOF trying to read vert %d (of %d)", |
327 | me, lineCount, vertGot, vertNum); |
328 | airMopError(mop); return 1; |
329 | } |
330 | if (1 == sscanf(line, "### LIMN BEGIN PART %d", &idxTmp)) { |
331 | if (idxTmp != 0) { |
332 | partIdx = limnObjectPartAdd(obj); |
333 | if (idxTmp != partIdx) { |
334 | biffAddf(LIMNlimnBiffKey, "%s: got signal to start part %d, not %d", |
335 | me, idxTmp, partIdx); |
336 | airMopError(mop); return 1; |
337 | } |
338 | airArrayLenIncr(vertBaseArr, 1); |
339 | vertBase[partIdx] = vertGot; |
340 | } |
341 | continue; |
342 | } |
343 | if (3 != airParseStrD(vert, line, AIR_WHITESPACE" \t\n\r\v\f", 3)) { |
344 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse 3 doubles from \"%s\" " |
345 | "for vert %d (of %d)", |
346 | me, line, vertGot, vertNum); |
347 | airMopError(mop); return 1; |
348 | } |
349 | if (6 == airParseStrD(vert, line, AIR_WHITESPACE" \t\n\r\v\f", 6)) { |
350 | /* we could also parse an RGB color */ |
351 | if (-1 == lastLook || !ELL_3V_EQUAL(lastRGB, vert+3)((lastRGB)[0] == (vert+3)[0] && (lastRGB)[1] == (vert +3)[1] && (lastRGB)[2] == (vert+3)[2])) { |
352 | lookIdx = limnObjectLookAdd(obj); |
353 | ELL_4V_SET(obj->look[lookIdx].rgba,((obj->look[lookIdx].rgba)[0] = (((float)(vert[3]))), (obj ->look[lookIdx].rgba)[1] = (((float)(vert[4]))), (obj-> look[lookIdx].rgba)[2] = (((float)(vert[5]))), (obj->look[ lookIdx].rgba)[3] = (1)) |
354 | AIR_CAST(float, vert[3]),((obj->look[lookIdx].rgba)[0] = (((float)(vert[3]))), (obj ->look[lookIdx].rgba)[1] = (((float)(vert[4]))), (obj-> look[lookIdx].rgba)[2] = (((float)(vert[5]))), (obj->look[ lookIdx].rgba)[3] = (1)) |
355 | AIR_CAST(float, vert[4]),((obj->look[lookIdx].rgba)[0] = (((float)(vert[3]))), (obj ->look[lookIdx].rgba)[1] = (((float)(vert[4]))), (obj-> look[lookIdx].rgba)[2] = (((float)(vert[5]))), (obj->look[ lookIdx].rgba)[3] = (1)) |
356 | AIR_CAST(float, vert[5]),((obj->look[lookIdx].rgba)[0] = (((float)(vert[3]))), (obj ->look[lookIdx].rgba)[1] = (((float)(vert[4]))), (obj-> look[lookIdx].rgba)[2] = (((float)(vert[5]))), (obj->look[ lookIdx].rgba)[3] = (1)) |
357 | 1)((obj->look[lookIdx].rgba)[0] = (((float)(vert[3]))), (obj ->look[lookIdx].rgba)[1] = (((float)(vert[4]))), (obj-> look[lookIdx].rgba)[2] = (((float)(vert[5]))), (obj->look[ lookIdx].rgba)[3] = (1)); |
358 | lastLook = lookIdx; |
359 | ELL_3V_COPY_TT(lastRGB, float, vert+3)((lastRGB)[0] = ((float)((vert+3)[0])), (lastRGB)[1] = ((float )((vert+3)[1])), (lastRGB)[2] = ((float)((vert+3)[2]))); |
360 | } else { |
361 | lookIdx = lastLook; |
362 | } |
363 | } else { |
364 | lookIdx = 0; |
365 | } |
366 | /* |
367 | fprintf(stderr, "line %d: vertGot = %d; lookIdx = %d; partIdx = %d\n", |
368 | lineCount, vertGot, lookIdx, partIdx); |
369 | */ |
370 | limnObjectVertexAdd(obj, partIdx, |
371 | AIR_CAST(float, vert[0])((float)(vert[0])), |
372 | AIR_CAST(float, vert[1])((float)(vert[1])), |
373 | AIR_CAST(float, vert[2])((float)(vert[2]))); |
374 | vertGot++; |
375 | } |
376 | /* read face information */ |
377 | partIdx = 0; |
378 | faceGot = 0; |
379 | while (faceGot < faceNum) { |
380 | do { |
381 | lret = airOneLine(file, line, AIR_STRLEN_LARGE(512+1)); |
382 | lineCount++; |
383 | } while (1 == lret); |
384 | if (!lret) { |
385 | biffAddf(LIMNlimnBiffKey, |
386 | "%s: (near line %d) hit EOF trying to read face %d (of %d)", |
387 | me, lineCount, faceGot, faceNum); |
388 | airMopError(mop); return 1; |
389 | } |
390 | if (1 == sscanf(line, "### LIMN BEGIN PART %d", &idxTmp)) { |
391 | if (idxTmp != 0) { |
392 | partIdx += 1; |
393 | if (idxTmp != partIdx) { |
394 | biffAddf(LIMNlimnBiffKey, "%s: (near line %d) got signal to start " |
395 | "part %d, not %d", |
396 | me, lineCount, idxTmp, partIdx); |
397 | airMopError(mop); return 1; |
398 | } |
399 | } |
400 | continue; |
401 | } |
402 | if ('#' == line[0]) { |
403 | /* its some other kind of comment line */ |
404 | continue; |
405 | } |
406 | if (1 != sscanf(line, "%u", &vertNum)) { |
407 | biffAddf(LIMNlimnBiffKey, "%s: (near line %d) can't get first int " |
408 | "(#verts) from \"%s\" for face %d (of %d)", |
409 | me, lineCount, line, faceGot, faceNum); |
410 | airMopError(mop); return 1; |
411 | } |
412 | if (vertNum+1 != airParseStrUI(ibuff, line, AIR_WHITESPACE" \t\n\r\v\f", vertNum+1)) { |
413 | biffAddf(LIMNlimnBiffKey, "%s: (near line %d) couldn't parse %d ints from \"%s\" " |
414 | "for face %d (of %d)", |
415 | me, lineCount, vertNum+1, line, faceGot, faceNum); |
416 | airMopError(mop); return 1; |
417 | } |
418 | if (vertNum+1+3 == airParseStrF(fbuff, line, |
419 | AIR_WHITESPACE" \t\n\r\v\f", vertNum+1+3)) { |
420 | /* could also parse color */ |
421 | if (-1 == lastLook || !ELL_3V_EQUAL(lastRGB, fbuff+vertNum+1)((lastRGB)[0] == (fbuff+vertNum+1)[0] && (lastRGB)[1] == (fbuff+vertNum+1)[1] && (lastRGB)[2] == (fbuff+vertNum +1)[2])) { |
422 | lookIdx = limnObjectLookAdd(obj); |
423 | ELL_4V_SET(obj->look[lookIdx].rgba, fbuff[vertNum+1+0],((obj->look[lookIdx].rgba)[0] = (fbuff[vertNum+1+0]), (obj ->look[lookIdx].rgba)[1] = (fbuff[vertNum+1+1]), (obj-> look[lookIdx].rgba)[2] = (fbuff[vertNum+1+2]), (obj->look[ lookIdx].rgba)[3] = (1)) |
424 | fbuff[vertNum+1+1], fbuff[vertNum+1+2], 1)((obj->look[lookIdx].rgba)[0] = (fbuff[vertNum+1+0]), (obj ->look[lookIdx].rgba)[1] = (fbuff[vertNum+1+1]), (obj-> look[lookIdx].rgba)[2] = (fbuff[vertNum+1+2]), (obj->look[ lookIdx].rgba)[3] = (1)); |
425 | lastLook = lookIdx; |
426 | ELL_3V_COPY(lastRGB, fbuff+vertNum+1)((lastRGB)[0] = (fbuff+vertNum+1)[0], (lastRGB)[1] = (fbuff+vertNum +1)[1], (lastRGB)[2] = (fbuff+vertNum+1)[2]); |
427 | } else { |
428 | lookIdx = lastLook; |
429 | } |
430 | } else { |
431 | lookIdx = 0; |
432 | } |
433 | /* |
434 | fprintf(stderr, "line %d: faceGot = %d; lookIdx = %d; partIdx = %d\n", |
435 | lineCount, faceGot, lookIdx, partIdx); |
436 | */ |
437 | limnObjectFaceAdd(obj, partIdx, lookIdx, vertNum, ibuff+1); |
438 | faceGot++; |
439 | } |
440 | |
441 | airMopOkay(mop); |
442 | return 0; |
443 | } |
444 | |
445 | /* |
446 | http://www.npr.org/templates/story/story.php?storyId=4531695 |
447 | */ |
448 | |
449 | #define LMPD_MAGIC"LIMN0001" "LIMN0001" |
450 | #define DEMARK_STR"====== " "====== " |
451 | #define DEMARK_CHAR'=' '=' |
452 | #define NUM_STR"num:" "num:" |
453 | #define INFO_STR"info:" "info:" |
454 | #define TYPE_STR"type:" "type:" |
455 | #define ICNT_STR"icnt:" "icnt:" |
456 | #define INDX_STR"indx:" "indx:" |
457 | #define XYZW_STR"xyzw:" "xyzw:" |
458 | |
459 | int |
460 | limnPolyDataWriteLMPD(FILE *file, const limnPolyData *pld) { |
461 | static const char me[]="limnPolyDataWriteLMPD"; |
462 | char infoS[AIR_STRLEN_MED(256+1)]; |
463 | unsigned int primIdx, infoNum, flag, bit; |
464 | Nrrd *nrrd; |
465 | airArray *mop; |
466 | |
467 | if (!(file && pld)) { |
468 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
469 | return 1; |
470 | } |
471 | |
472 | for (primIdx=0; primIdx<pld->primNum; primIdx++) { |
473 | if (limnPrimitiveNoop == pld->type[primIdx]) { |
474 | biffAddf(LIMNlimnBiffKey, "%s: sorry, can't save with prim[%u] type %s", me, |
475 | primIdx, airEnumStr(limnPrimitive, pld->type[primIdx])); |
476 | return 1; |
477 | } |
478 | } |
479 | |
480 | mop = airMopNew(); |
481 | |
482 | fprintf(file, "%s\n", LMPD_MAGIC"LIMN0001"); |
483 | fprintf(file, "%s%s %u %u %u\n", DEMARK_STR"====== ", NUM_STR"num:", |
484 | pld->xyzwNum, pld->indxNum, pld->primNum); |
485 | |
486 | flag = limnPolyDataInfoBitFlag(pld); |
487 | infoNum = 0; |
488 | bit = 0; |
489 | strcpy(infoS, "")__builtin___strcpy_chk (infoS, "", __builtin_object_size (infoS , 2 > 1 ? 1 : 0)); |
490 | while (flag) { |
491 | if (flag & 1) { |
492 | infoNum += 1; |
493 | strcat(infoS, airEnumStr(limnPolyDataInfo, bit))__builtin___strcat_chk (infoS, airEnumStr(limnPolyDataInfo, bit ), __builtin_object_size (infoS, 2 > 1 ? 1 : 0)); |
494 | strcat(infoS, "\n")__builtin___strcat_chk (infoS, "\n", __builtin_object_size (infoS , 2 > 1 ? 1 : 0)); |
495 | } |
496 | flag /= 2; |
497 | bit += 1; |
498 | } |
499 | fprintf(file, "%s%s %u\n%s", DEMARK_STR"====== ", INFO_STR"info:", infoNum, infoS); |
500 | |
501 | fprintf(file, "%s%s\n", DEMARK_STR"====== ", TYPE_STR"type:"); |
502 | for (primIdx=0; primIdx<pld->primNum; primIdx++) { |
503 | fprintf(file, "%s\n", airEnumStr(limnPrimitive, pld->type[primIdx])); |
504 | } |
505 | fprintf(file, "%s%s\n", DEMARK_STR"====== ", ICNT_STR"icnt:"); |
506 | for (primIdx=0; primIdx<pld->primNum; primIdx++) { |
507 | fprintf(file, "%u\n", pld->icnt[primIdx]); |
508 | } |
509 | nrrd = nrrdNew(); |
510 | airMopAdd(mop, nrrd, (airMopper)nrrdNix, airMopAlways); /* nix, not nuke */ |
511 | |
512 | fprintf(file, "%s%s\n", DEMARK_STR"====== ", INDX_STR"indx:"); |
513 | if (nrrdWrap_va(nrrd, pld->indx, nrrdTypeUInt, 1, pld->indxNum) |
514 | || nrrdWrite(file, nrrd, NULL((void*)0))) { |
515 | biffMovef(LIMNlimnBiffKey, NRRDnrrdBiffKey, "%s: problem saving indx array", me); |
516 | airMopError(mop); return 1; |
517 | } |
518 | fflush(file); |
519 | fprintf(file, "\n"); |
520 | |
521 | fprintf(file, "%s%s\n", DEMARK_STR"====== ", XYZW_STR"xyzw:"); |
522 | if (nrrdWrap_va(nrrd, pld->xyzw, nrrdTypeFloat, 2, 4, pld->xyzwNum) |
523 | || nrrdWrite(file, nrrd, NULL((void*)0))) { |
524 | biffMovef(LIMNlimnBiffKey, NRRDnrrdBiffKey, "%s: problem saving xyzw array", me); |
525 | airMopError(mop); return 1; |
526 | } |
527 | fflush(file); |
528 | fprintf(file, "\n"); |
529 | |
530 | if (infoNum) { |
531 | flag = limnPolyDataInfoBitFlag(pld); |
532 | bit = 0; |
533 | while (flag) { |
534 | if (flag & 1) { |
535 | int E; |
536 | fprintf(file, "%s%s %s\n", DEMARK_STR"====== ", INFO_STR"info:", |
537 | airEnumStr(limnPolyDataInfo, bit)); |
538 | switch (bit) { |
539 | case limnPolyDataInfoRGBA: |
540 | E = nrrdWrap_va(nrrd, pld->rgba, nrrdTypeUChar, 2, 4, pld->rgbaNum); |
541 | break; |
542 | case limnPolyDataInfoNorm: |
543 | E = nrrdWrap_va(nrrd, pld->norm, nrrdTypeFloat, 2, 3, pld->normNum); |
544 | break; |
545 | case limnPolyDataInfoTex2: |
546 | E = nrrdWrap_va(nrrd, pld->tex2, nrrdTypeFloat, 2, 2, pld->tex2Num); |
547 | break; |
548 | case limnPolyDataInfoTang: |
549 | E = nrrdWrap_va(nrrd, pld->tang, nrrdTypeFloat, 2, 3, pld->tangNum); |
550 | break; |
551 | default: |
552 | biffAddf(LIMNlimnBiffKey, "%s: info %d (%s) not handled", me, bit, |
553 | airEnumStr(limnPolyDataInfo, bit)); |
554 | airMopError(mop); return 1; |
555 | break; |
556 | } |
557 | if (E || nrrdWrite(file, nrrd, NULL((void*)0))) { |
558 | biffMovef(LIMNlimnBiffKey, NRRDnrrdBiffKey, "%s: problem saving %s info", |
559 | me, airEnumStr(limnPolyDataInfo, bit)); |
560 | airMopError(mop); return 1; |
561 | } |
562 | fflush(file); |
563 | fprintf(file, "\n"); |
564 | } |
565 | flag /= 2; |
566 | bit += 1; |
567 | } |
568 | } |
569 | |
570 | airMopOkay(mop); |
571 | return 0; |
572 | } |
573 | |
574 | /* |
575 | ******** limnPolyDataReadLMPD |
576 | ** |
577 | ** reads a limnPolyData from an LMPD file |
578 | ** |
579 | ** HEY: this was written in a hurry, is pretty hacky, and so it |
580 | ** needs some serious clean-up |
581 | */ |
582 | int |
583 | limnPolyDataReadLMPD(limnPolyData *pld, FILE *file) { |
584 | static const char me[]="limnPolyDatReadLMPD"; |
585 | char line[AIR_STRLEN_MED(256+1)], name[AIR_STRLEN_MED(256+1)], *tmp; |
586 | unsigned int vertNum, indxNum, primNum, primIdx, lineLen, |
587 | infoNum, infoIdx, info, flag; |
588 | Nrrd *nrrd; |
589 | airArray *mop; |
590 | int hackhack, tmpChar; |
591 | |
592 | if (!(pld && file)) { |
593 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
594 | return 1; |
595 | } |
596 | |
597 | sprintf(name, "magic")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "magic"); |
598 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
599 | if (!lineLen) { |
600 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
601 | return 1; |
602 | } |
603 | if (strcmp(line, LMPD_MAGIC"LIMN0001")) { |
604 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" not expected \"%s\"", |
605 | me, name, line, LMPD_MAGIC"LIMN0001"); |
606 | return 1; |
607 | } |
608 | |
609 | sprintf(name, "nums")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "nums"); |
610 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
611 | if (!lineLen) { |
612 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
613 | return 1; |
614 | } |
615 | if (strncmp(line, DEMARK_STR"====== " NUM_STR"num:", strlen(DEMARK_STR"====== " NUM_STR"num:"))) { |
616 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" didn't start w/ expected \"%s\"", |
617 | me, name, line, NUM_STR"num:"); |
618 | return 1; |
619 | } |
620 | tmp = line + strlen(DEMARK_STR"====== " NUM_STR"num:"); |
621 | if (3 != sscanf(tmp, " %u %u %u", &vertNum, &indxNum, &primNum)) { |
622 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse \"%s\" as 3 uints on %s line", |
623 | me, tmp, name); |
624 | return 1; |
625 | } |
626 | |
627 | sprintf(name, "info")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "info"); |
628 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
629 | if (!lineLen) { |
630 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
631 | return 1; |
632 | } |
633 | if (strncmp(line, DEMARK_STR"====== " INFO_STR"info:", strlen(DEMARK_STR"====== " INFO_STR"info:"))) { |
634 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" didn't start w/ expected \"%s\"", |
635 | me, name, line, DEMARK_STR"====== " INFO_STR"info:"); |
636 | return 1; |
637 | } |
638 | tmp = line + strlen(DEMARK_STR"====== " INFO_STR"info:"); |
639 | if (1 != sscanf(tmp, " %u", &infoNum)) { |
640 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse \"%s\" as 1 uints on %s line", |
641 | me, tmp, name); |
642 | return 1; |
643 | } |
644 | flag = 0; |
645 | for (infoIdx=0; infoIdx<infoNum; infoIdx++) { |
646 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
647 | if (!lineLen) { |
648 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line %u/%u", |
649 | me, name, infoIdx, infoNum); |
650 | return 1; |
651 | } |
652 | info = airEnumVal(limnPolyDataInfo, line); |
653 | if (!info) { |
654 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse \"%s\" %s line %u/%u", |
655 | me, line, name, infoIdx, infoNum); |
656 | return 1; |
657 | } |
658 | flag |= (1 << info); |
659 | } |
660 | |
661 | /* finally, allocate the polydata */ |
662 | if (limnPolyDataAlloc(pld, flag, vertNum, indxNum, primNum)) { |
663 | biffAddf(LIMNlimnBiffKey, "%s: couldn't allocate polydata", me); |
664 | return 1; |
665 | } |
666 | /* actually, caller owns pld, so we don't register it with mop */ |
667 | |
668 | sprintf(name, "type")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "type"); |
669 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
670 | if (!lineLen) { |
671 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
672 | return 1; |
673 | } |
674 | if (strcmp(line, DEMARK_STR"====== " TYPE_STR"type:")) { |
675 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" not expected \"%s\"", |
676 | me, name, line, DEMARK_STR"====== " TYPE_STR"type:"); |
677 | return 1; |
678 | } |
679 | for (primIdx=0; primIdx<primNum; primIdx++) { |
680 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
681 | if (!lineLen) { |
682 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line %u/%u", |
683 | me, name, primIdx, primNum); |
684 | return 1; |
685 | } |
686 | pld->type[primIdx] = airEnumVal(limnPrimitive, line); |
687 | if (!(pld->type[primIdx])) { |
688 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse \"%s\" %s line %u/%u", |
689 | me, line, name, primIdx, primNum); |
690 | return 1; |
691 | } |
692 | } |
693 | |
694 | sprintf(name, "icnt")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "icnt"); |
695 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
696 | if (!lineLen) { |
697 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
698 | return 1; |
699 | } |
700 | if (strcmp(line, DEMARK_STR"====== " ICNT_STR"icnt:")) { |
701 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" not expected \"%s\"", |
702 | me, name, line, DEMARK_STR"====== " ICNT_STR"icnt:"); |
703 | return 1; |
704 | } |
705 | for (primIdx=0; primIdx<primNum; primIdx++) { |
706 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
707 | if (!lineLen) { |
708 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line %u/%u", |
709 | me, name, primIdx, primNum); |
710 | return 1; |
711 | } |
712 | if (1 != sscanf(line, "%u", &(pld->icnt[primIdx]))) { |
713 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse \"%s\" %s line %u/%u", |
714 | me, line, name, primIdx, primNum); |
715 | return 1; |
716 | } |
717 | } |
718 | |
719 | sprintf(name, "indx")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "indx"); |
720 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
721 | if (!lineLen) { |
722 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
723 | return 1; |
724 | } |
725 | if (strcmp(line, DEMARK_STR"====== " INDX_STR"indx:")) { |
726 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" not expected \"%s\"", |
727 | me, name, line, DEMARK_STR"====== " ICNT_STR"icnt:"); |
728 | return 1; |
729 | } |
730 | |
731 | /* NOW its finally time to create the mop */ |
732 | mop = airMopNew(); |
733 | nrrd = nrrdNew(); |
734 | airMopAdd(mop, nrrd, (airMopper)nrrdNuke, airMopAlways); |
735 | /* HEY HEY HEY HOLY CRAP! |
736 | ** why the hell isn't the verbosity level a field in NrrdIoState ?!?! |
737 | ** THIS NEES TO BE FIXED (in nrrd) ASAP! |
738 | */ |
739 | hackhack = nrrdStateVerboseIO; |
740 | nrrdStateVerboseIO = 0; |
741 | if (nrrdRead(nrrd, file, NULL((void*)0))) { |
742 | biffMovef(LIMNlimnBiffKey, NRRDnrrdBiffKey, "%s: trouble reading %s data", me, name); |
743 | airMopError(mop); return 1; |
744 | } |
745 | if (!(nrrdTypeUInt == nrrd->type |
746 | && 1 == nrrd->dim |
747 | && indxNum == nrrd->axis[0].size)) { |
748 | biffAddf(LIMNlimnBiffKey, "%s: didn't get 1-D %s-type %u-sample array " |
749 | "(got %u-D %s-type %u-by-? array)", me, |
750 | airEnumStr(nrrdType, nrrdTypeUInt), |
751 | AIR_CAST(unsigned int, indxNum)((unsigned int)(indxNum)), |
752 | nrrd->dim, |
753 | airEnumStr(nrrdType, nrrd->type), |
754 | AIR_CAST(unsigned int, nrrd->axis[0].size)((unsigned int)(nrrd->axis[0].size))); |
755 | airMopError(mop); return 1; |
756 | } |
757 | /* now copy the data */ |
758 | memcpy(pld->indx, nrrd->data, nrrdElementSize(nrrd)*nrrdElementNumber(nrrd))__builtin___memcpy_chk (pld->indx, nrrd->data, nrrdElementSize (nrrd)*nrrdElementNumber(nrrd), __builtin_object_size (pld-> indx, 0)); |
759 | do { |
760 | tmpChar = getc(file); |
761 | if (EOF(-1) == tmpChar) { |
762 | biffAddf(LIMNlimnBiffKey, "%s: hit EOF seeking to begin next line", me); |
763 | airMopError(mop); return 1; |
764 | } |
765 | } while (DEMARK_CHAR'=' != tmpChar); |
766 | ungetc(tmpChar, file); |
767 | |
768 | sprintf(name, "xyzw")__builtin___sprintf_chk (name, 0, __builtin_object_size (name , 2 > 1 ? 1 : 0), "xyzw"); |
769 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
770 | if (!lineLen) { |
771 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line", me, name); |
772 | return 1; |
773 | } |
774 | if (strcmp(line, DEMARK_STR"====== " XYZW_STR"xyzw:")) { |
775 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" not expected \"%s\"", |
776 | me, name, line, DEMARK_STR"====== " XYZW_STR"xyzw:"); |
777 | return 1; |
778 | } |
779 | if (nrrdRead(nrrd, file, NULL((void*)0))) { |
780 | biffMovef(LIMNlimnBiffKey, NRRDnrrdBiffKey, "%s: trouble reading %s data", me, name); |
781 | airMopError(mop); return 1; |
782 | } |
783 | if (!(nrrdTypeFloat == nrrd->type |
784 | && 2 == nrrd->dim |
785 | && 4 == nrrd->axis[0].size |
786 | && vertNum == nrrd->axis[1].size)) { |
787 | biffAddf(LIMNlimnBiffKey, "%s: didn't get 2-D %s-type 4-by-%u array " |
788 | "(got %u-D %s-type %u-by-%u array)", me, |
789 | airEnumStr(nrrdType, nrrdTypeFloat), |
790 | AIR_CAST(unsigned int, vertNum)((unsigned int)(vertNum)), |
791 | nrrd->dim, |
792 | airEnumStr(nrrdType, nrrd->type), |
793 | AIR_CAST(unsigned int, nrrd->axis[0].size)((unsigned int)(nrrd->axis[0].size)), |
794 | AIR_CAST(unsigned int, nrrd->axis[1].size)((unsigned int)(nrrd->axis[1].size))); |
795 | airMopError(mop); return 1; |
796 | } |
797 | /* now copy the data */ |
798 | memcpy(pld->xyzw, nrrd->data, nrrdElementSize(nrrd)*nrrdElementNumber(nrrd))__builtin___memcpy_chk (pld->xyzw, nrrd->data, nrrdElementSize (nrrd)*nrrdElementNumber(nrrd), __builtin_object_size (pld-> xyzw, 0)); |
799 | |
800 | if (infoNum) { |
801 | int wantType; |
802 | unsigned int wantSize; |
803 | void *data; |
804 | for (infoIdx=0; infoIdx<infoNum; infoIdx++) { |
805 | do { |
806 | tmpChar = getc(file); |
807 | if (EOF(-1) == tmpChar) { |
808 | biffAddf(LIMNlimnBiffKey, "%s: hit EOF seeking to begin next line", me); |
809 | airMopError(mop); return 1; |
810 | } |
811 | } while (DEMARK_CHAR'=' != tmpChar); |
812 | ungetc(tmpChar, file); |
813 | lineLen = airOneLine(file, line, AIR_STRLEN_MED(256+1)); |
814 | if (!lineLen) { |
815 | biffAddf(LIMNlimnBiffKey, "%s: didn't get %s line %u/%u", me, |
816 | INFO_STR"info:", infoIdx, infoNum); |
817 | return 1; |
818 | } |
819 | if (strncmp(line, DEMARK_STR"====== " INFO_STR"info:", strlen(DEMARK_STR"====== " INFO_STR"info:"))) { |
820 | biffAddf(LIMNlimnBiffKey, "%s: %s line \"%s\" not expected \"%s\"", |
821 | me, INFO_STR"info:", line, DEMARK_STR"====== " INFO_STR"info:"); |
822 | return 1; |
823 | } |
824 | tmp = line + strlen(DEMARK_STR"====== " INFO_STR"info:") + strlen(" "); |
825 | info = airEnumVal(limnPolyDataInfo, tmp); |
826 | if (!info) { |
827 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse \"%s\" as %s in %s line \"%s\"", |
828 | me, tmp, limnPolyDataInfo->name, INFO_STR"info:", line); |
829 | return 1; |
830 | } |
831 | if (nrrdRead(nrrd, file, NULL((void*)0))) { |
832 | biffMovef(LIMNlimnBiffKey, NRRDnrrdBiffKey, "%s: trouble reading %s %s data", |
833 | me, INFO_STR"info:", tmp); |
834 | airMopError(mop); return 1; |
835 | } |
836 | switch (info) { |
837 | case limnPolyDataInfoRGBA: |
838 | wantType = nrrdTypeUChar; |
839 | wantSize = 4; |
840 | data = pld->rgba; |
841 | break; |
842 | case limnPolyDataInfoNorm: |
843 | wantType = nrrdTypeFloat; |
844 | wantSize = 3; |
845 | data = pld->norm; |
846 | break; |
847 | case limnPolyDataInfoTex2: |
848 | wantType = nrrdTypeFloat; |
849 | wantSize = 2; |
850 | data = pld->tex2; |
851 | break; |
852 | case limnPolyDataInfoTang: |
853 | wantType = nrrdTypeFloat; |
854 | wantSize = 3; |
855 | data = pld->tang; |
856 | break; |
857 | default: |
858 | biffAddf(LIMNlimnBiffKey, "%s: info %d (%s) not handled", me, info, |
859 | airEnumStr(limnPolyDataInfo, info)); |
860 | airMopError(mop); return 1; |
861 | break; |
862 | } |
863 | if (!(wantType == nrrd->type |
864 | && 2 == nrrd->dim |
865 | && wantSize == nrrd->axis[0].size |
866 | && vertNum == nrrd->axis[1].size)) { |
867 | biffAddf(LIMNlimnBiffKey, "%s: didn't get 2-D %s-type %u-by-%u array " |
868 | "(got %u-D %s-type %u-by-%u-by-? array)", me, |
869 | airEnumStr(nrrdType, wantType), |
870 | wantSize, AIR_CAST(unsigned int, vertNum)((unsigned int)(vertNum)), |
871 | nrrd->dim, |
872 | airEnumStr(nrrdType, nrrd->type), |
873 | AIR_CAST(unsigned int, nrrd->axis[0].size)((unsigned int)(nrrd->axis[0].size)), |
874 | AIR_CAST(unsigned int, nrrd->axis[1].size)((unsigned int)(nrrd->axis[1].size))); |
875 | airMopError(mop); return 1; |
876 | } |
877 | /* now copy the data */ |
878 | memcpy(data, nrrd->data, nrrdElementSize(nrrd)*nrrdElementNumber(nrrd))__builtin___memcpy_chk (data, nrrd->data, nrrdElementSize( nrrd)*nrrdElementNumber(nrrd), __builtin_object_size (data, 0 )); |
879 | } |
880 | } |
881 | |
882 | airMopOkay(mop); |
883 | nrrdStateVerboseIO = hackhack; |
884 | return 0; |
885 | } |
886 | |
887 | int |
888 | _limnHestPolyDataLMPDParse(void *ptr, char *str, char err[AIR_STRLEN_HUGE(1024+1)]) { |
889 | static const char me[] = "_limnHestPolyDataLMPDParse"; |
890 | char *nerr; |
891 | limnPolyData **lpldP; |
892 | airArray *mop; |
893 | FILE *file; |
894 | |
895 | if (!(ptr && str)) { |
896 | sprintf(err, "%s: got NULL pointer", me)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s: got NULL pointer", me); |
897 | return 1; |
898 | } |
899 | |
900 | lpldP = (limnPolyData **)ptr; |
901 | if (!strlen(str)) { |
902 | /* got empty filename; user didn't really want data, that's okay*/ |
903 | *lpldP = NULL((void*)0); |
904 | return 0; |
905 | } |
906 | |
907 | mop = airMopNew(); |
908 | if (!( file = airFopen(str, stdin__stdinp, "rb") )) { |
909 | sprintf(err, "%s: couldn't fopen(\"%s\",\"rb\"): %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s: couldn't fopen(\"%s\",\"rb\"): %s", me , str, strerror((*__error()))) |
910 | me, str, strerror(errno))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s: couldn't fopen(\"%s\",\"rb\"): %s", me , str, strerror((*__error()))); |
911 | biffAdd(LIMNlimnBiffKey, err); airMopError(mop); return 1; |
912 | } |
913 | airMopAdd(mop, file, (airMopper)airFclose, airMopAlways); |
914 | *lpldP = limnPolyDataNew(); |
915 | airMopAdd(mop, *lpldP, (airMopper)limnPolyDataNix, airMopOnError); |
916 | if (limnPolyDataReadLMPD(*lpldP, file)) { |
917 | airMopAdd(mop, nerr = biffGetDone(LIMNlimnBiffKey), airFree, airMopOnError); |
918 | airStrcpy(err, AIR_STRLEN_HUGE(1024+1), nerr); |
919 | airMopError(mop); |
920 | return 1; |
921 | } |
922 | airMopOkay(mop); |
923 | return 0; |
924 | } |
925 | |
926 | hestCB |
927 | _limnHestPolyDataLMPD = { |
928 | sizeof(limnPolyData *), |
929 | "polydata", |
930 | _limnHestPolyDataLMPDParse, |
931 | (airMopper)limnPolyDataNix |
932 | }; |
933 | |
934 | hestCB * |
935 | limnHestPolyDataLMPD = &_limnHestPolyDataLMPD; |
936 | |
937 | int |
938 | _limnHestPolyDataOFFParse(void *ptr, char *str, char err[AIR_STRLEN_HUGE(1024+1)]) { |
939 | static const char me[] = "_limnHestPolyDataOFFParse"; |
940 | char *nerr; |
941 | limnPolyData **lpldP; |
942 | airArray *mop; |
943 | FILE *file; |
944 | |
945 | if (!(ptr && str)) { |
946 | sprintf(err, "%s: got NULL pointer", me)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s: got NULL pointer", me); |
947 | return 1; |
948 | } |
949 | |
950 | lpldP = (limnPolyData **)ptr; |
951 | if (!strlen(str)) { |
952 | /* got empty filename; user didn't really want data, that's okay*/ |
953 | *lpldP = NULL((void*)0); |
954 | return 0; |
955 | } |
956 | |
957 | mop = airMopNew(); |
958 | if (!( file = airFopen(str, stdin__stdinp, "rb") )) { |
959 | sprintf(err, "%s: couldn't fopen(\"%s\",\"rb\"): %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s: couldn't fopen(\"%s\",\"rb\"): %s", me , str, strerror((*__error()))) |
960 | me, str, strerror(errno))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s: couldn't fopen(\"%s\",\"rb\"): %s", me , str, strerror((*__error()))); |
961 | airMopError(mop); return 1; |
962 | } |
963 | airMopAdd(mop, file, (airMopper)airFclose, airMopAlways); |
964 | *lpldP = limnPolyDataNew(); |
965 | airMopAdd(mop, *lpldP, (airMopper)limnPolyDataNix, airMopOnError); |
966 | if (limnPolyDataReadOFF(*lpldP, file)) { |
967 | airMopAdd(mop, nerr = biffGetDone(LIMNlimnBiffKey), airFree, airMopOnError); |
968 | strncpy(err, nerr, AIR_STRLEN_HUGE-1)__builtin___strncpy_chk (err, nerr, (1024+1)-1, __builtin_object_size (err, 2 > 1 ? 1 : 0)); |
969 | airMopError(mop); |
970 | return 1; |
971 | } |
972 | airMopOkay(mop); |
973 | return 0; |
974 | } |
975 | |
976 | hestCB |
977 | _limnHestPolyDataOFF = { |
978 | sizeof(limnPolyData *), |
979 | "polydata", |
980 | _limnHestPolyDataOFFParse, |
981 | (airMopper)limnPolyDataNix |
982 | }; |
983 | |
984 | hestCB * |
985 | limnHestPolyDataOFF = &_limnHestPolyDataOFF; |
986 | |
987 | int |
988 | limnPolyDataWriteVTK(FILE *file, const limnPolyData *pld) { |
989 | static const char me[]="limnPolyDataWriteVTK"; |
990 | unsigned int pntIdx, prmIdx, *indx, idxNum; |
991 | int linesOnly; |
992 | |
993 | if (!(file && pld)) { |
994 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
995 | return 1; |
996 | } |
997 | fprintf(file, "# vtk DataFile Version 2.0\n"); |
998 | fprintf(file, "limnPolyData\n"); |
999 | fprintf(file, "ASCII\n"); |
1000 | fprintf(file, "DATASET POLYDATA\n"); |
1001 | fprintf(file, "POINTS %u float\n", pld->xyzwNum); |
1002 | for (pntIdx=0; pntIdx<pld->xyzwNum; pntIdx++) { |
1003 | float xyz[3]; |
1004 | ELL_34V_HOMOG(xyz, pld->xyzw + 4*pntIdx)((xyz)[0] = (pld->xyzw + 4*pntIdx)[0]/(pld->xyzw + 4*pntIdx )[3], (xyz)[1] = (pld->xyzw + 4*pntIdx)[1]/(pld->xyzw + 4*pntIdx)[3], (xyz)[2] = (pld->xyzw + 4*pntIdx)[2]/(pld-> xyzw + 4*pntIdx)[3]); |
1005 | fprintf(file, "%f %f %f\n", xyz[0], xyz[1], xyz[2]); |
1006 | } |
1007 | |
1008 | fprintf(file, "\n"); |
1009 | |
1010 | /* first check if its only lines... */ |
1011 | linesOnly = AIR_TRUE1; |
1012 | for (prmIdx=0; prmIdx<pld->primNum; prmIdx++) { |
1013 | linesOnly &= (limnPrimitiveLineStrip == pld->type[prmIdx]); |
1014 | } |
1015 | if (linesOnly) { |
1016 | fprintf(file, "LINES %u %u\n", pld->primNum, pld->primNum + pld->indxNum); |
1017 | indx = pld->indx; |
1018 | for (prmIdx=0; prmIdx<pld->primNum; prmIdx++) { |
1019 | unsigned int ii; |
1020 | idxNum = pld->icnt[prmIdx]; |
1021 | fprintf(file, "%u", idxNum); |
1022 | for (ii=0; ii<idxNum; ii++) { |
1023 | fprintf(file, " %u", indx[ii]); |
1024 | } |
1025 | fprintf(file, "\n"); |
1026 | indx += idxNum; |
1027 | } |
1028 | } else { |
1029 | indx = pld->indx; |
1030 | for (prmIdx=0; prmIdx<pld->primNum; prmIdx++) { |
1031 | unsigned int triNum, triIdx; |
1032 | idxNum = pld->icnt[prmIdx]; |
1033 | switch (pld->type[prmIdx]) { |
1034 | case limnPrimitiveTriangleFan: |
1035 | biffAddf(LIMNlimnBiffKey, "%s: %s prims (prim[%u]) not supported in VTK?", |
1036 | me, airEnumStr(limnPrimitive, pld->type[prmIdx]), prmIdx); |
1037 | return 1; |
1038 | break; |
1039 | case limnPrimitiveQuads: |
1040 | case limnPrimitiveTriangleStrip: |
1041 | biffAddf(LIMNlimnBiffKey, "%s: sorry, saving %s prims (prim[%u]) not implemented", |
1042 | me, airEnumStr(limnPrimitive, pld->type[prmIdx]), prmIdx); |
1043 | return 1; |
1044 | break; |
1045 | case limnPrimitiveLineStrip: |
1046 | biffAddf(LIMNlimnBiffKey, "%s: confusion", me); |
1047 | return 1; |
1048 | break; |
1049 | case limnPrimitiveTriangles: |
1050 | triNum = idxNum/3; |
1051 | fprintf(file, "POLYGONS %u %u\n", triNum, triNum + idxNum); |
1052 | for (triIdx=0; triIdx<triNum; triIdx++) { |
1053 | fprintf(file, "3 %u %u %u\n", |
1054 | indx[0 + 3*triIdx], indx[1 + 3*triIdx], indx[2 + 3*triIdx]); |
1055 | } |
1056 | break; |
1057 | default: |
1058 | biffAddf(LIMNlimnBiffKey, "%s: sorry, type %s (prim %u) not handled here", me, |
1059 | airEnumStr(limnPrimitive, pld->type[prmIdx]), prmIdx); |
1060 | return 1; |
1061 | break; |
1062 | } |
1063 | fprintf(file, "\n"); |
1064 | indx += idxNum; |
1065 | } |
1066 | } |
1067 | |
1068 | return 0; |
1069 | } |
1070 | |
1071 | /* |
1072 | ******** limnPolyDataReadOFF |
1073 | ** |
1074 | ** HEY: this has to be re-written with different allocation strategies |
1075 | ** if it is to support anything other than a single limnPrimitiveTriangles |
1076 | */ |
1077 | int |
1078 | limnPolyDataReadOFF(limnPolyData *pld, FILE *file) { |
1079 | static const char me[]="limnPolyDataReadOFF"; |
1080 | char line[AIR_STRLEN_LARGE(512+1)]; /* HEY: bad Gordon */ |
1081 | unsigned int num[3], xyzwNum, xyzwGot, |
1082 | faceNum, faceGot, lineCount, got, lret; |
1083 | |
1084 | if (!( pld && file )) { |
1085 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
1086 | return 1; |
1087 | } |
1088 | |
1089 | /* HEY: this just snarfs lines until it parses 3 uints, |
1090 | disregarding whether the "OFF" magic was actually there! */ |
1091 | got = 0; |
Value stored to 'got' is never read | |
1092 | lineCount = 0; |
1093 | do { |
1094 | if (!airOneLine(file, line, AIR_STRLEN_LARGE(512+1))) { |
1095 | biffAddf(LIMNlimnBiffKey, "%s: hit EOF before getting #vert #face #edge line", me); |
1096 | return 1; |
1097 | } |
1098 | lineCount++; |
1099 | got = airParseStrUI(num, line, AIR_WHITESPACE" \t\n\r\v\f", 3); |
1100 | } while (3 != got); |
1101 | xyzwNum = num[0]; |
1102 | faceNum = num[1]; |
1103 | |
1104 | /* allocate */ |
1105 | if (limnPolyDataAlloc(pld, 0 /* no extra info */, |
1106 | xyzwNum, 3*faceNum, 1)) { |
1107 | biffAddf(LIMNlimnBiffKey, "%s: couldn't allocate", me); |
1108 | return 1; |
1109 | } |
1110 | |
1111 | /* read all vertex information */ |
1112 | xyzwGot = 0; |
1113 | while (xyzwGot < xyzwNum) { |
1114 | float *xyzw; |
1115 | do { |
1116 | lret = airOneLine(file, line, AIR_STRLEN_LARGE(512+1)); |
1117 | lineCount++; |
1118 | } while (1 == lret); |
1119 | if (!lret) { |
1120 | biffAddf(LIMNlimnBiffKey, |
1121 | "%s: (near line %d) hit EOF trying to read vert %d (of %d)", |
1122 | me, lineCount, xyzwGot, xyzwNum); |
1123 | return 1; |
1124 | } |
1125 | xyzw = pld->xyzw + 4*xyzwGot; |
1126 | if (3 != airParseStrF(xyzw, line, AIR_WHITESPACE" \t\n\r\v\f", 3)) { |
1127 | biffAddf(LIMNlimnBiffKey, "%s: couldn't parse 3 floats from \"%s\" " |
1128 | "for vert %d (of %d)", |
1129 | me, line, xyzwGot, xyzwNum); |
1130 | return 1; |
1131 | } |
1132 | xyzw[3] = 1.0; |
1133 | xyzwGot++; |
1134 | } |
1135 | |
1136 | /* read face information */ |
1137 | faceGot = 0; |
1138 | while (faceGot < faceNum) { |
1139 | unsigned int *indx, indxSingle[4], indxNum; |
1140 | do { |
1141 | lret = airOneLine(file, line, AIR_STRLEN_LARGE(512+1)); |
1142 | lineCount++; |
1143 | } while (1 == lret); |
1144 | if (!lret) { |
1145 | biffAddf(LIMNlimnBiffKey, |
1146 | "%s: (near line %d) hit EOF trying to read face %d (of %d)", |
1147 | me, lineCount, faceGot, faceNum); |
1148 | return 1; |
1149 | } |
1150 | if ('#' == line[0]) { |
1151 | /* its some kind of comment, either LIMN BEGIN PART or otherwise */ |
1152 | continue; |
1153 | } |
1154 | if (1 != sscanf(line, "%u", &indxNum)) { |
1155 | biffAddf(LIMNlimnBiffKey, "%s: (near line %d) can't get first uint " |
1156 | "(#verts) from \"%s\" for face %d (of %d)", |
1157 | me, lineCount, line, faceGot, faceNum); |
1158 | return 1; |
1159 | } |
1160 | if (3 != indxNum) { |
1161 | biffAddf(LIMNlimnBiffKey, "%s: sorry, can only handle triangles (not %u verts)", |
1162 | me, indxNum); |
1163 | return 1; |
1164 | } |
1165 | if (indxNum+1 != airParseStrUI(indxSingle, line, |
1166 | AIR_WHITESPACE" \t\n\r\v\f", indxNum+1)) { |
1167 | biffAddf(LIMNlimnBiffKey, "%s: (near line %d) couldn't parse %d uints from \"%s\" " |
1168 | "for face %d (of %d)", |
1169 | me, lineCount, indxNum+1, line, faceGot, faceNum); |
1170 | return 1; |
1171 | } |
1172 | indx = pld->indx + 3*faceGot; |
1173 | ELL_3V_SET(indx, indxSingle[1], indxSingle[2], indxSingle[3])((indx)[0] = (indxSingle[1]), (indx)[1] = (indxSingle[2]), (indx )[2] = (indxSingle[3])); |
1174 | /* for now ignoring the color information */ |
1175 | faceGot++; |
1176 | } |
1177 | |
1178 | /* set remaining info */ |
1179 | pld->type[0] = limnPrimitiveTriangles; |
1180 | pld->icnt[0] = 3*faceNum; |
1181 | |
1182 | return 0; |
1183 | } |
1184 | |
1185 | int |
1186 | limnPolyDataSave(const char *_fname, const limnPolyData *lpld) { |
1187 | static const char me[]="limnPolyDataSave"; |
1188 | char *fname; |
1189 | FILE *file; |
1190 | airArray *mop; |
1191 | int ret; |
1192 | |
1193 | if (!(_fname && lpld)) { |
1194 | biffAddf(LIMNlimnBiffKey, "%s: got NULL pointer", me); |
1195 | return 1; |
1196 | } |
1197 | mop = airMopNew(); |
1198 | |
1199 | if (!( file = airFopen(_fname, stdout__stdoutp, "wb") )) { |
1200 | biffAddf(LIMNlimnBiffKey, "%s: couldn't fopen(\"%s\",\"wb\"): %s", |
1201 | me, _fname, strerror(errno(*__error()))); |
1202 | airMopError(mop); return 1; |
1203 | } |
1204 | airMopAdd(mop, file, (airMopper)airFclose, airMopAlways); |
1205 | |
1206 | fname = airToLower(airStrdup(_fname)); |
1207 | airMopAdd(mop, fname, (airMopper)airFree, airMopAlways); |
1208 | if (airEndsWith(fname, ".vtk")) { |
1209 | ret = limnPolyDataWriteVTK(file, lpld); |
1210 | } else if (airEndsWith(fname, ".iv")) { |
1211 | ret = limnPolyDataWriteIV(file, lpld); |
1212 | } else { |
1213 | if (strcmp(_fname, "-") && !airEndsWith(fname, ".lmpd")) { |
1214 | fprintf(stderr__stderrp, "%s: WARNING: unknown or no suffix on \"%s\"; " |
1215 | "using LMPD format", me, _fname); |
1216 | } |
1217 | ret = limnPolyDataWriteLMPD(file, lpld); |
1218 | } |
1219 | if (ret) { |
1220 | biffAddf(LIMNlimnBiffKey, "%s: trouble", me); |
1221 | airMopError(mop); return 1; |
1222 | } |
1223 | |
1224 | airMopOkay(mop); |
1225 | return 0; |
1226 | } |