import vtk

global selectActor, planes, boxWidget

# This callback funciton does the actual work: updates the vtkPlanes
# implicit function.  This in turn causes the pipeline to update.
def selectPolygons(object, event):
    # object will be the boxWidget
    global selectActor, planes
    object.GetPlanes(planes)
    selectActor.VisibilityOn()

def selectPolygonsInit(object):
    # object will be the boxWidget
    global selectActor, planes
    object.GetPlanes(planes)
    selectActor.VisibilityOn()


def clipData(DataToClip, renderer, renderWindowInteractor):
    global selectActor, planes, boxWidget

    inputData = DataToClip.GetInput()
    
    planes = vtk.vtkPlanes()
    clipper = vtk.vtkClipPolyData()
    clipper.SetInput(inputData)
    clipper.SetClipFunction(planes)
    clipper.InsideOutOn()
    selectMapper = vtk.vtkPolyDataMapper()
    selectMapper.SetInputConnection(clipper.GetOutputPort())

    selectActor = vtk.vtkActor()
    selectActor.SetMapper(selectMapper)

    propertyBack = vtk.vtkProperty()
    propertyBack.SetDiffuseColor(1.0, 0.5, 0.4)
    propertyBack.SetOpacity(0.05)
    selectActor.GetProperty().SetColor(1.0,1.0,1.0)
    selectActor.GetProperty().SetOpacity(0.05)
    selectActor.SetBackfaceProperty(propertyBack)
    selectActor.GetProperty().SetRepresentationToWireframe()
    selectActor.VisibilityOn()    
    selectActor.SetScale(1.01, 1.01, 1.01)

    # The SetInteractor method is how 3D widgets are associated with the
    # render window interactor.  Internally, SetInteractor sets up a bunch
    # of callbacks using the Command/Observer mechanism (AddObserver()).
    boxWidget = vtk.vtkBoxWidget()
    boxWidget.SetInteractor(renderWindowInteractor)
    boxWidget.SetPlaceFactor(1.25)
    boxWidget.SetRotationEnabled(0)
    boxWidget.SetScalingEnabled(0)
    
    # Place the interactor initially. The input to a 3D widget is used to
    # initially position and scale the widget. The "EndInteractionEvent" is
    # observed which invokes the SelectPolygons callback.
    boxWidget.SetInput(inputData)
    boxWidget.PlaceWidget()
    boxWidget.AddObserver("EndInteractionEvent", selectPolygons)
    selectPolygonsInit(boxWidget)
    #boxWidget.On()
    boxWidget.Modified()
    #boxWidget.PlaceWidget(-150,-50,0,200,0,200)
    
    renderer.AddActor(selectActor)

def clipPlanePositions():
    global boxWidget, selectActor, planes
    
    boxWidget.Modified()
    u = planes.GetPoints().GetBounds()
    planes.SetBounds(u[0], u[1], u[2], u[3], u[4], 100)
    
    
