File: | src/limn/obj.c |
Location: | line 242, column 17 |
Description: | Access to field 'lookIdx' results in a dereference of a null pointer (loaded from variable 'part') |
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 | /* restricted to this file now since here is the only place its needed */ | |||
28 | typedef union { | |||
29 | limnVertex **vert; | |||
30 | limnEdge **edge; | |||
31 | limnFace **face; | |||
32 | limnLook **look; | |||
33 | limnPart ***partp; | |||
34 | void **v; | |||
35 | } limnPtrPtrUnion; | |||
36 | ||||
37 | int | |||
38 | limnObjectLookAdd(limnObject *obj) { | |||
39 | int lookIdx; | |||
40 | limnLook *look; | |||
41 | ||||
42 | lookIdx = airArrayLenIncr(obj->lookArr, 1); | |||
43 | look = &(obj->look[lookIdx]); | |||
44 | ELL_4V_SET(look->rgba, 1, 1, 1, 1)((look->rgba)[0] = (1), (look->rgba)[1] = (1), (look-> rgba)[2] = (1), (look->rgba)[3] = (1)); | |||
45 | ELL_3V_SET(look->kads, 0.0, 1.0, 0.0)((look->kads)[0] = (0.0), (look->kads)[1] = (1.0), (look ->kads)[2] = (0.0)); | |||
46 | look->spow = 50; | |||
47 | return lookIdx; | |||
48 | } | |||
49 | ||||
50 | ||||
51 | limnObject * | |||
52 | limnObjectNew(int incr, int doEdges) { | |||
53 | limnObject *obj; | |||
54 | limnPtrPtrUnion lppu; | |||
55 | ||||
56 | obj = AIR_CALLOC(1, limnObject)(limnObject*)(calloc((1), sizeof(limnObject))); | |||
57 | obj->vert = NULL((void*)0); | |||
58 | obj->edge = NULL((void*)0); | |||
59 | obj->face = NULL((void*)0); | |||
60 | obj->faceSort = NULL((void*)0); | |||
61 | obj->part = NULL((void*)0); | |||
62 | obj->partPool = NULL((void*)0); | |||
63 | obj->look = NULL((void*)0); | |||
64 | ||||
65 | /* create all various airArrays */ | |||
66 | obj->vertArr = airArrayNew((lppu.vert = &(obj->vert), lppu.v), | |||
67 | &(obj->vertNum), | |||
68 | sizeof(limnVertex), incr); | |||
69 | obj->edgeArr = airArrayNew((lppu.edge = &(obj->edge), lppu.v), | |||
70 | &(obj->edgeNum), | |||
71 | sizeof(limnEdge), incr); | |||
72 | obj->faceArr = airArrayNew((lppu.face = &(obj->face), lppu.v), | |||
73 | &(obj->faceNum), | |||
74 | sizeof(limnFace), incr); | |||
75 | obj->partArr = airArrayNew((lppu.partp = &(obj->part), lppu.v), | |||
76 | &(obj->partNum), | |||
77 | sizeof(limnPart*), incr); | |||
78 | obj->partPoolArr = airArrayNew((lppu.partp = &(obj->partPool), lppu.v), | |||
79 | &(obj->partPoolNum), | |||
80 | sizeof(limnPart*), incr); | |||
81 | obj->lookArr = airArrayNew((lppu.look = &(obj->look), lppu.v), | |||
82 | &(obj->lookNum), | |||
83 | sizeof(limnLook), incr); | |||
84 | ||||
85 | /* create (default) look 0 */ | |||
86 | limnObjectLookAdd(obj); | |||
87 | ||||
88 | obj->vertSpace = limnSpaceUnknown; | |||
89 | obj->setVertexRGBAFromLook = AIR_FALSE0; | |||
90 | obj->doEdges = doEdges; | |||
91 | obj->incr = incr; | |||
92 | ||||
93 | return obj; | |||
94 | } | |||
95 | ||||
96 | limnPart * | |||
97 | _limnObjectPartNew(int incr) { | |||
98 | limnPart *part; | |||
99 | airPtrPtrUnion appu; | |||
100 | ||||
101 | part = AIR_CALLOC(1, limnPart)(limnPart*)(calloc((1), sizeof(limnPart))); | |||
102 | if (part) { | |||
103 | part->vertIdx = NULL((void*)0); | |||
104 | part->edgeIdx = NULL((void*)0); | |||
105 | part->faceIdx = NULL((void*)0); | |||
106 | part->vertIdxArr = airArrayNew((appu.ui = &(part->vertIdx), appu.v), | |||
107 | &(part->vertIdxNum), | |||
108 | sizeof(int), incr); | |||
109 | part->edgeIdxArr = airArrayNew((appu.ui = &(part->edgeIdx), appu.v), | |||
110 | &(part->edgeIdxNum), | |||
111 | sizeof(int), incr); | |||
112 | part->faceIdxArr = airArrayNew((appu.ui = &(part->faceIdx), appu.v), | |||
113 | &(part->faceIdxNum), | |||
114 | sizeof(int), incr); | |||
115 | } | |||
116 | return part; | |||
117 | } | |||
118 | ||||
119 | limnPart * | |||
120 | _limnObjectPartNix(limnPart *part) { | |||
121 | ||||
122 | if (part) { | |||
123 | airArrayNuke(part->vertIdxArr); | |||
124 | airArrayNuke(part->edgeIdxArr); | |||
125 | airArrayNuke(part->faceIdxArr); | |||
126 | airFree(part); | |||
127 | } | |||
128 | return NULL((void*)0); | |||
129 | } | |||
130 | ||||
131 | void | |||
132 | _limnObjectFaceEmpty(limnFace *face) { | |||
133 | ||||
134 | if (face) { | |||
135 | airFree(face->vertIdx); | |||
136 | airFree(face->edgeIdx); | |||
137 | } | |||
138 | return; | |||
139 | } | |||
140 | ||||
141 | limnObject * | |||
142 | limnObjectNix(limnObject *obj) { | |||
143 | unsigned int partIdx, faceIdx; | |||
144 | ||||
145 | if (obj) { | |||
146 | for (partIdx=0; partIdx<obj->partNum; partIdx++) { | |||
147 | _limnObjectPartNix(obj->part[partIdx]); | |||
148 | } | |||
149 | airArrayNuke(obj->partArr); | |||
150 | for (partIdx=0; partIdx<obj->partPoolNum; partIdx++) { | |||
151 | _limnObjectPartNix(obj->partPool[partIdx]); | |||
152 | } | |||
153 | airArrayNuke(obj->partPoolArr); | |||
154 | for (faceIdx=0; faceIdx<obj->faceNum; faceIdx++) { | |||
155 | _limnObjectFaceEmpty(obj->face + faceIdx); | |||
156 | } | |||
157 | airArrayNuke(obj->faceArr); | |||
158 | airArrayNuke(obj->vertArr); | |||
159 | airArrayNuke(obj->edgeArr); | |||
160 | airFree(obj->faceSort); | |||
161 | airArrayNuke(obj->lookArr); | |||
162 | airFree(obj); | |||
163 | } | |||
164 | return NULL((void*)0); | |||
165 | } | |||
166 | ||||
167 | void | |||
168 | limnObjectEmpty(limnObject *obj) { | |||
169 | unsigned int partIdx, faceIdx; | |||
170 | ||||
171 | for (partIdx=0; partIdx<obj->partNum; partIdx++) { | |||
172 | _limnObjectPartNix(obj->part[partIdx]); | |||
173 | } | |||
174 | airArrayLenSet(obj->partArr, 0); | |||
175 | for (partIdx=0; partIdx<obj->partPoolNum; partIdx++) { | |||
176 | _limnObjectPartNix(obj->partPool[partIdx]); | |||
177 | } | |||
178 | airArrayLenSet(obj->partPoolArr, 0); | |||
179 | for (faceIdx=0; faceIdx<obj->faceNum; faceIdx++) { | |||
180 | _limnObjectFaceEmpty(obj->face + faceIdx); | |||
181 | } | |||
182 | airArrayLenSet(obj->faceArr, 0); | |||
183 | airArrayLenSet(obj->vertArr, 0); | |||
184 | airArrayLenSet(obj->edgeArr, 0); | |||
185 | airFree(obj->faceSort); | |||
186 | /* leaves (default) look 0 */ | |||
187 | airArrayLenSet(obj->lookArr, 1); | |||
188 | ||||
189 | /* don't touch state flags */ | |||
190 | ||||
191 | return; | |||
192 | } | |||
193 | ||||
194 | /* | |||
195 | ******** limnObjectPreSet | |||
196 | ** | |||
197 | ** an attempt at pre-allocating everything that will be needed in a | |||
198 | ** limnObject, so that there will be no calloc/memcpy overhead associated | |||
199 | ** with growing any of the airArrays inside | |||
200 | */ | |||
201 | int | |||
202 | limnObjectPreSet(limnObject *obj, unsigned int partNum, | |||
203 | unsigned int lookNum, unsigned int vertPerPart, | |||
204 | unsigned int edgePerPart, unsigned int facePerPart) { | |||
205 | limnPart *part; | |||
206 | unsigned int partIdx; | |||
207 | ||||
208 | limnObjectEmpty(obj); | |||
209 | airArrayLenPreSet(obj->vertArr, partNum*vertPerPart); | |||
210 | airArrayLenPreSet(obj->edgeArr, partNum*edgePerPart); | |||
211 | airArrayLenPreSet(obj->faceArr, partNum*facePerPart); | |||
212 | airArrayLenPreSet(obj->lookArr, lookNum); | |||
213 | airArrayLenPreSet(obj->partArr, partNum); | |||
214 | ||||
215 | airArrayLenSet(obj->partPoolArr, partNum); | |||
216 | for (partIdx=0; partIdx<partNum; partIdx++) { | |||
217 | part = obj->partPool[partIdx] = _limnObjectPartNew(obj->incr); | |||
218 | airArrayLenPreSet(part->vertIdxArr, vertPerPart); | |||
219 | airArrayLenPreSet(part->edgeIdxArr, edgePerPart); | |||
220 | airArrayLenPreSet(part->faceIdxArr, facePerPart); | |||
221 | } | |||
222 | ||||
223 | return 0; | |||
224 | } | |||
225 | ||||
226 | int | |||
227 | limnObjectPartAdd(limnObject *obj) { | |||
228 | unsigned int partIdx; | |||
229 | limnPart *part; | |||
230 | ||||
231 | partIdx = airArrayLenIncr(obj->partArr, 1); | |||
232 | if (obj->partPoolNum > 0) { | |||
| ||||
233 | part = obj->part[partIdx] = obj->partPool[obj->partPoolNum - 1]; | |||
234 | airArrayLenIncr(obj->partPoolArr, -1); | |||
235 | airArrayLenSet(part->vertIdxArr, 0); | |||
236 | airArrayLenSet(part->edgeIdxArr, 0); | |||
237 | airArrayLenSet(part->faceIdxArr, 0); | |||
238 | } else { | |||
239 | /* there are no available parts in the pool */ | |||
240 | part = obj->part[partIdx] = _limnObjectPartNew(obj->incr); | |||
241 | } | |||
242 | part->lookIdx = 0; | |||
| ||||
243 | part->depth = AIR_NAN(airFloatQNaN.f); | |||
244 | return partIdx; | |||
245 | } | |||
246 | ||||
247 | int | |||
248 | limnObjectVertexNumPreSet(limnObject *obj, unsigned int partIdx, | |||
249 | unsigned int vertNum) { | |||
250 | limnPart *part; | |||
251 | ||||
252 | part = obj->part[partIdx]; | |||
253 | airArrayLenPreSet(obj->vertArr, vertNum); | |||
254 | airArrayLenPreSet(part->vertIdxArr, vertNum); | |||
255 | return 0; | |||
256 | } | |||
257 | ||||
258 | int | |||
259 | limnObjectVertexAdd(limnObject *obj, unsigned int partIdx, | |||
260 | float x, float y, float z) { | |||
261 | limnPart *part; | |||
262 | limnVertex *vert; | |||
263 | int vertIdx, vertIdxIdx; | |||
264 | ||||
265 | part = obj->part[partIdx]; | |||
266 | vertIdx = airArrayLenIncr(obj->vertArr, 1); | |||
267 | vert = obj->vert + vertIdx; | |||
268 | vertIdxIdx = airArrayLenIncr(part->vertIdxArr, 1); | |||
269 | part->vertIdx[vertIdxIdx] = vertIdx; | |||
270 | ELL_4V_SET(vert->world, x, y, z, 1)((vert->world)[0] = (x), (vert->world)[1] = (y), (vert-> world)[2] = (z), (vert->world)[3] = (1)); | |||
271 | ELL_4V_SET(vert->coord, AIR_NAN, AIR_NAN, AIR_NAN, AIR_NAN)((vert->coord)[0] = ((airFloatQNaN.f)), (vert->coord)[1 ] = ((airFloatQNaN.f)), (vert->coord)[2] = ((airFloatQNaN. f)), (vert->coord)[3] = ((airFloatQNaN.f))); | |||
272 | /* HEY: this is kind of lame: this information is set in | |||
273 | a rather sneaky way, and the setVertexRGBAFromLook is | |||
274 | pretty clearly a hack */ | |||
275 | if (obj->setVertexRGBAFromLook) { | |||
276 | ELL_4V_COPY(vert->rgba, obj->look[part->lookIdx].rgba)((vert->rgba)[0] = (obj->look[part->lookIdx].rgba)[0 ], (vert->rgba)[1] = (obj->look[part->lookIdx].rgba) [1], (vert->rgba)[2] = (obj->look[part->lookIdx].rgba )[2], (vert->rgba)[3] = (obj->look[part->lookIdx].rgba )[3]); | |||
277 | } else { | |||
278 | ELL_4V_SET(vert->rgba, 1, 1, 1, 1)((vert->rgba)[0] = (1), (vert->rgba)[1] = (1), (vert-> rgba)[2] = (1), (vert->rgba)[3] = (1)); | |||
279 | } | |||
280 | /* ELL_3V_SET(vert->view, AIR_NAN, AIR_NAN, AIR_NAN); */ | |||
281 | /* ELL_3V_SET(vert->screen, AIR_NAN, AIR_NAN, AIR_NAN); */ | |||
282 | ELL_3V_SET(vert->worldNormal, AIR_NAN, AIR_NAN, AIR_NAN)((vert->worldNormal)[0] = ((airFloatQNaN.f)), (vert->worldNormal )[1] = ((airFloatQNaN.f)), (vert->worldNormal)[2] = ((airFloatQNaN .f))); | |||
283 | ||||
284 | return vertIdx; | |||
285 | } | |||
286 | ||||
287 | int | |||
288 | limnObjectEdgeAdd(limnObject *obj, unsigned int partIdx, | |||
289 | unsigned int lookIdx, unsigned int faceIdx, | |||
290 | unsigned int vertIdx0, unsigned int vertIdx1) { | |||
291 | int tmp, edgeIdx=-42; | |||
292 | unsigned int edgeIdxIdx; | |||
293 | limnEdge *edge=NULL((void*)0); | |||
294 | limnPart *part; | |||
295 | ||||
296 | part = obj->part[partIdx]; | |||
297 | if (vertIdx0 > vertIdx1) { | |||
298 | ELL_SWAP2(vertIdx0, vertIdx1, tmp)((tmp)=(vertIdx0),(vertIdx0)=(vertIdx1),(vertIdx1)=(tmp)); | |||
299 | } | |||
300 | ||||
301 | /* do a linear search through this part's existing edges */ | |||
302 | for (edgeIdxIdx=0; edgeIdxIdx<part->edgeIdxNum; edgeIdxIdx++) { | |||
303 | edgeIdx = part->edgeIdx[edgeIdxIdx]; | |||
304 | edge = obj->edge + edgeIdx; | |||
305 | if (edge->vertIdx[0] == vertIdx0 | |||
306 | && edge->vertIdx[1] == vertIdx1) { | |||
307 | break; | |||
308 | } | |||
309 | } | |||
310 | if (edgeIdxIdx == part->edgeIdxNum) { | |||
311 | /* edge not found, add it */ | |||
312 | edgeIdx = airArrayLenIncr(obj->edgeArr, 1); | |||
313 | edge = obj->edge + edgeIdx; | |||
314 | edgeIdxIdx = airArrayLenIncr(part->edgeIdxArr, 1); | |||
315 | part->edgeIdx[edgeIdxIdx] = edgeIdx; | |||
316 | edge->vertIdx[0] = vertIdx0; | |||
317 | edge->vertIdx[1] = vertIdx1; | |||
318 | edge->faceIdx[0] = faceIdx; | |||
319 | edge->faceIdx[1] = -1; | |||
320 | edge->lookIdx = lookIdx; | |||
321 | edge->partIdx = partIdx; | |||
322 | edge->type = limnEdgeTypeUnknown; | |||
323 | edge->once = AIR_FALSE0; | |||
324 | } else { | |||
325 | /* edge already exists; "edge", "edgeIdx", and "edgeIdxIdx" are all set */ | |||
326 | edge->faceIdx[1] = faceIdx; | |||
327 | } | |||
328 | ||||
329 | return edgeIdx; | |||
330 | } | |||
331 | ||||
332 | int | |||
333 | limnObjectFaceNumPreSet(limnObject *obj, unsigned int partIdx, | |||
334 | unsigned int faceNum) { | |||
335 | limnPart *part; | |||
336 | ||||
337 | part = obj->part[partIdx]; | |||
338 | airArrayLenPreSet(obj->faceArr, faceNum); | |||
339 | airArrayLenPreSet(part->faceIdxArr, faceNum); | |||
340 | return 0; | |||
341 | } | |||
342 | ||||
343 | int | |||
344 | limnObjectFaceAdd(limnObject *obj, unsigned int partIdx, | |||
345 | unsigned int lookIdx, unsigned int sideNum, | |||
346 | unsigned int *vertIdx) { | |||
347 | limnFace *face; | |||
348 | limnPart *part; | |||
349 | unsigned int faceIdx, faceIdxIdx, sideIdx; | |||
350 | ||||
351 | part = obj->part[partIdx]; | |||
352 | faceIdx = airArrayLenIncr(obj->faceArr, 1); | |||
353 | face = obj->face + faceIdx; | |||
354 | faceIdxIdx = airArrayLenIncr(part->faceIdxArr, 1); | |||
355 | part->faceIdx[faceIdxIdx] = faceIdx; | |||
356 | ||||
357 | face->vertIdx = AIR_CALLOC(sideNum, unsigned int)(unsigned int*)(calloc((sideNum), sizeof(unsigned int))); | |||
358 | face->sideNum = sideNum; | |||
359 | if (obj->doEdges) { | |||
360 | face->edgeIdx = AIR_CALLOC(sideNum, unsigned int)(unsigned int*)(calloc((sideNum), sizeof(unsigned int))); | |||
361 | } | |||
362 | for (sideIdx=0; sideIdx<sideNum; sideIdx++) { | |||
363 | face->vertIdx[sideIdx] = vertIdx[sideIdx]; | |||
364 | if (obj->doEdges) { | |||
365 | face->edgeIdx[sideIdx] = | |||
366 | limnObjectEdgeAdd(obj, partIdx, 0, faceIdx, | |||
367 | vertIdx[sideIdx], | |||
368 | vertIdx[AIR_MOD((int)sideIdx+1, (int)sideNum)(((int)sideIdx+1)%((int)sideNum) >= 0 ? ((int)sideIdx+1)%( (int)sideNum) : (int)sideNum + ((int)sideIdx+1)%((int)sideNum ))]); | |||
369 | } | |||
370 | } | |||
371 | ELL_3V_SET(face->worldNormal, AIR_NAN, AIR_NAN, AIR_NAN)((face->worldNormal)[0] = ((airFloatQNaN.f)), (face->worldNormal )[1] = ((airFloatQNaN.f)), (face->worldNormal)[2] = ((airFloatQNaN .f))); | |||
372 | ELL_3V_SET(face->screenNormal, AIR_NAN, AIR_NAN, AIR_NAN)((face->screenNormal)[0] = ((airFloatQNaN.f)), (face->screenNormal )[1] = ((airFloatQNaN.f)), (face->screenNormal)[2] = ((airFloatQNaN .f))); | |||
373 | /* HEY: its potentially confusing that obj->setVertexRGBAFromLook only | |||
374 | has an effect with whole parts, and not individual faces */ | |||
375 | face->lookIdx = lookIdx; | |||
376 | face->partIdx = partIdx; | |||
377 | face->visible = AIR_FALSE0; | |||
378 | face->depth = AIR_NAN(airFloatQNaN.f); | |||
379 | ||||
380 | return faceIdx; | |||
381 | } | |||
382 |