import sys
import vtk
from PyQt4 import QtCore, QtGui
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from gui import Ui_MainWindow
import math
class MainWindow(QtGui.QMainWindow):



    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self, parent)
        
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        self.ui.tableWidget_2.setColumnCount(3)
        self.ui.ren = vtk.vtkRenderer()
        self.ui.qvtkWidget.GetRenderWindow().AddRenderer(self.ui.ren)
        self.ui.iren = self.ui.qvtkWidget.GetRenderWindow().GetInteractor()      
        self.ui.iren.Initialize()

# Rendering of the whole volume
        self.ui.reader1 = vtk.vtkStructuredPointsReader()
        self.ui.reader1.SetFileName("result4.vtk")
        self.ui.reader2 = vtk.vtkStructuredPointsReader()
        self.ui.reader2.SetFileName("result5.vtk")
        self.ui.reader3 = vtk.vtkStructuredPointsReader()
        self.ui.reader3.SetFileName("result6.vtk")


        color = vtk.vtkColorTransferFunction()
        color.AddRGBPoint(0, 0.32, 0.34, 0.43)
        color.AddRGBPoint(43, 0, 0, 1)
        color.AddRGBPoint(87, 0, 1, 1)
        color.AddRGBPoint(127, 0, 1, 0)        
        color.AddRGBPoint(171, 1, 0, 0)
        color.AddRGBPoint(214, 1, 0, 0)
        color.AddRGBPoint(255, 0.88, 0, 1) 
        color.SetColorSpaceToRGB()
        color.SetScaleToLinear()


        opacity = vtk.vtkPiecewiseFunction()
        opacity.AddPoint(0, 0.0)
        opacity.AddPoint(250, 0.1)
        opacity.AddPoint(255, 1.0)


        self.ui.ren.SetBackground(0, 0, 0)


        Property= vtk.vtkVolumeProperty()
        Property.SetColor(color)
        Property.SetScalarOpacity(opacity)

#Mapping of the structured points
        compositeFunction = vtk.vtkVolumeRayCastCompositeFunction()

        mapper1 = vtk.vtkVolumeRayCastMapper()
        mapper1.SetVolumeRayCastFunction(compositeFunction)
        mapper1.SetInputConnection(self.ui.reader1.GetOutputPort())
        mapper2 = vtk.vtkVolumeRayCastMapper()
        mapper2.SetVolumeRayCastFunction(compositeFunction)
        mapper2.SetInputConnection(self.ui.reader2.GetOutputPort())
        mapper3 = vtk.vtkVolumeRayCastMapper()
        mapper3.SetVolumeRayCastFunction(compositeFunction)
        mapper3.SetInputConnection(self.ui.reader3.GetOutputPort())


        Volume1=vtk.vtkVolume()
        Volume1.SetProperty(Property)
        Volume1.SetMapper(mapper1)       
        Volume2=vtk.vtkVolume()
        Volume2.SetProperty(Property)
        Volume2.SetMapper(mapper2)
        Volume3=vtk.vtkVolume()
        Volume3.SetProperty(Property)
        Volume3.SetMapper(mapper3)
  

        self.ui.ren.AddVolume(Volume1)
        self.ui.ren.AddVolume(Volume2)
        self.ui.ren.AddVolume(Volume3)
        self.ui.ren.ResetCamera()
        self.ui.iren.Initialize()

#Assigning functions to the buttons
        self.ui.radioButton_7.pressed.connect(self.PickingInit)        
        self.ui.radioButton_9.pressed.connect(self.Picking)


        self.ui.propHigh = vtk.vtkProperty()
        self.ui.propHigh.SetPointSize(5)
        self.ui.points = vtk.vtkPoints()
        self.ui.vertices = vtk.vtkCellArray()
        self.ui.lines = vtk.vtkCellArray()
        
        self.ui.actorPlanes = vtk.vtkActor()
        self.ui.propPlanes = vtk.vtkProperty()
        self.ui.propPlanes.SetPointSize(3)   
        self.ui.propPlanes.SetColor(1,0,0) 
#Slicing displayed in the GUI - initialization
        self.ui.renZ = vtk.vtkRenderer()
        self.ui.qvtkWidget_5.GetRenderWindow().AddRenderer(self.ui.renZ)
        self.ui.irenZ = self.ui.qvtkWidget_5.GetRenderWindow().GetInteractor()      
        self.ui.irenZ.RemoveObservers('RightButtonPressEvent')
        self.ui.irenZ.RemoveObservers('LeftButtonPressEvent')
        self.ui.irenZ.AddObserver('RightButtonPressEvent', self.PickingPoints, 1.0) 
         
# Calculating the artery length
        self.a1 = 0
        self.a2 = 0
        self.a3 = 0
        self.ui.pushButton_3.clicked.connect(self.Length)
        self.D = 0
    def Length(self):
        print(self.D)
        self.ui.lineEdit.setText(str(self.D))


#Picking the Planes in the global volume
    def Planes(self, obj, ev):
        pick= vtk.vtkPicker()
     
        obj.GetPicker().Pick(obj.GetEventPosition()[0], obj.GetEventPosition()[1], 0,obj.GetRenderWindow().GetRenderers().GetFirstRenderer())
        PP = obj.GetPicker().GetPickPosition()

        pick.Pick(PP, self.ui.ren)
        spacing = pick.GetDataSet().GetSpacing()

        org = pick.GetDataSet().GetOrigin() 
        Z=int((PP[2]-org[2])/spacing[2])
      
        self.ui.sliceZ = vtk.vtkExtractVOI()
        self.ui.sliceZ.SetVOI(1,256,1,256,Z,Z)
        self.ui.sliceZ.SetInput(pick.GetDataSet())
        self.ui.sliceZ.Update()

        zmapper = vtk.vtkDataSetMapper()
        zmapper.SetInputConnection(self.ui.sliceZ.GetOutputPort())

        zactor = vtk.vtkActor()
        zactor.SetMapper(zmapper)

        cameraZ = self.ui.renZ.GetActiveCamera()
        cZ = self.ui.sliceZ.GetVOI()
        cameraZ.SetFocalPoint(round(cZ[0]+cZ[1])/2,round(cZ[2]+cZ[3])/2, Z)
        cameraZ.SetPosition(round(cZ[0]+cZ[1])/2,round(cZ[2]+cZ[3])/2,Z+400)
        cameraZ.SetViewUp(1,0,0)
       
        self.ui.renZ.AddActor(zactor)

        self.ui.renZ.ResetCamera()
        self.ui.irenZ.Initialize()
  


  
    def PickingInit(self):
        self.ui.iren.RemoveObservers('RightButtonPressEvent')
        self.ui.iren.AddObserver('RightButtonPressEvent', self.PickingPoints, 1.0) 
        self.ui.qvtkWidget.GetRenderWindow().Render()      


    def PickingPoints(self, obj, ev): 
        obj.GetPicker().Pick(obj.GetEventPosition()[0], obj.GetEventPosition()[1], 0,obj.GetRenderWindow().GetRenderers().GetFirstRenderer())
        self.ui.P = obj.GetPicker().GetPickPosition()
 
        b1 = self.a1
        b2 = self.a2
        b3 = self.a3  
       
        itemX = QtGui.QTableWidgetItem()
        itemY = QtGui.QTableWidgetItem()
        itemZ = QtGui.QTableWidgetItem()
        itemX.setData(QtCore.Qt.DisplayRole, self.ui.P[0])
        itemY.setData(QtCore.Qt.DisplayRole, self.ui.P[1])
        itemZ.setData(QtCore.Qt.DisplayRole, self.ui.P[2])     

        R = self.ui.tableWidget_2.currentRow()
        self.ui.tableWidget_2.insertRow(R+1) 
        self.ui.tableWidget_2.setItem(R+1, 0, itemX)
        self.ui.tableWidget_2.setItem(R+1, 1, itemY)
        self.ui.tableWidget_2.setItem(R+1, 2, itemZ)

        self.ui.renZ.RemoveActor(self.ui.actorPlanes)

        self.ui.qvtkWidget_5.GetRenderWindow().Render()

#Displaying Picked Points
        id =self.ui.points.InsertNextPoint(self.ui.P)
        self.ui.vertices.InsertNextCell(1)
        self.ui.vertices.InsertCellPoint(id)
        if (id > 0):
            line = vtk.vtkLine()
            line.GetPointIds().SetId(0,id - 1)
            line.GetPointIds().SetId(1,id)
            self.ui.lines.InsertNextCell(line)

        Highlight = vtk.vtkPolyData()
        Highlight.SetPoints(self.ui.points)
        Highlight.SetVerts(self.ui.vertices)
        Highlight.SetLines(self.ui.lines)

        mapperPoints = vtk.vtkDataSetMapper()
        mapperPoints.SetInput(Highlight)       
        actor= vtk.vtkActor()
        actor.SetProperty(self.ui.propHigh)
        actor.SetMapper(mapperPoints)

        points = vtk.vtkPoints()
        vertices = vtk.vtkCellArray()
        points.InsertPoint(0, self.ui.P)
        vertices.InsertNextCell(1)
        vertices.InsertCellPoint(0)
        HighlightPlanes = vtk.vtkPolyData()
        HighlightPlanes.SetPoints(points)
        HighlightPlanes.SetVerts(vertices)
        
        mapperPlanes = vtk.vtkDataSetMapper()
        mapperPlanes.SetInput(HighlightPlanes)
        self.ui.actorPlanes.SetProperty(self.ui.propPlanes)
        self.ui.actorPlanes.SetMapper(mapperPlanes)

        self.ui.renZ.AddActor(self.ui.actorPlanes)

        self.ui.qvtkWidget_5.GetRenderWindow().Render()

        self.ui.ren.AddActor(actor)
        self.ui.iren.Initialize()
        self.ui.qvtkWidget.GetRenderWindow().Render()  
        self.a1 = float(self.ui.P[0])
        self.a2 = float(self.ui.P[1])
        self.a3 = float(self.ui.P[2])
        if ((b1 + b2 +b3) == 0):
            self.D=0
        else:
            v = math.sqrt(math.pow((self.a1-b1),2) + math.pow((self.a2-b2),2) +math.pow((self.a3-b3),2));
            self.D = self.D+v;


    def Picking(self):
        self.ui.iren.RemoveObservers('RightButtonPressEvent')
        self.ui.iren.AddObserver('RightButtonPressEvent', self.Planes, 1.0) 
        self.ui.qvtkWidget.GetRenderWindow().Render()
              



if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
