Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 422 lines (345 sloc) 13.174 kb
f4b079a @schwehr Added ntoh functions
authored
1 // $Revision$ $Author$ $Date$
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
2
3 /// \brief Convert an xyz point set into a volume density
4 /// Uses a voxel representation
5
6
7 /***************************************************************************
8 * INCLUDES
9 ***************************************************************************/
10
11 #include <cassert>
12
13 #include <cstdlib>
14 #include <cstdio>
15
16 // C++ includes
17 #include <iostream>
18 #include <iomanip>
19 #include <fstream>
20
21 #include <string> // Good STL data types.
22 #include <vector>
23
24 // Local includes
175cf98 @schwehr removed volheader stuff
authored
25 #include "VolHeader.H"
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
26 #include "Density.H"
27
28 using namespace std;
29
30 /***************************************************************************
31 * LOCAL MACROS and DEFINES
32 ***************************************************************************/
33
34 #ifdef __GNUC__
35 #define UNUSED __attribute((__unused__))
36 #else
37 /*! \def UNUSED
38 \brief GNU CC attribute to denote unused paramters in function calls.
39 The attribute remove compiler warning for unused arguments and variable. Only works
40 for GNU compilers such as gcc and g++.
41 */
42 #define UNUSED
43 #endif
44
45 #ifdef REGRESSION_TEST
46 #define FAILED_HERE cout << __FILE__ << ":" << __LINE__ << " test failed" << endl
47 #else
48 /*! \def FAILED_HERE
49 \brief Used FAILED_HERE; to emit a string that looks like a compiler warning
50 Use this to allow emacs to jump to this source line with C-x `
51 */
52 #define FAILED_HERE // Empty
53 #endif
54
55 /***************************************************************************
56 * GLOBALS
57 ***************************************************************************/
58
59 /// Let the debugger find out which version is being used.
60 static const UNUSED char* RCSid ="@(#) $Id$";
61
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
62 //####################################################################
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
63 // DENSITY METHODS
64 //####################################################################
65
66
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
67 Density::Density() {
68 cout << "FIX: make sure that later, things get setup ok. Density()" << endl;
69 }
70
71 void
72 Density::resize(const size_t _width, const size_t _height, const size_t _depth,
73 const float minX, const float maxX,
74 const float minY, const float maxY,
75 const float minZ, const float maxZ)
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
76 {
77 assert (_width < 10000); // Would be bad to be much larger
78 assert (_height < 10000); // Would be bad to be much larger
79 assert (_depth < 10000); // Would be bad to be much larger
80 assert (minX < maxX);
81 assert (minY < maxY);
82 assert (minZ < maxZ);
83 width = _width;
84 height = _height;
85 depth = _depth;
86 dx = (maxX-minX)/width;
87 dy = (maxY-minY)/height;
88 dz = (maxZ-minZ)/depth;
89 xR[0]=minX;xR[1]=maxX;
90 yR[0]=minY;yR[1]=maxY;
91 zR[0]=minZ;zR[1]=maxZ;
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
92 counts.resize(width*height*depth,0); // set all to zero
93 //for (size_t i=0;i<counts.size();i++) counts[i]=0;
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
94 totalPointsInside=0;
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
95 return;
96 } // resize()
97
98 Density::Density(const size_t _width, const size_t _height, const size_t _depth,
99 const float minX, const float maxX,
100 const float minY, const float maxY,
101 const float minZ, const float maxZ)
102 {
103 resize(_width, _height, _depth, minX,maxX, minY,maxY, minZ,maxZ);
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
104 }
105
106 bool
107 Density::addPoint(const float x, const float y, const float z) {
108 const size_t cellNum=getCell(x,y,z);
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
109 if (cellNum==badValue()) {
110 #ifdef REGRESSION_TEST
111 cout << " Point outside volume: " << x << " " << y << " " << z << endl;
112 #endif
113 return (false); // Outside!!
114 }
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
115 assert (cellNum<counts.size());
116 counts[cellNum]++;
d0917e8 @schwehr passes tests 1 and 2
authored
117 totalPointsInside++;
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
118 return(true);
119 }
120
121 void Density::printCellCounts()const {
c32fd07 @schwehr working on printing of the volume. seems to work
authored
122 cout << "# " << endl
123 << "# i cx cy cz counts x y z " << endl
124 << "# " << endl
125 << "# " << endl
126 ;
d0917e8 @schwehr passes tests 1 and 2
authored
127 for (size_t i=0; i<width*height*depth;i++) {
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
128 float x,y,z; getCellCenter(i,x,y,z);
129 size_t cx,cy,cz;
c32fd07 @schwehr working on printing of the volume. seems to work
authored
130 getCellXYZ(i,cx,cy,cz);
131 cout << i << " " << counts[i]
132 << " " << cx << " " << cy << " " << cz
133 << " " << x << " " << y << " " << z
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
134 << endl;
135 }
136 }
137
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
138 size_t Density::getCellFromWHD(const size_t xIndex, const size_t yIndex, const size_t zIndex) const {
139 const size_t zOff = zIndex * getWidth() * getHeight();
140 const size_t yOff = yIndex * getWidth();
141 const size_t off = xIndex + yOff + zOff;
142 if (!isValidCell(off)) {
143 cerr << "WARNING: getCellFromWHD out of bounds" << endl;
144 FAILED_HERE;
145 return (badValue());
146 }
147 return (off);
148 }
149
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
150 size_t
151 Density::getCell(const float x, const float y, const float z) const {
d0917e8 @schwehr passes tests 1 and 2
authored
152 if (!(xR[0] <= x && x <= xR[1])) return (badValue()); // Outside
153 if (!(yR[0] <= y && y <= yR[1])) return (badValue()); // Outside
154 if (!(zR[0] <= z && z <= zR[1])) return (badValue()); // Outside
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
155
156 const size_t xIndex = getCellX(x); //size_t((x-xR[0])/dx);
157 const size_t yIndex = getCellY(y); //size_t((y-yR[0])/dy);
158 const size_t zIndex = getCellZ(z); //size_t((z-zR[0])/dz);
159
160 const size_t zOff = zIndex * getWidth() * getHeight();
161 const size_t yOff = yIndex * getWidth();
162 const size_t off = xIndex + yOff + zOff;
163 assert (off < 1e9); // FIX: get rid of this contrain as someday this may be ok (64bit machines baby!)
164 // wait, wasn't the dec alpha a 64bit machine in 1992? Yet we've regressed.
165 return (off);
166 }
167
168 void Density::getCellXYZ(const size_t index, size_t &cx, size_t &cy, size_t &cz) const {
c32fd07 @schwehr working on printing of the volume. seems to work
authored
169 assert (isValidCell(index));
170 assert (index<1000000);
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
171 cz = index/(getWidth() * getHeight());
c32fd07 @schwehr working on printing of the volume. seems to work
authored
172 const size_t i2=index-cz*(getWidth() * getHeight());
173 assert (i2<100000);
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
174 cy = i2/getWidth();
175 cx = i2 - cy*getWidth();
c32fd07 @schwehr working on printing of the volume. seems to work
authored
176 //cout << "getCellXYZ: " << index << " " << cx << " " << cy << " " << cz << endl;
177 assert (cx<100000);
178 assert (cy<100000);
179 assert (cz<100000);
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
180 }
181
182
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
183 size_t Density::getCellNeighbor(const size_t i, NeighborEnum which) const {
184 assert (isValidCell(i));
185 size_t cx,cy,cz;
186 getCellXYZ (i,cx,cy,cz);
187
188 size_t cxNew=cx,cyNew=cy,czNew=cz;
189 switch (which) {
190 case LEFT: cxNew = cx - 1; if (cxNew>cx) return (badValue()); break;
191 case RIGHT: cxNew = cx + 1; if (getWidth() <= cxNew) return (badValue()); break;
192 case FRONT: cyNew = cy - 1; if (cyNew>cy) return (badValue()); break;
193 case BACK: cyNew = cy + 1; if (getHeight() <= cyNew) return (badValue()); break;
194 case BELOW: czNew = cz - 1; if (czNew>cz) return (badValue()); break;
195 case ABOVE: czNew = cz + 1; if (getDepth() <= czNew) return (badValue()); break;
196 default:
197 assert(false);
198 }
199
200 return (getCellFromWHD(cxNew,cyNew,czNew));
201 } // getCellNeighbor
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
202
203
204 void Density::getCellCenter(const size_t cellNum, float &x, float &y, float &z) const {
c32fd07 @schwehr working on printing of the volume. seems to work
authored
205 assert(isValidCell(cellNum));
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
206 size_t cx, cy, cz; // number of cells from the origin
207 getCellXYZ(cellNum,cx,cy,cz);
c32fd07 @schwehr working on printing of the volume. seems to work
authored
208 //cout << "cIndex: " << cx << " " <<cy<<" "<<cz<<endl;
209 assert (cx<1000000);
210 assert (cy<1000000);
211 assert (cz<1000000);
212 x = xR[0] + (cx+0.5) * dx;
213 y = yR[0] + (cy+0.5) * dy;
214 z = zR[0] + (cz+0.5) * dz;
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
215 }
216
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
217 bool Density::writeVol(const string &filename) {
218 FILE *o=fopen(filename.c_str(),"wb");
219 if (!o) {perror("failed to open output file");cerr << " " << filename << endl;return(false);}
220
df8aae6 @schwehr Now write the header without endian issues. Lets volume header worry
authored
221 {
222 VolHeader hdr(getWidth(),getHeight(),getDepth());
223 hdr.write(o);
224 }
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
225
226 const size_t min=getMinCount();
227 const size_t max=getMaxCount();
228
229 // http://doc.coin3d.org/SIMVoleon/classSoVolumeData.html#a1
230 for (size_t i=0;i<counts.size();i++) {
231 // FIX: how do we fit the data?
232 const unsigned char data=scaleCount(i,min,max);
233 #ifdef REGRESSION_TEST
234 cout << " writing: " << i<<"("<<counts[i]<<") -> " << int(data)
235 << " (" << min <<","<<max<<")"<<endl;
236 #endif
df8aae6 @schwehr Now write the header without endian issues. Lets volume header worry
authored
237
238 // No endian issue with 1 byte data
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
239 if (1!=fwrite(&data,sizeof(data),1,o)) {perror("write failed");fclose(o);return(false);}
240 }
241
242 if (0!=fclose(o)) {perror("close failed... bizarre");return(false);}
243 return (true);
244 }
245
246 unsigned char Density::scaleCount(const size_t i, const size_t min, const size_t max) const {
247 const float _0to1 = float(counts[i]-min)/(max-min);
248 const unsigned char r = (unsigned char)(_0to1 * std::numeric_limits<unsigned char>::max());
249 return (r);
250 }
251
252 size_t Density::getMaxCount() const {
253 size_t max = std::numeric_limits<size_t>::min();
254 for (size_t i=0;i<counts.size();i++) if (counts[i]>max) max=counts[i];
255 return (max);
256 }
257 size_t Density::getMinCount() const {
258 size_t min = std::numeric_limits<size_t>::max();
259 for (size_t i=0;i<counts.size();i++) if (counts[i]<min) min=counts[i];
260 return(min);
261 }
262
263
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
264 //####################################################################
265 // TEST CODE
266 //####################################################################
267 #ifdef REGRESSION_TEST
268
269 bool test1() {
270 cout << " test1" << endl;
271
272 Density d(1,1,1, 0.,1., 0.,1., 0.,1.);
273 if (0!=d.getCountInside()) {FAILED_HERE;return(false);}
274 if (0!=d.getCell(0.1,0.1,0.1)) {FAILED_HERE;return(false);}
275 if (0!=d.getCell(0.9,0.9,0.9)) {FAILED_HERE;return(false);}
276
277 if (!d.addPoint(0.5,0.5,0.5)) {FAILED_HERE;return(false);}
278 if (1!=d.getCountInside()) {FAILED_HERE;return(false);}
279
280 if (d.addPoint(5,0.5,0.5)) {FAILED_HERE;return(false);}
281 if (1!=d.getCountInside()) {FAILED_HERE;return(false);}
282 if (d.addPoint(.5,5,0.5)) {FAILED_HERE;return(false);}
283 if (1!=d.getCountInside()) {FAILED_HERE;return(false);}
284 if (d.addPoint(.5,0.5,5)) {FAILED_HERE;return(false);}
285 if (1!=d.getCountInside()) {FAILED_HERE;return(false);}
286
d0917e8 @schwehr passes tests 1 and 2
authored
287 if (1!=d.getWidth()) {FAILED_HERE;return(false);}
288 if (1!=d.getHeight()) {FAILED_HERE;return(false);}
289 if (1!=d.getDepth()) {FAILED_HERE;return(false);}
290
291 cout << " cell counts: " << endl;
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
292 d.printCellCounts();
293
294 return (true);
d0917e8 @schwehr passes tests 1 and 2
authored
295 } // test1
296
297 bool test2() {
298 cout << " test2" << endl;
299
300 Density d(2,1,1, 0.,2., 0.,1., 0.,1.);
301 if (0!=d.getCountInside()) {FAILED_HERE;return(false);}
302 d.addPoint(0.5,.1,.1);
303 if (1!=d.getCellCount(0)) {FAILED_HERE;return(false);}
304 if (0!=d.getCellCount(1)) {FAILED_HERE;return(false);}
305 d.addPoint(1.5,.1,.1);
306 if (1!=d.getCellCount(0)) {FAILED_HERE;return(false);}
307 if (1!=d.getCellCount(1)) {FAILED_HERE;return(false);}
308
c32fd07 @schwehr working on printing of the volume. seems to work
authored
309 #if 0
310 {
311 cout << "Danger: "<< endl;
312 Density dx(10,1,1, -5,5., 0.,1., 0.,1.);
313 for (size_t i=0;i<10;i++) {
314 float x,y,z;
315 dx.getCellCenter(i,x,y,z);
316 cout << " " << x << " " << y << " " << z << endl;
317 }
318 }
319 #endif
320 #if 0
321 {
322 cout << "Danger: Y"<< endl;
323 Density dy(1,10,1, 0,1., -5.,5., 0.,1.);
324 for (size_t i=0;i<10;i++) {
325 float x,y,z;
326 dy.getCellCenter(i,x,y,z);
327 cout << " Y: " << x << " " << y << " " << z << endl;
328 }
329 }
330 #endif
331
332 #if 0
333 {
334 cout << "Danger: Z"<< endl;
335 Density dy(1,1,10, 0,1., 0.,1., -5.,5.);
336 for (size_t i=0;i<10;i++) {
337 float x,y,z;
338 dy.getCellCenter(i,x,y,z);
339 cout << " Y: " << x << " " << y << " " << z << endl;
340 }
341 }
342 #endif
343
d0917e8 @schwehr passes tests 1 and 2
authored
344 return(true);
345 } // test2
346
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
347
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
348
349 bool test3() {
350 cout << " test3" << endl;
351
352 Density d(2,2,2, 0.,2., 0.,2., 0.,2.);
353 d.addPoint(0.1,0.1,0.1); d.addPoint(0.1,0.1,0.1);
354 d.addPoint(1.5,0.1,0.1); d.addPoint(0.1,1.5,0.1);
355 for (size_t i=0;i<10;i++) d.addPoint(1.5,1.5,1.5);
356
357 if (!d.writeVol(string("test3.vol"))) {FAILED_HERE;return(false);}
358
359 return(true);
360 }
361
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
362
363 bool test4() {
ae12d9d @schwehr test4() is now passed
authored
364 bool ok=true;
365 {
366 // This is a pretty small/simple test case
367 Density d;
368 d.resize(1,2,3, 0.,2., 0.,2., 0.,2.);
369
370 if (1!=d.getWidth()) {ok=false;FAILED_HERE;}
371 if (2!=d.getHeight()) {ok=false;FAILED_HERE;}
372 if (3!=d.getDepth()) {ok=false;FAILED_HERE;}
373 if (6!=d.getSize()) {ok=false;FAILED_HERE;}
374
375 if (0!=d.getCellFromWHD(0,0,0)) {ok=false; FAILED_HERE;}
376 if (1!=d.getCellFromWHD(0,1,0)) {ok=false;FAILED_HERE;}
377
378 if (Density::badValue()!=d.getCellNeighbor(0,Density::LEFT)) {ok=false;FAILED_HERE;}
379 if (Density::badValue()!=d.getCellNeighbor(0,Density::RIGHT)) {ok=false;FAILED_HERE;}
380
381 if (Density::badValue()!=d.getCellNeighbor(0,Density::FRONT)) {ok=false;FAILED_HERE;}
382 if (1!=d.getCellNeighbor(0,Density::BACK)) {ok=false;FAILED_HERE;}
383
384 if (Density::badValue()!=d.getCellNeighbor(0,Density::BELOW)) {ok=false;FAILED_HERE;}
385 if (2!=d.getCellNeighbor(0,Density::ABOVE)) {ok=false;FAILED_HERE;}
386 }
387
388 //Density(string("filename")); //FIX: Implement and test
389 return(ok);
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
390 }
391
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
392 int main (UNUSED int argc, char *argv[]) {
393 // Put test code here
394 bool ok=true;
395
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
396 cout << " Size of Density (in bytes): " << sizeof(Density) << endl;
397 cout << " Size of VolHeader (in bytes): " << sizeof(VolHeader) << endl;
398
399 if (52 != sizeof(VolHeader)) {FAILED_HERE;ok=false;}
400
401 cout << " Size of float: " << sizeof(1.f) << endl;
402 cout << " Size of double: " << sizeof(1.) << endl;
403 if (4 != sizeof(1.f)) {FAILED_HERE;ok=false;}
404 if (8 != sizeof(1.)) {FAILED_HERE;ok=false;}
405
406 #ifdef BIGENDIAN
407 if (0x00010203!=hton_uint32(0x00010203)) {FAILED_HERE;ok=false;}
408 #endif
409
410 if (4!=sizeof(float)) {FAILED_HERE;ok=false;} // Must be 4 for vol_header
411 if (4!=sizeof(uint32_t)) {FAILED_HERE;ok=false;} // Must be 4 for vol_header
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
412
413 if (!test1()) {FAILED_HERE;ok=false;}
d0917e8 @schwehr passes tests 1 and 2
authored
414 if (!test2()) {FAILED_HERE;ok=false;}
3bb66ff @schwehr added hton_uint32(), hton_float(), VolHeader constructor
authored
415 if (!test3()) {FAILED_HERE;ok=false;} // test writing
745942c @schwehr Added Density(), Density(string filename), resize(), getSize(),
authored
416 if (!test4()) {FAILED_HERE;ok=false;}
d384586 @schwehr Doesn't actually pass the 1st test yet.
authored
417
418 cout << " " << argv[0] << " test: " << (ok?"ok":"failed")<<endl;
419 return (ok?EXIT_SUCCESS:EXIT_FAILURE);
420 }
421 #endif // REGRESSION_TEST
Something went wrong with that request. Please try again.