Sure. Here’s the .py file with the knob implementation.

-Nathan



From: ashNuke 
Sent: Wednesday, July 06, 2011 4:53 PM
To: [email protected] 
Subject: [Nuke-python] Re: PyCustom_Knob

Hi Nathan,

Thanks for all your help. Unfortunately i was not able to open the file at all, 
no
matter what i'v tried with it. Every application i've tried found that the 
archive was corrupted or incomplete.

Would it possible for you to just attach the py file demonstrating the use of 
the PyCustom_Knob ? I don't care so much about the complete example anyway.

Thanks a lot.

Cheers,

Ash


--------------------------------------------------------------------------------
_______________________________________________
Nuke-python mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
# Copyright (c) 2009 The Foundry Visionmongers Ltd.  All Rights Reserved.

from __future__ import with_statement
import nuke, nukescripts

# An example of using an OpenGL widget in your Python UI.
# This panel displays a sperically mapped image, and allows you to rotate it 
using the mouse.

import nuke
import math
import numpy

from PIL import Image
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
from pyui import *

# An implementation of the Observer pattern for knobChanged
_callbacks = [];
def addKnobChangedCallback( node, callback ):
  _callbacks.append( (node, callback ) )

def knobChangedCallback():
  n = nuke.thisNode()
  k = nuke.thisKnob()
  for (node, callback) in _callbacks:
    if node == n:
      callback( n, k )

nuke.addKnobChanged( knobChangedCallback )

# The widget which implements the UI for the knob
class SphereViewWidget( GLWidget ):

  def __init__( self, knob ):
    GLWidget.__init__( self )
    self.view_rotx = 0
    self.view_roty = 0
    self.view_rotz = 0
    self.view_zoom = 1
    self.focalLength = 20
    self.color = 0
    self.knob = knob;
    addKnobChangedCallback( nuke.thisNode(), self.knobChanged )

  def mousePressed( self, x, y, button, modifiers ):
    self.mouseX = x
    self.mouseY = y
  
  def mouseReleased( self, x, y, button, modifiers ):
    pass
  
  def mouseMoved( self, x, y, button, modifiers ):
    if modifiers != 0:
      self.focalLength += (x-self.mouseX) / 10.0;
      self.focalLength = max( 10, self.focalLength );
    else:
      self.view_roty += (x-self.mouseX) / 10.0;
      self.view_rotx += (y-self.mouseY) / 10.0
    self.mouseX = x
    self.mouseY = y
    self.repaint()
    self.knob.update( self.view_rotx, self.view_roty, self.view_rotz, 
self.focalLength )

  # This method is called when the widget is created. Set up your OpenGL state 
here.
  def initialize( self ):
    ambient = [0.0, 0.0, 0.0, 1.0]
    diffuse = [1.0, 1.0, 1.0, 1.0]
    specular = [1.0, 1.0, 1.0, 1.0]
    position = [0.0, 3.0, 3.0, 0.0]

    ambient = [0.2, 0.2, 0.2, 1.0]
    localView = [0.0]

    glLightfv( GL_LIGHT0, GL_AMBIENT, ambient )
    glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse )
    glLightfv( GL_LIGHT0, GL_POSITION, position )
    glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient )
    glLightModelfv( GL_LIGHT_MODEL_LOCAL_VIEWER, localView )

    # Load in our texture
    img = Image.open( self.knob.imagePath )
    img_data = numpy.array( img, numpy.int8 )
    self.texture = glGenTextures( 1 )
    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 )
    glBindTexture( GL_TEXTURE_2D, self.texture )
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP )
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP )
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR )
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR )
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, 
GL_RGB, GL_UNSIGNED_BYTE, img_data )

  def keyPressed( self, key, modifiers, text ):
    nuke.tprint ( "Press " + str(key) + " t:" + text );
    
  def keyReleased( self, key, modifiers, text ):
    nuke.tprint ( "Release " + str(key) + " t:" + text );

  def resize( self ):
    pass
    
  # This method is called whenever the widget needs painting
  def paint( self ):
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )

    glViewport( 0, 0, self.width(), self.height() )

    glMatrixMode( GL_PROJECTION )
    glLoadIdentity()
    FOV = 180 / 3.14159 * 2 * math.atan( 9.0 / (2 * self.focalLength) )
    gluPerspective( FOV, 1.5, 1.5, 20.0 )

    glMatrixMode( GL_MODELVIEW )
    glColor3f( 1.0, 1.0, 1.0 )
    glLoadIdentity()

    gluLookAt( 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 )

    glFrontFace( GL_CW )
    glEnable( GL_LIGHTING )
    glEnable( GL_LIGHT0 )
    glEnable( GL_AUTO_NORMAL )
    glEnable( GL_NORMALIZE)
    glEnable( GL_DEPTH_TEST ) 
    glEnable( GL_TEXTURE_2D )
    glBindTexture( GL_TEXTURE_2D, self.texture )

    glPushMatrix()
    glRotatef( -self.view_rotz, 0.0, 0.0, 1.0 )
    glRotatef( -self.view_rotx, 1.0, 0.0, 0.0 )
    glRotatef( -self.view_roty, 0.0, 1.0, 0.0 )
    glScalef( self.view_zoom, self.view_zoom, self.view_zoom )

    # Draw the sphere
    mat = [0, 0, 0, 0]

    glPushMatrix()
    mat[0] = 1.0; mat[1] = 1.0; mat[2] = 1.0; mat[3] = 1.0
    glMaterialfv( GL_FRONT, GL_AMBIENT, mat )
    glMaterialfv( GL_FRONT, GL_DIFFUSE, mat )
    
    glRotatef( 90, 1.0, 0.0, 0.0 )
    glScale(-1, 1, 1) # mirror the texture
    quad = gluNewQuadric(); 
    gluQuadricNormals(quad, GLU_SMOOTH);
    gluQuadricOrientation(quad, GLU_INSIDE)
    gluQuadricTexture(quad, GL_TRUE);
    gluSphere(quad, 8.0, 32, 10)
    glPopMatrix()

    glPopMatrix()
    glFlush()

  
  def knobChanged( self, node, knob ):
  # Update this widget when the rotate knob changes
    if knob.name() == "rotate":
      self.view_rotx = knob.getValue( 0 )
      self.view_roty = knob.getValue( 1 )
      self.view_rotz = knob.getValue( 2 )
      self.repaint()

# The class which defines the knob.
class SphereViewKnob:

  def __init__( self, imageFile ):
    self.knob = None
    self.imagePath = None
    
    for path in nuke.pluginPath():
      p = os.path.join( path, imageFile )
      if os.path.exists( p ):
        self.imagePath = p
       
    if not self.imagePath:
      nuke.tprint ( "Could not find image " + imageFile )
      nuke.message ( "Could not find image " + imageFile )
    
    return None

  # This method is called by the widget when the user changes the view
  def update( self, x, y, z, focalLength ):
    ## only valid if this knob is created in a regular node
    if not type(self.node) is nuke.PanelNode:
      k = self.node["rotate"]
      k.setValue( x, 0 )
      k.setValue( y, 1 )
      k.setValue( -z, 2 )
      k = self.node["focal"]
      k.setValue( focalLength, 0 )

  # This method is called by Nuke to create the knob's UI
  def makeUI( self ):
    self.node = nuke.thisNode()
    self.knob = nuke.thisKnob()
    return SphereViewWidget( self )


class OpenGLPanel(nukescripts.PythonPanel):
  def __init__(self):
    super(OpenGLPanel, self).__init__("OpenGLPanel", 
"uk.co.thefoundry.OpenGLPanel")
    self.__pyKnob = nuke.PyCustom_Knob( "view", "", 
"openGLPanel.SphereViewKnob( 'Sequoia_BeetleRock_Dome.png')" )
    self.addKnob(self.__pyKnob)

def createOpenGLPanel():
  return OpenGLPanel().show()

nukescripts.registerPanel("uk.co.thefoundry.OpenGLPanel", createOpenGLPanel)

_______________________________________________
Nuke-python mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python

Reply via email to