瀏覽代碼

Merge branch 'master' into vulkan

rdb 7 年之前
父節點
當前提交
e2f3b81749
共有 100 個文件被更改,包括 1459 次插入877 次删除
  1. 1 1
      .travis.yml
  2. 38 6
      README.md
  3. 1 1
      contrib/src/sceneeditor/MetadataPanel.py
  4. 37 29
      contrib/src/sceneeditor/SideWindow.py
  5. 3 4
      contrib/src/sceneeditor/collisionWindow.py
  6. 186 180
      contrib/src/sceneeditor/controllerWindow.py
  7. 50 48
      contrib/src/sceneeditor/dataHolder.py
  8. 2 2
      contrib/src/sceneeditor/duplicateWindow.py
  9. 32 25
      contrib/src/sceneeditor/lightingPanel.py
  10. 4 5
      contrib/src/sceneeditor/propertyWindow.py
  11. 6 8
      contrib/src/sceneeditor/quad.py
  12. 48 37
      contrib/src/sceneeditor/sceneEditor.py
  13. 9 5
      contrib/src/sceneeditor/seAnimPanel.py
  14. 9 5
      contrib/src/sceneeditor/seBlendAnimPanel.py
  15. 10 11
      contrib/src/sceneeditor/seCameraControl.py
  16. 8 2
      contrib/src/sceneeditor/seColorEntry.py
  17. 18 18
      contrib/src/sceneeditor/seFileSaver.py
  18. 1 3
      contrib/src/sceneeditor/seForceGroup.py
  19. 8 8
      contrib/src/sceneeditor/seGeometry.py
  20. 10 11
      contrib/src/sceneeditor/seLights.py
  21. 1 1
      contrib/src/sceneeditor/seManipulation.py
  22. 153 146
      contrib/src/sceneeditor/seMopathRecorder.py
  23. 4 4
      contrib/src/sceneeditor/seParticleEffect.py
  24. 29 22
      contrib/src/sceneeditor/seParticlePanel.py
  25. 5 25
      contrib/src/sceneeditor/seParticles.py
  26. 34 27
      contrib/src/sceneeditor/sePlacer.py
  27. 16 9
      contrib/src/sceneeditor/seSceneGraphExplorer.py
  28. 20 11
      contrib/src/sceneeditor/seSelection.py
  29. 9 6
      contrib/src/sceneeditor/seSession.py
  30. 15 9
      contrib/src/sceneeditor/seTree.py
  31. 1 1
      direct/src/dcparser/dcArrayParameter.h
  32. 1 1
      direct/src/dcparser/dcAtomicField.h
  33. 1 1
      direct/src/dcparser/dcClass.h
  34. 1 1
      direct/src/dcparser/dcClassParameter.h
  35. 1 1
      direct/src/dcparser/dcDeclaration.h
  36. 1 1
      direct/src/dcparser/dcField.h
  37. 1 1
      direct/src/dcparser/dcFile.h
  38. 1 1
      direct/src/dcparser/dcKeyword.h
  39. 1 1
      direct/src/dcparser/dcKeywordList.h
  40. 1 1
      direct/src/dcparser/dcMolecularField.h
  41. 5 5
      direct/src/dcparser/dcNumericRange.I
  42. 6 6
      direct/src/dcparser/dcNumericRange.h
  43. 1 1
      direct/src/dcparser/dcPackData.h
  44. 1 1
      direct/src/dcparser/dcPacker.h
  45. 1 1
      direct/src/dcparser/dcPackerCatalog.h
  46. 1 1
      direct/src/dcparser/dcPackerInterface.h
  47. 1 1
      direct/src/dcparser/dcParameter.h
  48. 1 1
      direct/src/dcparser/dcParserDefs.h
  49. 1 1
      direct/src/dcparser/dcSimpleParameter.h
  50. 1 1
      direct/src/dcparser/dcSwitch.h
  51. 1 1
      direct/src/dcparser/dcSwitchParameter.h
  52. 1 1
      direct/src/dcparser/dcTypedef.h
  53. 5 0
      direct/src/dcparser/dcbase.h
  54. 1 1
      direct/src/dcparser/hashGenerator.h
  55. 1 1
      direct/src/dcparser/primeNumberGenerator.h
  56. 1 1
      direct/src/deadrec/config_deadrec.cxx
  57. 9 0
      direct/src/directbase/directsymbols.h
  58. 1 1
      direct/src/directd/directd.cxx
  59. 2 2
      direct/src/distributed/PyDatagram.py
  60. 2 2
      direct/src/distributed/PyDatagramIterator.py
  61. 1 1
      direct/src/distributed/config_distributed.cxx
  62. 24 3
      direct/src/gui/DirectFrame.py
  63. 2 2
      direct/src/interval/cMetaInterval.cxx
  64. 1 1
      direct/src/interval/config_interval.cxx
  65. 1 0
      direct/src/leveleditor/ProtoPalette.py
  66. 1 1
      direct/src/motiontrail/config_motiontrail.cxx
  67. 2 2
      direct/src/showbase/Loader.py
  68. 20 12
      direct/src/showbase/Transitions.py
  69. 1 1
      direct/src/showbase/showBase.cxx
  70. 4 0
      dtool/src/cppparser/cppFunctionType.cxx
  71. 1 1
      dtool/src/dconfig/config_dconfig.cxx
  72. 14 14
      dtool/src/dtoolbase/atomicAdjust.h
  73. 3 0
      dtool/src/dtoolbase/dtool_platform.h
  74. 1 1
      dtool/src/dtoolbase/dtoolbase.cxx
  75. 49 16
      dtool/src/dtoolbase/dtoolbase_cc.h
  76. 2 9
      dtool/src/dtoolbase/mutexSpinlockImpl.I
  77. 10 1
      dtool/src/dtoolbase/mutexSpinlockImpl.cxx
  78. 5 3
      dtool/src/dtoolbase/mutexSpinlockImpl.h
  79. 1 1
      dtool/src/dtoolbase/stl_compares.I
  80. 0 3
      dtool/src/dtoolbase/typeHandle.cxx
  81. 0 3
      dtool/src/dtoolbase/typeHandle.h
  82. 1 1
      dtool/src/dtoolutil/config_dtoolutil.cxx
  83. 0 31
      dtool/src/dtoolutil/dSearchPath.cxx
  84. 7 4
      dtool/src/dtoolutil/dSearchPath.h
  85. 1 0
      dtool/src/dtoolutil/p3dtoolutil_ext_composite.cxx
  86. 1 1
      dtool/src/dtoolutil/stringDecoder.I
  87. 69 10
      dtool/src/dtoolutil/stringDecoder.cxx
  88. 9 6
      dtool/src/dtoolutil/stringDecoder.h
  89. 36 6
      dtool/src/dtoolutil/textEncoder.I
  90. 73 19
      dtool/src/dtoolutil/textEncoder.cxx
  91. 30 3
      dtool/src/dtoolutil/textEncoder.h
  92. 30 0
      dtool/src/dtoolutil/textEncoder_ext.I
  93. 159 0
      dtool/src/dtoolutil/textEncoder_ext.cxx
  94. 50 0
      dtool/src/dtoolutil/textEncoder_ext.h
  95. 2 3
      dtool/src/interrogate/functionRemap.cxx
  96. 24 6
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  97. 1 1
      dtool/src/interrogate/interrogate.cxx
  98. 1 1
      dtool/src/interrogate/interrogateBuilder.cxx
  99. 1 1
      dtool/src/interrogate/parameterRemapConcreteToPointer.cxx
  100. 1 1
      dtool/src/interrogate/parameterRemapReferenceToPointer.cxx

+ 1 - 1
.travis.yml

@@ -43,7 +43,7 @@ install:
 script:
 script:
     - $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4
     - $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4
     - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
     - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
-    - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest tests
+    - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests
 notifications:
 notifications:
   irc:
   irc:
     channels:
     channels:

+ 38 - 6
README.md

@@ -43,8 +43,9 @@ Building Panda3D
 Windows
 Windows
 -------
 -------
 
 
-We currently build using the Microsoft Visual C++ 2015 compiler.  You will
-also need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk),
+You can build Panda3D with the Microsoft Visual C++ 2015 or 2017 compiler,
+which can be downloaded for free from the [Visual Studio site](https://visualstudio.microsoft.com/downloads/).
+You will also need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk),
 and if you intend to target Windows XP, you will also need the
 and if you intend to target Windows XP, you will also need the
 [Windows 7.1 SDK](https://www.microsoft.com/en-us/download/details.aspx?id=8279).
 [Windows 7.1 SDK](https://www.microsoft.com/en-us/download/details.aspx?id=8279).
 
 
@@ -58,11 +59,12 @@ http://rdb.name/thirdparty-vc14-x64.7z
 http://rdb.name/thirdparty-vc14.7z
 http://rdb.name/thirdparty-vc14.7z
 
 
 After acquiring these dependencies, you may simply build Panda3D from the
 After acquiring these dependencies, you may simply build Panda3D from the
-command prompt using the following command.  (Add the `--windows-sdk=10`
-option if you don't need to support Windows XP.)
+command prompt using the following command.  (Change `14.1` to `14` if you are
+using Visual C++ 2015 instead of 2017.  Add the `--windows-sdk=10` option if
+you don't need to support Windows XP and did not install the Windows 7.1 SDK.)
 
 
 ```bash
 ```bash
-makepanda\makepanda.bat --everything --installer --no-eigen --threads=2
+makepanda\makepanda.bat --everything --installer --msvc-version=14.1 --no-eigen --threads=2
 ```
 ```
 
 
 When the build succeeds, it will produce an .exe file that you can use to
 When the build succeeds, it will produce an .exe file that you can use to
@@ -101,7 +103,7 @@ If you are on Ubuntu, this command should cover the most frequently
 used third-party packages:
 used third-party packages:
 
 
 ```bash
 ```bash
-sudo apt-get install build-essential pkg-config python-dev libpng-dev libjpeg-dev libtiff-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libeigen3-dev libopenal-dev libode-dev libbullet-dev nvidia-cg-toolkit libgtk2.0-dev
+sudo apt-get install build-essential pkg-config python-dev libpng-dev libjpeg-dev libtiff-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libeigen3-dev libopenal-dev libode-dev libbullet-dev nvidia-cg-toolkit libgtk2.0-dev libassimp-dev libopenexr-dev
 ```
 ```
 
 
 Once Panda3D has built, you can either install the .deb or .rpm package that
 Once Panda3D has built, you can either install the .deb or .rpm package that
@@ -163,6 +165,36 @@ python3.6 makepanda/makepanda.py --everything --installer --no-egl --no-gles --n
 If successful, this will produce a .pkg file in the root of the source
 If successful, this will produce a .pkg file in the root of the source
 directory which you can install using `pkg install`.
 directory which you can install using `pkg install`.
 
 
+Android
+-------
+
+Note: building on Android is very experimental and not guaranteed to work.
+
+You can experimentally build the Android Python runner via the [termux](https://termux.com/)
+shell.  You will need to install [Termux](https://play.google.com/store/apps/details?id=com.termux)
+and [Termux API](https://play.google.com/store/apps/details?id=com.termux.api)
+from the Play Store.  Many of the dependencies can be installed by running the
+following command in the Termux shell:
+
+```bash
+pkg install python-dev termux-tools ndk-stl ndk-sysroot clang libvorbis-dev libopus-dev opusfile-dev openal-soft-dev freetype-dev harfbuzz-dev libpng-dev ecj4.6 dx patchelf aapt apksigner libcrypt-dev
+```
+
+Then, you can build and install the .apk right away using these commands:
+
+```bash
+python makepanda/makepanda.py --everything --target android-21 --installer
+xdg-open panda3d.apk
+```
+
+To launch a Python program from Termux, you can use the `run_python.sh` script
+inside the `panda/src/android` directory.  It will launch Python in a separate
+activity, load it with the Python script you passed as argument, and use a
+socket for returning the command-line output to the Termux shell.  Do note
+that this requires the Python application to reside on the SD card and that
+Termux needs to be set up with access to the SD card (using the
+`termux-setup-storage` command).
+
 Running Tests
 Running Tests
 =============
 =============
 
 

+ 1 - 1
contrib/src/sceneeditor/MetadataPanel.py

@@ -36,7 +36,7 @@ class MetadataPanel(AppShell,Pmw.MegaWidget):
 
 
 
 
     def appInit(self):
     def appInit(self):
-        print "Metadata Panel"
+        print("Metadata Panel")
 
 
     def createInterface(self):
     def createInterface(self):
         interior = self.interior()
         interior = self.interior()

+ 37 - 29
contrib/src/sceneeditor/SideWindow.py

@@ -6,8 +6,16 @@ from direct.tkwidgets.AppShell import AppShell
 from direct.tkwidgets.VectorWidgets import ColorEntry
 from direct.tkwidgets.VectorWidgets import ColorEntry
 from direct.showbase.TkGlobal import spawnTkLoop
 from direct.showbase.TkGlobal import spawnTkLoop
 import seSceneGraphExplorer
 import seSceneGraphExplorer
-from Tkinter import Frame, IntVar, Checkbutton, Toplevel
-import Pmw, Tkinter
+
+import Pmw, sys
+
+if sys.version_info >= (3, 0):
+    from tkinter import Frame, IntVar, Checkbutton, Toplevel
+    import tkinter
+else:
+    from Tkinter import Frame, IntVar, Checkbutton, Toplevel
+    import Tkinter as tkinter
+
 
 
 class sideWindow(AppShell):
 class sideWindow(AppShell):
     #################################################################
     #################################################################
@@ -65,7 +73,7 @@ class sideWindow(AppShell):
         self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
         self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
 
 
     def appInit(self):
     def appInit(self):
-        print '----SideWindow is Initialized!!'
+        print('----SideWindow is Initialized!!')
 
 
     def createInterface(self):
     def createInterface(self):
         # The interior of the toplevel panel
         # The interior of the toplevel panel
@@ -73,7 +81,7 @@ class sideWindow(AppShell):
         mainFrame = Frame(interior)
         mainFrame = Frame(interior)
         ## Creat NoteBook
         ## Creat NoteBook
         self.notebookFrame = Pmw.NoteBook(mainFrame)
         self.notebookFrame = Pmw.NoteBook(mainFrame)
-        self.notebookFrame.pack(fill=Tkinter.BOTH,expand=1)
+        self.notebookFrame.pack(fill=tkinter.BOTH,expand=1)
         sgePage = self.notebookFrame.add('Tree Graph')
         sgePage = self.notebookFrame.add('Tree Graph')
         envPage = self.notebookFrame.add('World Setting')
         envPage = self.notebookFrame.add('World Setting')
         self.notebookFrame['raisecommand'] = self.updateInfo
         self.notebookFrame['raisecommand'] = self.updateInfo
@@ -83,7 +91,7 @@ class sideWindow(AppShell):
             sgePage, nodePath = render,
             sgePage, nodePath = render,
             scrolledCanvas_hull_width = 270,
             scrolledCanvas_hull_width = 270,
             scrolledCanvas_hull_height = 570)
             scrolledCanvas_hull_height = 570)
-        self.SGE.pack(fill = Tkinter.BOTH, expand = 0)
+        self.SGE.pack(fill = tkinter.BOTH, expand = 0)
 
 
         ## World Setting Page
         ## World Setting Page
         envPage = Frame(envPage)
         envPage = Frame(envPage)
@@ -95,8 +103,8 @@ class sideWindow(AppShell):
             text = 'Enable Lighting',
             text = 'Enable Lighting',
             variable = self.LightingVar,
             variable = self.LightingVar,
             command = self.toggleLights)
             command = self.toggleLights)
-        self.LightingButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.LightingButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.CollisionVar = IntVar()
         self.CollisionVar = IntVar()
@@ -106,8 +114,8 @@ class sideWindow(AppShell):
             text = 'Show Collision Object',
             text = 'Show Collision Object',
             variable = self.CollisionVar,
             variable = self.CollisionVar,
             command = self.showCollision)
             command = self.showCollision)
-        self.CollisionButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.CollisionButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.ParticleVar = IntVar()
         self.ParticleVar = IntVar()
@@ -117,8 +125,8 @@ class sideWindow(AppShell):
             text = 'Show Particle Dummy',
             text = 'Show Particle Dummy',
             variable = self.ParticleVar,
             variable = self.ParticleVar,
             command = self.enableParticle)
             command = self.enableParticle)
-        self.ParticleButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.ParticleButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.baseUseDriveVar = IntVar()
         self.baseUseDriveVar = IntVar()
@@ -128,8 +136,8 @@ class sideWindow(AppShell):
             text = 'Enable base.usedrive',
             text = 'Enable base.usedrive',
             variable = self.baseUseDriveVar,
             variable = self.baseUseDriveVar,
             command = self.enablebaseUseDrive)
             command = self.enablebaseUseDrive)
-        self.baseUseDriveButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.baseUseDriveButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.backfaceVar = IntVar()
         self.backfaceVar = IntVar()
@@ -139,8 +147,8 @@ class sideWindow(AppShell):
             text = 'Enable BackFace',
             text = 'Enable BackFace',
             variable = self.backfaceVar,
             variable = self.backfaceVar,
             command = self.toggleBackface)
             command = self.toggleBackface)
-        self.backfaceButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.backfaceButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.textureVar = IntVar()
         self.textureVar = IntVar()
@@ -150,8 +158,8 @@ class sideWindow(AppShell):
             text = 'Enable Texture',
             text = 'Enable Texture',
             variable = self.textureVar,
             variable = self.textureVar,
             command = self.toggleTexture)
             command = self.toggleTexture)
-        self.textureButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.textureButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.wireframeVar = IntVar()
         self.wireframeVar = IntVar()
@@ -161,8 +169,8 @@ class sideWindow(AppShell):
             text = 'Enable Wireframe',
             text = 'Enable Wireframe',
             variable = self.wireframeVar,
             variable = self.wireframeVar,
             command = self.toggleWireframe)
             command = self.toggleWireframe)
-        self.wireframeButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.wireframeButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.gridVar = IntVar()
         self.gridVar = IntVar()
@@ -172,8 +180,8 @@ class sideWindow(AppShell):
             text = 'Enable Grid',
             text = 'Enable Grid',
             variable = self.gridVar,
             variable = self.gridVar,
             command = self.toggleGrid)
             command = self.toggleGrid)
-        self.gridButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.gridButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.widgetVisVar = IntVar()
         self.widgetVisVar = IntVar()
@@ -183,8 +191,8 @@ class sideWindow(AppShell):
             text = 'Enable WidgetVisible',
             text = 'Enable WidgetVisible',
             variable = self.widgetVisVar,
             variable = self.widgetVisVar,
             command = self.togglewidgetVis)
             command = self.togglewidgetVis)
-        self.widgetVisButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.widgetVisButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.enableAutoCameraVar = IntVar()
         self.enableAutoCameraVar = IntVar()
@@ -194,17 +202,17 @@ class sideWindow(AppShell):
             text = 'Enable Auto Camera Movement for Loading Objects',
             text = 'Enable Auto Camera Movement for Loading Objects',
             variable = self.enableAutoCameraVar,
             variable = self.enableAutoCameraVar,
             command = self.toggleAutoCamera)
             command = self.toggleAutoCamera)
-        self.enableAutoCameraButton.pack(side=Tkinter.LEFT, expand=False)
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        self.enableAutoCameraButton.pack(side=tkinter.LEFT, expand=False)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         pageFrame = Frame(envPage)
         pageFrame = Frame(envPage)
         self.backgroundColor = ColorEntry(
         self.backgroundColor = ColorEntry(
             pageFrame, text = 'BG Color', value=self.worldColor)
             pageFrame, text = 'BG Color', value=self.worldColor)
         self.backgroundColor['command'] = self.setBackgroundColorVec
         self.backgroundColor['command'] = self.setBackgroundColorVec
         self.backgroundColor['resetValue'] = [0,0,0,0]
         self.backgroundColor['resetValue'] = [0,0,0,0]
-        self.backgroundColor.pack(side=Tkinter.LEFT, expand=False)
+        self.backgroundColor.pack(side=tkinter.LEFT, expand=False)
         self.bind(self.backgroundColor, 'Set background color')
         self.bind(self.backgroundColor, 'Set background color')
-        pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True)
+        pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
 
 
         envPage.pack(expand=False)
         envPage.pack(expand=False)
 
 
@@ -320,11 +328,11 @@ class sideWindow(AppShell):
         #
         #
         #################################################################
         #################################################################
         if self.enableBaseUseDrive==0:
         if self.enableBaseUseDrive==0:
-            print 'Enabled'
+            print('Enabled')
             base.useDrive()
             base.useDrive()
             self.enableBaseUseDrive = 1
             self.enableBaseUseDrive = 1
         else:
         else:
-            print 'disabled'
+            print('disabled')
             #base.useTrackball()
             #base.useTrackball()
             base.disableMouse()
             base.disableMouse()
             self.enableBaseUseDrive = 0
             self.enableBaseUseDrive = 0

+ 3 - 4
contrib/src/sceneeditor/collisionWindow.py

@@ -9,9 +9,8 @@ from seColorEntry import *
 from direct.tkwidgets import VectorWidgets
 from direct.tkwidgets import VectorWidgets
 from direct.tkwidgets import Floater
 from direct.tkwidgets import Floater
 from direct.tkwidgets import Slider
 from direct.tkwidgets import Slider
-from Tkinter import *
 import string, math, types
 import string, math, types
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 
 
 class collisionWindow(AppShell):
 class collisionWindow(AppShell):
@@ -195,7 +194,7 @@ class collisionWindow(AppShell):
         # put the object into a CollisionNode and attach it to the target nodePath
         # put the object into a CollisionNode and attach it to the target nodePath
         #################################################################
         #################################################################
         collisionObject = None
         collisionObject = None
-        print self.objType
+        print(self.objType)
         if self.objType=='collisionPolygon':
         if self.objType=='collisionPolygon':
             pointA =  Point3(float(self.widgetDict['PolygonPoint A'][0]._entry.get()),
             pointA =  Point3(float(self.widgetDict['PolygonPoint A'][0]._entry.get()),
                              float(self.widgetDict['PolygonPoint A'][1]._entry.get()),
                              float(self.widgetDict['PolygonPoint A'][1]._entry.get()),
@@ -236,7 +235,7 @@ class collisionWindow(AppShell):
                            float(self.widgetDict['RayDirection'][1]._entry.get()),
                            float(self.widgetDict['RayDirection'][1]._entry.get()),
                            float(self.widgetDict['RayDirection'][2]._entry.get()))
                            float(self.widgetDict['RayDirection'][2]._entry.get()))
 
 
-            print vector, point
+            print(vector, point)
 
 
             collisionObject = CollisionRay()
             collisionObject = CollisionRay()
             collisionObject.setOrigin(point)
             collisionObject.setOrigin(point)

+ 186 - 180
contrib/src/sceneeditor/controllerWindow.py

@@ -4,8 +4,14 @@
 #################################################################
 #################################################################
 
 
 from direct.tkwidgets.AppShell import AppShell
 from direct.tkwidgets.AppShell import AppShell
-from Tkinter import Frame, Label, Button
-import string, Pmw, Tkinter
+import sys, Pmw
+
+if sys.version_info >= (3, 0):
+    from tkinter import Frame, Label, Button
+    import tkinter
+else:
+    from Tkinter import Frame, Label, Button
+    import Tkinter as tkinter
 
 
 # Define the Category
 # Define the Category
 KEYBOARD = 'Keyboard-'
 KEYBOARD = 'Keyboard-'
@@ -75,11 +81,11 @@ class controllerWindow(AppShell):
         self.cotrollerTypeEntry = self.createcomponent(
         self.cotrollerTypeEntry = self.createcomponent(
             'Controller Type', (), None,
             'Controller Type', (), None,
             Pmw.ComboBox, (frame,),
             Pmw.ComboBox, (frame,),
-            labelpos = Tkinter.W, label_text='Controller Type:', entry_width = 20,entry_state = Tkinter.DISABLED,
+            labelpos = tkinter.W, label_text='Controller Type:', entry_width = 20,entry_state = tkinter.DISABLED,
             selectioncommand = self.setControllerType,
             selectioncommand = self.setControllerType,
             scrolledlist_items = self.controllerList)
             scrolledlist_items = self.controllerList)
-        self.cotrollerTypeEntry.pack(side=Tkinter.LEFT)
-        frame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=False, pady = 3)
+        self.cotrollerTypeEntry.pack(side=tkinter.LEFT)
+        frame.pack(side=tkinter.TOP, fill=tkinter.X, expand=False, pady = 3)
         self.cotrollerTypeEntry.selectitem('Keyboard', setentry=True)
         self.cotrollerTypeEntry.selectitem('Keyboard', setentry=True)
 
 
         self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None)
         self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None)
@@ -102,7 +108,7 @@ class controllerWindow(AppShell):
         keyboardPage = self.objNotebook.add('Keyboard')
         keyboardPage = self.objNotebook.add('Keyboard')
         tarckerPage = self.objNotebook.add('Tracker')
         tarckerPage = self.objNotebook.add('Tracker')
         self.objNotebook.selectpage('Keyboard')
         self.objNotebook.selectpage('Keyboard')
-        self.objNotebook.pack(side = Tkinter.TOP, fill='both',expand=False)
+        self.objNotebook.pack(side = tkinter.TOP, fill='both',expand=False)
         # Put this here so it isn't called right away
         # Put this here so it isn't called right away
         self.objNotebook['raisecommand'] = self.updateControlInfo
         self.objNotebook['raisecommand'] = self.updateControlInfo
 
 
@@ -113,11 +119,11 @@ class controllerWindow(AppShell):
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Target Type', (), None,
             'Target Type', (), None,
             Pmw.ComboBox, (Interior,),
             Pmw.ComboBox, (Interior,),
-            labelpos = Tkinter.W, label_text='Target Object:', entry_width = 20, entry_state = Tkinter.DISABLED,
+            labelpos = tkinter.W, label_text='Target Object:', entry_width = 20, entry_state = tkinter.DISABLED,
             selectioncommand = self.setTargetObj,
             selectioncommand = self.setTargetObj,
             scrolledlist_items = self.listOfObj)
             scrolledlist_items = self.listOfObj)
-        widget.pack(side=Tkinter.LEFT, padx=3)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 5)
+        widget.pack(side=tkinter.LEFT, padx=3)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 5)
         widget.selectitem(self.nameOfNode, setentry=True)
         widget.selectitem(self.nameOfNode, setentry=True)
         self.widgetsDict[KEYBOARD+'ObjList'] = widget
         self.widgetsDict[KEYBOARD+'ObjList'] = widget
 
 
@@ -126,411 +132,411 @@ class controllerWindow(AppShell):
         settingFrame = inputZone.interior()
         settingFrame = inputZone.interior()
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Assign a Key For:').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True,pady = 6 )
+        widget = Label(Interior, text = 'Assign a Key For:').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True,pady = 6 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Forward   :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Forward   :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Forward key', (), None,
             'Forward key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyForward'],
             value = self.keyboardMapDict['KeyForward'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyForward'] = widget
         self.widgetsDict[KEYBOARD+'KeyForward'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Forward Speed', (), None,
             'Forward Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedForward'],
             value = self.keyboardSpeedDict['SpeedForward'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedForward'] = widget
         self.widgetsDict[KEYBOARD+'SpeedForward'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Backward  :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Backward  :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Backward key', (), None,
             'Backward key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyBackward'],
             value = self.keyboardMapDict['KeyBackward'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyBackward'] = widget
         self.widgetsDict[KEYBOARD+'KeyBackward'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Backward Speed', (), None,
             'Backward Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedBackward'],
             value = self.keyboardSpeedDict['SpeedBackward'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedBackward'] = widget
         self.widgetsDict[KEYBOARD+'SpeedBackward'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Right     :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Right     :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Right key', (), None,
             'Right key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyRight'],
             value = self.keyboardMapDict['KeyRight'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyRight'] = widget
         self.widgetsDict[KEYBOARD+'KeyRight'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Right Speed', (), None,
             'Right Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedRight'],
             value = self.keyboardSpeedDict['SpeedRight'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedRight'] = widget
         self.widgetsDict[KEYBOARD+'SpeedRight'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Left      :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Left      :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Left key', (), None,
             'Left key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyLeft'],
             value = self.keyboardMapDict['KeyLeft'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyLeft'] = widget
         self.widgetsDict[KEYBOARD+'KeyLeft'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Left Speed', (), None,
             'Left Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedLeft'],
             value = self.keyboardSpeedDict['SpeedLeft'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedLeft'] = widget
         self.widgetsDict[KEYBOARD+'SpeedLeft'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Up        :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Up        :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Up key', (), None,
             'Up key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyUp'],
             value = self.keyboardMapDict['KeyUp'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyUp'] = widget
         self.widgetsDict[KEYBOARD+'KeyUp'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Up Speed', (), None,
             'Up Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedUp'],
             value = self.keyboardSpeedDict['SpeedUp'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedUp'] = widget
         self.widgetsDict[KEYBOARD+'SpeedUp'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Down      :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Down      :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Down key', (), None,
             'Down key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyDown'],
             value = self.keyboardMapDict['KeyDown'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyDown'] = widget
         self.widgetsDict[KEYBOARD+'KeyDown'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Down Speed', (), None,
             'Down Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedDown'],
             value = self.keyboardSpeedDict['SpeedDown'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedDown'] = widget
         self.widgetsDict[KEYBOARD+'SpeedDown'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Turn Right:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Turn Right:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn Right key', (), None,
             'Turn Right key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyTurnRight'],
             value = self.keyboardMapDict['KeyTurnRight'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyTurnRight'] = widget
         self.widgetsDict[KEYBOARD+'KeyTurnRight'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn Right Speed', (), None,
             'Turn Right Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedTurnRight'],
             value = self.keyboardSpeedDict['SpeedTurnRight'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedTurnRight'] = widget
         self.widgetsDict[KEYBOARD+'SpeedTurnRight'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Turn Left :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Turn Left :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn Left key', (), None,
             'Turn Left key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyTurnLeft'],
             value = self.keyboardMapDict['KeyTurnLeft'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyTurnLeft'] = widget
         self.widgetsDict[KEYBOARD+'KeyTurnLeft'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn Left Speed', (), None,
             'Turn Left Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedTurnLeft'],
             value = self.keyboardSpeedDict['SpeedTurnLeft'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedTurnLeft'] = widget
         self.widgetsDict[KEYBOARD+'SpeedTurnLeft'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Turn UP   :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Turn UP   :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn UP key', (), None,
             'Turn UP key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyTurnUp'],
             value = self.keyboardMapDict['KeyTurnUp'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyTurnUp'] = widget
         self.widgetsDict[KEYBOARD+'KeyTurnUp'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn UP Speed', (), None,
             'Turn UP Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedTurnUp'],
             value = self.keyboardSpeedDict['SpeedTurnUp'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedTurnUp'] = widget
         self.widgetsDict[KEYBOARD+'SpeedTurnUp'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Turn Down :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Turn Down :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn Down key', (), None,
             'Turn Down key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyTurnDown'],
             value = self.keyboardMapDict['KeyTurnDown'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyTurnDown'] = widget
         self.widgetsDict[KEYBOARD+'KeyTurnDown'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Turn Down Speed', (), None,
             'Turn Down Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedTurnDown'],
             value = self.keyboardSpeedDict['SpeedTurnDown'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedTurnDown'] = widget
         self.widgetsDict[KEYBOARD+'SpeedTurnDown'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Roll Right:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Roll Right:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Roll Right key', (), None,
             'Roll Right key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyRollRight'],
             value = self.keyboardMapDict['KeyRollRight'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyRollRight'] = widget
         self.widgetsDict[KEYBOARD+'KeyRollRight'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Roll Right Speed', (), None,
             'Roll Right Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedRollRight'],
             value = self.keyboardSpeedDict['SpeedRollRight'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedRollRight'] = widget
         self.widgetsDict[KEYBOARD+'SpeedRollRight'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Roll Left :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Roll Left :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Roll Left key', (), None,
             'Roll Left key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyRollLeft'],
             value = self.keyboardMapDict['KeyRollLeft'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyRollLeft'] = widget
         self.widgetsDict[KEYBOARD+'KeyRollLeft'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Roll Left Speed', (), None,
             'Roll Left Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedRollLeft'],
             value = self.keyboardSpeedDict['SpeedRollLeft'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedRollLeft'] = widget
         self.widgetsDict[KEYBOARD+'SpeedRollLeft'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale UP key', (), None,
             'Scale UP key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleUp'],
             value = self.keyboardMapDict['KeyScaleUp'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleUp'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleUp'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale UP Speed', (), None,
             'Scale UP Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleUp'],
             value = self.keyboardSpeedDict['SpeedScaleUp'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleUp'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleUp'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Down key', (), None,
             'Scale Down key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleDown'],
             value = self.keyboardMapDict['KeyScaleDown'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleDown'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleDown'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Down Speed', (), None,
             'Scale Down Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleDown'],
             value = self.keyboardSpeedDict['SpeedScaleDown'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleDown'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleDown'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale X UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale X UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale X UP key', (), None,
             'Scale X UP key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleXUp'],
             value = self.keyboardMapDict['KeyScaleXUp'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleXUp'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleXUp'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale X UP Speed', (), None,
             'Scale X UP Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleXUp'],
             value = self.keyboardSpeedDict['SpeedScaleXUp'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleXUp'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleXUp'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale X Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale X Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale X Down key', (), None,
             'Scale X Down key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleXDown'],
             value = self.keyboardMapDict['KeyScaleXDown'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleXDown'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleXDown'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Down X Speed', (), None,
             'Scale Down X Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleXDown'],
             value = self.keyboardSpeedDict['SpeedScaleXDown'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleXDown'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleXDown'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale Y UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale Y UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Y UP key', (), None,
             'Scale Y UP key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleYUp'],
             value = self.keyboardMapDict['KeyScaleYUp'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleYUp'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleYUp'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Y UP Speed', (), None,
             'Scale Y UP Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleYUp'],
             value = self.keyboardSpeedDict['SpeedScaleYUp'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleYUp'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleYUp'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale Y Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale Y Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Y Down key', (), None,
             'Scale Y Down key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleYDown'],
             value = self.keyboardMapDict['KeyScaleYDown'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleYDown'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleYDown'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Down XY Speed', (), None,
             'Scale Down XY Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleYDown'],
             value = self.keyboardSpeedDict['SpeedScaleYDown'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleYDown'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleYDown'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale Z UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale Z UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Z UP key', (), None,
             'Scale Z UP key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleZUp'],
             value = self.keyboardMapDict['KeyScaleZUp'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleZUp'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleZUp'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Z UP Speed', (), None,
             'Scale Z UP Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleZUp'],
             value = self.keyboardSpeedDict['SpeedScaleZUp'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleZUp'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleZUp'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
         Interior = Frame(settingFrame)
         Interior = Frame(settingFrame)
-        widget = Label(Interior, text = 'Scale Z Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = 'Scale Z Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Z Down key', (), None,
             'Scale Z Down key', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardMapDict['KeyScaleZDown'],
             value = self.keyboardMapDict['KeyScaleZDown'],
-            labelpos = Tkinter.W, label_text='Key :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Key :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'KeyScaleZDown'] = widget
         self.widgetsDict[KEYBOARD+'KeyScaleZDown'] = widget
-        widget = Label(Interior, text = '   ').pack(side=Tkinter.LEFT, expand = False)
+        widget = Label(Interior, text = '   ').pack(side=tkinter.LEFT, expand = False)
         widget = self.createcomponent(
         widget = self.createcomponent(
             'Scale Down Z Speed', (), None,
             'Scale Down Z Speed', (), None,
             Pmw.EntryField, (Interior,),
             Pmw.EntryField, (Interior,),
             value = self.keyboardSpeedDict['SpeedScaleZDown'],
             value = self.keyboardSpeedDict['SpeedScaleZDown'],
-            labelpos = Tkinter.W, label_text='Speed :', entry_width = 10)
-        widget.pack(side=Tkinter.LEFT, expand = False)
+            labelpos = tkinter.W, label_text='Speed :', entry_width = 10)
+        widget.pack(side=tkinter.LEFT, expand = False)
         self.widgetsDict[KEYBOARD+'SpeedScaleZDown'] = widget
         self.widgetsDict[KEYBOARD+'SpeedScaleZDown'] = widget
-        widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False)
-        Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 )
+        widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False)
+        Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 )
 
 
-        assignFrame.pack(side=Tkinter.TOP, expand=True, fill = Tkinter.X)
-        keyboardPage.pack(side=Tkinter.TOP, expand=True, fill = Tkinter.X)
+        assignFrame.pack(side=tkinter.TOP, expand=True, fill = tkinter.X)
+        keyboardPage.pack(side=tkinter.TOP, expand=True, fill = tkinter.X)
 
 
         ####################################################################
         ####################################################################
         ####################################################################
         ####################################################################
@@ -539,12 +545,12 @@ class controllerWindow(AppShell):
         ####################################################################
         ####################################################################
         # Pack the mainFrame
         # Pack the mainFrame
         frame = Frame(mainFrame)
         frame = Frame(mainFrame)
-        widget = Button(frame, text='OK', width = 13, command=self.ok_press).pack(side=Tkinter.RIGHT)
-        widget = Button(frame, text='Enable Control', width = 13, command=self.enableControl).pack(side=Tkinter.LEFT)
-        widget = Button(frame, text='Disable Control', width = 13, command=self.disableControl).pack(side=Tkinter.LEFT)
-        widget = Button(frame, text='Save & Keep', width = 13, command=self.saveKeepControl).pack(side=Tkinter.LEFT)
-        frame.pack(side = Tkinter.BOTTOM, expand=1, fill = Tkinter.X)
-        mainFrame.pack(expand=1, fill = Tkinter.BOTH)
+        widget = Button(frame, text='OK', width = 13, command=self.ok_press).pack(side=tkinter.RIGHT)
+        widget = Button(frame, text='Enable Control', width = 13, command=self.enableControl).pack(side=tkinter.LEFT)
+        widget = Button(frame, text='Disable Control', width = 13, command=self.disableControl).pack(side=tkinter.LEFT)
+        widget = Button(frame, text='Save & Keep', width = 13, command=self.saveKeepControl).pack(side=tkinter.LEFT)
+        frame.pack(side = tkinter.BOTTOM, expand=1, fill = tkinter.X)
+        mainFrame.pack(expand=1, fill = tkinter.BOTH)
 
 
     def onDestroy(self, event):
     def onDestroy(self, event):
         # Check if user wish to keep the control after the window closed.
         # Check if user wish to keep the control after the window closed.
@@ -688,7 +694,7 @@ class controllerWindow(AppShell):
                 self.keyboardMapDict[index] = self.widgetsDict['Keyboard-'+index].getvalue()
                 self.keyboardMapDict[index] = self.widgetsDict['Keyboard-'+index].getvalue()
             for index in self.keyboardSpeedDict:
             for index in self.keyboardSpeedDict:
                 self.keyboardSpeedDict[index] = float(self.widgetsDict['Keyboard-'+index].getvalue())
                 self.keyboardSpeedDict[index] = float(self.widgetsDict['Keyboard-'+index].getvalue())
-            print self.nodePath
+            print(self.nodePath)
             messenger.send('ControlW_saveSetting', ['Keyboard', [self.nodePath, self.keyboardMapDict, self.keyboardSpeedDict]])
             messenger.send('ControlW_saveSetting', ['Keyboard', [self.nodePath, self.keyboardMapDict, self.keyboardSpeedDict]])
         return
         return
 
 

+ 50 - 48
contrib/src/sceneeditor/dataHolder.py

@@ -2,13 +2,15 @@
 # TK and PMW INTERFACE MODULES#
 # TK and PMW INTERFACE MODULES#
 ###############################
 ###############################
 from direct.showbase.TkGlobal import*
 from direct.showbase.TkGlobal import*
-from tkFileDialog import *
 import Pmw
 import Pmw
-import tkFileDialog
-import tkMessageBox
 from direct.tkwidgets import Dial
 from direct.tkwidgets import Dial
 from direct.tkwidgets import Floater
 from direct.tkwidgets import Floater
 
 
+if sys.version_info >= (3, 0):
+    from tkinter.filedialog import askopenfilename
+else:
+    from tkFileDialog import askopenfilename
+
 
 
 #############################
 #############################
 # Scene Editor Python Files #
 # Scene Editor Python Files #
@@ -154,7 +156,7 @@ class dataHolder:
         self.ActorNum=0
         self.ActorNum=0
         self.theScene=None
         self.theScene=None
         messenger.send('SGE_Update Explorer',[render])
         messenger.send('SGE_Update Explorer',[render])
-        print 'Scene should be cleaned up!'
+        print('Scene should be cleaned up!')
 
 
     def removeObj(self, nodePath):
     def removeObj(self, nodePath):
         #################################################################
         #################################################################
@@ -169,7 +171,7 @@ class dataHolder:
         childrenList = nodePath.getChildren()
         childrenList = nodePath.getChildren()
 
 
 
 
-        if self.ModelDic.has_key(name):
+        if name in self.ModelDic:
             del self.ModelDic[name]
             del self.ModelDic[name]
             del self.ModelRefDic[name]
             del self.ModelRefDic[name]
             if len(childrenList) != 0:
             if len(childrenList) != 0:
@@ -178,7 +180,7 @@ class dataHolder:
             nodePath.removeNode()
             nodePath.removeNode()
             self.ModelNum -= 1
             self.ModelNum -= 1
             pass
             pass
-        elif self.ActorDic.has_key(name):
+        elif name in self.ActorDic:
             del self.ActorDic[name]
             del self.ActorDic[name]
             del self.ActorRefDic[name]
             del self.ActorRefDic[name]
             if len(childrenList) != 0:
             if len(childrenList) != 0:
@@ -187,14 +189,14 @@ class dataHolder:
             nodePath.removeNode()
             nodePath.removeNode()
             self.ActorNum -= 1
             self.ActorNum -= 1
             pass
             pass
-        elif self.collisionDict.has_key(name):
+        elif name in self.collisionDict:
             del self.collisionDict[name]
             del self.collisionDict[name]
             if len(childrenList) != 0:
             if len(childrenList) != 0:
                 for node in childrenList:
                 for node in childrenList:
                     self.removeObj(node)
                     self.removeObj(node)
             nodePath.removeNode()
             nodePath.removeNode()
             pass
             pass
-        elif self.dummyDict.has_key(name):
+        elif name in self.dummyDict:
             del self.dummyDict[name]
             del self.dummyDict[name]
             if len(childrenList) != 0:
             if len(childrenList) != 0:
                 for node in childrenList:
                 for node in childrenList:
@@ -207,12 +209,12 @@ class dataHolder:
                     self.removeObj(node)
                     self.removeObj(node)
             list = self.lightManager.delete(name)
             list = self.lightManager.delete(name)
             return list
             return list
-        elif self.particleNodes.has_key(name):
+        elif name in self.particleNodes:
             self.particleNodes[name].removeNode()
             self.particleNodes[name].removeNode()
             del self.particleNodes[name]
             del self.particleNodes[name]
             del self.particleDict[name]
             del self.particleDict[name]
         else:
         else:
-            print 'You cannot remove this NodePath'
+            print('You cannot remove this NodePath')
             return
             return
 
 
         messenger.send('SGE_Update Explorer',[render])
         messenger.send('SGE_Update Explorer',[render])
@@ -237,15 +239,15 @@ class dataHolder:
         cHpr = hpr
         cHpr = hpr
         cScale = scale
         cScale = scale
         parent = nodePath.getParent()
         parent = nodePath.getParent()
-        if self.ActorDic.has_key(name):
+        if name in self.ActorDic:
             holder = self.ActorDic
             holder = self.ActorDic
             holderRef = self.ActorRefDic
             holderRef = self.ActorRefDic
             isModel = False
             isModel = False
-        elif self.ModelDic.has_key(name):
+        elif name in self.ModelDic:
             holder = self.ModelDic
             holder = self.ModelDic
             holderRef = self.ModelRefDic
             holderRef = self.ModelRefDic
         else:
         else:
-            print '---- DataHolder: Target Obj is not a legal object could be duplicate!'
+            print('---- DataHolder: Target Obj is not a legal object could be duplicate!')
             return
             return
 
 
         FilePath = holderRef[name]
         FilePath = holderRef[name]
@@ -356,7 +358,7 @@ class dataHolder:
         # This funciton will return True if there is an Actor in the scene named "name"
         # This funciton will return True if there is an Actor in the scene named "name"
         # and will return False if not.
         # and will return False if not.
         ###########################################################################
         ###########################################################################
-        return self.ActorDic.has_key(name)
+        return name in self.ActorDic
 
 
     def getActor(self, name):
     def getActor(self, name):
         ###########################################################################
         ###########################################################################
@@ -366,7 +368,7 @@ class dataHolder:
         if self.isActor(name):
         if self.isActor(name):
             return self.ActorDic[name]
             return self.ActorDic[name]
         else:
         else:
-            print '----No Actor named: ', name
+            print('----No Actor named: ', name)
             return None
             return None
 
 
     def getModel(self, name):
     def getModel(self, name):
@@ -377,7 +379,7 @@ class dataHolder:
         if self.isModel(name):
         if self.isModel(name):
             return self.ModelDic[name]
             return self.ModelDic[name]
         else:
         else:
-            print '----No Model named: ', name
+            print('----No Model named: ', name)
             return None
             return None
 
 
     def isModel(self, name):
     def isModel(self, name):
@@ -386,7 +388,7 @@ class dataHolder:
         # This funciton will return True if there is a Model in the scene named "name"
         # This funciton will return True if there is a Model in the scene named "name"
         # and will return False if not.
         # and will return False if not.
         ###########################################################################
         ###########################################################################
-        return self.ModelDic.has_key(name)
+        return name in self.ModelDic
 
 
     def loadAnimation(self,name, Dic):
     def loadAnimation(self,name, Dic):
         ###########################################################################
         ###########################################################################
@@ -406,7 +408,7 @@ class dataHolder:
             messenger.send('DataH_loadFinish'+name)
             messenger.send('DataH_loadFinish'+name)
             return
             return
         else:
         else:
-            print '------ Error when loading animation for Actor: ', name
+            print('------ Error when loading animation for Actor: ', name)
 
 
     def removeAnimation(self, name, anim):
     def removeAnimation(self, name, anim):
         ###########################################################################
         ###########################################################################
@@ -527,7 +529,7 @@ class dataHolder:
             self.ActorDic[nName]= self.ActorDic[oName]
             self.ActorDic[nName]= self.ActorDic[oName]
             self.ActorRefDic[nName]= self.ActorRefDic[oName]
             self.ActorRefDic[nName]= self.ActorRefDic[oName]
             self.ActorDic[nName].setName(nName)
             self.ActorDic[nName].setName(nName)
-            if self.blendAnimDict.has_key(oName):
+            if oName in self.blendAnimDict:
                 self.blendAnimDict[nName] = self.blendAnimDict[oName]
                 self.blendAnimDict[nName] = self.blendAnimDict[oName]
                 del self.blendAnimDict[oName]
                 del self.blendAnimDict[oName]
             del self.ActorDic[oName]
             del self.ActorDic[oName]
@@ -540,16 +542,16 @@ class dataHolder:
             del self.ModelRefDic[oName]
             del self.ModelRefDic[oName]
         elif self.lightManager.isLight(oName):
         elif self.lightManager.isLight(oName):
             list, lightNode = self.lightManager.rename(oName, nName)
             list, lightNode = self.lightManager.rename(oName, nName)
-        elif self.dummyDict.has_key(oName):
+        elif oName in self.dummyDict:
             self.dummyDict[nName]= self.dummyDict[oName]
             self.dummyDict[nName]= self.dummyDict[oName]
             self.dummyDict[nName].setName(nName)
             self.dummyDict[nName].setName(nName)
             del self.dummyDict[oName]
             del self.dummyDict[oName]
-        elif self.collisionDict.has_key(oName):
+        elif oName in self.collisionDict:
             self.collisionDict[nName]= self.collisionDict[oName]
             self.collisionDict[nName]= self.collisionDict[oName]
             self.collisionDict[nName].setName(nName)
             self.collisionDict[nName].setName(nName)
             del self.collisionDict[oName]
             del self.collisionDict[oName]
 
 
-        elif self.particleNodes.has_key(oName):
+        elif oName in self.particleNodes:
             self.particleNodes[nName]= self.particleNodes[oName]
             self.particleNodes[nName]= self.particleNodes[oName]
             self.particleDict[nName]= self.particleDict[oName]
             self.particleDict[nName]= self.particleDict[oName]
             self.particleDict[nName].setName(nName)
             self.particleDict[nName].setName(nName)
@@ -557,9 +559,9 @@ class dataHolder:
             del self.particleNodes[oName]
             del self.particleNodes[oName]
             del self.particleDict[oName]
             del self.particleDict[oName]
         else:
         else:
-            print '----Error: This Object is not allowed to this function!'
+            print('----Error: This Object is not allowed to this function!')
 
 
-        if self.curveDict.has_key(oName):
+        if oName in self.curveDict:
             self.curveDict[nName] = self.curveDict[oName]
             self.curveDict[nName] = self.curveDict[oName]
             del self.curveDict[oName]
             del self.curveDict[oName]
 
 
@@ -578,11 +580,11 @@ class dataHolder:
             return True
             return True
         elif self.lightManager.isLight(name):
         elif self.lightManager.isLight(name):
             return True
             return True
-        elif self.dummyDict.has_key(name):
+        elif name in self.dummyDict:
             return True
             return True
-        elif self.collisionDict.has_key(name):
+        elif name in self.collisionDict:
             return True
             return True
-        elif self.particleNodes.has_key(name):
+        elif name in self.particleNodes:
             return True
             return True
         elif (name == 'render')or(name == 'SEditor')or(name == 'Lights')or(name == 'camera'):
         elif (name == 'render')or(name == 'SEditor')or(name == 'Lights')or(name == 'camera'):
             return True
             return True
@@ -596,7 +598,7 @@ class dataHolder:
         # using the node name as a reference to assosiate a list which contains all curves related to that node.
         # using the node name as a reference to assosiate a list which contains all curves related to that node.
         ###########################################################################
         ###########################################################################
         name = node.getName()
         name = node.getName()
-        if self.curveDict.has_key(name):
+        if name in self.curveDict:
             self.curveDict[name].append(curveCollection)
             self.curveDict[name].append(curveCollection)
             return
             return
         else:
         else:
@@ -612,7 +614,7 @@ class dataHolder:
         # If the input node has not been bindedwith any curve, it will return None.
         # If the input node has not been bindedwith any curve, it will return None.
         ###########################################################################
         ###########################################################################
         name = nodePath.getName()
         name = nodePath.getName()
-        if self.curveDict.has_key(name):
+        if name in self.curveDict:
             return self.curveDict[name]
             return self.curveDict[name]
         else:
         else:
             return None
             return None
@@ -626,7 +628,7 @@ class dataHolder:
         # This message will be caught by Property Window for this node.
         # This message will be caught by Property Window for this node.
         ###########################################################################
         ###########################################################################
         name =nodePath.getName()
         name =nodePath.getName()
-        if self.curveDict.has_key(name):
+        if name in self.curveDict:
             index = None
             index = None
             for curve in self.curveDict[name]:
             for curve in self.curveDict[name]:
                 if curve.getCurve(0).getName() == curveName:
                 if curve.getCurve(0).getName() == curveName:
@@ -677,12 +679,12 @@ class dataHolder:
         elif self.isLight(name):
         elif self.isLight(name):
             type = 'Light'
             type = 'Light'
             info['lightNode'] = self.lightManager.getLightNode(name)
             info['lightNode'] = self.lightManager.getLightNode(name)
-        elif self.dummyDict.has_key(name):
+        elif name in self.dummyDict:
             type = 'dummy'
             type = 'dummy'
-        elif self.collisionDict.has_key(name):
+        elif name in self.collisionDict:
             type = 'collisionNode'
             type = 'collisionNode'
             info['collisionNode'] = self.collisionDict[name]
             info['collisionNode'] = self.collisionDict[name]
-        if self.curveDict.has_key(name):
+        if name in self.curveDict:
             info['curveList'] = self.getCurveList(nodePath)
             info['curveList'] = self.getCurveList(nodePath)
 
 
         return type, info
         return type, info
@@ -794,7 +796,7 @@ class dataHolder:
         # The formate of thsi dictionary is
         # The formate of thsi dictionary is
         # {"name of Blend Animation" : ["Animation A, Animation B, Effect(Float, 0~1)"]}
         # {"name of Blend Animation" : ["Animation A, Animation B, Effect(Float, 0~1)"]}
         ###########################################################################
         ###########################################################################
-        if self.blendAnimDict.has_key(name):
+        if name in self.blendAnimDict:
             return self.blendAnimDict[name]
             return self.blendAnimDict[name]
         else:
         else:
             return {}
             return {}
@@ -808,8 +810,8 @@ class dataHolder:
         # Also, if this blend is the first blend animation that the target actor has,
         # Also, if this blend is the first blend animation that the target actor has,
         # this function will add a "Blending" tag on this actor which is "True".
         # this function will add a "Blending" tag on this actor which is "True".
         ###########################################################################
         ###########################################################################
-        if self.blendAnimDict.has_key(actorName):
-            if self.blendAnimDict[actorName].has_key(blendName):
+        if actorName in self.blendAnimDict:
+            if blendName in self.blendAnimDict[actorName]:
                 ### replace the original setting
                 ### replace the original setting
                 self.blendAnimDict[actorName][blendName][0] = animNameA
                 self.blendAnimDict[actorName][blendName][0] = animNameA
                 self.blendAnimDict[actorName][blendName][1] = animNameB
                 self.blendAnimDict[actorName][blendName][1] = animNameB
@@ -832,7 +834,7 @@ class dataHolder:
         # it will also rewrite the data to the newest one.
         # it will also rewrite the data to the newest one.
         ###########################################################################
         ###########################################################################
         self.removeBlendAnim(actorName,oName)
         self.removeBlendAnim(actorName,oName)
-        print self.blendAnimDict
+        print(self.blendAnimDict)
         return self.saveBlendAnim(actorName, nName, animNameA, animNameB, effect)
         return self.saveBlendAnim(actorName, nName, animNameA, animNameB, effect)
 
 
     def removeBlendAnim(self, actorName, blendName):
     def removeBlendAnim(self, actorName, blendName):
@@ -844,8 +846,8 @@ class dataHolder:
         # Also, it will check that there is any blended animation remained for this actor,
         # Also, it will check that there is any blended animation remained for this actor,
         # If none, this function will clear the "Blending" tag of this object.
         # If none, this function will clear the "Blending" tag of this object.
         ###########################################################################
         ###########################################################################
-        if self.blendAnimDict.has_key(actorName):
-            if self.blendAnimDict[actorName].has_key(blendName):
+        if actorName in self.blendAnimDict:
+            if blendName in self.blendAnimDict[actorName]:
                 ### replace the original setting
                 ### replace the original setting
                 del self.blendAnimDict[actorName][blendName]
                 del self.blendAnimDict[actorName][blendName]
             if len(self.blendAnimDict[actorName])==0:
             if len(self.blendAnimDict[actorName])==0:
@@ -876,15 +878,15 @@ class dataHolder:
         ###########################################################################
         ###########################################################################
         if name == 'camera':
         if name == 'camera':
             return camera
             return camera
-        elif self.ModelDic.has_key(name):
+        elif name in self.ModelDic:
             return self.ModelDic[name]
             return self.ModelDic[name]
-        elif self.ActorDic.has_key(name):
+        elif name in self.ActorDic:
             return self.ActorDic[name]
             return self.ActorDic[name]
-        elif self.collisionDict.has_key(name):
+        elif name in self.collisionDict:
             return self.collisionDict[name]
             return self.collisionDict[name]
-        elif self.dummyDict.has_key(name):
+        elif name in self.dummyDict:
             return self.dummyDict[name]
             return self.dummyDict[name]
-        elif self.particleNodes.has_key(name):
+        elif name in self.particleNodes:
             return self.particleNodes[name]
             return self.particleNodes[name]
         elif self.lightManager.isLight(name):
         elif self.lightManager.isLight(name):
             return self.lightManager.getLightNode(name)
             return self.lightManager.getLightNode(name)
@@ -935,13 +937,13 @@ class dataHolder:
         ###########################################################################
         ###########################################################################
 
 
         ### Ask for a filename
         ### Ask for a filename
-        OpenFilename = tkFileDialog.askopenfilename(filetypes = [("PY","py")],title = "Load Scene")
+        OpenFilename = askopenfilename(filetypes = [("PY","py")],title = "Load Scene")
         if(not OpenFilename):
         if(not OpenFilename):
             return None
             return None
         f=Filename.fromOsSpecific(OpenFilename)
         f=Filename.fromOsSpecific(OpenFilename)
         fileName=f.getBasenameWoExtension()
         fileName=f.getBasenameWoExtension()
         dirName=f.getFullpathWoExtension()
         dirName=f.getFullpathWoExtension()
-        print "DATAHOLDER::" + dirName
+        print("DATAHOLDER::" + dirName)
         ############################################################################
         ############################################################################
         # Append the path to this file to our sys path where python looks for modules
         # Append the path to this file to our sys path where python looks for modules
         # We do this so that we can use "import"  on our saved scene code and execute it
         # We do this so that we can use "import"  on our saved scene code and execute it
@@ -976,7 +978,7 @@ class dataHolder:
             self.ActorDic[actor]=self.Scene.ActorDic[actor]
             self.ActorDic[actor]=self.Scene.ActorDic[actor]
             #self.ActorRefDic[actor]=self.Scene.ActorRefDic[actor] # Old way of doing absolute paths
             #self.ActorRefDic[actor]=self.Scene.ActorRefDic[actor] # Old way of doing absolute paths
             self.ActorRefDic[actor]=Filename(dirName + "/" + self.Scene.ActorRefDic[actor]) # Relative Paths
             self.ActorRefDic[actor]=Filename(dirName + "/" + self.Scene.ActorRefDic[actor]) # Relative Paths
-            if(self.Scene.blendAnimDict.has_key(str(actor))):
+            if(str(actor) in self.Scene.blendAnimDict):
                 self.blendAnimDict[actor]=self.Scene.blendAnimDict[actor]
                 self.blendAnimDict[actor]=self.Scene.blendAnimDict[actor]
             self.ActorNum=self.ActorNum+1
             self.ActorNum=self.ActorNum+1
 
 
@@ -1006,7 +1008,7 @@ class dataHolder:
                 atten=alight.getAttenuation()
                 atten=alight.getAttenuation()
                 self.lightManager.create('spot',alight.getColor(),alight.getSpecularColor(),thenode.getPos(),thenode.getHpr(),atten.getX(),atten.getY(),atten.getZ(),alight.getExponent(),name=alight.getName(),tag=thenode.getTag("Metadata"))
                 self.lightManager.create('spot',alight.getColor(),alight.getSpecularColor(),thenode.getPos(),thenode.getHpr(),atten.getX(),atten.getY(),atten.getZ(),alight.getExponent(),name=alight.getName(),tag=thenode.getTag("Metadata"))
             else:
             else:
-                print 'Invalid light type'
+                print('Invalid light type')
 
 
         ############################################################################
         ############################################################################
         # Populate Dummy related Dictionaries
         # Populate Dummy related Dictionaries

+ 2 - 2
contrib/src/sceneeditor/duplicateWindow.py

@@ -45,7 +45,7 @@ class duplicateWindow(AppShell):
         self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
         self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
 
 
     def appInit(self):
     def appInit(self):
-        print '----SideWindow is Initialized!!'
+        print('----SideWindow is Initialized!!')
 
 
     def createInterface(self):
     def createInterface(self):
         # The interior of the toplevel panel
         # The interior of the toplevel panel
@@ -122,7 +122,7 @@ class duplicateWindow(AppShell):
         # This message will be caught by sceneEditor.
         # This message will be caught by sceneEditor.
         #################################################################
         #################################################################
         if not self.allEntryValid():
         if not self.allEntryValid():
-            print '---- Duplication Window: Invalid value!!'
+            print('---- Duplication Window: Invalid value!!')
             return
             return
         x = self.move_x.getvalue()
         x = self.move_x.getvalue()
         y = self.move_y.getvalue()
         y = self.move_y.getvalue()

+ 32 - 25
contrib/src/sceneeditor/lightingPanel.py

@@ -7,9 +7,16 @@ from direct.tkwidgets.AppShell import AppShell
 from seColorEntry import *
 from seColorEntry import *
 from direct.tkwidgets.VectorWidgets import Vector3Entry
 from direct.tkwidgets.VectorWidgets import Vector3Entry
 from direct.tkwidgets.Slider import Slider
 from direct.tkwidgets.Slider import Slider
-from Tkinter import Frame, Button, Menubutton, Menu
-import string, math, types, Pmw, Tkinter
-from pandac.PandaModules import *
+import sys, math, types, Pmw
+from panda3d.core import *
+
+if sys.version_info >= (3, 0):
+    from tkinter import Frame, Button, Menubutton, Menu
+    import tkinter
+else:
+    from Tkinter import Frame, Button, Menubutton, Menu
+    import Tkinter as tkinter
+
 
 
 class lightingPanel(AppShell):
 class lightingPanel(AppShell):
     #################################################################
     #################################################################
@@ -51,25 +58,25 @@ class lightingPanel(AppShell):
         mainFrame = Frame(interior)
         mainFrame = Frame(interior)
 
 
         self.listZone = Pmw.Group(mainFrame,tag_pyclass = None)
         self.listZone = Pmw.Group(mainFrame,tag_pyclass = None)
-        self.listZone.pack(expand=0, fill=Tkinter.X,padx=3,pady=3)
+        self.listZone.pack(expand=0, fill=tkinter.X,padx=3,pady=3)
         listFrame = self.listZone.interior()
         listFrame = self.listZone.interior()
 
 
         self.lightEntry = self.createcomponent(
         self.lightEntry = self.createcomponent(
             'Lights List', (), None,
             'Lights List', (), None,
             Pmw.ComboBox, (listFrame,),label_text='Light :',
             Pmw.ComboBox, (listFrame,),label_text='Light :',
-            labelpos = Tkinter.W, entry_width = 25, selectioncommand = self.selectLight,
+            labelpos = tkinter.W, entry_width = 25, selectioncommand = self.selectLight,
             scrolledlist_items = self.lightList)
             scrolledlist_items = self.lightList)
-        self.lightEntry.pack(side=Tkinter.LEFT)
+        self.lightEntry.pack(side=tkinter.LEFT)
 
 
         self.renameButton = self.createcomponent(
         self.renameButton = self.createcomponent(
             'Rename Light', (), None,
             'Rename Light', (), None,
             Button, (listFrame,),
             Button, (listFrame,),
             text = ' Rename ',
             text = ' Rename ',
             command = self.renameLight)
             command = self.renameLight)
-        self.renameButton.pack(side=Tkinter.LEFT)
+        self.renameButton.pack(side=tkinter.LEFT)
 
 
         self.addLighZone = Pmw.Group(listFrame,tag_pyclass = None)
         self.addLighZone = Pmw.Group(listFrame,tag_pyclass = None)
-        self.addLighZone.pack(side=Tkinter.LEFT)
+        self.addLighZone.pack(side=tkinter.LEFT)
         insideFrame = self.addLighZone.interior()
         insideFrame = self.addLighZone.interior()
         self.lightsButton = Menubutton(insideFrame, text = 'Add light',borderwidth = 3,
         self.lightsButton = Menubutton(insideFrame, text = 'Add light',borderwidth = 3,
                                        activebackground = '#909090')
                                        activebackground = '#909090')
@@ -91,13 +98,13 @@ class lightingPanel(AppShell):
             Button, (listFrame,),
             Button, (listFrame,),
             text = '  Delete  ',
             text = '  Delete  ',
             command = self.deleteLight)
             command = self.deleteLight)
-        self.deleteButton.pack(side=Tkinter.LEFT)
+        self.deleteButton.pack(side=tkinter.LEFT)
 
 
         self.lightColor = seColorEntry(
         self.lightColor = seColorEntry(
             mainFrame, text = 'Light Color', value=self.lightColor)
             mainFrame, text = 'Light Color', value=self.lightColor)
         self.lightColor['command'] = self.setLightingColorVec
         self.lightColor['command'] = self.setLightingColorVec
         self.lightColor['resetValue'] = [0.3*255,0.3*255,0.3*255,0]
         self.lightColor['resetValue'] = [0.3*255,0.3*255,0.3*255,0]
-        self.lightColor.pack(fill=Tkinter.X,expand=0)
+        self.lightColor.pack(fill=tkinter.X,expand=0)
         self.bind(self.lightColor, 'Set light color')
         self.bind(self.lightColor, 'Set light color')
 
 
         # Notebook pages for light specific controls
         # Notebook pages for light specific controls
@@ -114,27 +121,27 @@ class lightingPanel(AppShell):
         self.dSpecularColor = seColorEntry(
         self.dSpecularColor = seColorEntry(
             directionalPage, text = 'Specular Color')
             directionalPage, text = 'Specular Color')
         self.dSpecularColor['command'] = self.setSpecularColor
         self.dSpecularColor['command'] = self.setSpecularColor
-        self.dSpecularColor.pack(fill = Tkinter.X, expand = 0)
+        self.dSpecularColor.pack(fill = tkinter.X, expand = 0)
         self.bind(self.dSpecularColor,
         self.bind(self.dSpecularColor,
                   'Set directional light specular color')
                   'Set directional light specular color')
         self.dPosition = Vector3Entry(
         self.dPosition = Vector3Entry(
             directionalPage, text = 'Position')
             directionalPage, text = 'Position')
         self.dPosition['command'] = self.setPosition
         self.dPosition['command'] = self.setPosition
         self.dPosition['resetValue'] = [0,0,0,0]
         self.dPosition['resetValue'] = [0,0,0,0]
-        self.dPosition.pack(fill = Tkinter.X, expand = 0)
+        self.dPosition.pack(fill = tkinter.X, expand = 0)
         self.bind(self.dPosition, 'Set directional light position')
         self.bind(self.dPosition, 'Set directional light position')
         self.dOrientation = Vector3Entry(
         self.dOrientation = Vector3Entry(
             directionalPage, text = 'Orientation')
             directionalPage, text = 'Orientation')
         self.dOrientation['command'] = self.setOrientation
         self.dOrientation['command'] = self.setOrientation
         self.dOrientation['resetValue'] = [0,0,0,0]
         self.dOrientation['resetValue'] = [0,0,0,0]
-        self.dOrientation.pack(fill = Tkinter.X, expand = 0)
+        self.dOrientation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.dOrientation, 'Set directional light orientation')
         self.bind(self.dOrientation, 'Set directional light orientation')
 
 
         # Point light controls
         # Point light controls
         self.pSpecularColor = seColorEntry(
         self.pSpecularColor = seColorEntry(
             pointPage, text = 'Specular Color')
             pointPage, text = 'Specular Color')
         self.pSpecularColor['command'] = self.setSpecularColor
         self.pSpecularColor['command'] = self.setSpecularColor
-        self.pSpecularColor.pack(fill = Tkinter.X, expand = 0)
+        self.pSpecularColor.pack(fill = tkinter.X, expand = 0)
         self.bind(self.pSpecularColor,
         self.bind(self.pSpecularColor,
                   'Set point light specular color')
                   'Set point light specular color')
 
 
@@ -142,7 +149,7 @@ class lightingPanel(AppShell):
             pointPage, text = 'Position')
             pointPage, text = 'Position')
         self.pPosition['command'] = self.setPosition
         self.pPosition['command'] = self.setPosition
         self.pPosition['resetValue'] = [0,0,0,0]
         self.pPosition['resetValue'] = [0,0,0,0]
-        self.pPosition.pack(fill = Tkinter.X, expand = 0)
+        self.pPosition.pack(fill = tkinter.X, expand = 0)
         self.bind(self.pPosition, 'Set point light position')
         self.bind(self.pPosition, 'Set point light position')
 
 
         self.pConstantAttenuation = Slider(
         self.pConstantAttenuation = Slider(
@@ -152,7 +159,7 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 1.0)
             value = 1.0)
         self.pConstantAttenuation['command'] = self.setConstantAttenuation
         self.pConstantAttenuation['command'] = self.setConstantAttenuation
-        self.pConstantAttenuation.pack(fill = Tkinter.X, expand = 0)
+        self.pConstantAttenuation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.pConstantAttenuation,
         self.bind(self.pConstantAttenuation,
                   'Set point light constant attenuation')
                   'Set point light constant attenuation')
 
 
@@ -163,7 +170,7 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 0.0)
             value = 0.0)
         self.pLinearAttenuation['command'] = self.setLinearAttenuation
         self.pLinearAttenuation['command'] = self.setLinearAttenuation
-        self.pLinearAttenuation.pack(fill = Tkinter.X, expand = 0)
+        self.pLinearAttenuation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.pLinearAttenuation,
         self.bind(self.pLinearAttenuation,
                   'Set point light linear attenuation')
                   'Set point light linear attenuation')
 
 
@@ -174,7 +181,7 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 0.0)
             value = 0.0)
         self.pQuadraticAttenuation['command'] = self.setQuadraticAttenuation
         self.pQuadraticAttenuation['command'] = self.setQuadraticAttenuation
-        self.pQuadraticAttenuation.pack(fill = Tkinter.X, expand = 0)
+        self.pQuadraticAttenuation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.pQuadraticAttenuation,
         self.bind(self.pQuadraticAttenuation,
                   'Set point light quadratic attenuation')
                   'Set point light quadratic attenuation')
 
 
@@ -182,7 +189,7 @@ class lightingPanel(AppShell):
         self.sSpecularColor = seColorEntry(
         self.sSpecularColor = seColorEntry(
             spotPage, text = 'Specular Color')
             spotPage, text = 'Specular Color')
         self.sSpecularColor['command'] = self.setSpecularColor
         self.sSpecularColor['command'] = self.setSpecularColor
-        self.sSpecularColor.pack(fill = Tkinter.X, expand = 0)
+        self.sSpecularColor.pack(fill = tkinter.X, expand = 0)
         self.bind(self.sSpecularColor,
         self.bind(self.sSpecularColor,
                   'Set spot light specular color')
                   'Set spot light specular color')
 
 
@@ -193,7 +200,7 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 1.0)
             value = 1.0)
         self.sConstantAttenuation['command'] = self.setConstantAttenuation
         self.sConstantAttenuation['command'] = self.setConstantAttenuation
-        self.sConstantAttenuation.pack(fill = Tkinter.X, expand = 0)
+        self.sConstantAttenuation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.sConstantAttenuation,
         self.bind(self.sConstantAttenuation,
                   'Set spot light constant attenuation')
                   'Set spot light constant attenuation')
 
 
@@ -204,7 +211,7 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 0.0)
             value = 0.0)
         self.sLinearAttenuation['command'] = self.setLinearAttenuation
         self.sLinearAttenuation['command'] = self.setLinearAttenuation
-        self.sLinearAttenuation.pack(fill = Tkinter.X, expand = 0)
+        self.sLinearAttenuation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.sLinearAttenuation,
         self.bind(self.sLinearAttenuation,
                   'Set spot light linear attenuation')
                   'Set spot light linear attenuation')
 
 
@@ -215,7 +222,7 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 0.0)
             value = 0.0)
         self.sQuadraticAttenuation['command'] = self.setQuadraticAttenuation
         self.sQuadraticAttenuation['command'] = self.setQuadraticAttenuation
-        self.sQuadraticAttenuation.pack(fill = Tkinter.X, expand = 0)
+        self.sQuadraticAttenuation.pack(fill = tkinter.X, expand = 0)
         self.bind(self.sQuadraticAttenuation,
         self.bind(self.sQuadraticAttenuation,
                   'Set spot light quadratic attenuation')
                   'Set spot light quadratic attenuation')
 
 
@@ -226,16 +233,16 @@ class lightingPanel(AppShell):
             resolution = 0.01,
             resolution = 0.01,
             value = 0.0)
             value = 0.0)
         self.sExponent['command'] = self.setExponent
         self.sExponent['command'] = self.setExponent
-        self.sExponent.pack(fill = Tkinter.X, expand = 0)
+        self.sExponent.pack(fill = tkinter.X, expand = 0)
         self.bind(self.sExponent,
         self.bind(self.sExponent,
                   'Set spot light exponent')
                   'Set spot light exponent')
 
 
         # MRM: Add frustum controls
         # MRM: Add frustum controls
 
 
         self.lightNotebook.setnaturalsize()
         self.lightNotebook.setnaturalsize()
-        self.lightNotebook.pack(expand = 1, fill = Tkinter.BOTH)
+        self.lightNotebook.pack(expand = 1, fill = tkinter.BOTH)
 
 
-        mainFrame.pack(expand=1, fill = Tkinter.BOTH)
+        mainFrame.pack(expand=1, fill = tkinter.BOTH)
 
 
     def onDestroy(self, event):
     def onDestroy(self, event):
         messenger.send('LP_close')
         messenger.send('LP_close')

+ 4 - 5
contrib/src/sceneeditor/propertyWindow.py

@@ -11,8 +11,7 @@ from direct.tkwidgets import Floater
 from direct.tkwidgets import Dial
 from direct.tkwidgets import Dial
 from direct.tkwidgets import Slider
 from direct.tkwidgets import Slider
 from direct.tkwidgets import VectorWidgets
 from direct.tkwidgets import VectorWidgets
-from pandac.PandaModules import *
-from Tkinter import *
+from panda3d.core import *
 import Pmw
 import Pmw
 
 
 class propertyWindow(AppShell,Pmw.MegaWidget):
 class propertyWindow(AppShell,Pmw.MegaWidget):
@@ -108,7 +107,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
 
 
         self.curveFrame = None
         self.curveFrame = None
         #### If nodePath has been binded with any curves
         #### If nodePath has been binded with any curves
-        if self.info.has_key('curveList'):
+        if 'curveList' in self.info:
             self.createCurveFrame(self.contentFrame)
             self.createCurveFrame(self.contentFrame)
 
 
         ## Set all stuff done
         ## Set all stuff done
@@ -271,7 +270,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
         # And, it will set the call back function to setNodeColorVec()
         # And, it will set the call back function to setNodeColorVec()
         #################################################################
         #################################################################
         color = self.nodePath.getColor()
         color = self.nodePath.getColor()
-        print color
+        print(color)
         self.nodeColor = VectorWidgets.ColorEntry(
         self.nodeColor = VectorWidgets.ColorEntry(
             contentFrame, text = 'Node Color', value=[color.getX()*255,
             contentFrame, text = 'Node Color', value=[color.getX()*255,
                                                       color.getY()*255,
                                                       color.getY()*255,
@@ -725,7 +724,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
         # But, not directly removed be this function.
         # But, not directly removed be this function.
         # This function will send out a message to notice dataHolder to remove this animation
         # This function will send out a message to notice dataHolder to remove this animation
         #################################################################
         #################################################################
-        print anim
+        print(anim)
         widget = self.widgetsDict[anim]
         widget = self.widgetsDict[anim]
         self.accept('animRemovedFromNode',self.redrawAnimProperty)
         self.accept('animRemovedFromNode',self.redrawAnimProperty)
         messenger.send('PW_removeAnimFromNode',[self.name, anim])
         messenger.send('PW_removeAnimFromNode',[self.name, anim])

+ 6 - 8
contrib/src/sceneeditor/quad.py

@@ -9,10 +9,8 @@
 from direct.showbase.ShowBaseGlobal import *
 from direct.showbase.ShowBaseGlobal import *
 from direct.interval.IntervalGlobal import *
 from direct.interval.IntervalGlobal import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from pandac.PandaModules import *
+from panda3d.core import *
 import math
 import math
-#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import
-from pandac.PandaModules import MouseWatcher
 
 
 
 
 class ViewPort:
 class ViewPort:
@@ -506,7 +504,7 @@ class QuadView(DirectObject):
             ansY=-1.0+y2
             ansY=-1.0+y2
 
 
         self.xy=[ansX,ansY]
         self.xy=[ansX,ansY]
-        print "Sent X:%f Sent Y:%f"%(ansX,ansY)
+        print("Sent X:%f Sent Y:%f"%(ansX,ansY))
         #SEditor.iRay.pick(render,self.xy)
         #SEditor.iRay.pick(render,self.xy)
         SEditor.manipulationControl.manipulationStop(self.xy)
         SEditor.manipulationControl.manipulationStop(self.xy)
         #print "MouseX " + str(base.mouseWatcherNode.getMouseX()) + "MouseY " + str(base.mouseWatcherNode.getMouseY()) + "\n"
         #print "MouseX " + str(base.mouseWatcherNode.getMouseX()) + "MouseY " + str(base.mouseWatcherNode.getMouseY()) + "\n"
@@ -550,28 +548,28 @@ class QuadView(DirectObject):
             dr.setDimensions(0.5,1,0,0.5)
             dr.setDimensions(0.5,1,0,0.5)
 
 
     def setLeft(self):
     def setLeft(self):
-        print "LEFT"
+        print("LEFT")
         self.CurrentQuad=3
         self.CurrentQuad=3
         self.ChangeBaseDR()
         self.ChangeBaseDR()
         self.Left.setCam()
         self.Left.setCam()
         #self.Left.setDR(self.mouseWatcherNode)
         #self.Left.setDR(self.mouseWatcherNode)
 
 
     def setTop(self):
     def setTop(self):
-        print "TOP"
+        print("TOP")
         self.CurrentQuad=2
         self.CurrentQuad=2
         self.ChangeBaseDR()
         self.ChangeBaseDR()
         self.Top.setCam()
         self.Top.setCam()
         #self.Top.setDR(self.mouseWatcherNode)
         #self.Top.setDR(self.mouseWatcherNode)
 
 
     def setPerspective(self):
     def setPerspective(self):
-        print "PERSPECTIVE"
+        print("PERSPECTIVE")
         self.CurrentQuad=4
         self.CurrentQuad=4
         self.ChangeBaseDR()
         self.ChangeBaseDR()
         self.Perspective.setCam()
         self.Perspective.setCam()
         #self.Perspective.setDR(self.mouseWatcherNode)
         #self.Perspective.setDR(self.mouseWatcherNode)
 
 
     def setFront(self):
     def setFront(self):
-        print "FRONT"
+        print("FRONT")
         self.CurrentQuad=1
         self.CurrentQuad=1
         self.ChangeBaseDR()
         self.ChangeBaseDR()
         self.Front.setCam()
         self.Front.setCam()

+ 48 - 37
contrib/src/sceneeditor/sceneEditor.py

@@ -3,11 +3,19 @@ import sys
 try: import _tkinter
 try: import _tkinter
 except: sys.exit("Please install python module 'Tkinter'")
 except: sys.exit("Please install python module 'Tkinter'")
 
 
-import direct
-from direct.directbase.DirectStart import*
+from direct.showbase.ShowBase import ShowBase
+
+ShowBase()
+
 from direct.showbase.TkGlobal import spawnTkLoop
 from direct.showbase.TkGlobal import spawnTkLoop
-from Tkinter import *
-from tkFileDialog import *
+
+if sys.version_info >= (3, 0):
+    from tkinter import *
+    from tkinter.filedialog import *
+else:
+    from Tkinter import *
+    from tkFileDialog import *
+
 from direct.directtools.DirectGlobals import *
 from direct.directtools.DirectGlobals import *
 from direct.tkwidgets.AppShell import*
 from direct.tkwidgets.AppShell import*
 
 
@@ -251,7 +259,10 @@ class myLevelEditor(AppShell):
         for event in self.actionEvents:
         for event in self.actionEvents:
             self.accept(event[0], event[1], extraArgs = event[2:])
             self.accept(event[0], event[1], extraArgs = event[2:])
 
 
-        camera.toggleVis()
+        if camera.is_hidden():
+            camera.show()
+        else:
+            camera.hide()
         self.selectNode(base.camera) ## Initially, we select camera as the first node...
         self.selectNode(base.camera) ## Initially, we select camera as the first node...
 
 
     def appInit(self):
     def appInit(self):
@@ -386,31 +397,31 @@ class myLevelEditor(AppShell):
             self.showAbout()
             self.showAbout()
             return
             return
         elif buttonIndex==12:
         elif buttonIndex==12:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==13:
         elif buttonIndex==13:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==14:
         elif buttonIndex==14:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==15:
         elif buttonIndex==15:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==16:
         elif buttonIndex==16:
-            print "Your scene will be eliminated within five seconds, Save your world!!!, Number %d."%buttonIndex
+            print("Your scene will be eliminated within five seconds, Save your world!!!, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==17:
         elif buttonIndex==17:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==18:
         elif buttonIndex==18:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==19:
         elif buttonIndex==19:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
         elif buttonIndex==20:
         elif buttonIndex==20:
-            print "You haven't defined the function for this Button, Number %d."%buttonIndex
+            print("You haven't defined the function for this Button, Number %d."%buttonIndex)
             return
             return
 
 
         return
         return
@@ -666,17 +677,17 @@ class myLevelEditor(AppShell):
         #################################################################
         #################################################################
         type, info = AllScene.getInfoOfThisNode(nodePath)
         type, info = AllScene.getInfoOfThisNode(nodePath)
         name = nodePath.getName()
         name = nodePath.getName()
-        if not self.propertyWindow.has_key(name):
+        if name not in self.propertyWindow:
             self.propertyWindow[name] = propertyWindow(nodePath, type,info )
             self.propertyWindow[name] = propertyWindow(nodePath, type,info )
         pass
         pass
 
 
     def closePropertyWindow(self, name):
     def closePropertyWindow(self, name):
-        if self.propertyWindow.has_key(name):
+        if name in self.propertyWindow:
             del self.propertyWindow[name]
             del self.propertyWindow[name]
         return
         return
 
 
     def openMetadataPanel(self,nodePath=None):
     def openMetadataPanel(self,nodePath=None):
-        print nodePath
+        print(nodePath)
         self.MetadataPanel=MetadataPanel(nodePath)
         self.MetadataPanel=MetadataPanel(nodePath)
         pass
         pass
 
 
@@ -685,7 +696,7 @@ class myLevelEditor(AppShell):
         # duplicate(self, nodePath = None)
         # duplicate(self, nodePath = None)
         # This function will be called when user try to open the duplication window
         # This function will be called when user try to open the duplication window
         #################################################################
         #################################################################
-        print '----Duplication!!'
+        print('----Duplication!!')
         if nodePath != None:
         if nodePath != None:
             self.duplicateWindow = duplicateWindow(nodePath = nodePath)
             self.duplicateWindow = duplicateWindow(nodePath = nodePath)
         pass
         pass
@@ -791,8 +802,8 @@ class myLevelEditor(AppShell):
         #################################################################
         #################################################################
         name = nodePath.getName()
         name = nodePath.getName()
         if AllScene.isActor(name):
         if AllScene.isActor(name):
-            if self.animPanel.has_key(name):
-                print '---- You already have an animation panel for this Actor!'
+            if name in self.animPanel:
+                print('---- You already have an animation panel for this Actor!')
                 return
                 return
             else:
             else:
                 Actor = AllScene.getActor(name)
                 Actor = AllScene.getActor(name)
@@ -842,9 +853,9 @@ class myLevelEditor(AppShell):
             # Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module
             # Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module
             # And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it
             # And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it
             # If there is ever a garbage colleciton bug..this might be a point to look at
             # If there is ever a garbage colleciton bug..this might be a point to look at
-            if sys.modules.has_key(currentModName):
+            if currentModName in sys.modules:
                 del sys.modules[currentModName]
                 del sys.modules[currentModName]
-                print sys.getrefcount(AllScene.theScene)
+                print(sys.getrefcount(AllScene.theScene))
                 del AllScene.theScene
                 del AllScene.theScene
         else:
         else:
             AllScene.resetAll()
             AllScene.resetAll()
@@ -872,9 +883,9 @@ class myLevelEditor(AppShell):
             # Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module
             # Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module
             # And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it
             # And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it
             # If there is ever a garbage colleciton bug..this might be a point to look at
             # If there is ever a garbage colleciton bug..this might be a point to look at
-            if sys.modules.has_key(currentModName):
+            if currentModName in sys.modules:
                 del sys.modules[currentModName]
                 del sys.modules[currentModName]
-                print sys.getrefcount(AllScene.theScene)
+                print(sys.getrefcount(AllScene.theScene))
                 del AllScene.theScene
                 del AllScene.theScene
         else:
         else:
             AllScene.resetAll()
             AllScene.resetAll()
@@ -886,7 +897,7 @@ class myLevelEditor(AppShell):
 
 
         thefile=Filename(self.CurrentFileName)
         thefile=Filename(self.CurrentFileName)
         thedir=thefile.getFullpathWoExtension()
         thedir=thefile.getFullpathWoExtension()
-        print "SCENE EDITOR::" + thedir
+        print("SCENE EDITOR::" + thedir)
         self.CurrentDirName=thedir
         self.CurrentDirName=thedir
         if self.CurrentFileName != None:
         if self.CurrentFileName != None:
             self.parent.title('Scene Editor - '+ Filename.fromOsSpecific(self.CurrentFileName).getBasenameWoExtension())
             self.parent.title('Scene Editor - '+ Filename.fromOsSpecific(self.CurrentFileName).getBasenameWoExtension())
@@ -934,7 +945,7 @@ class myLevelEditor(AppShell):
             theScene.writeBamFile(fileName)
             theScene.writeBamFile(fileName)
         else:
         else:
             render.writeBamFile(fileName+".bad")
             render.writeBamFile(fileName+".bad")
-        print " Scenegraph saved as :" +str(fileName)
+        print(" Scenegraph saved as :" +str(fileName))
 
 
     def loadFromBam(self):
     def loadFromBam(self):
         fileName = tkFileDialog.askopenfilename(filetypes = [("BAM",".bam")],title = "Load Scenegraph from Bam file")
         fileName = tkFileDialog.askopenfilename(filetypes = [("BAM",".bam")],title = "Load Scenegraph from Bam file")
@@ -959,7 +970,7 @@ class myLevelEditor(AppShell):
         ###############################################################################
         ###############################################################################
         # !!!!! See if a module exists by this name... if it does you cannot use this filename !!!!!
         # !!!!! See if a module exists by this name... if it does you cannot use this filename !!!!!
         ###############################################################################
         ###############################################################################
-        if(sys.modules.has_key(fCheck.getBasenameWoExtension())):
+        if(fCheck.getBasenameWoExtension() in sys.modules):
             tkMessageBox.showwarning(
             tkMessageBox.showwarning(
             "Save file",
             "Save file",
             "Cannot save with this name because there is a system module with the same name. Please resave as something else."
             "Cannot save with this name because there is a system module with the same name. Please resave as something else."
@@ -993,7 +1004,7 @@ class myLevelEditor(AppShell):
         if modelFilename:
         if modelFilename:
             self.makeDirty()
             self.makeDirty()
             if not AllScene.loadModel(modelFilename, Filename.fromOsSpecific(modelFilename)):
             if not AllScene.loadModel(modelFilename, Filename.fromOsSpecific(modelFilename)):
-                print '----Error! No Such Model File!'
+                print('----Error! No Such Model File!')
         pass
         pass
 
 
     def loadActor(self):
     def loadActor(self):
@@ -1016,12 +1027,12 @@ class myLevelEditor(AppShell):
         if ActorFilename:
         if ActorFilename:
             self.makeDirty()
             self.makeDirty()
             if not AllScene.loadActor(ActorFilename, Filename.fromOsSpecific(ActorFilename)):
             if not AllScene.loadActor(ActorFilename, Filename.fromOsSpecific(ActorFilename)):
-                print '----Error! No Such Model File!'
+                print('----Error! No Such Model File!')
         pass
         pass
 
 
     def importScene(self):
     def importScene(self):
         self.makeDirty()
         self.makeDirty()
-        print '----God bless you Please Import!'
+        print('----God bless you Please Import!')
         pass
         pass
 
 
 
 
@@ -1495,7 +1506,7 @@ class myLevelEditor(AppShell):
         return
         return
 
 
     def animPanelClose(self, name):
     def animPanelClose(self, name):
-        if self.animPanel.has_key(name):
+        if name in self.animPanel:
             del self.animPanel[name]
             del self.animPanel[name]
         return
         return
 
 
@@ -1508,8 +1519,8 @@ class myLevelEditor(AppShell):
         ################################################################
         ################################################################
         name = nodePath.getName()
         name = nodePath.getName()
         if AllScene.isActor(name):
         if AllScene.isActor(name):
-            if self.animBlendPanel.has_key(name):
-                print '---- You already have an Blend Animation Panel for this Actor!'
+            if name in self.animBlendPanel:
+                print('---- You already have an Blend Animation Panel for this Actor!')
                 return
                 return
             else:
             else:
                 Actor = AllScene.getActor(name)
                 Actor = AllScene.getActor(name)
@@ -1554,7 +1565,7 @@ class myLevelEditor(AppShell):
         # This function will be called when Blend panel has been closed.
         # This function will be called when Blend panel has been closed.
         # Here we will reset the reference dictionary so it can be open again.
         # Here we will reset the reference dictionary so it can be open again.
         ################################################################
         ################################################################
-        if self.animBlendPanel.has_key(name):
+        if name in self.animBlendPanel:
             del self.animBlendPanel[name]
             del self.animBlendPanel[name]
         return
         return
 
 
@@ -1613,7 +1624,7 @@ class myLevelEditor(AppShell):
 
 
     def openAlignPanel(self, nodePath=None):
     def openAlignPanel(self, nodePath=None):
         name = nodePath.getName()
         name = nodePath.getName()
-        if not self.alignPanelDict.has_key(name):
+        if name not in self.alignPanelDict:
             list = AllScene.getAllObjNameAsList()
             list = AllScene.getAllObjNameAsList()
             if name in list:
             if name in list:
                 list.remove(name)
                 list.remove(name)
@@ -1623,7 +1634,7 @@ class myLevelEditor(AppShell):
         return
         return
 
 
     def closeAlignPanel(self, name=None):
     def closeAlignPanel(self, name=None):
-        if self.alignPanelDict.has_key(name):
+        if name in self.alignPanelDict:
             del self.alignPanelDict[name]
             del self.alignPanelDict[name]
 
 
     def alignObject(self, nodePath, name, list):
     def alignObject(self, nodePath, name, list):
@@ -1705,4 +1716,4 @@ class myLevelEditor(AppShell):
 
 
 editor = myLevelEditor(parent = base.tkRoot)
 editor = myLevelEditor(parent = base.tkRoot)
 
 
-run()
+base.run()

+ 9 - 5
contrib/src/sceneeditor/seAnimPanel.py

@@ -5,12 +5,16 @@
 # Import Tkinter, Pmw, and the floater code from this directory tree.
 # Import Tkinter, Pmw, and the floater code from this directory tree.
 from direct.tkwidgets.AppShell import *
 from direct.tkwidgets.AppShell import *
 from direct.showbase.TkGlobal import *
 from direct.showbase.TkGlobal import *
-from tkSimpleDialog import askfloat
 import string
 import string
 import math
 import math
 import types
 import types
 from direct.task import Task
 from direct.task import Task
 
 
+if sys.version_info >= (3, 0):
+    from tkinter.simpledialog import askfloat
+else:
+    from tkSimpleDialog import askfloat
+
 FRAMES = 0
 FRAMES = 0
 SECONDS = 1
 SECONDS = 1
 
 
@@ -112,7 +116,7 @@ class AnimPanel(AppShell):
         self.playRateEntry.selectitem('1.0')
         self.playRateEntry.selectitem('1.0')
 
 
         ### Loop checkbox
         ### Loop checkbox
-        Label(actorFrame, text= "Loop:", font=('MSSansSerif', 12)).place(x=420,y=05,anchor=NW)
+        Label(actorFrame, text= "Loop:", font=('MSSansSerif', 12)).place(x=420,y=5,anchor=NW)
 
 
         self.loopVar = IntVar()
         self.loopVar = IntVar()
         self.loopVar.set(0)
         self.loopVar.set(0)
@@ -250,7 +254,7 @@ class AnimPanel(AppShell):
         self['animList'] = self['actor'].getAnimNames()
         self['animList'] = self['actor'].getAnimNames()
         animL = self['actor'].getAnimNames()
         animL = self['actor'].getAnimNames()
         self.AnimEntry.setlist(animL)
         self.AnimEntry.setlist(animL)
-        print '-----',animL
+        print('-----',animL)
         return
         return
 
 
     def loadAnimation(self):
     def loadAnimation(self):
@@ -278,7 +282,7 @@ class AnimPanel(AppShell):
             taskMgr.add(self.playTask, self.id + '_UpdateTask')
             taskMgr.add(self.playTask, self.id + '_UpdateTask')
             self.stopButton.config(state=NORMAL)
             self.stopButton.config(state=NORMAL)
         else:
         else:
-            print '----Illegal Animaion name!!', self.animName
+            print('----Illegal Animaion name!!', self.animName)
         return
         return
 
 
     def playTask(self, task):
     def playTask(self, task):
@@ -591,7 +595,7 @@ class LoadAnimPanel(AppShell):
         else:
         else:
             self.animList.append(name)
             self.animList.append(name)
         self.AnimName_1.setlist(self.animList)
         self.AnimName_1.setlist(self.animList)
-        print self.animDic
+        print(self.animDic)
         return
         return
 
 
     def ok_press(self):
     def ok_press(self):

+ 9 - 5
contrib/src/sceneeditor/seBlendAnimPanel.py

@@ -5,12 +5,16 @@
 # Import Tkinter, Pmw, and the floater code from this directory tree.
 # Import Tkinter, Pmw, and the floater code from this directory tree.
 from direct.tkwidgets.AppShell import *
 from direct.tkwidgets.AppShell import *
 from direct.showbase.TkGlobal import *
 from direct.showbase.TkGlobal import *
-from tkSimpleDialog import askfloat
 import string
 import string
 import math
 import math
 import types
 import types
 from direct.task import Task
 from direct.task import Task
 
 
+if sys.version_info >= (3, 0):
+    from tkinter.simpledialog import askfloat
+else:
+    from tkSimpleDialog import askfloat
+
 FRAMES = 0
 FRAMES = 0
 SECONDS = 1
 SECONDS = 1
 
 
@@ -304,7 +308,7 @@ class BlendAnimPanel(AppShell):
             taskMgr.add(self.playTask, self.id + '_UpdateTask')
             taskMgr.add(self.playTask, self.id + '_UpdateTask')
             self.stopButton.config(state=NORMAL)
             self.stopButton.config(state=NORMAL)
         else:
         else:
-            print '----Illegal Animaion name!!', self.animNameA +  ',  '+ self.animNameB
+            print('----Illegal Animaion name!!', self.animNameA +  ',  '+ self.animNameB)
         return
         return
 
 
     def playTask(self, task):
     def playTask(self, task):
@@ -348,7 +352,7 @@ class BlendAnimPanel(AppShell):
         # setAnimation(self, animation, AB = 'a')
         # setAnimation(self, animation, AB = 'a')
         # see play(self)
         # see play(self)
         #################################################################
         #################################################################
-        print 'OK!!!'
+        print('OK!!!')
         if AB == 'a':
         if AB == 'a':
             if self.animNameA != None:
             if self.animNameA != None:
                 self['actor'].setControlEffect(self.animNameA, 1.0, 'modelRoot','lodRoot')
                 self['actor'].setControlEffect(self.animNameA, 1.0, 'modelRoot','lodRoot')
@@ -519,7 +523,7 @@ class BlendAnimPanel(AppShell):
         # then this function will set Animation A to "a" and animation B
         # then this function will set Animation A to "a" and animation B
         # to "b" and set the ratio slider to "c" position.
         # to "b" and set the ratio slider to "c" position.
         #################################################################
         #################################################################
-        if self.blendDict.has_key(name):
+        if name in self.blendDict:
             self.currentBlendName = name
             self.currentBlendName = name
             animA = self.blendDict[name][0]
             animA = self.blendDict[name][0]
             animB = self.blendDict[name][1]
             animB = self.blendDict[name][1]
@@ -544,7 +548,7 @@ class BlendAnimPanel(AppShell):
         self.blendDict.clear()
         self.blendDict.clear()
         del self.blendDict
         del self.blendDict
         self.blendDict = dict.copy()
         self.blendDict = dict.copy()
-        print self.blendDict
+        print(self.blendDict)
         if len(self.blendDict)>0:
         if len(self.blendDict)>0:
             self.blendList = self.blendDict.keys()
             self.blendList = self.blendDict.keys()
         else:
         else:

+ 10 - 11
contrib/src/sceneeditor/seCameraControl.py

@@ -55,14 +55,14 @@ class DirectCameraControl(DirectObject):
             ['n', self.pickNextCOA],
             ['n', self.pickNextCOA],
             ['u', self.orbitUprightCam],
             ['u', self.orbitUprightCam],
             ['shift-u', self.uprightCam],
             ['shift-u', self.uprightCam],
-            [`1`, self.spawnMoveToView, 1],
-            [`2`, self.spawnMoveToView, 2],
-            [`3`, self.spawnMoveToView, 3],
-            [`4`, self.spawnMoveToView, 4],
-            [`5`, self.spawnMoveToView, 5],
-            [`6`, self.spawnMoveToView, 6],
-            [`7`, self.spawnMoveToView, 7],
-            [`8`, self.spawnMoveToView, 8],
+            ['1', self.spawnMoveToView, 1],
+            ['2', self.spawnMoveToView, 2],
+            ['3', self.spawnMoveToView, 3],
+            ['4', self.spawnMoveToView, 4],
+            ['5', self.spawnMoveToView, 5],
+            ['6', self.spawnMoveToView, 6],
+            ['7', self.spawnMoveToView, 7],
+            ['8', self.spawnMoveToView, 8],
             ['9', self.swingCamAboutWidget, -90.0, t],
             ['9', self.swingCamAboutWidget, -90.0, t],
             ['0', self.swingCamAboutWidget,  90.0, t],
             ['0', self.swingCamAboutWidget,  90.0, t],
             ['`', self.removeManipulateCameraTask],
             ['`', self.removeManipulateCameraTask],
@@ -351,7 +351,7 @@ class DirectCameraControl(DirectObject):
             # MRM: Would be nice to be able to control this
             # MRM: Would be nice to be able to control this
             # At least display it
             # At least display it
             dist = pow(10.0, self.nullHitPointCount)
             dist = pow(10.0, self.nullHitPointCount)
-            SEditor.message('COA Distance: ' + `dist`)
+            SEditor.message('COA Distance: ' + repr(dist))
             coa.set(0,dist,0)
             coa.set(0,dist,0)
         # Compute COA Dist
         # Compute COA Dist
         coaDist = Vec3(coa - ZERO_POINT).length()
         coaDist = Vec3(coa - ZERO_POINT).length()
@@ -392,8 +392,7 @@ class DirectCameraControl(DirectObject):
             sf = 0.1
             sf = 0.1
         self.coaMarker.setScale(sf)
         self.coaMarker.setScale(sf)
         # Lerp color to fade out
         # Lerp color to fade out
-        self.coaMarker.lerpColor(VBase4(1,0,0,1), VBase4(1,0,0,0), 3.0,
-                                 task = 'fadeAway')
+        self.coaMarker.colorInterval(3.0, VBase4(1, 0, 0, 0), name='fadeAway').start()
 
 
     def homeCam(self):
     def homeCam(self):
         # Record undo point
         # Record undo point

+ 8 - 2
contrib/src/sceneeditor/seColorEntry.py

@@ -12,9 +12,15 @@
 from direct.tkwidgets import Valuator
 from direct.tkwidgets import Valuator
 from direct.tkwidgets import Floater
 from direct.tkwidgets import Floater
 from direct.tkwidgets import Slider
 from direct.tkwidgets import Slider
-import string, Pmw, Tkinter, tkColorChooser
+import sys, Pmw
 from direct.tkwidgets.VectorWidgets import VectorEntry
 from direct.tkwidgets.VectorWidgets import VectorEntry
 
 
+if sys.version_info >= (3, 0):
+    from tkinter.colorchooser import askcolor
+else:
+    from tkColorChooser import askcolor
+
+
 class seColorEntry(VectorEntry):
 class seColorEntry(VectorEntry):
     def __init__(self, parent = None, **kw):
     def __init__(self, parent = None, **kw):
         # Initialize options for the class (overriding some superclass options)
         # Initialize options for the class (overriding some superclass options)
@@ -41,7 +47,7 @@ class seColorEntry(VectorEntry):
 
 
     def popupColorPicker(self):
     def popupColorPicker(self):
         # Can pass in current color with: color = (255, 0, 0)
         # Can pass in current color with: color = (255, 0, 0)
-        color = tkColorChooser.askcolor(
+        color = askcolor(
             parent = self.interior(),
             parent = self.interior(),
             # Initialize it to current color
             # Initialize it to current color
             initialcolor = tuple(self.get()[:3]))[0]
             initialcolor = tuple(self.get()[:3]))[0]

+ 18 - 18
contrib/src/sceneeditor/seFileSaver.py

@@ -3,7 +3,7 @@
 # This code saves the scene out as python code... the scene is stored in the various dictionaries in "dataHolder.py" ...the class "AllScene"
 # This code saves the scene out as python code... the scene is stored in the various dictionaries in "dataHolder.py" ...the class "AllScene"
 #
 #
 ####################################################################################################################################################
 ####################################################################################################################################################
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 from direct.showbase.ShowBaseGlobal import *
 from direct.showbase.ShowBaseGlobal import *
 import os
 import os
@@ -42,7 +42,7 @@ class FileSaver:
         i1="    " # indentation
         i1="    " # indentation
         i2=i1+i1  # double indentation
         i2=i1+i1  # double indentation
         out_file = open(filename,"w")
         out_file = open(filename,"w")
-        print "dirname:" + dirname
+        print("dirname:" + dirname)
         if( not os.path.isdir(dirname)):
         if( not os.path.isdir(dirname)):
             os.mkdir(dirname)
             os.mkdir(dirname)
         savepathname=Filename(filename)
         savepathname=Filename(filename)
@@ -176,7 +176,7 @@ class FileSaver:
                     newtexpathF=Filename(newtexpath)
                     newtexpathF=Filename(newtexpath)
                     newtexpathSpecific=newtexpathF.toOsSpecific()
                     newtexpathSpecific=newtexpathF.toOsSpecific()
 
 
-                    print "TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific
+                    print("TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific)
                     if(oldtexpath != newtexpathSpecific):
                     if(oldtexpath != newtexpathSpecific):
                         shutil.copyfile(oldtexpath,newtexpathSpecific)
                         shutil.copyfile(oldtexpath,newtexpathSpecific)
 
 
@@ -187,7 +187,7 @@ class FileSaver:
 
 
                 # Copy the file over to the relative directory
                 # Copy the file over to the relative directory
                 oldModelpath=AllScene.ModelRefDic[model].toOsSpecific()
                 oldModelpath=AllScene.ModelRefDic[model].toOsSpecific()
-                print "FILESAVER:: copying from " + AllScene.ModelRefDic[model].toOsSpecific() + "to" + newpathSpecific
+                print("FILESAVER:: copying from " + AllScene.ModelRefDic[model].toOsSpecific() + "to" + newpathSpecific)
                 if(oldModelpath!=newpathSpecific):
                 if(oldModelpath!=newpathSpecific):
                     shutil.copyfile(oldModelpath,newpathSpecific)
                     shutil.copyfile(oldModelpath,newpathSpecific)
 
 
@@ -197,7 +197,7 @@ class FileSaver:
                 etc=EggTextureCollection()
                 etc=EggTextureCollection()
                 etc.extractTextures(e)
                 etc.extractTextures(e)
                 for index in range(len(fnamelist)):
                 for index in range(len(fnamelist)):
-                    print fnamelist[index]
+                    print(fnamelist[index])
                     tex=etc.findFilename(Filename(fnamelist[index]))
                     tex=etc.findFilename(Filename(fnamelist[index]))
                     fn=Filename(tex.getFilename())
                     fn=Filename(tex.getFilename())
                     fn.setDirname("")
                     fn.setDirname("")
@@ -305,14 +305,14 @@ class FileSaver:
                     newtexpath=dirname + "/" + texfilename.getBasename()
                     newtexpath=dirname + "/" + texfilename.getBasename()
                     newtexpathF=Filename(newtexpath)
                     newtexpathF=Filename(newtexpath)
                     newtexpathSpecific=newtexpathF.toOsSpecific()
                     newtexpathSpecific=newtexpathF.toOsSpecific()
-                    print "TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific
+                    print("TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific)
                     if(oldtexpath != newtexpathSpecific):
                     if(oldtexpath != newtexpathSpecific):
                         shutil.copyfile(oldtexpath,newtexpathSpecific)
                         shutil.copyfile(oldtexpath,newtexpathSpecific)
 
 
 
 
                 # Copy the file over to the relative directory
                 # Copy the file over to the relative directory
                 oldActorpath=AllScene.ActorRefDic[actor].toOsSpecific()
                 oldActorpath=AllScene.ActorRefDic[actor].toOsSpecific()
-                print "FILESAVER:: copying from " + AllScene.ActorRefDic[actor].toOsSpecific() + "to" + newpathSpecific
+                print("FILESAVER:: copying from " + AllScene.ActorRefDic[actor].toOsSpecific() + "to" + newpathSpecific)
                 if(oldActorpath!=newpathSpecific):
                 if(oldActorpath!=newpathSpecific):
                     shutil.copyfile(oldActorpath,newpathSpecific)
                     shutil.copyfile(oldActorpath,newpathSpecific)
 
 
@@ -322,7 +322,7 @@ class FileSaver:
                 etc=EggTextureCollection()
                 etc=EggTextureCollection()
                 etc.extractTextures(e)
                 etc.extractTextures(e)
                 for index in range(len(actorfnamelist)):
                 for index in range(len(actorfnamelist)):
-                    print actorfnamelist[index]
+                    print(actorfnamelist[index])
                     tex=etc.findFilename(Filename(actorfnamelist[index]))
                     tex=etc.findFilename(Filename(actorfnamelist[index]))
                     fn=Filename(tex.getFilename())
                     fn=Filename(tex.getFilename())
                     fn.setDirname("")
                     fn.setDirname("")
@@ -362,12 +362,12 @@ class FileSaver:
                         #out_file.write(i2+ "self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Old way with absolute paths
                         #out_file.write(i2+ "self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Old way with absolute paths
                         #Manakel 2/12/2004: solve the not empty but not defined animation case
                         #Manakel 2/12/2004: solve the not empty but not defined animation case
                         if not animation is None:
                         if not animation is None:
-                            print "ACTOR ANIMATIONS:" + ActorAnimations[animation]
+                            print("ACTOR ANIMATIONS:" + ActorAnimations[animation])
                             oldAnimPath=Filename(ActorAnimations[animation])
                             oldAnimPath=Filename(ActorAnimations[animation])
                             oldAnim=oldAnimPath.toOsSpecific()
                             oldAnim=oldAnimPath.toOsSpecific()
                             dirOS=Filename(dirname)
                             dirOS=Filename(dirname)
                             newAnim=dirOS.toOsSpecific() + "\\" + oldAnimPath.getBasename()
                             newAnim=dirOS.toOsSpecific() + "\\" + oldAnimPath.getBasename()
-                            print "ACTOR ANIM SAVER:: Comparing" + oldAnim +"and" + newAnim
+                            print("ACTOR ANIM SAVER:: Comparing" + oldAnim +"and" + newAnim)
                             if(oldAnim!=newAnim):
                             if(oldAnim!=newAnim):
                                 shutil.copyfile(oldAnim,newAnim)
                                 shutil.copyfile(oldAnim,newAnim)
                             newAnimF=Filename.fromOsSpecific(newAnim)
                             newAnimF=Filename.fromOsSpecific(newAnim)
@@ -379,16 +379,16 @@ class FileSaver:
                 out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Now with new relative paths
                 out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Now with new relative paths
                 out_file.write(i2+"else:\n")
                 out_file.write(i2+"else:\n")
                 theloadAnimString=str(ActorAnimationsInvoke)# We hack the "self.executionpath" part into the dictionary as a variable using string replace
                 theloadAnimString=str(ActorAnimationsInvoke)# We hack the "self.executionpath" part into the dictionary as a variable using string replace
-                print "LOAD ANIM STRING BEFORE" + theloadAnimString
+                print("LOAD ANIM STRING BEFORE" + theloadAnimString)
                 theloadAnimString=theloadAnimString.replace('\'self.executionpath +','self.executionpath + \'')
                 theloadAnimString=theloadAnimString.replace('\'self.executionpath +','self.executionpath + \'')
-                print "LOAD ANIM STRING AFTER" + theloadAnimString
+                print("LOAD ANIM STRING AFTER" + theloadAnimString)
                 out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + theloadAnimString +")\n") # Now with new relative paths based on editor invocation
                 out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + theloadAnimString +")\n") # Now with new relative paths based on editor invocation
 
 
                 out_file.write(i2+ "self.ActorDic[\'" + actorS + "\']=self." + AllScene.ActorDic[actor].getName()+"\n")
                 out_file.write(i2+ "self.ActorDic[\'" + actorS + "\']=self." + AllScene.ActorDic[actor].getName()+"\n")
                 #out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=Filename(\'"+AllScene.ActorRefDic[actor].getFullpath() +"\')\n") # Old way with absolute paths
                 #out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=Filename(\'"+AllScene.ActorRefDic[actor].getFullpath() +"\')\n") # Old way with absolute paths
                 out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=\'"+ AllScene.ActorRefDic[actor].getBasename() +"\'\n")# Relative paths
                 out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=\'"+ AllScene.ActorRefDic[actor].getBasename() +"\'\n")# Relative paths
                 out_file.write(i2+ "self.ActorDic[\'"+ actorS + "\'].setName(\'"+ actorS +"\')\n")
                 out_file.write(i2+ "self.ActorDic[\'"+ actorS + "\'].setName(\'"+ actorS +"\')\n")
-                if(AllScene.blendAnimDict.has_key(actor)): # Check if a dictionary of blended animations exists
+                if(actor in AllScene.blendAnimDict): # Check if a dictionary of blended animations exists
                     out_file.write(i2+ "self.blendAnimDict[\"" + actorS +"\"]=" + str(AllScene.blendAnimDict[actor]) + "\n")
                     out_file.write(i2+ "self.blendAnimDict[\"" + actorS +"\"]=" + str(AllScene.blendAnimDict[actor]) + "\n")
 
 
 
 
@@ -458,7 +458,7 @@ class FileSaver:
 
 
                 pass
                 pass
             else:
             else:
-                 print "Invalid Collision Node: " + nodetype
+                 print("Invalid Collision Node: " + nodetype)
             out_file.write("\n")
             out_file.write("\n")
 
 
 
 
@@ -653,7 +653,7 @@ class FileSaver:
             if(parent=="render" or parent=="camera"):
             if(parent=="render" or parent=="camera"):
                 out_file.write(i2+ "self."+ modelS + ".reparentTo(" + parent + ")\n")
                 out_file.write(i2+ "self."+ modelS + ".reparentTo(" + parent + ")\n")
             else:
             else:
-                if(AllScene.particleDict.has_key(parent)):
+                if(parent in AllScene.particleDict):
                     out_file.write(i2+ "self."+ modelS + ".reparentTo(self." + parent + ".getEffect())\n")
                     out_file.write(i2+ "self."+ modelS + ".reparentTo(self." + parent + ".getEffect())\n")
                 else:
                 else:
                     out_file.write(i2+ "self."+ modelS + ".reparentTo(self." + parent + ")\n")
                     out_file.write(i2+ "self."+ modelS + ".reparentTo(self." + parent + ")\n")
@@ -666,7 +666,7 @@ class FileSaver:
             if(parent=="render" or parent=="camera"):
             if(parent=="render" or parent=="camera"):
                 out_file.write(i2+ "self."+ dummyS + ".reparentTo(" + parent + ")\n")
                 out_file.write(i2+ "self."+ dummyS + ".reparentTo(" + parent + ")\n")
             else:
             else:
-                if(AllScene.particleDict.has_key(parent)):
+                if(parent in AllScene.particleDict):
                     out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ".getEffect())\n")
                     out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ".getEffect())\n")
                 else:
                 else:
                     out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ")\n")
                     out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ")\n")
@@ -680,7 +680,7 @@ class FileSaver:
             if(parent=="render" or parent=="camera"):
             if(parent=="render" or parent=="camera"):
                 out_file.write(i2+ "self."+ actorS + ".reparentTo(" + parent + ")\n")
                 out_file.write(i2+ "self."+ actorS + ".reparentTo(" + parent + ")\n")
             else:
             else:
-                if(AllScene.particleDict.has_key(parent)):
+                if(parent in AllScene.particleDict):
                     out_file.write(i2+ "self."+ actorS + ".reparentTo(self." + parent + ".getEffect())\n")
                     out_file.write(i2+ "self."+ actorS + ".reparentTo(self." + parent + ".getEffect())\n")
                 else:
                 else:
                     out_file.write(i2+ "self."+ actorS + ".reparentTo(self." + parent + ")\n")
                     out_file.write(i2+ "self."+ actorS + ".reparentTo(self." + parent + ")\n")
@@ -698,7 +698,7 @@ class FileSaver:
                 out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]="+ parentname + ".attachNewNode(self." + collnodeS + "_Node)\n")
                 out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]="+ parentname + ".attachNewNode(self." + collnodeS + "_Node)\n")
             else:
             else:
                 #Manakel 2/12/2005: parent replaced by parent Name but why Parent name in partice and parent for other objects?
                 #Manakel 2/12/2005: parent replaced by parent Name but why Parent name in partice and parent for other objects?
-                if(AllScene.particleDict.has_key(parentname)):
+                if(parentname in AllScene.particleDict):
                     out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]=self."+ parentname + "getEffect().attachNewNode(self." + collnodeS + "_Node)\n")
                     out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]=self."+ parentname + "getEffect().attachNewNode(self." + collnodeS + "_Node)\n")
                 else:
                 else:
                     out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]=self."+ parentname + ".attachNewNode(self." + collnodeS + "_Node)\n")
                     out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]=self."+ parentname + ".attachNewNode(self." + collnodeS + "_Node)\n")

+ 1 - 3
contrib/src/sceneeditor/seForceGroup.py

@@ -1,8 +1,6 @@
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.PhysicsManagerGlobal import *
 from direct.showbase.PhysicsManagerGlobal import *
-#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import
-from pandac.PandaModules import ForceNode
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 import sys
 import sys
 
 

+ 8 - 8
contrib/src/sceneeditor/seGeometry.py

@@ -12,7 +12,7 @@
 #
 #
 #################################################################
 #################################################################
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.directtools.DirectGlobals import *
 from direct.directtools.DirectGlobals import *
 from direct.directtools.DirectUtil import *
 from direct.directtools.DirectUtil import *
 import math
 import math
@@ -41,10 +41,10 @@ class LineNodePath(NodePath):
         ls.setColor(colorVec)
         ls.setColor(colorVec)
 
 
     def moveTo( self, *_args ):
     def moveTo( self, *_args ):
-        apply( self.lineSegs.moveTo, _args )
+        self.lineSegs.moveTo(*_args)
 
 
     def drawTo( self, *_args ):
     def drawTo( self, *_args ):
-        apply( self.lineSegs.drawTo, _args )
+        self.lineSegs.drawTo(*_args)
 
 
     def create( self, frameAccurate = 0 ):
     def create( self, frameAccurate = 0 ):
         self.lineSegs.create( self.lineNode, frameAccurate )
         self.lineSegs.create( self.lineNode, frameAccurate )
@@ -60,13 +60,13 @@ class LineNodePath(NodePath):
         self.lineSegs.setThickness( thickness )
         self.lineSegs.setThickness( thickness )
 
 
     def setColor( self, *_args ):
     def setColor( self, *_args ):
-        apply( self.lineSegs.setColor, _args )
+        self.lineSegs.setColor(*_args)
 
 
     def setVertex( self, *_args):
     def setVertex( self, *_args):
-        apply( self.lineSegs.setVertex, _args )
+        self.lineSegs.setVertex(*_args)
 
 
     def setVertexColor( self, vertex, *_args ):
     def setVertexColor( self, vertex, *_args ):
-        apply( self.lineSegs.setVertexColor, (vertex,) + _args )
+        self.lineSegs.setVertexColor(*(vertex,) + _args)
 
 
     def getCurrentPosition( self ):
     def getCurrentPosition( self ):
         return self.lineSegs.getCurrentPosition()
         return self.lineSegs.getCurrentPosition()
@@ -132,9 +132,9 @@ class LineNodePath(NodePath):
         Given a list of lists of points, draw a separate line for each list
         Given a list of lists of points, draw a separate line for each list
         """
         """
         for pointList in lineList:
         for pointList in lineList:
-            apply(self.moveTo, pointList[0])
+            self.moveTo(*pointList[0])
             for point in pointList[1:]:
             for point in pointList[1:]:
-                apply(self.drawTo, point)
+                self.drawTo(*point)
 
 
 ##
 ##
 ## Given a point in space, and a direction, find the point of intersection
 ## Given a point in space, and a direction, find the point of intersection

+ 10 - 11
contrib/src/sceneeditor/seLights.py

@@ -3,9 +3,8 @@
 # Written by Yi-Hong Lin, [email protected], 2004
 # Written by Yi-Hong Lin, [email protected], 2004
 #################################################################
 #################################################################
 from direct.showbase.DirectObject import *
 from direct.showbase.DirectObject import *
-from string import lower
 from direct.directtools import DirectUtil
 from direct.directtools import DirectUtil
-from pandac.PandaModules import *
+from panda3d.core import *
 import string
 import string
 
 
 
 
@@ -341,7 +340,7 @@ class seLightManager(NodePath):
         if type == 'ambient':
         if type == 'ambient':
             self.ambientCount += 1
             self.ambientCount += 1
             if(name=='DEFAULT_NAME'):
             if(name=='DEFAULT_NAME'):
-                light = AmbientLight('ambient_' + `self.ambientCount`)
+                light = AmbientLight('ambient_' + repr(self.ambientCount))
             else:
             else:
                 light = AmbientLight(name)
                 light = AmbientLight(name)
 
 
@@ -350,7 +349,7 @@ class seLightManager(NodePath):
         elif type == 'directional':
         elif type == 'directional':
             self.directionalCount += 1
             self.directionalCount += 1
             if(name=='DEFAULT_NAME'):
             if(name=='DEFAULT_NAME'):
-                light = DirectionalLight('directional_' + `self.directionalCount`)
+                light = DirectionalLight('directional_' + repr(self.directionalCount))
             else:
             else:
                 light = DirectionalLight(name)
                 light = DirectionalLight(name)
 
 
@@ -360,7 +359,7 @@ class seLightManager(NodePath):
         elif type == 'point':
         elif type == 'point':
             self.pointCount += 1
             self.pointCount += 1
             if(name=='DEFAULT_NAME'):
             if(name=='DEFAULT_NAME'):
-                light = PointLight('point_' + `self.pointCount`)
+                light = PointLight('point_' + repr(self.pointCount))
             else:
             else:
                 light = PointLight(name)
                 light = PointLight(name)
 
 
@@ -371,7 +370,7 @@ class seLightManager(NodePath):
         elif type == 'spot':
         elif type == 'spot':
             self.spotCount += 1
             self.spotCount += 1
             if(name=='DEFAULT_NAME'):
             if(name=='DEFAULT_NAME'):
-                light = Spotlight('spot_' + `self.spotCount`)
+                light = Spotlight('spot_' + repr(self.spotCount))
             else:
             else:
                 light = Spotlight(name)
                 light = Spotlight(name)
 
 
@@ -382,7 +381,7 @@ class seLightManager(NodePath):
             light.setAttenuation(Vec3(constant, linear, quadratic))
             light.setAttenuation(Vec3(constant, linear, quadratic))
             light.setExponent(exponent)
             light.setExponent(exponent)
         else:
         else:
-            print 'Invalid light type'
+            print('Invalid light type')
             return None
             return None
 
 
         # Create the seLight objects and put the light object we just created into it.
         # Create the seLight objects and put the light object we just created into it.
@@ -411,7 +410,7 @@ class seLightManager(NodePath):
         # Attention!!
         # Attention!!
         # only Spotlight obj nneds to be specified a lens node first. i.e. setLens() first!
         # only Spotlight obj nneds to be specified a lens node first. i.e. setLens() first!
         #################################################################
         #################################################################
-        type = lower(light.getType().getName())
+        type = light.getType().getName().lower()
 
 
         specularColor = VBase4(1)
         specularColor = VBase4(1)
         position = Point3(0,0,0)
         position = Point3(0,0,0)
@@ -451,7 +450,7 @@ class seLightManager(NodePath):
             quadratic = Attenuation.getZ()
             quadratic = Attenuation.getZ()
             exponent = light.getExponent()
             exponent = light.getExponent()
         else:
         else:
-            print 'Invalid light type'
+            print('Invalid light type')
             return None
             return None
 
 
         lightNode = seLight(light,self,type,
         lightNode = seLight(light,self,type,
@@ -508,7 +507,7 @@ class seLightManager(NodePath):
         # isLight(self.name)
         # isLight(self.name)
         # Use a string as a index to check if there existing a light named "name"
         # Use a string as a index to check if there existing a light named "name"
         #################################################################
         #################################################################
-        return self.lightDict.has_key(name)
+        return name in self.lightDict
 
 
     def rename(self,oName,nName):
     def rename(self,oName,nName):
         #################################################################
         #################################################################
@@ -523,7 +522,7 @@ class seLightManager(NodePath):
             del self.lightDict[oName]
             del self.lightDict[oName]
             return self.lightDict.keys(),lightNode
             return self.lightDict.keys(),lightNode
         else:
         else:
-            print '----Light Mnager: No such Light!'
+            print('----Light Mnager: No such Light!')
 
 
     def getLightNodeList(self):
     def getLightNodeList(self):
         #################################################################
         #################################################################

+ 1 - 1
contrib/src/sceneeditor/seManipulation.py

@@ -520,7 +520,7 @@ class ObjectHandles(NodePath,DirectObject):
         # To avoid recreating a vec every frame
         # To avoid recreating a vec every frame
         self.hitPt = Vec3(0)
         self.hitPt = Vec3(0)
         # Get a handle on the components
         # Get a handle on the components
-        self.xHandles = self.find('**/X')
+        self.xHandles = self.find('**/ohScalingNode')
         self.xPostGroup = self.xHandles.find('**/x-post-group')
         self.xPostGroup = self.xHandles.find('**/x-post-group')
         self.xPostCollision = self.xHandles.find('**/x-post')
         self.xPostCollision = self.xHandles.find('**/x-post')
         self.xRingGroup = self.xHandles.find('**/x-ring-group')
         self.xRingGroup = self.xHandles.find('**/x-ring-group')

+ 153 - 146
contrib/src/sceneeditor/seMopathRecorder.py

@@ -25,10 +25,17 @@ from direct.tkwidgets.Slider import Slider
 from direct.tkwidgets.EntryScale import EntryScale
 from direct.tkwidgets.EntryScale import EntryScale
 from direct.tkwidgets.VectorWidgets import Vector2Entry, Vector3Entry
 from direct.tkwidgets.VectorWidgets import Vector2Entry, Vector3Entry
 from direct.tkwidgets.VectorWidgets import ColorEntry
 from direct.tkwidgets.VectorWidgets import ColorEntry
-from Tkinter import Button, Frame, Radiobutton, Checkbutton, Label
-from Tkinter import StringVar, BooleanVar, Entry, Scale
-import os, string, Tkinter, Pmw
-import __builtin__
+import os, string, sys, Pmw
+
+if sys.version_info >= (3, 0):
+    from tkinter import Button, Frame, Radiobutton, Checkbutton, Label
+    from tkinter import StringVar, BooleanVar, Entry, Scale
+    import tkinter
+else:
+    from Tkinter import Button, Frame, Radiobutton, Checkbutton, Label
+    from Tkinter import StringVar, BooleanVar, Entry, Scale
+    import Tkinter as tkinter
+
 
 
 PRF_UTILITIES = [
 PRF_UTILITIES = [
     'lambda: camera.lookAt(render)',
     'lambda: camera.lookAt(render)',
@@ -123,7 +130,7 @@ class MopathRecorder(AppShell, DirectObject):
         self.postPoints = []
         self.postPoints = []
         self.pointSetDict = {}
         self.pointSetDict = {}
         self.pointSetCount = 0
         self.pointSetCount = 0
-        self.pointSetName = self.name + '-ps-' + `self.pointSetCount`
+        self.pointSetName = self.name + '-ps-' + repr(self.pointSetCount)
         # User callback to call before recording point
         # User callback to call before recording point
         self.samplingMode = 'Continuous'
         self.samplingMode = 'Continuous'
         self.preRecordFunc = None
         self.preRecordFunc = None
@@ -233,7 +240,7 @@ class MopathRecorder(AppShell, DirectObject):
             self.undoButton['state'] = 'normal'
             self.undoButton['state'] = 'normal'
         else:
         else:
             self.undoButton['state'] = 'disabled'
             self.undoButton['state'] = 'disabled'
-        self.undoButton.pack(side = Tkinter.LEFT, expand = 0)
+        self.undoButton.pack(side = tkinter.LEFT, expand = 0)
         self.bind(self.undoButton, 'Undo last operation')
         self.bind(self.undoButton, 'Undo last operation')
 
 
         self.redoButton = Button(self.menuFrame, text = 'Redo',
         self.redoButton = Button(self.menuFrame, text = 'Redo',
@@ -242,19 +249,19 @@ class MopathRecorder(AppShell, DirectObject):
             self.redoButton['state'] = 'normal'
             self.redoButton['state'] = 'normal'
         else:
         else:
             self.redoButton['state'] = 'disabled'
             self.redoButton['state'] = 'disabled'
-        self.redoButton.pack(side = Tkinter.LEFT, expand = 0)
+        self.redoButton.pack(side = tkinter.LEFT, expand = 0)
         self.bind(self.redoButton, 'Redo last operation')
         self.bind(self.redoButton, 'Redo last operation')
 
 
         # Record button
         # Record button
-        mainFrame = Frame(interior, relief = Tkinter.SUNKEN, borderwidth = 2)
+        mainFrame = Frame(interior, relief = tkinter.SUNKEN, borderwidth = 2)
         frame = Frame(mainFrame)
         frame = Frame(mainFrame)
         # Active node path
         # Active node path
         # Button to select active node path
         # Button to select active node path
         widget = self.createButton(frame, 'Recording', 'Node Path:',
         widget = self.createButton(frame, 'Recording', 'Node Path:',
                                    'Select Active Mopath Node Path',
                                    'Select Active Mopath Node Path',
                                    lambda s = self: SEditor.select(s.nodePath),
                                    lambda s = self: SEditor.select(s.nodePath),
-                                   side = Tkinter.LEFT, expand = 0)
-        widget['relief'] = Tkinter.FLAT
+                                   side = tkinter.LEFT, expand = 0)
+        widget['relief'] = tkinter.FLAT
         self.nodePathMenu = Pmw.ComboBox(
         self.nodePathMenu = Pmw.ComboBox(
             frame, entry_width = 20,
             frame, entry_width = 20,
             selectioncommand = self.selectNodePathNamed,
             selectioncommand = self.selectNodePathNamed,
@@ -264,7 +271,7 @@ class MopathRecorder(AppShell, DirectObject):
             self.nodePathMenu.component('entryfield_entry'))
             self.nodePathMenu.component('entryfield_entry'))
         self.nodePathMenuBG = (
         self.nodePathMenuBG = (
             self.nodePathMenuEntry.configure('background')[3])
             self.nodePathMenuEntry.configure('background')[3])
-        self.nodePathMenu.pack(side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+        self.nodePathMenu.pack(side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         self.bind(self.nodePathMenu,
         self.bind(self.nodePathMenu,
                   'Select active node path used for recording and playback')
                   'Select active node path used for recording and playback')
         # Recording type
         # Recording type
@@ -285,81 +292,81 @@ class MopathRecorder(AppShell, DirectObject):
             'Recording', 'Extend',
             'Recording', 'Extend',
             ('Next record session extends existing path'),
             ('Next record session extends existing path'),
             self.recordingType, 'Extend', expand = 0)
             self.recordingType, 'Extend', expand = 0)
-        frame.pack(fill = Tkinter.X, expand = 1)
+        frame.pack(fill = tkinter.X, expand = 1)
 
 
         frame = Frame(mainFrame)
         frame = Frame(mainFrame)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Recording', 'Record',
             frame, 'Recording', 'Record',
             'On: path is being recorded', self.toggleRecord, 0,
             'On: path is being recorded', self.toggleRecord, 0,
-            side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 1)
-        widget.configure(foreground = 'Red', relief = Tkinter.RAISED, borderwidth = 2,
-                         anchor = Tkinter.CENTER, width = 16)
+            side = tkinter.LEFT, fill = tkinter.BOTH, expand = 1)
+        widget.configure(foreground = 'Red', relief = tkinter.RAISED, borderwidth = 2,
+                         anchor = tkinter.CENTER, width = 16)
         widget = self.createButton(frame, 'Recording', 'Add Keyframe',
         widget = self.createButton(frame, 'Recording', 'Add Keyframe',
                                    'Add Keyframe To Current Path',
                                    'Add Keyframe To Current Path',
                                    self.addKeyframe,
                                    self.addKeyframe,
-                                   side = Tkinter.LEFT, expand = 1)
+                                   side = tkinter.LEFT, expand = 1)
 
 
         widget = self.createButton(frame, 'Recording', 'Bind Path to Node',
         widget = self.createButton(frame, 'Recording', 'Bind Path to Node',
                                    'Bind Motion Path to selected Object',
                                    'Bind Motion Path to selected Object',
                                    self.bindMotionPathToNode,
                                    self.bindMotionPathToNode,
-                                   side = Tkinter.LEFT, expand = 1)
+                                   side = tkinter.LEFT, expand = 1)
 
 
 
 
-        frame.pack(fill = Tkinter.X, expand = 1)
+        frame.pack(fill = tkinter.X, expand = 1)
 
 
-        mainFrame.pack(expand = 1, fill = Tkinter.X, pady = 3)
+        mainFrame.pack(expand = 1, fill = tkinter.X, pady = 3)
 
 
         # Playback controls
         # Playback controls
-        playbackFrame = Frame(interior, relief = Tkinter.SUNKEN,
+        playbackFrame = Frame(interior, relief = tkinter.SUNKEN,
                               borderwidth = 2)
                               borderwidth = 2)
         Label(playbackFrame, text = 'PLAYBACK CONTROLS',
         Label(playbackFrame, text = 'PLAYBACK CONTROLS',
-              font=('MSSansSerif', 12, 'bold')).pack(fill = Tkinter.X)
+              font=('MSSansSerif', 12, 'bold')).pack(fill = tkinter.X)
         # Main playback control slider
         # Main playback control slider
         widget = self.createEntryScale(
         widget = self.createEntryScale(
             playbackFrame, 'Playback', 'Time', 'Set current playback time',
             playbackFrame, 'Playback', 'Time', 'Set current playback time',
-            resolution = 0.01, command = self.playbackGoTo, side = Tkinter.TOP)
-        widget.component('hull')['relief'] = Tkinter.RIDGE
+            resolution = 0.01, command = self.playbackGoTo, side = tkinter.TOP)
+        widget.component('hull')['relief'] = tkinter.RIDGE
         # Kill playback task if drag slider
         # Kill playback task if drag slider
         widget['preCallback'] = self.stopPlayback
         widget['preCallback'] = self.stopPlayback
         # Jam duration entry into entry scale
         # Jam duration entry into entry scale
         self.createLabeledEntry(widget.labelFrame, 'Resample', 'Path Duration',
         self.createLabeledEntry(widget.labelFrame, 'Resample', 'Path Duration',
                                 'Set total curve duration',
                                 'Set total curve duration',
                                 command = self.setPathDuration,
                                 command = self.setPathDuration,
-                                side = Tkinter.LEFT, expand = 0)
+                                side = tkinter.LEFT, expand = 0)
         # Start stop buttons
         # Start stop buttons
         frame = Frame(playbackFrame)
         frame = Frame(playbackFrame)
         widget = self.createButton(frame, 'Playback', '<<',
         widget = self.createButton(frame, 'Playback', '<<',
                                    'Jump to start of playback',
                                    'Jump to start of playback',
                                    self.jumpToStartOfPlayback,
                                    self.jumpToStartOfPlayback,
-                                   side = Tkinter.LEFT, expand = 1)
+                                   side = tkinter.LEFT, expand = 1)
         widget['font'] = (('MSSansSerif', 12, 'bold'))
         widget['font'] = (('MSSansSerif', 12, 'bold'))
         widget = self.createCheckbutton(frame, 'Playback', 'Play',
         widget = self.createCheckbutton(frame, 'Playback', 'Play',
                                         'Start/Stop playback',
                                         'Start/Stop playback',
                                         self.startStopPlayback, 0,
                                         self.startStopPlayback, 0,
-                                        side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 1)
+                                        side = tkinter.LEFT, fill = tkinter.BOTH, expand = 1)
         widget.configure(anchor = 'center', justify = 'center',
         widget.configure(anchor = 'center', justify = 'center',
-                         relief = Tkinter.RAISED, font = ('MSSansSerif', 12, 'bold'))
+                         relief = tkinter.RAISED, font = ('MSSansSerif', 12, 'bold'))
         widget = self.createButton(frame, 'Playback', '>>',
         widget = self.createButton(frame, 'Playback', '>>',
                                    'Jump to end of playback',
                                    'Jump to end of playback',
                                    self.jumpToEndOfPlayback,
                                    self.jumpToEndOfPlayback,
-                                   side = Tkinter.LEFT, expand = 1)
+                                   side = tkinter.LEFT, expand = 1)
         widget['font'] = (('MSSansSerif', 12, 'bold'))
         widget['font'] = (('MSSansSerif', 12, 'bold'))
         self.createCheckbutton(frame, 'Playback', 'Loop',
         self.createCheckbutton(frame, 'Playback', 'Loop',
                                'On: loop playback',
                                'On: loop playback',
                                self.setLoopPlayback, self.loopPlayback,
                                self.setLoopPlayback, self.loopPlayback,
-                               side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 0)
-        frame.pack(fill = Tkinter.X, expand = 1)
+                               side = tkinter.LEFT, fill = tkinter.BOTH, expand = 0)
+        frame.pack(fill = tkinter.X, expand = 1)
 
 
         # Speed control
         # Speed control
         frame = Frame(playbackFrame)
         frame = Frame(playbackFrame)
-        widget = Button(frame, text = 'PB Speed Vernier', relief = Tkinter.FLAT,
+        widget = Button(frame, text = 'PB Speed Vernier', relief = tkinter.FLAT,
                         command = lambda s = self: s.setSpeedScale(1.0))
                         command = lambda s = self: s.setSpeedScale(1.0))
-        widget.pack(side = Tkinter.LEFT, expand = 0)
+        widget.pack(side = tkinter.LEFT, expand = 0)
         self.speedScale = Scale(frame, from_ = -1, to = 1,
         self.speedScale = Scale(frame, from_ = -1, to = 1,
                                 resolution = 0.01, showvalue = 0,
                                 resolution = 0.01, showvalue = 0,
                                 width = 10, orient = 'horizontal',
                                 width = 10, orient = 'horizontal',
                                 command = self.setPlaybackSF)
                                 command = self.setPlaybackSF)
-        self.speedScale.pack(side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+        self.speedScale.pack(side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         self.speedVar = StringVar()
         self.speedVar = StringVar()
         self.speedVar.set("0.00")
         self.speedVar.set("0.00")
         self.speedEntry = Entry(frame, textvariable = self.speedVar,
         self.speedEntry = Entry(frame, textvariable = self.speedVar,
@@ -368,14 +375,14 @@ class MopathRecorder(AppShell, DirectObject):
             '<Return>',
             '<Return>',
             lambda e = None, s = self: s.setSpeedScale(
             lambda e = None, s = self: s.setSpeedScale(
             string.atof(s.speedVar.get())))
             string.atof(s.speedVar.get())))
-        self.speedEntry.pack(side = Tkinter.LEFT, expand = 0)
-        frame.pack(fill = Tkinter.X, expand = 1)
+        self.speedEntry.pack(side = tkinter.LEFT, expand = 0)
+        frame.pack(fill = tkinter.X, expand = 1)
 
 
-        playbackFrame.pack(fill = Tkinter.X, pady = 2)
+        playbackFrame.pack(fill = tkinter.X, pady = 2)
 
 
         # Create notebook pages
         # Create notebook pages
         self.mainNotebook = Pmw.NoteBook(interior)
         self.mainNotebook = Pmw.NoteBook(interior)
-        self.mainNotebook.pack(fill = Tkinter.BOTH, expand = 1)
+        self.mainNotebook.pack(fill = tkinter.BOTH, expand = 1)
         self.resamplePage = self.mainNotebook.add('Resample')
         self.resamplePage = self.mainNotebook.add('Resample')
         self.refinePage = self.mainNotebook.add('Refine')
         self.refinePage = self.mainNotebook.add('Refine')
         self.extendPage = self.mainNotebook.add('Extend')
         self.extendPage = self.mainNotebook.add('Extend')
@@ -386,35 +393,35 @@ class MopathRecorder(AppShell, DirectObject):
         ## RESAMPLE PAGE
         ## RESAMPLE PAGE
         label = Label(self.resamplePage, text = 'RESAMPLE CURVE',
         label = Label(self.resamplePage, text = 'RESAMPLE CURVE',
                       font=('MSSansSerif', 12, 'bold'))
                       font=('MSSansSerif', 12, 'bold'))
-        label.pack(fill = Tkinter.X)
+        label.pack(fill = tkinter.X)
 
 
         # Resample
         # Resample
         resampleFrame = Frame(
         resampleFrame = Frame(
-            self.resamplePage, relief = Tkinter.SUNKEN, borderwidth = 2)
+            self.resamplePage, relief = tkinter.SUNKEN, borderwidth = 2)
         label = Label(resampleFrame, text = 'RESAMPLE CURVE',
         label = Label(resampleFrame, text = 'RESAMPLE CURVE',
                       font=('MSSansSerif', 12, 'bold')).pack()
                       font=('MSSansSerif', 12, 'bold')).pack()
         widget = self.createSlider(
         widget = self.createSlider(
             resampleFrame, 'Resample', 'Num. Samples',
             resampleFrame, 'Resample', 'Num. Samples',
             'Number of samples in resampled curve',
             'Number of samples in resampled curve',
             resolution = 1, min = 2, max = 1000, command = self.setNumSamples)
             resolution = 1, min = 2, max = 1000, command = self.setNumSamples)
-        widget.component('hull')['relief'] = Tkinter.RIDGE
+        widget.component('hull')['relief'] = tkinter.RIDGE
         widget['postCallback'] = self.sampleCurve
         widget['postCallback'] = self.sampleCurve
 
 
         frame = Frame(resampleFrame)
         frame = Frame(resampleFrame)
         self.createButton(
         self.createButton(
             frame, 'Resample', 'Make Even',
             frame, 'Resample', 'Make Even',
             'Apply timewarp so resulting path has constant velocity',
             'Apply timewarp so resulting path has constant velocity',
-            self.makeEven, side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+            self.makeEven, side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         self.createButton(
         self.createButton(
             frame, 'Resample', 'Face Forward',
             frame, 'Resample', 'Face Forward',
             'Compute HPR so resulting hpr curve faces along xyz tangent',
             'Compute HPR so resulting hpr curve faces along xyz tangent',
-            self.faceForward, side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
-        frame.pack(fill = Tkinter.X, expand = 0)
-        resampleFrame.pack(fill = Tkinter.X, expand = 0, pady = 2)
+            self.faceForward, side = tkinter.LEFT, fill = tkinter.X, expand = 1)
+        frame.pack(fill = tkinter.X, expand = 0)
+        resampleFrame.pack(fill = tkinter.X, expand = 0, pady = 2)
 
 
         # Desample
         # Desample
         desampleFrame = Frame(
         desampleFrame = Frame(
-            self.resamplePage, relief = Tkinter.SUNKEN, borderwidth = 2)
+            self.resamplePage, relief = tkinter.SUNKEN, borderwidth = 2)
         Label(desampleFrame, text = 'DESAMPLE CURVE',
         Label(desampleFrame, text = 'DESAMPLE CURVE',
               font=('MSSansSerif', 12, 'bold')).pack()
               font=('MSSansSerif', 12, 'bold')).pack()
         widget = self.createSlider(
         widget = self.createSlider(
@@ -422,16 +429,16 @@ class MopathRecorder(AppShell, DirectObject):
             'Specify number of points to skip between samples',
             'Specify number of points to skip between samples',
             min = 1, max = 100, resolution = 1,
             min = 1, max = 100, resolution = 1,
             command = self.setDesampleFrequency)
             command = self.setDesampleFrequency)
-        widget.component('hull')['relief'] = Tkinter.RIDGE
+        widget.component('hull')['relief'] = tkinter.RIDGE
         widget['postCallback'] = self.desampleCurve
         widget['postCallback'] = self.desampleCurve
-        desampleFrame.pack(fill = Tkinter.X, expand = 0, pady = 2)
+        desampleFrame.pack(fill = tkinter.X, expand = 0, pady = 2)
 
 
         ## REFINE PAGE ##
         ## REFINE PAGE ##
-        refineFrame = Frame(self.refinePage, relief = Tkinter.SUNKEN,
+        refineFrame = Frame(self.refinePage, relief = tkinter.SUNKEN,
                             borderwidth = 2)
                             borderwidth = 2)
         label = Label(refineFrame, text = 'REFINE CURVE',
         label = Label(refineFrame, text = 'REFINE CURVE',
                       font=('MSSansSerif', 12, 'bold'))
                       font=('MSSansSerif', 12, 'bold'))
-        label.pack(fill = Tkinter.X)
+        label.pack(fill = tkinter.X)
 
 
         widget = self.createSlider(refineFrame,
         widget = self.createSlider(refineFrame,
                                        'Refine Page', 'Refine From',
                                        'Refine Page', 'Refine From',
@@ -460,14 +467,14 @@ class MopathRecorder(AppShell, DirectObject):
                                        command = self.setRefineStop)
                                        command = self.setRefineStop)
         widget['preCallback'] = self.setRefineMode
         widget['preCallback'] = self.setRefineMode
         widget['postCallback'] = self.getPostPoints
         widget['postCallback'] = self.getPostPoints
-        refineFrame.pack(fill = Tkinter.X)
+        refineFrame.pack(fill = tkinter.X)
 
 
         ## EXTEND PAGE ##
         ## EXTEND PAGE ##
-        extendFrame = Frame(self.extendPage, relief = Tkinter.SUNKEN,
+        extendFrame = Frame(self.extendPage, relief = tkinter.SUNKEN,
                             borderwidth = 2)
                             borderwidth = 2)
         label = Label(extendFrame, text = 'EXTEND CURVE',
         label = Label(extendFrame, text = 'EXTEND CURVE',
                       font=('MSSansSerif', 12, 'bold'))
                       font=('MSSansSerif', 12, 'bold'))
-        label.pack(fill = Tkinter.X)
+        label.pack(fill = tkinter.X)
 
 
         widget = self.createSlider(extendFrame,
         widget = self.createSlider(extendFrame,
                                        'Extend Page', 'Extend From',
                                        'Extend Page', 'Extend From',
@@ -483,14 +490,14 @@ class MopathRecorder(AppShell, DirectObject):
             resolution = 0.01,
             resolution = 0.01,
             command = self.setControlStart)
             command = self.setControlStart)
         widget['preCallback'] = self.setExtendMode
         widget['preCallback'] = self.setExtendMode
-        extendFrame.pack(fill = Tkinter.X)
+        extendFrame.pack(fill = tkinter.X)
 
 
         ## CROP PAGE ##
         ## CROP PAGE ##
-        cropFrame = Frame(self.cropPage, relief = Tkinter.SUNKEN,
+        cropFrame = Frame(self.cropPage, relief = tkinter.SUNKEN,
                             borderwidth = 2)
                             borderwidth = 2)
         label = Label(cropFrame, text = 'CROP CURVE',
         label = Label(cropFrame, text = 'CROP CURVE',
                       font=('MSSansSerif', 12, 'bold'))
                       font=('MSSansSerif', 12, 'bold'))
-        label.pack(fill = Tkinter.X)
+        label.pack(fill = tkinter.X)
 
 
         widget = self.createSlider(
         widget = self.createSlider(
             cropFrame,
             cropFrame,
@@ -508,11 +515,11 @@ class MopathRecorder(AppShell, DirectObject):
 
 
         self.createButton(cropFrame, 'Crop Page', 'Crop Curve',
         self.createButton(cropFrame, 'Crop Page', 'Crop Curve',
                           'Crop curve to specified from to times',
                           'Crop curve to specified from to times',
-                          self.cropCurve, fill = Tkinter.NONE)
-        cropFrame.pack(fill = Tkinter.X)
+                          self.cropCurve, fill = tkinter.NONE)
+        cropFrame.pack(fill = tkinter.X)
 
 
         ## DRAW PAGE ##
         ## DRAW PAGE ##
-        drawFrame = Frame(self.drawPage, relief = Tkinter.SUNKEN,
+        drawFrame = Frame(self.drawPage, relief = tkinter.SUNKEN,
                            borderwidth = 2)
                            borderwidth = 2)
 
 
         self.sf = Pmw.ScrolledFrame(self.drawPage, horizflex = 'elastic')
         self.sf = Pmw.ScrolledFrame(self.drawPage, horizflex = 'elastic')
@@ -521,57 +528,57 @@ class MopathRecorder(AppShell, DirectObject):
 
 
         label = Label(sfFrame, text = 'CURVE RENDERING STYLE',
         label = Label(sfFrame, text = 'CURVE RENDERING STYLE',
                       font=('MSSansSerif', 12, 'bold'))
                       font=('MSSansSerif', 12, 'bold'))
-        label.pack(fill = Tkinter.X)
+        label.pack(fill = tkinter.X)
 
 
         frame = Frame(sfFrame)
         frame = Frame(sfFrame)
-        Label(frame, text = 'SHOW:').pack(side = Tkinter.LEFT, expand = 0)
+        Label(frame, text = 'SHOW:').pack(side = tkinter.LEFT, expand = 0)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Style', 'Path',
             frame, 'Style', 'Path',
             'On: path is visible', self.setPathVis, 1,
             'On: path is visible', self.setPathVis, 1,
-            side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+            side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Style', 'Knots',
             frame, 'Style', 'Knots',
             'On: path knots are visible', self.setKnotVis, 1,
             'On: path knots are visible', self.setKnotVis, 1,
-            side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+            side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Style', 'CVs',
             frame, 'Style', 'CVs',
             'On: path CVs are visible', self.setCvVis, 0,
             'On: path CVs are visible', self.setCvVis, 0,
-            side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+            side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Style', 'Hull',
             frame, 'Style', 'Hull',
             'On: path hull is visible', self.setHullVis, 0,
             'On: path hull is visible', self.setHullVis, 0,
-            side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+            side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Style', 'Trace',
             frame, 'Style', 'Trace',
             'On: record is visible', self.setTraceVis, 0,
             'On: record is visible', self.setTraceVis, 0,
-            side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
+            side = tkinter.LEFT, fill = tkinter.X, expand = 1)
         widget = self.createCheckbutton(
         widget = self.createCheckbutton(
             frame, 'Style', 'Marker',
             frame, 'Style', 'Marker',
             'On: playback marker is visible', self.setMarkerVis, 0,
             'On: playback marker is visible', self.setMarkerVis, 0,
-            side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
-        frame.pack(fill = Tkinter.X, expand = 1)
+            side = tkinter.LEFT, fill = tkinter.X, expand = 1)
+        frame.pack(fill = tkinter.X, expand = 1)
         # Sliders
         # Sliders
         widget = self.createSlider(
         widget = self.createSlider(
             sfFrame, 'Style', 'Num Segs',
             sfFrame, 'Style', 'Num Segs',
             'Set number of segments used to approximate each parametric unit',
             'Set number of segments used to approximate each parametric unit',
             min = 1.0, max = 400, resolution = 1.0,
             min = 1.0, max = 400, resolution = 1.0,
             value = 40,
             value = 40,
-            command = self.setNumSegs, side = Tkinter.TOP)
-        widget.component('hull')['relief'] = Tkinter.RIDGE
+            command = self.setNumSegs, side = tkinter.TOP)
+        widget.component('hull')['relief'] = tkinter.RIDGE
         widget = self.createSlider(
         widget = self.createSlider(
             sfFrame, 'Style', 'Num Ticks',
             sfFrame, 'Style', 'Num Ticks',
             'Set number of tick marks drawn for each unit of time',
             'Set number of tick marks drawn for each unit of time',
             min = 0.0, max = 10.0, resolution = 1.0,
             min = 0.0, max = 10.0, resolution = 1.0,
             value = 0.0,
             value = 0.0,
-            command = self.setNumTicks, side = Tkinter.TOP)
-        widget.component('hull')['relief'] = Tkinter.RIDGE
+            command = self.setNumTicks, side = tkinter.TOP)
+        widget.component('hull')['relief'] = tkinter.RIDGE
         widget = self.createSlider(
         widget = self.createSlider(
             sfFrame, 'Style', 'Tick Scale',
             sfFrame, 'Style', 'Tick Scale',
             'Set visible size of time tick marks',
             'Set visible size of time tick marks',
             min = 0.01, max = 100.0, resolution = 0.01,
             min = 0.01, max = 100.0, resolution = 0.01,
             value = 5.0,
             value = 5.0,
-            command = self.setTickScale, side = Tkinter.TOP)
-        widget.component('hull')['relief'] = Tkinter.RIDGE
+            command = self.setTickScale, side = tkinter.TOP)
+        widget.component('hull')['relief'] = tkinter.RIDGE
         self.createColorEntry(
         self.createColorEntry(
             sfFrame, 'Style', 'Path Color',
             sfFrame, 'Style', 'Path Color',
             'Color of curve',
             'Color of curve',
@@ -598,14 +605,14 @@ class MopathRecorder(AppShell, DirectObject):
             command = self.setHullColor,
             command = self.setHullColor,
             value = [255.0,128.0,128.0,255.0])
             value = [255.0,128.0,128.0,255.0])
 
 
-        #drawFrame.pack(fill = Tkinter.X)
+        #drawFrame.pack(fill = tkinter.X)
 
 
         ## OPTIONS PAGE ##
         ## OPTIONS PAGE ##
-        optionsFrame = Frame(self.optionsPage, relief = Tkinter.SUNKEN,
+        optionsFrame = Frame(self.optionsPage, relief = tkinter.SUNKEN,
                             borderwidth = 2)
                             borderwidth = 2)
         label = Label(optionsFrame, text = 'RECORDING OPTIONS',
         label = Label(optionsFrame, text = 'RECORDING OPTIONS',
                       font=('MSSansSerif', 12, 'bold'))
                       font=('MSSansSerif', 12, 'bold'))
-        label.pack(fill = Tkinter.X)
+        label.pack(fill = tkinter.X)
         # Hooks
         # Hooks
         frame = Frame(optionsFrame)
         frame = Frame(optionsFrame)
         widget = self.createLabeledEntry(
         widget = self.createLabeledEntry(
@@ -614,7 +621,7 @@ class MopathRecorder(AppShell, DirectObject):
             value = self.startStopHook,
             value = self.startStopHook,
             command = self.setStartStopHook)[0]
             command = self.setStartStopHook)[0]
         label = self.getWidget('Recording', 'Record Hook-Label')
         label = self.getWidget('Recording', 'Record Hook-Label')
-        label.configure(width = 16, anchor = Tkinter.W)
+        label.configure(width = 16, anchor = tkinter.W)
         self.setStartStopHook()
         self.setStartStopHook()
         widget = self.createLabeledEntry(
         widget = self.createLabeledEntry(
             frame, 'Recording', 'Keyframe Hook',
             frame, 'Recording', 'Keyframe Hook',
@@ -622,9 +629,9 @@ class MopathRecorder(AppShell, DirectObject):
             value = self.keyframeHook,
             value = self.keyframeHook,
             command = self.setKeyframeHook)[0]
             command = self.setKeyframeHook)[0]
         label = self.getWidget('Recording', 'Keyframe Hook-Label')
         label = self.getWidget('Recording', 'Keyframe Hook-Label')
-        label.configure(width = 16, anchor = Tkinter.W)
+        label.configure(width = 16, anchor = tkinter.W)
         self.setKeyframeHook()
         self.setKeyframeHook()
-        frame.pack(expand = 1, fill = Tkinter.X)
+        frame.pack(expand = 1, fill = tkinter.X)
         # PreRecordFunc
         # PreRecordFunc
         frame = Frame(optionsFrame)
         frame = Frame(optionsFrame)
         widget = self.createComboBox(
         widget = self.createComboBox(
@@ -632,17 +639,17 @@ class MopathRecorder(AppShell, DirectObject):
             'Function called before sampling each point',
             'Function called before sampling each point',
             PRF_UTILITIES, self.setPreRecordFunc,
             PRF_UTILITIES, self.setPreRecordFunc,
             history = 1, expand = 1)
             history = 1, expand = 1)
-        widget.configure(label_width = 16, label_anchor = Tkinter.W)
+        widget.configure(label_width = 16, label_anchor = tkinter.W)
         widget.configure(entryfield_entry_state = 'normal')
         widget.configure(entryfield_entry_state = 'normal')
         # Initialize preRecordFunc
         # Initialize preRecordFunc
         self.preRecordFunc = eval(PRF_UTILITIES[0])
         self.preRecordFunc = eval(PRF_UTILITIES[0])
         self.createCheckbutton(frame, 'Recording', 'PRF Active',
         self.createCheckbutton(frame, 'Recording', 'PRF Active',
                                'On: Pre Record Func enabled',
                                'On: Pre Record Func enabled',
                                None, 0,
                                None, 0,
-                               side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 0)
-        frame.pack(expand = 1, fill = Tkinter.X)
+                               side = tkinter.LEFT, fill = tkinter.BOTH, expand = 0)
+        frame.pack(expand = 1, fill = tkinter.X)
         # Pack record frame
         # Pack record frame
-        optionsFrame.pack(fill = Tkinter.X, pady = 2)
+        optionsFrame.pack(fill = tkinter.X, pady = 2)
 
 
         self.mainNotebook.setnaturalsize()
         self.mainNotebook.setnaturalsize()
 
 
@@ -682,16 +689,16 @@ class MopathRecorder(AppShell, DirectObject):
         marker if subnode selected
         marker if subnode selected
         """
         """
         taskMgr.remove(self.name + '-curveEditTask')
         taskMgr.remove(self.name + '-curveEditTask')
-        print nodePath.id()
-        if nodePath.id() in self.playbackMarkerIds:
+        print(nodePath.get_key())
+        if nodePath.get_key() in self.playbackMarkerIds:
             SEditor.select(self.playbackMarker)
             SEditor.select(self.playbackMarker)
-        elif nodePath.id() in self.tangentMarkerIds:
+        elif nodePath.get_key() in self.tangentMarkerIds:
             SEditor.select(self.tangentMarker)
             SEditor.select(self.tangentMarker)
-        elif nodePath.id() == self.playbackMarker.id():
+        elif nodePath.get_key() == self.playbackMarker.get_key():
             self.tangentGroup.show()
             self.tangentGroup.show()
             taskMgr.add(self.curveEditTask,
             taskMgr.add(self.curveEditTask,
                                      self.name + '-curveEditTask')
                                      self.name + '-curveEditTask')
-        elif nodePath.id() == self.tangentMarker.id():
+        elif nodePath.get_key() == self.tangentMarker.get_key():
             self.tangentGroup.show()
             self.tangentGroup.show()
             taskMgr.add(self.curveEditTask,
             taskMgr.add(self.curveEditTask,
                                      self.name + '-curveEditTask')
                                      self.name + '-curveEditTask')
@@ -699,7 +706,7 @@ class MopathRecorder(AppShell, DirectObject):
             self.tangentGroup.hide()
             self.tangentGroup.hide()
 
 
     def getChildIds(self, nodePath):
     def getChildIds(self, nodePath):
-        ids = [nodePath.id()]
+        ids = [nodePath.get_key()]
         kids = nodePath.getChildren()
         kids = nodePath.getChildren()
         for kid in kids:
         for kid in kids:
             ids += self.getChildIds(kid)
             ids += self.getChildIds(kid)
@@ -710,14 +717,14 @@ class MopathRecorder(AppShell, DirectObject):
         Hook called upon deselection of a node path used to select playback
         Hook called upon deselection of a node path used to select playback
         marker if subnode selected
         marker if subnode selected
         """
         """
-        if ((nodePath.id() == self.playbackMarker.id()) or
-            (nodePath.id() == self.tangentMarker.id())):
+        if ((nodePath.get_key() == self.playbackMarker.get_key()) or
+            (nodePath.get_key() == self.tangentMarker.get_key())):
             self.tangentGroup.hide()
             self.tangentGroup.hide()
 
 
     def curveEditTask(self,state):
     def curveEditTask(self,state):
         if self.curveCollection != None:
         if self.curveCollection != None:
             # Update curve position
             # Update curve position
-            if self.manipulandumId == self.playbackMarker.id():
+            if self.manipulandumId == self.playbackMarker.get_key():
                 # Show playback marker
                 # Show playback marker
                 self.playbackMarker.getChild(0).show()
                 self.playbackMarker.getChild(0).show()
                 pos = Point3(0)
                 pos = Point3(0)
@@ -731,7 +738,7 @@ class MopathRecorder(AppShell, DirectObject):
                 # Note: this calls recompute on the curves
                 # Note: this calls recompute on the curves
                 self.nurbsCurveDrawer.draw()
                 self.nurbsCurveDrawer.draw()
             # Update tangent
             # Update tangent
-            if self.manipulandumId == self.tangentMarker.id():
+            if self.manipulandumId == self.tangentMarker.get_key():
                 # If manipulating marker, update tangent
                 # If manipulating marker, update tangent
                 # Hide playback marker
                 # Hide playback marker
                 self.playbackMarker.getChild(0).hide()
                 self.playbackMarker.getChild(0).hide()
@@ -766,10 +773,10 @@ class MopathRecorder(AppShell, DirectObject):
     def manipulateObjectStartHook(self):
     def manipulateObjectStartHook(self):
         self.manipulandumId = None
         self.manipulandumId = None
         if SEditor.selected.last:
         if SEditor.selected.last:
-            if SEditor.selected.last.id() == self.playbackMarker.id():
-                self.manipulandumId = self.playbackMarker.id()
-            elif SEditor.selected.last.id() == self.tangentMarker.id():
-                self.manipulandumId = self.tangentMarker.id()
+            if SEditor.selected.last.get_key() == self.playbackMarker.get_key():
+                self.manipulandumId = self.playbackMarker.get_key()
+            elif SEditor.selected.last.get_key() == self.tangentMarker.get_key():
+                self.manipulandumId = self.tangentMarker.get_key()
 
 
     def manipulateObjectCleanupHook(self):
     def manipulateObjectCleanupHook(self):
         # Clear flag
         # Clear flag
@@ -799,7 +806,7 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def createNewPointSet(self, curveName = None):
     def createNewPointSet(self, curveName = None):
         if curveName == None:
         if curveName == None:
-            self.pointSetName = self.name + '-ps-' + `self.pointSetCount`
+            self.pointSetName = self.name + '-ps-' + repr(self.pointSetCount)
         else:
         else:
             self.pointSetName = curveName
             self.pointSetName = curveName
         # Update dictionary and record pointer to new point set
         # Update dictionary and record pointer to new point set
@@ -1137,7 +1144,7 @@ class MopathRecorder(AppShell, DirectObject):
     def computeCurves(self):
     def computeCurves(self):
         # Check to make sure curve fitters have points
         # Check to make sure curve fitters have points
         if (self.curveFitter.getNumSamples() == 0):
         if (self.curveFitter.getNumSamples() == 0):
-            print 'MopathRecorder.computeCurves: Must define curve first'
+            print('MopathRecorder.computeCurves: Must define curve first')
             return
             return
         # Create curves
         # Create curves
         # XYZ
         # XYZ
@@ -1282,8 +1289,8 @@ class MopathRecorder(AppShell, DirectObject):
             dictName = name
             dictName = name
         else:
         else:
             # Generate a unique name for the dict
             # Generate a unique name for the dict
-            dictName = name # + '-' + `nodePath.id()`
-        if not dict.has_key(dictName):
+            dictName = name # + '-' + repr(nodePath.get_key())
+        if dictName not in dict:
             # Update combo box to include new item
             # Update combo box to include new item
             names.append(dictName)
             names.append(dictName)
             listbox = menu.component('scrolledlist')
             listbox = menu.component('scrolledlist')
@@ -1386,7 +1393,7 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def desampleCurve(self):
     def desampleCurve(self):
         if (self.curveFitter.getNumSamples() == 0):
         if (self.curveFitter.getNumSamples() == 0):
-            print 'MopathRecorder.desampleCurve: Must define curve first'
+            print('MopathRecorder.desampleCurve: Must define curve first')
             return
             return
         # NOTE: This is destructive, points will be deleted from curve fitter
         # NOTE: This is destructive, points will be deleted from curve fitter
         self.curveFitter.desample(self.desampleFrequency)
         self.curveFitter.desample(self.desampleFrequency)
@@ -1400,7 +1407,7 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def sampleCurve(self, fCompute = 1, curveName = None):
     def sampleCurve(self, fCompute = 1, curveName = None):
         if self.curveCollection == None:
         if self.curveCollection == None:
-            print 'MopathRecorder.sampleCurve: Must define curve first'
+            print('MopathRecorder.sampleCurve: Must define curve first')
             return
             return
         # Reset curve fitters
         # Reset curve fitters
         self.curveFitter.reset()
         self.curveFitter.reset()
@@ -1617,7 +1624,7 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def cropCurve(self):
     def cropCurve(self):
         if self.pointSet == None:
         if self.pointSet == None:
-            print 'Empty Point Set'
+            print('Empty Point Set')
             return
             return
         # Keep handle on old points
         # Keep handle on old points
         oldPoints = self.pointSet
         oldPoints = self.pointSet
@@ -1653,15 +1660,15 @@ class MopathRecorder(AppShell, DirectObject):
         # Use first directory in model path
         # Use first directory in model path
         mPath = getModelPath()
         mPath = getModelPath()
         if mPath.getNumDirectories() > 0:
         if mPath.getNumDirectories() > 0:
-            if `mPath.getDirectory(0)` == '.':
+            if repr(mPath.getDirectory(0)) == '.':
                 path = '.'
                 path = '.'
             else:
             else:
                 path = mPath.getDirectory(0).toOsSpecific()
                 path = mPath.getDirectory(0).toOsSpecific()
         else:
         else:
             path = '.'
             path = '.'
         if not os.path.isdir(path):
         if not os.path.isdir(path):
-            print 'MopathRecorder Info: Empty Model Path!'
-            print 'Using current directory'
+            print('MopathRecorder Info: Empty Model Path!')
+            print('Using current directory')
             path = '.'
             path = '.'
         mopathFilename = askopenfilename(
         mopathFilename = askopenfilename(
             defaultextension = '.egg',
             defaultextension = '.egg',
@@ -1692,15 +1699,15 @@ class MopathRecorder(AppShell, DirectObject):
         # Use first directory in model path
         # Use first directory in model path
         mPath = getModelPath()
         mPath = getModelPath()
         if mPath.getNumDirectories() > 0:
         if mPath.getNumDirectories() > 0:
-            if `mPath.getDirectory(0)` == '.':
+            if repr(mPath.getDirectory(0)) == '.':
                 path = '.'
                 path = '.'
             else:
             else:
                 path = mPath.getDirectory(0).toOsSpecific()
                 path = mPath.getDirectory(0).toOsSpecific()
         else:
         else:
             path = '.'
             path = '.'
         if not os.path.isdir(path):
         if not os.path.isdir(path):
-            print 'MopathRecorder Info: Empty Model Path!'
-            print 'Using current directory'
+            print('MopathRecorder Info: Empty Model Path!')
+            print('Using current directory')
             path = '.'
             path = '.'
         mopathFilename = asksaveasfilename(
         mopathFilename = asksaveasfilename(
             defaultextension = '.egg',
             defaultextension = '.egg',
@@ -1734,28 +1741,28 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def createLabeledEntry(self, parent, category, text, balloonHelp,
     def createLabeledEntry(self, parent, category, text, balloonHelp,
                            value = '', command = None,
                            value = '', command = None,
-                           relief = 'sunken', side = Tkinter.LEFT,
+                           relief = 'sunken', side = tkinter.LEFT,
                            expand = 1, width = 12):
                            expand = 1, width = 12):
         frame = Frame(parent)
         frame = Frame(parent)
         variable = StringVar()
         variable = StringVar()
         variable.set(value)
         variable.set(value)
         label = Label(frame, text = text)
         label = Label(frame, text = text)
-        label.pack(side = Tkinter.LEFT, fill = Tkinter.X)
+        label.pack(side = tkinter.LEFT, fill = tkinter.X)
         self.bind(label, balloonHelp)
         self.bind(label, balloonHelp)
         self.widgetDict[category + '-' + text + '-Label'] = label
         self.widgetDict[category + '-' + text + '-Label'] = label
         entry = Entry(frame, width = width, relief = relief,
         entry = Entry(frame, width = width, relief = relief,
                       textvariable = variable)
                       textvariable = variable)
-        entry.pack(side = Tkinter.LEFT, fill = Tkinter.X, expand = expand)
+        entry.pack(side = tkinter.LEFT, fill = tkinter.X, expand = expand)
         self.bind(entry, balloonHelp)
         self.bind(entry, balloonHelp)
         self.widgetDict[category + '-' + text] = entry
         self.widgetDict[category + '-' + text] = entry
         self.variableDict[category + '-' + text] = variable
         self.variableDict[category + '-' + text] = variable
         if command:
         if command:
             entry.bind('<Return>', command)
             entry.bind('<Return>', command)
-        frame.pack(side = side, fill = Tkinter.X, expand = expand)
+        frame.pack(side = side, fill = tkinter.X, expand = expand)
         return (frame, label, entry)
         return (frame, label, entry)
 
 
     def createButton(self, parent, category, text, balloonHelp, command,
     def createButton(self, parent, category, text, balloonHelp, command,
-                     side = 'top', expand = 0, fill = Tkinter.X):
+                     side = 'top', expand = 0, fill = tkinter.X):
         widget = Button(parent, text = text)
         widget = Button(parent, text = text)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
@@ -1766,10 +1773,10 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def createCheckbutton(self, parent, category, text,
     def createCheckbutton(self, parent, category, text,
                           balloonHelp, command, initialState,
                           balloonHelp, command, initialState,
-                          side = 'top', fill = Tkinter.X, expand = 0):
+                          side = 'top', fill = tkinter.X, expand = 0):
         bool = BooleanVar()
         bool = BooleanVar()
         bool.set(initialState)
         bool.set(initialState)
-        widget = Checkbutton(parent, text = text, anchor = Tkinter.W,
+        widget = Checkbutton(parent, text = text, anchor = tkinter.W,
                          variable = bool)
                          variable = bool)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
@@ -1781,8 +1788,8 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def createRadiobutton(self, parent, side, category, text,
     def createRadiobutton(self, parent, side, category, text,
                           balloonHelp, variable, value,
                           balloonHelp, variable, value,
-                          command = None, fill = Tkinter.X, expand = 0):
-        widget = Radiobutton(parent, text = text, anchor = Tkinter.W,
+                          command = None, fill = tkinter.X, expand = 0):
+        widget = Radiobutton(parent, text = text, anchor = tkinter.W,
                              variable = variable, value = value)
                              variable = variable, value = value)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
@@ -1798,10 +1805,10 @@ class MopathRecorder(AppShell, DirectObject):
         kw['min'] = min
         kw['min'] = min
         kw['maxVelocity'] = maxVelocity
         kw['maxVelocity'] = maxVelocity
         kw['resolution'] = resolution
         kw['resolution'] = resolution
-        widget = apply(Floater, (parent,), kw)
+        widget = Floater(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
-        widget.pack(fill = Tkinter.X)
+        widget.pack(fill = tkinter.X)
         self.bind(widget, balloonHelp)
         self.bind(widget, balloonHelp)
         self.widgetDict[category + '-' + text] = widget
         self.widgetDict[category + '-' + text] = widget
         return widget
         return widget
@@ -1809,10 +1816,10 @@ class MopathRecorder(AppShell, DirectObject):
     def createAngleDial(self, parent, category, text, balloonHelp,
     def createAngleDial(self, parent, category, text, balloonHelp,
                         command = None, **kw):
                         command = None, **kw):
         kw['text'] = text
         kw['text'] = text
-        widget = apply(AngleDial,(parent,), kw)
+        widget = AngleDial(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
-        widget.pack(fill = Tkinter.X)
+        widget.pack(fill = tkinter.X)
         self.bind(widget, balloonHelp)
         self.bind(widget, balloonHelp)
         self.widgetDict[category + '-' + text] = widget
         self.widgetDict[category + '-' + text] = widget
         return widget
         return widget
@@ -1820,13 +1827,13 @@ class MopathRecorder(AppShell, DirectObject):
     def createSlider(self, parent, category, text, balloonHelp,
     def createSlider(self, parent, category, text, balloonHelp,
                          command = None, min = 0.0, max = 1.0,
                          command = None, min = 0.0, max = 1.0,
                          resolution = None,
                          resolution = None,
-                         side = Tkinter.TOP, fill = Tkinter.X, expand = 1, **kw):
+                         side = tkinter.TOP, fill = tkinter.X, expand = 1, **kw):
         kw['text'] = text
         kw['text'] = text
         kw['min'] = min
         kw['min'] = min
         kw['max'] = max
         kw['max'] = max
         kw['resolution'] = resolution
         kw['resolution'] = resolution
         #widget = apply(EntryScale, (parent,), kw)
         #widget = apply(EntryScale, (parent,), kw)
-        widget = apply(Slider, (parent,), kw)
+        widget = Slider(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(side = side, fill = fill, expand = expand)
         widget.pack(side = side, fill = fill, expand = expand)
@@ -1837,12 +1844,12 @@ class MopathRecorder(AppShell, DirectObject):
     def createEntryScale(self, parent, category, text, balloonHelp,
     def createEntryScale(self, parent, category, text, balloonHelp,
                          command = None, min = 0.0, max = 1.0,
                          command = None, min = 0.0, max = 1.0,
                          resolution = None,
                          resolution = None,
-                         side = Tkinter.TOP, fill = Tkinter.X, expand = 1, **kw):
+                         side = tkinter.TOP, fill = tkinter.X, expand = 1, **kw):
         kw['text'] = text
         kw['text'] = text
         kw['min'] = min
         kw['min'] = min
         kw['max'] = max
         kw['max'] = max
         kw['resolution'] = resolution
         kw['resolution'] = resolution
-        widget = apply(EntryScale, (parent,), kw)
+        widget = EntryScale(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(side = side, fill = fill, expand = expand)
         widget.pack(side = side, fill = fill, expand = expand)
@@ -1854,10 +1861,10 @@ class MopathRecorder(AppShell, DirectObject):
                            command = None, **kw):
                            command = None, **kw):
         # Set label's text
         # Set label's text
         kw['text'] = text
         kw['text'] = text
-        widget = apply(Vector2Entry, (parent,), kw)
+        widget = Vector2Entry(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
-        widget.pack(fill = Tkinter.X)
+        widget.pack(fill = tkinter.X)
         self.bind(widget, balloonHelp)
         self.bind(widget, balloonHelp)
         self.widgetDict[category + '-' + text] = widget
         self.widgetDict[category + '-' + text] = widget
         return widget
         return widget
@@ -1866,10 +1873,10 @@ class MopathRecorder(AppShell, DirectObject):
                            command = None, **kw):
                            command = None, **kw):
         # Set label's text
         # Set label's text
         kw['text'] = text
         kw['text'] = text
-        widget = apply(Vector3Entry, (parent,), kw)
+        widget = Vector3Entry(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
-        widget.pack(fill = Tkinter.X)
+        widget.pack(fill = tkinter.X)
         self.bind(widget, balloonHelp)
         self.bind(widget, balloonHelp)
         self.widgetDict[category + '-' + text] = widget
         self.widgetDict[category + '-' + text] = widget
         return widget
         return widget
@@ -1878,10 +1885,10 @@ class MopathRecorder(AppShell, DirectObject):
                          command = None, **kw):
                          command = None, **kw):
         # Set label's text
         # Set label's text
         kw['text'] = text
         kw['text'] = text
-        widget = apply(ColorEntry, (parent,) ,kw)
+        widget = ColorEntry(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
-        widget.pack(fill = Tkinter.X)
+        widget.pack(fill = tkinter.X)
         self.bind(widget, balloonHelp)
         self.bind(widget, balloonHelp)
         self.widgetDict[category + '-' + text] = widget
         self.widgetDict[category + '-' + text] = widget
         return widget
         return widget
@@ -1891,13 +1898,13 @@ class MopathRecorder(AppShell, DirectObject):
         optionVar = StringVar()
         optionVar = StringVar()
         if len(items) > 0:
         if len(items) > 0:
             optionVar.set(items[0])
             optionVar.set(items[0])
-        widget = Pmw.OptionMenu(parent, labelpos = Tkinter.W, label_text = text,
+        widget = Pmw.OptionMenu(parent, labelpos = tkinter.W, label_text = text,
                                 label_width = 12, menu_tearoff = 1,
                                 label_width = 12, menu_tearoff = 1,
                                 menubutton_textvariable = optionVar,
                                 menubutton_textvariable = optionVar,
                                 items = items)
                                 items = items)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
-        widget.pack(fill = Tkinter.X)
+        widget.pack(fill = tkinter.X)
         self.bind(widget.component('menubutton'), balloonHelp)
         self.bind(widget.component('menubutton'), balloonHelp)
         self.widgetDict[category + '-' + text] = widget
         self.widgetDict[category + '-' + text] = widget
         self.variableDict[category + '-' + text] = optionVar
         self.variableDict[category + '-' + text] = optionVar
@@ -1905,9 +1912,9 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def createComboBox(self, parent, category, text, balloonHelp,
     def createComboBox(self, parent, category, text, balloonHelp,
                        items, command, history = 0,
                        items, command, history = 0,
-                       side = Tkinter.LEFT, expand = 0, fill = Tkinter.X):
+                       side = tkinter.LEFT, expand = 0, fill = tkinter.X):
         widget = Pmw.ComboBox(parent,
         widget = Pmw.ComboBox(parent,
-                              labelpos = Tkinter.W,
+                              labelpos = tkinter.W,
                               label_text = text,
                               label_text = text,
                               label_anchor = 'e',
                               label_anchor = 'e',
                               label_width = 12,
                               label_width = 12,
@@ -1959,14 +1966,14 @@ class MopathRecorder(AppShell, DirectObject):
 
 
     def bindMotionPathToNode(self):
     def bindMotionPathToNode(self):
         if self.curveCollection == None:
         if self.curveCollection == None:
-            print '----Error: you need to select or create a curve first!'
+            print('----Error: you need to select or create a curve first!')
             return
             return
         self.accept('MP_checkName', self.bindMotionPath)
         self.accept('MP_checkName', self.bindMotionPath)
         self.askName = namePathPanel(MopathRecorder.count)
         self.askName = namePathPanel(MopathRecorder.count)
         return
         return
 
 
     def bindMotionPath(self,name=None,test=None):
     def bindMotionPath(self,name=None,test=None):
-        print test
+        print(test)
         self.ignore('MP_checkName')
         self.ignore('MP_checkName')
         del self.askName
         del self.askName
         self.curveCollection.getCurve(0).setName(name)
         self.curveCollection.getCurve(0).setName(name)
@@ -1993,7 +2000,7 @@ class MopathRecorder(AppShell, DirectObject):
         If the list is not None, it will put the vurve back into the curve list.
         If the list is not None, it will put the vurve back into the curve list.
         else, do nothing.
         else, do nothing.
         '''
         '''
-        print curveList
+        print(curveList)
         self.ignore('curveListFor'+self.name)
         self.ignore('curveListFor'+self.name)
         if curveList != None:
         if curveList != None:
             for collection in curveList:
             for collection in curveList:
@@ -2037,8 +2044,8 @@ class namePathPanel(AppShell):
 
 
         dataFrame = Frame(mainFrame)
         dataFrame = Frame(mainFrame)
         label = Label(dataFrame, text='This name will be used as a reference for this Path.',font=('MSSansSerif', 10))
         label = Label(dataFrame, text='This name will be used as a reference for this Path.',font=('MSSansSerif', 10))
-        label.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X)
-        dataFrame.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X, padx=5, pady=10)
+        label.pack(side = tkinter.TOP, expand = 0, fill = tkinter.X)
+        dataFrame.pack(side = tkinter.TOP, expand = 0, fill = tkinter.X, padx=5, pady=10)
 
 
         dataFrame = Frame(mainFrame)
         dataFrame = Frame(mainFrame)
         self.inputZone = Pmw.EntryField(dataFrame, labelpos='w', label_text = 'Name Selected Path: ',
         self.inputZone = Pmw.EntryField(dataFrame, labelpos='w', label_text = 'Name Selected Path: ',
@@ -2046,14 +2053,14 @@ class namePathPanel(AppShell):
                                         label_font=('MSSansSerif', 10),
                                         label_font=('MSSansSerif', 10),
                                         validate = None,
                                         validate = None,
                                         entry_width = 20)
                                         entry_width = 20)
-        self.inputZone.pack(side = Tkinter.LEFT, fill=Tkinter.X,expand=0)
+        self.inputZone.pack(side = tkinter.LEFT, fill=tkinter.X,expand=0)
 
 
         self.button_ok = Button(dataFrame, text="OK", command=self.ok_press,width=10)
         self.button_ok = Button(dataFrame, text="OK", command=self.ok_press,width=10)
-        self.button_ok.pack(fill=Tkinter.X,expand=0,side=Tkinter.LEFT, padx = 3)
+        self.button_ok.pack(fill=tkinter.X,expand=0,side=tkinter.LEFT, padx = 3)
 
 
-        dataFrame.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X, padx=10, pady=10)
+        dataFrame.pack(side = tkinter.TOP, expand = 0, fill = tkinter.X, padx=10, pady=10)
 
 
-        mainFrame.pack(expand = 1, fill = Tkinter.BOTH)
+        mainFrame.pack(expand = 1, fill = tkinter.BOTH)
 
 
 
 
 
 

+ 4 - 4
contrib/src/sceneeditor/seParticleEffect.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import *
+from panda3d.core import *
 import seParticles
 import seParticles
 import seForceGroup
 import seForceGroup
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
@@ -209,9 +209,9 @@ class ParticleEffect(NodePath):
         """loadConfig(filename)"""
         """loadConfig(filename)"""
         #try:
         #try:
         #    if vfs:
         #    if vfs:
-        print vfs.readFile(filename)
-        exec vfs.readFile(filename)
-        print "Particle Effect Reading using VFS"
+        print(vfs.readFile(filename))
+        exec(vfs.readFile(filename))
+        print("Particle Effect Reading using VFS")
         #    else:
         #    else:
         #       execfile(filename.toOsSpecific())
         #       execfile(filename.toOsSpecific())
         #       print "Shouldnt be wrong"
         #       print "Shouldnt be wrong"

+ 29 - 22
contrib/src/sceneeditor/seParticlePanel.py

@@ -2,9 +2,7 @@
 
 
 # Import Tkinter, Pmw, and the floater code from this directory tree.
 # Import Tkinter, Pmw, and the floater code from this directory tree.
 from direct.tkwidgets.AppShell import AppShell
 from direct.tkwidgets.AppShell import AppShell
-from tkFileDialog import *
-from tkSimpleDialog import askstring
-import os, Pmw, Tkinter
+import os, Pmw, sys
 from direct.tkwidgets.Dial import AngleDial
 from direct.tkwidgets.Dial import AngleDial
 from direct.tkwidgets.Floater import Floater
 from direct.tkwidgets.Floater import Floater
 from direct.tkwidgets.Slider import Slider
 from direct.tkwidgets.Slider import Slider
@@ -15,6 +13,15 @@ import seForceGroup
 import seParticles
 import seParticles
 import seParticleEffect
 import seParticleEffect
 
 
+
+if sys.version_info >= (3, 0):
+    from tkinter.filedialog import *
+    from tkinter.simpledialog import askstring
+else:
+    from tkFileDialog import *
+    from tkSimpleDialog import askstring
+
+
 class ParticlePanel(AppShell):
 class ParticlePanel(AppShell):
     # Override class variables
     # Override class variables
     appname = 'Particle Panel'
     appname = 'Particle Panel'
@@ -774,7 +781,7 @@ class ParticlePanel(AppShell):
         kw['min'] = min
         kw['min'] = min
         kw['resolution'] = resolution
         kw['resolution'] = resolution
         kw['numDigits'] = numDigits
         kw['numDigits'] = numDigits
-        widget = apply(Floater, (parent,), kw)
+        widget = Floater(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(fill = X)
         widget.pack(fill = X)
@@ -786,7 +793,7 @@ class ParticlePanel(AppShell):
                         command = None, **kw):
                         command = None, **kw):
         kw['text'] = text
         kw['text'] = text
         kw['style'] = 'mini'
         kw['style'] = 'mini'
-        widget = apply(AngleDial,(parent,), kw)
+        widget = AngleDial(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(fill = X)
         widget.pack(fill = X)
@@ -801,7 +808,7 @@ class ParticlePanel(AppShell):
         kw['min'] = min
         kw['min'] = min
         kw['max'] = max
         kw['max'] = max
         kw['resolution'] = resolution
         kw['resolution'] = resolution
-        widget = apply(Slider, (parent,), kw)
+        widget = Slider(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(fill = X)
         widget.pack(fill = X)
@@ -813,7 +820,7 @@ class ParticlePanel(AppShell):
                            command = None, **kw):
                            command = None, **kw):
         # Set label's text
         # Set label's text
         kw['text'] = text
         kw['text'] = text
-        widget = apply(Vector2Entry, (parent,), kw)
+        widget = Vector2Entry(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(fill = X)
         widget.pack(fill = X)
@@ -825,7 +832,7 @@ class ParticlePanel(AppShell):
                            command = None, **kw):
                            command = None, **kw):
         # Set label's text
         # Set label's text
         kw['text'] = text
         kw['text'] = text
-        widget = apply(Vector3Entry, (parent,), kw)
+        widget = Vector3Entry(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(fill = X)
         widget.pack(fill = X)
@@ -837,7 +844,7 @@ class ParticlePanel(AppShell):
                          command = None, **kw):
                          command = None, **kw):
         # Set label's text
         # Set label's text
         kw['text'] = text
         kw['text'] = text
-        widget = apply(ColorEntry, (parent,) ,kw)
+        widget = ColorEntry(parent, **kw)
         # Do this after the widget so command isn't called on creation
         # Do this after the widget so command isn't called on creation
         widget['command'] = command
         widget['command'] = command
         widget.pack(fill = X)
         widget.pack(fill = X)
@@ -992,7 +999,7 @@ class ParticlePanel(AppShell):
             self.mainNotebook.selectpage('System')
             self.mainNotebook.selectpage('System')
             self.updateInfo('System')
             self.updateInfo('System')
         else:
         else:
-            print 'ParticlePanel: No effect named ' + name
+            print('ParticlePanel: No effect named ' + name)
 
 
     def toggleEffect(self, effect, var):
     def toggleEffect(self, effect, var):
         if var.get():
         if var.get():
@@ -1041,15 +1048,15 @@ class ParticlePanel(AppShell):
         # Find path to particle directory
         # Find path to particle directory
         pPath = getParticlePath()
         pPath = getParticlePath()
         if pPath.getNumDirectories() > 0:
         if pPath.getNumDirectories() > 0:
-            if `pPath.getDirectory(0)` == '.':
+            if repr(pPath.getDirectory(0)) == '.':
                 path = '.'
                 path = '.'
             else:
             else:
                 path = pPath.getDirectory(0).toOsSpecific()
                 path = pPath.getDirectory(0).toOsSpecific()
         else:
         else:
             path = '.'
             path = '.'
         if not os.path.isdir(path):
         if not os.path.isdir(path):
-            print 'ParticlePanel Warning: Invalid default DNA directory!'
-            print 'Using current directory'
+            print('ParticlePanel Warning: Invalid default DNA directory!')
+            print('Using current directory')
             path = '.'
             path = '.'
         particleFilename = askopenfilename(
         particleFilename = askopenfilename(
             defaultextension = '.ptf',
             defaultextension = '.ptf',
@@ -1070,15 +1077,15 @@ class ParticlePanel(AppShell):
         # Find path to particle directory
         # Find path to particle directory
         pPath = getParticlePath()
         pPath = getParticlePath()
         if pPath.getNumDirectories() > 0:
         if pPath.getNumDirectories() > 0:
-            if `pPath.getDirectory(0)` == '.':
+            if repr(pPath.getDirectory(0)) == '.':
                 path = '.'
                 path = '.'
             else:
             else:
                 path = pPath.getDirectory(0).toOsSpecific()
                 path = pPath.getDirectory(0).toOsSpecific()
         else:
         else:
             path = '.'
             path = '.'
         if not os.path.isdir(path):
         if not os.path.isdir(path):
-            print 'ParticlePanel Warning: Invalid default DNA directory!'
-            print 'Using current directory'
+            print('ParticlePanel Warning: Invalid default DNA directory!')
+            print('Using current directory')
             path = '.'
             path = '.'
         particleFilename = asksaveasfilename(
         particleFilename = asksaveasfilename(
             defaultextension = '.ptf',
             defaultextension = '.ptf',
@@ -1654,7 +1661,7 @@ class ParticlePanel(AppShell):
     def setRendererSpriteNonAnimatedTheta(self, theta):
     def setRendererSpriteNonAnimatedTheta(self, theta):
         self.particles.renderer.setNonanimatedTheta(theta)
         self.particles.renderer.setNonanimatedTheta(theta)
     def setRendererSpriteBlendMethod(self, blendMethod):
     def setRendererSpriteBlendMethod(self, blendMethod):
-        print blendMethod
+        print(blendMethod)
         if blendMethod == 'PP_NO_BLEND':
         if blendMethod == 'PP_NO_BLEND':
             bMethod = BaseParticleRenderer.PPNOBLEND
             bMethod = BaseParticleRenderer.PPNOBLEND
         elif blendMethod == 'PP_BLEND_LINEAR':
         elif blendMethod == 'PP_BLEND_LINEAR':
@@ -1863,7 +1870,7 @@ class ParticlePanel(AppShell):
                                       count, force):
                                       count, force):
         def setVec(vec, f = force):
         def setVec(vec, f = force):
             f.setVector(vec[0], vec[1], vec[2])
             f.setVector(vec[0], vec[1], vec[2])
-        forceName = 'Vector Force-' + `count`
+        forceName = 'Vector Force-' + repr(count)
         frame = self.createForceFrame(forcePage, forceName, force)
         frame = self.createForceFrame(forcePage, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         vec = force.getLocalVector()
         vec = force.getLocalVector()
@@ -1875,7 +1882,7 @@ class ParticlePanel(AppShell):
 
 
     def createLinearRandomForceWidget(self, forcePage, pageName, count,
     def createLinearRandomForceWidget(self, forcePage, pageName, count,
                                 force, type):
                                 force, type):
-        forceName = type + ' Force-' + `count`
+        forceName = type + ' Force-' + repr(count)
         frame = self.createForceFrame(forcePage, forceName, force)
         frame = self.createForceFrame(forcePage, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         self.createForceActiveWidget(frame, pageName, forceName, force)
         self.createForceActiveWidget(frame, pageName, forceName, force)
@@ -1884,7 +1891,7 @@ class ParticlePanel(AppShell):
                                         count, force):
                                         count, force):
         def setCoef(coef, f = force):
         def setCoef(coef, f = force):
             f.setCoef(coef)
             f.setCoef(coef)
-        forceName = 'Friction Force-' + `count`
+        forceName = 'Friction Force-' + repr(count)
         frame = self.createForceFrame(forcePage, forceName, force)
         frame = self.createForceFrame(forcePage, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         self.createFloater(frame, pageName, forceName + ' Coef',
         self.createFloater(frame, pageName, forceName + ' Coef',
@@ -1895,7 +1902,7 @@ class ParticlePanel(AppShell):
 
 
     def createLinearCylinderVortexForceWidget(self, forcePage, pageName,
     def createLinearCylinderVortexForceWidget(self, forcePage, pageName,
                                               count, force):
                                               count, force):
-        forceName = 'Vortex Force-' + `count`
+        forceName = 'Vortex Force-' + repr(count)
         def setCoef(coef, f = force):
         def setCoef(coef, f = force):
             f.setCoef(coef)
             f.setCoef(coef)
         def setLength(length, f = force):
         def setLength(length, f = force):
@@ -1934,7 +1941,7 @@ class ParticlePanel(AppShell):
             f.setForceCenter(Point3(vec[0], vec[1], vec[2]))
             f.setForceCenter(Point3(vec[0], vec[1], vec[2]))
         def setRadius(radius, f = force):
         def setRadius(radius, f = force):
             f.setRadius(radius)
             f.setRadius(radius)
-        forceName = type + ' Force-' + `count`
+        forceName = type + ' Force-' + repr(count)
         frame = self.createForceFrame(forcePage, forceName, force)
         frame = self.createForceFrame(forcePage, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         self.createLinearForceWidgets(frame, pageName, forceName, force)
         var = self.createOptionMenu(
         var = self.createOptionMenu(

+ 5 - 25
contrib/src/sceneeditor/seParticles.py

@@ -1,28 +1,8 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.physics import *
 from direct.particles.ParticleManagerGlobal import *
 from direct.particles.ParticleManagerGlobal import *
 from direct.showbase.PhysicsManagerGlobal import *
 from direct.showbase.PhysicsManagerGlobal import *
-#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import
-from pandac.PandaModules import ParticleSystem
-from pandac.PandaModules import BaseParticleFactory
-from pandac.PandaModules import PointParticleFactory
-from pandac.PandaModules import ZSpinParticleFactory
 #import OrientedParticleFactory
 #import OrientedParticleFactory
-from pandac.PandaModules import BaseParticleRenderer
-from pandac.PandaModules import PointParticleRenderer
-from pandac.PandaModules import LineParticleRenderer
-from pandac.PandaModules import GeomParticleRenderer
-from pandac.PandaModules import SparkleParticleRenderer
-from pandac.PandaModules import SpriteParticleRenderer
-from pandac.PandaModules import BaseParticleEmitter
-from pandac.PandaModules import BoxEmitter
-from pandac.PandaModules import DiscEmitter
-from pandac.PandaModules import LineEmitter
-from pandac.PandaModules import PointEmitter
-from pandac.PandaModules import RectangleEmitter
-from pandac.PandaModules import RingEmitter
-from pandac.PandaModules import SphereSurfaceEmitter
-from pandac.PandaModules import SphereVolumeEmitter
-from pandac.PandaModules import TangentRingEmitter
 import string
 import string
 import os
 import os
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
@@ -113,7 +93,7 @@ class Particles(ParticleSystem):
         elif (type == "OrientedParticleFactory"):
         elif (type == "OrientedParticleFactory"):
             self.factory = OrientedParticleFactory.OrientedParticleFactory()
             self.factory = OrientedParticleFactory.OrientedParticleFactory()
         else:
         else:
-            print "unknown factory type: %s" % type
+            print("unknown factory type: %s" % type)
             return None
             return None
         self.factory.setLifespanBase(0.5)
         self.factory.setLifespanBase(0.5)
         ParticleSystem.ParticleSystem.setFactory(self, self.factory)
         ParticleSystem.ParticleSystem.setFactory(self, self.factory)
@@ -152,7 +132,7 @@ class Particles(ParticleSystem):
                 # See sourceFileName and sourceNodeName in SpriteParticleRenderer-extensions.py
                 # See sourceFileName and sourceNodeName in SpriteParticleRenderer-extensions.py
                 self.renderer.setTextureFromNode()
                 self.renderer.setTextureFromNode()
         else:
         else:
-            print "unknown renderer type: %s" % type
+            print("unknown renderer type: %s" % type)
             return None
             return None
         ParticleSystem.ParticleSystem.setRenderer(self, self.renderer)
         ParticleSystem.ParticleSystem.setRenderer(self, self.renderer)
 
 
@@ -183,7 +163,7 @@ class Particles(ParticleSystem):
         elif (type == "TangentRingEmitter"):
         elif (type == "TangentRingEmitter"):
             self.emitter = TangentRingEmitter.TangentRingEmitter()
             self.emitter = TangentRingEmitter.TangentRingEmitter()
         else:
         else:
-            print "unknown emitter type: %s" % type
+            print("unknown emitter type: %s" % type)
             return None
             return None
         ParticleSystem.ParticleSystem.setEmitter(self, self.emitter)
         ParticleSystem.ParticleSystem.setEmitter(self, self.emitter)
 
 

+ 34 - 27
contrib/src/sceneeditor/sePlacer.py

@@ -5,9 +5,16 @@ from direct.directtools.DirectGlobals import *
 from direct.tkwidgets.AppShell import AppShell
 from direct.tkwidgets.AppShell import AppShell
 from direct.tkwidgets.Dial import AngleDial
 from direct.tkwidgets.Dial import AngleDial
 from direct.tkwidgets.Floater import Floater
 from direct.tkwidgets.Floater import Floater
-from Tkinter import Button, Menubutton, Menu, StringVar
-from pandac.PandaModules import *
-import Tkinter, Pmw
+from panda3d.core import *
+import sys, Pmw
+
+if sys.version_info >= (3, 0):
+    from tkinter import Button, Menubutton, Menu, StringVar
+    import tkinter
+else:
+    from Tkinter import Button, Menubutton, Menu, StringVar
+    import Tkinter as tkinter
+
 """
 """
 TODO:
 TODO:
 Task to monitor pose
 Task to monitor pose
@@ -84,7 +91,7 @@ class Placer(AppShell):
     def createInterface(self):
     def createInterface(self):
         # The interior of the toplevel panel
         # The interior of the toplevel panel
         interior = self.interior()
         interior = self.interior()
-        interior['relief'] = Tkinter.FLAT
+        interior['relief'] = tkinter.FLAT
         # Add placer commands to menubar
         # Add placer commands to menubar
         self.menuBar.addmenu('Placer', 'Placer Panel Operations')
         self.menuBar.addmenu('Placer', 'Placer Panel Operations')
         self.menuBar.addmenuitem('Placer', 'command',
         self.menuBar.addmenuitem('Placer', 'command',
@@ -113,7 +120,7 @@ class Placer(AppShell):
         # Get a handle to the menu frame
         # Get a handle to the menu frame
         menuFrame = self.menuFrame
         menuFrame = self.menuFrame
         self.nodePathMenu = Pmw.ComboBox(
         self.nodePathMenu = Pmw.ComboBox(
-            menuFrame, labelpos = Tkinter.W, label_text = 'Node Path:',
+            menuFrame, labelpos = tkinter.W, label_text = 'Node Path:',
             entry_width = 20,
             entry_width = 20,
             selectioncommand = self.selectNodePathNamed,
             selectioncommand = self.selectNodePathNamed,
             scrolledlist_items = self.nodePathNames)
             scrolledlist_items = self.nodePathNames)
@@ -168,7 +175,7 @@ class Placer(AppShell):
                              tag_text = 'Position',
                              tag_text = 'Position',
                              tag_font=('MSSansSerif', 14),
                              tag_font=('MSSansSerif', 14),
                              tag_activebackground = '#909090',
                              tag_activebackground = '#909090',
-                             ring_relief = Tkinter.RIDGE)
+                             ring_relief = tkinter.RIDGE)
         posMenubutton = posGroup.component('tag')
         posMenubutton = posGroup.component('tag')
         self.bind(posMenubutton, 'Position menu operations')
         self.bind(posMenubutton, 'Position menu operations')
         posMenu = Menu(posMenubutton, tearoff = 0)
         posMenu = Menu(posMenubutton, tearoff = 0)
@@ -182,7 +189,7 @@ class Placer(AppShell):
         # Create the dials
         # Create the dials
         self.posX = self.createcomponent('posX', (), None,
         self.posX = self.createcomponent('posX', (), None,
                                          Floater, (posInterior,),
                                          Floater, (posInterior,),
-                                         text = 'X', relief = Tkinter.FLAT,
+                                         text = 'X', relief = tkinter.FLAT,
                                          value = 0.0,
                                          value = 0.0,
                                          label_foreground = 'Red')
                                          label_foreground = 'Red')
         self.posX['commandData'] = ['x']
         self.posX['commandData'] = ['x']
@@ -193,7 +200,7 @@ class Placer(AppShell):
 
 
         self.posY = self.createcomponent('posY', (), None,
         self.posY = self.createcomponent('posY', (), None,
                                          Floater, (posInterior,),
                                          Floater, (posInterior,),
-                                         text = 'Y', relief = Tkinter.FLAT,
+                                         text = 'Y', relief = tkinter.FLAT,
                                          value = 0.0,
                                          value = 0.0,
                                          label_foreground = '#00A000')
                                          label_foreground = '#00A000')
         self.posY['commandData'] = ['y']
         self.posY['commandData'] = ['y']
@@ -204,7 +211,7 @@ class Placer(AppShell):
 
 
         self.posZ = self.createcomponent('posZ', (), None,
         self.posZ = self.createcomponent('posZ', (), None,
                                          Floater, (posInterior,),
                                          Floater, (posInterior,),
-                                         text = 'Z', relief = Tkinter.FLAT,
+                                         text = 'Z', relief = tkinter.FLAT,
                                          value = 0.0,
                                          value = 0.0,
                                          label_foreground = 'Blue')
                                          label_foreground = 'Blue')
         self.posZ['commandData'] = ['z']
         self.posZ['commandData'] = ['z']
@@ -219,7 +226,7 @@ class Placer(AppShell):
                              tag_text = 'Orientation',
                              tag_text = 'Orientation',
                              tag_font=('MSSansSerif', 14),
                              tag_font=('MSSansSerif', 14),
                              tag_activebackground = '#909090',
                              tag_activebackground = '#909090',
-                             ring_relief = Tkinter.RIDGE)
+                             ring_relief = tkinter.RIDGE)
         hprMenubutton = hprGroup.component('tag')
         hprMenubutton = hprGroup.component('tag')
         self.bind(hprMenubutton, 'Orientation menu operations')
         self.bind(hprMenubutton, 'Orientation menu operations')
         hprMenu = Menu(hprMenubutton, tearoff = 0)
         hprMenu = Menu(hprMenubutton, tearoff = 0)
@@ -234,7 +241,7 @@ class Placer(AppShell):
                                          AngleDial, (hprInterior,),
                                          AngleDial, (hprInterior,),
                                          style = 'mini',
                                          style = 'mini',
                                          text = 'H', value = 0.0,
                                          text = 'H', value = 0.0,
-                                         relief = Tkinter.FLAT,
+                                         relief = tkinter.FLAT,
                                          label_foreground = 'blue')
                                          label_foreground = 'blue')
         self.hprH['commandData'] = ['h']
         self.hprH['commandData'] = ['h']
         self.hprH['preCallback'] = self.xformStart
         self.hprH['preCallback'] = self.xformStart
@@ -246,7 +253,7 @@ class Placer(AppShell):
                                          AngleDial, (hprInterior,),
                                          AngleDial, (hprInterior,),
                                          style = 'mini',
                                          style = 'mini',
                                          text = 'P', value = 0.0,
                                          text = 'P', value = 0.0,
-                                         relief = Tkinter.FLAT,
+                                         relief = tkinter.FLAT,
                                          label_foreground = 'red')
                                          label_foreground = 'red')
         self.hprP['commandData'] = ['p']
         self.hprP['commandData'] = ['p']
         self.hprP['preCallback'] = self.xformStart
         self.hprP['preCallback'] = self.xformStart
@@ -258,7 +265,7 @@ class Placer(AppShell):
                                          AngleDial, (hprInterior,),
                                          AngleDial, (hprInterior,),
                                          style = 'mini',
                                          style = 'mini',
                                          text = 'R', value = 0.0,
                                          text = 'R', value = 0.0,
-                                         relief = Tkinter.FLAT,
+                                         relief = tkinter.FLAT,
                                          label_foreground = '#00A000')
                                          label_foreground = '#00A000')
         self.hprR['commandData'] = ['r']
         self.hprR['commandData'] = ['r']
         self.hprR['preCallback'] = self.xformStart
         self.hprR['preCallback'] = self.xformStart
@@ -276,7 +283,7 @@ class Placer(AppShell):
                                tag_pyclass = Menubutton,
                                tag_pyclass = Menubutton,
                                tag_font=('MSSansSerif', 14),
                                tag_font=('MSSansSerif', 14),
                                tag_activebackground = '#909090',
                                tag_activebackground = '#909090',
-                               ring_relief = Tkinter.RIDGE)
+                               ring_relief = tkinter.RIDGE)
         self.scaleMenubutton = scaleGroup.component('tag')
         self.scaleMenubutton = scaleGroup.component('tag')
         self.bind(self.scaleMenubutton, 'Scale menu operations')
         self.bind(self.scaleMenubutton, 'Scale menu operations')
         self.scaleMenubutton['textvariable'] = self.scalingMode
         self.scaleMenubutton['textvariable'] = self.scalingMode
@@ -302,7 +309,7 @@ class Placer(AppShell):
         self.scaleX = self.createcomponent('scaleX', (), None,
         self.scaleX = self.createcomponent('scaleX', (), None,
                                            Floater, (scaleInterior,),
                                            Floater, (scaleInterior,),
                                            text = 'X Scale',
                                            text = 'X Scale',
-                                           relief = Tkinter.FLAT,
+                                           relief = tkinter.FLAT,
                                            min = 0.0001, value = 1.0,
                                            min = 0.0001, value = 1.0,
                                            resetValue = 1.0,
                                            resetValue = 1.0,
                                            label_foreground = 'Red')
                                            label_foreground = 'Red')
@@ -315,7 +322,7 @@ class Placer(AppShell):
         self.scaleY = self.createcomponent('scaleY', (), None,
         self.scaleY = self.createcomponent('scaleY', (), None,
                                            Floater, (scaleInterior,),
                                            Floater, (scaleInterior,),
                                            text = 'Y Scale',
                                            text = 'Y Scale',
-                                           relief = Tkinter.FLAT,
+                                           relief = tkinter.FLAT,
                                            min = 0.0001, value = 1.0,
                                            min = 0.0001, value = 1.0,
                                            resetValue = 1.0,
                                            resetValue = 1.0,
                                            label_foreground = '#00A000')
                                            label_foreground = '#00A000')
@@ -328,7 +335,7 @@ class Placer(AppShell):
         self.scaleZ = self.createcomponent('scaleZ', (), None,
         self.scaleZ = self.createcomponent('scaleZ', (), None,
                                            Floater, (scaleInterior,),
                                            Floater, (scaleInterior,),
                                            text = 'Z Scale',
                                            text = 'Z Scale',
-                                           relief = Tkinter.FLAT,
+                                           relief = tkinter.FLAT,
                                            min = 0.0001, value = 1.0,
                                            min = 0.0001, value = 1.0,
                                            resetValue = 1.0,
                                            resetValue = 1.0,
                                            label_foreground = 'Blue')
                                            label_foreground = 'Blue')
@@ -428,7 +435,7 @@ class Placer(AppShell):
                 background = self.nodePathMenuBG)
                 background = self.nodePathMenuBG)
             # Check to see if node path and ref node path are the same
             # Check to see if node path and ref node path are the same
             if ((self.refCS != None) and
             if ((self.refCS != None) and
-                (self.refCS.id() == self['nodePath'].id())):
+                (self.refCS.get_key() == self['nodePath'].get_key())):
                 # Yes they are, use temp CS as ref
                 # Yes they are, use temp CS as ref
                 # This calls updatePlacer
                 # This calls updatePlacer
                 self.setReferenceNodePath(self.tempCS)
                 self.setReferenceNodePath(self.tempCS)
@@ -473,7 +480,7 @@ class Placer(AppShell):
                     listbox = self.refNodePathMenu.component('scrolledlist')
                     listbox = self.refNodePathMenu.component('scrolledlist')
                     listbox.setlist(self.refNodePathNames)
                     listbox.setlist(self.refNodePathNames)
         # Check to see if node path and ref node path are the same
         # Check to see if node path and ref node path are the same
-        if (nodePath != None) and (nodePath.id() == self['nodePath'].id()):
+        if (nodePath != None) and (nodePath.get_key() == self['nodePath'].get_key()):
             # Yes they are, use temp CS and update listbox accordingly
             # Yes they are, use temp CS and update listbox accordingly
             nodePath = self.tempCS
             nodePath = self.tempCS
             self.refNodePathMenu.selectitem('parent')
             self.refNodePathMenu.selectitem('parent')
@@ -508,8 +515,8 @@ class Placer(AppShell):
             dictName = name
             dictName = name
         else:
         else:
             # Generate a unique name for the dict
             # Generate a unique name for the dict
-            dictName = name + '-' + `nodePath.id()`
-        if not dict.has_key(dictName):
+            dictName = name + '-' + repr(nodePath.get_key())
+        if dictName not in dict:
             # Update combo box to include new item
             # Update combo box to include new item
             names.append(dictName)
             names.append(dictName)
             listbox = menu.component('scrolledlist')
             listbox = menu.component('scrolledlist')
@@ -769,12 +776,12 @@ class Placer(AppShell):
             posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2])
             posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2])
             hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2])
             hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2])
             scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[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))
+            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):
     def onDestroy(self, event):
         # Remove hooks
         # Remove hooks

+ 16 - 9
contrib/src/sceneeditor/seSceneGraphExplorer.py

@@ -9,9 +9,16 @@
 #
 #
 #################################################################
 #################################################################
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from Tkinter import IntVar, Frame, Label
 from seTree import TreeNode, TreeItem
 from seTree import TreeNode, TreeItem
-import Pmw, Tkinter
+
+import Pmw, sys
+
+if sys.version_info >= (3, 0):
+    from tkinter import IntVar, Frame, Label
+    import tkinter
+else:
+    from Tkinter import IntVar, Frame, Label
+    import Tkinter as tkinter
 
 
 # changing these strings requires changing sceneEditor.py SGE_ strs too!
 # changing these strings requires changing sceneEditor.py SGE_ strs too!
 # This list of items will be showed on the pop out window when user right click on
 # This list of items will be showed on the pop out window when user right click on
@@ -57,7 +64,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
 
 
         # Setup up container
         # Setup up container
         interior = self.interior()
         interior = self.interior()
-        interior.configure(relief = Tkinter.GROOVE, borderwidth = 2)
+        interior.configure(relief = tkinter.GROOVE, borderwidth = 2)
 
 
         # Create a label and an entry
         # Create a label and an entry
         self._scrolledCanvas = self.createcomponent(
         self._scrolledCanvas = self.createcomponent(
@@ -69,7 +76,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
         self._canvas = self._scrolledCanvas.component('canvas')
         self._canvas = self._scrolledCanvas.component('canvas')
         self._canvas['scrollregion'] = ('0i', '0i', '2i', '4i')
         self._canvas['scrollregion'] = ('0i', '0i', '2i', '4i')
         self._scrolledCanvas.resizescrollregion()
         self._scrolledCanvas.resizescrollregion()
-        self._scrolledCanvas.pack(padx = 3, pady = 3, expand=1, fill = Tkinter.BOTH)
+        self._scrolledCanvas.pack(padx = 3, pady = 3, expand=1, fill = tkinter.BOTH)
 
 
         self._canvas.bind('<ButtonPress-2>', self.mouse2Down)
         self._canvas.bind('<ButtonPress-2>', self.mouse2Down)
         self._canvas.bind('<B2-Motion>', self.mouse2Motion)
         self._canvas.bind('<B2-Motion>', self.mouse2Motion)
@@ -91,8 +98,8 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
             (), None,
             (), None,
             Label, (interior,),
             Label, (interior,),
             text = 'Active Reparent Target: ',
             text = 'Active Reparent Target: ',
-            anchor = Tkinter.W, justify = Tkinter.LEFT)
-        self._label.pack(fill = Tkinter.X)
+            anchor = tkinter.W, justify = tkinter.LEFT)
+        self._label.pack(fill = tkinter.X)
 
 
         # Add update parent label
         # Add update parent label
         def updateLabel(nodePath = None, s = self):
         def updateLabel(nodePath = None, s = self):
@@ -141,11 +148,11 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
         self._node.deselecttree()
         self._node.deselecttree()
 
 
     def selectNodePath(self,nodePath, callBack=True):
     def selectNodePath(self,nodePath, callBack=True):
-        item = self._node.find(nodePath.id())
+        item = self._node.find(nodePath.get_key())
         if item!= None:
         if item!= None:
             item.select(callBack)
             item.select(callBack)
         else:
         else:
-            print '----SGE: Error Selection'
+            print('----SGE: Error Selection')
 
 
 class SceneGraphExplorerItem(TreeItem):
 class SceneGraphExplorerItem(TreeItem):
 
 
@@ -164,7 +171,7 @@ class SceneGraphExplorerItem(TreeItem):
         return name
         return name
 
 
     def GetKey(self):
     def GetKey(self):
-        return self.nodePath.id()
+        return self.nodePath.get_key()
 
 
     def IsEditable(self):
     def IsEditable(self):
         # All nodes' names can be edited nowadays.
         # All nodes' names can be edited nowadays.

+ 20 - 11
contrib/src/sceneeditor/seSelection.py

@@ -11,7 +11,7 @@
 # (If we do change original directools, it will force user has to install the latest version of OUR Panda)
 # (If we do change original directools, it will force user has to install the latest version of OUR Panda)
 #
 #
 #################################################################
 #################################################################
-from pandac.PandaModules import GeomNode
+from panda3d.core import GeomNode
 from direct.directtools.DirectGlobals import *
 from direct.directtools.DirectGlobals import *
 from direct.directtools.DirectUtil import *
 from direct.directtools.DirectUtil import *
 from seGeometry import *
 from seGeometry import *
@@ -70,7 +70,7 @@ class SelectedNodePaths(DirectObject):
         """ Select the specified node path.  Multiselect as required """
         """ Select the specified node path.  Multiselect as required """
         # Do nothing if nothing selected
         # Do nothing if nothing selected
         if not nodePath:
         if not nodePath:
-            print 'Nothing selected!!'
+            print('Nothing selected!!')
             return None
             return None
 
 
         # Reset selected objects and highlight if multiSelect is false
         # Reset selected objects and highlight if multiSelect is false
@@ -78,7 +78,7 @@ class SelectedNodePaths(DirectObject):
             self.deselectAll()
             self.deselectAll()
 
 
         # Get this pointer
         # Get this pointer
-        id = nodePath.id()
+        id = nodePath.get_key()
         # First see if its already in the selected dictionary
         # First see if its already in the selected dictionary
         dnp = self.getSelectedDict(id)
         dnp = self.getSelectedDict(id)
         # If so, we're done
         # If so, we're done
@@ -96,7 +96,7 @@ class SelectedNodePaths(DirectObject):
                 # Show its bounding box
                 # Show its bounding box
                 dnp.highlight()
                 dnp.highlight()
             # Add it to the selected dictionary
             # Add it to the selected dictionary
-            self.selectedDict[dnp.id()] = dnp
+            self.selectedDict[dnp.get_key()] = dnp
         # And update last
         # And update last
         __builtins__["last"] = self.last = dnp
         __builtins__["last"] = self.last = dnp
         return dnp
         return dnp
@@ -104,7 +104,7 @@ class SelectedNodePaths(DirectObject):
     def deselect(self, nodePath):
     def deselect(self, nodePath):
         """ Deselect the specified node path """
         """ Deselect the specified node path """
         # Get this pointer
         # Get this pointer
-        id = nodePath.id()
+        id = nodePath.get_key()
         # See if it is in the selected dictionary
         # See if it is in the selected dictionary
         dnp = self.getSelectedDict(id)
         dnp = self.getSelectedDict(id)
         if dnp:
         if dnp:
@@ -124,7 +124,7 @@ class SelectedNodePaths(DirectObject):
         Return a list of all selected node paths.  No verification of
         Return a list of all selected node paths.  No verification of
         connectivity is performed on the members of the list
         connectivity is performed on the members of the list
         """
         """
-        return self.selectedDict.values()[:]
+        return list(self.selectedDict.values())
 
 
     def __getitem__(self,index):
     def __getitem__(self,index):
         return self.getSelectedAsList()[index]
         return self.getSelectedAsList()[index]
@@ -141,7 +141,7 @@ class SelectedNodePaths(DirectObject):
             return None
             return None
 
 
     def getDeselectedAsList(self):
     def getDeselectedAsList(self):
-        return self.deselectedDict.values()[:]
+        return list(self.deselectedDict.values())
 
 
     def getDeselectedDict(self, id):
     def getDeselectedDict(self, id):
         """
         """
@@ -204,15 +204,24 @@ class SelectedNodePaths(DirectObject):
         # Remove all selected nodePaths from the Scene Graph
         # Remove all selected nodePaths from the Scene Graph
         self.forEachSelectedNodePathDo(NodePath.remove)
         self.forEachSelectedNodePathDo(NodePath.remove)
 
 
+    def toggleVis(self, nodePath):
+        if nodePath.is_hidden():
+            nodePath.show()
+        else:
+            nodePath.hide()
+
     def toggleVisSelected(self):
     def toggleVisSelected(self):
         selected = self.last
         selected = self.last
         # Toggle visibility of selected node paths
         # Toggle visibility of selected node paths
         if selected:
         if selected:
-            selected.toggleVis()
+            if selected.is_hidden():
+                selected.show()
+            else:
+                selected.hide()
 
 
     def toggleVisAll(self):
     def toggleVisAll(self):
         # Toggle viz for all selected node paths
         # Toggle viz for all selected node paths
-        self.forEachSelectedNodePathDo(NodePath.toggleVis)
+        self.forEachSelectedNodePathDo(self.toggleVis)
 
 
     def isolateSelected(self):
     def isolateSelected(self):
         selected = self.last
         selected = self.last
@@ -221,7 +230,7 @@ class SelectedNodePaths(DirectObject):
 
 
     def getDirectNodePath(self, nodePath):
     def getDirectNodePath(self, nodePath):
         # Get this pointer
         # Get this pointer
-        id = nodePath.id()
+        id = nodePath.get_key()
         # First check selected dict
         # First check selected dict
         dnp = self.getSelectedDict(id)
         dnp = self.getSelectedDict(id)
         if dnp:
         if dnp:
@@ -376,7 +385,7 @@ class DirectBoundingBox:
         return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2])
         return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2])
 
 
     def __repr__(self):
     def __repr__(self):
-        return (`self.__class__` +
+        return (repr(self.__class__) +
                 '\nNodePath:\t%s\n' % self.nodePath.getName() +
                 '\nNodePath:\t%s\n' % self.nodePath.getName() +
                 'Min:\t\t%s\n' % self.vecAsString(self.min) +
                 'Min:\t\t%s\n' % self.vecAsString(self.min) +
                 'Max:\t\t%s\n' % self.vecAsString(self.max) +
                 'Max:\t\t%s\n' % self.vecAsString(self.max) +

+ 9 - 6
contrib/src/sceneeditor/seSession.py

@@ -388,7 +388,7 @@ class SeSession(DirectObject):  ### Customized DirectSession
             messenger.send('DIRECT_preSelectNodePath', [dnp])
             messenger.send('DIRECT_preSelectNodePath', [dnp])
             if fResetAncestry:
             if fResetAncestry:
                 # Update ancestry
                 # Update ancestry
-                self.ancestry = dnp.getAncestors()
+                self.ancestry = list(dnp.getAncestors())
                 self.ancestry.reverse()
                 self.ancestry.reverse()
                 self.ancestryIndex = 0
                 self.ancestryIndex = 0
             # Update the selectedNPReadout
             # Update the selectedNPReadout
@@ -479,8 +479,8 @@ class SeSession(DirectObject):  ### Customized DirectSession
 
 
 
 
     def isNotCycle(self, nodePath, parent):
     def isNotCycle(self, nodePath, parent):
-        if nodePath.id() == parent.id():
-            print 'DIRECT.reparent: Invalid parent'
+        if nodePath.get_key() == parent.get_key():
+            print('DIRECT.reparent: Invalid parent')
             return 0
             return 0
         elif parent.hasParent():
         elif parent.hasParent():
             return self.isNotCycle(nodePath, parent.getParent())
             return self.isNotCycle(nodePath, parent.getParent())
@@ -520,7 +520,10 @@ class SeSession(DirectObject):  ### Customized DirectSession
             nodePath = self.selected.last
             nodePath = self.selected.last
         if nodePath:
         if nodePath:
             # Now toggle node path's visibility state
             # Now toggle node path's visibility state
-            nodePath.toggleVis()
+            if nodePath.is_hidden():
+                nodePath.show()
+            else:
+                nodePath.hide()
 
 
     def removeNodePath(self, nodePath = 'None Given'):
     def removeNodePath(self, nodePath = 'None Given'):
         if nodePath == 'None Given':
         if nodePath == 'None Given':
@@ -732,8 +735,8 @@ class SeSession(DirectObject):  ### Customized DirectSession
         hprB = base.camera.getHpr()
         hprB = base.camera.getHpr()
         posE = Point3((radius*-1.41)+center.getX(), (radius*-1.41)+center.getY(), (radius*1.41)+center.getZ())
         posE = Point3((radius*-1.41)+center.getX(), (radius*-1.41)+center.getY(), (radius*1.41)+center.getZ())
         hprE = Point3(-45, -38, 0)
         hprE = Point3(-45, -38, 0)
-        print posB, hprB
-        print posE, hprE
+        print(posB, hprB)
+        print(posE, hprE)
         posInterval1 = base.camera.posInterval(time, posE, bakeInStart = 1)
         posInterval1 = base.camera.posInterval(time, posE, bakeInStart = 1)
         posInterval2 = base.camera.posInterval(time, posB, bakeInStart = 1)
         posInterval2 = base.camera.posInterval(time, posB, bakeInStart = 1)
 
 

+ 15 - 9
contrib/src/sceneeditor/seTree.py

@@ -12,15 +12,21 @@
 #
 #
 #################################################################
 #################################################################
 
 
-import os, sys, string, Pmw, Tkinter
+import os, sys, string, Pmw
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from Tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry
-from pandac.PandaModules import *
+from panda3d.core import *
+
+if sys.version_info >= (3, 0):
+    import tkinter
+    from tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry
+else:
+    import Tkinter as tkinter
+    from Tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry
 
 
 # Initialize icon directory
 # Initialize icon directory
 ICONDIR = getModelPath().findFile(Filename('icons')).toOsSpecific()
 ICONDIR = getModelPath().findFile(Filename('icons')).toOsSpecific()
 if not os.path.isdir(ICONDIR):
 if not os.path.isdir(ICONDIR):
-    raise RuntimeError, "can't find DIRECT icon directory (%s)" % `ICONDIR`
+    raise RuntimeError("can't find DIRECT icon directory (%r)" % ICONDIR)
 
 
 class TreeNode:
 class TreeNode:
 
 
@@ -187,9 +193,9 @@ class TreeNode:
             oldcursor = self.canvas['cursor']
             oldcursor = self.canvas['cursor']
             self.canvas['cursor'] = "watch"
             self.canvas['cursor'] = "watch"
             self.canvas.update()
             self.canvas.update()
-            self.canvas.delete(Tkinter.ALL)     # XXX could be more subtle
+            self.canvas.delete(tkinter.ALL)     # XXX could be more subtle
             self.draw(7, 2)
             self.draw(7, 2)
-            x0, y0, x1, y1 = self.canvas.bbox(Tkinter.ALL)
+            x0, y0, x1, y1 = self.canvas.bbox(tkinter.ALL)
             self.canvas.configure(scrollregion=(0, 0, x1, y1))
             self.canvas.configure(scrollregion=(0, 0, x1, y1))
             self.canvas['cursor'] = oldcursor
             self.canvas['cursor'] = oldcursor
 
 
@@ -208,7 +214,7 @@ class TreeNode:
         self.kidKeys = []
         self.kidKeys = []
         for item in sublist:
         for item in sublist:
             key = item.GetKey()
             key = item.GetKey()
-            if self.children.has_key(key):
+            if key in self.children:
                 child = self.children[key]
                 child = self.children[key]
             else:
             else:
                 child = TreeNode(self.canvas, self, item, self.menuList)
                 child = TreeNode(self.canvas, self, item, self.menuList)
@@ -309,7 +315,7 @@ class TreeNode:
     def edit(self, event=None):
     def edit(self, event=None):
         self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
         self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
         self.entry.insert(0, self.label['text'])
         self.entry.insert(0, self.label['text'])
-        self.entry.selection_range(0, Tkinter.END)
+        self.entry.selection_range(0, tkinter.END)
         self.entry.pack(ipadx=5)
         self.entry.pack(ipadx=5)
         self.entry.focus_set()
         self.entry.focus_set()
         self.entry.bind("<Return>", self.edit_finish)
         self.entry.bind("<Return>", self.edit_finish)
@@ -344,7 +350,7 @@ class TreeNode:
         for item in sublist:
         for item in sublist:
             key = item.GetKey()
             key = item.GetKey()
             # Use existing child or create new TreeNode if none exists
             # Use existing child or create new TreeNode if none exists
-            if self.children.has_key(key):
+            if key in self.children:
                 child = self.children[key]
                 child = self.children[key]
             else:
             else:
                 child = TreeNode(self.canvas, self, item, self.menuList)
                 child = TreeNode(self.canvas, self, item, self.menuList)

+ 1 - 1
direct/src/dcparser/dcArrayParameter.h

@@ -23,7 +23,7 @@
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * fields, all of which are of the same type.
  * fields, all of which are of the same type.
  */
  */
-class DCArrayParameter : public DCParameter {
+class EXPCL_DIRECT_DCPARSER DCArrayParameter : public DCParameter {
 public:
 public:
   DCArrayParameter(DCParameter *element_type,
   DCArrayParameter(DCParameter *element_type,
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());

+ 1 - 1
direct/src/dcparser/dcAtomicField.h

@@ -27,7 +27,7 @@
  * This defines an interface to the Distributed Class, and is always
  * This defines an interface to the Distributed Class, and is always
  * implemented as a remote procedure method.
  * implemented as a remote procedure method.
  */
  */
-class DCAtomicField : public DCField {
+class EXPCL_DIRECT_DCPARSER DCAtomicField : public DCField {
 public:
 public:
   DCAtomicField(const std::string &name, DCClass *dclass, bool bogus_field);
   DCAtomicField(const std::string &name, DCClass *dclass, bool bogus_field);
   virtual ~DCAtomicField();
   virtual ~DCAtomicField();

+ 1 - 1
direct/src/dcparser/dcClass.h

@@ -41,7 +41,7 @@ class DCParameter;
 /**
 /**
  * Defines a particular DistributedClass as read from an input .dc file.
  * Defines a particular DistributedClass as read from an input .dc file.
  */
  */
-class DCClass : public DCDeclaration {
+class EXPCL_DIRECT_DCPARSER DCClass : public DCDeclaration {
 public:
 public:
   DCClass(DCFile *dc_file, const std::string &name,
   DCClass(DCFile *dc_file, const std::string &name,
           bool is_struct, bool bogus_class);
           bool is_struct, bool bogus_class);

+ 1 - 1
direct/src/dcparser/dcClassParameter.h

@@ -23,7 +23,7 @@ class DCClass;
  * This represents a class (or struct) object used as a parameter itself.
  * This represents a class (or struct) object used as a parameter itself.
  * This means that all the fields of the class get packed into the message.
  * This means that all the fields of the class get packed into the message.
  */
  */
-class DCClassParameter : public DCParameter {
+class EXPCL_DIRECT_DCPARSER DCClassParameter : public DCParameter {
 public:
 public:
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClassParameter &copy);
   DCClassParameter(const DCClassParameter &copy);

+ 1 - 1
direct/src/dcparser/dcDeclaration.h

@@ -26,7 +26,7 @@ class DCSwitch;
  * only purpose is so that classes and typedefs can be stored in one list
  * only purpose is so that classes and typedefs can be stored in one list
  * together so they can be ordered correctly on output.
  * together so they can be ordered correctly on output.
  */
  */
-class DCDeclaration {
+class EXPCL_DIRECT_DCPARSER DCDeclaration {
 public:
 public:
   virtual ~DCDeclaration();
   virtual ~DCDeclaration();
 
 

+ 1 - 1
direct/src/dcparser/dcField.h

@@ -34,7 +34,7 @@ class HashGenerator;
 /**
 /**
  * A single field of a Distributed Class, either atomic or molecular.
  * A single field of a Distributed Class, either atomic or molecular.
  */
  */
-class DCField : public DCPackerInterface, public DCKeywordList {
+class EXPCL_DIRECT_DCPARSER DCField : public DCPackerInterface, public DCKeywordList {
 public:
 public:
   DCField();
   DCField();
   DCField(const std::string &name, DCClass *dclass);
   DCField(const std::string &name, DCClass *dclass);

+ 1 - 1
direct/src/dcparser/dcFile.h

@@ -29,7 +29,7 @@ class DCDeclaration;
  * Represents the complete list of Distributed Class descriptions as read from
  * Represents the complete list of Distributed Class descriptions as read from
  * a .dc file.
  * a .dc file.
  */
  */
-class DCFile {
+class EXPCL_DIRECT_DCPARSER DCFile {
 PUBLISHED:
 PUBLISHED:
   DCFile();
   DCFile();
   ~DCFile();
   ~DCFile();

+ 1 - 1
direct/src/dcparser/dcKeyword.h

@@ -25,7 +25,7 @@ class HashGenerator;
  * define a communication property associated with a field, for instance
  * define a communication property associated with a field, for instance
  * "broadcast" or "airecv".
  * "broadcast" or "airecv".
  */
  */
-class DCKeyword : public DCDeclaration {
+class EXPCL_DIRECT_DCPARSER DCKeyword : public DCDeclaration {
 public:
 public:
   DCKeyword(const std::string &name, int historical_flag = ~0);
   DCKeyword(const std::string &name, int historical_flag = ~0);
   virtual ~DCKeyword();
   virtual ~DCKeyword();

+ 1 - 1
direct/src/dcparser/dcKeywordList.h

@@ -23,7 +23,7 @@ class HashGenerator;
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * field.
  * field.
  */
  */
-class DCKeywordList {
+class EXPCL_DIRECT_DCPARSER DCKeywordList {
 public:
 public:
   DCKeywordList();
   DCKeywordList();
   DCKeywordList(const DCKeywordList &copy);
   DCKeywordList(const DCKeywordList &copy);

+ 1 - 1
direct/src/dcparser/dcMolecularField.h

@@ -25,7 +25,7 @@ class DCParameter;
  * This represents a combination of two or more related atomic fields, that
  * This represents a combination of two or more related atomic fields, that
  * will often be treated as a unit.
  * will often be treated as a unit.
  */
  */
-class DCMolecularField : public DCField {
+class EXPCL_DIRECT_DCPARSER DCMolecularField : public DCField {
 public:
 public:
   DCMolecularField(const std::string &name, DCClass *dclass);
   DCMolecularField(const std::string &name, DCClass *dclass);
 
 

+ 5 - 5
direct/src/dcparser/dcNumericRange.I

@@ -52,7 +52,7 @@ operator = (const DCNumericRange<NUM> &copy) {
  * otherwise.
  * otherwise.
  */
  */
 template <class NUM>
 template <class NUM>
-bool DCNumericRange<NUM>::
+INLINE bool DCNumericRange<NUM>::
 is_in_range(Number num) const {
 is_in_range(Number num) const {
   if (_ranges.empty()) {
   if (_ranges.empty()) {
     return true;
     return true;
@@ -106,7 +106,7 @@ get_one_value() const {
  *
  *
  */
  */
 template <class NUM>
 template <class NUM>
-void DCNumericRange<NUM>::
+INLINE void DCNumericRange<NUM>::
 generate_hash(HashGenerator &hashgen) const {
 generate_hash(HashGenerator &hashgen) const {
   if (!_ranges.empty()) {
   if (!_ranges.empty()) {
     hashgen.add_int(_ranges.size());
     hashgen.add_int(_ranges.size());
@@ -124,7 +124,7 @@ generate_hash(HashGenerator &hashgen) const {
  *
  *
  */
  */
 template <class NUM>
 template <class NUM>
-void DCNumericRange<NUM>::
+INLINE void DCNumericRange<NUM>::
 output(std::ostream &out, Number divisor) const {
 output(std::ostream &out, Number divisor) const {
   if (!_ranges.empty()) {
   if (!_ranges.empty()) {
     typename Ranges::const_iterator ri;
     typename Ranges::const_iterator ri;
@@ -144,7 +144,7 @@ output(std::ostream &out, Number divisor) const {
  * characters.
  * characters.
  */
  */
 template <class NUM>
 template <class NUM>
-void DCNumericRange<NUM>::
+INLINE void DCNumericRange<NUM>::
 output_char(std::ostream &out, Number divisor) const {
 output_char(std::ostream &out, Number divisor) const {
   if (divisor != 1) {
   if (divisor != 1) {
     output(out, divisor);
     output(out, divisor);
@@ -179,7 +179,7 @@ clear() {
  * minmax overlaps an existing minmax.
  * minmax overlaps an existing minmax.
  */
  */
 template <class NUM>
 template <class NUM>
-bool DCNumericRange<NUM>::
+INLINE bool DCNumericRange<NUM>::
 add_range(Number min, Number max) {
 add_range(Number min, Number max) {
   // Check for an overlap.  This is probably indicative of a typo and should
   // Check for an overlap.  This is probably indicative of a typo and should
   // be reported.
   // be reported.

+ 6 - 6
direct/src/dcparser/dcNumericRange.h

@@ -23,7 +23,7 @@
  * to constrain simple numeric types, as well as array sizes.
  * to constrain simple numeric types, as well as array sizes.
  */
  */
 template <class NUM>
 template <class NUM>
-class DCNumericRange {
+class EXPCL_DIRECT_DCPARSER DCNumericRange {
 public:
 public:
   typedef NUM Number;
   typedef NUM Number;
 
 
@@ -32,20 +32,20 @@ public:
   INLINE DCNumericRange(const DCNumericRange &copy);
   INLINE DCNumericRange(const DCNumericRange &copy);
   INLINE void operator = (const DCNumericRange &copy);
   INLINE void operator = (const DCNumericRange &copy);
 
 
-  bool is_in_range(Number num) const;
+  INLINE bool is_in_range(Number num) const;
   INLINE void validate(Number num, bool &range_error) const;
   INLINE void validate(Number num, bool &range_error) const;
 
 
   INLINE bool has_one_value() const;
   INLINE bool has_one_value() const;
   INLINE Number get_one_value() const;
   INLINE Number get_one_value() const;
 
 
-  void generate_hash(HashGenerator &hashgen) const;
+  INLINE void generate_hash(HashGenerator &hashgen) const;
 
 
-  void output(std::ostream &out, Number divisor = 1) const;
-  void output_char(std::ostream &out, Number divisor = 1) const;
+  INLINE void output(std::ostream &out, Number divisor = 1) const;
+  INLINE void output_char(std::ostream &out, Number divisor = 1) const;
 
 
 public:
 public:
   INLINE void clear();
   INLINE void clear();
-  bool add_range(Number min, Number max);
+  INLINE bool add_range(Number min, Number max);
 
 
   INLINE bool is_empty() const;
   INLINE bool is_empty() const;
   INLINE int get_num_ranges() const;
   INLINE int get_num_ranges() const;

+ 1 - 1
direct/src/dcparser/dcPackData.h

@@ -19,7 +19,7 @@
 /**
 /**
  * This is a block of data that receives the results of DCPacker.
  * This is a block of data that receives the results of DCPacker.
  */
  */
-class DCPackData {
+class EXPCL_DIRECT_DCPARSER DCPackData {
 PUBLISHED:
 PUBLISHED:
   INLINE DCPackData();
   INLINE DCPackData();
   INLINE ~DCPackData();
   INLINE ~DCPackData();

+ 1 - 1
direct/src/dcparser/dcPacker.h

@@ -31,7 +31,7 @@ class DCSwitchParameter;
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * examples of using this class.
  * examples of using this class.
  */
  */
-class DCPacker {
+class EXPCL_DIRECT_DCPARSER DCPacker {
 PUBLISHED:
 PUBLISHED:
   DCPacker();
   DCPacker();
   ~DCPacker();
   ~DCPacker();

+ 1 - 1
direct/src/dcparser/dcPackerCatalog.h

@@ -26,7 +26,7 @@ class DCSwitchParameter;
  * requested from a particular field; its ownership is retained by the field
  * requested from a particular field; its ownership is retained by the field
  * so it must not be deleted.
  * so it must not be deleted.
  */
  */
-class DCPackerCatalog {
+class EXPCL_DIRECT_DCPARSER DCPackerCatalog {
 private:
 private:
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerCatalog &copy);
   DCPackerCatalog(const DCPackerCatalog &copy);

+ 1 - 1
direct/src/dcparser/dcPackerInterface.h

@@ -64,7 +64,7 @@ END_PUBLISH
  * Normally these methods are called only by the DCPacker object; the user
  * Normally these methods are called only by the DCPacker object; the user
  * wouldn't normally call these directly.
  * wouldn't normally call these directly.
  */
  */
-class DCPackerInterface {
+class EXPCL_DIRECT_DCPARSER DCPackerInterface {
 public:
 public:
   DCPackerInterface(const std::string &name = std::string());
   DCPackerInterface(const std::string &name = std::string());
   DCPackerInterface(const DCPackerInterface &copy);
   DCPackerInterface(const DCPackerInterface &copy);

+ 1 - 1
direct/src/dcparser/dcParameter.h

@@ -32,7 +32,7 @@ class HashGenerator;
  * This may also be a typedef reference to another type, which has the same
  * This may also be a typedef reference to another type, which has the same
  * properties as the referenced type, but a different name.
  * properties as the referenced type, but a different name.
  */
  */
-class DCParameter : public DCField {
+class EXPCL_DIRECT_DCPARSER DCParameter : public DCField {
 protected:
 protected:
   DCParameter();
   DCParameter();
   DCParameter(const DCParameter &copy);
   DCParameter(const DCParameter &copy);

+ 1 - 1
direct/src/dcparser/dcParserDefs.h

@@ -43,7 +43,7 @@ extern DCFile *dc_file;
 // that has member functions in a union), so we'll use a class instead.  That
 // that has member functions in a union), so we'll use a class instead.  That
 // means we need to declare it externally, here.
 // means we need to declare it externally, here.
 
 
-class DCTokenType {
+class EXPCL_DIRECT_DCPARSER DCTokenType {
 public:
 public:
   union U {
   union U {
     int s_int;
     int s_int;

+ 1 - 1
direct/src/dcparser/dcSimpleParameter.h

@@ -25,7 +25,7 @@
  * divisor, which is meaningful only for the numeric type elements (and
  * divisor, which is meaningful only for the numeric type elements (and
  * represents a fixed-point numeric convention).
  * represents a fixed-point numeric convention).
  */
  */
-class DCSimpleParameter : public DCParameter {
+class EXPCL_DIRECT_DCPARSER DCSimpleParameter : public DCParameter {
 public:
 public:
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(const DCSimpleParameter &copy);
   DCSimpleParameter(const DCSimpleParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSwitch.h

@@ -27,7 +27,7 @@ class DCField;
  * and represents two or more alternative unpacking schemes based on the first
  * and represents two or more alternative unpacking schemes based on the first
  * field read.
  * field read.
  */
  */
-class DCSwitch : public DCDeclaration {
+class EXPCL_DIRECT_DCPARSER DCSwitch : public DCDeclaration {
 public:
 public:
   DCSwitch(const std::string &name, DCField *key_parameter);
   DCSwitch(const std::string &name, DCField *key_parameter);
   virtual ~DCSwitch();
   virtual ~DCSwitch();

+ 1 - 1
direct/src/dcparser/dcSwitchParameter.h

@@ -23,7 +23,7 @@ class DCSwitch;
  * This represents a switch object used as a parameter itself, which packs the
  * This represents a switch object used as a parameter itself, which packs the
  * appropriate fields of the switch into the message.
  * appropriate fields of the switch into the message.
  */
  */
-class DCSwitchParameter : public DCParameter {
+class EXPCL_DIRECT_DCPARSER DCSwitchParameter : public DCParameter {
 public:
 public:
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitchParameter &copy);
   DCSwitchParameter(const DCSwitchParameter &copy);

+ 1 - 1
direct/src/dcparser/dcTypedef.h

@@ -23,7 +23,7 @@ class DCParameter;
  * This represents a single typedef declaration in the dc file.  It assigns a
  * This represents a single typedef declaration in the dc file.  It assigns a
  * particular type to a new name, just like a C typedef.
  * particular type to a new name, just like a C typedef.
  */
  */
-class DCTypedef : public DCDeclaration {
+class EXPCL_DIRECT_DCPARSER DCTypedef : public DCDeclaration {
 public:
 public:
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(const std::string &name);
   DCTypedef(const std::string &name);

+ 5 - 0
direct/src/dcparser/dcbase.h

@@ -70,6 +70,11 @@
 #define END_PUBLISH
 #define END_PUBLISH
 #define BLOCKING
 #define BLOCKING
 
 
+// These control the declspec(dllexport/dllimport) on Windows.  When compiling
+// outside of Panda, we assume we aren't part of a DLL.
+#define EXPCL_DIRECT_DCPARSER
+#define EXPTP_DIRECT_DCPARSER
+
 // Panda defines some assert-type macros.  We map those to the standard assert
 // Panda defines some assert-type macros.  We map those to the standard assert
 // macro outside of Panda.
 // macro outside of Panda.
 #define nassertr(condition, return_value) assert(condition)
 #define nassertr(condition, return_value) assert(condition)

+ 1 - 1
direct/src/dcparser/hashGenerator.h

@@ -20,7 +20,7 @@
 /**
 /**
  * This class generates an arbitrary hash number from a sequence of ints.
  * This class generates an arbitrary hash number from a sequence of ints.
  */
  */
-class HashGenerator {
+class EXPCL_DIRECT_DCPARSER HashGenerator {
 public:
 public:
   HashGenerator();
   HashGenerator();
 
 

+ 1 - 1
direct/src/dcparser/primeNumberGenerator.h

@@ -30,7 +30,7 @@ typedef std::vector<int> vector_int;
  * For a given integer n, it will return the nth prime number.  This will
  * For a given integer n, it will return the nth prime number.  This will
  * involve a recompute step only if n is greater than any previous n.
  * involve a recompute step only if n is greater than any previous n.
  */
  */
-class PrimeNumberGenerator {
+class EXPCL_DIRECT_DCPARSER PrimeNumberGenerator {
 public:
 public:
   PrimeNumberGenerator();
   PrimeNumberGenerator();
 
 

+ 1 - 1
direct/src/deadrec/config_deadrec.cxx

@@ -15,7 +15,7 @@
 
 
 #include "dconfig.h"
 #include "dconfig.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_DEADREC)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DIRECT_DEADREC)
   #error Buildsystem error: BUILDING_DIRECT_DEADREC not defined
   #error Buildsystem error: BUILDING_DIRECT_DEADREC not defined
 #endif
 #endif
 
 

+ 9 - 0
direct/src/directbase/directsymbols.h

@@ -18,6 +18,7 @@
 
 
 /* BUILDING_DIRECT is just a buildsystem shortcut for all of these: */
 /* BUILDING_DIRECT is just a buildsystem shortcut for all of these: */
 #ifdef BUILDING_DIRECT
 #ifdef BUILDING_DIRECT
+  #define BUILDING_DIRECT_DCPARSER
   #define BUILDING_DIRECT_DEADREC
   #define BUILDING_DIRECT_DEADREC
   #define BUILDING_DIRECT_DIRECTD
   #define BUILDING_DIRECT_DIRECTD
   #define BUILDING_DIRECT_INTERVAL
   #define BUILDING_DIRECT_INTERVAL
@@ -26,6 +27,14 @@
   #define BUILDING_DIRECT_DISTRIBUTED
   #define BUILDING_DIRECT_DISTRIBUTED
 #endif
 #endif
 
 
+#ifdef BUILDING_DIRECT_DCPARSER
+  #define EXPCL_DIRECT_DCPARSER EXPORT_CLASS
+  #define EXPTP_DIRECT_DCPARSER EXPORT_TEMPL
+#else
+  #define EXPCL_DIRECT_DCPARSER IMPORT_CLASS
+  #define EXPTP_DIRECT_DCPARSER IMPORT_TEMPL
+#endif
+
 #ifdef BUILDING_DIRECT_DEADREC
 #ifdef BUILDING_DIRECT_DEADREC
   #define EXPCL_DIRECT_DEADREC EXPORT_CLASS
   #define EXPCL_DIRECT_DEADREC EXPORT_CLASS
   #define EXPTP_DIRECT_DEADREC EXPORT_TEMPL
   #define EXPTP_DIRECT_DEADREC EXPORT_TEMPL

+ 1 - 1
direct/src/directd/directd.cxx

@@ -30,7 +30,7 @@
 
 
 #include "pset.h"
 #include "pset.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_DIRECTD)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DIRECT_DIRECTD)
   #error Buildsystem error: BUILDING_DIRECT_DIRECTD not defined
   #error Buildsystem error: BUILDING_DIRECT_DIRECTD not defined
 #endif
 #endif
 
 

+ 2 - 2
direct/src/distributed/PyDatagram.py

@@ -25,8 +25,8 @@ class PyDatagram(Datagram):
         STUint64: (Datagram.addUint64, int),
         STUint64: (Datagram.addUint64, int),
         STFloat64: (Datagram.addFloat64, None),
         STFloat64: (Datagram.addFloat64, None),
         STString: (Datagram.addString, None),
         STString: (Datagram.addString, None),
-        STBlob: (Datagram.addString, None),
-        STBlob32: (Datagram.addString32, None),
+        STBlob: (Datagram.addBlob, None),
+        STBlob32: (Datagram.addBlob32, None),
         }
         }
 
 
     #def addChannel(self, channelId):
     #def addChannel(self, channelId):

+ 2 - 2
direct/src/distributed/PyDatagramIterator.py

@@ -23,8 +23,8 @@ class PyDatagramIterator(DatagramIterator):
         STUint64: DatagramIterator.getUint64,
         STUint64: DatagramIterator.getUint64,
         STFloat64: DatagramIterator.getFloat64,
         STFloat64: DatagramIterator.getFloat64,
         STString: DatagramIterator.getString,
         STString: DatagramIterator.getString,
-        STBlob: DatagramIterator.getString,
-        STBlob32: DatagramIterator.getString32,
+        STBlob: DatagramIterator.getBlob,
+        STBlob32: DatagramIterator.getBlob32,
         }
         }
 
 
     getChannel = DatagramIterator.getUint64
     getChannel = DatagramIterator.getUint64

+ 1 - 1
direct/src/distributed/config_distributed.cxx

@@ -14,7 +14,7 @@
 #include "config_distributed.h"
 #include "config_distributed.h"
 #include "dconfig.h"
 #include "dconfig.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_DISTRIBUTED)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DIRECT_DISTRIBUTED)
   #error Buildsystem error: BUILDING_DIRECT_DISTRIBUTED not defined
   #error Buildsystem error: BUILDING_DIRECT_DISTRIBUTED not defined
 #endif
 #endif
 
 

+ 24 - 3
direct/src/gui/DirectFrame.py

@@ -61,7 +61,14 @@ class DirectFrame(DirectGuiWidget):
     def destroy(self):
     def destroy(self):
         DirectGuiWidget.destroy(self)
         DirectGuiWidget.destroy(self)
 
 
-    def setText(self):
+    def clearText(self):
+        self['text'] = None
+        self.setText()
+
+    def setText(self, text=None):
+        if text is not None:
+            self['text'] = text
+
         # Determine if user passed in single string or a sequence
         # Determine if user passed in single string or a sequence
         if self['text'] == None:
         if self['text'] == None:
             textList = (None,) * self['numStates']
             textList = (None,) * self['numStates']
@@ -100,7 +107,14 @@ class DirectFrame(DirectGuiWidget):
                         sort = DGG.TEXT_SORT_INDEX,
                         sort = DGG.TEXT_SORT_INDEX,
                         )
                         )
 
 
-    def setGeom(self):
+    def clearGeom(self):
+        self['geom'] = None
+        self.setGeom()
+
+    def setGeom(self, geom=None):
+        if geom is not None:
+            self['geom'] = geom
+
         # Determine argument type
         # Determine argument type
         geom = self['geom']
         geom = self['geom']
 
 
@@ -142,7 +156,14 @@ class DirectFrame(DirectGuiWidget):
                         geom = geom, scale = 1,
                         geom = geom, scale = 1,
                         sort = DGG.GEOM_SORT_INDEX)
                         sort = DGG.GEOM_SORT_INDEX)
 
 
-    def setImage(self):
+    def clearImage(self):
+        self['image'] = None
+        self.setImage()
+
+    def setImage(self, image=None):
+        if image is not None:
+            self['image'] = image
+
         # Determine argument type
         # Determine argument type
         arg = self['image']
         arg = self['image']
         if arg == None:
         if arg == None:

+ 2 - 2
direct/src/interval/cMetaInterval.cxx

@@ -679,7 +679,7 @@ write(std::ostream &out, int indent_level) const {
   int total_digits = num_decimals + 4;
   int total_digits = num_decimals + 4;
   static const int max_digits = 32;  // totally arbitrary
   static const int max_digits = 32;  // totally arbitrary
   nassertv(total_digits <= max_digits);
   nassertv(total_digits <= max_digits);
-  char format_str[12];
+  char format_str[16];
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
 
   indent(out, indent_level) << get_name() << ":\n";
   indent(out, indent_level) << get_name() << ":\n";
@@ -708,7 +708,7 @@ timeline(std::ostream &out) const {
   int total_digits = num_decimals + 4;
   int total_digits = num_decimals + 4;
   static const int max_digits = 32;  // totally arbitrary
   static const int max_digits = 32;  // totally arbitrary
   nassertv(total_digits <= max_digits);
   nassertv(total_digits <= max_digits);
-  char format_str[12];
+  char format_str[16];
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
 
   int extra_indent_level = 0;
   int extra_indent_level = 0;

+ 1 - 1
direct/src/interval/config_interval.cxx

@@ -29,7 +29,7 @@
 
 
 #include "dconfig.h"
 #include "dconfig.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_INTERVAL)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DIRECT_INTERVAL)
   #error Buildsystem error: BUILDING_DIRECT_INTERVAL not defined
   #error Buildsystem error: BUILDING_DIRECT_INTERVAL not defined
 #endif
 #endif
 
 

+ 1 - 0
direct/src/leveleditor/ProtoPalette.py

@@ -3,6 +3,7 @@ Palette for Prototyping
 """
 """
 
 
 from .ProtoPaletteBase import *
 from .ProtoPaletteBase import *
+import os
 
 
 class ProtoPalette(ProtoPaletteBase):
 class ProtoPalette(ProtoPaletteBase):
     def __init__(self):
     def __init__(self):

+ 1 - 1
direct/src/motiontrail/config_motiontrail.cxx

@@ -14,7 +14,7 @@
 #include "config_motiontrail.h"
 #include "config_motiontrail.h"
 #include "dconfig.h"
 #include "dconfig.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_MOTIONTRAIL)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DIRECT_MOTIONTRAIL)
   #error Buildsystem error: BUILDING_DIRECT_MOTIONTRAIL not defined
   #error Buildsystem error: BUILDING_DIRECT_MOTIONTRAIL not defined
 #endif
 #endif
 
 

+ 2 - 2
direct/src/showbase/Loader.py

@@ -934,8 +934,8 @@ class Loader(DirectObject):
         just as in loadModel(); otherwise, the loading happens before
         just as in loadModel(); otherwise, the loading happens before
         loadSound() returns."""
         loadSound() returns."""
 
 
-        if not isinstance(soundPath, (MovieAudio, tuple, list, set)):
-            # We were given a single sound pathname.
+        if not isinstance(soundPath, (tuple, list, set)):
+            # We were given a single sound pathname or a MovieAudio instance.
             soundList = [soundPath]
             soundList = [soundPath]
             gotList = False
             gotList = False
         else:
         else:

+ 20 - 12
direct/src/showbase/Transitions.py

@@ -89,7 +89,7 @@ class Transitions:
             self.fade.setBin('unsorted', 0)
             self.fade.setBin('unsorted', 0)
             self.fade.setColor(0,0,0,0)
             self.fade.setColor(0,0,0,0)
 
 
-    def getFadeInIval(self, t=0.5, finishIval=None):
+    def getFadeInIval(self, t=0.5, finishIval=None, blendType='noBlend'):
         """
         """
         Returns an interval without starting it.  This is particularly useful in
         Returns an interval without starting it.  This is particularly useful in
         cutscenes, so when the cutsceneIval is escaped out of we can finish the fade immediately
         cutscenes, so when the cutsceneIval is escaped out of we can finish the fade immediately
@@ -103,6 +103,7 @@ class Transitions:
                                   self.lerpFunc(self.fade, t,
                                   self.lerpFunc(self.fade, t,
                                                 self.alphaOff,
                                                 self.alphaOff,
                                                 # self.alphaOn,
                                                 # self.alphaOn,
+                                                blendType=blendType
                                                 ),
                                                 ),
                                   Func(self.fade.detachNode),
                                   Func(self.fade.detachNode),
                                   name = self.fadeTaskName,
                                   name = self.fadeTaskName,
@@ -111,7 +112,7 @@ class Transitions:
             transitionIval.append(finishIval)
             transitionIval.append(finishIval)
         return transitionIval
         return transitionIval
 
 
-    def getFadeOutIval(self, t=0.5, finishIval=None):
+    def getFadeOutIval(self, t=0.5, finishIval=None, blendType='noBlend'):
         """
         """
         Create a sequence that lerps the color out, then
         Create a sequence that lerps the color out, then
         parents the fade to hidden
         parents the fade to hidden
@@ -125,6 +126,7 @@ class Transitions:
                                   self.lerpFunc(self.fade, t,
                                   self.lerpFunc(self.fade, t,
                                                 self.alphaOn,
                                                 self.alphaOn,
                                                 # self.alphaOff,
                                                 # self.alphaOff,
+                                                blendType=blendType
                                                 ),
                                                 ),
                                   name = self.fadeTaskName,
                                   name = self.fadeTaskName,
                                   )
                                   )
@@ -132,7 +134,7 @@ class Transitions:
             transitionIval.append(finishIval)
             transitionIval.append(finishIval)
         return transitionIval
         return transitionIval
 
 
-    def fadeIn(self, t=0.5, finishIval=None):
+    def fadeIn(self, t=0.5, finishIval=None, blendType='noBlend'):
         """
         """
         Play a fade in transition over t seconds.
         Play a fade in transition over t seconds.
         Places a polygon on the aspect2d plane then lerps the color
         Places a polygon on the aspect2d plane then lerps the color
@@ -159,13 +161,13 @@ class Transitions:
         else:
         else:
             # Create a sequence that lerps the color out, then
             # Create a sequence that lerps the color out, then
             # parents the fade to hidden
             # parents the fade to hidden
-            self.transitionIval = self.getFadeInIval(t, finishIval)
+            self.transitionIval = self.getFadeInIval(t, finishIval, blendType)
             self.transitionIval.append(Func(self.__finishTransition))
             self.transitionIval.append(Func(self.__finishTransition))
             self.__transitionFuture = AsyncFuture()
             self.__transitionFuture = AsyncFuture()
             self.transitionIval.start()
             self.transitionIval.start()
             return self.__transitionFuture
             return self.__transitionFuture
 
 
-    def fadeOut(self, t=0.5, finishIval=None):
+    def fadeOut(self, t=0.5, finishIval=None, blendType='noBlend'):
         """
         """
         Play a fade out transition over t seconds.
         Play a fade out transition over t seconds.
         Places a polygon on the aspect2d plane then lerps the color
         Places a polygon on the aspect2d plane then lerps the color
@@ -189,7 +191,7 @@ class Transitions:
         else:
         else:
             # Create a sequence that lerps the color out, then
             # Create a sequence that lerps the color out, then
             # parents the fade to hidden
             # parents the fade to hidden
-            self.transitionIval = self.getFadeOutIval(t, finishIval)
+            self.transitionIval = self.getFadeOutIval(t, finishIval, blendType)
             self.transitionIval.append(Func(self.__finishTransition))
             self.transitionIval.append(Func(self.__finishTransition))
             self.__transitionFuture = AsyncFuture()
             self.__transitionFuture = AsyncFuture()
             self.transitionIval.start()
             self.transitionIval.start()
@@ -264,7 +266,7 @@ class Transitions:
             self.iris = loader.loadModel(self.IrisModelName)
             self.iris = loader.loadModel(self.IrisModelName)
             self.iris.setPos(0, 0, 0)
             self.iris.setPos(0, 0, 0)
 
 
-    def irisIn(self, t=0.5, finishIval=None):
+    def irisIn(self, t=0.5, finishIval=None, blendType = 'noBlend'):
         """
         """
         Play an iris in transition over t seconds.
         Play an iris in transition over t seconds.
         Places a polygon on the aspect2d plane then lerps the scale
         Places a polygon on the aspect2d plane then lerps the scale
@@ -284,7 +286,8 @@ class Transitions:
             scale = 0.18 * max(base.a2dRight, base.a2dTop)
             scale = 0.18 * max(base.a2dRight, base.a2dTop)
             self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
             self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
                                                    scale = scale,
                                                    scale = scale,
-                                                   startScale = 0.01),
+                                                   startScale = 0.01,
+                                                   blendType=blendType),
                                  Func(self.iris.detachNode),
                                  Func(self.iris.detachNode),
                                  Func(self.__finishTransition),
                                  Func(self.__finishTransition),
                                  name = self.irisTaskName,
                                  name = self.irisTaskName,
@@ -295,7 +298,7 @@ class Transitions:
             self.transitionIval.start()
             self.transitionIval.start()
             return self.__transitionFuture
             return self.__transitionFuture
 
 
-    def irisOut(self, t=0.5, finishIval=None):
+    def irisOut(self, t=0.5, finishIval=None, blendType='noBlend'):
         """
         """
         Play an iris out transition over t seconds.
         Play an iris out transition over t seconds.
         Places a polygon on the aspect2d plane then lerps the scale
         Places a polygon on the aspect2d plane then lerps the scale
@@ -318,7 +321,8 @@ class Transitions:
             scale = 0.18 * max(base.a2dRight, base.a2dTop)
             scale = 0.18 * max(base.a2dRight, base.a2dTop)
             self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
             self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
                                                    scale = 0.01,
                                                    scale = 0.01,
-                                                   startScale = scale),
+                                                   startScale = scale,
+                                                   blendType=blendType),
                                  Func(self.iris.detachNode),
                                  Func(self.iris.detachNode),
                                  # Use the fade to cover up the hole that the iris would leave
                                  # Use the fade to cover up the hole that the iris would leave
                                  Func(self.fadeOut, 0),
                                  Func(self.fadeOut, 0),
@@ -441,7 +445,7 @@ class Transitions:
             self.__letterboxFuture.setResult(None)
             self.__letterboxFuture.setResult(None)
             self.__letterboxFuture = None
             self.__letterboxFuture = None
 
 
-    def letterboxOn(self, t=0.25, finishIval=None):
+    def letterboxOn(self, t=0.25, finishIval=None, blendType='noBlend'):
         """
         """
         Move black bars in over t seconds.
         Move black bars in over t seconds.
         """
         """
@@ -461,11 +465,13 @@ class Transitions:
                                 t,
                                 t,
                                 pos = Vec3(0, 0, -1),
                                 pos = Vec3(0, 0, -1),
                                 #startPos = Vec3(0, 0, -1.2),
                                 #startPos = Vec3(0, 0, -1.2),
+                                blendType=blendType
                                 ),
                                 ),
                 LerpPosInterval(self.letterboxTop,
                 LerpPosInterval(self.letterboxTop,
                                 t,
                                 t,
                                 pos = Vec3(0, 0, 0.8),
                                 pos = Vec3(0, 0, 0.8),
                                 # startPos = Vec3(0, 0, 1),
                                 # startPos = Vec3(0, 0, 1),
+                                blendType=blendType
                                 ),
                                 ),
                 ),
                 ),
                                           Func(self.__finishLetterbox),
                                           Func(self.__finishLetterbox),
@@ -476,7 +482,7 @@ class Transitions:
             self.letterboxIval.start()
             self.letterboxIval.start()
             return self.__letterboxFuture
             return self.__letterboxFuture
 
 
-    def letterboxOff(self, t=0.25, finishIval=None):
+    def letterboxOff(self, t=0.25, finishIval=None, blendType='noBlend'):
         """
         """
         Move black bars away over t seconds.
         Move black bars away over t seconds.
         """
         """
@@ -495,11 +501,13 @@ class Transitions:
                                 t,
                                 t,
                                 pos = Vec3(0, 0, -1.2),
                                 pos = Vec3(0, 0, -1.2),
                                 # startPos = Vec3(0, 0, -1),
                                 # startPos = Vec3(0, 0, -1),
+                                blendType=blendType
                                 ),
                                 ),
                 LerpPosInterval(self.letterboxTop,
                 LerpPosInterval(self.letterboxTop,
                                 t,
                                 t,
                                 pos = Vec3(0, 0, 1),
                                 pos = Vec3(0, 0, 1),
                                 # startPos = Vec3(0, 0, 0.8),
                                 # startPos = Vec3(0, 0, 0.8),
+                                blendType=blendType
                                 ),
                                 ),
                 ),
                 ),
                                           Func(self.letterbox.stash),
                                           Func(self.letterbox.stash),

+ 1 - 1
direct/src/showbase/showBase.cxx

@@ -37,7 +37,7 @@ FILTERKEYS g_StartupFilterKeys = {sizeof(FILTERKEYS), 0};
 using std::max;
 using std::max;
 using std::min;
 using std::min;
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_SHOWBASE)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DIRECT_SHOWBASE)
   #error Buildsystem error: BUILDING_DIRECT_SHOWBASE not defined
   #error Buildsystem error: BUILDING_DIRECT_SHOWBASE not defined
 #endif
 #endif
 
 

+ 4 - 0
dtool/src/cppparser/cppFunctionType.cxx

@@ -292,6 +292,10 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
 
 
     out << str;
     out << str;
 
 
+  } else if (_flags & F_operator_typecast) {
+    out << "operator ";
+    _return_type->output_instance(out, indent_level, scope, complete, "", prename + str);
+
   } else {
   } else {
     if (prename.empty()) {
     if (prename.empty()) {
       _return_type->output_instance(out, indent_level, scope, complete,
       _return_type->output_instance(out, indent_level, scope, complete,

+ 1 - 1
dtool/src/dconfig/config_dconfig.cxx

@@ -13,7 +13,7 @@
 
 
 #include "config_dconfig.h"
 #include "config_dconfig.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DTOOL_DCONFIG)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DTOOL_DCONFIG)
   #error Buildsystem error: BUILDING_DTOOL_DCONFIG not defined
   #error Buildsystem error: BUILDING_DTOOL_DCONFIG not defined
 #endif
 #endif
 
 

+ 14 - 14
dtool/src/dtoolbase/atomicAdjust.h

@@ -30,6 +30,20 @@ struct AtomicAdjust {
 #include "atomicAdjustDummyImpl.h"
 #include "atomicAdjustDummyImpl.h"
 typedef AtomicAdjustDummyImpl AtomicAdjust;
 typedef AtomicAdjustDummyImpl AtomicAdjust;
 
 
+#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (defined(__clang__) && (__clang_major__ >= 3))
+// GCC 4.7 and above has built-in __atomic functions for atomic operations.
+// Clang 3.0 and above also supports them.
+
+#include "atomicAdjustGccImpl.h"
+typedef AtomicAdjustGccImpl AtomicAdjust;
+
+#if (__GCC_ATOMIC_INT_LOCK_FREE + __GCC_ATOMIC_LONG_LOCK_FREE) > 0
+#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
+#endif
+#if __GCC_ATOMIC_POINTER_LOCK_FREE > 0
+#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
+#endif
+
 #elif (defined(__i386__) || defined(_M_IX86)) && !defined(__APPLE__)
 #elif (defined(__i386__) || defined(_M_IX86)) && !defined(__APPLE__)
 // For an i386 architecture, we'll always use the i386 implementation.  It
 // For an i386 architecture, we'll always use the i386 implementation.  It
 // should be safe for any OS, and it might be a bit faster than any OS-
 // should be safe for any OS, and it might be a bit faster than any OS-
@@ -45,20 +59,6 @@ typedef AtomicAdjustI386Impl AtomicAdjust;
 #define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
 #define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
 #define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
 #define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
 
 
-#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (defined(__clang__) && (__clang_major__ >= 3))
-// GCC 4.7 and above has built-in __atomic functions for atomic operations.
-// Clang 3.0 and above also supports them.
-
-#include "atomicAdjustGccImpl.h"
-typedef AtomicAdjustGccImpl AtomicAdjust;
-
-#if (__GCC_ATOMIC_INT_LOCK_FREE + __GCC_ATOMIC_INT_LOCK_FREE) > 0
-#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
-#endif
-#if __GCC_ATOMIC_POINTER_LOCK_FREE > 0
-#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
-#endif
-
 #elif defined(THREAD_WIN32_IMPL)
 #elif defined(THREAD_WIN32_IMPL)
 
 
 #include "atomicAdjustWin32Impl.h"
 #include "atomicAdjustWin32Impl.h"

+ 3 - 0
dtool/src/dtoolbase/dtool_platform.h

@@ -63,6 +63,9 @@
 #define DTOOL_PLATFORM "android_i386"
 #define DTOOL_PLATFORM "android_i386"
 #endif
 #endif
 
 
+#elif defined(__aarch64__)
+#define DTOOL_PLATFORM "linux_aarch64"
+
 #elif defined(__x86_64)
 #elif defined(__x86_64)
 #define DTOOL_PLATFORM "linux_amd64"
 #define DTOOL_PLATFORM "linux_amd64"
 
 

+ 1 - 1
dtool/src/dtoolbase/dtoolbase.cxx

@@ -14,7 +14,7 @@
 #include "dtoolbase.h"
 #include "dtoolbase.h"
 #include "memoryHook.h"
 #include "memoryHook.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DTOOL_DTOOLBASE)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DTOOL_DTOOLBASE)
   #error Buildsystem error: BUILDING_DTOOL_DTOOLBASE not defined
   #error Buildsystem error: BUILDING_DTOOL_DTOOLBASE not defined
 #endif
 #endif
 
 

+ 49 - 16
dtool/src/dtoolbase/dtoolbase_cc.h

@@ -49,6 +49,8 @@
 // interrogate pass (CPPPARSER isn't defined), this maps to public.
 // interrogate pass (CPPPARSER isn't defined), this maps to public.
 #define PUBLISHED __published
 #define PUBLISHED __published
 
 
+#define PHAVE_ATOMIC 1
+
 typedef int ios_openmode;
 typedef int ios_openmode;
 typedef int ios_fmtflags;
 typedef int ios_fmtflags;
 typedef int ios_iostate;
 typedef int ios_iostate;
@@ -93,6 +95,23 @@ typedef std::ios::iostate ios_iostate;
 typedef std::ios::seekdir ios_seekdir;
 typedef std::ios::seekdir ios_seekdir;
 #endif
 #endif
 
 
+#ifdef _MSC_VER
+#define ALWAYS_INLINE __forceinline
+#elif defined(__GNUC__)
+#define ALWAYS_INLINE __attribute__((always_inline)) inline
+#else
+#define ALWAYS_INLINE inline
+#endif
+
+#ifdef FORCE_INLINING
+// If FORCE_INLINING is defined, we use the keyword __forceinline, which tells
+// MS VC++ to override its internal benefit heuristic and inline the fn if it
+// is technically possible to do so.
+#define INLINE ALWAYS_INLINE
+#else
+#define INLINE inline
+#endif
+
 // Apple has an outdated libstdc++.  Not all is lost, though, as we can fill
 // Apple has an outdated libstdc++.  Not all is lost, though, as we can fill
 // in some important missing functions.
 // in some important missing functions.
 #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719
 #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719
@@ -115,24 +134,38 @@ namespace std {
   }
   }
 
 
   template<class T> struct owner_less;
   template<class T> struct owner_less;
-};
-#endif
-
-#ifdef _MSC_VER
-#define ALWAYS_INLINE __forceinline
-#elif defined(__GNUC__)
-#define ALWAYS_INLINE __attribute__((always_inline)) inline
-#else
-#define ALWAYS_INLINE inline
-#endif
 
 
-#ifdef FORCE_INLINING
-// If FORCE_INLINING is defined, we use the keyword __forceinline, which tells
-// MS VC++ to override its internal benefit heuristic and inline the fn if it
-// is technically possible to do so.
-#define INLINE ALWAYS_INLINE
+  typedef enum memory_order {
+    memory_order_relaxed,
+    memory_order_consume,
+    memory_order_acquire,
+    memory_order_release,
+    memory_order_acq_rel,
+    memory_order_seq_cst,
+  } memory_order;
+
+  #define ATOMIC_FLAG_INIT { 0 }
+  class atomic_flag {
+    bool _flag;
+
+  public:
+    atomic_flag() noexcept = default;
+    ALWAYS_INLINE constexpr atomic_flag(bool flag) noexcept : _flag(flag) {}
+    atomic_flag(const atomic_flag &) = delete;
+    ~atomic_flag() noexcept = default;
+    atomic_flag &operator = (const atomic_flag&) = delete;
+
+    ALWAYS_INLINE bool test_and_set(memory_order order = memory_order_seq_cst) noexcept {
+      return __atomic_test_and_set(&_flag, order);
+    }
+    ALWAYS_INLINE void clear(memory_order order = memory_order_seq_cst) noexcept {
+      __atomic_clear(&_flag, order);
+    }
+  };
+};
 #else
 #else
-#define INLINE inline
+// Expect that we have access to the <atomic> header.
+#define PHAVE_ATOMIC 1
 #endif
 #endif
 
 
 // Determine the availability of C++11 features.
 // Determine the availability of C++11 features.

+ 2 - 9
dtool/src/dtoolbase/mutexSpinlockImpl.I

@@ -11,13 +11,6 @@
  * @date 2006-04-11
  * @date 2006-04-11
  */
  */
 
 
-/**
- *
- */
-constexpr MutexSpinlockImpl::
-MutexSpinlockImpl() : _lock(0) {
-}
-
 /**
 /**
  *
  *
  */
  */
@@ -33,7 +26,7 @@ lock() {
  */
  */
 INLINE bool MutexSpinlockImpl::
 INLINE bool MutexSpinlockImpl::
 try_lock() {
 try_lock() {
-  return (AtomicAdjust::compare_and_exchange(_lock, 0, 1) == 0);
+  return !_flag.test_and_set(std::memory_order_acquire);
 }
 }
 
 
 /**
 /**
@@ -41,5 +34,5 @@ try_lock() {
  */
  */
 INLINE void MutexSpinlockImpl::
 INLINE void MutexSpinlockImpl::
 unlock() {
 unlock() {
-  AtomicAdjust::set(_lock, 0);
+  _flag.clear(std::memory_order_release);
 }
 }

+ 10 - 1
dtool/src/dtoolbase/mutexSpinlockImpl.cxx

@@ -17,12 +17,21 @@
 
 
 #include "mutexSpinlockImpl.h"
 #include "mutexSpinlockImpl.h"
 
 
+#if defined(__i386__) || defined(__x86_64) || defined(_M_IX86) || defined(_M_X64)
+#include <emmintrin.h>
+#define PAUSE() _mm_pause()
+#else
+#define PAUSE()
+#endif
+
 /**
 /**
  *
  *
  */
  */
 void MutexSpinlockImpl::
 void MutexSpinlockImpl::
 do_lock() {
 do_lock() {
-  while (AtomicAdjust::compare_and_exchange(_lock, 0, 1) != 0) {
+  // Loop until we changed the flag from 0 to 1 (and it wasn't already 1).
+  while (_flag.test_and_set(std::memory_order_acquire)) {
+    PAUSE();
   }
   }
 }
 }
 
 

+ 5 - 3
dtool/src/dtoolbase/mutexSpinlockImpl.h

@@ -19,7 +19,9 @@
 
 
 #ifdef MUTEX_SPINLOCK
 #ifdef MUTEX_SPINLOCK
 
 
-#include "atomicAdjust.h"
+#ifdef PHAVE_ATOMIC
+#include <atomic>
+#endif
 
 
 /**
 /**
  * Uses a simple user-space spinlock to implement a mutex.  It is usually not
  * Uses a simple user-space spinlock to implement a mutex.  It is usually not
@@ -29,7 +31,7 @@
  */
  */
 class EXPCL_DTOOL_DTOOLBASE MutexSpinlockImpl {
 class EXPCL_DTOOL_DTOOLBASE MutexSpinlockImpl {
 public:
 public:
-  constexpr MutexSpinlockImpl();
+  constexpr MutexSpinlockImpl() noexcept = default;
   MutexSpinlockImpl(const MutexSpinlockImpl &copy) = delete;
   MutexSpinlockImpl(const MutexSpinlockImpl &copy) = delete;
 
 
   MutexSpinlockImpl &operator = (const MutexSpinlockImpl &copy) = delete;
   MutexSpinlockImpl &operator = (const MutexSpinlockImpl &copy) = delete;
@@ -42,7 +44,7 @@ public:
 private:
 private:
   void do_lock();
   void do_lock();
 
 
-  TVOLATILE AtomicAdjust::Integer _lock;
+  std::atomic_flag _flag = ATOMIC_FLAG_INIT;
 };
 };
 
 
 #include "mutexSpinlockImpl.I"
 #include "mutexSpinlockImpl.I"

+ 1 - 1
dtool/src/dtoolbase/stl_compares.I

@@ -169,7 +169,7 @@ add_hash(size_t hash, const Key &key) {
 #ifdef _DEBUG
 #ifdef _DEBUG
   // We assume that the sequence is laid out sequentially in memory.
   // We assume that the sequence is laid out sequentially in memory.
   if (key.size() > 0) {
   if (key.size() > 0) {
-    assert(&key[key.size() - 1] - &key[0] == key.size() - 1);
+    assert(&key[key.size() - 1] - &key[0] == (ptrdiff_t)key.size() - 1);
   }
   }
 #endif
 #endif
   size_t num_bytes = (key.size() * sizeof(key[0]));
   size_t num_bytes = (key.size() * sizeof(key[0]));

+ 0 - 3
dtool/src/dtoolbase/typeHandle.cxx

@@ -15,9 +15,6 @@
 #include "typeRegistryNode.h"
 #include "typeRegistryNode.h"
 #include "atomicAdjust.h"
 #include "atomicAdjust.h"
 
 
-// This is initialized to zero by static initialization.
-TypeHandle TypeHandle::_none;
-
 /**
 /**
  * Returns the total allocated memory used by objects of this type, for the
  * Returns the total allocated memory used by objects of this type, for the
  * indicated memory class.  This is only updated if track-memory-usage is set
  * indicated memory class.  This is only updated if track-memory-usage is set

+ 0 - 3
dtool/src/dtoolbase/typeHandle.h

@@ -147,9 +147,6 @@ public:
 private:
 private:
   constexpr TypeHandle(int index);
   constexpr TypeHandle(int index);
 
 
-  // Only kept temporarily for ABI compatibility.
-  static TypeHandle _none;
-
   int _index;
   int _index;
   friend class TypeRegistry;
   friend class TypeRegistry;
 };
 };

+ 1 - 1
dtool/src/dtoolutil/config_dtoolutil.cxx

@@ -16,7 +16,7 @@
 #include "filename.h"
 #include "filename.h"
 #include "pandaSystem.h"
 #include "pandaSystem.h"
 
 
-#if !defined(CPPPARSER) && !defined(BUILDING_DTOOL_DTOOLUTIL)
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DTOOL_DTOOLUTIL)
   #error Buildsystem error: BUILDING_DTOOL_DCTOOLUTIL not defined
   #error Buildsystem error: BUILDING_DTOOL_DCTOOLUTIL not defined
 #endif
 #endif
 
 

+ 0 - 31
dtool/src/dtoolutil/dSearchPath.cxx

@@ -116,13 +116,6 @@ write(ostream &out, int indent_level) const {
   }
   }
 }
 }
 
 
-/**
- * Creates an empty search path.
- */
-DSearchPath::
-DSearchPath() {
-}
-
 /**
 /**
  *
  *
  */
  */
@@ -139,30 +132,6 @@ DSearchPath(const Filename &directory) {
   append_directory(directory);
   append_directory(directory);
 }
 }
 
 
-/**
- *
- */
-DSearchPath::
-DSearchPath(const DSearchPath &copy) :
-  _directories(copy._directories)
-{
-}
-
-/**
- *
- */
-void DSearchPath::
-operator = (const DSearchPath &copy) {
-  _directories = copy._directories;
-}
-
-/**
- *
- */
-DSearchPath::
-~DSearchPath() {
-}
-
 /**
 /**
  * Removes all the directories from the search list.
  * Removes all the directories from the search list.
  */
  */

+ 7 - 4
dtool/src/dtoolutil/dSearchPath.h

@@ -52,12 +52,15 @@ PUBLISHED:
     Files _files;
     Files _files;
   };
   };
 
 
-  DSearchPath();
+  DSearchPath() = default;
   DSearchPath(const std::string &path, const std::string &separator = std::string());
   DSearchPath(const std::string &path, const std::string &separator = std::string());
   DSearchPath(const Filename &directory);
   DSearchPath(const Filename &directory);
-  DSearchPath(const DSearchPath &copy);
-  void operator = (const DSearchPath &copy);
-  ~DSearchPath();
+  DSearchPath(const DSearchPath &copy) = default;
+  DSearchPath(DSearchPath &&from) = default;
+  ~DSearchPath() = default;
+
+  DSearchPath &operator = (const DSearchPath &copy) = default;
+  DSearchPath &operator = (DSearchPath &&from) = default;
 
 
   void clear();
   void clear();
   void append_directory(const Filename &directory);
   void append_directory(const Filename &directory);

+ 1 - 0
dtool/src/dtoolutil/p3dtoolutil_ext_composite.cxx

@@ -1,2 +1,3 @@
 #include "filename_ext.cxx"
 #include "filename_ext.cxx"
 #include "globPattern_ext.cxx"
 #include "globPattern_ext.cxx"
+#include "textEncoder_ext.cxx"

+ 1 - 1
dtool/src/dtoolutil/stringDecoder.I

@@ -53,5 +53,5 @@ StringUtf8Decoder(const std::string &input) : StringDecoder(input) {
  *
  *
  */
  */
 INLINE StringUnicodeDecoder::
 INLINE StringUnicodeDecoder::
-StringUnicodeDecoder(const std::string &input) : StringDecoder(input) {
+StringUtf16Decoder(const std::string &input) : StringDecoder(input) {
 }
 }

+ 69 - 10
dtool/src/dtoolutil/stringDecoder.cxx

@@ -26,7 +26,7 @@ StringDecoder::
 /**
 /**
  * Returns the next character in sequence.
  * Returns the next character in sequence.
  */
  */
-int StringDecoder::
+char32_t StringDecoder::
 get_next_character() {
 get_next_character() {
   if (test_eof()) {
   if (test_eof()) {
     return -1;
     return -1;
@@ -57,19 +57,20 @@ get_notify_ptr() {
 
 
 /*
 /*
 In UTF-8, each 16-bit Unicode character is encoded as a sequence of
 In UTF-8, each 16-bit Unicode character is encoded as a sequence of
-one, two, or three 8-bit bytes, depending on the value of the
+one, two, three or four 8-bit bytes, depending on the value of the
 character. The following table shows the format of such UTF-8 byte
 character. The following table shows the format of such UTF-8 byte
 sequences (where the "free bits" shown by x's in the table are
 sequences (where the "free bits" shown by x's in the table are
 combined in the order shown, and interpreted from most significant to
 combined in the order shown, and interpreted from most significant to
 least significant):
 least significant):
 
 
  Binary format of bytes in sequence:
  Binary format of bytes in sequence:
-                                        Number of    Maximum expressible
- 1st byte     2nd byte    3rd byte      free bits:      Unicode value:
+                                              Number of    Maximum expressible
+ 1st byte    2nd byte   3rd byte   4th byte   free bits:     Unicode value:
 
 
- 0xxxxxxx                                  7           007F hex   (127)
- 110xxxxx     10xxxxxx                  (5+6)=11       07FF hex  (2047)
- 1110xxxx     10xxxxxx    10xxxxxx     (4+6+6)=16      FFFF hex (65535)
+ 0xxxxxxx                                         7          007F hex   (127)
+ 110xxxxx    10xxxxxx                          (5+6)=11      07FF hex  (2047)
+ 1110xxxx    10xxxxxx   10xxxxxx              (4+6+6)=16     FFFF hex (65535)
+ 11110xxx    10xxxxxx   10xxxxxx   10xxxxxx   (4+6*3)=21   10FFFF hex (1114111)
 
 
 The value of each individual byte indicates its UTF-8 function, as follows:
 The value of each individual byte indicates its UTF-8 function, as follows:
 
 
@@ -77,12 +78,13 @@ The value of each individual byte indicates its UTF-8 function, as follows:
  80 to BF hex (128 to 191):  continuing byte in a multi-byte sequence.
  80 to BF hex (128 to 191):  continuing byte in a multi-byte sequence.
  C2 to DF hex (194 to 223):  first byte of a two-byte sequence.
  C2 to DF hex (194 to 223):  first byte of a two-byte sequence.
  E0 to EF hex (224 to 239):  first byte of a three-byte sequence.
  E0 to EF hex (224 to 239):  first byte of a three-byte sequence.
+ F0 to F7 hex (240 to 247):  first byte of a four-byte sequence.
 */
 */
 
 
 /**
 /**
  * Returns the next character in sequence.
  * Returns the next character in sequence.
  */
  */
-int StringUtf8Decoder::
+char32_t StringUtf8Decoder::
 get_next_character() {
 get_next_character() {
   unsigned int result;
   unsigned int result;
   while (!test_eof()) {
   while (!test_eof()) {
@@ -125,6 +127,35 @@ get_next_character() {
       unsigned int three = (unsigned char)_input[_p++];
       unsigned int three = (unsigned char)_input[_p++];
       result = ((result & 0x0f) << 12) | ((two & 0x3f) << 6) | (three & 0x3f);
       result = ((result & 0x0f) << 12) | ((two & 0x3f) << 6) | (three & 0x3f);
       return result;
       return result;
+
+    } else if ((result & 0xf8) == 0xf0) {
+      // First byte of four.
+      if (test_eof()) {
+        if (_notify_ptr != nullptr) {
+          (*_notify_ptr)
+            << "utf-8 encoded string '" << _input << "' ends abruptly.\n";
+        }
+        return -1;
+      }
+      unsigned int two = (unsigned char)_input[_p++];
+      if (test_eof()) {
+        if (_notify_ptr != nullptr) {
+          (*_notify_ptr)
+            << "utf-8 encoded string '" << _input << "' ends abruptly.\n";
+        }
+        return -1;
+      }
+      unsigned int three = (unsigned char)_input[_p++];
+      if (test_eof()) {
+        if (_notify_ptr != nullptr) {
+          (*_notify_ptr)
+            << "utf-8 encoded string '" << _input << "' ends abruptly.\n";
+        }
+        return -1;
+      }
+      unsigned int four = (unsigned char)_input[_p++];
+      result = ((result & 0x07) << 18) | ((two & 0x3f) << 12) | ((three & 0x3f) << 6) | (four & 0x3f);
+      return result;
     }
     }
 
 
     // Otherwise--the high bit is set but it is not one of the introductory
     // Otherwise--the high bit is set but it is not one of the introductory
@@ -144,7 +175,7 @@ get_next_character() {
 /**
 /**
  * Returns the next character in sequence.
  * Returns the next character in sequence.
  */
  */
-int StringUnicodeDecoder::
+char32_t StringUtf16Decoder::
 get_next_character() {
 get_next_character() {
   if (test_eof()) {
   if (test_eof()) {
     return -1;
     return -1;
@@ -159,5 +190,33 @@ get_next_character() {
     return -1;
     return -1;
   }
   }
   unsigned int low = (unsigned char)_input[_p++];
   unsigned int low = (unsigned char)_input[_p++];
-  return ((high << 8) | low);
+  int ch = ((high << 8) | low);
+
+  /*
+  using std::swap;
+
+  if (ch == 0xfffe) {
+    // This is a byte-swapped byte-order-marker.  That means we need to swap
+    // the endianness of the rest of the stream.
+    char *data = (char *)_input.data();
+    for (size_t p = _p; p < _input.size() - 1; p += 2) {
+      std::swap(data[p], data[p + 1]);
+    }
+    ch = 0xfeff;
+  }
+  */
+
+  if (ch >= 0xd800 && ch < 0xdc00 && (_p + 1) < _input.size()) {
+    // This is a high surrogate.  Look for a subsequent low surrogate.
+    unsigned int high = (unsigned char)_input[_p];
+    unsigned int low = (unsigned char)_input[_p + 1];
+    int ch2 = ((high << 8) | low);
+    if (ch2 >= 0xdc00 && ch2 < 0xe000) {
+      // Yes, this is a low surrogate.
+      _p += 2;
+      return 0x10000 + ((ch - 0xd800) << 10) + (ch2 - 0xdc00);
+    }
+  }
+  // No, this is just a regular character, or an unpaired surrogate.
+  return ch;
 }
 }

+ 9 - 6
dtool/src/dtoolutil/stringDecoder.h

@@ -26,7 +26,7 @@ public:
   INLINE StringDecoder(const std::string &input);
   INLINE StringDecoder(const std::string &input);
   virtual ~StringDecoder();
   virtual ~StringDecoder();
 
 
-  virtual int get_next_character();
+  virtual char32_t get_next_character();
   INLINE bool is_eof();
   INLINE bool is_eof();
 
 
   static void set_notify_ptr(std::ostream *ptr);
   static void set_notify_ptr(std::ostream *ptr);
@@ -48,20 +48,23 @@ class StringUtf8Decoder : public StringDecoder {
 public:
 public:
   INLINE StringUtf8Decoder(const std::string &input);
   INLINE StringUtf8Decoder(const std::string &input);
 
 
-  virtual int get_next_character();
+  virtual char32_t get_next_character();
 };
 };
 
 
 /**
 /**
  * This decoder extracts characters two at a time to get a plain wide
  * This decoder extracts characters two at a time to get a plain wide
- * character sequence.
+ * character sequence.  It supports surrogate pairs.
  */
  */
-class StringUnicodeDecoder : public StringDecoder {
+class StringUtf16Decoder : public StringDecoder {
 public:
 public:
-  INLINE StringUnicodeDecoder(const std::string &input);
+  INLINE StringUtf16Decoder(const std::string &input);
 
 
-  virtual int get_next_character();
+  virtual char32_t get_next_character();
 };
 };
 
 
+// Deprecated alias of StringUtf16Encoder.
+typedef StringUtf16Decoder StringUnicodeDecoder;
+
 #include "stringDecoder.I"
 #include "stringDecoder.I"
 
 
 #endif
 #endif

+ 36 - 6
dtool/src/dtoolutil/textEncoder.I

@@ -90,6 +90,7 @@ set_text(const std::string &text) {
   if (!has_text() || _text != text) {
   if (!has_text() || _text != text) {
     _text = text;
     _text = text;
     _flags = (_flags | F_got_text) & ~F_got_wtext;
     _flags = (_flags | F_got_text) & ~F_got_wtext;
+    text_changed();
   }
   }
 }
 }
 
 
@@ -101,7 +102,11 @@ set_text(const std::string &text) {
  */
  */
 INLINE void TextEncoder::
 INLINE void TextEncoder::
 set_text(const std::string &text, TextEncoder::Encoding encoding) {
 set_text(const std::string &text, TextEncoder::Encoding encoding) {
-  set_wtext(decode_text(text, encoding));
+  if (encoding == _encoding) {
+    set_text(text);
+  } else {
+    set_wtext(decode_text(text, encoding));
+  }
 }
 }
 
 
 /**
 /**
@@ -112,6 +117,7 @@ clear_text() {
   _text = std::string();
   _text = std::string();
   _wtext = std::wstring();
   _wtext = std::wstring();
   _flags |= (F_got_text | F_got_wtext);
   _flags |= (F_got_text | F_got_wtext);
+  text_changed();
 }
 }
 
 
 /**
 /**
@@ -151,8 +157,11 @@ get_text(TextEncoder::Encoding encoding) const {
  */
  */
 INLINE void TextEncoder::
 INLINE void TextEncoder::
 append_text(const std::string &text) {
 append_text(const std::string &text) {
-  _text = get_text() + text;
-  _flags = (_flags | F_got_text) & ~F_got_wtext;
+  if (!text.empty()) {
+    _text = get_text() + text;
+    _flags = (_flags | F_got_text) & ~F_got_wtext;
+    text_changed();
+  }
 }
 }
 
 
 /**
 /**
@@ -160,9 +169,25 @@ append_text(const std::string &text) {
  * wide character, up to 16 bits in Unicode.
  * wide character, up to 16 bits in Unicode.
  */
  */
 INLINE void TextEncoder::
 INLINE void TextEncoder::
-append_unicode_char(int character) {
+append_unicode_char(char32_t character) {
+#if WCHAR_MAX >= 0x10FFFF
+  // wchar_t might be UTF-32.
   _wtext = get_wtext() + std::wstring(1, (wchar_t)character);
   _wtext = get_wtext() + std::wstring(1, (wchar_t)character);
+#else
+  if ((character & ~0xffff) == 0) {
+    _wtext = get_wtext() + std::wstring(1, (wchar_t)character);
+  } else {
+    // Encode as a surrogate pair.
+    uint32_t v = (uint32_t)character - 0x10000u;
+    wchar_t wstr[2] = {
+      (wchar_t)((v >> 10u) | 0xd800u),
+      (wchar_t)((v & 0x3ffu) | 0xdc00u),
+    };
+    _wtext = get_wtext() + std::wstring(wstr, 2);
+  }
+#endif
   _flags = (_flags | F_got_wtext) & ~F_got_text;
   _flags = (_flags | F_got_wtext) & ~F_got_text;
+  text_changed();
 }
 }
 
 
 /**
 /**
@@ -200,6 +225,7 @@ set_unicode_char(size_t index, int character) {
   if (index < _wtext.length()) {
   if (index < _wtext.length()) {
     _wtext[index] = character;
     _wtext[index] = character;
     _flags &= ~F_got_text;
     _flags &= ~F_got_text;
+    text_changed();
   }
   }
 }
 }
 
 
@@ -418,6 +444,7 @@ set_wtext(const std::wstring &wtext) {
   if (!has_text() || _wtext != wtext) {
   if (!has_text() || _wtext != wtext) {
     _wtext = wtext;
     _wtext = wtext;
     _flags = (_flags | F_got_wtext) & ~F_got_text;
     _flags = (_flags | F_got_wtext) & ~F_got_text;
+    text_changed();
   }
   }
 }
 }
 
 
@@ -439,8 +466,11 @@ get_wtext() const {
  */
  */
 INLINE void TextEncoder::
 INLINE void TextEncoder::
 append_wtext(const std::wstring &wtext) {
 append_wtext(const std::wstring &wtext) {
-  _wtext = get_wtext() + wtext;
-  _flags = (_flags | F_got_wtext) & ~F_got_text;
+  if (!wtext.empty()) {
+    _wtext = get_wtext() + wtext;
+    _flags = (_flags | F_got_wtext) & ~F_got_text;
+    text_changed();
+  }
 }
 }
 
 
 /**
 /**

+ 73 - 19
dtool/src/dtoolutil/textEncoder.cxx

@@ -21,7 +21,7 @@ using std::ostream;
 using std::string;
 using std::string;
 using std::wstring;
 using std::wstring;
 
 
-TextEncoder::Encoding TextEncoder::_default_encoding = TextEncoder::E_iso8859;
+TextEncoder::Encoding TextEncoder::_default_encoding = TextEncoder::E_utf8;
 
 
 /**
 /**
  * Adjusts the text stored within the encoder to all uppercase letters
  * Adjusts the text stored within the encoder to all uppercase letters
@@ -35,6 +35,7 @@ make_upper() {
     (*si) = unicode_toupper(*si);
     (*si) = unicode_toupper(*si);
   }
   }
   _flags &= ~F_got_text;
   _flags &= ~F_got_text;
+  text_changed();
 }
 }
 
 
 /**
 /**
@@ -49,6 +50,7 @@ make_lower() {
     (*si) = unicode_tolower(*si);
     (*si) = unicode_tolower(*si);
   }
   }
   _flags &= ~F_got_text;
   _flags &= ~F_got_text;
+  text_changed();
 }
 }
 
 
 /**
 /**
@@ -107,11 +109,11 @@ is_wtext() const {
 }
 }
 
 
 /**
 /**
- * Encodes a single wide char into a one-, two-, or three-byte string,
- * according to the given encoding system.
+ * Encodes a single Unicode character into a one-, two-, three-, or four-byte
+ * string, according to the given encoding system.
  */
  */
 string TextEncoder::
 string TextEncoder::
-encode_wchar(wchar_t ch, TextEncoder::Encoding encoding) {
+encode_wchar(char32_t ch, TextEncoder::Encoding encoding) {
   switch (encoding) {
   switch (encoding) {
   case E_iso8859:
   case E_iso8859:
     if ((ch & ~0xff) == 0) {
     if ((ch & ~0xff) == 0) {
@@ -143,17 +145,38 @@ encode_wchar(wchar_t ch, TextEncoder::Encoding encoding) {
       return
       return
         string(1, (char)((ch >> 6) | 0xc0)) +
         string(1, (char)((ch >> 6) | 0xc0)) +
         string(1, (char)((ch & 0x3f) | 0x80));
         string(1, (char)((ch & 0x3f) | 0x80));
-    } else {
+    } else if ((ch & ~0xffff) == 0) {
       return
       return
         string(1, (char)((ch >> 12) | 0xe0)) +
         string(1, (char)((ch >> 12) | 0xe0)) +
         string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) +
         string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) +
         string(1, (char)((ch & 0x3f) | 0x80));
         string(1, (char)((ch & 0x3f) | 0x80));
+    } else {
+      return
+        string(1, (char)((ch >> 18) | 0xf0)) +
+        string(1, (char)(((ch >> 12) & 0x3f) | 0x80)) +
+        string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) +
+        string(1, (char)((ch & 0x3f) | 0x80));
     }
     }
 
 
-  case E_unicode:
-    return
-      string(1, (char)(ch >> 8)) +
-      string(1, (char)(ch & 0xff));
+  case E_utf16be:
+    if ((ch & ~0xffff) == 0) {
+      // Note that this passes through surrogates and BOMs unharmed.
+      return
+        string(1, (char)(ch >> 8)) +
+        string(1, (char)(ch & 0xff));
+    } else {
+      // Use a surrogate pair.
+      uint32_t v = (uint32_t)ch - 0x10000u;
+      uint16_t hi = (v >> 10u) | 0xd800u;
+      uint16_t lo = (v & 0x3ffu) | 0xdc00u;
+      char encoded[4] = {
+        (char)(hi >> 8),
+        (char)(hi & 0xff),
+        (char)(lo >> 8),
+        (char)(lo & 0xff),
+      };
+      return string(encoded, 4);
+    }
   }
   }
 
 
   return "";
   return "";
@@ -167,8 +190,25 @@ string TextEncoder::
 encode_wtext(const wstring &wtext, TextEncoder::Encoding encoding) {
 encode_wtext(const wstring &wtext, TextEncoder::Encoding encoding) {
   string result;
   string result;
 
 
-  for (wstring::const_iterator pi = wtext.begin(); pi != wtext.end(); ++pi) {
-    result += encode_wchar(*pi, encoding);
+  for (size_t i = 0; i < wtext.size(); ++i) {
+    wchar_t ch = wtext[i];
+
+    // On some systems, wstring may be UTF-16, and contain surrogate pairs.
+#if WCHAR_MAX < 0x10FFFF
+    if (ch >= 0xd800 && ch < 0xdc00 && (i + 1) < wtext.size()) {
+      // This is a high surrogate.  Look for a subsequent low surrogate.
+      wchar_t ch2 = wtext[i + 1];
+      if (ch2 >= 0xdc00 && ch2 < 0xe000) {
+        // Yes, this is a low surrogate.
+        char32_t code_point = 0x10000 + ((ch - 0xd800) << 10) + (ch2 - 0xdc00);
+        result += encode_wchar(code_point, encoding);
+        i++;
+        continue;
+      }
+    }
+#endif
+
+    result += encode_wchar(ch, encoding);
   }
   }
 
 
   return result;
   return result;
@@ -187,9 +227,9 @@ decode_text(const string &text, TextEncoder::Encoding encoding) {
       return decode_text_impl(decoder);
       return decode_text_impl(decoder);
     }
     }
 
 
-  case E_unicode:
+  case E_utf16be:
     {
     {
-      StringUnicodeDecoder decoder(text);
+      StringUtf16Decoder decoder(text);
       return decode_text_impl(decoder);
       return decode_text_impl(decoder);
     }
     }
 
 
@@ -211,7 +251,7 @@ decode_text_impl(StringDecoder &decoder) {
   wstring result;
   wstring result;
   // bool expand_amp = get_expand_amp();
   // bool expand_amp = get_expand_amp();
 
 
-  wchar_t character = decoder.get_next_character();
+  char32_t character = decoder.get_next_character();
   while (!decoder.is_eof()) {
   while (!decoder.is_eof()) {
     /*
     /*
     if (character == '&' && expand_amp) {
     if (character == '&' && expand_amp) {
@@ -219,7 +259,14 @@ decode_text_impl(StringDecoder &decoder) {
       character = expand_amp_sequence(decoder);
       character = expand_amp_sequence(decoder);
     }
     }
     */
     */
-    result += character;
+    if (character <= WCHAR_MAX) {
+      result += character;
+    } else {
+      // We need to encode this as a surrogate pair.
+      uint32_t v = (uint32_t)character - 0x10000u;
+      result += (wchar_t)((v >> 10u) | 0xd800u);
+      result += (wchar_t)((v & 0x3ffu) | 0xdc00u);
+    }
     character = decoder.get_next_character();
     character = decoder.get_next_character();
   }
   }
 
 
@@ -314,6 +361,12 @@ expand_amp_sequence(StringDecoder &decoder) const {
 }
 }
 */
 */
 
 
+/**
+ * Called whenever the text has been changed.
+ */
+void TextEncoder::
+text_changed() {
+}
 
 
 /**
 /**
  *
  *
@@ -327,8 +380,8 @@ operator << (ostream &out, TextEncoder::Encoding encoding) {
   case TextEncoder::E_utf8:
   case TextEncoder::E_utf8:
     return out << "utf8";
     return out << "utf8";
 
 
-  case TextEncoder::E_unicode:
-    return out << "unicode";
+  case TextEncoder::E_utf16be:
+    return out << "utf16be";
   };
   };
 
 
   return out << "**invalid TextEncoder::Encoding(" << (int)encoding << ")**";
   return out << "**invalid TextEncoder::Encoding(" << (int)encoding << ")**";
@@ -346,8 +399,9 @@ operator >> (istream &in, TextEncoder::Encoding &encoding) {
     encoding = TextEncoder::E_iso8859;
     encoding = TextEncoder::E_iso8859;
   } else if (word == "utf8" || word == "utf-8") {
   } else if (word == "utf8" || word == "utf-8") {
     encoding = TextEncoder::E_utf8;
     encoding = TextEncoder::E_utf8;
-  } else if (word == "unicode") {
-    encoding = TextEncoder::E_unicode;
+  } else if (word == "unicode" || word == "utf16be" || word == "utf-16be" ||
+                                  word == "utf16-be" || word == "utf-16-be") {
+    encoding = TextEncoder::E_utf16be;
   } else {
   } else {
     ostream *notify_ptr = StringDecoder::get_notify_ptr();
     ostream *notify_ptr = StringDecoder::get_notify_ptr();
     if (notify_ptr != nullptr) {
     if (notify_ptr != nullptr) {

+ 30 - 3
dtool/src/dtoolutil/textEncoder.h

@@ -35,7 +35,10 @@ PUBLISHED:
   enum Encoding {
   enum Encoding {
     E_iso8859,
     E_iso8859,
     E_utf8,
     E_utf8,
-    E_unicode
+    E_utf16be,
+
+    // Deprecated alias for E_utf16be
+    E_unicode = E_utf16be,
   };
   };
 
 
   INLINE TextEncoder();
   INLINE TextEncoder();
@@ -48,18 +51,29 @@ PUBLISHED:
   INLINE static Encoding get_default_encoding();
   INLINE static Encoding get_default_encoding();
   MAKE_PROPERTY(default_encoding, get_default_encoding, set_default_encoding);
   MAKE_PROPERTY(default_encoding, get_default_encoding, set_default_encoding);
 
 
+#ifdef CPPPARSER
+  EXTEND void set_text(PyObject *text);
+  EXTEND void set_text(PyObject *text, Encoding encoding);
+#else
   INLINE void set_text(const std::string &text);
   INLINE void set_text(const std::string &text);
   INLINE void set_text(const std::string &text, Encoding encoding);
   INLINE void set_text(const std::string &text, Encoding encoding);
+#endif
   INLINE void clear_text();
   INLINE void clear_text();
   INLINE bool has_text() const;
   INLINE bool has_text() const;
 
 
   void make_upper();
   void make_upper();
   void make_lower();
   void make_lower();
 
 
+#ifdef CPPPARSER
+  EXTEND PyObject *get_text() const;
+  EXTEND PyObject *get_text(Encoding encoding) const;
+  EXTEND void append_text(PyObject *text);
+#else
   INLINE std::string get_text() const;
   INLINE std::string get_text() const;
   INLINE std::string get_text(Encoding encoding) const;
   INLINE std::string get_text(Encoding encoding) const;
   INLINE void append_text(const std::string &text);
   INLINE void append_text(const std::string &text);
-  INLINE void append_unicode_char(int character);
+#endif
+  INLINE void append_unicode_char(char32_t character);
   INLINE size_t get_num_chars() const;
   INLINE size_t get_num_chars() const;
   INLINE int get_unicode_char(size_t index) const;
   INLINE int get_unicode_char(size_t index) const;
   INLINE void set_unicode_char(size_t index, int character);
   INLINE void set_unicode_char(size_t index, int character);
@@ -91,11 +105,24 @@ PUBLISHED:
   std::wstring get_wtext_as_ascii() const;
   std::wstring get_wtext_as_ascii() const;
   bool is_wtext() const;
   bool is_wtext() const;
 
 
-  static std::string encode_wchar(wchar_t ch, Encoding encoding);
+#ifdef CPPPARSER
+  EXTEND static PyObject *encode_wchar(char32_t ch, Encoding encoding);
+  EXTEND INLINE PyObject *encode_wtext(const std::wstring &wtext) const;
+  EXTEND static PyObject *encode_wtext(const std::wstring &wtext, Encoding encoding);
+  EXTEND INLINE PyObject *decode_text(PyObject *text) const;
+  EXTEND static PyObject *decode_text(PyObject *text, Encoding encoding);
+#else
+  static std::string encode_wchar(char32_t ch, Encoding encoding);
   INLINE std::string encode_wtext(const std::wstring &wtext) const;
   INLINE std::string encode_wtext(const std::wstring &wtext) const;
   static std::string encode_wtext(const std::wstring &wtext, Encoding encoding);
   static std::string encode_wtext(const std::wstring &wtext, Encoding encoding);
   INLINE std::wstring decode_text(const std::string &text) const;
   INLINE std::wstring decode_text(const std::string &text) const;
   static std::wstring decode_text(const std::string &text, Encoding encoding);
   static std::wstring decode_text(const std::string &text, Encoding encoding);
+#endif
+
+  MAKE_PROPERTY(text, get_text, set_text);
+
+protected:
+  virtual void text_changed();
 
 
 private:
 private:
   enum Flags {
   enum Flags {

+ 30 - 0
dtool/src/dtoolutil/textEncoder_ext.I

@@ -0,0 +1,30 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file textEncoder_ext.I
+ * @author rdb
+ * @date 2018-10-08
+ */
+
+/**
+ * Encodes a wide-text string into a single-char string, according to the
+ * current encoding.
+ */
+INLINE PyObject *Extension<TextEncoder>::
+encode_wtext(const std::wstring &wtext) const {
+  return encode_wtext(wtext, _this->get_encoding());
+}
+
+/**
+ * Returns the given wstring decoded to a single-byte string, via the current
+ * encoding system.
+ */
+INLINE PyObject *Extension<TextEncoder>::
+decode_text(PyObject *text) const {
+  return decode_text(text, _this->get_encoding());
+}

+ 159 - 0
dtool/src/dtoolutil/textEncoder_ext.cxx

@@ -0,0 +1,159 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file textEncoder_ext.cxx
+ * @author rdb
+ * @date 2018-09-29
+ */
+
+#include "textEncoder_ext.h"
+
+#ifdef HAVE_PYTHON
+
+/**
+ * Sets the text as a Unicode string.  In Python 2, if a regular str is given,
+ * it is assumed to be in the TextEncoder's specified encoding.
+ */
+void Extension<TextEncoder>::
+set_text(PyObject *text) {
+  if (PyUnicode_Check(text)) {
+#if PY_VERSION_HEX >= 0x03030000
+    Py_ssize_t len;
+    const char *str = PyUnicode_AsUTF8AndSize(text, &len);
+    _this->set_text(std::string(str, len), TextEncoder::E_utf8);
+#else
+    Py_ssize_t len = PyUnicode_GET_SIZE(text);
+    wchar_t *str = (wchar_t *)alloca(sizeof(wchar_t) * (len + 1));
+    PyUnicode_AsWideChar((PyUnicodeObject *)text, str, len);
+    _this->set_wtext(std::wstring(str, len));
+#endif
+  } else {
+#if PY_MAJOR_VERSION >= 3
+    Dtool_Raise_TypeError("expected string");
+#else
+    char *str;
+    Py_ssize_t len;
+    if (PyString_AsStringAndSize(text, (char **)&str, &len) != -1) {
+      _this->set_text(std::string(str, len));
+    }
+#endif
+  }
+}
+
+/**
+ * Sets the text as an encoded byte string of the given encoding.
+ */
+void Extension<TextEncoder>::
+set_text(PyObject *text, TextEncoder::Encoding encoding) {
+  char *str;
+  Py_ssize_t len;
+  if (PyBytes_AsStringAndSize(text, &str, &len) >= 0) {
+    _this->set_text(std::string(str, len), encoding);
+  }
+}
+
+/**
+ * Returns the text as a string.  In Python 2, the returned string is in the
+ * TextEncoder's specified encoding.  In Python 3, it is returned as unicode.
+ */
+PyObject *Extension<TextEncoder>::
+get_text() const {
+#if PY_MAJOR_VERSION >= 3
+  std::wstring text = _this->get_wtext();
+  return PyUnicode_FromWideChar(text.data(), (Py_ssize_t)text.size());
+#else
+  std::string text = _this->get_text();
+  return PyString_FromStringAndSize((char *)text.data(), (Py_ssize_t)text.size());
+#endif
+}
+
+/**
+ * Returns the text as a bytes object in the given encoding.
+ */
+PyObject *Extension<TextEncoder>::
+get_text(TextEncoder::Encoding encoding) const {
+  std::string text = _this->get_text(encoding);
+#if PY_MAJOR_VERSION >= 3
+  return PyBytes_FromStringAndSize((char *)text.data(), (Py_ssize_t)text.size());
+#else
+  return PyString_FromStringAndSize((char *)text.data(), (Py_ssize_t)text.size());
+#endif
+}
+
+/**
+ * Appends the text as a string (or Unicode object in Python 2).
+ */
+void Extension<TextEncoder>::
+append_text(PyObject *text) {
+  if (PyUnicode_Check(text)) {
+#if PY_VERSION_HEX >= 0x03030000
+    Py_ssize_t len;
+    const char *str = PyUnicode_AsUTF8AndSize(text, &len);
+    _this->append_text(std::string(str, len));
+#else
+    Py_ssize_t len = PyUnicode_GET_SIZE(text);
+    wchar_t *str = (wchar_t *)alloca(sizeof(wchar_t) * (len + 1));
+    PyUnicode_AsWideChar((PyUnicodeObject *)text, str, len);
+    _this->append_wtext(std::wstring(str, len));
+#endif
+  } else {
+#if PY_MAJOR_VERSION >= 3
+    Dtool_Raise_TypeError("expected string");
+#else
+    char *str;
+    Py_ssize_t len;
+    if (PyString_AsStringAndSize(text, (char **)&str, &len) != -1) {
+      _this->append_text(std::string(str, len));
+    }
+#endif
+  }
+}
+
+/**
+ * Encodes the given wide character as byte string in the given encoding.
+ */
+PyObject *Extension<TextEncoder>::
+encode_wchar(char32_t ch, TextEncoder::Encoding encoding) {
+  std::string value = TextEncoder::encode_wchar(ch, encoding);
+#if PY_MAJOR_VERSION >= 3
+  return PyBytes_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
+#else
+  return PyString_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
+#endif
+}
+
+/**
+ * Encodes a wide-text string into a single-char string, according to the
+ * given encoding.
+ */
+PyObject *Extension<TextEncoder>::
+encode_wtext(const wstring &wtext, TextEncoder::Encoding encoding) {
+  std::string value = TextEncoder::encode_wtext(wtext, encoding);
+#if PY_MAJOR_VERSION >= 3
+  return PyBytes_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
+#else
+  return PyString_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
+#endif
+}
+
+/**
+ * Returns the given wstring decoded to a single-byte string, via the given
+ * encoding system.
+ */
+PyObject *Extension<TextEncoder>::
+decode_text(PyObject *text, TextEncoder::Encoding encoding) {
+  char *str;
+  Py_ssize_t len;
+  if (PyBytes_AsStringAndSize(text, &str, &len) >= 0) {
+    return Dtool_WrapValue(TextEncoder::decode_text(std::string(str, len), encoding));
+  } else {
+    return nullptr;
+  }
+}
+
+#endif  // HAVE_PYTHON

+ 50 - 0
dtool/src/dtoolutil/textEncoder_ext.h

@@ -0,0 +1,50 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file textEncoder_ext.h
+ * @author rdb
+ * @date 2018-09-29
+ */
+
+#ifndef TEXTENCODER_EXT_H
+#define TEXTENCODER_EXT_H
+
+#include "dtoolbase.h"
+
+#ifdef HAVE_PYTHON
+
+#include "extension.h"
+#include "textEncoder.h"
+#include "py_panda.h"
+
+/**
+ * This class defines the extension methods for TextEncoder, which are called
+ * instead of any C++ methods with the same prototype.
+ */
+template<>
+class Extension<TextEncoder> : public ExtensionBase<TextEncoder> {
+public:
+  void set_text(PyObject *text);
+  void set_text(PyObject *text, TextEncoder::Encoding encoding);
+
+  PyObject *get_text() const;
+  PyObject *get_text(TextEncoder::Encoding encoding) const;
+  void append_text(PyObject *text);
+
+  static PyObject *encode_wchar(char32_t ch, TextEncoder::Encoding encoding);
+  INLINE PyObject *encode_wtext(const std::wstring &wtext) const;
+  static PyObject *encode_wtext(const std::wstring &wtext, TextEncoder::Encoding encoding);
+  INLINE PyObject *decode_text(PyObject *text) const;
+  static PyObject *decode_text(PyObject *text, TextEncoder::Encoding encoding);
+};
+
+#include "textEncoder_ext.I"
+
+#endif  // HAVE_PYTHON
+
+#endif  // TEXTENCODER_EXT_H

+ 2 - 3
dtool/src/interrogate/functionRemap.cxx

@@ -254,14 +254,13 @@ call_function(ostream &out, int indent_level, bool convert_result,
                                                            &parser);
                                                            &parser);
         out << " = " << call << ";\n";
         out << " = " << call << ";\n";
 
 
-        // MOVE() expands to std::move() when we are compiling with a compiler
-        // that supports rvalue references.  It basically turns an lvalue into
+        // Use of the C++11 std::move function basically turns an lvalue into
         // an rvalue, allowing a move constructor to be called instead of a
         // an rvalue, allowing a move constructor to be called instead of a
         // copy constructor (since we won't be using the return value any
         // copy constructor (since we won't be using the return value any
         // more), which is usually more efficient if it exists.  If it
         // more), which is usually more efficient if it exists.  If it
         // doesn't, it shouldn't do any harm.
         // doesn't, it shouldn't do any harm.
         string new_str =
         string new_str =
-          _return_type->prepare_return_expr(out, indent_level, "MOVE(result)");
+          _return_type->prepare_return_expr(out, indent_level, "std::move(result)");
         return_expr = _return_type->get_return_expr(new_str);
         return_expr = _return_type->get_return_expr(new_str);
 
 
       } else {
       } else {

+ 24 - 6
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -789,8 +789,6 @@ InterfaceMakerPythonNative::
  */
  */
 void InterfaceMakerPythonNative::
 void InterfaceMakerPythonNative::
 write_prototypes(ostream &out_code, ostream *out_h) {
 write_prototypes(ostream &out_code, ostream *out_h) {
-  Functions::iterator fi;
-
   if (out_h != nullptr) {
   if (out_h != nullptr) {
     *out_h << "#include \"py_panda.h\"\n\n";
     *out_h << "#include \"py_panda.h\"\n\n";
   }
   }
@@ -917,7 +915,6 @@ write_prototypes_class_external(ostream &out, Object *obj) {
 void InterfaceMakerPythonNative::
 void InterfaceMakerPythonNative::
 write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
 write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
   std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
   std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
-  Functions::iterator fi;
 
 
   out_code << "/**\n";
   out_code << "/**\n";
   out_code << " * Forward declarations for top-level class " << ClassName << "\n";
   out_code << " * Forward declarations for top-level class " << ClassName << "\n";
@@ -1089,6 +1086,27 @@ write_class_details(ostream &out, Object *obj) {
       }
       }
     }
     }
 
 
+    // Are there any implicit cast operators that can cast this object to our
+    // desired pointer?
+    for (Function *func : obj->_methods) {
+      for (FunctionRemap *remap : func->_remaps) {
+        if (remap->_type == FunctionRemap::T_typecast_method &&
+            is_remap_legal(remap) &&
+            !remap->_return_type->return_value_needs_management() &&
+            (remap->_cppfunc->_storage_class & CPPInstance::SC_explicit) == 0 &&
+            TypeManager::is_pointer(remap->_return_type->get_new_type())) {
+
+          CPPType *cast_type = remap->_return_type->get_orig_type();
+          CPPType *obj_type = TypeManager::unwrap(TypeManager::resolve_type(remap->_return_type->get_new_type()));
+          string return_expr = "(" + cast_type->get_local_name(&parser) + ")*local_this";
+          out << "  // " << *remap->_cppfunc << "\n";
+          out << "  if (requested_type == Dtool_Ptr_" << make_safe_name(obj_type->get_local_name(&parser)) << ") {\n";
+          out << "    return (void *)(" << remap->_return_type->get_return_expr(return_expr) << ");\n";
+          out << "  }\n";
+        }
+      }
+    }
+
     out << "  return nullptr;\n";
     out << "  return nullptr;\n";
     out << "}\n\n";
     out << "}\n\n";
 
 
@@ -3301,7 +3319,7 @@ write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
  */
  */
 void InterfaceMakerPythonNative::
 void InterfaceMakerPythonNative::
 write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) {
 write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) {
-  Function::Remaps::const_iterator ri;
+// Function::Remaps::const_iterator ri;
 
 
 // for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
 // for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
 // FunctionRemap *remap = (*ri);
 // FunctionRemap *remap = (*ri);
@@ -5473,7 +5491,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
 
 
           // Use move constructor when available for functions that take an
           // Use move constructor when available for functions that take an
           // actual PointerTo.  This eliminates an unref()ref() pair.
           // actual PointerTo.  This eliminates an unref()ref() pair.
-          pexpr_string = "MOVE(" + param_name + "_this)";
+          pexpr_string = "std::move(" + param_name + "_this)";
 
 
         } else {
         } else {
           // This is a move-assignable type, such as TypeHandle or LVecBase4.
           // This is a move-assignable type, such as TypeHandle or LVecBase4.
@@ -6138,7 +6156,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
       indent(out, indent_level) << "return true;\n";
       indent(out, indent_level) << "return true;\n";
 
 
     } else if (TypeManager::is_reference_count(remap->_cpptype)) {
     } else if (TypeManager::is_reference_count(remap->_cpptype)) {
-      indent(out, indent_level) << "coerced = MOVE(" << return_expr << ");\n";
+      indent(out, indent_level) << "coerced = std::move(" << return_expr << ");\n";
       indent(out, indent_level) << "return true;\n";
       indent(out, indent_level) << "return true;\n";
 
 
     } else {
     } else {

+ 1 - 1
dtool/src/interrogate/interrogate.cxx

@@ -516,7 +516,7 @@ main(int argc, char **argv) {
       cerr << "Error parsing file: '" << argv[i] << "'\n";
       cerr << "Error parsing file: '" << argv[i] << "'\n";
       exit(1);
       exit(1);
     }
     }
-    builder.add_source_file(filename);
+    builder.add_source_file(filename.to_os_generic());
   }
   }
 
 
   // Now that we've parsed all the source code, change the way things are
   // Now that we've parsed all the source code, change the way things are

+ 1 - 1
dtool/src/interrogate/interrogateBuilder.cxx

@@ -2943,7 +2943,7 @@ define_method(CPPInstance *function, InterrogateType &itype,
   // specifically flag get_class_type() as published.
   // specifically flag get_class_type() as published.
   bool force_publish = false;
   bool force_publish = false;
   if (function->get_simple_name() == "get_class_type" &&
   if (function->get_simple_name() == "get_class_type" &&
-      (function->_storage_class && CPPInstance::SC_static) != 0 &&
+      (function->_storage_class & CPPInstance::SC_static) != 0 &&
       function->_vis <= V_public) {
       function->_vis <= V_public) {
     force_publish = true;
     force_publish = true;
   }
   }

+ 1 - 1
dtool/src/interrogate/parameterRemapConcreteToPointer.cxx

@@ -40,7 +40,7 @@ pass_parameter(std::ostream &out, const std::string &variable_name) {
   if (variable_name.size() > 1 && variable_name[0] == '&') {
   if (variable_name.size() > 1 && variable_name[0] == '&') {
     // Prevent generating something like *&param Also, if this is really some
     // Prevent generating something like *&param Also, if this is really some
     // local type, we can presumably just move it?
     // local type, we can presumably just move it?
-    out << "MOVE(" << variable_name.substr(1) << ")";
+    out << "std::move(" << variable_name.substr(1) << ")";
   } else {
   } else {
     out << "*" << variable_name;
     out << "*" << variable_name;
   }
   }

+ 1 - 1
dtool/src/interrogate/parameterRemapReferenceToPointer.cxx

@@ -42,7 +42,7 @@ pass_parameter(std::ostream &out, const std::string &variable_name) {
     // this parameter is an rvalue reference, but CPPParser can't know that,
     // this parameter is an rvalue reference, but CPPParser can't know that,
     // and it might have an overload that takes an rvalue reference.  It
     // and it might have an overload that takes an rvalue reference.  It
     // shouldn't hurt either way.
     // shouldn't hurt either way.
-    out << "MOVE(" << variable_name.substr(1) << ")";
+    out << "std::move(" << variable_name.substr(1) << ")";
   } else {
   } else {
     out << "*" << variable_name;
     out << "*" << variable_name;
   }
   }

部分文件因文件數量過多而無法顯示