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 438 of file marchingcubes.cpp.

00439         : _isodl(0)
00440 {
00441 }

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 443 of file marchingcubes.cpp.

References set_data().

00444         : _isodl(0)
00445 {
00446         set_data(em);
00447 }

MarchingCubes::~MarchingCubes (  )  [virtual]

Definition at line 505 of file marchingcubes.cpp.

References clear_min_max_vals().

00505                               {
00506         clear_min_max_vals();
00507 }


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 464 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().

00465 {
00466 
00467         if (_emdata == NULL ) throw NullPointerException("Error, cannot generate search tree if the overriding EMData object is NULL");
00468 
00469         clear_min_max_vals();
00470 
00471         int nx = _emdata->get_xsize();
00472         int ny = _emdata->get_ysize();
00473         int nz = _emdata->get_zsize();
00474 
00475         // Create the binary min max tree
00476         while ( nx > 1 || ny > 1 || nz > 1 )
00477         {
00478                 int size = minvals.size();
00479 
00480                 if ( size == 0 ){
00481                         Dict a;
00482                         // Setting search to 3 at the bottom level is most important.
00483                         // FIXME - d.woolford add comments heere
00484                         a["search"] = 3;
00485                         minvals.push_back(_emdata->process("math.minshrink",a));
00486                         maxvals.push_back(_emdata->process("math.maxshrink",a));
00487                 }else {
00488                         minvals.push_back(minvals[size-1]->process("math.minshrink"));
00489                         maxvals.push_back(maxvals[size-1]->process("math.maxshrink"));
00490                 }
00491 
00492                 nx = minvals[size]->get_xsize();
00493                 ny = minvals[size]->get_ysize();
00494                 nz = minvals[size]->get_zsize();
00495 #if MARCHING_CUBES_DEBUG
00496                 cout << "dims are " << nx << " " << ny << " " << nz << endl;
00497 #endif
00498         }
00499 
00500         drawing_level = -1;
00501 
00502         return true;
00503 }

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 567 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().

00567                                       {
00568 
00569         if ( _emdata == 0 ) throw NullPointerException("Error, attempt to generate isosurface, but the emdata image object has not been set");
00570         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");
00571 
00572         point_map.clear();
00573         pp.clear();
00574         nn.clear();
00575         ff.clear();
00576 
00577 #if MARCHING_CUBES_DEBUG
00578         int time0 = clock();
00579 #endif
00580 
00581         float min = minvals[minvals.size()-1]->get_value_at(0,0,0);
00582         float max = maxvals[minvals.size()-1]->get_value_at(0,0,0);
00583         if ( min < _surf_value &&  max > _surf_value) draw_cube(0,0,0,minvals.size()-1);
00584 
00585 #if MARCHING_CUBES_DEBUG
00586         int time1 = clock();
00587         cout << "It took " << (time1-time0) << " " << (float)(time1-time0)/CLOCKS_PER_SEC << " to traverse the search tree and generate polygons" << endl;
00588         cout << "... using surface value " << _surf_value << endl;
00589 #endif
00590 }

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 449 of file marchingcubes.cpp.

References maxvals, and minvals.

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

00450 {
00451         for (vector<EMData*>::iterator it = minvals.begin(); it != minvals.end(); ++it)
00452         {
00453                 if ( (*it) != 0 ) delete *it;
00454         }
00455         minvals.clear();
00456 
00457         for (vector<EMData*>::iterator it = maxvals.begin(); it != maxvals.end(); ++it)
00458         {
00459                 if ( (*it) != 0 ) delete *it;
00460         }
00461         maxvals.clear();
00462 }

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 592 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().

00592                                                                                          {
00593 
00594         if ( cur_level == drawing_level )
00595         {
00596                 EMData* e;
00597                 if ( drawing_level == - 1 ) e = _emdata;
00598                 else e = minvals[drawing_level];
00599                 if ( x < (e->get_xsize()-1) && y < (e->get_ysize()-1) && z < (e->get_zsize()-1))
00600                         marching_cube(x,y,z, cur_level);
00601         }
00602         else
00603         {
00604                 EMData* e;
00605                 if ( cur_level > 0 ) {
00606                         int xsize = minvals[cur_level-1]->get_xsize();
00607                         int ysize = minvals[cur_level-1]->get_ysize();
00608                         int zsize = minvals[cur_level-1]->get_zsize();
00609                         e = minvals[cur_level-1];
00610                         for(int i=0; i<8; ++i ) {
00611                                 int xx = 2*x+a2fVertexOffset[i][0];
00612                                 if ( xx >= xsize ) continue;
00613                                 int yy = 2*y+a2fVertexOffset[i][1];
00614                                 if ( yy >= ysize ) continue;
00615                                 int zz = 2*z+a2fVertexOffset[i][2];
00616                                 if ( zz >= zsize ) continue;
00617 
00618                                 float min = minvals[cur_level-1]->get_value_at(xx,yy,zz);
00619                                 float max = maxvals[cur_level-1]->get_value_at(xx,yy,zz);
00620                                 if ( min < _surf_value &&  max > _surf_value)
00621                                         draw_cube(xx,yy,zz,cur_level-1);
00622                         }
00623                 }
00624                 else {
00625                         e = _emdata;
00626                         for(int i=0; i<8; ++i ) {
00627                                         draw_cube(2*x+a2fVertexOffset[i][0],2*y+a2fVertexOffset[i][1],2*z+a2fVertexOffset[i][2],cur_level-1);
00628                         }
00629                 }
00630 
00631                 if ( x == (minvals[cur_level]->get_xsize()-1) ) {
00632                         if ( e->get_xsize() > 2*x ){
00633                                 for(int i=0; i<4; ++i ) {
00634                                         draw_cube(2*x+a2fPosXOffset[i][0],2*y+a2fPosXOffset[i][1],2*z+a2fPosXOffset[i][2],cur_level-1);
00635                                 }
00636                         }
00637                         if ( y == (minvals[cur_level]->get_ysize()-1) ) {
00638                                 if ( e->get_ysize() > 2*y ) {
00639                                         for(int i=0; i<2; ++i ) {
00640                                                 draw_cube(2*x+a2fPosXPosYOffset[i][0],2*y+a2fPosXPosYOffset[i][1],2*z+a2fPosXPosYOffset[i][2],cur_level-1);
00641                                         }
00642                                 }
00643                                 if (  z == (minvals[cur_level]->get_zsize()-1) ){
00644                                         if ( e->get_zsize() > 2*z ) {
00645                                                 draw_cube(2*x+2,2*y+2,2*z+2,cur_level-1);
00646                                         }
00647                                 }
00648                         }
00649                         if ( z == (minvals[cur_level]->get_zsize()-1) ) {
00650                                 if ( e->get_zsize() > 2*z ) {
00651                                         for(int i=0; i<2; ++i ) {
00652                                                 draw_cube(2*x+a2fPosXPosZOffset[i][0],2*y+a2fPosXPosZOffset[i][1],2*z+a2fPosXPosZOffset[i][2],cur_level-1);
00653                                         }
00654                                 }
00655                         }
00656                 }
00657                 if ( y == (minvals[cur_level]->get_ysize()-1) ) {
00658                         if ( e->get_ysize() > 2*y ) {
00659                                 for(int i=0; i<4; ++i ) {
00660                                         draw_cube(2*x+a2fPosYOffset[i][0],2*y+a2fPosYOffset[i][1],2*z+a2fPosYOffset[i][2],cur_level-1);
00661                                 }
00662                         }
00663                         if ( z == (minvals[cur_level]->get_ysize()-1) ) {
00664                                 if ( e->get_zsize() > 2*z ) {
00665                                         for(int i=0; i<2; ++i ) {
00666                                                 draw_cube(2*x+a2fPosYPosZOffset[i][0],2*y+a2fPosYPosZOffset[i][1],2*z+a2fPosYPosZOffset[i][2],cur_level-1);
00667                                         }
00668                                 }
00669                         }
00670                 }
00671                 if ( z == (minvals[cur_level]->get_zsize()-1) ) {
00672                         if ( e->get_zsize() > 2*z ) {
00673                                 for(int i=0; i<4; ++i ) {
00674                                         draw_cube(2*x+a2fPosZOffset[i][0],2*y+a2fPosZOffset[i][1],2*z+a2fPosZOffset[i][2],cur_level-1);
00675                                 }
00676                         }
00677                 }
00678 
00679         }
00680 }

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

Get edge num needs better commenting.

Definition at line 701 of file marchingcubes.cpp.

Referenced by marching_cube().

00701                                                              {
00702         // edge direction is right, down, back (x, y, z)
00703         unsigned int index = 0;
00704         index = (x << 22) | (y << 12) | (z << 2) | edge;
00705         return index;
00706 }

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 509 of file marchingcubes.cpp.

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

00510 {
00511         calculate_surface();
00512         Dict d;
00513         d.put("points", (float*)pp.get_data());
00514         for (unsigned int i = 0; i < ff.elem(); ++i ) ff[i] /= 3;
00515         d.put("faces", (unsigned int*)ff.get_data());
00516         d.put("normals", (float*)nn.get_data());
00517         d.put("size", ff.elem());
00518         return d;
00519 }

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 682 of file marchingcubes.cpp.

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

00683 {
00684         normal[0] = _emdata->get_value_at(fX-1, fY, fZ) - _emdata->get_value_at(fX+1, fY, fZ);
00685     normal[1] = _emdata->get_value_at(fX, fY-1, fZ) - _emdata->get_value_at(fX, fY+1, fZ);
00686     normal[2] = _emdata->get_value_at(fX, fY, fZ-1) - _emdata->get_value_at(fX, fY, fZ+1);
00687     normal.normalize();
00688 }

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 690 of file marchingcubes.cpp.

Referenced by marching_cube().

00691 {
00692         float fDelta = fValue2 - fValue1;
00693 
00694         if(fDelta == 0.0f)
00695         {
00696                 return 0.5f;
00697         }
00698         return (fValueDesired - fValue1)/fDelta;
00699 }

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 708 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().

00709 {
00710 //      extern int aiCubeEdgeFlags[256];
00711 //      extern int a2iTriangleConnectionTable[256][16];
00712 
00713         int iCorner, iVertex, iVertexTest, iEdge, iTriangle, iFlagIndex, iEdgeFlags;
00714         float fOffset;
00715         Vector3 sColor;
00716         float afCubeValue[8];
00717         float asEdgeVertex[12][3];
00718         int pointIndex[12];
00719 
00720         int fxScale = 1, fyScale = 1, fzScale = 1;
00721         if ( cur_level != -1 )
00722         {
00723                 fxScale = _emdata->get_xsize()/minvals[cur_level]->get_xsize();
00724                 fyScale = _emdata->get_ysize()/minvals[cur_level]->get_ysize();
00725                 fzScale = _emdata->get_zsize()/minvals[cur_level]->get_zsize();
00726                 for(iVertex = 0; iVertex < 8; iVertex++)
00727                 {
00728                         afCubeValue[iVertex] = _emdata->get_value_at( fxScale*(fX + a2fVertexOffset[iVertex][0]),
00729                                                 fyScale*(fY + a2fVertexOffset[iVertex][1]), fzScale*(fZ + a2fVertexOffset[iVertex][2]));
00730                 }
00731         }
00732         else
00733         {
00734                 //Make a local copy of the values at the cube's corners
00735                 for(iVertex = 0; iVertex < 8; iVertex++)
00736                 {
00737                         afCubeValue[iVertex] = _emdata->get_value_at( fX + a2fVertexOffset[iVertex][0],
00738                                         fY + a2fVertexOffset[iVertex][1], fZ + a2fVertexOffset[iVertex][2]);
00739                 }
00740         }
00741 
00742         //Find which vertices are inside of the surface and which are outside
00743         iFlagIndex = 0;
00744         for(iVertexTest = 0; iVertexTest < 8; iVertexTest++)
00745         {
00746                 if (_surf_value >= 0 ){
00747                         if(afCubeValue[iVertexTest] <= _surf_value)
00748                                 iFlagIndex |= 1<<iVertexTest;
00749                 }
00750                 else {
00751                         if(afCubeValue[iVertexTest] >= _surf_value)
00752                                 iFlagIndex |= 1<<iVertexTest;
00753                 }
00754         }
00755 
00756         //Find which edges are intersected by the surface
00757         iEdgeFlags = aiCubeEdgeFlags[iFlagIndex];
00758 
00759         //If the cube is entirely inside or outside of the surface, then there will be no intersections
00760         if(iEdgeFlags == 0) return;
00761 
00762         //Find the point of intersection of the surface with each edge
00763         //Then find the normal to the surface at those points
00764         for(iEdge = 0; iEdge < 12; iEdge++)
00765         {
00766                 //if there is an intersection on this edge
00767                 if(iEdgeFlags & (1<<iEdge))
00768                 {
00769                         fOffset = get_offset(afCubeValue[ a2iEdgeConnection[iEdge][0] ],
00770                                                                  afCubeValue[ a2iEdgeConnection[iEdge][1] ], _surf_value);
00771 
00772                         if ( cur_level == -1 ){
00773                                 asEdgeVertex[iEdge][0] = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0]  +  fOffset * a2fEdgeDirection[iEdge][0]) + 0.5f;
00774                                 asEdgeVertex[iEdge][1] = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1]  +  fOffset * a2fEdgeDirection[iEdge][1]) + 0.5f;
00775                                 asEdgeVertex[iEdge][2] = fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2]  +  fOffset * a2fEdgeDirection[iEdge][2]) + 0.5f;
00776                         } else {
00777                                 asEdgeVertex[iEdge][0] = fxScale*(fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0]  +  fOffset * a2fEdgeDirection[iEdge][0])) + 0.5f;
00778                                 asEdgeVertex[iEdge][1] = fyScale*(fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1]  +  fOffset * a2fEdgeDirection[iEdge][1])) + 0.5f;
00779                                 asEdgeVertex[iEdge][2] = fzScale*(fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2]  +  fOffset * a2fEdgeDirection[iEdge][2])) + 0.5f;
00780                         }
00781 
00782                         pointIndex[iEdge] = get_edge_num(fX+edgeLookUp[iEdge][0], fY+edgeLookUp[iEdge][1], fZ+edgeLookUp[iEdge][2], edgeLookUp[iEdge][3]);
00783                 }
00784         }
00785 
00786         //Draw the triangles that were found.  There can be up to five per cube
00787         for(iTriangle = 0; iTriangle < 5; iTriangle++)
00788         {
00789                 if(a2iTriangleConnectionTable[iFlagIndex][3*iTriangle] < 0)
00790                         break;
00791 
00792                 float pts[3][3];
00793                 for(iCorner = 0; iCorner < 3; iCorner++)
00794                 {
00795                         iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00796                         memcpy(&pts[iCorner][0],  &asEdgeVertex[iVertex][0], 3*sizeof(float));
00797                 }
00798 
00799                 
00800                 
00801                 float v1[3] = {pts[1][0]-pts[0][0],pts[1][1]-pts[0][1],pts[1][2]-pts[0][2]};
00802                 float v2[3] = {pts[2][0]-pts[1][0],pts[2][1]-pts[1][1],pts[2][2]-pts[1][2]};
00803                 
00804                 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] };
00805                 
00806                 for(iCorner = 0; iCorner < 3; iCorner++)
00807                 {
00808                         // Without vertex normalization
00809 //                      iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00810 //                      int ss = pp.elem();
00811 //                      pp.push_back_3(&pts[iCorner][0]);
00812 //                      nn.push_back_3(&n[0]);
00813 //                      ff.push_back(ss);
00814 
00815 //                      With vertex normalization
00816                         iVertex = a2iTriangleConnectionTable[iFlagIndex][3*iTriangle+iCorner];
00817                         map<int,int>::iterator it = point_map.find(pointIndex[iVertex]);
00818                         if ( it == point_map.end() ){
00819                                 int ss = pp.elem();
00820                                 pp.push_back_3(&pts[iCorner][0]);
00821                                 nn.push_back_3(&n[0]);
00822                                 ff.push_back(ss);
00823                                 point_map[pointIndex[iVertex]] = ss;
00824                         } else {
00825                                 int idx = it->second;
00826                                 ff.push_back(idx);
00827                                 nn[idx] += n[0];
00828                                 nn[idx+1] += n[1];
00829                                 nn[idx+2] += n[2];
00830                         }
00831                 }
00832         }
00833 }

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 552 of file marchingcubes.cpp.

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

Referenced by MarchingCubes().

00553 {
00554         if ( data->get_zsize() == 1 ) throw ImageDimensionException("The z dimension of the image must be greater than 1");
00555         _emdata = data;
00556         calculate_min_max_vals();
00557 }

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 559 of file marchingcubes.cpp.

References EMAN::Isosurface::_surf_value.

00559                                                        {
00560 
00561         if(_surf_value == value) return;
00562 
00563         _surf_value = value;
00564 
00565 }

void MarchingCubes::surface_face_z (  ) 

Definition at line 521 of file marchingcubes.cpp.

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

00522 {
00523         float* f = pp.get_data();
00524         float* n = nn.get_data();
00525         for (unsigned int i = 0; i < pp.elem(); i += 3 ) {
00526                 if (f[i+2] == 0.5) continue;
00527                 Vec3f z(0,0,1.0);
00528                 Vec3f axis(-n[i+1],n[i],0);
00529                 axis.normalize();
00530         
00531                 Dict d;
00532                 d["type"] = "spin";
00533                 d["Omega"] =  90.f;
00534                 d["n1"] = axis[0];
00535                 d["n2"] = axis[1];
00536                 d["n3"] = 0;
00537                 Transform t(d);
00538                 Vec3f delta = t*z;
00539                 
00540                 f[i] += delta[0]*.25f;
00541                 f[i+1] += delta[1]*.25f;
00542                 f[i+2] = 0.5;
00543         }
00544         
00545         for (unsigned int i = 0; i < nn.elem(); i += 3 ) {
00546                 n[i] = 0;
00547                 n[i+1] = 0;
00548                 n[i+2] = 1;
00549         }
00550 }


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 Thu Nov 17 12:45:41 2011 for EMAN2 by  doxygen 1.4.7