EMAN2
marchingcubes.h
Go to the documentation of this file.
1/*
2 * Author: Tao Ju, 5/16/2007 <taoju@cs.wustl.edu>, code ported by Grant Tang
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#ifndef _MARCHING_CUBES_H_
33#define _MARCHING_CUBES_H_
34
35#include <vector>
36using std::vector;
37
38#include "vecmath.h"
39#include "isosurface.h"
40
41// Marching cubes debug will turn on debug and timing information
42#define MARCHING_CUBES_DEBUG 0
43
44#include <ostream>
45using std::ostream;
46
47#include <climits>
48// for CHAR_BIT
49
50#ifdef __APPLE__
51 #include "OpenGL/gl.h"
52 #include "OpenGL/glext.h"
53#else // WIN32, LINUX
54 #include "GL/gl.h"
55 #include "GL/glext.h"
56#endif //__APPLE__
57
58namespace EMAN
59{
73 template<typename type>
75 {
76 public:
80 explicit CustomVector(unsigned int starting_size=1024) : data(0), size(0), elements(0)
81 {
82 resize(starting_size);
83 }
84
86 {
87 if(data) {free(data); data=0;}
88 }
89
94 inline void clear(unsigned int starting_size=1024)
95 {
96 if (data) {free(data); data = 0;}
97 size = 0;
98 elements = 0;
99 resize(starting_size);
100 }
101
108 inline void resize(const unsigned int n)
109 {
110 data = (type*)realloc(data, n*sizeof(type));
111
112 for(unsigned int i = size; i < n; ++i) data[i] = 0;
113 size = n;
114 }
115
120 inline void push_back(const type& t)
121 {
122 if ( elements == size ) resize(2*size);
123 data[elements] = t;
124 ++elements;
125 }
126
131 inline void push_back_3(const type* const p)
132 {
133 if ( elements+2 >= size ) resize(2*size);
134 memcpy( &data[elements], p, 3*sizeof(type));
135 elements = elements + 3;
136 }
137
140 inline void mult3(const type& v1, const type& v2, const type& v3)
141 {
142 for(unsigned int i = 0; (i + 2) < elements; i += 3 ){
143 data[i] *= v1;
144 data[i+1] *= v2;
145 data[i+2] *= v3;
146 }
147 }
148
155 inline unsigned int elem() { return elements; }
156
161 inline type& operator[](const unsigned int idx)
162 {
163 unsigned int csize = size;
164 while (idx >= csize ) {
165 csize *= 2;
166 }
167 if ( csize != size ) resize(csize);
168 return data[idx];
169 }
170
174 inline type* get_data() { return data; }
175
176 private:
178 type* data;
180 unsigned int size;
182 unsigned int elements;
183 };
184
189 public:
193
195 float* getRGBColor(int x, int y, int z);
196
198 void set_data(EMData* data);
199
202
205
207 inline void setOrigin(int orix, int oriy, int oriz)
208 {
209 originx = orix;
210 originy = oriy;
211 originz = oriz;
212 needtorecolor = true;
213 }
215 inline void setScale(float i, float o)
216 {
217 inner = i;
218 outer = o;
219 needtorecolor = true;
220 }
222 inline void setRGBmode(int mode)
223 {
224 rgbmode = mode;
225 needtorecolor = true;
226 }
227
229 inline void setMinMax(float min, float max)
230 {
231 minimum = min;
232 maximum = max;
233 needtorecolor = true;
234 }
235
237 inline int getRGBmode()
238 {
239 return rgbmode;
240 }
241
243 inline bool getNeedToRecolor()
244 {
245 return needtorecolor;
246 }
247
248 inline void setNeedToRecolor(bool recolor)
249 {
250 needtorecolor = recolor;
251 }
252 private:
257 float inner;
258 float outer;
259 float minimum;
260 float maximum;
261
262 bool needtorecolor; // dirty bit to let the system know when we need to recolor
263
264 float* colormap; // pointer to a colormap
265 EMData* em_data; // pointer to EMdata
266 EMData* cmap; // pointer to colormap data
267
268 float rgb[3]; //little array to hold RGB values;
269 };
270
271 class MarchingCubes : public Isosurface {
272 friend class GLUtil;
273 public:
277
283 virtual ~MarchingCubes();
284
290 void set_data(EMData* data);
291
295 void set_surface_value(const float value);
296
300 float get_surface_value() const { return _surf_value; }
301
310 void set_sampling(const int rate) { drawing_level = rate; }
311
315 int get_sampling() const { return drawing_level; }
316
319 int get_sampling_range() { return minvals.size()-1; }
320
324
330
332
335 inline void setRGBorigin(int x, int y, int z)
336 {
338 }
339
340 inline void setRGBscale(float i, float o)
341 {
343 }
344
345 inline void setRGBmode(int mode)
346 {
348 }
349
351 inline int getRGBmode()
352 {
353 return rgbgenerator.getRGBmode();
354 }
355
357 inline void setCmapData(EMData* data)
358 {
360 }
361
363 inline void setCmapMinMax(float min, float max)
364 {
365 rgbgenerator.setMinMax(min, max);
366 }
367
368 private:
369 map<int, int> point_map;
370 unsigned long _isodl;
371 GLuint buffer[4];
372
379
380
385
387 vector<EMData*> minvals, maxvals;
388
391
401 void draw_cube(const int x, const int y, const int z, const int cur_level );
402
403
411 void marching_cube(int fX, int fY, int fZ, const int cur_level);
412
417
426 float get_offset(float fValue1, float fValue2, float fValueDesired);
427
431 int get_edge_num(int x, int y, int z, int edge);
432
443 void get_normal(Vector3 &normal, int fX, int fY, int fZ);
444
451
454
455 bool needtobind; // A dirty bit to signal when the the MC algorithm or color has chaged and hence a need to update GPU buffers
456 };
457
461// class CudaMarchingCubes : public Isosurface {
462// public:
463//
464// /** Most commonly used constructor
465// * calls set_data(em)
466// * @param em the EMData object to generate triangles and normals for
467// */
468// CudaMarchingCubes(EMData * em);
469// virtual ~CudaMarchingCubes();
470// /**
471// * Set Isosurface value
472// */
473// virtual void set_surface_value(const float value);
474//
475// /** Sets Voxel data for Isosurface implementation
476// * Calls calculate_min_max_vals which generates the tree of data
477// * @param data the emdata object to be rendered in 3D
478// * @exception ImageDimensionException if the image z dimension is 1
479// */
480// void set_data(EMData* data);
481//
482// virtual float get_surface_value() const { return _surf_value; }
483//
484// /**
485// * Set Grid Size
486// */
487// virtual void set_sampling(const int size) {} ;
488//
489// virtual int get_sampling() const { return 0; };
490//
491// /** Get the number of feasible samplings
492// *
493// */
494// virtual int get_sampling_range() {return 0; }
495//
496// virtual Dict get_isosurface() { return Dict;}
497//
498// }
499
503 public:
504 typedef unsigned int U32;
505 typedef long unsigned int U64;
506 typedef double F64;
507 typedef float F32;
508 typedef short int I16;
509 typedef short unsigned int U16;
510 typedef unsigned char U8;
511
512
513
516
517 int write(const string& filename);
518
519 ostream& write(ostream&);
520
521 private:
522 unsigned int size_of_in_bytes();
523
525
526 ostream& write_header(ostream&);
527 ostream& write_clod_mesh_generator_node(ostream& os);
528
529
530 template<typename type>
531 ostream& write(ostream& os, const type& T) {
532 os.write( (const char*)(&T), sizeof(type) );
533 return os;
534 }
535
536
537// U8 reverse_bits_3d( U8 val ) {
538// U8 ret = 0;
539// U8 n_bits = sizeof ( val ) * CHAR_BIT;
540//
541// for ( unsigned i = 0; i < n_bits; ++i ) {
542// ret = ( ret << 1 ) | ( val & 1 );
543// val >>= 1;
544// }
545//
546// return ret;
547// }
548
549// U16 reverse_bits_u3d( U16 val ) {
550// bool is_big_endian = ByteOrder::is_host_big_endian();
551//
552// U16 ret = 0;
553//
554// U8* pu8 = (U8*)&val;
555// U8* pu8ret = (U8*)&ret;
556// U8 high_order = 0;
557// U8 low_order = 0;
558// if (is_big_endian) {
559// high_order = pu8[0];
560// low_order = pu8[1];
561// }
562// else {
563// high_order = pu8[1];
564// low_order = pu8[0];
565// }
566//
567// pu8ret[0] = low_order;
568// pu8ret[1] = higher_order;
569//
570// high_order = reverse_bits_u3d(high_order);
571// low_order = reverse_bits_u3d(low_order);
572//
573// return ret;
574//
575// }
576//
577// U32 reverse_bits_u3d( U32 val ) {
578// bool is_big_endian = ByteOrder::is_host_big_endian();
579//
580// U32 ret = 0;
581//
582// U16 * pu16 = (U16*)&val;
583// U16* pu16ret = (U16*)&ret;
584// U16 high_order = 0;
585// U16 low_order = 0;
586// if (is_big_endian) {
587// high_order = pu16[0];
588// low_order = pu16[1];
589// }
590// else {
591// high_order = pu16[1];
592// low_order = pu16[0];
593// }
594//
595// high_order = reverse_bits_u3d(high_order);
596// low_order = reverse_bits_u3d(low_order);
597//
598// pu16ret[0] = low_order;
599// pu16ret[1] = higher_order;
600//
601// return ret;
602//
603// }
604//
605
608
609
613 };
614
615 // Template specialization. Have to be careful when dealing with strings
616 template<> ostream& U3DWriter::write(ostream& os, const string& );
617
618// class U3DBitStreamWriter {
619// public:
620// typedef unsigned int U32;
621// typedef long unsigned int U64;
622// typedef double F64;
623// typedef float F32;
624// typedef short int I16;
625// typedef short unsigned int U16;
626// typedef unsigned char U8;
627//
628//
629// U3D_BitStreamWriter();
630// ~U3D_BitStreamWriter();
631//
632// // We could do this kind of thing with templates, but
633// // we would have to specialize each function anyhow,
634// // so it makes sense just to do it the C way.
635// void writeU8( U8 value );
636// void writeU16( U16 value );
637// void writeU32( U32 value );
638// void writeU64( U64 value );
639// void writeI32( I32 value );
640// void writeF32( F32 value );
641// void writeF64( F64 value );
642//
643// void WriteCompressedU32( U32 context, U32 value );
644// void WriteCompressedU16( U32 context, U32 value );
645// void WriteCompressedU8( U32 context, U32 value );
646//
647// };
648
649
650
651}
652
653#endif
Class to encapsulate an RGB color generator for marching cubes isosurface generator For now you can o...
float * getRGBColor(int x, int y, int z)
Generate a color based on pixel coords.
void set_data(EMData *data)
set the emdata
void setScale(float i, float o)
Set scaling.
ColorRGBGenerator(EMData *emdata)
Constructor.
void setNeedToRecolor(bool recolor)
void set_cmap_data(EMData *data)
Set min max data.
void setOrigin(int orix, int oriy, int oriz)
Set origin.
void generateRadialColorMap()
Generate a color map.
void setMinMax(float min, float max)
Set the mn max for cmap coloring.
bool getNeedToRecolor()
Lets us know if we need to recalculate colors.
void setRGBmode(int mode)
Set RGB mode 0 = none, 1 = color by radius, more to come :)
int getRGBmode()
Return RGB mode.
CustomVector has some trivial optimizations of the STL vector.
Definition: marchingcubes.h:75
type * get_data()
get the underlying data as a pointer objects
void resize(const unsigned int n)
Resize Resize the data pointer using realloc In general you want to resize to a larger size....
void push_back_3(const type *const p)
Push back 3 values Potentially resizes.
unsigned int elements
The number of stored elements.
CustomVector(unsigned int starting_size=1024)
Constructor.
Definition: marchingcubes.h:80
type * data
The data pointer.
void mult3(const type &v1, const type &v2, const type &v3)
Multiply contiguous groups of 3 by different values.
unsigned int elem()
The number of elements, is the same as STL::vector size() Should be called size() but oh well....
void clear(unsigned int starting_size=1024)
Clear clears all data and resizes.
Definition: marchingcubes.h:94
void push_back(const type &t)
Push back a value Potentially resizes.
unsigned int size
The size of the associated memory block.
type & operator[](const unsigned int idx)
Operator[] - provide convenient set functionality (note NOT get)
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
void marching_cube(int fX, int fY, int fZ, const int cur_level)
Function for managing cases where a triangles can potentially be rendered Called by draw_cube.
void calculate_surface()
Calculate and generate the entire set of vertices and normals using current states Calls draw_cube(0,...
unsigned long _isodl
void set_surface_value(const float value)
Set Isosurface value.
ColorRGBGenerator rgbgenerator
Color by radius generator.
void setCmapData(EMData *data)
Sets the colormap.
CustomVector< float > cc
void get_normal(Vector3 &normal, int fX, int fY, int fZ)
Find the gradient of the scalar field at a point.
bool calculate_min_max_vals()
Calculate the min and max value trees Stores minimum and maximum cube neighborhood values in a tree s...
float get_offset(float fValue1, float fValue2, float fValueDesired)
Find the approximate point of intersection of the surface between two points with the values fValue1 ...
void set_data(EMData *data)
Sets Voxel data for Isosurface implementation Calls calculate_min_max_vals which generates the tree o...
vector< EMData * > maxvals
void draw_cube(const int x, const int y, const int z, const int cur_level)
The main cube drawing function To start the process of generate triangles call with draw_cube(0,...
int drawing_level
The "sampling rate".
void setRGBorigin(int x, int y, int z)
Functions to control colroing mode.
float get_surface_value() const
Get the current isosurface value being used.
CustomVector< float > nn
int getRGBmode()
Return RGB mode.
Dict get_isosurface()
Get the isosurface as dictionary Traverses the tree and marches the cubes.
int get_sampling_range()
Get the range of feasible sampling rates.
int get_edge_num(int x, int y, int z, int edge)
Get edge num needs better commenting.
CustomVector< unsigned int > ff
MarchingCubes()
Default constructor.
int get_sampling() const
Current the current sampling rate Finest sampling is -1.
void color_vertices()
Color the vertices.
void setRGBmode(int mode)
MarchingCubes(EMData *em)
Most commonly used constructor calls set_data(em)
virtual ~MarchingCubes()
void set_sampling(const int rate)
Set sampling rates A smaller value means a finer sampling.
void clear_min_max_vals()
Clear the minimum and maximum value search trees Frees memory in the minvals and maxvals.
CustomVector< int > vv
vector< EMData * > minvals
Vectors for storing the search trees.
void setRGBscale(float i, float o)
CustomVector< float > pp
.Custom vectors for storing points, normals and faces
map< int, int > point_map
void setCmapMinMax(float min, float max)
Sets the colormap mix max range.
A work in progress by David Woolford.
ostream & write(ostream &)
CustomVector< F32 > nn
CustomVector< unsigned int > ff
ostream & write_clod_mesh_generator_node(ostream &os)
void test_type_sizes()
ostream & write_header(ostream &)
short unsigned int U16
long unsigned int U64
CustomVector< F32 > pp
int write(const string &filename)
ostream & write(ostream &os, const type &T)
unsigned char U8
unsigned int size_of_in_bytes()
unsigned int U32
E2Exception class.
Definition: aligner.h:40
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517