EMAN::MarchingCubes Class Reference

#include <marchingcubes.h>

Inheritance diagram for EMAN::MarchingCubes:

Inheritance graph
[legend]
Collaboration diagram for EMAN::MarchingCubes:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 MarchingCubes ()
 Default constructor.
 MarchingCubes (EMData *em)
 Most commonly used constructor calls set_data(em).
virtual ~MarchingCubes ()
void set_data (EMData *data)
 Sets Voxel data for Isosurface implementation Calls calculate_min_max_vals which generates the tree of data.
void set_surface_value (const float value)
 Set Isosurface value.
float get_surface_value () const
 Get the current isosurface value being used.
void set_sampling (const int rate)
 Set sampling rates A smaller value means a finer sampling.
int get_sampling () const
 Current the current sampling rate Finest sampling is -1.
int get_sampling_range ()
 Get the range of feasible sampling rates.
Dict get_isosurface ()
 Get the isosurface as dictionary Traverses the tree and marches the cubes.
void surface_face_z ()

Private Member Functions

bool calculate_min_max_vals ()
 Calculate the min and max value trees Stores minimum and maximum cube neighborhood values in a tree structure
Exceptions:
NullPointerException if _emdata is null.

void clear_min_max_vals ()
 Clear the minimum and maximum value search trees Frees memory in the minvals and 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,0,0,minvals.size()-1) Once cur_level becomes drawing_level marching_cube is called.
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,0,0,minvals.size()-1).
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 and fValue2.
int get_edge_num (int x, int y, int z, int edge)
 Get edge num needs better commenting.
void get_normal (Vector3 &normal, int fX, int fY, int fZ)
 Find the gradient of the scalar field at a point.

Private Attributes

map< int, int > point_map
unsigned long _isodl
vector< EMData * > minvals
 Vectors for storing the search trees.
vector< EMData * > maxvals
int drawing_level
 The "sampling rate".
CustomVector< float > pp
 .Custom vectors for storing points, normals and faces
CustomVector< float > nn
CustomVector< unsigned int > ff

Friends

class GLUtil

Detailed Description

Definition at line 181 of file marchingcubes.h.


Constructor & Destructor Documentation

MarchingCubes::MarchingCubes (  ) 

Default constructor.

Definition at line 143 of file marchingcubes.cpp.

00144         : _isodl(0)
00145 {
00146 }

MarchingCubes::MarchingCubes ( EMData em  ) 

Most commonly used constructor calls set_data(em).

Parameters:
em the EMData object to generate triangles and normals for

Definition at line 148 of file marchingcubes.cpp.

References set_data().

00149         : _isodl(0)
00150 {
00151         set_data(em);
00152 }

MarchingCubes::~MarchingCubes (  )  [virtual]

Definition at line 210 of file marchingcubes.cpp.

References clear_min_max_vals().

00210                               {
00211         clear_min_max_vals();
00212 }


Member Function Documentation

bool MarchingCubes::calculate_min_max_vals (  )  [private]

Calculate the min and max value trees Stores minimum and maximum cube neighborhood values in a tree structure

Exceptions:
NullPointerException if _emdata is null.

.. this should not happen but is left for clarity for programmers

Definition at line 169 of file marchingcubes.cpp.

References EMAN::Isosurface::_emdata, clear_min_max_vals(), drawing_level, EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), maxvals, minvals, NullPointerException, nx, ny, process(), and EMAN::EMData::process().

Referenced by set_data().

00170 {
00171 
00172         if (_emdata == NULL ) throw NullPointerException("Error, cannot generate search tree if the overriding EMData object is NULL");
00173 
00174         clear_min_max_vals();
00175 
00176         int nx = _emdata->get_xsize();
00177         int ny = _emdata->get_ysize();
00178         int nz = _emdata->get_zsize();
00179 
00180         // Create the binary min max tree
00181         while ( nx > 1 || ny > 1 || nz > 1 )
00182         {
00183                 int size = minvals.size();
00184 
00185                 if ( size == 0 ){
00186                         Dict a;
00187                         // Setting search to 3 at the bottom level is most important.
00188                         // FIXME - d.woolford add comments heere
00189                         a["search"] = 3;
00190                         minvals.push_back(_emdata->process("math.minshrink",a));
00191                         maxvals.push_back(_emdata->process("math.maxshrink",a));
00192                 }else {
00193                         minvals.push_back(minvals[size-1]->process("math.minshrink"));
00194                         maxvals.push_back(maxvals[size-1]->process("math.maxshrink"));
00195                 }
00196 
00197                 nx = minvals[size]->get_xsize();
00198                 ny = minvals[size]->get_ysize();
00199                 nz = minvals[size]->get_zsize();
00200 #if MARCHING_CUBES_DEBUG
00201                 cout << "dims are " << nx << " " << ny << " " << nz << endl;
00202 #endif
00203         }
00204 
00205         drawing_level = -1;
00206 
00207         return true;
00208 }

void MarchingCubes::calculate_surface (  )  [private]

Calculate and generate the entire set of vertices and normals using current states Calls draw_cube(0,0,0,minvals.size()-1).

Definition at line 272 of file marchingcubes.cpp.

References EMAN::Isosurface::_emdata, EMAN::Isosurface::_surf_value, EMAN::CustomVector< type >::clear(), draw_cube(), ff, max, maxvals, min, minvals, nn, NotExistingObjectException, NullPointerException, point_map, and pp.

Referenced by get_isosurface().

00272                                       {
00273 
00274         if ( _emdata == 0 ) throw NullPointerException("Error, attempt to generate isosurface, but the emdata image object has not been set");
00275         if ( minvals.size() == 0 || maxvals.size() == 0 ) throw NotExistingObjectException("Vector of EMData pointers", "Error, the min and max val search trees have not been created");
00276 
00277         point_map.clear();
00278         pp.clear();
00279         nn.clear();
00280         ff.clear();
00281 
00282 #if MARCHING_CUBES_DEBUG
00283         int time0 = clock();
00284 #endif
00285 
00286         float min = minvals[minvals.size()-1]->get_value_at(0,0,0);
00287         float max = maxvals[minvals.size()-1]->get_value_at(0,0,0);
00288         if ( min < _surf_value &&  max > _surf_value) draw_cube(0,0,0,minvals.size()-1);
00289 
00290 #if MARCHING_CUBES_DEBUG
00291         int time1 = clock();
00292         cout << "It took " << (time1-time0) << " " << (float)(time1-time0)/CLOCKS_PER_SEC << " to traverse the search tree and generate polygons" << endl;
00293         cout << "... using surface value " << _surf_value << endl;
00294 #endif
00295 }

void MarchingCubes::clear_min_max_vals (  )  [private]

Clear the minimum and maximum value search trees Frees memory in the minvals and maxvals.

Definition at line 154 of file marchingcubes.cpp.

References maxvals, and minvals.

Referenced by calculate_min_max_vals(), and ~MarchingCubes().

00155 {
00156         for (vector<EMData*>::iterator it = minvals.begin(); it != minvals.end(); ++it)
00157         {
00158                 if ( (*it) != 0 ) delete *it;
00159         }
00160         minvals.clear();
00161 
00162         for (vector<EMData*>::iterator it = maxvals.begin(); it != maxvals.end(); ++it)
00163         {
00164                 if ( (*it) != 0 ) delete *it;
00165         }
00166         maxvals.clear();
00167 }

void MarchingCubes::draw_cube ( const int  x,
const int  y,
const int  z,
const int  cur_level 
) [private]

The main cube drawing function To start the process of generate triangles call with draw_cube(0,0,0,minvals.size()-1) Once cur_level becomes drawing_level marching_cube is called.

Parameters:
x the current x value, relative to cur_level
y the current y value, relative to cur_level
z the current z value, relative to cur_level
cur_level the current tree traversal level

Definition at line 297 of file marchingcubes.cpp.

References EMAN::Isosurface::_emdata, EMAN::Isosurface::_surf_value, a2fPosXOffset, a2fPosXPosYOffset, a2fPosXPosZOffset, a2fPosYOffset, a2fPosYPosZOffset, a2fPosZOffset, a2fVertexOffset, drawing_level, get_xsize(), EMAN::EMData::get_xsize(), get_ysize(), EMAN::EMData::get_ysize(), get_zsize(), EMAN::EMData::get_zsize(), marching_cube(), max, maxvals, min, and minvals.

Referenced by calculate_surface().

00297                                                                                          {
00298 
00299         if ( cur_level == drawing_level )
00300         {
00301                 EMData* e;
00302                 if ( drawing_level == - 1 ) e = _emdata;
00303                 else e = minvals[drawing_level];
00304                 if ( x < (e->get_xsize()-1) && y < (e->get_ysize()-1) && z < (e->get_zsize()-1))
00305                         marching_cube(x,y,z, cur_level);
00306         }
00307         else
00308         {
00309                 EMData* e;
00310                 if ( cur_level > 0 ) {
00311                         int xsize = minvals[cur_level-1]->get_xsize();
00312                         int ysize = minvals[cur_level-1]->get_ysize();
00313                         int zsize = minvals[cur_level-1]->get_zsize();
00314                         e = minvals[cur_level-1];
00315                         for(int i=0; i<8; ++i ) {
00316                                 int xx = 2*x+a2fVertexOffset[i][0];
00317                                 if ( xx >= xsize ) continue;
00318                                 int yy = 2*y+a2fVertexOffset[i][1];
00319                                 if ( yy >= ysize ) continue;
00320                                 int zz = 2*z+a2fVertexOffset[i][2];
00321                                 if ( zz >= zsize ) continue;
00322 
00323                                 float min = minvals[cur_level-1]->get_value_at(xx,yy,zz);
00324                                 float max = maxvals[cur_level-1]->get_value_at(xx,yy,zz);
00325                                 if ( min < _surf_value &&  max > _surf_value)
00326                                         draw_cube(xx,yy,zz,cur_level-1);
00327                         }
00328                 }
00329                 else {
00330                         e = _emdata;
00331                         for(int i=0; i<8; ++i ) {
00332                                         draw_cube(2*x+a2fVertexOffset[i][0],2*y+a2fVertexOffset[i][1],2*z+a2fVertexOffset[i][2],cur_level-1);
00333                         }
00334                 }
00335 
00336                 if ( x == (minvals[cur_level]->get_xsize()-1) ) {
00337                         if ( e->get_xsize() > 2*x ){
00338                                 for(int i=0; i<4; ++i ) {
00339                                         draw_cube(2*x+a2fPosXOffset[i][0],2*y+a2fPosXOffset[i][1],2*z+a2fPosXOffset[i][2],cur_level-1);
00340                                 }
00341                         }
00342                         if ( y == (minvals[cur_level]->get_ysize()-1) ) {
00343                                 if ( e->get_ysize() > 2*y ) {
00344                                         for(int i=0; i<2; ++i ) {
00345                                                 draw_cube(2*x+a2fPosXPosYOffset[i][0],2*y+a2fPosXPosYOffset[i][1],2*z+a2fPosXPosYOffset[i][2],cur_level-1);
00346                                         }
00347                                 }
00348                                 if (  z == (minvals[cur_level]->get_zsize()-1) ){
00349                                         if ( e->get_zsize() > 2*z ) {
00350                                                 draw_cube(2*x+2,2*y+2,2*z+2,cur_level-1);
00351                                         }
00352                                 }
00353                         }
00354                         if ( z == (minvals[cur_level]->get_zsize()-1) ) {
00355                                 if ( e->get_zsize() > 2*z ) {
00356                                         for(int i=0; i<2; ++i ) {
00357                                                 draw_cube(2*x+a2fPosXPosZOffset[i][0],2*y+a2fPosXPosZOffset[i][1],2*z+a2fPosXPosZOffset[i][2],cur_level-1);
00358                                         }
00359                                 }
00360                         }
00361                 }
00362                 if ( y == (minvals[cur_level]->get_ysize()-1) ) {
00363                         if ( e->get_ysize() > 2*y ) {
00364                                 for(int i=0; i<4; ++i ) {
00365                                         draw_cube(2*x+a2fPosYOffset[i][0],2*y+a2fPosYOffset[i][1],2*z+a2fPosYOffset[i][2],cur_level-1);
00366                                 }
00367                         }
00368                         if ( z == (minvals[cur_level]->get_ysize()-1) ) {
00369                                 if ( e->get_zsize() > 2*z ) {
00370                                         for(int i=0; i<2; ++i ) {
00371                                                 draw_cube(2*x+a2fPosYPosZOffset[i][0],2*y+a2fPosYPosZOffset[i][1],2*z+a2fPosYPosZOffset[i][2],cur_level-1);
00372                                         }
00373                                 }
00374                         }
00375                 }
00376                 if ( z == (minvals[cur_level]->get_zsize()-1) ) {
00377                         if ( e->get_zsize() > 2*z ) {
00378                                 for(int i=0; i<4; ++i ) {
00379                                         draw_cube(2*x+a2fPosZOffset[i][0],2*y+a2fPosZOffset[i][1],2*z+a2fPosZOffset[i][2],cur_level-1);
00380                                 }
00381                         }
00382                 }
00383 
00384         }
00385 }

int MarchingCubes::get_edge_num ( int  x,
int  y,
int  z,
int  edge 
) [private]

Get edge num needs better commenting.

Definition at line 406 of file marchingcubes.cpp.

Referenced by marching_cube().

00406                                                              {
00407         // edge direction is right, down, back (x, y, z)
00408         unsigned int index = 0;
00409         index = (x << 22) | (y << 12) | (z << 2) | edge;
00410         return index;
00411 }

Dict MarchingCubes::get_isosurface (  )  [virtual]

Get the isosurface as dictionary Traverses the tree and marches the cubes.

Returns:
a dictionary object containing to float pointers (to vertex and normal data), and an int pointer (to face data)

Implements EMAN::Isosurface.

Definition at line 214 of file marchingcubes.cpp.

References calculate_surface(), EMAN::CustomVector< type >::elem(), ff, EMAN::CustomVector< type >::get_data(), nn, pp, and EMAN::Dict::put().

00215 {
00216         calculate_surface();
00217         Dict d;
00218         d.put("points", (float*)pp.get_data());
00219         for (unsigned int i = 0; i < ff.elem(); ++i ) ff[i] /= 3;
00220         d.put("faces", (unsigned int*)ff.get_data());
00221         d.put("normals", (float*)nn.get_data());
00222         d.put("size", ff.elem());
00223         return d;
00224 }

void MarchingCubes::get_normal ( Vector3 normal,
int  fX,
int  fY,
int  fZ 
) [private]

Find the gradient of the scalar field at a point.

This gradient can be used as a very accurate vertx normal for lighting calculations.

THIS FUNCTION IS NO LONGER CALLED - d.woolford but is retained because it may be useful, perhaps even for saving time

Parameters:
normal where to store the normal
fX 
fY 
fZ 

Definition at line 387 of file marchingcubes.cpp.

References EMAN::Isosurface::_emdata, EMAN::EMData::get_value_at(), and EMAN::Vector3::normalize().

00388 {
00389         normal[0] = _emdata->get_value_at(fX-1, fY, fZ) - _emdata->get_value_at(fX+1, fY, fZ);
00390     normal[1] = _emdata->get_value_at(fX, fY-1, fZ) - _emdata->get_value_at(fX, fY+1, fZ);
00391     normal[2] = _emdata->get_value_at(fX, fY, fZ-1) - _emdata->get_value_at(fX, fY, fZ+1);
00392     normal.normalize();
00393 }

float MarchingCubes::get_offset ( float  fValue1,
float  fValue2,
float  fValueDesired 
) [private]

Find the approximate point of intersection of the surface between two points with the values fValue1 and fValue2.

Parameters:
fValue1 
fValue2 
fValueDesired 
Returns:
offset

Definition at line 395 of file marchingcubes.cpp.

Referenced by marching_cube().

00396 {
00397         float fDelta = fValue2 - fValue1;
00398 
00399         if(fDelta == 0.0f)
00400         {
00401                 return 0.5f;
00402         }
00403         return (fValueDesired - fValue1)/fDelta;
00404 }

int EMAN::MarchingCubes::get_sampling (  )  const [inline, virtual]

Current the current sampling rate Finest sampling is -1.

Implements EMAN::Isosurface.

Definition at line 225 of file marchingcubes.h.

References drawing_level.

00225 { return drawing_level; }

int EMAN::MarchingCubes::get_sampling_range (  )  [inline, virtual]

Get the range of feasible sampling rates.

Implements EMAN::Isosurface.

Definition at line 229 of file marchingcubes.h.

References minvals.

00229 { return minvals.size()-1; }

float EMAN::MarchingCubes::get_surface_value (  )  const [inline, virtual]

Get the current isosurface value being used.

Returns:
the current isosurface value

Implements EMAN::Isosurface.

Definition at line 210 of file marchingcubes.h.

References EMAN::Isosurface::_surf_value.

00210 { return _surf_value; }

void MarchingCubes::marching_cube ( int  fX,
int  fY,
int  fZ,
const int  cur_level 
) [private]

Function for managing cases where a triangles can potentially be rendered Called by draw_cube.

Generates vertices, normals, and keeps track of common points

Parameters:
fX the current x coordinate, relative to cur_level
fY the current y coordinate, relative to cur_level
fZ the current z coordinate, relative to cur_level
cur_level 

Definition at line 413 of file marchingcubes.cpp.

References EMAN::Isosurface::_emdata, EMAN::Isosurface::_surf_value, a2fEdgeDirection, a2fVertexOffset, a2iEdgeConnection, a2iTriangleConnectionTable, aiCubeEdgeFlags, edgeLookUp, EMAN::CustomVector< type >::elem(), ff, get_edge_num(), get_offset(), EMAN::EMData::get_value_at(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), minvals, nn, point_map, pp, EMAN::CustomVector< type >::push_back(), and EMAN::CustomVector< type >::push_back_3().

Referenced by draw_cube().

00414 {
00415         extern int aiCubeEdgeFlags[256];
00416         extern int a2iTriangleConnectionTable[256][16];
00417 
00418         int iCorner, iVertex, iVertexTest, iEdge, iTriangle, iFlagIndex, iEdgeFlags;
00419         float fOffset;
00420         Vector3 sColor;
00421         float afCubeValue[8];
00422         float asEdgeVertex[12][3];
00423         int pointIndex[12];
00424 
00425         int fxScale = 1, fyScale = 1, fzScale = 1;
00426         if ( cur_level != -1 )
00427         {
00428                 fxScale = _emdata->get_xsize()/minvals[cur_level]->get_xsize();
00429                 fyScale = _emdata->get_ysize()/minvals[cur_level]->get_ysize();
00430                 fzScale = _emdata->get_zsize()/minvals[cur_level]->get_zsize();
00431                 for(iVertex = 0; iVertex < 8; iVertex++)
00432                 {
00433                         afCubeValue[iVertex] = _emdata->get_value_at( fxScale*(fX + a2fVertexOffset[iVertex][0]),
00434                                                 fyScale*(fY + a2fVertexOffset[iVertex][1]), fzScale*(fZ + a2fVertexOffset[iVertex][2]));
00435                 }
00436         }
00437         else
00438         {
00439                 //Make a local copy of the values at the cube's corners
00440                 for(iVertex = 0; iVertex < 8; iVertex++)
00441                 {
00442                         afCubeValue[iVertex] = _emdata->get_value_at( fX + a2fVertexOffset[iVertex][0],
00443                                         fY + a2fVertexOffset[iVertex][1], fZ + a2fVertexOffset[iVertex][2]);
00444                 }
00445         }
00446 
00447         //Find which vertices are inside of the surface and which are outside
00448         iFlagIndex = 0;
00449         for(iVertexTest = 0; iVertexTest < 8; iVertexTest++)
00450         {
00451                 if (_surf_value >= 0 ){
00452                         if(afCubeValue[iVertexTest] <= _surf_value)
00453                                 iFlagIndex |= 1<<iVertexTest;
00454                 }
00455                 else {
00456                         if(afCubeValue[iVertexTest] >= _surf_value)
00457                                 iFlagIndex |= 1<<iVertexTest;
00458                 }
00459         }
00460 
00461         //Find which edges are intersected by the surface
00462         iEdgeFlags = aiCubeEdgeFlags[iFlagIndex];
00463 
00464         //If the cube is entirely inside or outside of the surface, then there will be no intersections
00465         if(iEdgeFlags == 0) return;
00466 
00467         //Find the point of intersection of the surface with each edge
00468         //Then find the normal to the surface at those points
00469         for(iEdge = 0; iEdge < 12; iEdge++)
00470         {
00471                 //if there is an intersection on this edge
00472                 if(iEdgeFlags & (1<<iEdge))
00473                 {
00474                         fOffset = get_offset(afCubeValue[ a2iEdgeConnection[iEdge][0] ],
00475                                                                  afCubeValue[ a2iEdgeConnection[iEdge][1] ], _surf_value);
00476 
00477                         if ( cur_level == -1 ){
00478                                 asEdgeVertex[iEdge][0] = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0]  +  fOffset * a2fEdgeDirection[iEdge][0]) + 0.5f;
00479                                 asEdgeVertex[iEdge][1] = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1]  +  fOffset * a2fEdgeDirection[iEdge][1]) + 0.5f;
00480                                 asEdgeVertex[iEdge][2] = fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2]  +  fOffset * a2fEdgeDirection[iEdge][2]) + 0.5f;
00481                         } else {
00482                                 asEdgeVertex[iEdge][0] = fxScale*(fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0]  +  fOffset * a2fEdgeDirection[iEdge][0])) + 0.5f;
00483                                 asEdgeVertex[iEdge][1] = fyScale*(fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1]  +  fOffset * a2fEdgeDirection[iEdge][1])) + 0.5f;
00484                                 asEdgeVertex[iEdge][2] = fzScale*(fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2]  +  fOffset * a2fEdgeDirection[iEdge][2])) + 0.5f;
00485                         }
00486 
00487                         pointIndex[iEdge] = get_edge_num(fX+edgeLookUp[iEdge][0], fY+edgeLookUp[iEdge][1], fZ+edgeLookUp[iEdge][2], edgeLookUp[iEdge][3]);
00488                 }
00489         }
00490 
00491         //Draw the triangles that were found.  There can be up to five per cube
00492         for(iTriangle = 0; iTriangle < 5; iTriangle++)
00493         {
00494                 if(a2iTriangleConnectionTable[iFlagIndex][3*iTriangle] < 0)
00495                         break;
00496 
00497                 float pts[3][3];
00498                 for(iCorner = 0; iCorner < 3; iCorner++)
00499                 {
00500                         iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00501                         memcpy(&pts[iCorner][0],  &asEdgeVertex[iVertex][0], 3*sizeof(float));
00502                 }
00503 
00504                 
00505                 
00506                 float v1[3] = {pts[1][0]-pts[0][0],pts[1][1]-pts[0][1],pts[1][2]-pts[0][2]};
00507                 float v2[3] = {pts[2][0]-pts[1][0],pts[2][1]-pts[1][1],pts[2][2]-pts[1][2]};
00508                 
00509                 float n[3] = { v1[1]*v2[2] - v1[2]*v2[1], v1[2]*v2[0] - v1[0]*v2[2], v1[0]*v2[1] - v1[1]*v2[0] };
00510                 
00511                 for(iCorner = 0; iCorner < 3; iCorner++)
00512                 {
00513                         // Without vertex normalization
00514 //                      iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00515 //                      int ss = pp.elem();
00516 //                      pp.push_back_3(&pts[iCorner][0]);
00517 //                      nn.push_back_3(&n[0]);
00518 //                      ff.push_back(ss);
00519 
00520 //                      With vertex normalization
00521                         iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00522                         map<int,int>::iterator it = point_map.find(pointIndex[iVertex]);
00523                         if ( it == point_map.end() ){
00524                                 int ss = pp.elem();
00525                                 pp.push_back_3(&pts[iCorner][0]);
00526                                 nn.push_back_3(&n[0]);
00527                                 ff.push_back(ss);
00528                                 point_map[pointIndex[iVertex]] = ss;
00529                         } else {
00530                                 int idx = it->second;
00531                                 ff.push_back(idx);
00532                                 nn[idx] += n[0];
00533                                 nn[idx+1] += n[1];
00534                                 nn[idx+2] += n[2];
00535                         }
00536                 }
00537         }
00538 }

void MarchingCubes::set_data ( EMData data  )  [virtual]

Sets Voxel data for Isosurface implementation Calls calculate_min_max_vals which generates the tree of data.

Parameters:
data the emdata object to be rendered in 3D
Exceptions:
ImageDimensionException if the image z dimension is 1

Reimplemented from EMAN::Isosurface.

Definition at line 257 of file marchingcubes.cpp.

References EMAN::Isosurface::_emdata, calculate_min_max_vals(), data, and ImageDimensionException.

Referenced by MarchingCubes().

00258 {
00259         if ( data->get_zsize() == 1 ) throw ImageDimensionException("The z dimension of the image must be greater than 1");
00260         _emdata = data;
00261         calculate_min_max_vals();
00262 }

void EMAN::MarchingCubes::set_sampling ( const int  rate  )  [inline, virtual]

Set sampling rates A smaller value means a finer sampling.

The finest sampling level is -1 Sampling values increment in steps of 1, and a single increment is interpreted as one step up or down the tree stored in minvals and maxvals

Parameters:
rate the tree level to render

Implements EMAN::Isosurface.

Definition at line 220 of file marchingcubes.h.

References drawing_level.

00220 { drawing_level = rate; }

void MarchingCubes::set_surface_value ( const float  value  )  [virtual]

Set Isosurface value.

Parameters:
value the new isosurface value

Implements EMAN::Isosurface.

Definition at line 264 of file marchingcubes.cpp.

References EMAN::Isosurface::_surf_value.

00264                                                        {
00265 
00266         if(_surf_value == value) return;
00267 
00268         _surf_value = value;
00269 
00270 }

void MarchingCubes::surface_face_z (  ) 

Definition at line 226 of file marchingcubes.cpp.

References EMAN::CustomVector< type >::elem(), EMAN::CustomVector< type >::get_data(), nn, EMAN::Vec3< Type >::normalize(), pp, and t.

00227 {
00228         float* f = pp.get_data();
00229         float* n = nn.get_data();
00230         for (unsigned int i = 0; i < pp.elem(); i += 3 ) {
00231                 if (f[i+2] == 0.5) continue;
00232                 Vec3f z(0,0,1.0);
00233                 Vec3f axis(-n[i+1],n[i],0);
00234                 axis.normalize();
00235         
00236                 Dict d;
00237                 d["type"] = "spin";
00238                 d["Omega"] =  90.f;
00239                 d["n1"] = axis[0];
00240                 d["n2"] = axis[1];
00241                 d["n3"] = 0;
00242                 Transform t(d);
00243                 Vec3f delta = t*z;
00244                 
00245                 f[i] += delta[0]*.25f;
00246                 f[i+1] += delta[1]*.25f;
00247                 f[i+2] = 0.5;
00248         }
00249         
00250         for (unsigned int i = 0; i < nn.elem(); i += 3 ) {
00251                 n[i] = 0;
00252                 n[i+1] = 0;
00253                 n[i+2] = 1;
00254         }
00255 }


Friends And Related Function Documentation

friend class GLUtil [friend]

Definition at line 182 of file marchingcubes.h.


Member Data Documentation

unsigned long EMAN::MarchingCubes::_isodl [private]

Definition at line 240 of file marchingcubes.h.

int EMAN::MarchingCubes::drawing_level [private]

The "sampling rate".

Definition at line 259 of file marchingcubes.h.

Referenced by calculate_min_max_vals(), draw_cube(), get_sampling(), and set_sampling().

CustomVector<unsigned int> EMAN::MarchingCubes::ff [private]

Definition at line 317 of file marchingcubes.h.

Referenced by calculate_surface(), get_isosurface(), and marching_cube().

vector<EMData*> EMAN::MarchingCubes::maxvals [private]

Definition at line 256 of file marchingcubes.h.

Referenced by calculate_min_max_vals(), calculate_surface(), clear_min_max_vals(), and draw_cube().

vector<EMData*> EMAN::MarchingCubes::minvals [private]

Vectors for storing the search trees.

Definition at line 256 of file marchingcubes.h.

Referenced by calculate_min_max_vals(), calculate_surface(), clear_min_max_vals(), draw_cube(), get_sampling_range(), and marching_cube().

CustomVector<float> EMAN::MarchingCubes::nn [private]

Definition at line 316 of file marchingcubes.h.

Referenced by calculate_surface(), get_isosurface(), marching_cube(), and surface_face_z().

map<int, int> EMAN::MarchingCubes::point_map [private]

Definition at line 239 of file marchingcubes.h.

Referenced by calculate_surface(), and marching_cube().

CustomVector<float> EMAN::MarchingCubes::pp [private]

.Custom vectors for storing points, normals and faces

Definition at line 315 of file marchingcubes.h.

Referenced by calculate_surface(), get_isosurface(), marching_cube(), and surface_face_z().


The documentation for this class was generated from the following files:
Generated on Tue Jul 12 13:48:25 2011 for EMAN2 by  doxygen 1.4.7