import vtk.util.VtkPanelContainer;
import vtk.util.VtkPanelUtil;
import vtk.util.VtkUtil;
import vtk.*;

import javax.swing.*;
import java.awt.*;

/**
 * This example reads a volume dataset, extracts an isosurface that
 * represents the skin and displays it.
 */
public class Medical1 extends JComponent implements VtkPanelContainer {

  private vtkPanel renWin;

  public Medical1() {
 
    renWin = new vtkPanel();

    vtkVolume16Reader v16 = new vtkVolume16Reader();
    v16.SetDataDimensions(64, 64);
    v16.SetDataByteOrderToLittleEndian();
    v16.SetFilePrefix(VtkUtil.getVtkDataRoot() + "/Data/headsq/quarter");
    v16.SetImageRange(1, 93);
    v16.SetDataSpacing(3.2, 3.2, 1.5);
    
    vtkImageData img = v16.GetOutput();
    
    vtkImageData img2 = this.byteToData(this.dataToByte(img));

    vtkContourFilter skinExtractor = new vtkContourFilter();
    skinExtractor.SetInput(img2);
    skinExtractor.SetValue(0, 500);
    vtkPolyDataNormals skinNormals = new vtkPolyDataNormals();
    skinNormals.SetInput(skinExtractor.GetOutput());
    skinNormals.SetFeatureAngle(60.0);
    vtkPolyDataMapper skinMapper = new vtkPolyDataMapper();
    skinMapper.SetInput(skinNormals.GetOutput());
    skinMapper.ScalarVisibilityOff();
    vtkActor skin = new vtkActor();
    skin.SetMapper(skinMapper);
   
    vtkOutlineFilter outlineData = new vtkOutlineFilter();
    outlineData.SetInput(v16.GetOutput());
    vtkPolyDataMapper mapOutline = new vtkPolyDataMapper();
    mapOutline.SetInput(outlineData.GetOutput());
    vtkActor outline = new vtkActor();
    outline.SetMapper(mapOutline);
    outline.GetProperty().SetColor(0, 0, 0);
    
    vtkCamera aCamera = new vtkCamera();
    aCamera.SetViewUp(0, 0, -1);
    aCamera.SetPosition(0, 1, 0);
    aCamera.SetFocalPoint(0, 0, 0);
    aCamera.ComputeViewPlaneNormal();

    renWin.GetRenderer().AddActor(outline);
    renWin.GetRenderer().AddActor(skin);
    renWin.GetRenderer().SetActiveCamera(aCamera);
    renWin.GetRenderer().ResetCamera();
    aCamera.Dolly(1.5);

    renWin.GetRenderer().SetBackground(1, 1, 1);
    VtkPanelUtil.setSize(renWin, 640, 480);

    renWin.GetRenderer().ResetCameraClippingRange();

    setLayout(new BorderLayout());
    add(renWin, BorderLayout.CENTER);
  }
  
  private int xsize; 
  private int ysize; 
  private int zsize; 
  private int xmin;
  private int ymin; 
  private int zmin; 
  private int xmax; 
  private int ymax; 
  private int zmax;
  private double xorigin;
  private double yorigin;
  private double zorigin;
  private double xspacing;
  private double yspacing;
  private double zspacing;
  
  public byte[] dataToByte(vtkImageData image){
  	
	System.out.println("fction dataTOBYTe");
	
  	byte[] tab; 
	
	int[] dims = image.GetDimensions();
	
	xsize = dims[0];
	ysize = dims[1];
	zsize = dims[2];
	
	tab = new byte[dims[0]*dims[1]*dims[2]];
	
	int[] extent = image.GetExtent();
	
	xmin = extent[0];
	xmax = extent[1];
	ymin = extent[2];
	ymax = extent[3];
	zmin = extent[4];
	zmax = extent[5];
	
	int nbScalarComponent = image.GetNumberOfScalarComponents();
	
	double[] origin = image.GetOrigin();
	
	xorigin = origin[0];
	yorigin = origin[1];
	zorigin = origin[2];
	
	double[] spacing = image.GetSpacing();
	
	xspacing = spacing[0];
	yspacing = spacing[1];
	zspacing = spacing[2];
	
	
	vtkDataArray scalars = new vtkDataArray();
		
	scalars=image.GetPointData().GetScalars();  	
	
	int index = 0;
		for ( int x = 0; x < dims[0]; x++ )
		{
			for ( int y = 0; y < dims[1]; y++ )
			{
				for ( int z = 0; z < dims[2]; z++ )
				{
					tab[index] = (byte)scalars.GetComponent(index, 0);
					index++;
				}
			}
		}
	
	int ms = image.GetActualMemorySize();
	int es = image.GetEstimatedMemorySize();
	
	System.out.println("actual memory size = " + ms + "  estimated memorysize = " + es + "   " + xmin + xmax );
	
	return tab;
  	}	
  
  public vtkImageData byteToData( byte[] data)
	{
	
	System.out.println("fction bytetodata");
	
		vtkImageData image = new vtkImageData();
		image.SetDimensions( xsize, ysize, zsize );
		image.SetExtent( xmin, xmax, ymin, ymax, zmin, zmax );
		image.SetNumberOfScalarComponents( 1 );
		image.SetOrigin( xorigin, yorigin, zorigin );
		image.SetSpacing( xspacing, yspacing, zspacing );
		image.SetScalarType( 3 ); 
		
		vtkDataArray scalars = new vtkDataArray();
		//vtkUnsignedCharArray scalars = new vtkUnsignedCharArray();
		//scalars.SetNumberOfComponents(1);
		//scalars.SetDataTypeToUnsignedChar();

		int index = 0;
		for ( int x = 0; x < xsize; x++ )
		{
			for ( int y = 0; y < ysize; y++ )
			{
				for ( int z = 0; z < zsize; z++ )
				{
					scalars.SetComponent(index, 0, data[ index ] );
					index++;
				}
			}
		}
		image.GetPointData().SetScalars( scalars );

		return image;
	}

  public vtkPanel getRenWin() {
    return renWin;
  }

  public static void main(String s[]) {
    Medical1 panel = new Medical1();

    JFrame frame = new JFrame("Medical1");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add("Center", panel);
    frame.pack();
    frame.setVisible(true);
  }
}