"""
Screw.py --                                                                                            
                                                                                                                                                                                                        
It sets a Cylinder with a Hole geometric properties.                                              
                                                                                                                                                                                                            
Date of creation: 2007-03-17                                                                        
                                                                                                                                                                                                
Copyright  Robotics and Automation Group, Pontificia Universidad Javeriana - Cali.                  
    Freddy Naranjo Perez, fnaranjo@puj.edu.co                                                                   
    Antonio Alejandro Matta Gomez amatta@puj.edu.co                                      
    Julian David Colorado, jdcolorado@puj.edu.co                           
    Juan Camilo Acosta Mejia, jcacosta@puj.edu.co                                    
                                                                                                                                                                                                        
See the file "license.terms" for information on usage and redistribution of this file, and for a    
DISCLAIMER OF ALL WARRANTIES.
"""

import vtk
from vtk.util.colors import *

class Screw:
  def __init__( self, ren, geomdim, posorient, lighting, color ):
        """ Inits a tube's 3d object and its associated color and lighting"""
        
        #Wheel's geometrical parameters. 
        wheelRadius = geomdim[3]
        wheelTopPoint = geomdim[1]
        wheelBottomPoint = 0.0

        #Wheel's base cylinder. 
        baseCylinder = vtk.vtkCylinder()
        baseCylinder.SetRadius(wheelRadius)
        topPlane = vtk.vtkPlane()
        topPlane.SetOrigin(0, wheelTopPoint, 0)
        topPlane.SetNormal(0, 1, 0)
        bottomPlane = vtk.vtkPlane()
        bottomPlane.SetOrigin(0, wheelBottomPoint, 0)
        bottomPlane.SetNormal(0, -1, 0)

        #Wheel's hole cylinder.
        holeCylinder= vtk.vtkCylinder()
        #holeCylinder.SetRadius(wheelRadius - 0.0001)
        holeCylinder.SetRadius(0.001)
        htopPlane = vtk.vtkPlane()
        htopPlane.SetOrigin(0, wheelTopPoint+0.5, 0)
        htopPlane.SetNormal(0, 1, 0)
        hbottomPlane = vtk.vtkPlane()
        hbottomPlane.SetOrigin(0, wheelBottomPoint-0.5, 0)
        hbottomPlane.SetNormal(0, -1, 0)

        holeTrans = vtk.vtkTransform()
        holeTrans.Translate(0.0, 0.0, 0.0)
        holeCylinder.SetTransform(holeTrans)

        #Base cylinder's boolean function: Intersection between baseCylinder
        #and the two planes.
        theWheel = vtk.vtkImplicitBoolean()
        theWheel.SetOperationTypeToIntersection()
        theWheel.AddFunction(baseCylinder)
        theWheel.AddFunction(topPlane)
        theWheel.AddFunction(bottomPlane)

        #Hole cylinder's boolean function: Intersection between holeCylinder
        #and the two planes.
        theHole = vtk.vtkImplicitBoolean()
        theHole.SetOperationTypeToIntersection()
        theHole.AddFunction(holeCylinder)
        theHole.AddFunction(htopPlane)
        theHole.AddFunction(hbottomPlane)

        #The Wheel's boolean function: Difference between theWheel
        #and theHole.
        theWheelHole= vtk.vtkImplicitBoolean()
        theWheelHole.SetOperationTypeToDifference()
        theWheelHole.AddFunction(theWheel)
        theWheelHole.AddFunction(theHole)

        # The sample function generates a distance function from the implicit
        # function (which in this case is the WheelHole). This is then contoured to
        # get a polygonal surface.
        offset = 0.001
        theWheelSample = vtk.vtkSampleFunction()
        theWheelSample.SetImplicitFunction(theWheelHole)
        theWheelSample.SetModelBounds(-geomdim[1]-offset, geomdim[1]+offset, -geomdim[1]-offset, geomdim[1]+offset, -geomdim[1]-offset, geomdim[1]+offset)
        theWheelSample.SetSampleDimensions(6, 20, 6)
        theWheelSample.ComputeNormalsOn()

        #vtk.vtkContourFilter applied in order to get a polygonal surface.
        theWheelSurface = vtk.vtkContourFilter()
        theWheelSurface.SetInputConnection(theWheelSample.GetOutputPort())
        theWheelSurface.SetValue(0, 0.00005)
        
        decimation = vtk.vtkDecimatePro()
        decimation.SetInputConnection(theWheelSurface.GetOutputPort())
        decimation.SetTargetReduction(0.25)
        decimation.PreserveTopologyOn()

        #Smoothing applied in order to get a better surface.
        smooth= vtk.vtkSmoothPolyDataFilter()
        smooth.SetInputConnection(decimation.GetOutputPort())
        smooth.SetNumberOfIterations(20)

        #Normal's computation.
        normals = vtk.vtkPolyDataNormals()
        normals.SetInputConnection(smooth.GetOutputPort())
        normals.FlipNormalsOn()

        #Normal's passed to the poly data mapper.
        wheelMapper = vtk.vtkPolyDataMapper()
        wheelMapper.SetInputConnection(normals.GetOutputPort())
        wheelMapper.ScalarVisibilityOff()

        self.screwActor = vtk.vtkActor()
        self.screwActor.SetMapper(wheelMapper)
        self.screwActor.GetProperty().SetInterpolationToGouraud()
        self.screwActor.GetProperty().SetColor(color)
        self.screwActor.GetProperty().SetSpecular(.3)
        self.screwActor.GetProperty().SetSpecularPower(30)
        self.screwActor.SetPosition( posorient[0], posorient[1], posorient[2] )
        self.screwActor.SetOrientation( posorient[3], posorient[4], posorient[5] )
        
        
    
        
    
    

        
        
            
        
    

    
  
  