| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800 |
- """ DIRECT Nine DoF Manipulation Panel """
- from direct.showbase.DirectObject import DirectObject
- from direct.directtools.DirectGlobals import *
- from direct.tkwidgets.AppShell import AppShell
- from direct.tkwidgets.Dial import AngleDial
- from direct.tkwidgets.Floater import Floater
- from Tkinter import Button, Menubutton, Menu, StringVar
- from pandac.PandaModules import *
- import Tkinter, Pmw
- """
- TODO:
- Task to monitor pose
- """
- class Placer(AppShell):
- # Override class variables here
- appname = 'Placer Panel'
- frameWidth = 625
- frameHeight = 215
- usecommandarea = 0
- usestatusarea = 0
- def __init__(self, parent = None, **kw):
- INITOPT = Pmw.INITOPT
- optiondefs = (
- ('title', self.appname, None),
- ('nodePath', SEditor.camera, None),
- )
- self.defineoptions(kw, optiondefs)
- # Call superclass initialization function
- AppShell.__init__(self)
-
- self.initialiseoptions(Placer)
- # Accept the message from sceneEditor to update the information about the target nodePath
- self.accept('placerUpdate', self.updatePlacer)
- def appInit(self):
- # Initialize state
- self.tempCS = SEditor.group.attachNewNode('placerTempCS')
- self.orbitFromCS = SEditor.group.attachNewNode(
- 'placerOrbitFromCS')
- self.orbitToCS = SEditor.group.attachNewNode('placerOrbitToCS')
- self.refCS = self.tempCS
-
- # Dictionary keeping track of all node paths manipulated so far
- self.nodePathDict = {}
- self.nodePathDict['camera'] = SEditor.camera
- self.nodePathDict['widget'] = SEditor.widget
- self.nodePathNames = ['camera', 'widget', 'selected']
- self.refNodePathDict = {}
- self.refNodePathDict['parent'] = self['nodePath'].getParent()
- self.refNodePathDict['render'] = render
- self.refNodePathDict['camera'] = SEditor.camera
- self.refNodePathDict['widget'] = SEditor.widget
- self.refNodePathNames = ['parent', 'self', 'render',
- 'camera', 'widget', 'selected']
- # Initial state
- self.initPos = Vec3(0)
- self.initHpr = Vec3(0)
- self.initScale = Vec3(1)
- self.deltaHpr = Vec3(0)
- # Offset for orbital mode
- self.posOffset = Vec3(0)
- # Set up event hooks
- self.undoEvents = [('DIRECT_undo', self.undoHook),
- ('DIRECT_pushUndo', self.pushUndoHook),
- ('DIRECT_undoListEmpty', self.undoListEmptyHook),
- ('DIRECT_redo', self.redoHook),
- ('DIRECT_pushRedo', self.pushRedoHook),
- ('DIRECT_redoListEmpty', self.redoListEmptyHook)]
- for event, method in self.undoEvents:
- self.accept(event, method)
- # Init movement mode
- self.movementMode = 'Relative To:'
- def createInterface(self):
- # The interior of the toplevel panel
- interior = self.interior()
- interior['relief'] = Tkinter.FLAT
- # Add placer commands to menubar
- self.menuBar.addmenu('Placer', 'Placer Panel Operations')
- self.menuBar.addmenuitem('Placer', 'command',
- 'Zero Node Path',
- label = 'Zero All',
- command = self.zeroAll)
- self.menuBar.addmenuitem('Placer', 'command',
- 'Reset Node Path',
- label = 'Reset All',
- command = self.resetAll)
- self.menuBar.addmenuitem('Placer', 'command',
- 'Print Node Path Info',
- label = 'Print Info',
- command = self.printNodePathInfo)
- self.menuBar.addmenuitem(
- 'Placer', 'command',
- 'Toggle widget visability',
- label = 'Toggle Widget Vis',
- command = SEditor.toggleWidgetVis)
- self.menuBar.addmenuitem(
- 'Placer', 'command',
- 'Toggle widget manipulation mode',
- label = 'Toggle Widget Mode',
- command = SEditor.manipulationControl.toggleObjectHandlesMode)
-
- # Get a handle to the menu frame
- menuFrame = self.menuFrame
- self.nodePathMenu = Pmw.ComboBox(
- menuFrame, labelpos = Tkinter.W, label_text = 'Node Path:',
- entry_width = 20,
- selectioncommand = self.selectNodePathNamed,
- scrolledlist_items = self.nodePathNames)
- self.nodePathMenu.selectitem('selected')
- self.nodePathMenuEntry = (
- self.nodePathMenu.component('entryfield_entry'))
- self.nodePathMenuBG = (
- self.nodePathMenuEntry.configure('background')[3])
- self.nodePathMenu.pack(side = 'left', fill = 'x', expand = 1)
- self.bind(self.nodePathMenu, 'Select node path to manipulate')
- modeMenu = Pmw.OptionMenu(menuFrame,
- items = ('Relative To:',
- 'Orbit:'),
- initialitem = 'Relative To:',
- command = self.setMovementMode,
- menubutton_width = 8)
- modeMenu.pack(side = 'left', expand = 0)
- self.bind(modeMenu, 'Select manipulation mode')
-
- self.refNodePathMenu = Pmw.ComboBox(
- menuFrame, entry_width = 16,
- selectioncommand = self.selectRefNodePathNamed,
- scrolledlist_items = self.refNodePathNames)
- self.refNodePathMenu.selectitem('parent')
- self.refNodePathMenuEntry = (
- self.refNodePathMenu.component('entryfield_entry'))
- self.refNodePathMenu.pack(side = 'left', fill = 'x', expand = 1)
- self.bind(self.refNodePathMenu, 'Select relative node path')
- self.undoButton = Button(menuFrame, text = 'Undo',
- command = SEditor.undo)
- if SEditor.undoList:
- self.undoButton['state'] = 'normal'
- else:
- self.undoButton['state'] = 'disabled'
- self.undoButton.pack(side = 'left', expand = 0)
- self.bind(self.undoButton, 'Undo last operation')
- self.redoButton = Button(menuFrame, text = 'Redo',
- command = SEditor.redo)
- if SEditor.redoList:
- self.redoButton['state'] = 'normal'
- else:
- self.redoButton['state'] = 'disabled'
- self.redoButton.pack(side = 'left', expand = 0)
- self.bind(self.redoButton, 'Redo last operation')
- # Create and pack the Pos Controls
- posGroup = Pmw.Group(interior,
- tag_pyclass = Menubutton,
- tag_text = 'Position',
- tag_font=('MSSansSerif', 14),
- tag_activebackground = '#909090',
- ring_relief = Tkinter.RIDGE)
- posMenubutton = posGroup.component('tag')
- self.bind(posMenubutton, 'Position menu operations')
- posMenu = Menu(posMenubutton, tearoff = 0)
- posMenu.add_command(label = 'Set to zero', command = self.zeroPos)
- posMenu.add_command(label = 'Reset initial',
- command = self.resetPos)
- posMenubutton['menu'] = posMenu
- posGroup.pack(side='left', fill = 'both', expand = 1)
- posInterior = posGroup.interior()
- # Create the dials
- self.posX = self.createcomponent('posX', (), None,
- Floater, (posInterior,),
- text = 'X', relief = Tkinter.FLAT,
- value = 0.0,
- label_foreground = 'Red')
- self.posX['commandData'] = ['x']
- self.posX['preCallback'] = self.xformStart
- self.posX['postCallback'] = self.xformStop
- self.posX['callbackData'] = ['x']
- self.posX.pack(expand=1,fill='both')
-
- self.posY = self.createcomponent('posY', (), None,
- Floater, (posInterior,),
- text = 'Y', relief = Tkinter.FLAT,
- value = 0.0,
- label_foreground = '#00A000')
- self.posY['commandData'] = ['y']
- self.posY['preCallback'] = self.xformStart
- self.posY['postCallback'] = self.xformStop
- self.posY['callbackData'] = ['y']
- self.posY.pack(expand=1,fill='both')
-
- self.posZ = self.createcomponent('posZ', (), None,
- Floater, (posInterior,),
- text = 'Z', relief = Tkinter.FLAT,
- value = 0.0,
- label_foreground = 'Blue')
- self.posZ['commandData'] = ['z']
- self.posZ['preCallback'] = self.xformStart
- self.posZ['postCallback'] = self.xformStop
- self.posZ['callbackData'] = ['z']
- self.posZ.pack(expand=1,fill='both')
- # Create and pack the Hpr Controls
- hprGroup = Pmw.Group(interior,
- tag_pyclass = Menubutton,
- tag_text = 'Orientation',
- tag_font=('MSSansSerif', 14),
- tag_activebackground = '#909090',
- ring_relief = Tkinter.RIDGE)
- hprMenubutton = hprGroup.component('tag')
- self.bind(hprMenubutton, 'Orientation menu operations')
- hprMenu = Menu(hprMenubutton, tearoff = 0)
- hprMenu.add_command(label = 'Set to zero', command = self.zeroHpr)
- hprMenu.add_command(label = 'Reset initial', command = self.resetHpr)
- hprMenubutton['menu'] = hprMenu
- hprGroup.pack(side='left',fill = 'both', expand = 1)
- hprInterior = hprGroup.interior()
-
- # Create the dials
- self.hprH = self.createcomponent('hprH', (), None,
- AngleDial, (hprInterior,),
- style = 'mini',
- text = 'H', value = 0.0,
- relief = Tkinter.FLAT,
- label_foreground = 'blue')
- self.hprH['commandData'] = ['h']
- self.hprH['preCallback'] = self.xformStart
- self.hprH['postCallback'] = self.xformStop
- self.hprH['callbackData'] = ['h']
- self.hprH.pack(expand=1,fill='both')
-
- self.hprP = self.createcomponent('hprP', (), None,
- AngleDial, (hprInterior,),
- style = 'mini',
- text = 'P', value = 0.0,
- relief = Tkinter.FLAT,
- label_foreground = 'red')
- self.hprP['commandData'] = ['p']
- self.hprP['preCallback'] = self.xformStart
- self.hprP['postCallback'] = self.xformStop
- self.hprP['callbackData'] = ['p']
- self.hprP.pack(expand=1,fill='both')
-
- self.hprR = self.createcomponent('hprR', (), None,
- AngleDial, (hprInterior,),
- style = 'mini',
- text = 'R', value = 0.0,
- relief = Tkinter.FLAT,
- label_foreground = '#00A000')
- self.hprR['commandData'] = ['r']
- self.hprR['preCallback'] = self.xformStart
- self.hprR['postCallback'] = self.xformStop
- self.hprR['callbackData'] = ['r']
- self.hprR.pack(expand=1,fill='both')
- # Create and pack the Scale Controls
- # The available scaling modes
- self.scalingMode = StringVar()
- self.scalingMode.set('Scale Uniform')
- # The scaling widgets
- scaleGroup = Pmw.Group(interior,
- tag_text = 'Scale Uniform',
- tag_pyclass = Menubutton,
- tag_font=('MSSansSerif', 14),
- tag_activebackground = '#909090',
- ring_relief = Tkinter.RIDGE)
- self.scaleMenubutton = scaleGroup.component('tag')
- self.bind(self.scaleMenubutton, 'Scale menu operations')
- self.scaleMenubutton['textvariable'] = self.scalingMode
- # Scaling menu
- scaleMenu = Menu(self.scaleMenubutton, tearoff = 0)
- scaleMenu.add_command(label = 'Set to unity',
- command = self.unitScale)
- scaleMenu.add_command(label = 'Reset initial',
- command = self.resetScale)
- scaleMenu.add_radiobutton(label = 'Scale Free',
- variable = self.scalingMode)
- scaleMenu.add_radiobutton(label = 'Scale Uniform',
- variable = self.scalingMode)
- scaleMenu.add_radiobutton(label = 'Scale Proportional',
- variable = self.scalingMode)
- self.scaleMenubutton['menu'] = scaleMenu
- # Pack group widgets
- scaleGroup.pack(side='left',fill = 'both', expand = 1)
- scaleInterior = scaleGroup.interior()
-
- # Create the dials
- self.scaleX = self.createcomponent('scaleX', (), None,
- Floater, (scaleInterior,),
- text = 'X Scale',
- relief = Tkinter.FLAT,
- min = 0.0001, value = 1.0,
- resetValue = 1.0,
- label_foreground = 'Red')
- self.scaleX['commandData'] = ['sx']
- self.scaleX['callbackData'] = ['sx']
- self.scaleX['preCallback'] = self.xformStart
- self.scaleX['postCallback'] = self.xformStop
- self.scaleX.pack(expand=1,fill='both')
-
- self.scaleY = self.createcomponent('scaleY', (), None,
- Floater, (scaleInterior,),
- text = 'Y Scale',
- relief = Tkinter.FLAT,
- min = 0.0001, value = 1.0,
- resetValue = 1.0,
- label_foreground = '#00A000')
- self.scaleY['commandData'] = ['sy']
- self.scaleY['callbackData'] = ['sy']
- self.scaleY['preCallback'] = self.xformStart
- self.scaleY['postCallback'] = self.xformStop
- self.scaleY.pack(expand=1,fill='both')
-
- self.scaleZ = self.createcomponent('scaleZ', (), None,
- Floater, (scaleInterior,),
- text = 'Z Scale',
- relief = Tkinter.FLAT,
- min = 0.0001, value = 1.0,
- resetValue = 1.0,
- label_foreground = 'Blue')
- self.scaleZ['commandData'] = ['sz']
- self.scaleZ['callbackData'] = ['sz']
- self.scaleZ['preCallback'] = self.xformStart
- self.scaleZ['postCallback'] = self.xformStop
- self.scaleZ.pack(expand=1,fill='both')
- # Make sure appropriate labels are showing
- self.setMovementMode('Relative To:')
- # Set up placer for inital node path
- self.selectNodePathNamed('init')
- self.selectRefNodePathNamed('parent')
- # Update place to reflect initial state
- self.updatePlacer()
- # Now that you're done setting up, attach commands
- self.posX['command'] = self.xform
- self.posY['command'] = self.xform
- self.posZ['command'] = self.xform
- self.hprH['command'] = self.xform
- self.hprP['command'] = self.xform
- self.hprR['command'] = self.xform
- self.scaleX['command'] = self.xform
- self.scaleY['command'] = self.xform
- self.scaleZ['command'] = self.xform
- ### WIDGET OPERATIONS ###
- def setMovementMode(self, movementMode):
- # Set prefix
- namePrefix = ''
- self.movementMode = movementMode
- if (movementMode == 'Relative To:'):
- namePrefix = 'Relative '
- elif (movementMode == 'Orbit:'):
- namePrefix = 'Orbit '
- # Update pos widgets
- self.posX['text'] = namePrefix + 'X'
- self.posY['text'] = namePrefix + 'Y'
- self.posZ['text'] = namePrefix + 'Z'
- # Update hpr widgets
- if (movementMode == 'Orbit:'):
- namePrefix = 'Orbit delta '
- self.hprH['text'] = namePrefix + 'H'
- self.hprP['text'] = namePrefix + 'P'
- self.hprR['text'] = namePrefix + 'R'
- # Update temp cs and initialize widgets
- self.updatePlacer()
- def setScalingMode(self):
- if self['nodePath']:
- scale = self['nodePath'].getScale()
- if ((scale[0] != scale[1]) or
- (scale[0] != scale[2]) or
- (scale[1] != scale[2])):
- self.scalingMode.set('Scale Free')
- def selectNodePathNamed(self, name):
- nodePath = None
- if name == 'init':
- nodePath = self['nodePath']
- # Add Combo box entry for the initial node path
- self.addNodePath(nodePath)
- elif name == 'selected':
- nodePath = SEditor.selected.last
- # Add Combo box entry for this selected object
- self.addNodePath(nodePath)
- else:
- nodePath = self.nodePathDict.get(name, None)
- if (nodePath == None):
- # See if this evaluates into a node path
- try:
- nodePath = eval(name)
- if isinstance(nodePath, NodePath):
- self.addNodePath(nodePath)
- else:
- # Good eval but not a node path, give up
- nodePath = None
- except:
- # Bogus eval
- nodePath = None
- # Clear bogus entry from listbox
- listbox = self.nodePathMenu.component('scrolledlist')
- listbox.setlist(self.nodePathNames)
- else:
- if name == 'widget':
- # Record relationship between selected nodes and widget
- SEditor.selected.getWrtAll()
- # Update active node path
- self.setActiveNodePath(nodePath)
- def setActiveNodePath(self, nodePath):
- self['nodePath'] = nodePath
- if self['nodePath']:
- self.nodePathMenuEntry.configure(
- background = self.nodePathMenuBG)
- # Check to see if node path and ref node path are the same
- if ((self.refCS != None) and
- (self.refCS.id() == self['nodePath'].id())):
- # Yes they are, use temp CS as ref
- # This calls updatePlacer
- self.setReferenceNodePath(self.tempCS)
- # update listbox accordingly
- self.refNodePathMenu.selectitem('parent')
- else:
- # Record initial value and initialize the widgets
- self.updatePlacer()
- # Record initial position
- self.updateResetValues(self['nodePath'])
- # Set scaling mode based on node path's current scale
- self.setScalingMode()
- else:
- # Flash entry
- self.nodePathMenuEntry.configure(background = 'Pink')
- def selectRefNodePathNamed(self, name):
- nodePath = None
- if name == 'self':
- nodePath = self.tempCS
- elif name == 'selected':
- nodePath = SEditor.selected.last
- # Add Combo box entry for this selected object
- self.addRefNodePath(nodePath)
- elif name == 'parent':
- nodePath = self['nodePath'].getParent()
- else:
- nodePath = self.refNodePathDict.get(name, None)
- if (nodePath == None):
- # See if this evaluates into a node path
- try:
- nodePath = eval(name)
- if isinstance(nodePath, NodePath):
- self.addRefNodePath(nodePath)
- else:
- # Good eval but not a node path, give up
- nodePath = None
- except:
- # Bogus eval
- nodePath = None
- # Clear bogus entry from listbox
- listbox = self.refNodePathMenu.component('scrolledlist')
- listbox.setlist(self.refNodePathNames)
- # Check to see if node path and ref node path are the same
- if (nodePath != None) and (nodePath.id() == self['nodePath'].id()):
- # Yes they are, use temp CS and update listbox accordingly
- nodePath = self.tempCS
- self.refNodePathMenu.selectitem('parent')
- # Update ref node path
- self.setReferenceNodePath(nodePath)
- def setReferenceNodePath(self, nodePath):
- self.refCS = nodePath
- if self.refCS:
- self.refNodePathMenuEntry.configure(
- background = self.nodePathMenuBG)
- # Update placer to reflect new state
- self.updatePlacer()
- else:
- # Flash entry
- self.refNodePathMenuEntry.configure(background = 'Pink')
-
- def addNodePath(self, nodePath):
- self.addNodePathToDict(nodePath, self.nodePathNames,
- self.nodePathMenu, self.nodePathDict)
- def addRefNodePath(self, nodePath):
- self.addNodePathToDict(nodePath, self.refNodePathNames,
- self.refNodePathMenu, self.refNodePathDict)
- def addNodePathToDict(self, nodePath, names, menu, dict):
- if not nodePath:
- return
- # Get node path's name
- name = nodePath.getName()
- if name in ['parent', 'render', 'camera']:
- dictName = name
- else:
- # Generate a unique name for the dict
- dictName = name + '-' + `nodePath.id()`
- if not dict.has_key(dictName):
- # Update combo box to include new item
- names.append(dictName)
- listbox = menu.component('scrolledlist')
- listbox.setlist(names)
- # Add new item to dictionary
- dict[dictName] = nodePath
- menu.selectitem(dictName)
- def updatePlacer(self):
- pos = Vec3(0)
- hpr = Vec3(0)
- scale = Vec3(1)
- np = self['nodePath']
- if (np != None) and isinstance(np, NodePath):
- # Update temp CS
- self.updateAuxiliaryCoordinateSystems()
- # Update widgets
- if self.movementMode == 'Orbit:':
- pos.assign(self.posOffset)
- hpr.assign(ZERO_VEC)
- scale.assign(np.getScale())
- elif self.refCS:
- pos.assign(np.getPos(self.refCS))
- hpr.assign(np.getHpr(self.refCS))
- scale.assign(np.getScale())
- self.updatePosWidgets(pos)
- self.updateHprWidgets(hpr)
- self.updateScaleWidgets(scale)
- def updateAuxiliaryCoordinateSystems(self):
- # Temp CS
- self.tempCS.setPosHpr(self['nodePath'], 0,0,0,0,0,0)
- # Orbit CS
- # At reference
- self.orbitFromCS.setPos(self.refCS, 0,0,0)
- # But aligned with target
- self.orbitFromCS.setHpr(self['nodePath'], 0,0,0)
- # Also update to CS
- self.orbitToCS.setPosHpr(self.orbitFromCS, 0,0,0,0,0,0)
- # Get offset from origin
- self.posOffset.assign(self['nodePath'].getPos(self.orbitFromCS))
- ### NODE PATH TRANSFORMATION OPERATIONS ###
- def xform(self, value, axis):
- if axis in ['sx', 'sy', 'sz']:
- self.xformScale(value,axis)
- elif self.movementMode == 'Relative To:':
- self.xformRelative(value, axis)
- elif self.movementMode == 'Orbit:':
- self.xformOrbit(value, axis)
- if self.nodePathMenu.get() == 'widget':
- if SEditor.manipulationControl.fSetCoa:
- # Update coa based on current widget position
- SEditor.selected.last.mCoa2Dnp.assign(
- SEditor.widget.getMat(SEditor.selected.last))
- else:
- # Move the objects with the widget
- SEditor.selected.moveWrtWidgetAll()
-
- def xformStart(self, data):
- # Record undo point
- self.pushUndo()
- # If moving widget kill follow task and update wrts
- if self.nodePathMenu.get() == 'widget':
- taskMgr.remove('followSelectedNodePath')
- # Record relationship between selected nodes and widget
- SEditor.selected.getWrtAll()
- # Record initial state
- self.deltaHpr = self['nodePath'].getHpr(self.refCS)
- # Update placer to reflect new state
- self.updatePlacer()
-
- def xformStop(self, data):
- # Throw event to signal manipulation done
- # Send nodepath as a list
- messenger.send('DIRECT_manipulateObjectCleanup', [[self['nodePath']]])
- # Update placer to reflect new state
- self.updatePlacer()
- # If moving widget restart follow task
- if self.nodePathMenu.get() == 'widget':
- # Restart followSelectedNodePath task
- SEditor.manipulationControl.spawnFollowSelectedNodePathTask()
- def xformRelative(self, value, axis):
- nodePath = self['nodePath']
- if (nodePath != None) and (self.refCS != None):
- if axis == 'x':
- nodePath.setX(self.refCS, value)
- elif axis == 'y':
- nodePath.setY(self.refCS, value)
- elif axis == 'z':
- nodePath.setZ(self.refCS, value)
- else:
- if axis == 'h':
- self.deltaHpr.setX(value)
- elif axis == 'p':
- self.deltaHpr.setY(value)
- elif axis == 'r':
- self.deltaHpr.setZ(value)
- # Put node path at new hpr
- nodePath.setHpr(self.refCS, self.deltaHpr)
- def xformOrbit(self, value, axis):
- nodePath = self['nodePath']
- if ((nodePath != None) and (self.refCS != None) and
- (self.orbitFromCS != None) and (self.orbitToCS != None)):
- if axis == 'x':
- self.posOffset.setX(value)
- elif axis == 'y':
- self.posOffset.setY(value)
- elif axis == 'z':
- self.posOffset.setZ(value)
- elif axis == 'h':
- self.orbitToCS.setH(self.orbitFromCS, value)
- elif axis == 'p':
- self.orbitToCS.setP(self.orbitFromCS, value)
- elif axis == 'r':
- self.orbitToCS.setR(self.orbitFromCS, value)
- nodePath.setPosHpr(self.orbitToCS, self.posOffset, ZERO_VEC)
- def xformScale(self, value, axis):
- if self['nodePath']:
- mode = self.scalingMode.get()
- scale = self['nodePath'].getScale()
- if mode == 'Scale Free':
- if axis == 'sx':
- scale.setX(value)
- elif axis == 'sy':
- scale.setY(value)
- elif axis == 'sz':
- scale.setZ(value)
- elif mode == 'Scale Uniform':
- scale.set(value,value,value)
- elif mode == 'Scale Proportional':
- if axis == 'sx':
- sf = value/scale[0]
- elif axis == 'sy':
- sf = value/scale[1]
- elif axis == 'sz':
- sf = value/scale[2]
- scale = scale * sf
- self['nodePath'].setScale(scale)
- def updatePosWidgets(self, pos):
- self.posX.set(pos[0])
- self.posY.set(pos[1])
- self.posZ.set(pos[2])
- def updateHprWidgets(self, hpr):
- self.hprH.set(hpr[0])
- self.hprP.set(hpr[1])
- self.hprR.set(hpr[2])
- def updateScaleWidgets(self, scale):
- self.scaleX.set(scale[0])
- self.scaleY.set(scale[1])
- self.scaleZ.set(scale[2])
- def zeroAll(self):
- self.xformStart(None)
- self.updatePosWidgets(ZERO_VEC)
- self.updateHprWidgets(ZERO_VEC)
- self.updateScaleWidgets(UNIT_VEC)
- self.xformStop(None)
- def zeroPos(self):
- self.xformStart(None)
- self.updatePosWidgets(ZERO_VEC)
- self.xformStop(None)
- def zeroHpr(self):
- self.xformStart(None)
- self.updateHprWidgets(ZERO_VEC)
- self.xformStop(None)
- def unitScale(self):
- self.xformStart(None)
- self.updateScaleWidgets(UNIT_VEC)
- self.xformStop(None)
- def updateResetValues(self, nodePath):
- self.initPos.assign(nodePath.getPos())
- self.posX['resetValue'] = self.initPos[0]
- self.posY['resetValue'] = self.initPos[1]
- self.posZ['resetValue'] = self.initPos[2]
- self.initHpr.assign(nodePath.getHpr())
- self.hprH['resetValue'] = self.initHpr[0]
- self.hprP['resetValue'] = self.initHpr[1]
- self.hprR['resetValue'] = self.initHpr[2]
- self.initScale.assign(nodePath.getScale())
- self.scaleX['resetValue'] = self.initScale[0]
- self.scaleY['resetValue'] = self.initScale[1]
- self.scaleZ['resetValue'] = self.initScale[2]
- def resetAll(self):
- if self['nodePath']:
- self.xformStart(None)
- self['nodePath'].setPosHprScale(
- self.initPos, self.initHpr, self.initScale)
- self.xformStop(None)
- def resetPos(self):
- if self['nodePath']:
- self.xformStart(None)
- self['nodePath'].setPos(self.initPos)
- self.xformStop(None)
- def resetHpr(self):
- if self['nodePath']:
- self.xformStart(None)
- self['nodePath'].setHpr(self.initHpr)
- self.xformStop(None)
- def resetScale(self):
- if self['nodePath']:
- self.xformStart(None)
- self['nodePath'].setScale(self.initScale)
- self.xformStop(None)
- def pushUndo(self, fResetRedo = 1):
- SEditor.pushUndo([self['nodePath']])
- def undoHook(self, nodePathList = []):
- # Reflect new changes
- self.updatePlacer()
- def pushUndoHook(self):
- # Make sure button is reactivated
- self.undoButton.configure(state = 'normal')
- def undoListEmptyHook(self):
- # Make sure button is deactivated
- self.undoButton.configure(state = 'disabled')
- def pushRedo(self):
- SEditor.pushRedo([self['nodePath']])
-
- def redoHook(self, nodePathList = []):
- # Reflect new changes
- self.updatePlacer()
- def pushRedoHook(self):
- # Make sure button is reactivated
- self.redoButton.configure(state = 'normal')
- def redoListEmptyHook(self):
- # Make sure button is deactivated
- self.redoButton.configure(state = 'disabled')
-
- def printNodePathInfo(self):
- np = self['nodePath']
- if np:
- name = np.getName()
- pos = np.getPos()
- hpr = np.getHpr()
- scale = np.getScale()
- posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2])
- hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2])
- scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[2])
- print 'NodePath: %s' % name
- print 'Pos: %s' % posString
- print 'Hpr: %s' % hprString
- print 'Scale: %s' % scaleString
- print ('%s.setPosHprScale(%s, %s, %s)' %
- (name, posString, hprString, scaleString))
- def onDestroy(self, event):
- # Remove hooks
- for event, method in self.undoEvents:
- self.ignore(event)
- self.tempCS.removeNode()
- self.orbitFromCS.removeNode()
- self.orbitToCS.removeNode()
- # send out a message to let sceneEditor know that placer panel has been closed.
- # Also, stop accepting the updata message from sceneEditor
- messenger.send('Placer_close')
- self.ignore('placerUpdate')
-
- def place(nodePath):
- return Placer(nodePath = nodePath)
- ######################################################################
- # Create demo in root window for testing.
- if __name__ == '__main__':
- root = Pmw.initialise()
- widget = Placer()
|