Index: /trunk/gui/vizservers/nanovis/ConvexPolygon.cpp
===================================================================
--- /trunk/gui/vizservers/nanovis/ConvexPolygon.cpp	(revision 414)
+++ /trunk/gui/vizservers/nanovis/ConvexPolygon.cpp	(revision 415)
@@ -25,4 +25,6 @@
 }
 
+void ConvexPolygon::set_id(int v_id) { volume_id; };
+
 void ConvexPolygon::append_vertex(Vector4 vert){
     vertices.push_back(vert);
@@ -105,5 +107,5 @@
 }
 
-void ConvexPolygon::clip(Plane &clipPlane) {
+void ConvexPolygon::clip(Plane &clipPlane, bool copy_to_texcoord) {
 	if (vertices.size() == 0) {
 		//fprintf(stderr, "ConvexPolygon: polygon has no vertices\n");	
@@ -159,4 +161,7 @@
 		    clippedVerts.begin(),
 		    clippedVerts.end());
+
+    if(copy_to_texcoord)
+      copy_vertices_to_texcoords();
 }
 
Index: /trunk/gui/vizservers/nanovis/ConvexPolygon.h
===================================================================
--- /trunk/gui/vizservers/nanovis/ConvexPolygon.h	(revision 414)
+++ /trunk/gui/vizservers/nanovis/ConvexPolygon.h	(revision 415)
@@ -27,4 +27,5 @@
 	VertexVector vertices;
 	TexVector texcoords;
+	int volume_id;	//which volume this polygon slice belongs to
 
 	ConvexPolygon();
@@ -37,8 +38,9 @@
 
 	// Clips the polygon, retaining the portion where ax + by + cz + d >= 0
-	void clip(Plane &clipPlane);
+	void clip(Plane &clipPlane, bool copy_to_texcoords);
 	void Emit(bool use_texture);
 	void Emit(bool use_texture, Vector3& shift, Vector3& scale);
 	void copy_vertices_to_texcoords();
+	void set_id(int v_id);
 };
 
Index: /trunk/gui/vizservers/nanovis/Makefile
===================================================================
--- /trunk/gui/vizservers/nanovis/Makefile	(revision 414)
+++ /trunk/gui/vizservers/nanovis/Makefile	(revision 415)
@@ -20,5 +20,6 @@
 CFLAG = -g -c -Wall $(INCLUDES)
 
-all: nanovis simclient 
+all: nanovis 
+#  simclient 
 
 clean:
@@ -58,7 +59,7 @@
 	gcc -g -o client $(OBJ_CLIENT) $(LIB_CLIENT)
 
-simclient: Event.o nanoscale/EventPlayer.cpp
-	gcc -g $(INCLUDES) $(NANOSCALESRC)/EventPlayer.cpp $(NANOSCALESRC)/clientlib.cpp -o simclient Event.o $(LIB_CLIENT)
-	#g++ -g $(INCLUDES) $(NANOSCALESRC)/EventPlayer.cpp $(NANOSCALESRC)/clientlib.cpp -o simclient Event.o
+#simclient: Event.o $(NANOSCALESRC)/EventPlayer.cpp
+#	gcc -g $(INCLUDES) $(NANOSCALESRC)/EventPlayer.cpp $(NANOSCALESRC)/clientlib.cpp -o simclient Event.o $(LIB_CLIENT)
+#	g++ -g $(INCLUDES) $(NANOSCALESRC)/EventPlayer.cpp $(NANOSCALESRC)/clientlib.cpp -o simclient Event.o
 
 Color.o: Color.cpp Color.h
Index: /trunk/gui/vizservers/nanovis/Plane.h
===================================================================
--- /trunk/gui/vizservers/nanovis/Plane.h	(revision 414)
+++ /trunk/gui/vizservers/nanovis/Plane.h	(revision 415)
@@ -21,5 +21,5 @@
 class Plane {
 public:
-	float a, b, c, d;
+    float a, b, c, d;
 	
     Plane(float a, float b, float c, float d);
Index: /trunk/gui/vizservers/nanovis/VolumeRenderer.cpp
===================================================================
--- /trunk/gui/vizservers/nanovis/VolumeRenderer.cpp	(revision 414)
+++ /trunk/gui/vizservers/nanovis/VolumeRenderer.cpp	(revision 415)
@@ -23,5 +23,7 @@
   cam(_cam),
   n_volumes(0),
-  g_context(_context)
+  g_context(_context),
+  slice_mode(false),
+  volume_mode(true)
 {
   //init the vectors for volumes and transfer functions
@@ -54,5 +56,7 @@
 VolumeRenderer::~VolumeRenderer(){}
 
-void VolumeRenderer::add_volume(Volume* _vol, TransferFunction* _tf, int _slice){
+int VolumeRenderer::add_volume(Volume* _vol, TransferFunction* _tf, int _slice){
+  int ret = n_volumes;
+
   volume.push_back(_vol);
   tf.push_back(_tf);
@@ -61,5 +65,223 @@
 
   n_volumes++;
-}
+
+  return ret;
+}
+
+typedef struct SortElement{
+  float z;
+  int volume_id;
+  int slice_id;
+  SortElement(float _z, int _v, int _s):
+	  z(_z), volume_id(_v), slice_id(_s){}
+};
+
+int slice_sort(const void* a, const void* b){
+  if((*((SortElement*)a)).z > (*((SortElement*)b)).z)
+      return 1;
+   else
+      return -1;
+}
+
+
+void VolumeRenderer::render_all(){
+  int total_enabled_volumes = 0;
+  int total_rendered_slices = 0;
+
+  for(int i=0; i<n_volumes; i++){
+    if(render_bit[i])
+      total_enabled_volumes ++;
+  }
+  fprintf(stderr, "total volumes rendered: %d\n", total_enabled_volumes);
+
+  ConvexPolygon*** polys = new ConvexPolygon**[total_enabled_volumes];
+  int* actual_slices = new int[total_enabled_volumes];
+
+  int cur_index = -1;
+  for(int i=0; i<n_volumes; i++){
+    if(!render_bit[i])
+      continue;
+    cur_index++;
+
+    int volume_index = i;
+    int n_slices = slice[volume_index];
+
+    //volume start location
+    Vector4 shift_4d(volume[volume_index]->location.x, volume[volume_index]->location.y, volume[volume_index]->location.z, 0);
+
+    double x0 = 0;
+    double y0 = 0;
+    double z0 = 0;
+
+    Mat4x4 model_view_no_trans, model_view_trans;
+    Mat4x4 model_view_no_trans_inverse, model_view_trans_inverse;
+
+    double zNear, zFar;
+
+    //initialize volume plane with world coordinates
+    Plane volume_planes[6];
+    volume_planes[0].set_coeffs(1, 0, 0, -x0);
+    volume_planes[1].set_coeffs(-1, 0, 0, x0+1);
+    volume_planes[2].set_coeffs(0, 1, 0, -y0);
+    volume_planes[3].set_coeffs(0, -1, 0, y0+1);
+    volume_planes[4].set_coeffs(0, 0, 1, -z0);
+    volume_planes[5].set_coeffs(0, 0, -1, z0+1);
+  
+    glPushMatrix();
+
+    glScalef(volume[volume_index]->aspect_ratio_width, 
+	  volume[volume_index]->aspect_ratio_height, 
+	  volume[volume_index]->aspect_ratio_depth);
+
+    glEnable(GL_DEPTH_TEST);
+
+    GLfloat mv_no_trans[16];
+    glGetFloatv(GL_MODELVIEW_MATRIX, mv_no_trans);
+
+    model_view_no_trans = Mat4x4(mv_no_trans);
+    model_view_no_trans_inverse = model_view_no_trans.inverse();
+
+    glPopMatrix();
+
+    //get modelview matrix with translation
+    glPushMatrix();
+    glTranslatef(shift_4d.x, shift_4d.y, shift_4d.z);
+    glScalef(volume[volume_index]->aspect_ratio_width, 
+	  volume[volume_index]->aspect_ratio_height, 
+	  volume[volume_index]->aspect_ratio_depth);
+    GLfloat mv_trans[16];
+    glGetFloatv(GL_MODELVIEW_MATRIX, mv_trans);
+
+    model_view_trans = Mat4x4(mv_trans);
+    model_view_trans_inverse = model_view_trans.inverse();
+
+    //draw volume bounding box
+    draw_bounding_box(x0, y0, z0, x0+1, y0+1, z0+1, 0.8, 0.1, 0.1, 1.5);
+    glPopMatrix();
+
+    //transform volume_planes to eye coordinates.
+    for(int i=0; i<6; i++)
+      volume_planes[i].transform(model_view_no_trans);
+
+    get_near_far_z(mv_no_trans, zNear, zFar);
+    //fprintf(stderr, "zNear:%f, zFar:%f\n", zNear, zFar);
+    //fflush(stderr);
+
+    //compute actual rendering slices
+    float z_step = fabs(zNear-zFar)/n_slices;		
+    int n_actual_slices = (int)(fabs(zNear-zFar)/z_step + 1);
+    actual_slices[cur_index] = n_actual_slices;
+    polys[cur_index] = new ConvexPolygon*[n_actual_slices];
+
+    //fprintf(stderr, "slices: %d\n", n_actual_slices);
+    //fflush(stderr);
+
+    float slice_z;
+
+    Vector4 vert1 = (Vector4(-10, -10, -0.5, 1));
+    Vector4 vert2 = (Vector4(-10, +10, -0.5, 1));
+    Vector4 vert3 = (Vector4(+10, +10, -0.5, 1));
+    Vector4 vert4 = (Vector4(+10, -10, -0.5, 1));
+
+    int counter = 0;
+    //transform slices and store them
+    for (int i=0; i<n_actual_slices; i++){
+      slice_z = zFar + i * z_step;	//back to front
+
+      ConvexPolygon *poly = new ConvexPolygon();
+      polys[cur_index][counter] = poly;
+      counter++;
+
+      poly->vertices.clear();
+      poly->set_id(volume_index);
+
+      //Setting Z-coordinate 
+      vert1.z = slice_z;
+      vert2.z = slice_z;
+      vert3.z = slice_z;
+      vert4.z = slice_z;
+		
+      poly->append_vertex(vert1);
+      poly->append_vertex(vert2);
+      poly->append_vertex(vert3);
+      poly->append_vertex(vert4);
+	
+      for(int k=0; k<6; k++){
+        poly->clip(volume_planes[k], true);
+      }
+
+      poly->transform(model_view_no_trans_inverse);
+      poly->transform(model_view_trans);
+
+      if(poly->vertices.size()>=3)
+	total_rendered_slices++; 
+    }
+  } //iterate all volumes
+
+
+  //We sort all the polygons according to their eye-space depth, from farthest to the closest.
+  //This step is critical for correct blending
+
+  SortElement* slices = (SortElement*) malloc(sizeof(SortElement)*total_rendered_slices);
+
+  int counter = 0;
+  for(int i=0; i<total_enabled_volumes; i++){
+    for(int j=0; j<actual_slices[i]; j++){
+      if(polys[i][j]->vertices.size() >= 3){
+        slices[counter] = SortElement(polys[i][j]->vertices[0].z, i, j);
+        counter++;
+      }
+    }
+  }
+
+  //sort them
+  qsort(slices, total_rendered_slices, sizeof(SortElement), slice_sort);
+
+  //debug
+  for(int i=0; i<total_rendered_slices; i++){
+    fprintf(stderr, "%f ", slices[i].z);
+  }
+  fprintf(stderr, "\n\n");
+
+
+  //Now we are ready to render all the slices from back to front
+
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_BLEND);
+
+  for(int i=0; i<total_rendered_slices; i++){
+    int volume_index = slices[i].volume_id;
+    int slice_index = slices[i].slice_id;
+    ConvexPolygon* cur = polys[volume_index][slice_index];
+
+    glPushMatrix();
+    glScalef(volume[volume_index]->aspect_ratio_width, volume[volume_index]->aspect_ratio_height, volume[volume_index]->aspect_ratio_depth);
+    
+    activate_one_volume_shader(volume_index, 1, 1);
+    glPopMatrix();
+
+    glEnable(GL_DEPTH_TEST);
+    glBegin(GL_POLYGON);
+      cur->Emit(true); 
+    glEnd();
+
+    deactivate_one_volume_shader();
+  }
+
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_BLEND);
+
+  //Deallocate all the memory used
+  for(int i=0; i<total_enabled_volumes; i++){
+    for(int j=0; j<actual_slices[i]; j++){
+      delete polys[i][j];
+    }
+    delete[] polys[i];
+  }
+  delete[] polys;
+  delete[] actual_slices;
+  free(slices);
+}
+
 
 void VolumeRenderer::render(int volume_index){
@@ -73,6 +295,6 @@
   double z0 = 0;
 
-  Mat4x4 model_view;
-  Mat4x4 model_view_inverse;
+  Mat4x4 model_view_no_trans, model_view_trans;
+  Mat4x4 model_view_no_trans_inverse, model_view_trans_inverse;
 
   double zNear, zFar;
@@ -80,5 +302,4 @@
   //initialize volume plane with world coordinates
   Plane volume_planes[6];
-
   volume_planes[0].set_coeffs(1, 0, 0, -x0);
   volume_planes[1].set_coeffs(-1, 0, 0, x0+1);
@@ -87,5 +308,5 @@
   volume_planes[4].set_coeffs(0, 0, 1, -z0);
   volume_planes[5].set_coeffs(0, 0, -1, z0+1);
-
+  
   glPushMatrix();
 
@@ -96,20 +317,33 @@
   glEnable(GL_DEPTH_TEST);
 
+  GLfloat mv_no_trans[16];
+  glGetFloatv(GL_MODELVIEW_MATRIX, mv_no_trans);
+
+  model_view_no_trans = Mat4x4(mv_no_trans);
+  model_view_no_trans_inverse = model_view_no_trans.inverse();
+
+  glPopMatrix();
+
+  //get modelview matrix with translation
+  glPushMatrix();
+  glTranslatef(shift_4d.x, shift_4d.y, shift_4d.z);
+  glScalef(volume[volume_index]->aspect_ratio_width, 
+	  volume[volume_index]->aspect_ratio_height, 
+	  volume[volume_index]->aspect_ratio_depth);
+  GLfloat mv_trans[16];
+  glGetFloatv(GL_MODELVIEW_MATRIX, mv_trans);
+
+  model_view_trans = Mat4x4(mv_trans);
+  model_view_trans_inverse = model_view_trans.inverse();
+
   //draw volume bounding box
-  draw_bounding_box(x0+shift_4d.x, y0+shift_4d.y, z0+shift_4d.z, x0+shift_4d.x+1, y0+shift_4d.y+1, z0+shift_4d.z+1, 0.8, 0.1, 0.1, 1.5);
-
-  GLfloat mv[16];
-  glGetFloatv(GL_MODELVIEW_MATRIX, mv);
-
-  model_view = Mat4x4(mv);
-  model_view_inverse = model_view.inverse();
-
+  draw_bounding_box(x0, y0, z0, x0+1, y0+1, z0+1, 0.8, 0.1, 0.1, 1.5);
   glPopMatrix();
 
   //transform volume_planes to eye coordinates.
   for(int i=0; i<6; i++)
-    volume_planes[i].transform(model_view);
-
-  get_near_far_z(mv, zNear, zFar);
+    volume_planes[i].transform(model_view_no_trans);
+
+  get_near_far_z(mv_no_trans, zNear, zFar);
   //fprintf(stderr, "zNear:%f, zFar:%f\n", zNear, zFar);
   //fflush(stderr);
@@ -129,6 +363,9 @@
   Vector4 vert4 = (Vector4(+10, -10, -0.5, 1));
 
-  glEnable(GL_DEPTH_TEST);
   glEnable(GL_BLEND);
+
+#if 0
+  if(slice_mode){
+    glEnable(GL_DEPTH_TEST);
 
   //render the cut planes
@@ -171,8 +408,7 @@
 
     for(int k=0; k<6; k++){
-      poly->clip(volume_planes[k]);
-    }
-
-    poly->copy_vertices_to_texcoords();
+      poly->clip(volume_planes[k], true);
+    }
+
     poly->transform(model_view_inverse);
     poly->translate(shift_4d);
@@ -182,15 +418,27 @@
     glScalef(volume[volume_index]->aspect_ratio_width, volume[volume_index]->aspect_ratio_height, volume[volume_index]->aspect_ratio_depth);
 
-    activate_one_volume_shader(volume_index, 1, 1);
+    //activate_one_volume_shader(volume_index, 1, 1);
     glPopMatrix();
 
-    glBegin(GL_POLYGON);
-      poly->Emit(true); 
+    glDisable(GL_TEXTURE_3D);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glColor3f(1,1,1);
+
+    //glBegin(GL_POLYGON);
+    glBegin(GL_LINE_LOOP);
+      //poly->Emit(true); 
+      poly->Emit(false); 
     glEnd();
 
-    deactivate_one_volume_shader();
-  }
-
-#if 1 
+    //deactivate_one_volume_shader();
+  }
+  } //slice_mode
+
+#endif
+
+  if(volume_mode){ 
+  glEnable(GL_DEPTH_TEST);
+
   for (int i=0; i<n_actual_slices; i++){
     slice_z = zFar + i * z_step;	//back to front
@@ -212,23 +460,19 @@
 	
     for(int k=0; k<6; k++){
-      poly->clip(volume_planes[k]);
-    }
-
-    poly->copy_vertices_to_texcoords();
+      poly->clip(volume_planes[k], true);
+    }
+
     //move the volume to the proper location
-
-    poly->transform(model_view_inverse);
-    poly->translate(shift_4d);
-    poly->transform(model_view);
+    //poly->transform(model_view_inverse);
+    //poly->translate(shift_4d);
+    //poly->transform(model_view);
+
+    poly->transform(model_view_no_trans_inverse);
+    poly->transform(model_view_trans);
 
     glPushMatrix();
     glScalef(volume[volume_index]->aspect_ratio_width, volume[volume_index]->aspect_ratio_height, volume[volume_index]->aspect_ratio_depth);
     
-    //glPushMatrix();
-    //glMatrixMode(GL_MODELVIEW);
-    //glLoadIdentity();
-    //glScaled(volume[volume_index]->aspect_ratio_width, volume[volume_index]->aspect_ratio_height, volume[volume_index]->aspect_ratio_depth);
-
-    /*
+   /* 
     //draw slice lines only
     glDisable(GL_BLEND);
@@ -252,5 +496,5 @@
 		
   }
-#endif
+  } //volume_mode
 
   glDisable(GL_BLEND);
@@ -378,3 +622,7 @@
 void VolumeRenderer::set_diffuse(float val){ live_diffuse = val; }
 
-
+void VolumeRenderer::set_slice_mode(bool val) { slice_mode = val; }
+void VolumeRenderer::set_volume_mode(bool val) { volume_mode = val; }
+void VolumeRenderer::switch_slice_mode() { slice_mode = (!slice_mode); }
+void VolumeRenderer::switch_volume_mode() { volume_mode = (!volume_mode); }
+
Index: /trunk/gui/vizservers/nanovis/VolumeRenderer.h
===================================================================
--- /trunk/gui/vizservers/nanovis/VolumeRenderer.h	(revision 414)
+++ /trunk/gui/vizservers/nanovis/VolumeRenderer.h	(revision 415)
@@ -50,4 +50,7 @@
   float live_specular;
 
+  bool slice_mode;	//enable cut planes
+  bool volume_mode;	//enable full volume rendering
+
   //cg related
   CGcontext g_context;		//the Nvidia cg context 
@@ -78,11 +81,16 @@
   ~VolumeRenderer();
 
-  void add_volume(Volume* _vol, TransferFunction* _tf, int _slice); 
+  int add_volume(Volume* _vol, TransferFunction* _tf, int _slice); 
   						//add a volume and its transfer function
   						//we require a transfer function when a 
 						//volume is added.
   void render(int volume_index);
+  void render_all();	//render all enabled volumes;
   void set_specular(float val);
   void set_diffuse(float val);
+  void set_slice_mode(bool val); //control independently.
+  void set_volume_mode(bool val);
+  void switch_slice_mode(); //switch_cutplane_mode
+  void switch_volume_mode();
 };
 
Index: /trunk/gui/vizservers/nanovis/nanovis.cpp
===================================================================
--- /trunk/gui/vizservers/nanovis/nanovis.cpp	(revision 414)
+++ /trunk/gui/vizservers/nanovis/nanovis.cpp	(revision 415)
@@ -862,4 +862,6 @@
    load_vector_file(0, "./data/J-wire-vec.dx");
    load_volume_file(1, "./data/mu-wire-3d.dx");
+   load_volume_file(2, "./data/mu-wire-3d.dx");
+   load_volume_file(3, "./data/mu-wire-3d.dx");
 
    init_tf();   //initialize transfer function
@@ -870,4 +872,9 @@
    //create volume renderer
    vol_render = new VolumeRenderer(cam, volume[1], tf[0], g_context);
+   vol_render->add_volume(volume[2], tf[0], 256);
+   volume[2]->location =Vector3(0.42, 0.1, 0.1);
+   vol_render->add_volume(volume[3], tf[0], 256);
+   volume[3]->location =Vector3(0.2, -0.1, -0.1);
+
    
    psys = new ParticleSystem(NMESH, NMESH, g_context, volume[0]->id,
@@ -1470,12 +1477,6 @@
 
    perf->enable();
-     //render volume :0 
-     //volume[0]->location =Vector3(0.,0.,0.);
-     //render_volume(0, 256);
-
-     //render volume :1
-     volume[1]->location =Vector3(0., 0., 0.);
-     //render_volume(1, 256);
-     vol_render->render(0);
+     //vol_render->render(0);
+     vol_render->render_all();
 
      //fprintf(stderr, "%lf\n", get_time_interval());
@@ -1639,4 +1640,10 @@
 		vol_render->set_diffuse(live_diffuse);
 		break;
+	case 'v':
+		vol_render->switch_volume_mode();
+		break;
+	case 'b':
+		vol_render->switch_slice_mode();
+		break;
 
 	default:
Index: /trunk/gui/vizservers/nanovis/shaders/one_volume.cg
===================================================================
--- /trunk/gui/vizservers/nanovis/shaders/one_volume.cg	(revision 414)
+++ /trunk/gui/vizservers/nanovis/shaders/one_volume.cg	(revision 415)
@@ -18,5 +18,5 @@
 
 
-#define PHONG_SHADING
+//#define PHONG_SHADING
 
 PixelOut main(v2f IN, /* uniform sampler1D tf,*/
@@ -49,5 +49,6 @@
       //sample the transfer function texture
       float4 color = tex1D(tf, sample.x);
-      color.w = renderParameters.y*color.w/renderParameters.x;
+      //color.w = renderParameters.y*color.w/renderParameters.x;
+      //color.w = 0.5;
 
       //float4 color = float4(sample.x, 0, 0, 1);
