| File: | src/limn/io.c |
| Location: | line 364, column 7 |
| Description: | Value stored to 'lookIdx' 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; |
Value stored to 'lookIdx' is never read | |
| 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; |
| 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 | } |