direct: More code style changes

This commit is contained in:
rdb 2023-02-22 11:42:13 +01:00
parent 9a15e9245c
commit 37b5c9ad9e
112 changed files with 1312 additions and 775 deletions

View File

@ -493,7 +493,8 @@ disable=raw-checker-failed,
using-constant-test,
wrong-import-order,
wrong-import-position,
not-callable
not-callable,
wildcard-import
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
@ -615,6 +616,7 @@ contextmanager-decorators=contextlib.contextmanager
# expressions are accepted.
generated-members=base.cr,
base.le,
base.localAvatar,
Pmw.AboutDialog,
Pmw.Balloon,
Pmw.ButtonBox,
@ -629,8 +631,10 @@ generated-members=base.cr,
Pmw.MenuBar,
Pmw.MessageBar,
Pmw.NoteBook,
Pmw.OK,
Pmw.OptionMenu,
Pmw.OptionMenu,
Pmw.PARTIAL,
Pmw.PanedWidget,
Pmw.ScrolledCanvas,
Pmw.ScrolledFrame,
@ -640,8 +644,10 @@ generated-members=base.cr,
Pmw.aboutcopyright,
Pmw.aboutversion,
Pmw.forwardmethods,
Pmw.integervalidator,
Pmw.popgrab,
Pmw.pushgrab,
Pmw.realvalidator,
Pmw.setgeometryanddeiconify
# Tells whether to warn about missing members when the owner of the attribute
@ -699,7 +705,8 @@ additional-builtins=base,
cluster,
launcher,
taskMgr,
localAvatar
localAvatar,
game
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes

View File

@ -113,7 +113,6 @@ class ClusterClient(DirectObject.DirectObject):
self.notify.debug('post startMoveCam')
self.startMoveSelectedTask()
def startReaderPollTask(self):
""" Task to handle datagrams from server """
# Run this task just after the listener poll task
@ -130,7 +129,6 @@ class ClusterClient(DirectObject.DirectObject):
return Task.cont
def startControlObjectTask(self):
self.notify.debug("moving control objects")
taskMgr.add(self.controlObjectTask,"controlObjectTask",50)
@ -152,7 +150,6 @@ class ClusterClient(DirectObject.DirectObject):
self.notify.debug('adding move cam')
taskMgr.add(self.moveCameraTask, "moveCamTask", 49)
def controlObjectTask(self, task):
for pair in self.sortedControlMappings:
object = pair[1]
@ -171,8 +168,6 @@ class ClusterClient(DirectObject.DirectObject):
for server in serverList:
self.serverList[server].sendNamedMovementDone()
def redoSortedPriorities(self):
self.sortedControlMappings = []
for key in self.controlMappings:
@ -194,7 +189,6 @@ class ClusterClient(DirectObject.DirectObject):
for server in serverList:
self.serverList[server].sendMoveNamedObject(xyz,hpr,scale,color,hidden,object)
def moveCameraTask(self, task):
self.moveCamera(
base.camera.getPos(render),
@ -221,7 +215,6 @@ class ClusterClient(DirectObject.DirectObject):
server.sendMoveSelected(xyz, hpr, scale)
return Task.cont
def addNamedObjectMapping(self, object, name, hasColor = True):
if name not in self.objectMappings:
self.objectMappings[name] = object
@ -233,7 +226,6 @@ class ClusterClient(DirectObject.DirectObject):
if name in self.objectMappings:
self.objectMappings.pop(name)
def addControlMapping(self, objectName, controlledName, serverList = None,
offset = None, priority = 0):
if objectName not in self.controlMappings:
@ -278,7 +270,6 @@ class ClusterClient(DirectObject.DirectObject):
self.controlPriorities.pop(name)
self.redoSortedPriorities()
def getNodePathFindCmd(self, nodePath):
pathString = repr(nodePath)
index = pathString.find('/')
@ -298,7 +289,6 @@ class ClusterClient(DirectObject.DirectObject):
else:
return pathString
def addObjectTag(self,object,selectFunction,deselectFunction,selectArgs,deselectArgs):
newTag = {}
newTag["selectFunction"] = selectFunction
@ -307,12 +297,10 @@ class ClusterClient(DirectObject.DirectObject):
newTag["deselectArgs"] = deselectArgs
self.taggedObjects[object] = newTag
def removeObjectTag(self,object):
self.taggedObjects.pop(object)
def selectNodePath(self, nodePath):
name = self.getNodePathName(nodePath)
if name in self.taggedObjects:
@ -325,7 +313,6 @@ class ClusterClient(DirectObject.DirectObject):
else:
self(self.getNodePathFindCmd(nodePath) + '.select()', 0)
def deselectNodePath(self, nodePath):
name = self.getNodePathName(nodePath)
if name in self.taggedObjects:
@ -363,7 +350,6 @@ class ClusterClient(DirectObject.DirectObject):
# Execute locally
exec(commandString, __builtins__)
def handleDatagram(self,dgi,type,server):
if type == CLUSTER_NONE:
pass
@ -388,7 +374,6 @@ class ClusterClient(DirectObject.DirectObject):
# clear the queue
self.serverQueues[server] = []
def handleNamedMovement(self, data):
""" Update cameraJig position to reflect latest position """
@ -408,7 +393,6 @@ class ClusterClient(DirectObject.DirectObject):
else:
self.notify.debug("recieved unknown named object command: "+name)
def exit(self):
# Execute remotely
for server in self.serverList:
@ -475,8 +459,6 @@ class DisplayConnection:
self.qcr.addConnection(self.tcpConn)
self.cw=ConnectionWriter(qcm, 0)
def poll(self):
""" Non blocking task to read all available datagrams """
dataGrams = []
@ -491,9 +473,6 @@ class DisplayConnection:
return dataGrams
def sendCamOffset(self, xyz, hpr):
ClusterClient.notify.debug("send cam offset...")
ClusterClient.notify.debug(("packet %d xyz, hpr=%f %f %f %f %f %f" %
@ -514,7 +493,6 @@ class DisplayConnection:
focalLength, filmSize, filmOffset)
self.cw.send(datagram, self.tcpConn)
def sendNamedMovementDone(self):
datagram = self.msgHandler.makeNamedMovementDone()
@ -584,6 +562,7 @@ class DisplayConnection:
frameCount, frameTime, dt)
self.cw.send(datagram, self.tcpConn)
class ClusterConfigItem:
def __init__(self, serverConfigName, serverName,
serverDaemonPort, serverMsgPort):
@ -599,9 +578,11 @@ class ClusterConfigItem:
self.focalLength = None
self.filmSize = None
self.filmOffset = None
def setCamOffset(self, xyz, hpr):
self.xyz = xyz
self.hpr = hpr
def setCamFrustum(self, focalLength, filmSize, filmOffset):
self.fFrustum = 1
self.focalLength = focalLength
@ -689,6 +670,7 @@ def createClusterClient():
class DummyClusterClient(DirectObject.DirectObject):
""" Dummy class to handle command strings when not in cluster mode """
notify = DirectNotifyGlobal.directNotify.newCategory("DummyClusterClient")
def __init__(self):
pass

View File

@ -164,4 +164,4 @@ ClientConfigs = {
'film offset': (0.000, 0.173),
}
],
}
}

View File

@ -40,6 +40,7 @@ import builtins
# Also, I'm not sure multiple camera-group configurations are working for the
# cluster system.
class ClusterServer(DirectObject.DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory("ClusterServer")
MSG_NUM = 2000000
@ -101,8 +102,6 @@ class ClusterServer(DirectObject.DirectObject):
clusterDaemonPort = CLUSTER_DAEMON_PORT
self.daemon.serverReady(clusterDaemonClient, clusterDaemonPort)
def startListenerPollTask(self):
# Run this task near the start of frame, sometime after the dataLoop
taskMgr.add(self.listenerPollTask, "serverListenerPollTask", -40)
@ -125,7 +124,6 @@ class ClusterServer(DirectObject.DirectObject):
self.notify.warning("getNewConnection returned false")
return Task.cont
def addNamedObjectMapping(self, object, name, hasColor = True,
priority = 0):
if name not in self.objectMappings:
@ -138,7 +136,6 @@ class ClusterServer(DirectObject.DirectObject):
if name in self.objectMappings:
self.objectMappings.pop(name)
def redoSortedPriorities(self):
self.sortedControlMappings = []
@ -148,7 +145,6 @@ class ClusterServer(DirectObject.DirectObject):
self.sortedControlMappings.sort()
def addControlMapping(self, objectName, controlledName, offset = None,
priority = 0):
if objectName not in self.controlMappings:
@ -165,14 +161,12 @@ class ClusterServer(DirectObject.DirectObject):
if objectName in self.controlMappings:
self.controlOffsets[objectName] = offset
def removeControlMapping(self, name):
if name in self.controlMappings:
self.controlMappings.pop(name)
self.controlPriorities.pop(name)
self.redoSortedPriorities()
def startControlObjectTask(self):
self.notify.debug("moving control objects")
taskMgr.add(self.controlObjectTask,"controlObjectTask",50)
@ -189,7 +183,6 @@ class ClusterServer(DirectObject.DirectObject):
self.sendNamedMovementDone()
return Task.cont
def sendNamedMovementDone(self):
self.notify.debug("named movement done")
datagram = self.msgHandler.makeNamedMovementDone()
@ -333,7 +326,6 @@ class ClusterServer(DirectObject.DirectObject):
else:
self.notify.debug("recieved unknown named object command: "+name)
def handleMessageQueue(self):
#print(self.messageQueue)
for data in self.messageQueue:
@ -369,5 +361,5 @@ class ClusterServer(DirectObject.DirectObject):
command = self.msgHandler.parseCommandStringDatagram(dgi)
try:
exec(command, __builtins__)
except:
except Exception:
pass

View File

@ -41,8 +41,6 @@ class ControlManager:
#self.monitorTask = taskMgr.add(self.monitor, "ControlManager-%s"%(id(self)), priority=-1)
self.forceAvJumpToken = None
if self.passMessagesThrough: # for not breaking toontown
ist=self.inputStateTokens
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
@ -50,7 +48,6 @@ class ControlManager:
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
def __str__(self):
return 'ControlManager: using \'%s\'' % self.currentControlsName

View File

@ -8,36 +8,47 @@ from direct.showbase.MessengerGlobal import messenger
class InputStateToken:
_SerialGen = SerialNumGen()
Inval = 'invalidatedToken'
def __init__(self, inputState):
self._id = InputStateToken._SerialGen.next()
self._hash = self._id
self._inputState = inputState
def release(self):
# subclasses will override
assert False
def isValid(self):
return self._id != InputStateToken.Inval
def invalidate(self):
self._id = InputStateToken.Inval
def __hash__(self):
return self._hash
#snake_case alias:
is_valid = isValid
class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
def release(self):
self._inputState._ignore(self)
self.ignoreAll()
class InputStateForceToken(InputStateToken):
def release(self):
self._inputState._unforce(self)
class InputStateTokenGroup:
def __init__(self):
self._tokens = []
def addToken(self, token):
self._tokens.append(token)
def release(self):
for token in self._tokens:
token.release()
@ -46,6 +57,7 @@ class InputStateTokenGroup:
#snake_case alias:
add_token = addToken
class InputState(DirectObject.DirectObject):
"""
InputState is for tracking the on/off state of some events.
@ -190,7 +202,6 @@ class InputState(DirectObject.DirectObject):
# input state simply because we're not looking at it anymore.
# self.set(name, False, inputSource)
def force(self, name, value, inputSource):
"""
Force isSet(name) to return 'value'.

View File

@ -55,6 +55,7 @@ import math
#import LineStream
class PhysicsWalker(DirectObject.DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory("PhysicsWalker")

View File

@ -35,6 +35,7 @@ JOYBOX_RANGE = JOYBOX_MAX - JOYBOX_MIN
JOYBOX_TREAD_SEPERATION = 1.0
class DirectJoybox(DirectObject):
joyboxCount = 0
xyzMultiplier = 1.0
@ -87,12 +88,10 @@ class DirectJoybox(DirectObject):
# Spawn update task
self.enable()
def setHeadingNodePath(self,np):
self.headingNP = np
def enable(self):
# Kill existing task
self.disable()
@ -126,18 +125,25 @@ class DirectJoybox(DirectObject):
def getNodePath(self):
return self.nodePath
def setRefCS(self, refCS):
self.refCS = refCS
def getRefCS(self):
return self.refCS
def getEventName(self, index):
return self.name + '-button-' + repr(index)
def setXyzMultiplier(self, multiplier):
DirectJoybox.xyzMultiplier = multiplier
def getXyzMultiplier(self):
return DirectJoybox.xyzMultiplier
def setHprMultiplier(self, multiplier):
DirectJoybox.hprMultiplier = multiplier
def getHprMultiplier(self):
return DirectJoybox.hprMultiplier
@ -193,6 +199,7 @@ class DirectJoybox(DirectObject):
def acceptSwitchModeEvent(self, button = R_UPPER):
self.accept(self.getEventName(button), self.switchMode)
def ignoreSwitchModeEvent(self, button = R_UPPER):
self.ignore(self.getEventName(button))
@ -208,7 +215,7 @@ class DirectJoybox(DirectObject):
pass
def showMode(self, modeText):
def hideText(state, s = self):
def hideText(state, s=self):
s.readout.setText('')
return Task.done
taskMgr.remove(self.name + '-showMode')
@ -220,6 +227,7 @@ class DirectJoybox(DirectObject):
def acceptUprightCameraEvent(self, button = L_UPPER):
self.accept(self.getEventName(button),
base.direct.cameraControl.orbitUprightCam)
def ignoreUprightCameraEvent(self, button = L_UPPER):
self.ignore(self.getEventName(button))
@ -230,29 +238,29 @@ class DirectJoybox(DirectObject):
self.showMode(self.modeName)
self.enable()
def setUseHeadingNP(self,enabled):
def setUseHeadingNP(self, enabled):
self.useHeadingNP = enabled
def setRotateInPlace(self,enabled):
def setRotateInPlace(self, enabled):
self.rotateInPlace = enabled
def joyboxFly(self):
# Do nothing if no nodePath selected
if self.nodePath is None:
return
hprScale = ((self.aList[L_SLIDE] + 1.0) *
50.0 * DirectJoybox.hprMultiplier)
posScale = ((self.aList[R_SLIDE] + 1.0) *
50.0 * DirectJoybox.xyzMultiplier)
def getAxisVal(index, s = self):
def getAxisVal(index, s=self):
try:
return s.aList[s.mapping[index]]
except IndexError:
# If it is a null axis return 0
return 0.0
x = getAxisVal(0) * self.modifier[0]
y = getAxisVal(1) * self.modifier[1]
z = getAxisVal(2) * self.modifier[2]
@ -262,13 +270,13 @@ class DirectJoybox(DirectObject):
p = getAxisVal(4) * self.modifier[4]
r = getAxisVal(5) * self.modifier[5]
hpr = Vec3(h, p, r) * (hprScale * self.deltaTime)
# if we are using a heading nodepath, we want
# to drive in the direction we are facing,
# however, we don't want the z component to change
if self.useHeadingNP and self.headingNP is not None:
oldZ = pos.getZ()
pos = self.nodePath.getRelativeVector(self.headingNP,
pos)
pos = self.nodePath.getRelativeVector(self.headingNP, pos)
pos.setZ(oldZ)
# if we are using a heading NP we might want to rotate
# in place around that NP
@ -282,7 +290,6 @@ class DirectJoybox(DirectObject):
self.nodePath.wrtReparentTo(parent)
hpr = Vec3(0,0,0)
self.nodePath.setPosHpr(self.nodePath, pos, hpr)
def joeMode(self):
@ -291,25 +298,23 @@ class DirectJoybox(DirectObject):
self.modifier = [1, 1, 1, -1, -1, 0]
self.setMode(self.joyboxFly, 'Joe Mode')
def basicMode(self):
self.mapping = [NULL_AXIS, R_FWD_BACK, NULL_AXIS,
R_LEFT_RIGHT, NULL_AXIS, NULL_AXIS]
self.modifier = [0,1,0,-1,0,0]
self.setMode(self.joyboxFly,'Basic Mode')
self.modifier = [0, 1, 0, -1, 0, 0]
self.setMode(self.joyboxFly, 'Basic Mode')
def fpsMode(self):
self.mapping = [L_LEFT_RIGHT,R_FWD_BACK,L_FWD_BACK,
R_LEFT_RIGHT, NULL_AXIS, NULL_AXIS]
self.modifier = [1,1,1,-1,0,0]
self.setMode(self.joyboxFly,'FPS Mode')
self.modifier = [1, 1, 1, -1, 0, 0]
self.setMode(self.joyboxFly, 'FPS Mode')
def tankMode(self):
self.setMode(self.tankFly,'Tank Mode')
self.setMode(self.tankFly, 'Tank Mode')
def nullMode(self):
self.setMode(self.nullFly,'Null Mode')
self.setMode(self.nullFly, 'Null Mode')
def lucMode(self):
self.mapping = [R_LEFT_RIGHT, R_FWD_BACK, L_FWD_BACK,
@ -362,7 +367,6 @@ class DirectJoybox(DirectObject):
def spaceMode(self):
self.setMode(self.spaceFly, 'Space Mode')
def nullFly(self):
return
@ -384,10 +388,6 @@ class DirectJoybox(DirectObject):
self.nodePath.setH(self.nodePath,dh)
self.nodePath.setY(self.nodePath,dy)
def spaceFly(self):
# Do nothing if no nodePath selected
if self.nodePath is None:
@ -498,9 +498,9 @@ class DirectJoybox(DirectObject):
# Restore the original hpr of the orbiter
self.nodePath.setHpr(self.tempCS, 0, 0, 0)
# We need to override the DirectAnalog normalizeChannel to
# correct the ranges of the two twist axes of the joybox.
def normalizeChannel(self, chan, minVal = -1, maxVal = 1):
try:
if chan == L_TWIST or chan == R_TWIST:

View File

@ -5,6 +5,7 @@ DirectNotify module: this module contains the DirectNotify class
from . import Notifier
from . import Logger
class DirectNotify:
"""
DirectNotify class: this class contains methods for creating
@ -15,7 +16,7 @@ class DirectNotify:
"""
DirectNotify class keeps a dictionary of Notfiers
"""
self.__categories = { }
self.__categories = {}
# create a default log file
self.logger = Logger.Logger()
@ -100,7 +101,6 @@ class DirectNotify:
print("DirectNotify: unknown notify level: " + str(level)
+ " for category: " + str(categoryName))
def setDconfigLevels(self):
for categoryName in self.getCategories():
self.setDconfigLevel(categoryName)

View File

@ -65,6 +65,7 @@ def comment(code):
else:
return ''
def block_comment(code):
code = code.strip()
@ -77,6 +78,7 @@ def block_comment(code):
return code
def translateFunctionName(name):
if name.startswith("__"):
return name
@ -93,6 +95,7 @@ def translateFunctionName(name):
new += i[0].upper() + i[1:]
return new
def translateTypeName(name, mangle=True):
# Equivalent to C++ classNameFromCppName
class_name = ""
@ -115,6 +118,7 @@ def translateTypeName(name, mangle=True):
return class_name
def translated_type_name(type, scoped=True):
while interrogate_type_is_wrapped(type):
if interrogate_type_is_const(type):
@ -205,7 +209,7 @@ def processFunction(handle, function, isConstructor = False):
def processType(handle, type):
typename = translated_type_name(type, scoped=False)
derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ]
derivations = [translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type))]
if interrogate_type_has_comment(type):
print(block_comment(interrogate_type_comment(type)), file=handle)
@ -258,6 +262,7 @@ def processType(handle, type):
print("};", file=handle)
def processModule(handle, package):
print("Processing module %s" % (package))
print("namespace %s {" % package, file=handle)

View File

@ -14,6 +14,7 @@ CAM_MOVE_DURATION = 1.2
COA_MARKER_SF = 0.0075
Y_AXIS = Vec3(0, 1, 0)
class DirectCameraControl(DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory('DirectCameraControl')
@ -351,7 +352,7 @@ class DirectCameraControl(DirectObject):
else:
moveDir = Vec3(Y_AXIS)
if self.useMayaCamControls : # use maya controls
if self.useMayaCamControls: # use maya controls
moveDir.assign(moveDir * ((base.direct.dr.mouseDeltaX -1.0 * base.direct.dr.mouseDeltaY)
* state.zoomSF))
hVal = 0.0
@ -699,7 +700,6 @@ class DirectCameraControl(DirectObject):
name = 'manipulateCamera')
self.__startManipulateCamera(ival = ival)
def zoomCam(self, zoomFactor, t):
self.__stopManipulateCamera()
# Record undo point
@ -769,7 +769,6 @@ class DirectCameraControl(DirectObject):
name = 'manipulateCamera')
self.__startManipulateCamera(ival = ival)
def swingCamAboutWidget(self, degrees, t):
# Remove existing camera manipulation task
self.__stopManipulateCamera()
@ -834,7 +833,6 @@ class DirectCameraControl(DirectObject):
name = 'manipulateCamera')
self.__startManipulateCamera(ival = ival)
def moveToFit(self):
# How big is the active widget?
widgetScale = base.direct.widget.scalingNode.getScale(render)

View File

@ -18,6 +18,7 @@ from .DirectGlobals import Q_EPSILON, UNIT_VEC, ZERO_VEC
from .DirectUtil import CLAMP
import math
class LineNodePath(NodePath):
def __init__(self, parent = None, name = None,
thickness = 1.0, colorVec = VBase4(1)):
@ -140,13 +141,16 @@ class LineNodePath(NodePath):
##
## Given a point in space, and a direction, find the point of intersection
## of that ray with a plane at the specified origin, with the specified normal
def planeIntersect (lineOrigin, lineDir, planeOrigin, normal):
def planeIntersect(lineOrigin, lineDir, planeOrigin, normal):
t = 0
offset = planeOrigin - lineOrigin
t = offset.dot(normal) / lineDir.dot(normal)
hitPt = lineDir * t
return hitPt + lineOrigin
def getNearProjectionPoint(nodePath):
# Find the position of the projection of the specified node path
# on the near plane
@ -158,6 +162,7 @@ def getNearProjectionPoint(nodePath):
# Object is coplaner with camera, just return something reasonable
return Point3(0, base.direct.dr.near, 0)
def getScreenXY(nodePath):
# Where does the node path's projection fall on the near plane
nearVec = getNearProjectionPoint(nodePath)
@ -172,6 +177,7 @@ def getScreenXY(nodePath):
# Return the resulting value
return screenXY
def getCrankAngle(center):
# Used to compute current angle of mouse (relative to the coa's
# origin) in screen space
@ -179,6 +185,7 @@ def getCrankAngle(center):
y = base.direct.dr.mouseY - center[2]
return 180 + rad2Deg(math.atan2(y, x))
def relHpr(nodePath, base, h, p, r):
# Compute nodePath2newNodePath relative to base coordinate system
# nodePath2base
@ -202,6 +209,8 @@ def relHpr(nodePath, base, h, p, r):
nodePath.setHpr(hpr)
# Quaternion interpolation
def qSlerp(startQuat, endQuat, t):
startQ = Quat(startQuat)
destQuat = Quat(Quat.identQuat())

View File

@ -192,8 +192,8 @@ class DirectManipulationControl(DirectObject):
return Task.done
def watchMouseTask(self, state):
if (((abs (state.initX - base.direct.dr.mouseX)) > 0.01) or
((abs (state.initY - base.direct.dr.mouseY)) > 0.01)):
if (abs(state.initX - base.direct.dr.mouseX) > 0.01 or
abs(state.initY - base.direct.dr.mouseY) > 0.01):
taskMgr.remove('manip-move-wait')
self.mode = 'move'
self.manipulateObject()
@ -221,8 +221,8 @@ class DirectManipulationControl(DirectObject):
endX = base.direct.dr.mouseX
endY = base.direct.dr.mouseY
if (((abs (endX - startX)) < 0.01) and
((abs (endY - startY)) < 0.01)):
if (abs(endX - startX) < 0.01 and
abs(endY - startY) < 0.01):
return
self.marquee = LineNodePath(base.render2d, 'marquee', 0.5, VBase4(.8, .6, .6, 1))
@ -1082,6 +1082,7 @@ class DirectManipulationControl(DirectObject):
messenger.send('DIRECT_manipulateObjectCleanup',
[base.direct.selected.getSelectedAsList()])
class ObjectHandles(NodePath, DirectObject):
def __init__(self, name='objectHandles'):
# Initialize the superclass
@ -1754,6 +1755,7 @@ class ObjectHandles(NodePath, DirectObject):
return self.hitPt
def drawBox(lines, center, sideLength):
l = sideLength * 0.5
lines.moveTo(center[0] + l, center[1] + l, center[2] + l)

View File

@ -26,6 +26,8 @@ COA_ORIGIN = 0
COA_CENTER = 1
# MRM: To do: handle broken node paths in selected and deselected dicts
class DirectNodePath(NodePath):
# A node path augmented with info, bounding box, and utility methods
def __init__(self, nodePath, bboxColor=None):
@ -65,6 +67,7 @@ class DirectNodePath(NodePath):
def getMax(self):
return self.bbox.getMax()
class SelectedNodePaths(DirectObject):
def __init__(self):
self.reset()
@ -588,16 +591,16 @@ class SelectionQueue(CollisionHandlerQueue):
# Skip if parented to a camera.
pass
# Can pick unpickable, use the first visible node
elif (skipFlags & DG.SKIP_UNPICKABLE) and\
elif (skipFlags & DG.SKIP_UNPICKABLE) and \
(nodePath.getName() in self.unpickable):
# Skip if in unpickable list
pass
elif base.direct and\
elif base.direct and \
((skipFlags & DG.SKIP_WIDGET) and
(nodePath.getTag('WidgetName') != base.direct.widget.getName())):
# Skip if this widget part is not belong to current widget
pass
elif base.direct and\
elif base.direct and \
((skipFlags & DG.SKIP_WIDGET) and base.direct.fControl and
(nodePath.getName()[2:] == 'ring')):
# Skip when ununiformly scale in ortho view
@ -608,6 +611,7 @@ class SelectionQueue(CollisionHandlerQueue):
break
return self.getCurrentEntry()
class SelectionRay(SelectionQueue):
def __init__(self, parentNP = None):
if parentNP is None:

View File

@ -134,7 +134,6 @@ class DirectSession(DirectObject):
for i in range(len(fastrak))[1:]:
self.fastrak.append(DirectFastrak.DirectFastrak(fastrak[0] + ':' + fastrak[i]))
self.fControl = 0
self.fAlt = 0
self.fShift = 0
@ -293,7 +292,7 @@ class DirectSession(DirectObject):
'shift-a': ('Toggle Vis all', 'DIRECT-toggleVisAll'),
'w': ('Toggle Wireframe', 'DIRECT-toggleWireframe'),
'control-z': ('Undo', 'LE-Undo'),
'shift-z' : ('Redo', 'LE-Redo'),
'shift-z': ('Redo', 'LE-Redo'),
'control-d': ('Duplicate', 'LE-Duplicate'),
'control-l': ('Make Live', 'LE-MakeLive'),
'control-n': ('New Scene', 'LE-NewScene'),
@ -327,7 +326,6 @@ class DirectSession(DirectObject):
self.cluster = DummyClusterClient()
__builtins__['cluster'] = self.cluster
def addPassThroughKey(self,key):
self.passThroughKeys.append(key)
@ -876,6 +874,7 @@ class DirectSession(DirectObject):
# If nothing specified, try selected node path
nodePath = self.selected.last
base.direct.select(nodePath)
def fitTask(state, self = self):
self.cameraControl.fitOnWidget()
return Task.done

View File

@ -23,7 +23,7 @@ class Mopath(DirectObject):
def __init__(self, name = None, fluid = 1, objectToLoad = None, upVectorNodePath = None, reverseUpVector = False):
if name is None:
name = 'mopath%d' % self.nameIndex
name = f'mopath{self.nameIndex}'
self.nameIndex = self.nameIndex + 1
self.name = name
self.fluid = fluid
@ -38,12 +38,12 @@ class Mopath(DirectObject):
self.upVectorNodePath = upVectorNodePath
self.reverseUpVector = reverseUpVector
self.reset()
if isinstance( objectToLoad, NodePath ):
self.loadNodePath( objectToLoad )
elif isinstance( objectToLoad, str ):
self.loadFile( objectToLoad )
if isinstance(objectToLoad, NodePath):
self.loadNodePath(objectToLoad)
elif isinstance(objectToLoad, str):
self.loadFile(objectToLoad)
elif objectToLoad is not None:
print("Mopath: Unable to load object '%s', objectToLoad must be a file name string or a NodePath" % objectToLoad)
print(f"Mopath: Unable to load object '{objectToLoad}', objectToLoad must be a file name string or a NodePath")
def getMaxT(self):
return self.maxT * self.timeScale
@ -70,7 +70,6 @@ class Mopath(DirectObject):
else:
print('Mopath: no valid curves in nodePath: %s' % nodePath)
def reset(self):
self.maxT = 0.0
self.loop = 0

View File

@ -275,31 +275,31 @@ class CompilationEnvironment:
def compileExe(self, filename, basename, extraLink=[]):
compile = self.compileObjExe % dict({
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'suffix64' : self.suffix64,
'MD' : self.MD,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'arch' : self.arch,
'filename' : filename,
'basename' : basename,
'python': self.Python,
'MSVC': self.MSVC,
'PSDK': self.PSDK,
'suffix64': self.suffix64,
'MD': self.MD,
'pythonIPath': self.PythonIPath,
'pythonVersion': self.PythonVersion,
'arch': self.arch,
'filename': filename,
'basename': basename,
}, **sysconf.get_config_vars())
sys.stderr.write(compile + '\n')
if os.system(compile) != 0:
raise Exception('failed to compile %s.' % basename)
link = self.linkExe % dict({
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'suffix64' : self.suffix64,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'arch' : self.arch,
'filename' : filename,
'basename' : basename,
'python': self.Python,
'MSVC': self.MSVC,
'PSDK': self.PSDK,
'suffix64': self.suffix64,
'pythonIPath': self.PythonIPath,
'pythonVersion': self.PythonVersion,
'arch': self.arch,
'filename': filename,
'basename': basename,
}, **sysconf.get_config_vars())
link += ' ' + ' '.join(extraLink)
sys.stderr.write(link + '\n')
@ -308,38 +308,39 @@ class CompilationEnvironment:
def compileDll(self, filename, basename, extraLink=[]):
compile = self.compileObjDll % dict({
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'suffix64' : self.suffix64,
'MD' : self.MD,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'arch' : self.arch,
'filename' : filename,
'basename' : basename,
'python': self.Python,
'MSVC': self.MSVC,
'PSDK': self.PSDK,
'suffix64': self.suffix64,
'MD': self.MD,
'pythonIPath': self.PythonIPath,
'pythonVersion': self.PythonVersion,
'arch': self.arch,
'filename': filename,
'basename': basename,
}, **sysconf.get_config_vars())
sys.stderr.write(compile + '\n')
if os.system(compile) != 0:
raise Exception('failed to compile %s.' % basename)
link = self.linkDll % dict({
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'suffix64' : self.suffix64,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'arch' : self.arch,
'filename' : filename,
'basename' : basename,
'dllext' : self.dllext,
'python': self.Python,
'MSVC': self.MSVC,
'PSDK': self.PSDK,
'suffix64': self.suffix64,
'pythonIPath': self.PythonIPath,
'pythonVersion': self.PythonVersion,
'arch': self.arch,
'filename': filename,
'basename': basename,
'dllext': self.dllext,
}, **sysconf.get_config_vars())
link += ' ' + ' '.join(extraLink)
sys.stderr.write(link + '\n')
if os.system(link) != 0:
raise Exception('failed to link %s.' % basename)
# The code from frozenmain.c in the Python source repository.
frozenMainCode = """
/* Python interpreter main program for frozen scripts */
@ -675,7 +676,7 @@ okMissing = [
'direct.extensions_native.extensions_darwin', '_manylinux',
'collections.Iterable', 'collections.Mapping', 'collections.MutableMapping',
'collections.Sequence', 'numpy_distutils', '_winapi',
]
]
# Since around macOS 10.15, Apple's codesigning process has become more strict.
# Appending data to the end of a Mach-O binary is now explicitly forbidden. The
@ -722,6 +723,7 @@ lc_indices_to_slide = {
LC_DATA_IN_CODE: [2],
}
class Freezer:
class ModuleDef:
def __init__(self, moduleName, filename = None,
@ -1141,7 +1143,7 @@ class Freezer:
if mdef.implicit and '.' in newName:
# For implicit modules, check if the parent is excluded.
parentName, baseName = newName.rsplit('.', 1)
if parentName in excludeDict :
if parentName in excludeDict:
mdef = excludeDict[parentName]
if mdef.exclude:
@ -1182,7 +1184,7 @@ class Freezer:
self.__loadModule(mdef)
# Since it successfully loaded, it's no longer a guess.
mdef.guess = False
except:
except Exception:
# Something went wrong, guess it's not an importable
# module.
pass
@ -1220,7 +1222,7 @@ class Freezer:
try:
self.__loadModule(self.ModuleDef(modname, implicit=True))
except:
except Exception:
missing.append(modname)
# Now, any new modules we found get added to the export list.
@ -1697,10 +1699,10 @@ class Freezer:
if self.platform.startswith('win'):
code += self.frozenDllMainCode
initCode = self.mainInitCode % {
'frozenMainCode' : code,
'programName' : os.path.basename(basename),
'dllexport' : dllexport,
'dllimport' : dllimport,
'frozenMainCode': code,
'programName': os.path.basename(basename),
'dllexport': dllexport,
'dllimport': dllimport,
}
if self.platform.startswith('win'):
target = basename + '.exe'
@ -1716,9 +1718,9 @@ class Freezer:
target = basename + '.so'
initCode = dllInitCode % {
'moduleName' : os.path.basename(basename),
'dllexport' : dllexport,
'dllimport' : dllimport,
'moduleName': os.path.basename(basename),
'dllexport': dllexport,
'dllimport': dllimport,
}
compileFunc = self.cenv.compileDll
@ -2357,7 +2359,6 @@ class Freezer:
def makeForbiddenModuleListEntry(self, moduleName):
return ' {"%s", NULL, 0},' % (moduleName)
def __writingModule(self, moduleName):
""" Returns true if we are outputting the named module in this
pass, false if we have already output in a previous pass, or

View File

@ -28,6 +28,7 @@ def _unpack_zstring(mem, offs=0):
c = mem[offs]
return str
def _unpack_wstring(mem, offs=0):
"Read a UCS-2 string from memory."
name_len, = unpack('<H', mem[offs:offs+2])
@ -37,6 +38,7 @@ def _unpack_wstring(mem, offs=0):
name += chr(*unpack('<H', mem[offs:offs+2]))
return name
def _padded(n, boundary):
align = n % boundary
if align:

View File

@ -122,7 +122,7 @@ class ClientRepositoryBase(ConnectionRepository):
def _getMsgName(self, msgId):
# we might get a list of message names, use the first one
return makeList(MsgId2Names.get(msgId, 'UNKNOWN MESSAGE: %s' % msgId))[0]
return makeList(MsgId2Names.get(msgId, f'UNKNOWN MESSAGE: {msgId}'))[0]
def allocateContext(self):
self.context+=1
@ -161,7 +161,7 @@ class ClientRepositoryBase(ConnectionRepository):
# Look up the dclass
assert parentId == self.GameGlobalsId or parentId in self.doId2do
dclass = self.dclassesByNumber[classId]
assert self.notify.debug("performing generate for %s %s" % (dclass.getName(), doId))
assert self.notify.debug(f"performing generate for {dclass.getName()} {doId}")
dclass.startGenerate()
# Create a new distributed object, and put it in the dictionary
distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId)
@ -360,7 +360,6 @@ class ClientRepositoryBase(ConnectionRepository):
# updateRequiredOtherFields calls announceGenerate
return distObj
def disableDoId(self, doId, ownerView=False):
table, cache = self.getTables(ownerView)
# Make sure the object exists
@ -442,7 +441,6 @@ class ClientRepositoryBase(ConnectionRepository):
# This object has been fully generated. It's OK to update.
self.__doUpdate(doId, di, ovUpdated)
def __doUpdate(self, doId, di, ovUpdated):
# Find the DO
do = self.doId2do.get(doId)
@ -463,13 +461,12 @@ class ClientRepositoryBase(ConnectionRepository):
if handle:
dclass = self.dclassesByName[handle.dclassName]
dclass.receiveUpdate(handle, di)
else:
self.notify.warning(
"Asked to update non-existent DistObj " + str(doId))
except:
f"Asked to update non-existent DistObj {doId}")
except Exception:
self.notify.warning(
"Asked to update non-existent DistObj " + str(doId) + "and failed to find it")
f"Asked to update non-existent DistObj {doId} and failed to find it")
def __doUpdateOwner(self, doId, di):
ovObj = self.doId2ownerView.get(doId)
@ -488,7 +485,7 @@ class ClientRepositoryBase(ConnectionRepository):
self.bootedText = di.getString()
self.notify.warning(
"Server is booting us out (%d): %s" % (self.bootedIndex, self.bootedText))
f"Server is booting us out ({self.bootedIndex}): {self.bootedText}")
else:
self.bootedIndex = None
self.bootedText = None
@ -536,7 +533,6 @@ class ClientRepositoryBase(ConnectionRepository):
doDict[doId] = do
return doDict
def considerHeartbeat(self):
"""Send a heartbeat message if we haven't sent one recently."""
if not self.heartbeatStarted:
@ -566,7 +562,7 @@ class ClientRepositoryBase(ConnectionRepository):
def waitForNextHeartBeat(self):
taskMgr.doMethodLater(self.heartbeatInterval, self.sendHeartbeatTask,
"heartBeat", taskChain = 'net')
"heartBeat", taskChain='net')
def replaceMethod(self, oldMethod, newFunction):
return 0

View File

@ -13,6 +13,7 @@ import gc
__all__ = ["ConnectionRepository", "GCTrigger"]
class ConnectionRepository(
DoInterestManager, DoCollectionManager, CConnectionRepository):
"""
@ -589,7 +590,7 @@ class ConnectionRepository(
if self.http is None:
try:
self.http = HTTPClient()
except:
except Exception:
pass
return self.http
@ -667,6 +668,7 @@ class ConnectionRepository(
def uniqueName(self, idString):
return "%s-%s" % (idString, self.uniqueId)
class GCTrigger:
# used to trigger garbage collection
pass

View File

@ -24,7 +24,7 @@ ESNum2Str = {
ESDisabled: 'ESDisabled',
ESGenerating: 'ESGenerating',
ESGenerated: 'ESGenerated',
}
}
class DistributedObject(DistributedObjectBase):
@ -240,7 +240,6 @@ class DistributedObject(DistributedObjectBase):
"""
assert self.notify.debug('announceGenerate(): %s' % (self.doId))
def _deactivateDO(self):
# after this is called, the object is no longer an active DistributedObject
# and it may be placed in the cache
@ -324,9 +323,9 @@ class DistributedObject(DistributedObjectBase):
"""
return self.doId
#This message was moved out of announce generate
#to avoid ordering issues.
def postGenerateMessage(self):
if self.activeState != ESGenerated:
self.activeState = ESGenerated

View File

@ -36,6 +36,8 @@ PredictionLag = ConfigVariableDouble("smooth-prediction-lag", 0.0)
GlobalSmoothing = 0
GlobalPrediction = 0
def globalActivateSmoothing(smoothing, prediction):
""" Globally activates or deactivates smoothing and prediction on
all DistributedSmoothNodes currently in existence, or yet to be
@ -48,6 +50,7 @@ def globalActivateSmoothing(smoothing, prediction):
for obj in base.cr.getAllOfType(DistributedSmoothNode):
obj.activateSmoothing(smoothing, prediction)
# For historical reasons, we temporarily define
# DistributedSmoothNode.activateSmoothing() to be the global function.
# We'll remove this soon, so it won't get confused with the instance
@ -154,6 +157,7 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
def setSmoothWrtReparents(self, flag):
self._smoothWrtReparents = flag
def getSmoothWrtReparents(self):
return self._smoothWrtReparents
@ -213,42 +217,50 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
def setSmStop(self, timestamp=None):
self.setComponentTLive(timestamp)
self.stopped = True
def setSmH(self, h, timestamp=None):
self._checkResume(timestamp)
self.setComponentH(h)
self.setComponentTLive(timestamp)
def setSmZ(self, z, timestamp=None):
self._checkResume(timestamp)
self.setComponentZ(z)
self.setComponentTLive(timestamp)
def setSmXY(self, x, y, timestamp=None):
self._checkResume(timestamp)
self.setComponentX(x)
self.setComponentY(y)
self.setComponentTLive(timestamp)
def setSmXZ(self, x, z, timestamp=None):
self._checkResume(timestamp)
self.setComponentX(x)
self.setComponentZ(z)
self.setComponentTLive(timestamp)
def setSmPos(self, x, y, z, timestamp=None):
self._checkResume(timestamp)
self.setComponentX(x)
self.setComponentY(y)
self.setComponentZ(z)
self.setComponentTLive(timestamp)
def setSmHpr(self, h, p, r, timestamp=None):
self._checkResume(timestamp)
self.setComponentH(h)
self.setComponentP(p)
self.setComponentR(r)
self.setComponentTLive(timestamp)
def setSmXYH(self, x, y, h, timestamp):
self._checkResume(timestamp)
self.setComponentX(x)
self.setComponentY(y)
self.setComponentH(h)
self.setComponentTLive(timestamp)
def setSmXYZH(self, x, y, z, h, timestamp=None):
self._checkResume(timestamp)
self.setComponentX(x)
@ -256,6 +268,7 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
self.setComponentZ(z)
self.setComponentH(h)
self.setComponentTLive(timestamp)
def setSmPosHpr(self, x, y, z, h, p, r, timestamp=None):
self._checkResume(timestamp)
self.setComponentX(x)
@ -285,26 +298,33 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentX(self, x):
self.smoother.setX(x)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentY(self, y):
self.smoother.setY(y)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentZ(self, z):
self.smoother.setZ(z)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentH(self, h):
self.smoother.setH(h)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentP(self, p):
self.smoother.setP(p)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentR(self, r):
self.smoother.setR(r)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentL(self, l):
if l != self.zoneId:
# only perform set location if location is different
self.setLocation(self.parentId,l)
@report(types = ['args'], dConfigParam = 'smoothnode')
def setComponentT(self, timestamp):
# This is a little bit hacky. If *this* function is called,
@ -387,18 +407,25 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
# match set* in more cases than the Disney server does.
def getComponentL(self):
return self.zoneId
def getComponentX(self):
return self.getX()
def getComponentY(self):
return self.getY()
def getComponentZ(self):
return self.getZ()
def getComponentH(self):
return self.getH()
def getComponentP(self):
return self.getP()
def getComponentR(self):
return self.getR()
def getComponentT(self):
return 0
@ -409,7 +436,6 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
#printStack()
self.smoother.clearPositions(1)
@report(types = ['args'], dConfigParam = 'smoothnode')
def wrtReparentTo(self, parent):
# We override this NodePath method to force it to
@ -476,7 +502,6 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
serverTime,
globalClockDelta.getUncertainty())
def d_returnResync(self, avId, timestampB, serverTime, uncertainty):
serverTimeSec = math.floor(serverTime)
serverTimeUSec = (serverTime - serverTimeSec) * 10000.0

View File

@ -13,8 +13,10 @@ class DummyTaskClass:
def setDelay(self, blah):
pass
DummyTask = DummyTaskClass()
class DistributedSmoothNodeBase:
"""common base class for DistributedSmoothNode and DistributedSmoothNodeAI
"""
@ -43,6 +45,7 @@ class DistributedSmoothNodeBase:
def b_clearSmoothing(self):
self.d_clearSmoothing()
self.clearSmoothing()
def d_clearSmoothing(self):
self.sendUpdate("clearSmoothing", [0])

View File

@ -137,7 +137,7 @@ MsgName2Id = {
'CLIENTAGENT_ADD_INTEREST': 1200,
'CLIENTAGENT_ADD_INTEREST_MULTIPLE': 1201,
'CLIENTAGENT_REMOVE_INTEREST': 1203,
}
}
# create id->name table for debugging
MsgId2Names = invertDictLossless(MsgName2Id)
@ -157,7 +157,7 @@ QUIET_ZONE_IGNORED_LIST = [
#CLIENT_CREATE_OBJECT_REQUIRED,
#CLIENT_CREATE_OBJECT_REQUIRED_OTHER,
]
]
# The following is a different set of numbers from above.
# These are the sub-message types for CLIENT_LOGIN_2.

View File

@ -20,7 +20,7 @@ MsgName2Id = {
'CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU' : 9011,
'CLIENT_OBJECT_UPDATE_FIELD' : 120, # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD
}
}
# create id->name table for debugging
MsgId2Names = invertDictLossless(MsgName2Id)

View File

@ -351,7 +351,7 @@ class CommonFilters:
text += "{\n"
text += " o_color = tex2D(k_txcolor, %s);\n" % (texcoords["color"])
if "CartoonInk" in configuration:
text += CARTOON_BODY % {"texcoord" : texcoords["aux"]}
text += CARTOON_BODY % {"texcoord": texcoords["aux"]}
if "AmbientOcclusion" in configuration:
text += " o_color *= tex2D(k_txssao2, %s).r;\n" % (texcoords["ssao2"])
if "BlurSharpen" in configuration:

View File

@ -150,7 +150,6 @@ class ClassicFSM(DirectObject):
def getCurrentState(self):
return self.__currentState
# lookup funcs
def getStateNamed(self, stateName):
@ -315,7 +314,6 @@ class ClassicFSM(DirectObject):
ClassicFSM.notify.warning(msg)
return 0
def forceTransition(self, aStateName, enterArgList=[], exitArgList=[]):
"""
force a transition -- for debugging ONLY

View File

@ -10,11 +10,13 @@ from panda3d.core import Mat4, MouseButton, PGButton
from . import DirectGuiGlobals as DGG
from .DirectFrame import DirectFrame
class DirectButton(DirectFrame):
"""
DirectButton(parent) - Create a DirectGuiWidget which responds
to mouse clicks and execute a callback function if defined
"""
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
# A Direct Frame can have:

View File

@ -10,6 +10,7 @@ class DirectCheckBox(DirectButton):
Uses an image swap rather than a text change to indicate state.
"""
def __init__(self, parent = None, **kw):
optiondefs = (
@ -42,7 +43,6 @@ class DirectCheckBox(DirectButton):
self.initialiseoptions(DirectCheckBox)
def commandFunc(self, event):
self['isChecked'] = not self['isChecked']

View File

@ -12,12 +12,14 @@ from panda3d.core import PGFrameStyle, VBase4
from .DirectButton import DirectButton
from .DirectLabel import DirectLabel
class DirectCheckButton(DirectButton):
"""
DirectCheckButton(parent) - Create a DirectGuiWidget which responds
to mouse clicks by setting a state of on or off and execute a callback
function (passing that state through) if defined
"""
def __init__(self, parent = None, **kw):
# Inherits from DirectButton
# A Direct Frame can have:
@ -167,7 +169,6 @@ class DirectCheckButton(DirectButton):
self.indicator.setPos(newpos[0], newpos[1], newpos[2])
def commandFunc(self, event):
self['indicatorValue'] = 1 - self['indicatorValue']
if self.colors is not None:

View File

@ -356,6 +356,7 @@ class DirectDialog(DirectFrame):
button.destroy()
DirectFrame.destroy(self)
class OkDialog(DirectDialog):
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
@ -369,6 +370,7 @@ class OkDialog(DirectDialog):
DirectDialog.__init__(self, parent)
self.initialiseoptions(OkDialog)
class OkCancelDialog(DirectDialog):
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
@ -382,6 +384,7 @@ class OkCancelDialog(DirectDialog):
DirectDialog.__init__(self, parent)
self.initialiseoptions(OkCancelDialog)
class YesNoDialog(DirectDialog):
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
@ -395,6 +398,7 @@ class YesNoDialog(DirectDialog):
DirectDialog.__init__(self, parent)
self.initialiseoptions(YesNoDialog)
class YesNoCancelDialog(DirectDialog):
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
@ -409,6 +413,7 @@ class YesNoCancelDialog(DirectDialog):
DirectDialog.__init__(self, parent)
self.initialiseoptions(YesNoCancelDialog)
class RetryCancelDialog(DirectDialog):
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame

View File

@ -21,6 +21,7 @@ ENTRY_FOCUS_STATE = PGEntry.SFocus # 0
ENTRY_NO_FOCUS_STATE = PGEntry.SNoFocus # 1
ENTRY_INACTIVE_STATE = PGEntry.SInactive # 2
class DirectEntry(DirectFrame):
"""
DirectEntry(parent) - Create a DirectGuiWidget which responds
@ -215,6 +216,7 @@ class DirectEntry(DirectFrame):
def _handleTyping(self, guiEvent):
self._autoCapitalize()
def _handleErasing(self, guiEvent):
self._autoCapitalize()

View File

@ -80,7 +80,6 @@ class DirectEntryScroll(DirectFrame):
if abs(distanceToCenter) > (clipExtent * 0.5):
self.moveToCenterCursor()
def moveToCenterCursor(self):
cursorX = self.entry.guiItem.getCursorX() * self.entry['text_scale'][0]
canvasX = self.canvas.getX()
@ -121,7 +120,6 @@ class DirectEntryScroll(DirectFrame):
self.entry = None
DirectFrame.destroy(self)
def getCanvas(self):
return self.canvas

View File

@ -659,9 +659,11 @@ class DirectGuiBase(DirectObject.DirectObject):
gEvent = event + self.guiId
self.ignore(gEvent)
def toggleGuiGridSnap():
DirectGuiWidget.snapToGrid = 1 - DirectGuiWidget.snapToGrid
def setGuiGridSpacing(spacing):
DirectGuiWidget.gridSpacing = spacing
@ -911,7 +913,6 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
self.bounds[2] - bw[1],
self.bounds[3] + bw[1])
def getBounds(self, state = 0):
self.stateNodePath[state].calcTightBounds(self.ll, self.ur)
# Scale bounds to give a pad around graphics

View File

@ -9,11 +9,13 @@ __all__ = ['DirectLabel']
from panda3d.core import PGItem
from .DirectFrame import DirectFrame
class DirectLabel(DirectFrame):
"""
DirectLabel(parent) - Create a DirectGuiWidget which has multiple
states. User explicitly chooses a state to display
"""
def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
# A Direct Frame can have:

View File

@ -21,6 +21,7 @@ class DirectOptionMenu(DirectButton):
To cancel the popup menu click anywhere on the screen outside of the
popup menu. No command is executed in this case.
"""
def __init__(self, parent = None, **kw):
# Inherits from DirectButton
optiondefs = (

View File

@ -14,12 +14,14 @@ from . import DirectGuiGlobals as DGG
from .DirectButton import DirectButton
from .DirectLabel import DirectLabel
class DirectRadioButton(DirectButton):
"""
DirectRadioButton(parent) - Create a DirectGuiWidget which responds
to mouse clicks by setting given value to given variable and
execute a callback function (passing that state through) if defined
"""
def __init__(self, parent = None, **kw):
# Inherits from DirectButton
# A Direct Frame can have:
@ -194,7 +196,6 @@ class DirectRadioButton(DirectButton):
self.indicator.setPos(newpos[0], newpos[1], newpos[2])
def commandFunc(self, event):
if len(self['value']) == len(self['variable']) != 0:
for i in range(len(self['value'])):

View File

@ -17,6 +17,7 @@ class DirectScrollBar(DirectFrame):
DirectScrollBar -- a widget which represents a scroll bar the user can
use for paging through a large document or panel.
"""
def __init__(self, parent = None, **kw):
optiondefs = (
# Define type of DirectGuiWidget

View File

@ -24,6 +24,7 @@ class DirectScrolledFrame(DirectFrame):
0 and explicitly position and hide or show the scroll bars
yourself.
"""
def __init__(self, parent = None, **kw):
optiondefs = (
# Define type of DirectGuiWidget

View File

@ -198,7 +198,7 @@ class DirectScrolledList(DirectFrame):
#print "scrollTo[", index,"] called, len(self[items])=", len(self["items"])," self[numItemsVisible]=", self["numItemsVisible"]
try:
self["numItemsVisible"]
except:
except Exception:
# RAU hack to kill 27633
self.notify.info('crash 27633 fixed!')
return

View File

@ -18,6 +18,7 @@ class DirectSlider(DirectFrame):
DirectSlider -- a widget which represents a slider that the
user can pull left and right to represent a continuous value.
"""
def __init__(self, parent = None, **kw):
optiondefs = (
# Define type of DirectGuiWidget

View File

@ -20,6 +20,7 @@ ScreenPrompt = 3
NameConfirm = 4
BlackOnWhite = 5
class OnscreenText(NodePath):
def __init__(self, text = '',

View File

@ -15,8 +15,8 @@ from .IndirectInterval import *
from .MopathInterval import *
try:
import panda3d.physics
##Some people may have the particle system compiled out
if hasattr( panda3d.physics, 'ParticleSystem' ):
# Some people may have the particle system compiled out
if hasattr(panda3d.physics, 'ParticleSystem'):
from .ParticleInterval import *
if __debug__:
from .TestInterval import *

View File

@ -10,7 +10,7 @@ __all__ = [
'LerpColorInterval', 'LerpColorScaleInterval',
'LerpTexOffsetInterval', 'LerpTexRotateInterval', 'LerpTexScaleInterval',
'LerpFunctionInterval', 'LerpFunc','LerpFunctionNoStateInterval','LerpFuncNS'
]
]
from panda3d.core import LOrientationf, NodePath
from panda3d.direct import CInterval, CLerpNodePathInterval
@ -25,6 +25,7 @@ from . import LerpBlendHelpers
# performance.
#
class LerpNodePathInterval(CLerpNodePathInterval):
# This is the base class for all of the lerps, defined below, that
# affect a property on a NodePath, like pos or hpr.
@ -99,6 +100,7 @@ class LerpNodePathInterval(CLerpNodePathInterval):
##
#####################################################################
class LerpPosInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, startPos = None,
other = None, blendType = 'noBlend',
@ -157,6 +159,7 @@ class LerpHprInterval(LerpNodePathInterval):
self.setupParam(self.setStartQuat, self.startQuat)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpQuatInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, quat = None,
startHpr = None, startQuat = None,
@ -195,6 +198,7 @@ class LerpQuatInterval(LerpNodePathInterval):
self.setupParam(self.setStartQuat, self.startQuat)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, scale, startScale = None,
other = None, blendType = 'noBlend',
@ -220,6 +224,7 @@ class LerpScaleInterval(LerpNodePathInterval):
self.setupParam(self.setStartScale, self.startScale)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpShearInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, shear, startShear = None,
other = None, blendType = 'noBlend',
@ -245,6 +250,7 @@ class LerpShearInterval(LerpNodePathInterval):
self.setupParam(self.setStartShear, self.startShear)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpPosHprInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, hpr,
startPos = None, startHpr = None, startQuat = None,
@ -282,6 +288,7 @@ class LerpPosHprInterval(LerpNodePathInterval):
self.setupParam(self.setStartQuat, self.startQuat)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpPosQuatInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, quat = None,
startPos = None, startHpr = None, startQuat = None,
@ -327,6 +334,7 @@ class LerpPosQuatInterval(LerpNodePathInterval):
self.setupParam(self.setStartQuat, self.startQuat)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpHprScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, hpr, scale,
startHpr = None, startQuat = None, startScale = None,
@ -365,6 +373,7 @@ class LerpHprScaleInterval(LerpNodePathInterval):
self.setupParam(self.setStartScale, self.startScale)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpQuatScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, quat = None, scale = None,
hpr = None,
@ -413,6 +422,7 @@ class LerpQuatScaleInterval(LerpNodePathInterval):
self.setupParam(self.setStartScale, self.startScale)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpPosHprScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, hpr, scale,
startPos = None, startHpr = None, startQuat = None,
@ -459,6 +469,7 @@ class LerpPosHprScaleInterval(LerpNodePathInterval):
self.setupParam(self.setStartScale, self.startScale)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpPosQuatScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, quat = None, scale = None,
startPos = None, startHpr = None, startQuat = None,
@ -515,6 +526,7 @@ class LerpPosQuatScaleInterval(LerpNodePathInterval):
self.setupParam(self.setStartScale, self.startScale)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpPosHprScaleShearInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, hpr, scale, shear,
startPos = None, startHpr = None, startQuat = None,
@ -569,6 +581,7 @@ class LerpPosHprScaleShearInterval(LerpNodePathInterval):
self.setupParam(self.setStartShear, self.startShear)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpPosQuatScaleShearInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, pos, quat = None, scale = None,
shear = None,
@ -635,6 +648,7 @@ class LerpPosQuatScaleShearInterval(LerpNodePathInterval):
self.setupParam(self.setStartShear, self.startShear)
LerpNodePathInterval.privDoEvent(self, t, event)
class LerpColorInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, color, startColor = None,
other = None, blendType = 'noBlend',
@ -647,6 +661,7 @@ class LerpColorInterval(LerpNodePathInterval):
if override is not None:
self.setOverride(override)
class LerpColorScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, colorScale, startColorScale = None,
other = None, blendType = 'noBlend',
@ -659,6 +674,7 @@ class LerpColorScaleInterval(LerpNodePathInterval):
if override is not None:
self.setOverride(override)
class LerpTexOffsetInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, texOffset, startTexOffset = None,
other = None, blendType = 'noBlend',
@ -674,6 +690,7 @@ class LerpTexOffsetInterval(LerpNodePathInterval):
if override is not None:
self.setOverride(override)
class LerpTexRotateInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, texRotate, startTexRotate = None,
other = None, blendType = 'noBlend',
@ -689,6 +706,7 @@ class LerpTexRotateInterval(LerpNodePathInterval):
if override is not None:
self.setOverride(override)
class LerpTexScaleInterval(LerpNodePathInterval):
def __init__(self, nodePath, duration, texScale, startTexScale = None,
other = None, blendType = 'noBlend',
@ -705,8 +723,6 @@ class LerpTexScaleInterval(LerpNodePathInterval):
self.setOverride(override)
#
# The remaining intervals defined in this module are the old-school
# Python-based intervals.
@ -733,6 +749,7 @@ class LerpFunctionNoStateInterval(Interval.Interval):
# create LerpFunctionInterval DirectNotify category
notify = directNotify.newCategory('LerpFunctionNoStateInterval')
# Class methods
def __init__(self, function, duration = 0.0, fromData = 0, toData = 1,
blendType = 'noBlend', extraArgs = [], name = None):
"""__init__(function, duration, fromData, toData, name)
@ -758,9 +775,8 @@ class LerpFunctionNoStateInterval(Interval.Interval):
# Initialize superclass
Interval.Interval.__init__(self, name, duration)
#def privDoEvent(self,t,event):
#print "doing event",t,event
#def privDoEvent(self, t, event):
#print("doing event", t, event)
#bt = self.blendType(t/self.duration)
#data = (self.fromData * (1 - bt)) + (self.toData * bt)
## Evaluate function
@ -770,7 +786,7 @@ class LerpFunctionNoStateInterval(Interval.Interval):
def privStep(self, t):
# Evaluate the function
#print "doing priv step",t
#print("doing priv step", t)
if t >= self.duration:
# Set to end value
if t > self.duration:
@ -787,12 +803,14 @@ class LerpFunctionNoStateInterval(Interval.Interval):
self.function(*[data] + self.extraArgs)
# Print debug information
# assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
#assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
self.state = CInterval.SStarted
self.currT = t
# New interface
class LerpFuncNS(LerpFunctionNoStateInterval):
def __init__(self, *args, **kw):
LerpFunctionNoStateInterval.__init__(self, *args, **kw)
@ -810,6 +828,7 @@ class LerpFunctionInterval(Interval.Interval):
# create LerpFunctionInterval DirectNotify category
notify = directNotify.newCategory('LerpFunctionInterval')
# Class methods
def __init__(self, function, duration = 0.0, fromData = 0, toData = 1,
blendType = 'noBlend', extraArgs = [], name = None):
"""__init__(function, duration, fromData, toData, name)
@ -838,7 +857,7 @@ class LerpFunctionInterval(Interval.Interval):
def privStep(self, t):
# Evaluate the function
#print "doing priv step",t
#print("doing priv step", t)
if t >= self.duration:
# Set to end value
self.function(*[self.toData] + self.extraArgs)
@ -853,12 +872,14 @@ class LerpFunctionInterval(Interval.Interval):
self.function(*[data] + self.extraArgs)
# Print debug information
# assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
#assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
self.state = CInterval.SStarted
self.currT = t
# New interface
class LerpFunc(LerpFunctionInterval):
def __init__(self, *args, **kw):
LerpFunctionInterval.__init__(self, *args, **kw)

View File

@ -25,23 +25,23 @@ class AnimMgrBase:
#normal properties
self.lerpFuncs = {
'H' : self.lerpFuncH,
'P' : self.lerpFuncP,
'R' : self.lerpFuncR,
'SX' : self.lerpFuncSX,
'SY' : self.lerpFuncSY,
'SZ' : self.lerpFuncSZ,
'CR' : self.lerpFuncCR,
'CG' : self.lerpFuncCG,
'CB' : self.lerpFuncCB,
'CA' : self.lerpFuncCA
'H': self.lerpFuncH,
'P': self.lerpFuncP,
'R': self.lerpFuncR,
'SX': self.lerpFuncSX,
'SY': self.lerpFuncSY,
'SZ': self.lerpFuncSZ,
'CR': self.lerpFuncCR,
'CG': self.lerpFuncCG,
'CB': self.lerpFuncCB,
'CA': self.lerpFuncCA
}
#Properties which has animation curves
self.curveLerpFuncs = {
'X' : [ self.lerpFuncX, self.lerpCurveFuncX ],
'Y' : [ self.lerpFuncY, self.lerpCurveFuncY ],
'Z' : [ self.lerpFuncZ, self.lerpCurveFuncZ ]
'X': [self.lerpFuncX, self.lerpCurveFuncX],
'Y': [self.lerpFuncY, self.lerpCurveFuncY],
'Z': [self.lerpFuncZ, self.lerpCurveFuncZ]
}
def reset(self):

View File

@ -10,6 +10,7 @@ class CurveAnimUI(wx.Dialog):
"""
This is the Curve Animation Panel implementation.
"""
def __init__(self, parent, editor):
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Curve Animation",
pos=wx.DefaultPosition, size=(430, 140))
@ -20,19 +21,19 @@ class CurveAnimUI(wx.Dialog):
self.mainPanel = wx.Panel(self, -1)
self.chooseNode = wx.StaticText( self.mainPanel, -1, "Choose NodePath:")
self.chooseNodeTxt = wx.TextCtrl( self.mainPanel, -1, "")
self.chooseNodeButton = wx.Button( self.mainPanel, -1, "Choose..")
self.chooseNode = wx.StaticText(self.mainPanel, -1, "Choose NodePath:")
self.chooseNodeTxt = wx.TextCtrl(self.mainPanel, -1, "")
self.chooseNodeButton = wx.Button(self.mainPanel, -1, "Choose..")
self.chooseCurve = wx.StaticText( self.mainPanel, -1, "Choose attch Curve:")
self.chooseCurveTxt = wx.TextCtrl( self.mainPanel, -1, "")
self.chooseCurveButton = wx.Button( self.mainPanel, -1, "Choose..")
self.chooseCurve = wx.StaticText(self.mainPanel, -1, "Choose attch Curve:")
self.chooseCurveTxt = wx.TextCtrl(self.mainPanel, -1, "")
self.chooseCurveButton = wx.Button(self.mainPanel, -1, "Choose..")
self.duritionTime = wx.StaticText( self.mainPanel, -1, "Durition(Frame):")
self.duritionTimeSpin = wx.SpinCtrl( self.mainPanel, -1, "",size = (70,25), min=24, max=10000)
self.duritionTime = wx.StaticText(self.mainPanel, -1, "Durition(Frame):")
self.duritionTimeSpin = wx.SpinCtrl(self.mainPanel, -1, "", size=(70,25), min=24, max=10000)
self.createAnimButton = wx.Button( self.mainPanel, -1, "Creat")
self.saveAnimButton = wx.Button( self.mainPanel, -1, "Save Animation")
self.createAnimButton = wx.Button(self.mainPanel, -1, "Creat")
self.saveAnimButton = wx.Button(self.mainPanel, -1, "Save Animation")
self.SetProperties()
self.DoLayout()
@ -46,44 +47,44 @@ class CurveAnimUI(wx.Dialog):
def SetProperties(self):
self.duritionTimeSpin.SetValue(24)
self.chooseNodeTxt.SetMinSize((200,21))
self.chooseCurveTxt.SetMinSize((200,21))
self.chooseNodeTxt.SetMinSize((200, 21))
self.chooseCurveTxt.SetMinSize((200, 21))
self.saveAnimButton.SetToolTipString("Save the animation to the global animation control")
def DoLayout(self):
dialogSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer = wx.FlexGridSizer(4, 3, 0, 0)
mainSizer.Add(self.chooseNode, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
mainSizer.Add(self.chooseNodeTxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.chooseNodeButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.chooseNode, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)
mainSizer.Add(self.chooseNodeTxt, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(self.chooseNodeButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(self.chooseCurve, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
mainSizer.Add(self.chooseCurveTxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.chooseCurveButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.chooseCurve, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)
mainSizer.Add(self.chooseCurveTxt, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(self.chooseCurveButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(self.duritionTime, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
mainSizer.Add(self.duritionTimeSpin, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.createAnimButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.duritionTime, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)
mainSizer.Add(self.duritionTimeSpin, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(self.createAnimButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(self.saveAnimButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
mainSizer.Add(self.saveAnimButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
self.mainPanel.SetSizerAndFit(mainSizer)
dialogSizer.Add(self.mainPanel, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
dialogSizer.Add(self.mainPanel, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
self.SetSizer(dialogSizer)
self.Layout()
def OnChooseNode(self, evt):
if base.direct.selected.last is None or base.direct.selected.last.hasTag('Controller') or not base.direct.selected.last.hasTag('OBJRoot'):
dlg = wx.MessageDialog(None, 'Please select an object.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select an object.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
else:
obj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
if obj[OG.OBJ_DEF].name == '__Curve__':
dlg = wx.MessageDialog(None, 'Please select an object, not a curve.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select an object, not a curve.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
else:
@ -92,13 +93,13 @@ class CurveAnimUI(wx.Dialog):
def OnChooseCurve(self, evt):
if base.direct.selected.last is None or base.direct.selected.last.hasTag('Controller') or not base.direct.selected.last.hasTag('OBJRoot'):
dlg = wx.MessageDialog(None, 'Please select a curve.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select a curve.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
else:
obj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
if obj[OG.OBJ_DEF].name != '__Curve__':
dlg = wx.MessageDialog(None, 'Please select a curve, not an object.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select a curve, not an object.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
elif obj[OG.OBJ_DEF].name == '__Curve__':
@ -108,43 +109,45 @@ class CurveAnimUI(wx.Dialog):
def OnCreateAnim(self, evt):
self.time = self.duritionTimeSpin.GetValue()
if self.nodePath is None or self.curve is None:
dlg = wx.MessageDialog(None, 'Please select an object and a curve first.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select an object and a curve first.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
else:
self.curveSequence = self.editor.animMgr.singleCurveAnimation(self.nodePath, self.curve, self.time)
self.curveSequence.start()
def OnSaveAnim(self,evt):
def OnSaveAnim(self, evt):
if not self.curveSequence:
dlg = wx.MessageDialog(None, 'Please create a animation first.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please create an animation first.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
else:
if self.editor.animMgr.curveAnimation == {}:
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID])] = (self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID],self.time)
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID])] = \
(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID], self.time)
self.editor.updateStatusReadout('Sucessfully saved to global animation list')
return
hasKey = False
for key in self.editor.animMgr.curveAnimation:
if key == (self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID]):
dlg = wx.MessageDialog(None, 'Already have the animation for this object attach to this curve.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Already have the animation for this object attach to this curve.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
hasKey = True
return
elif self.nodePath[OG.OBJ_UID] == key[0]:
dlg = wx.MessageDialog(None, 'This object is already attached to a curve.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'This object is already attached to a curve.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
hasKey = True
return
if not hasKey and self.editor.animMgr.curveAnimation != {}:
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID])] = (self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID],self.time)
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID])] = \
(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID], self.time)
self.editor.updateStatusReadout('Sucessfully saved to global animation list')
def OnExit(self,evt):
def OnExit(self, evt):
self.Destroy()
self.editor.ui.curveAnimMenuItem.Check(False)

View File

@ -11,6 +11,7 @@ from direct.task import Task
class CurveEditor(DirectObject):
""" CurveEditor will create and edit the curve """
def __init__(self, editor):
self.editor = editor
self.i = 0
@ -76,11 +77,11 @@ class CurveEditor(DirectObject):
self.i = 0
for item in self.curveControl:
item[1].hide()
if self.editor.preMode == self.editor.BASE_MODE :
if self.editor.preMode == self.editor.BASE_MODE:
pass
if self.editor.preMode == self.editor.CREATE_CURVE_MODE :
if self.editor.preMode == self.editor.CREATE_CURVE_MODE:
self.updateScene()
if self.editor.preMode == self.editor.EDIT_CURVE_MODE :
if self.editor.preMode == self.editor.EDIT_CURVE_MODE:
self.doneEdit()
self.curveControl = []
self.curve = []

View File

@ -48,5 +48,5 @@ class FileMgr:
module = imp.load_module(moduleName, file, pathname, description)
self.editor.updateStatusReadout('Sucessfully opened file %s'%fileName)
self.editor.fNeedToSave = False
except:
except Exception:
print('failed to load %s'%fileName)

View File

@ -11,7 +11,7 @@ property = [
"translateX",
"translateY",
"translateZ"
]
]
#----------------------------------------------------------------------
ZoomIn = PyEmbeddedImage(
@ -79,10 +79,12 @@ TwoTangents = PyEmbeddedImage(
#----------------------------------------------------------------------
class GraphEditorWindow(wx.Window):
"""
This is the main graph editor window.
"""
def __init__(self, parent, windowSize, property, xRange, yRange, curFrame, object):
wx.Window.__init__(self, parent, size = windowSize, style = wx.SUNKEN_BORDER)
@ -388,7 +390,7 @@ class GraphEditorWindow(wx.Window):
dc.DrawLine(list[0][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[0][AG.KEYFRAME][AG.LOCAL_VALUE][1], list[1][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[1][AG.KEYFRAME][AG.LOCAL_VALUE][1])
return
if len(list)>=3 :
if len(list) >= 3:
for i in range(len(list)-1):
x1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
@ -406,7 +408,6 @@ class GraphEditorWindow(wx.Window):
scale1 = (x2 - x1) / t1x
y2 = y1 - t1y * scale1
x3 = x4 - (x4 - x1) / 3.0
scale2 = (x4 - x3) / t2x
y3 = y4 + t2y * scale2
@ -445,12 +446,12 @@ class GraphEditorWindow(wx.Window):
pointY = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
if list[i][AG.KEYFRAME][AG.SELECT] == 0:
dc.SetPen(wx.Pen("black",3))
dc.SetPen(wx.Pen("black", 3))
dc.SetBrush(wx.Brush("black"))
dc.DrawCircle(pointX, pointY, 2)
if list[i][AG.KEYFRAME][AG.SELECT] == 1:
dc.SetPen(wx.Pen("cyan",3))
dc.SetPen(wx.Pen("cyan", 3))
dc.SetBrush(wx.Brush("cyan"))
dc.DrawCircle(pointX, pointY, 2)
@ -460,64 +461,64 @@ class GraphEditorWindow(wx.Window):
X1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
Y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
if self._OneTangent is True:
for j in range(3,5):
for j in range(3, 5):
X = list[i][j][AG.LOCAL_VALUE][0]
Y = list[i][j][AG.LOCAL_VALUE][1]
if list[i][j][AG.SELECT] == 1:
dc.SetPen(wx.Pen("cyan",3))
dc.SetPen(wx.Pen("cyan", 3))
dc.SetBrush(wx.Brush("cyan"))
dc.DrawCircle(X, Y, 2)
dc.SetPen(wx.Pen("cyan",1))
dc.SetPen(wx.Pen("cyan", 1))
dc.DrawLine(X1, Y1, X, Y)
if list[i][j][AG.SELECT] == 0:
dc.SetPen(wx.Pen("brown",3))
dc.SetPen(wx.Pen("brown", 3))
dc.SetBrush(wx.Brush("brown"))
dc.DrawCircle(X, Y, 2)
dc.SetPen(wx.Pen("brown",1))
dc.SetPen(wx.Pen("brown", 1))
dc.DrawLine(X1, Y1, X, Y)
if self._OneTangent is False:
if list[i][AG.IN_TANGENT][AG.SELECT] == 1:
X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
dc.SetPen(wx.Pen("cyan",3))
dc.SetPen(wx.Pen("cyan", 3))
dc.SetBrush(wx.Brush("cyan"))
dc.DrawCircle(X, Y, 2)
dc.SetPen(wx.Pen("cyan",1))
dc.SetPen(wx.Pen("cyan", 1))
dc.DrawLine(X1, Y1, X, Y)
if list[i][AG.IN_TANGENT][AG.SELECT] == 0:
X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
dc.SetPen(wx.Pen("navy",3))
dc.SetPen(wx.Pen("navy", 3))
dc.SetBrush(wx.Brush("navy"))
dc.DrawCircle(X, Y, 2)
dc.SetPen(wx.Pen("navy",1))
dc.SetPen(wx.Pen("navy", 1))
dc.DrawLine(X1, Y1, X, Y)
if list[i][AG.OUT_TANGENT][AG.SELECT] == 1:
X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
dc.SetPen(wx.Pen("cyan",3))
dc.SetPen(wx.Pen("cyan", 3))
dc.SetBrush(wx.Brush("cyan"))
dc.DrawCircle(X, Y, 2)
dc.SetPen(wx.Pen("cyan",1))
dc.SetPen(wx.Pen("cyan", 1))
dc.DrawLine(X1, Y1, X, Y)
if list[i][AG.OUT_TANGENT][AG.SELECT] == 0:
X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
dc.SetPen(wx.Pen("brown",3))
dc.SetPen(wx.Pen("brown", 3))
dc.SetBrush(wx.Brush("brown"))
dc.DrawCircle(X, Y, 2)
dc.SetPen(wx.Pen("brown",1))
dc.SetPen(wx.Pen("brown", 1))
dc.DrawLine(X1, Y1, X, Y)
def DrawSelectRec(self, dc):
@ -706,7 +707,7 @@ class GraphEditorWindow(wx.Window):
newPointX = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0] + moveX
newPointY = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1] + moveY
newSlope = [list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] - newPointX , newPointY - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]]
newSlope = [list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] - newPointX, newPointY - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]]
temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0]
temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1]
@ -740,7 +741,7 @@ class GraphEditorWindow(wx.Window):
newPointX = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0] + moveX
newPointY = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1] + moveY
newSlope = [newPointX - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] , list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1] - newPointY]
newSlope = [newPointX - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1] - newPointY]
temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0]
temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1]
@ -785,6 +786,7 @@ class GraphEditorUI(wx.Dialog):
"""
This is the graph editor main class implementation.
"""
def __init__(self, parent, editor, object):
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Graph Editor",
pos=wx.DefaultPosition, size=(735, 535))
@ -805,10 +807,10 @@ class GraphEditorUI(wx.Dialog):
bmpOneTangent = OneTangent.GetBitmap()
bmpTwoTangents = TwoTangents.GetBitmap()
self.buttonZoomIn = wx.BitmapButton(self.mainPanel1, -1, bmpZoomIn, size = (30,30),style = wx.BU_AUTODRAW)
self.buttonZoomOut = wx.BitmapButton(self.mainPanel1, -1, bmpZoomOut, size = (30,30),style = wx.BU_AUTODRAW)
self.buttonOneTangent = wx.BitmapButton(self.mainPanel1, -1, bmpOneTangent, size = (30,30),style = wx.BU_AUTODRAW)
self.buttonTwoTangents = wx.BitmapButton(self.mainPanel1, -1, bmpTwoTangents, size = (30,30),style = wx.BU_AUTODRAW)
self.buttonZoomIn = wx.BitmapButton(self.mainPanel1, -1, bmpZoomIn, size = (30, 30),style = wx.BU_AUTODRAW)
self.buttonZoomOut = wx.BitmapButton(self.mainPanel1, -1, bmpZoomOut, size = (30, 30),style = wx.BU_AUTODRAW)
self.buttonOneTangent = wx.BitmapButton(self.mainPanel1, -1, bmpOneTangent, size = (30, 30),style = wx.BU_AUTODRAW)
self.buttonTwoTangents = wx.BitmapButton(self.mainPanel1, -1, bmpTwoTangents, size = (30, 30),style = wx.BU_AUTODRAW)
self.mainPanel2 = wx.Panel(self, -1)

View File

@ -16,7 +16,7 @@ class LayerEditorUI(wx.Panel):
self.layersDataDict = dict()
self.layersDataDictNextKey = 0
self.systemLayerKeys = []
self.llist = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.LC_EDIT_LABELS|wx.LC_NO_HEADER)
self.llist = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_EDIT_LABELS | wx.LC_NO_HEADER)
self.llist.InsertColumn(0, "Layers")
sizer = wx.BoxSizer(wx.VERTICAL)
@ -170,7 +170,7 @@ class LayerEditorUI(wx.Panel):
def removeObj(self):
objNodePath = base.direct.selected.last
if objNodePath is None:
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
return
obj = self.editor.objectMgr.findObjectByNodePath(objNodePath)
if obj is not None:
@ -179,11 +179,11 @@ class LayerEditorUI(wx.Panel):
def addObj(self):
index = self.llist.GetFirstSelected()
if index == -1:
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
return
objNodePath = base.direct.selected.last
if objNodePath is None:
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
return
# Checking if the object was laready added to the layer
@ -193,7 +193,7 @@ class LayerEditorUI(wx.Panel):
layersData = self.layersDataDict[i]
for j in range(len(layersData)):
if layersData[j] == obj[OG.OBJ_UID]:
wx.MessageBox("Selected object already is this layer", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("Selected object already is this layer", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
return
# Looking for the object in the other layers
# If the object is found - delete it.
@ -220,7 +220,7 @@ class LayerEditorUI(wx.Panel):
def HideObj(self, hide):
index = self.llist.GetFirstSelected()
if index == -1:
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
return
key = self.llist.GetItemData(index)

View File

@ -28,6 +28,7 @@ from .MayaConverter import FROM_BAM_TO_MAYA, MayaConverter
class LevelEditorBase(DirectObject):
""" Base Class for Panda3D LevelEditor """
def __init__(self):
#loadPrcFileData('startup', 'window-type none')
self.currentFile = None
@ -143,14 +144,12 @@ class LevelEditorBase(DirectObject):
if base.direct.fAlt or modifiers == 4:
self.fMoveCamera = True
return
if self.mode == self.CREATE_CURVE_MODE :
if self.mode == self.CREATE_CURVE_MODE:
self.curveEditor.createCurve()
def handleMouse1Up(self):
self.fMoveCamera = False
def handleMouse2(self, modifiers):
if base.direct.fAlt or modifiers == 4:
self.fMoveCamera = True

View File

@ -21,6 +21,7 @@ from .AnimControlUI import AnimControlUI
from .CurveAnimUI import CurveAnimUI
from .GraphEditorUI import GraphEditorUI
class PandaTextDropTarget(wx.TextDropTarget):
def __init__(self, editor, view):
wx.TextDropTarget.__init__(self)
@ -104,6 +105,7 @@ class PandaTextDropTarget(wx.TextDropTarget):
iRay.collisionNodePath.removeNode()
del iRay
ID_NEW = 101
ID_OPEN = 102
ID_SAVE = 103
@ -129,31 +131,33 @@ ID_CURVE_ANIM = 603
ID_ANIM = 701
ID_GRAPH = 702
class LevelEditorUIBase(WxPandaShell):
""" Class for Panda3D LevelEditor """
def __init__(self, editor):
self.MENU_TEXTS.update({
ID_NEW : ("&New", "LE-NewScene"),
ID_OPEN : ("&Open", "LE-OpenScene"),
ID_SAVE : ("&Save", "LE-SaveScene"),
ID_SAVE_AS : ("Save &As", None),
ID_EXPORT_TO_MAYA : ("Export to Maya", None),
wx.ID_EXIT : ("&Quit", "LE-Quit"),
ID_DUPLICATE : ("&Duplicate", "LE-Duplicate"),
ID_MAKE_LIVE : ("Make &Live", "LE-MakeLive"),
ID_UNDO : ("&Undo", "LE-Undo"),
ID_REDO : ("&Redo", "LE-Redo"),
ID_SHOW_GRID : ("&Show Grid", None),
ID_GRID_SIZE : ("&Grid Size", None),
ID_GRID_SNAP : ("Grid S&nap", None),
ID_SHOW_PANDA_OBJECT : ("Show &Panda Objects", None),
ID_HOT_KEYS : ("&Hot Keys", None),
ID_PARENT_TO_SELECTED : ("&Parent To Selected", None),
ID_CREATE_CURVE : ("&Create Curve", None),
ID_EDIT_CURVE : ("&Edit Curve", None),
ID_CURVE_ANIM : ("&Curve Animation", None),
ID_ANIM : ("&Edit Animation", None),
ID_GRAPH : ("&Graph Editor", None)
ID_NEW: ("&New", "LE-NewScene"),
ID_OPEN: ("&Open", "LE-OpenScene"),
ID_SAVE: ("&Save", "LE-SaveScene"),
ID_SAVE_AS: ("Save &As", None),
ID_EXPORT_TO_MAYA: ("Export to Maya", None),
wx.ID_EXIT: ("&Quit", "LE-Quit"),
ID_DUPLICATE: ("&Duplicate", "LE-Duplicate"),
ID_MAKE_LIVE: ("Make &Live", "LE-MakeLive"),
ID_UNDO: ("&Undo", "LE-Undo"),
ID_REDO: ("&Redo", "LE-Redo"),
ID_SHOW_GRID: ("&Show Grid", None),
ID_GRID_SIZE: ("&Grid Size", None),
ID_GRID_SNAP: ("Grid S&nap", None),
ID_SHOW_PANDA_OBJECT: ("Show &Panda Objects", None),
ID_HOT_KEYS: ("&Hot Keys", None),
ID_PARENT_TO_SELECTED: ("&Parent To Selected", None),
ID_CREATE_CURVE: ("&Create Curve", None),
ID_EDIT_CURVE: ("&Edit Curve", None),
ID_CURVE_ANIM: ("&Curve Animation", None),
ID_ANIM: ("&Edit Animation", None),
ID_GRAPH: ("&Graph Editor", None)
})
self.editor = editor
@ -245,9 +249,9 @@ class LevelEditorUIBase(WxPandaShell):
WxPandaShell.createMenu(self)
def onGraphEditor(self,e):
def onGraphEditor(self, e):
if base.direct.selected.last is None:
dlg = wx.MessageDialog(None, 'Please select a object first.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select a object first.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
self.graphEditorMenuItem.Check(False)
@ -257,7 +261,7 @@ class LevelEditorUIBase(WxPandaShell):
self.graphEditorUI.Show()
self.graphEditorMenuItem.Check(True)
def onAnimation(self,e):
def onAnimation(self, e):
if self.editor.mode != self.editor.ANIM_MODE:
self.animUI = AnimControlUI(self, self.editor)
self.animUI.Show()
@ -265,12 +269,12 @@ class LevelEditorUIBase(WxPandaShell):
if self.editor.mode == self.editor.ANIM_MODE:
self.editAnimMenuItem.Check(True)
def onCurveAnim(self,e):
def onCurveAnim(self, e):
self.curveAnimUI = CurveAnimUI(self, self.editor)
self.curveAnimUI.Show()
self.curveAnimMenuItem.Check(True)
def onCreateCurve(self,e):
def onCreateCurve(self, e):
"""Function to invoke curve creating, need to check previous mode"""
if self.editor.mode == self.editor.CREATE_CURVE_MODE:
self.createCurveMenuItem.Check(False)
@ -284,7 +288,7 @@ class LevelEditorUIBase(WxPandaShell):
else:
self.currentView = self.getCurrentView()
if self.currentView is None:
dlg = wx.MessageDialog(None, 'Please select a viewport first.Do not support curve creation under four viewports.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select a viewport first.Do not support curve creation under four viewports.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
self.createCurveMenuItem.Check(False)
@ -297,7 +301,7 @@ class LevelEditorUIBase(WxPandaShell):
base.direct.manipulationControl.disableManipulation()
self.editCurveMenuItem.Check(False)
def onEditCurve(self,e):
def onEditCurve(self, e):
"""Function to invoke curve editing and translate global information to local information. Need to check previous mode"""
if self.editor.mode == self.editor.EDIT_CURVE_MODE:
self.editCurveMenuItem.Check(False)
@ -310,11 +314,11 @@ class LevelEditorUIBase(WxPandaShell):
self.onEditCurve(None)
else:
if base.direct.selected.last is None:
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
self.editCurveMenuItem.Check(False)
if base.direct.selected.last is not None :
if base.direct.selected.last is not None:
base.direct.manipulationControl.enableManipulation()
self.createCurveMenuItem.Check(False)
self.curveObj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
@ -328,7 +332,7 @@ class LevelEditorUIBase(WxPandaShell):
item[1].show()
self.editor.curveEditor.curve.append((None, item[1].getPos()))
else:
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK )
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK)
dlg.ShowModal()
dlg.Destroy()
self.editCurveMenuItem.Check(False)
@ -603,6 +607,7 @@ class LevelEditorUIBase(WxPandaShell):
else:
self.editor.objectMgr.replaceObjectWithTypeName(currObj, targetType)
class GridSizeUI(wx.Dialog):
def __init__(self, parent, id, title, gridSize, gridSpacing):
wx.Dialog.__init__(self, parent, id, title, size=(250, 240))
@ -640,8 +645,10 @@ class GridSizeUI(wx.Dialog):
base.le.ui.bindKeyEvents(True)
self.Destroy()
class ViewportMenu(wx.Menu):
"""Represents a menu that appears when right-clicking a viewport."""
def __init__(self):
wx.Menu.__init__(self)
@ -664,6 +671,7 @@ class ViewportMenu(wx.Menu):
parent.AppendMenu(id, name, subMenu)
return subMenu
class CurveDegreeUI(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(150, 120))

View File

@ -1,5 +1,6 @@
import imp
class LevelLoaderBase:
"""
Base calss for LevelLoader
@ -7,6 +8,7 @@ class LevelLoaderBase:
which you will use to load level editor data in your game.
Refer LevelLoader.py for example.
"""
def __init__(self):
self.defaultPath = None # this should be set in your LevelLoader.py
self.initLoader()
@ -32,6 +34,6 @@ class LevelLoaderBase:
try:
module = imp.load_module(fileName, file, pathname, description)
return True
except:
except Exception:
print('failed to load %s'%fileName)
return None

View File

@ -18,7 +18,8 @@ from . import ObjectGlobals as OG
# python wrapper around a panda.NodePath object
class PythonNodePath(NodePath):
def __init__(self,node):
NodePath.__init__(self,node)
NodePath.__init__(self, node)
class ObjectMgrBase:
""" ObjectMgr will create, manage, update objects in the scene """
@ -89,21 +90,21 @@ class ObjectMgrBase:
for item in curveInfo:
controler = base.render.attachNewNode("controler")
controler = base.loader.loadModel('models/misc/smiley')
controlerPathname = 'controler%d' % item[0]
controlerPathname = f'controler{item[0]}'
controler.setName(controlerPathname)
controler.setPos(item[1])
controler.setColor(0, 0, 0, 1)
controler.setScale(0.2)
controler.reparentTo(base.render)
controler.setTag('OBJRoot','1')
controler.setTag('Controller','1')
controler.setTag('OBJRoot', '1')
controler.setTag('Controller', '1')
curve.append((None, item[1]))
curveControl.append((item[0], controler))
self.editor.curveEditor.degree = degree
self.editor.curveEditor.ropeUpdate (curve)
self.editor.curveEditor.ropeUpdate(curve)
#add new curve to the scene
curveObjNP = self.addNewCurve(curveControl, degree, uid, parent, fSelectObject, nodePath = self.editor.curveEditor.currentRope)
curveObjNP = self.addNewCurve(curveControl, degree, uid, parent, fSelectObject, nodePath=self.editor.curveEditor.currentRope)
curveObj = self.findObjectByNodePath(curveObjNP)
self.editor.objectMgr.updateObjectPropValue(curveObj, 'Degree', degree, fSelectObject=False, fUndo=False)
@ -136,7 +137,7 @@ class ObjectMgrBase:
newobj = nodePath
newobj.reparentTo(parent)
newobj.setTag('OBJRoot','1')
newobj.setTag('OBJRoot', '1')
# populate obj data using default values
properties = {}
@ -254,7 +255,7 @@ class ObjectMgrBase:
return None
newobj.reparentTo(parent)
newobj.setTag('OBJRoot','1')
newobj.setTag('OBJRoot', '1')
# populate obj data using default values
properties = {}
@ -276,11 +277,11 @@ class ObjectMgrBase:
obj = self.findObjectById(uid)
nodePath = obj[OG.OBJ_NP]
for i in range(0,len(self.Actor)):
for i in range(0, len(self.Actor)):
if self.Actor[i] == obj:
del self.Actor[i]
break
for i in range(0,len(self.Nodes)):
for i in range(0, len(self.Nodes)):
if self.Nodes[i][OG.OBJ_UID] == uid:
del self.Nodes[i]
break
@ -300,11 +301,11 @@ class ObjectMgrBase:
def removeObjectByNodePath(self, nodePath):
uid = self.npIndex.get(nodePath)
if uid:
for i in range(0,len(self.Actor)):
for i in range(0, len(self.Actor)):
if self.Actor[i][OG.OBJ_UID] == uid:
del self.Actor[i]
break
for i in range(0,len(self.Nodes)):
for i in range(0, len(self.Nodes)):
if self.Nodes[i][OG.OBJ_UID] == uid:
del self.Nodes[i]
break
@ -520,7 +521,7 @@ class ObjectMgrBase:
return
self.flatten(newobjModel, model, objDef, uid)
newobj = PythonNodePath(newobjModel)
newobj.setTag('OBJRoot','1')
newobj.setTag('OBJRoot', '1')
# reparent children
objNP.findAllMatches("=OBJRoot").reparentTo(newobj)
@ -921,7 +922,6 @@ class ObjectMgrBase:
self.findActors(child)
def findNodes(self, parent):
for child in parent.getChildren():
if child.hasTag('OBJRoot') and not child.hasTag('Controller'):

View File

@ -17,6 +17,7 @@ and in the populate function you can define ObjectPalette tree structure.
from . import ObjectGlobals as OG
from .ObjectPaletteBase import ObjectBase, ObjectPaletteBase
class ObjectProp(ObjectBase):
def __init__(self, *args, **kw):
ObjectBase.__init__(self, *args, **kw)

View File

@ -4,14 +4,19 @@ from . import ObjectGlobals as OG
class ObjectGen:
""" Base class for obj definitions """
def __init__(self, name=''):
self.name = name
class ObjectBase(ObjectGen):
""" Base class for obj definitions """
def __init__(self, name='', createFunction = None, model = None, models= [], anims = [], animNames = [], animDict = {}, properties={},
movable = True, actor = False, named=False, updateModelFunction = None, orderedProperties=[], propertiesMask={}):
def __init__(self, name='', createFunction=None, model=None, models=[],
anims=[], animNames=[], animDict={}, properties={},
movable=True, actor=False, named=False,
updateModelFunction=None, orderedProperties=[],
propertiesMask={}):
ObjectGen.__init__(self, name)
self.createFunction = createFunction
self.model = model
@ -33,11 +38,14 @@ class ObjectBase(ObjectGen):
class ObjectCurve(ObjectBase):
def __init__(self, *args, **kw):
ObjectBase.__init__(self, *args, **kw)
self.properties['Degree'] =[OG.PROP_UI_COMBO, # UI type
self.properties['Degree'] = [
OG.PROP_UI_COMBO, # UI type
OG.PROP_INT, # data type
('base.le.objectMgr.updateCurve', {'val':OG.ARG_VAL, 'obj':OG.ARG_OBJ}), # update function
('base.le.objectMgr.updateCurve', {'val': OG.ARG_VAL, 'obj': OG.ARG_OBJ}), # update function
3, # default value
[2, 3, 4]] # value range
[2, 3, 4], # value range
]
class ObjectPaletteBase:
"""
@ -72,9 +80,9 @@ class ObjectPaletteBase:
self.data[item.name] = item
self.dataKeys.append(item.name)
def add(self, item, parentName = None):
def add(self, item, parentName=None):
if isinstance(item, str):
self.insertItem(ObjectGen(name = item), parentName)
self.insertItem(ObjectGen(name=item), parentName)
else:
self.insertItem(item, parentName)
@ -91,8 +99,7 @@ class ObjectPaletteBase:
if node is not None:
deleteItems[key] = node
return item
except:
return None
except Exception:
return None
def delete(self, name):
@ -103,14 +110,13 @@ class ObjectPaletteBase:
deleteItems[name] = node
for key in list(deleteItems.keys()):
item = self.dataStruct.pop(key)
except:
return
except Exception:
return
def findItem(self, name):
try:
item = self.data[name]
except:
except Exception:
return None
return item
@ -137,7 +143,7 @@ class ObjectPaletteBase:
item = self.data.pop(oldName)
item.name = newName
self.data[newName] = item
except:
except Exception:
return False
return True

View File

@ -24,6 +24,7 @@ Key = PyEmbeddedImage(
"EMaYtpbOXlu01vf5Hz/wDRuDdIDl5WtQAAAAAElFTkSuQmCC")
#----------------------------------------------------------------------
class AnimFileDrop(wx.FileDropTarget):
def __init__(self, editor):
wx.FileDropTarget.__init__(self)
@ -56,11 +57,13 @@ class AnimFileDrop(wx.FileDropTarget):
obj[OG.OBJ_ANIM] = animName
self.editor.ui.objectPropertyUI.updateProps(obj)
class ObjectPropUI(wx.Panel):
"""
Base class for ObjectPropUIs,
It consists of label area and ui area.
"""
def __init__(self, parent, label):
wx.Panel.__init__(self, parent)
self.parent = parent
@ -80,24 +83,22 @@ class ObjectPropUI(wx.Panel):
self.setKeyButton.Bind(wx.EVT_BUTTON, self.onKey)
def onKey(self,evt):
def onKey(self, evt):
self.parent = wx.GetTopLevelParent(self)
if self.parent.editor.mode == self.parent.editor.ANIM_MODE:
obj= self.parent.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
objUID = obj[OG.OBJ_UID]
propertyName = self.label.GetLabelText()
obj = self.parent.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
value = self.getValue()
frame = self.parent.editor.ui.animUI.curFrame
if (objUID, propertyName) in self.parent.editor.animMgr.keyFramesInfo:
for i in range(len(self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)])):
if self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)][i][AG.FRAME] == frame:
del self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)][i]
self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)].append([frame, value, [], []])
if property in self.parent.editor.animMgr.keyFramesInfo:
for i in range(len(self.parent.editor.animMgr.keyFramesInfo[property])):
if self.parent.editor.animMgr.keyFramesInfo[property][i][AG.FRAME] == frame:
del self.parent.editor.animMgr.keyFramesInfo[property][i]
self.parent.editor.animMgr.keyFramesInfo[property].append([frame, value, [], []])
#sort keyFrameInfo list by the order of frame number
sortKeyList = self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)]
sortKeyList = self.parent.editor.animMgr.keyFramesInfo[property]
for i in range(0, len(sortKeyList)-1):
for j in range(i+1, len(sortKeyList)):
if sortKeyList[i][AG.FRAME]>sortKeyList[j][AG.FRAME]:
@ -105,9 +106,9 @@ class ObjectPropUI(wx.Panel):
sortKeyList[i] = sortKeyList[j]
sortKeyList[j] = temp
self.parent.editor.animMgr.generateSlope(self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)])
self.parent.editor.animMgr.generateSlope(self.parent.editor.animMgr.keyFramesInfo[property])
else:
self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)] = [[frame, value, [], []]]
self.parent.editor.animMgr.keyFramesInfo[property] = [[frame, value, [], []]]
exist = False
for keyFrame in self.parent.editor.animMgr.keyFrames:
@ -133,8 +134,10 @@ class ObjectPropUI(wx.Panel):
if valFunc:
self.ui.Bind(self.eventType, valFunc)
class ObjectPropUIEntry(ObjectPropUI):
""" UI for string value properties """
def __init__(self, parent, label):
ObjectPropUI.__init__(self, parent, label)
self.ui = wx.TextCtrl(self.uiPane, -1)
@ -144,8 +147,10 @@ class ObjectPropUIEntry(ObjectPropUI):
def setValue(self, value):
self.ui.SetValue(str(value))
class ObjectPropUISlider(ObjectPropUI):
""" UI for float value properties """
def __init__(self, parent, label, value, minValue, maxValue):
ObjectPropUI.__init__(self, parent, label)
self.ui = WxSlider(self.uiPane, -1, value, minValue, maxValue,
@ -166,6 +171,7 @@ class ObjectPropUISlider(ObjectPropUI):
class ObjectPropUISpinner(ObjectPropUI):
""" UI for int value properties """
def __init__(self, parent, label, value, minValue, maxValue):
ObjectPropUI.__init__(self, parent, label)
self.ui = wx.SpinCtrl(self.uiPane, -1, "", min=minValue, max=maxValue, initial=value)
@ -218,6 +224,7 @@ class ObjectPropUICombo(ObjectPropUI):
def setItems(self, valueList):
self.ui.SetItems(valueList)
class ObjectPropUITime(wx.Panel):
def __init__(self, parent, label, value):
wx.Panel.__init__(self, parent)
@ -288,9 +295,11 @@ class ObjectPropUITime(wx.Panel):
self.uiHour.Bind(self.eventType, valFunc)
self.uiMin.Bind(self.eventType, valFunc)
class ColorPicker(CubeColourDialog):
def __init__(self, parent, colourData=None, style=CCD_SHOW_ALPHA, alpha = 255, updateCB=None, exitCB=None):
self.updateCB=updateCB
def __init__(self, parent, colourData=None, style=CCD_SHOW_ALPHA,
alpha=255, updateCB=None, exitCB=None):
self.updateCB = updateCB
CubeColourDialog.__init__(self, parent, colourData, style)
self.okButton.Hide()
self.cancelButton.Hide()
@ -306,6 +315,7 @@ class ColorPicker(CubeColourDialog):
if self.updateCB:
self.updateCB(self._colour.r, self._colour.g, self._colour.b, self._colour.alpha)
class ObjectPropertyUI(ScrolledPanel):
def __init__(self, parent, editor):
self.editor = editor
@ -329,7 +339,7 @@ class ObjectPropertyUI(ScrolledPanel):
self.propPane.Destroy()
self.SetSizer(None)
self.Layout()
self.SetupScrolling(self, scroll_y = True, rate_y = 20)
self.SetupScrolling(self, scroll_y=True, rate_y=20)
def colorPickerExitCB(self, evt=None):
self.lastColorPickerPos = self.colorPicker.GetPosition()
@ -414,8 +424,11 @@ class ObjectPropertyUI(ScrolledPanel):
self.propSY = ObjectPropUIEntry(self.transformPane, 'SY')
self.propSZ = ObjectPropUIEntry(self.transformPane, 'SZ')
transformProps = [self.propX, self.propY, self.propZ, self.propH, self.propP, self.propR,
self.propSX, self.propSY, self.propSZ]
transformProps = [
self.propX, self.propY, self.propZ,
self.propH, self.propP, self.propR,
self.propSX, self.propSY, self.propSZ,
]
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.AddMany(transformProps)
@ -635,7 +648,6 @@ class ObjectPropertyUI(ScrolledPanel):
self.editor.objectMgr.onLeaveObjectPropUI,
lambda p0=None, p1=obj, p2=key: self.editor.objectMgr.updateObjectProperty(p0, p1, p2))
self.propsPane.SetSizer(sizer)
self.Layout()
self.SetupScrolling(self, scroll_y = True, rate_y = 20)

View File

@ -9,7 +9,7 @@ class ProtoObjs:
def __init__(self, name):
self.dirname = os.path.dirname(__file__)
self.name = name
self.filename = "/%s.py" % (name)
self.filename = f"/{name}.py"
self.data = {}
def populate(self):
@ -18,16 +18,16 @@ class ProtoObjs:
file, pathname, description = imp.find_module(moduleName, [self.dirname])
module = imp.load_module(moduleName, file, pathname, description)
self.data = module.protoData
except:
print("%s doesn't exist"%(self.name))
except Exception:
print(f"{self.name} doesn't exist")
return
def saveProtoData(self, f):
if not f:
return
for key in self.data.keys():
f.write("\t'%s':'%s',\n"%(key, self.data[key]))
for key, value in self.data.items():
f.write(f"\t'{key}':'{value}',\n")
def saveToFile(self):
try:
@ -36,5 +36,5 @@ class ProtoObjs:
self.saveProtoData(f)
f.write("}\n")
f.close()
except:
except Exception:
pass

View File

@ -7,6 +7,7 @@ from .ActionMgr import ActionChangeHierarchy, ActionDeleteObjById
from . import ObjectGlobals as OG
class SceneGraphUIDropTarget(wx.TextDropTarget):
def __init__(self, editor):
print("in SceneGraphUIDropTarget::init...")
@ -17,6 +18,7 @@ class SceneGraphUIDropTarget(wx.TextDropTarget):
print("in SceneGraphUIDropTarget::OnDropText...")
self.editor.ui.sceneGraphUI.changeHierarchy(text, x, y)
class SceneGraphUIBase(wx.Panel):
def __init__(self, parent, editor):
wx.Panel.__init__(self, parent)
@ -121,7 +123,7 @@ class SceneGraphUIBase(wx.Panel):
if obj is None:
return
if parentNP is None :
if parentNP is None:
parentNP = obj[OG.OBJ_NP].getParent()
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNP)

View File

@ -68,5 +68,5 @@ if objects['1252623762.9gjeon']:
if hasattr(base, 'le'):
ui.layerEditorUI.reset()
ui.layerEditorUI.addLayerEntry('Layer1', 1 )
ui.layerEditorUI.addLayerEntry('Layer1', 1)
ui.layerEditorUI.addLayerData(1, '1252538687.73gjeon')

View File

@ -229,7 +229,7 @@ class MotionTrail(NodePath, DirectObject):
index = 0
while index < total_motion_trails:
motion_trail = MotionTrail.motion_trail_list [index]
motion_trail = MotionTrail.motion_trail_list[index]
if MotionTrail.global_enable:
if motion_trail.use_python_version:
@ -577,7 +577,7 @@ class MotionTrail(NodePath, DirectObject):
v0 = start_transform.xform(motion_trail_vertex_start.vertex)
v2 = end_transform.xform(motion_trail_vertex_start.vertex)
nurbs_curve_evaluator = nurbs_curve_evaluator_list [vertex_segment_index]
nurbs_curve_evaluator = nurbs_curve_evaluator_list[vertex_segment_index]
nurbs_curve_evaluator.setVertex(segment_index, v0)
@ -589,7 +589,7 @@ class MotionTrail(NodePath, DirectObject):
v1 = start_transform.xform(motion_trail_vertex_end.vertex)
v3 = end_transform.xform(motion_trail_vertex_end.vertex)
nurbs_curve_evaluator = nurbs_curve_evaluator_list [vertex_segment_index + 1]
nurbs_curve_evaluator = nurbs_curve_evaluator_list[vertex_segment_index + 1]
nurbs_curve_evaluator.setVertex(segment_index, v1)
@ -607,7 +607,7 @@ class MotionTrail(NodePath, DirectObject):
index = 0
nurbs_curve_result_list = []
while index < self.total_vertices:
nurbs_curve_evaluator = nurbs_curve_evaluator_list [index]
nurbs_curve_evaluator = nurbs_curve_evaluator_list[index]
nurbs_curve_result = nurbs_curve_evaluator.evaluate()
nurbs_curve_result_list = nurbs_curve_result_list + [nurbs_curve_result]
@ -665,8 +665,8 @@ class MotionTrail(NodePath, DirectObject):
motion_trail_vertex_start = self.vertex_list[vertex_segment_index]
motion_trail_vertex_end = self.vertex_list[vertex_segment_index + 1]
start_nurbs_curve_result = nurbs_curve_result_list [vertex_segment_index]
end_nurbs_curve_result = nurbs_curve_result_list [vertex_segment_index + 1]
start_nurbs_curve_result = nurbs_curve_result_list[vertex_segment_index]
end_nurbs_curve_result = nurbs_curve_result_list[vertex_segment_index + 1]
start_nurbs_start_t = start_nurbs_curve_result.getStartT()
start_nurbs_end_t = start_nurbs_curve_result.getEndT()

View File

@ -214,7 +214,7 @@ class ParticleEffect(NodePath):
data = vfs.readFile(fn, True)
data = data.replace(b'\r', b'')
exec(data)
except:
except Exception:
self.notify.warning('loadConfig: failed to load particle file: '+ repr(filename))
raise

View File

@ -89,7 +89,7 @@ class BufferViewer(DirectObject):
if not self.isValidTextureSet(elt):
return 0
else:
return (x=="all") or (isinstance(x, Texture)) or (isinstance(x, GraphicsOutput))
return x == "all" or isinstance(x, Texture) or isinstance(x, GraphicsOutput)
def isEnabled(self):
"""Returns true if the buffer viewer is currently enabled."""
@ -237,8 +237,8 @@ class BufferViewer(DirectObject):
self.analyzeTextureSet(win, set)
elif x == "all":
self.analyzeTextureSet(self.engine, set)
else: return
else:
return
def makeFrame(self, sizex, sizey):
"""Access: private. Each texture card is displayed with
@ -271,14 +271,14 @@ class BufferViewer(DirectObject):
triangles = GeomTriangles(Geom.UHStatic)
for i in range(2):
delta = i*8
triangles.addVertices(0+delta, 4+delta, 1+delta)
triangles.addVertices(1+delta, 4+delta, 5+delta)
triangles.addVertices(1+delta, 5+delta, 2+delta)
triangles.addVertices(2+delta, 5+delta, 6+delta)
triangles.addVertices(2+delta, 6+delta, 3+delta)
triangles.addVertices(3+delta, 6+delta, 7+delta)
triangles.addVertices(3+delta, 7+delta, 0+delta)
triangles.addVertices(0+delta, 7+delta, 4+delta)
triangles.addVertices(0 + delta, 4 + delta, 1 + delta)
triangles.addVertices(1 + delta, 4 + delta, 5 + delta)
triangles.addVertices(1 + delta, 5 + delta, 2 + delta)
triangles.addVertices(2 + delta, 5 + delta, 6 + delta)
triangles.addVertices(2 + delta, 6 + delta, 3 + delta)
triangles.addVertices(3 + delta, 6 + delta, 7 + delta)
triangles.addVertices(3 + delta, 7 + delta, 0 + delta)
triangles.addVertices(0 + delta, 7 + delta, 4 + delta)
triangles.closePrimitive()
geom = Geom(vdata)
@ -287,7 +287,6 @@ class BufferViewer(DirectObject):
geomnode.addGeom(geom)
return NodePath(geomnode)
def maintainReadout(self, task):
"""Access: private. Whenever necessary, rebuilds the entire
display from scratch. This is only done when the configuration
@ -408,24 +407,24 @@ class BufferViewer(DirectObject):
bordersize = 4.0
if (float(self.sizex)==0.0) and (float(self.sizey)==0.0):
if float(self.sizex) == 0.0 and float(self.sizey) == 0.0:
sizey = int(0.4266666667 * self.win.getYSize())
sizex = (sizey * aspectx) // aspecty
v_sizey = (self.win.getYSize() - (rows-1) - (rows*2)) // rows
v_sizey = (self.win.getYSize() - (rows - 1) - (rows * 2)) // rows
v_sizex = (v_sizey * aspectx) // aspecty
if (v_sizey < sizey) or (v_sizex < sizex):
sizey = v_sizey
sizex = v_sizex
adjustment = 2
h_sizex = float (self.win.getXSize() - adjustment) / float (cols)
h_sizex = float(self.win.getXSize() - adjustment) / float(cols)
h_sizex -= bordersize
if h_sizex < 1.0:
h_sizex = 1.0
h_sizey = (h_sizex * aspecty) // aspectx
if (h_sizey < sizey) or (h_sizex < sizex):
if h_sizey < sizey or h_sizex < sizex:
sizey = h_sizey
sizex = h_sizex
else:
@ -466,7 +465,7 @@ class BufferViewer(DirectObject):
for r in range(rows):
for c in range(cols):
index = c + r*cols
index = c + r * cols
if index < ncards:
index = (index + self.cardindex) % len(cards)
@ -474,7 +473,7 @@ class BufferViewer(DirectObject):
posy = diry * (1.0 - ((r + 0.5) * (fsizey + fpixely * bordersize))) - (fpixely * diry)
placer = NodePath("card-structure")
placer.setPos(Point3.rfu(posx, 0, posy))
placer.setScale(Vec3.rfu(fsizex*0.5, 1.0, fsizey*0.5))
placer.setScale(Vec3.rfu(fsizex * 0.5, 1.0, fsizey * 0.5))
placer.setBin(self.cullbin, self.cullsort)
placer.reparentTo(self.renderParent)
frame.instanceTo(placer)

View File

@ -33,6 +33,7 @@ def _createContainerLeak():
# use tuples as keys since they can't be weakref'd, and use an instance
# since it can't be repr/eval'd
# that will force the leak detector to hold a normal 'non-weak' reference
class LeakKey:
pass
base.leakContainer[(LeakKey(),)] = {}
@ -47,13 +48,17 @@ def _createContainerLeak():
return task.done
leakContainer()
def _createTaskLeak():
leakTaskName = uniqueName('leakedTask')
leakDoLaterName = uniqueName('leakedDoLater')
def nullTask(task=None):
return task.cont
def nullDoLater(task=None):
return task.done
def leakTask(task=None, leakTaskName=leakTaskName):
base = getBase()
taskMgr.add(nullTask, uniqueName(leakTaskName))
@ -63,9 +68,11 @@ def _createTaskLeak():
return task.done
leakTask()
class NoDictKey:
pass
class Indirection:
"""
Represents the indirection that brings you from a container to an element of the container.
@ -75,6 +82,7 @@ class Indirection:
TODO: store string components that are duplicates of strings in the actual system so that
Python will keep one copy and reduce memory usage
"""
def __init__(self, evalStr=None, dictKey=NoDictKey):
# if this is a dictionary lookup, pass dictKey instead of evalStr
self.evalStr = evalStr
@ -89,7 +97,7 @@ class Indirection:
try:
keyEval = eval(keyRepr)
useEval = True
except:
except Exception:
pass
if useEval:
# check to make sure the eval succeeded
@ -114,6 +122,7 @@ class Indirection:
def acquire(self):
self._refCount += 1
def release(self):
self._refCount -= 1
if self._refCount == 0:
@ -164,6 +173,7 @@ class Indirection:
def __repr__(self):
return self.getString()
class ObjectRef:
"""
stores a reference to a container in a way that does not prevent garbage
@ -346,10 +356,12 @@ class ObjectRef:
pass
return result
class FindContainers(Job):
"""
Explore the Python graph, looking for objects that support __len__()
"""
def __init__(self, name, leakDetector):
Job.__init__(self, name)
self._leakDetector = leakDetector
@ -382,7 +394,7 @@ class FindContainers(Job):
pass
try:
base
except:
except Exception:
pass
else:
ref = ObjectRef(Indirection(evalStr='base.__dict__'), id(base.__dict__))
@ -391,7 +403,7 @@ class FindContainers(Job):
pass
try:
simbase
except:
except Exception:
pass
else:
ref = ObjectRef(Indirection(evalStr='simbase.__dict__'), id(simbase.__dict__))
@ -411,7 +423,7 @@ class FindContainers(Job):
# how good of a starting object is this object for traversing the object graph?
try:
return len(startObj)
except:
except Exception:
return 1
def _isDeadEnd(self, obj, objName=None):
@ -426,7 +438,7 @@ class FindContainers(Job):
return True
try:
className = obj.__class__.__name__
except:
except Exception:
pass
else:
# prevent infinite recursion in built-in containers related to methods
@ -529,7 +541,7 @@ class FindContainers(Job):
try:
for containerRef in self._leakDetector.getContainerByIdGen(startId):
yield None
except:
except Exception:
# ref is invalid
self.notify.debug('invalid startRef, stored as id %s' % startId)
self._leakDetector.removeContainerById(startId)
@ -539,7 +551,7 @@ class FindContainers(Job):
try:
for curObj in curObjRef.getContainerGen():
yield None
except:
except Exception:
self.notify.debug('lost current container, ref.getContainerGen() failed')
# that container is gone, try again
curObjRef = None
@ -642,6 +654,7 @@ class FindContainers(Job):
raise
yield Job.Done
class CheckContainers(Job):
"""
Job to check container sizes and find potential leaks; sub-job of ContainerLeakDetector
@ -724,7 +737,7 @@ class CheckContainers(Job):
try:
for container in self._leakDetector.getContainerByIdGen(objId):
yield None
except:
except Exception:
# TODO
self.notify.debug('caught exception in getContainerByIdGen (1)')
else:
@ -745,7 +758,7 @@ class CheckContainers(Job):
try:
for container in self._leakDetector.getContainerByIdGen(objId):
yield None
except:
except Exception:
# TODO
self.notify.debug('caught exception in getContainerByIdGen (2)')
else:
@ -766,7 +779,7 @@ class CheckContainers(Job):
try:
for container in self._leakDetector.getContainerByIdGen(objId):
yield None
except:
except Exception:
# TODO
self.notify.debug('caught exception in getContainerByIdGen (3)')
else:
@ -786,6 +799,7 @@ class CheckContainers(Job):
raise
yield Job.Done
class FPTObjsOfType(Job):
def __init__(self, name, leakDetector, otn, doneCallback=None):
Job.__init__(self, name)
@ -820,7 +834,7 @@ class FPTObjsOfType(Job):
for container in self._leakDetector.getContainerByIdGen(
id, getInstance=getInstance):
yield None
except:
except Exception:
pass
else:
if hasattr(container, '__class__'):
@ -832,7 +846,7 @@ class FPTObjsOfType(Job):
for ptc in self._leakDetector.getContainerNameByIdGen(
id, getInstance=getInstance):
yield None
except:
except Exception:
pass
else:
print('GPTC(' + self._otn + '):' + self.getJobName() + ': ' + ptc)
@ -846,6 +860,7 @@ class FPTObjsOfType(Job):
if self._doneCallback:
self._doneCallback(self)
class FPTObjsNamed(Job):
def __init__(self, name, leakDetector, on, doneCallback=None):
Job.__init__(self, name)
@ -878,7 +893,7 @@ class FPTObjsNamed(Job):
try:
for container in self._leakDetector.getContainerByIdGen(id):
yield None
except:
except Exception:
pass
else:
name = self._leakDetector._id2ref[id].getFinalIndirectionStr()
@ -886,7 +901,7 @@ class FPTObjsNamed(Job):
try:
for ptc in self._leakDetector.getContainerNameByIdGen(id):
yield None
except:
except Exception:
pass
else:
print('GPTCN(' + self._on + '):' + self.getJobName() + ': ' + ptc)
@ -900,11 +915,13 @@ class FPTObjsNamed(Job):
if self._doneCallback:
self._doneCallback(self)
class PruneObjectRefs(Job):
"""
Job to destroy any container refs that are no longer valid.
Checks validity by asking for each container
"""
def __init__(self, name, leakDetector):
Job.__init__(self, name)
self._leakDetector = leakDetector
@ -926,7 +943,7 @@ class PruneObjectRefs(Job):
try:
for container in self._leakDetector.getContainerByIdGen(id):
yield None
except:
except Exception:
# reference is invalid, remove it
self._leakDetector.removeContainerById(id)
_id2baseStartRef = self._leakDetector._findContainersJob._id2baseStartRef
@ -936,7 +953,7 @@ class PruneObjectRefs(Job):
try:
for container in _id2baseStartRef[id].getContainerGen():
yield None
except:
except Exception:
# reference is invalid, remove it
del _id2baseStartRef[id]
_id2discoveredStartRef = self._leakDetector._findContainersJob._id2discoveredStartRef
@ -946,7 +963,7 @@ class PruneObjectRefs(Job):
try:
for container in _id2discoveredStartRef[id].getContainerGen():
yield None
except:
except Exception:
# reference is invalid, remove it
del _id2discoveredStartRef[id]
except Exception as e:
@ -955,6 +972,7 @@ class PruneObjectRefs(Job):
raise
yield Job.Done
class ContainerLeakDetector(Job):
"""
Low-priority Python object-graph walker that looks for leaking containers.
@ -1028,12 +1046,14 @@ class ContainerLeakDetector(Job):
@classmethod
def addPrivateObj(cls, obj):
cls.PrivateIds.add(id(obj))
@classmethod
def removePrivateObj(cls, obj):
cls.PrivateIds.remove(id(obj))
def _getCheckTaskName(self):
return 'checkForLeakingContainers-%s' % self._serialNum
def _getPruneTaskName(self):
return 'pruneLeakingContainerRefs-%s' % self._serialNum
@ -1043,16 +1063,20 @@ class ContainerLeakDetector(Job):
def getContainerByIdGen(self, id, **kwArgs):
# return a generator to look up a container
return self._id2ref[id].getContainerGen(**kwArgs)
def getContainerById(self, id):
for result in self._id2ref[id].getContainerGen():
pass
return result
def getContainerNameByIdGen(self, id, **kwArgs):
return self._id2ref[id].getEvalStrGen(**kwArgs)
def getContainerNameById(self, id):
if id in self._id2ref:
return repr(self._id2ref[id])
return '<unknown container>'
def removeContainerById(self, id):
if id in self._id2ref:
self._id2ref[id].destroy()

View File

@ -58,17 +58,17 @@ class ContainerReport(Job):
# for the sake of the variable-name printouts
try:
base
except:
except NameError:
pass
else:
self._enqueueContainer( base.__dict__,
self._enqueueContainer(base.__dict__,
'base')
try:
simbase
except:
except NameError:
pass
else:
self._enqueueContainer( simbase.__dict__,
self._enqueueContainer(simbase.__dict__,
'simbase')
self._queue.push(__builtins__)
self._id2pathStr[id(__builtins__)] = ''
@ -86,7 +86,7 @@ class ContainerReport(Job):
try:
if parentObj.__class__.__name__ == 'method-wrapper':
continue
except:
except Exception:
pass
if isinstance(parentObj, (str, bytes)):
@ -142,7 +142,7 @@ class ContainerReport(Job):
if not isinstance(parentObj, io.TextIOWrapper):
try:
itr = iter(parentObj)
except:
except Exception:
pass
else:
try:
@ -150,7 +150,7 @@ class ContainerReport(Job):
while 1:
try:
attr = next(itr)
except:
except Exception:
# some custom classes don't do well when iterated
attr = None
break
@ -168,7 +168,7 @@ class ContainerReport(Job):
try:
childNames = dir(parentObj)
except:
except Exception:
pass
else:
childName = None
@ -176,7 +176,7 @@ class ContainerReport(Job):
for childName in childNames:
try:
child = getattr(parentObj, childName)
except:
except Exception:
continue
if id(child) not in self._visitedIds:
self._visitedIds.add(id(child))
@ -206,12 +206,13 @@ class ContainerReport(Job):
# if it's a container, put it in the tables
try:
length = len(obj)
except:
except Exception:
length = None
if length is not None and length > 0:
self._id2container[objId] = obj
self._type2id2len.setdefault(type(obj), {})
self._type2id2len[type(obj)][objId] = length
def _examine(self, obj):
# return False if it's an object that can't contain or lead to other objects
if type(obj) in deadEndTypes:

View File

@ -260,6 +260,7 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath):
self.cTrav.traverse(self)
base.eventMgr.doEvents()
class BufferedDistancePhasedNode(DistancePhasedNode):
"""
This class is similar to DistancePhasedNode except you can also
@ -329,7 +330,7 @@ class BufferedDistancePhasedNode(DistancePhasedNode):
if __debug__ and 0:
cSphere = CollisionSphere(0,0,0,0.1)
cSphere = CollisionSphere(0, 0, 0, 0.1)
cNode = CollisionNode('camCol')
cNode.addSolid(cSphere)
cNodePath = NodePath(cNode)
@ -344,11 +345,11 @@ if __debug__ and 0:
eventHandler.addOutPattern('exit%in')
# messenger.toggleVerbose()
base.cTrav.addCollider(cNodePath,eventHandler)
base.cTrav.addCollider(cNodePath, eventHandler)
p = BufferedDistancePhasedNode('p',{'At':(10,20),'Near':(100,200),'Far':(1000, 1020)},
autoCleanup = False,
fromCollideNode = cNodePath,
p = BufferedDistancePhasedNode('p', {'At': (10, 20), 'Near': (100, 200), 'Far': (1000, 1020)},
autoCleanup=False,
fromCollideNode=cNodePath,
)
p.reparentTo(render)

View File

@ -10,6 +10,7 @@ notify = directNotify.newCategory("ExceptionVarDump")
reentry = 0
def _varDump__init__(self, *args, **kArgs):
global reentry
if reentry > 0:
@ -30,8 +31,10 @@ def _varDump__init__(self, *args, **kArgs):
self._moved__init__(*args, **kArgs)
reentry -= 1
sReentry = 0
def _varDump__print(exc):
global sReentry
global notify
@ -60,6 +63,7 @@ def _varDump__print(exc):
notify.info(exc._savedExcString)
sReentry -= 1
oldExcepthook = None
# store these values here so that Task.py can always reliably access them
# from its main exception handler
@ -68,9 +72,11 @@ wantStackDumpUpload = False
variableDumpReasons = []
dumpOnExceptionInit = False
class _AttrNotFound:
pass
def _excepthookDumpVars(eType, eValue, tb):
origTb = tb
excStrs = traceback.format_exception(eType, eValue, origTb)
@ -137,7 +143,7 @@ def _excepthookDumpVars(eType, eValue, tb):
# prevent infinite recursion on method wrappers (__init__.__init__.__init__...)
try:
className = attr.__class__.__name__
except:
except Exception:
pass
else:
if className == 'method-wrapper':
@ -168,16 +174,17 @@ def _excepthookDumpVars(eType, eValue, tb):
timeMgr = None
try:
timeMgr = base.cr.timeManager
except:
except Exception:
try:
timeMgr = simbase.air.timeManager
except:
except Exception:
pass
if timeMgr:
timeMgr.setStackDump(s)
oldExcepthook(eType, eValue, origTb)
def install(log, upload):
"""Installs the exception hook."""
global oldExcepthook

View File

@ -60,7 +60,7 @@ def rebindClass(filename):
res = findClass(className)
if not res:
print ('Warning: Finder could not find class')
print('Warning: Finder could not find class')
# Remove the temp file we made
file.close()
os.remove(filename)
@ -87,7 +87,7 @@ def rebindClass(filename):
file.close()
os.remove(filename)
print (' Finished rebind')
print(' Finished rebind')
def copyFuncs(fromClass, toClass):
@ -148,25 +148,28 @@ def copyFuncs(fromClass, toClass):
# print "adding new func: ", oldFunc, funcName, newFunc
setattr(toClass, funcName, newFunc)
def replaceMessengerFunc(replaceFuncList):
try:
messenger
except:
except Exception:
return
for oldFunc, funcName, newFunc in replaceFuncList:
res = messenger.replaceMethod(oldFunc, newFunc)
if res:
print('replaced %s messenger function(s): %s' % (res, funcName))
def replaceTaskMgrFunc(replaceFuncList):
try:
taskMgr
except:
except Exception:
return
for oldFunc, funcName, newFunc in replaceFuncList:
if taskMgr.replaceMethod(oldFunc, newFunc):
print('replaced taskMgr function: %s' % funcName)
def replaceStateFunc(replaceFuncList):
if not sys.modules.get('base.direct.fsm.State'):
return
@ -176,28 +179,31 @@ def replaceStateFunc(replaceFuncList):
if res:
print('replaced %s FSM transition function(s): %s' % (res, funcName))
def replaceCRFunc(replaceFuncList):
try:
base.cr
except:
except Exception:
return
# masad: Gyedo's fake cr causes a crash in followingreplaceMethod on rebinding, so
# I throw in the isFake check. I still think the fake cr should be eliminated.
if hasattr(base.cr,'isFake'):
if hasattr(base.cr, 'isFake'):
return
for oldFunc, funcName, newFunc in replaceFuncList:
if base.cr.replaceMethod(oldFunc, newFunc):
print('replaced DistributedObject function: %s' % funcName)
def replaceAIRFunc(replaceFuncList):
try:
simbase.air
except:
except Exception:
return
for oldFunc, funcName, newFunc in replaceFuncList:
if simbase.air.replaceMethod(oldFunc, newFunc):
print('replaced DistributedObject function: %s' % funcName)
def replaceIvalFunc(replaceFuncList):
# Make sure we have imported IntervalManager and thus created
# a global ivalMgr.

View File

@ -17,10 +17,12 @@ GarbageCycleCountAnnounceEvent = 'announceGarbageCycleDesc2num'
class FakeObject:
pass
class FakeDelObject:
def __del__(self):
pass
def _createGarbage(num=1):
for i in range(num):
a = FakeObject()
@ -32,6 +34,7 @@ def _createGarbage(num=1):
a.other = b
b.other = a
class GarbageReport(Job):
"""Detects leaked Python objects (via gc.collect()) and reports on garbage
items, garbage-to-garbage references, and garbage cycles.
@ -544,19 +547,23 @@ class GarbageReport(Job):
break
yield cycles
class GarbageLogger(GarbageReport):
"""If you just want to log the current garbage to the log file, make
one of these. It automatically destroys itself after logging"""
def __init__(self, name, *args, **kArgs):
kArgs['log'] = True
kArgs['autoDestroy'] = True
GarbageReport.__init__(self, name, *args, **kArgs)
class _CFGLGlobals:
# for checkForGarbageLeaks
LastNumGarbage = 0
LastNumCycles = 0
def checkForGarbageLeaks():
gc.collect()
numGarbage = len(gc.garbage)
@ -577,6 +584,7 @@ def checkForGarbageLeaks():
func('%s garbage cycles found, see info above' % _CFGLGlobals.LastNumCycles)
return numGarbage
def b_checkForGarbageLeaks(wantReply=False):
if not __dev__:
return 0
@ -586,7 +594,7 @@ def b_checkForGarbageLeaks(wantReply=False):
try:
# if this is the client, tell the AI to check for leaks too
base.cr.timeManager
except:
except Exception:
pass
else:
if base.cr.timeManager:

View File

@ -122,11 +122,7 @@ class SceneGraphLeakDetector(LeakDetector):
LeakDetector.destroy(self)
def __len__(self):
try:
# this will be available when the build server finishes
return self._render.countNumDescendants()
except:
return self._render.getNumDescendants()
def __repr__(self):
return 'SceneGraphLeakDetector(%s)' % self._render
@ -138,15 +134,7 @@ class SceneGraphLeakDetector(LeakDetector):
class CppMemoryUsage(LeakDetector):
def __len__(self):
haveMemoryUsage = True
try:
MemoryUsage
except:
haveMemoryUsage = False
if haveMemoryUsage:
return int(MemoryUsage.getCurrentCppSize())
else:
return 0
return MemoryUsage.getCurrentCppSize()
class TaskLeakDetectorBase:

View File

@ -480,8 +480,8 @@ class Loader(DirectObject):
i += 1
return cb
# font loading funcs
def loadFont(self, modelPath,
spaceAdvance = None, lineHeight = None,
pointSize = None,
@ -926,7 +926,6 @@ class Loader(DirectObject):
return texture
def unloadTexture(self, texture):
"""
Removes the previously-loaded texture from the cache, so
that when the last reference to it is gone, it will be
@ -971,7 +970,6 @@ class Loader(DirectObject):
def loadSound(self, manager, soundPath, positional = False,
callback = None, extraArgs = []):
"""Loads one or more sound files, specifying the particular
AudioManager that should be used to load them. The soundPath
may be either a single filename, or a list of filenames. If a
@ -1021,7 +1019,7 @@ class Loader(DirectObject):
def unloadSfx(self, sfx):
if sfx:
if self.base.sfxManagerList:
self.base.sfxManagerList[0].uncacheSound (sfx.getName())
self.base.sfxManagerList[0].uncacheSound(sfx.getName())
## def makeNodeNamesUnique(self, nodePath, nodeCount):
## if nodeCount == 0:
@ -1033,7 +1031,7 @@ class Loader(DirectObject):
## self.makeNodeNamesUnique(nodePath.getChild(i), nodeCount)
def loadShader(self, shaderPath, okMissing = False):
shader = ShaderPool.loadShader (shaderPath)
shader = ShaderPool.loadShader(shaderPath)
if not shader and not okMissing:
message = 'Could not load shader file: %s' % (shaderPath)
raise IOError(message)

View File

@ -417,7 +417,7 @@ class Messenger:
# Release the lock temporarily while we call the method.
self.lock.release()
try:
result = method (*(extraArgs + sentArgs))
result = method(*(extraArgs + sentArgs))
finally:
self.lock.acquire()

View File

@ -11,12 +11,15 @@ import builtins
class MessengerLeakObject(DirectObject):
def __init__(self):
self.accept('leakEvent', self._handleEvent)
def _handleEvent(self):
pass
def _leakMessengerObject():
leakObject = MessengerLeakObject()
class MessengerLeakDetector(Job):
# check for objects that are only referenced by the messenger
# and would otherwise be garbage collected
@ -37,19 +40,19 @@ class MessengerLeakDetector(Job):
builtinIds.add(id(base))
builtinIds.add(id(base.cr))
builtinIds.add(id(base.cr.doId2do))
except:
except Exception:
pass
try:
builtinIds.add(id(simbase))
builtinIds.add(id(simbase.air))
builtinIds.add(id(simbase.air.doId2do))
except:
except Exception:
pass
try:
builtinIds.add(id(uber))
builtinIds.add(id(uber.air))
builtinIds.add(id(uber.air.doId2do))
except:
except Exception:
pass
while True:

View File

@ -43,7 +43,7 @@ class ObjectPool:
self._type2objs[typ].append(obj)
try:
self._len2obj[len(obj)] = obj
except:
except Exception:
pass
self._count2types = invertDictLossless(type2count)

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ __all__ = ['randHash', 'RandomNumGen']
from direct.directnotify import DirectNotifyGlobal
from panda3d.core import Mersenne
def randHash(num):
""" this returns a random 16-bit integer, given a seed integer.
It will always return the same output given the same input.
@ -14,9 +15,9 @@ def randHash(num):
rng = RandomNumGen(num)
return rng.randint(0, (1<<16) - 1)
class RandomNumGen:
notify = \
DirectNotifyGlobal.directNotify.newCategory("RandomNumGen")
notify = DirectNotifyGlobal.directNotify.newCategory("RandomNumGen")
def __init__(self, seed):
"""seed must be an integer or another RandomNumGen"""

View File

@ -113,7 +113,7 @@ class ReferrerSearch(Job):
(isinstance(ref, dict) and \
list(ref.keys()) == list(locals().keys())) or \
ref is self.__dict__ or \
id(ref) in self.visited) ]
id(ref) in self.visited)]
# Check to see if this object has an unusually large
# ref-count. This usually indicates that it is some
@ -162,7 +162,7 @@ class ReferrerSearch(Job):
# We found the reference on self
ref is self.__dict__ or \
# We've already seen this referrer
id(ref) in self.visited) ]
id(ref) in self.visited)]
# Check to see if this object has an unusually large
# ref-count. This usually indicates that it is some

View File

@ -146,6 +146,7 @@ if __debug__:
from . import OnScreenDebug
import warnings
@atexit.register
def exitfunc():
if getattr(builtins, 'base', None) is not None:
@ -154,6 +155,8 @@ def exitfunc():
# Now ShowBase is a DirectObject. We need this so ShowBase can hang
# hooks on messages, particularly on window-event. This doesn't
# *seem* to cause anyone any problems.
class ShowBase(DirectObject.DirectObject):
#: The deprecated `.DConfig` interface for accessing config variables.
@ -610,6 +613,7 @@ class ShowBase(DirectObject.DirectObject):
def pushCTrav(self, cTrav):
self.cTravStack.push(self.cTrav)
self.cTrav = cTrav
def popCTrav(self):
self.cTrav = self.cTravStack.pop()
@ -829,7 +833,7 @@ class ShowBase(DirectObject.DirectObject):
# Save this lambda here for convenience; we'll use it to call
# down to the underlying _doOpenWindow() with all of the above
# parameters.
func = lambda : self._doOpenWindow(
func = lambda: self._doOpenWindow(
props = props, fbprops = fbprops, pipe = pipe, gsg = gsg,
host = host, type = type, name = name, size = size,
aspectRatio = aspectRatio, makeCamera = makeCamera,
@ -1728,7 +1732,6 @@ class ShowBase(DirectObject.DirectObject):
np = mw.getParent().attachNewNode(mouseRecorder)
mw.reparentTo(np)
mw = self.buttonThrowers[0].getParent()
#: A special ButtonThrower to generate keyboard events and
@ -2861,7 +2864,6 @@ class ShowBase(DirectObject.DirectObject):
camera = None, size = 128,
cameraMask = PandaNode.getAllCameraMask(),
sourceLens = None):
"""
Similar to :meth:`screenshot()`, this sets up a temporary cube
map Texture which it uses to take a series of six snapshots of
@ -3428,7 +3430,6 @@ class ShowBase(DirectObject.DirectObject):
(self.appRunner.interactiveConsole and not self.appRunner.initialAppImport):
self.taskMgr.run()
# Snake-case aliases, for people who prefer these. We're in the process
# of migrating everyone to use the snake-case alternatives.
make_default_pipe = makeDefaultPipe

View File

@ -255,7 +255,6 @@ class Transitions:
self.alphaOn.set(r, g, b, 1)
self.alphaOff.set(r, g, b, 0)
##################################################
# Iris
##################################################

View File

@ -31,11 +31,11 @@ sharedPackages = {}
vfs = VirtualFileSystem.getGlobalPtr()
compiledExtensions = [ 'pyc', 'pyo' ]
compiledExtensions = ['pyc', 'pyo']
if not __debug__:
# In optimized mode, we prefer loading .pyo files over .pyc files.
# We implement that by reversing the extension names.
compiledExtensions = [ 'pyo', 'pyc' ]
compiledExtensions = ['pyo', 'pyc']
class VFSImporter:
@ -104,6 +104,7 @@ class VFSImporter:
#print >>sys.stderr, "not found."
return None
class VFSLoader:
""" The second part of VFSImporter, this is created for a
particular .py file or directory. """
@ -298,7 +299,6 @@ class VFSLoader:
else:
raise ValueError("Timestamp wrong on %s" % (vfile))
def _compile(self, filename, source):
""" Compiles the Python source code to a code object and
attempts to write it to an appropriate .pyc file. May raise
@ -472,6 +472,8 @@ class VFSSharedLoader:
_registered = False
def register():
""" Register the VFSImporter on the path_hooks, if it has not
already been registered, so that future Python import statements

View File

@ -51,7 +51,7 @@ def addCircle(attachNode, vertexCount, radius, color = Vec4(1.0, 1.0, 1.0, 1.0),
targetCircleColorWriter.addData4f(centerColor[0], centerColor[1], centerColor[2], centerColor[3])
for vertex in targetCircleShape:
targetCircleVertexWriter.addData3f(0.0 + vertex[0] , 0.0 + vertex[1] , zFloat)
targetCircleVertexWriter.addData3f(0.0 + vertex[0], 0.0 + vertex[1], zFloat)
targetCircleColorWriter.addData4f(color[0], color[1], color[2], color[3])
#targetCircleColorWriter.addData4f(1.0, 1.0, 1.0, 1.0)
@ -96,7 +96,6 @@ def addSquare(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer
boxColorWriter = GeomVertexWriter(boxVertexData, "color")
boxTextureWriter = GeomVertexWriter(boxVertexData, "texcoord")
boxVertexWriter.addData3f(-sX, sY, 0.0)
boxNormalWriter.addData3f(0, 0, 1)
boxColorWriter.addData4f(color[0], color[1], color[2], color[3])
@ -128,7 +127,6 @@ def addSquare(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer
boxGeom = Geom(boxVertexData)
boxGeom.addPrimitive(boxTris)
attachNode.addGeom(boxGeom)
return boxGeom
@ -163,7 +161,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
boxNormalWriter = GeomVertexWriter(boxVertexData, "normal")
boxColorWriter = GeomVertexWriter(boxVertexData, "color")
#Front
boxVertexWriter.addData3f(sX, sY, sZ)
@ -254,7 +251,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
boxNormalWriter.addData3f(0, 0, 1)
boxColorWriter.addData4f(color1[0], color1[1], color1[2], color1[3])
#Left
boxVertexWriter.addData3f(-sX, sY, -sZ)
@ -273,7 +269,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
boxNormalWriter.addData3f(0, 0, 1)
boxColorWriter.addData4f(color2[0], color2[1], color2[2], color2[3])
boxTris = GeomTristrips(Geom.UHStatic) # trianglestrip obejcet
boxTris.addVertex(0)#(1)
boxTris.addVertex(1)#(2)
@ -314,7 +309,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
boxGeom = Geom(boxVertexData)
boxGeom.addPrimitive(boxTris)
attachNode.addGeom(boxGeom)
return boxGeom
@ -344,7 +338,6 @@ def addArrow(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer =
boxNormalWriter = GeomVertexWriter(boxVertexData, "normal")
boxColorWriter = GeomVertexWriter(boxVertexData, "color")
boxVertexWriter.addData3f(-sX, sY, 0.0)
boxNormalWriter.addData3f(0, 0, 1)
boxColorWriter.addData4f(color[0], color[1], color[2], color[3])
@ -386,11 +379,9 @@ def addArrow(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer =
boxTris.addVertex(6)
boxTris.closePrimitive()
boxGeom = Geom(boxVertexData)
boxGeom.addPrimitive(boxTris)
attachNode.addGeom(boxGeom)
return boxGeom

View File

@ -8,7 +8,7 @@ __all__ = [
'open', 'listdir', 'walk', 'join',
'isfile', 'isdir', 'exists', 'lexists', 'getmtime', 'getsize',
'execfile',
]
]
from panda3d import core
import os
@ -293,6 +293,7 @@ def listdir(path):
files.append(file.getFilename().getBasename())
return files
def walk(top, topdown = True, onerror = None, followlinks = True):
""" Implements os.walk over vfs.
@ -321,30 +322,37 @@ def walk(top, topdown = True, onerror = None, followlinks = True):
if not topdown:
yield (top, dirnames, filenames)
def isfile(path):
return _vfs.isRegularFile(core.Filename.fromOsSpecific(path))
def isdir(path):
return _vfs.isDirectory(core.Filename.fromOsSpecific(path))
def exists(path):
return _vfs.exists(core.Filename.fromOsSpecific(path))
def lexists(path):
return _vfs.exists(core.Filename.fromOsSpecific(path))
def getmtime(path):
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
if not file:
raise os.error
return file.getTimestamp()
def getsize(path):
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
if not file:
raise os.error
return file.getFileSize()
def execfile(path, globals=None, locals=None):
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
if not file:

View File

@ -14,7 +14,7 @@ __all__ = [
'force_yield', 'consider_yield',
'forceYield', 'considerYield',
'TIMEOUT_MAX'
]
]
from panda3d import core
import sys
@ -85,17 +85,22 @@ class LockType:
def __exit__(self, t, v, tb):
self.release()
# Helper to generate new thread names
_counter = 0
def _newname(template="Thread-%d"):
global _counter
_counter = _counter + 1
return template % _counter
_threads = {}
_nextThreadId = 0
_threadsLock = core.Mutex('thread._threadsLock')
def start_new_thread(function, args, kwargs = {}, name = None):
def threadFunc(threadId, function = function, args = args, kwargs = kwargs):
try:
@ -126,6 +131,7 @@ def start_new_thread(function, args, kwargs = {}, name = None):
finally:
_threadsLock.release()
def _add_thread(thread, wrapper):
""" Adds the indicated core.Thread object, with the indicated Python
wrapper, to the thread list. Returns the new thread ID. """
@ -143,6 +149,7 @@ def _add_thread(thread, wrapper):
finally:
_threadsLock.release()
def _get_thread_wrapper(thread, wrapperClass):
""" Returns the thread wrapper for the indicated thread. If there
is not one, creates an instance of the indicated wrapperClass
@ -180,6 +187,7 @@ def _get_thread_wrapper(thread, wrapperClass):
finally:
_threadsLock.release()
def _get_thread_locals(thread, i):
""" Returns the locals dictionary for the indicated thread. If
there is not one, creates an empty dictionary. """
@ -237,15 +245,19 @@ def interrupt_main():
# TODO.
pass
def exit():
raise SystemExit
def allocate_lock():
return LockType()
def get_ident():
return core.Thread.getCurrentThread().this
def stack_size(size = 0):
raise error

View File

@ -41,7 +41,7 @@ __all__ = [
'enumerate', 'active_count',
'settrace', 'setprofile', 'stack_size',
'TIMEOUT_MAX',
]
]
TIMEOUT_MAX = _thread.TIMEOUT_MAX
@ -49,6 +49,7 @@ local = _thread._local
_newname = _thread._newname
ThreadError = _thread.error
class ThreadBase:
""" A base class for both Thread and ExternalThread in this
module. """
@ -78,12 +79,14 @@ class ThreadBase:
else:
self.__dict__[key] = value
# Copy these static methods from Panda's Thread object. These are
# useful if you may be running in Panda's SIMPLE_THREADS compilation
# mode.
ThreadBase.forceYield = core.Thread.forceYield
ThreadBase.considerYield = core.Thread.considerYield
class Thread(ThreadBase):
""" This class provides a wrapper around Panda's PythonThread
object. The wrapper is designed to emulate Python's own
@ -161,6 +164,7 @@ class Thread(ThreadBase):
self.__dict__['name'] = name
self.__thread.setName(name)
class ExternalThread(ThreadBase):
""" Returned for a Thread object that wasn't created by this
interface. """
@ -191,6 +195,7 @@ class ExternalThread(ThreadBase):
def setDaemon(self, daemon):
raise RuntimeError
class MainThread(ExternalThread):
""" Returned for the MainThread object. """
@ -198,6 +203,7 @@ class MainThread(ExternalThread):
ExternalThread.__init__(self, extThread, threadId)
self.__dict__['daemon'] = False
class Lock(core.Mutex):
""" This class provides a wrapper around Panda's Mutex object.
The wrapper is designed to emulate Python's own threading.Lock
@ -254,6 +260,7 @@ class Condition(core.ConditionVar):
def __exit__(self, t, v, tb):
self.release()
class Semaphore(core.Semaphore):
""" This class provides a wrapper around Panda's Semaphore
object. The wrapper is designed to emulate Python's own
@ -274,6 +281,7 @@ class Semaphore(core.Semaphore):
def __exit__(self, t, v, tb):
self.release()
class BoundedSemaphore(Semaphore):
""" This class provides a wrapper around Panda's Semaphore
object. The wrapper is designed to emulate Python's own
@ -289,6 +297,7 @@ class BoundedSemaphore(Semaphore):
Semaphore.release(self)
class Event:
""" This class is designed to emulate Python's own threading.Event
object. """
@ -339,6 +348,7 @@ class Event:
finally:
self.__lock.release()
class Timer(Thread):
"""Call a function after a specified number of seconds:
@ -365,6 +375,7 @@ class Timer(Thread):
self.function(*self.args, **self.kwargs)
self.finished.set()
def _create_thread_wrapper(t, threadId):
""" Creates a thread wrapper for the indicated external thread. """
if isinstance(t, core.MainThread):
@ -374,16 +385,20 @@ def _create_thread_wrapper(t, threadId):
return pyt
def current_thread():
t = core.Thread.getCurrentThread()
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
def main_thread():
t = core.Thread.getMainThread()
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
currentThread = current_thread
def enumerate():
tlist = []
_thread._threadsLock.acquire()
@ -395,24 +410,33 @@ def enumerate():
finally:
_thread._threadsLock.release()
def active_count():
return len(enumerate())
activeCount = active_count
_settrace_func = None
def settrace(func):
global _settrace_func
_settrace_func = func
_setprofile_func = None
def setprofile(func):
global _setprofile_func
_setprofile_func = func
def stack_size(size = None):
raise ThreadError
if __debug__:
def _test():
from collections import deque
@ -482,7 +506,6 @@ if __debug__:
self.queue.put("%s.%d" % (self.getName(), counter))
_sleep(random() * 0.00001)
class ConsumerThread(Thread):
def __init__(self, queue, count):

View File

@ -74,10 +74,11 @@ def print_exc_plus():
#error we don't want.
try:
valueStr = str(value)
except:
except Exception:
valueStr = "<ERROR WHILE PRINTING VALUE>"
print("\t%20s = %s" % (key, valueStr))
# For historical purposes, we remap the C++-defined enumeration to
# these Python names, and define them both at the module level, here,
# and at the class level (below). The preferred access is via the
@ -109,21 +110,28 @@ Task.DtoolClassDict['pause'] = staticmethod(pause)
gather = Task.gather
shield = Task.shield
def sequence(*taskList):
seq = AsyncTaskSequence('sequence')
for task in taskList:
seq.addTask(task)
return seq
Task.DtoolClassDict['sequence'] = staticmethod(sequence)
def loop(*taskList):
seq = AsyncTaskSequence('loop')
for task in taskList:
seq.addTask(task)
seq.setRepeatCount(-1)
return seq
Task.DtoolClassDict['loop'] = staticmethod(loop)
class TaskManager:
notify = directNotify.newCategory("TaskManager")
@ -317,7 +325,6 @@ class TaskManager:
def doMethodLater(self, delayTime, funcOrTask, name, extraArgs = None,
sort = None, priority = None, taskChain = None,
uponDeath = None, appendTask = False, owner = None):
"""Adds a task to be performed at some time in the future.
This is identical to `add()`, except that the specified
delayTime is applied to the Task object first, which means
@ -553,6 +560,7 @@ class TaskManager:
try:
if len(self._frameProfileQueue) > 0:
numFrames, session, callback = self._frameProfileQueue.pop(0)
def _profileFunc(numFrames=numFrames):
self._doProfiledFrames(numFrames)
session.setFunc(_profileFunc)
@ -605,7 +613,7 @@ class TaskManager:
# a nested try block are not caught by the inner try block's except
try:
(code, message) = ioError
except:
except Exception:
code = 0
message = ioError
return code, message
@ -817,6 +825,7 @@ class TaskManager:
# run-once task
l = []
def _testDone(task, l=l):
l.append(None)
return task.done
@ -848,6 +857,7 @@ class TaskManager:
# continued task
l = []
def _testCont(task, l = l):
l.append(None)
return task.cont
@ -862,6 +872,7 @@ class TaskManager:
# continue until done task
l = []
def _testContDone(task, l = l):
l.append(None)
if len(l) >= 2:
@ -891,9 +902,11 @@ class TaskManager:
# task sort
l = []
def _testPri1(task, l = l):
l.append(1)
return task.cont
def _testPri2(task, l = l):
l.append(2)
return task.cont
@ -913,6 +926,7 @@ class TaskManager:
# task extraArgs
l = []
def _testExtraArgs(arg1, arg2, l=l):
l.extend([arg1, arg2,])
return done
@ -925,6 +939,7 @@ class TaskManager:
# task appendTask
l = []
def _testAppendTask(arg1, arg2, task, l=l):
l.extend([arg1, arg2,])
return task.done
@ -937,8 +952,10 @@ class TaskManager:
# task uponDeath
l = []
def _uponDeathFunc(task, l=l):
l.append(task.name)
def _testUponDeath(task):
return done
tm.add(_testUponDeath, 'testUponDeath', uponDeath=_uponDeathFunc)
@ -953,10 +970,12 @@ class TaskManager:
class _TaskOwner:
def _addTask(self, task):
self.addedTaskName = task.name
def _clearTask(self, task):
self.clearedTaskName = task.name
to = _TaskOwner()
l = []
def _testOwner(task):
return done
tm.add(_testOwner, 'testOwner', owner=to)
@ -968,15 +987,17 @@ class TaskManager:
_TaskOwner = None
tm._checkMemLeaks()
doLaterTests = [0,]
# doLater
l = []
def _testDoLater1(task, l=l):
l.append(1)
def _testDoLater2(task, l=l):
l.append(2)
def _monitorDoLater(task, tm=tm, l=l, doLaterTests=doLaterTests):
if task.time > .03:
assert l == [1, 2,]
@ -996,10 +1017,13 @@ class TaskManager:
# doLater sort
l = []
def _testDoLaterPri1(task, l=l):
l.append(1)
def _testDoLaterPri2(task, l=l):
l.append(2)
def _monitorDoLaterPri(task, tm=tm, l=l, doLaterTests=doLaterTests):
if task.time > .02:
assert l == [1, 2,]
@ -1019,8 +1043,10 @@ class TaskManager:
# doLater extraArgs
l = []
def _testDoLaterExtraArgs(arg1, l=l):
l.append(arg1)
def _monitorDoLaterExtraArgs(task, tm=tm, l=l, doLaterTests=doLaterTests):
if task.time > .02:
assert l == [3,]
@ -1038,9 +1064,11 @@ class TaskManager:
# doLater appendTask
l = []
def _testDoLaterAppendTask(arg1, task, l=l):
assert task.name == 'testDoLaterAppendTask'
l.append(arg1)
def _monitorDoLaterAppendTask(task, tm=tm, l=l, doLaterTests=doLaterTests):
if task.time > .02:
assert l == [4,]
@ -1059,11 +1087,14 @@ class TaskManager:
# doLater uponDeath
l = []
def _testUponDeathFunc(task, l=l):
assert task.name == 'testDoLaterUponDeath'
l.append(10)
def _testDoLaterUponDeath(arg1, l=l):
return done
def _monitorDoLaterUponDeath(task, tm=tm, l=l, doLaterTests=doLaterTests):
if task.time > .02:
assert l == [10,]
@ -1085,12 +1116,15 @@ class TaskManager:
class _DoLaterOwner:
def _addTask(self, task):
self.addedTaskName = task.name
def _clearTask(self, task):
self.clearedTaskName = task.name
doLaterOwner = _DoLaterOwner()
l = []
def _testDoLaterOwner(l=l):
pass
def _monitorDoLaterOwner(task, tm=tm, l=l, doLaterOwner=doLaterOwner,
doLaterTests=doLaterTests):
if task.time > .02:
@ -1223,6 +1257,7 @@ class TaskManager:
# create Task object and add to mgr
l = []
def _testTaskObj(task, l=l):
l.append(None)
return task.cont
@ -1240,6 +1275,7 @@ class TaskManager:
# remove Task via task.remove()
l = []
def _testTaskObjRemove(task, l=l):
l.append(None)
return task.cont
@ -1299,6 +1335,7 @@ if __debug__:
gc.enable()
from direct.showbase.DirectObject import DirectObject
from direct.task.TaskManagerGlobal import taskMgr
class TestClass(DirectObject):
def doTask(self, task):
return task.done

View File

@ -19,6 +19,7 @@ import tkinter as tk
FRAMES = 0
SECONDS = 1
class AnimPanel(AppShell):
# Override class variables
appname = 'Anim Panel'
@ -55,7 +56,6 @@ class AnimPanel(AppShell):
# Initialize the superclass
AppShell.__init__(self)
# Execute option callbacks
self.initialiseoptions(AnimPanel)
# We need to know when AnimPanel is closed
@ -291,7 +291,6 @@ class AnimPanel(AppShell):
self.clearActorControls()
self.createActorControls()
def playActorControls(self):
self.stopActorControls()
self.lastT = ClockObject.getGlobalClock().getFrameTime()
@ -372,6 +371,7 @@ class AnimPanel(AppShell):
self.destroyCallBack = None
AppShell.destroy(self)
class ActorControl(Pmw.MegaWidget):
def __init__(self, parent = None, **kw):
@ -662,6 +662,7 @@ class ActorControl(Pmw.MegaWidget):
self.fOneShot = 1
self.goToT((self.currT-(1/self.fps))%self.duration)
"""
# EXAMPLE CODE
from direct.actor import Actor

View File

@ -476,7 +476,6 @@ class DirectSessionPanel(AppShell):
lightFrame.pack(expand = 1, fill = tk.BOTH)
def createGridPage(self, gridPage):
tk.Label(gridPage, text = 'Grid',
font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
@ -649,7 +648,7 @@ class DirectSessionPanel(AppShell):
else:
# Good eval but not a node path, give up
nodePath = None
except:
except Exception:
# Bogus eval
nodePath = None
# Clear bogus entry from listbox
@ -699,7 +698,7 @@ class DirectSessionPanel(AppShell):
else:
# Good eval but not a node path, give up
nodePath = None
except:
except Exception:
# Bogus eval
nodePath = None
# Clear bogus entry from listbox
@ -740,6 +739,7 @@ class DirectSessionPanel(AppShell):
# Background #
def setBackgroundColor(self, r, g, b):
self.setBackgroundColorVec((r, g, b))
def setBackgroundColorVec(self, color):
base.setBackgroundColor(color[0]/255.0,
color[1]/255.0,

View File

@ -393,6 +393,7 @@ class FSMInspector(AppShell):
self.ignore(self.name + '_' + si.getName() + '_entered')
self.ignore(self.name + '_' + si.getName() + '_exited')
class StateInspector(Pmw.MegaArchetype):
def __init__(self, inspector, state, **kw):
@ -439,7 +440,6 @@ class StateInspector(Pmw.MegaArchetype):
half, half,
tags = (self.tag,))
# The Popup State Menu
self._popupMenu = tk.Menu(self._canvas, tearoff = 0)
self._popupMenu.add_command(label = 'Request transition to ' +

View File

@ -19,6 +19,7 @@ import tkinter as tk
### public API
def inspect(anObject):
"""Opens up a window for visually inspecting the details of a given Python
object. See :ref:`inspection-utilities`.
@ -30,6 +31,7 @@ def inspect(anObject):
### private
def inspectorFor(anObject):
typeName = type(anObject).__name__.capitalize() + 'Type'
if typeName in _InspectorMap:
@ -72,7 +74,8 @@ def initializeInspectorMap():
'StringType': 'SequenceInspector',
'TupleType': 'SequenceInspector',
'TypeType': 'Inspector',
'UnboundMethodType': 'FunctionInspector'}
'UnboundMethodType': 'FunctionInspector',
}
for each in notFinishedTypes:
_InspectorMap[each] = 'Inspector'
@ -119,10 +122,7 @@ class Inspector:
object = self.partNumber(partNumber)
doc = None
if callable(object):
try:
doc = object.__doc__
except:
pass
doc = getattr(object, '__doc__', None)
if doc:
return str(object) + '\n' + str(doc)
else:
@ -150,10 +150,12 @@ class Inspector:
###
class ModuleInspector(Inspector):
def namedParts(self):
return ['__dict__']
class ClassInspector(Inspector):
def namedParts(self):
return ['__bases__'] + list(self.object.__dict__.keys())
@ -161,34 +163,41 @@ class ClassInspector(Inspector):
def title(self):
return self.object.__name__ + ' Class'
class InstanceInspector(Inspector):
def title(self):
return self.object.__class__.__name__
def namedParts(self):
return ['__class__'] + dir(self.object)
###
class FunctionInspector(Inspector):
def title(self):
return self.object.__name__ + "()"
class InstanceMethodInspector(Inspector):
def title(self):
return str(self.object.__self__.__class__) + "." + self.object.__name__ + "()"
class CodeInspector(Inspector):
def title(self):
return str(self.object)
###
class ComplexInspector(Inspector):
def namedParts(self):
return ['real', 'imag']
###
class DictionaryInspector(Inspector):
def initializePartsList(self):
@ -208,6 +217,7 @@ class DictionaryInspector(Inspector):
else:
return getattr(self.object, key)
class SequenceInspector(Inspector):
def initializePartsList(self):
Inspector.initializePartsList(self)
@ -224,6 +234,7 @@ class SequenceInspector(Inspector):
else:
return getattr(self.object, index)
class SliceInspector(Inspector):
def namedParts(self):
return ['start', 'stop', 'step']
@ -232,6 +243,7 @@ class SliceInspector(Inspector):
### Initialization
initializeInspectorMap()
class InspectorWindow:
def __init__(self, inspector):
self.inspectors = [inspector]
@ -346,8 +358,8 @@ class InspectorWindow:
command = self.commandWidget.get(commandStart,
commandStart + ' lineend')
if command:
partDict = { 'this': self.selectedPart(),
'object': self.topInspector().object }
partDict = {'this': self.selectedPart(),
'object': self.topInspector().object}
result = eval(command, partDict)
self.commandWidget.insert(tk.INSERT, repr(result) + '\n>>> ')
self.commandWidget.see(tk.INSERT)

View File

@ -46,6 +46,7 @@ PRF_UTILITIES = [
'lambda s = self: s.playbackMarker.setZ(render, 0.0)',
'lambda s = self: s.followTerrain(10.0)']
class MopathRecorder(AppShell, DirectObject):
# Override class variables here
appname = 'Mopath Recorder Panel'
@ -930,6 +931,7 @@ class MopathRecorder(AppShell, DirectObject):
def disableKeyframeButton(self):
self.getWidget('Recording', 'Add Keyframe')['state'] = 'disabled'
def enableKeyframeButton(self):
self.getWidget('Recording', 'Add Keyframe')['state'] = 'normal'
@ -1211,7 +1213,7 @@ class MopathRecorder(AppShell, DirectObject):
else:
# Good eval but not a node path, give up
nodePath = None
except:
except Exception:
# Bogus eval
nodePath = None
# Clear bogus entry from listbox

View File

@ -113,7 +113,6 @@ class ParticlePanel(AppShell):
self.particleEffect)
self.forcePagesDict = {}
def createInterface(self):
# Handle to the toplevels hull
interior = self.interior()
@ -171,6 +170,7 @@ class ParticlePanel(AppShell):
self.effectsLabelMenu.add_command(
label = 'Place Particle Effect',
command = lambda s = self: Placer.place(s.particleEffect))
def togglePEVis(s = self):
if s.particleEffect.isHidden():
s.particleEffect.show()
@ -327,8 +327,7 @@ class ParticlePanel(AppShell):
self.createCheckbutton(
zSpinPage, 'Z Spin Factory', 'Enable Angular Velocity',
("On: angular velocity is used; " +
"Off: final angle is used"),
'On: angular velocity is used; Off: final angle is used',
self.toggleAngularVelocity, 0, side = tk.TOP)
self.createFloater(
@ -1379,24 +1378,33 @@ class ParticlePanel(AppShell):
self.particles.getLocalVelocityFlag())
self.getVariable('System', 'System Grows Older').set(
self.particles.getSystemGrowsOlderFlag())
def setSystemPoolSize(self, value):
self.particles.setPoolSize(int(value))
def setSystemBirthRate(self, value):
self.particles.setBirthRate(value)
def setSystemLitterSize(self, value):
self.particles.setLitterSize(int(value))
def setSystemLitterSpread(self, value):
self.particles.setLitterSpread(int(value))
def setSystemLifespan(self, value):
self.particles.setSystemLifespan(value)
def toggleSystemLocalVelocity(self):
self.particles.setLocalVelocityFlag(
self.getVariable('System', 'Render Space Velocities').get())
def toggleSystemGrowsOlder(self):
self.particles.setSystemGrowsOlderFlag(
self.getVariable('System', 'System Grows Older').get())
def setSystemPos(self, pos):
self.particles.nodePath.setPos(Vec3(pos[0], pos[1], pos[2]))
def setSystemHpr(self, pos):
self.particles.nodePath.setHpr(Vec3(pos[0], pos[1], pos[2]))
@ -1427,28 +1435,39 @@ class ParticlePanel(AppShell):
def setFactoryLifeSpan(self, value):
self.particles.factory.setLifespanBase(value)
def setFactoryLifeSpanSpread(self, value):
self.particles.factory.setLifespanSpread(value)
def setFactoryParticleMass(self, value):
self.particles.factory.setMassBase(value)
def setFactoryParticleMassSpread(self, value):
self.particles.factory.setMassSpread(value)
def setFactoryTerminalVelocity(self, value):
self.particles.factory.setTerminalVelocityBase(value)
def setFactoryTerminalVelocitySpread(self, value):
self.particles.factory.setTerminalVelocitySpread(value)
# Point Page #
# Z Spin Page #
def setFactoryZSpinInitialAngle(self, angle):
self.particles.factory.setInitialAngle(angle)
def setFactoryZSpinInitialAngleSpread(self, spread):
self.particles.factory.setInitialAngleSpread(spread)
def setFactoryZSpinFinalAngle(self, angle):
self.particles.factory.setFinalAngle(angle)
def setFactoryZSpinFinalAngleSpread(self, spread):
self.particles.factory.setFinalAngleSpread(spread)
def setFactoryZSpinAngularVelocity(self, vel):
self.particles.factory.setAngularVelocity(vel)
def setFactoryZSpinAngularVelocitySpread(self, spread):
self.particles.factory.setAngularVelocitySpread(spread)
@ -1539,6 +1558,7 @@ class ParticlePanel(AppShell):
self.getWidget('Tangent Ring Emitter', 'Radius Spread').set(
radiusSpread, 0)
# All #
def setEmissionType(self, newType = None):
if newType:
type = newType
@ -1601,57 +1621,76 @@ class ParticlePanel(AppShell):
self.particles.emitter.setMinBound(Point3(point[0],
point[1],
point[2]))
def setEmitterBoxPoint2(self, point):
self.particles.emitter.setMaxBound(Point3(point[0],
point[1],
point[2]))
# Disc #
def setEmitterDiscRadius(self, radius):
self.particles.emitter.setRadius(radius)
def setEmitterDiscInnerAngle(self, angle):
self.particles.emitter.setInnerAngle(angle)
def setEmitterDiscInnerVelocity(self, velocity):
self.particles.emitter.setInnerMagnitude(velocity)
def setEmitterDiscOuterAngle(self, angle):
self.particles.emitter.setOuterAngle(angle)
def setEmitterDiscOuterVelocity(self, velocity):
self.particles.emitter.setOuterMagnitude(velocity)
def toggleEmitterDiscCubicLerping(self):
self.particles.emitter.setCubicLerping(
self.getVariable('Disc Emitter', 'Cubic Lerping').get())
# Line #
def setEmitterLinePoint1(self, point):
self.particles.emitter.setEndpoint1(Point3(point[0],
point[1],
point[2]))
def setEmitterLinePoint2(self, point):
self.particles.emitter.setEndpoint2(Point3(point[0],
point[1],
point[2]))
# Point #
def setEmitterPointPosition(self, pos):
self.particles.emitter.setLocation(Point3(pos[0], pos[1], pos[2]))
# Rectangle #
def setEmitterRectanglePoint1(self, point):
self.particles.emitter.setMinBound(Point2(point[0], point[1]))
def setEmitterRectanglePoint2(self, point):
self.particles.emitter.setMaxBound(Point2(point[0], point[1]))
# Ring #
def setEmitterRingRadius(self, radius):
self.particles.emitter.setRadius(radius)
def setEmitterRingRadiusSpread(self, radiusSpread):
self.particles.emitter.setRadiusSpread(radiusSpread)
def setEmitterRingLaunchAngle(self, angle):
self.particles.emitter.setAngle(angle)
# Sphere surface #
def setEmitterSphereSurfaceRadius(self, radius):
self.particles.emitter.setRadius(radius)
# Sphere volume #
def setEmitterSphereVolumeRadius(self, radius):
self.particles.emitter.setRadius(radius)
# Tangent ring #
def setEmitterTangentRingRadius(self, radius):
self.particles.emitter.setRadius(radius)
def setEmitterTangentRingRadiusSpread(self, radiusSpread):
self.particles.emitter.setRadiusSpread(radiusSpread)
@ -1849,13 +1888,16 @@ class ParticlePanel(AppShell):
self.particles.renderer.setHeadColor(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setRendererLineTailColor(self, color):
self.particles.renderer.setTailColor(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setRendererLineScaleFactor(self, sf):
self.particles.renderer.setLineScaleFactor(sf)
# Geom #
def setRendererGeomNode(self, event):
node = None
nodePath = base.loader.loadModel(self.rendererGeomNode.get())
@ -1865,16 +1907,20 @@ class ParticlePanel(AppShell):
self.particles.geomReference = self.rendererGeomNode.get()
self.particles.renderer.setGeomNode(node)
# Point #
def setRendererPointSize(self, size):
self.particles.renderer.setPointSize(size)
def setRendererPointStartColor(self, color):
self.particles.renderer.setStartColor(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setRendererPointEndColor(self, color):
self.particles.renderer.setEndColor(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def rendererPointSelectBlendType(self, blendType):
if blendType == "PP_ONE_COLOR":
bType = PointParticleRenderer.PPONECOLOR
@ -1883,6 +1929,7 @@ class ParticlePanel(AppShell):
elif blendType == "PP_BLEND_VEL":
bType = PointParticleRenderer.PPBLENDVEL
self.particles.renderer.setBlendType(bType)
def rendererPointSelectBlendMethod(self, blendMethod):
if blendMethod == "PP_NO_BLEND":
bMethod = BaseParticleRenderer.PPNOBLEND
@ -1892,18 +1939,23 @@ class ParticlePanel(AppShell):
bMethod = BaseParticleRenderer.PPBLENDCUBIC
self.particles.renderer.setBlendMethod(bMethod)
# Sparkle #
def setRendererSparkleCenterColor(self, color):
self.particles.renderer.setCenterColor(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setRendererSparkleEdgeColor(self, color):
self.particles.renderer.setEdgeColor(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setRendererSparkleBirthRadius(self, radius):
self.particles.renderer.setBirthRadius(radius)
def setRendererSparkleDeathRadius(self, radius):
self.particles.renderer.setDeathRadius(radius)
def setRendererSparkleLifeScale(self, lifeScaleMethod):
if lifeScaleMethod == 'SP_NO_SCALE':
lScale = SparkleParticleRenderer.SPNOSCALE
@ -1911,6 +1963,7 @@ class ParticlePanel(AppShell):
lScale = SparkleParticleRenderer.SPSCALE
self.particles.renderer.setLifeScale(lScale)
# Sprite #
def setSpriteSourceType(self):
if self.rendererSpriteSourceType.get() == 0:
self.rendererSpriteTextureEntry['state'] = 'normal'
@ -1929,9 +1982,11 @@ class ParticlePanel(AppShell):
def setRendererSpriteAnimationFrameRate(self, rate):
self.particles.renderer.setAnimateFramesRate(rate)
def setRendererSpriteAnimationEnable(self):
self.particles.renderer.setAnimateFramesEnable(
self.getVariable('Sprite Renderer','Enable Animation').get())
def addRendererSpriteAnimationTexture(self):
ren = self.particles.getRenderer()
parent = self.rendererSpriteAnimationFrame
@ -1953,6 +2008,7 @@ class ParticlePanel(AppShell):
self.rendererSpriteAnimationWidgetList.append(
self.createSpriteAnimationTextureWidget(parent, anim, repr(frameNum)))
parent.pack(fill=tk.BOTH, expand=1)
def addRendererSpriteAnimationFromNode(self):
ren = self.particles.getRenderer()
parent = self.rendererSpriteAnimationFrame
@ -1978,9 +2034,11 @@ class ParticlePanel(AppShell):
def toggleRendererSpriteXScale(self):
self.particles.renderer.setXScaleFlag(
self.getVariable('Sprite Renderer', 'X Scale').get())
def toggleRendererSpriteYScale(self):
self.particles.renderer.setYScaleFlag(
self.getVariable('Sprite Renderer', 'Y Scale').get())
def toggleRendererSpriteAnimAngle(self):
self.particles.renderer.setAnimAngleFlag(
self.getVariable('Sprite Renderer', 'Anim Angle').get())
@ -1991,14 +2049,19 @@ class ParticlePanel(AppShell):
def setRendererSpriteInitialXScale(self, xScale):
self.particles.renderer.setInitialXScale(xScale)
def setRendererSpriteFinalXScale(self, xScale):
self.particles.renderer.setFinalXScale(xScale)
def setRendererSpriteInitialYScale(self, yScale):
self.particles.renderer.setInitialYScale(yScale)
def setRendererSpriteFinalYScale(self, yScale):
self.particles.renderer.setFinalYScale(yScale)
def setRendererSpriteNonAnimatedTheta(self, theta):
self.particles.renderer.setNonanimatedTheta(theta)
def setRendererSpriteBlendMethod(self, blendMethod):
if blendMethod == 'PP_NO_BLEND':
bMethod = BaseParticleRenderer.PPNOBLEND
@ -2008,9 +2071,11 @@ class ParticlePanel(AppShell):
bMethod = BaseParticleRenderer.PPBLENDCUBIC
else:
bMethod = BaseParticleRenderer.PPNOBLEND
def toggleRendererSpriteAlphaDisable(self):
self.particles.renderer.setAlphaDisable(
self.getVariable('Sprite Renderer', 'Alpha Disable').get())
def setRendererColorBlendAttrib(self, rendererName, blendMethodStr, incomingOperandStr, fbufferOperandStr):
self.particles.getRenderer().setColorBlendMode(getattr(ColorBlendAttrib, blendMethodStr),
getattr(ColorBlendAttrib, incomingOperandStr),
@ -2024,48 +2089,56 @@ class ParticlePanel(AppShell):
self.getWidget(rendererName,'Fbuffer Op.').pack_forget()
self.updateRendererWidgets()
def setRendererSpriteColorBlendMethod(self, blendMethod):
blendMethodStr = blendMethod
incomingOperandStr = self.getVariable('Sprite Renderer','Incoming Op.').get()
fbufferOperandStr = self.getVariable('Sprite Renderer','Fbuffer Op.').get()
self.setRendererColorBlendAttrib('Sprite Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
def setRendererSpriteColorBlendIncomingOperand(self, operand):
blendMethodStr = self.getVariable('Sprite Renderer','Color Blend').get()
incomingOperandStr = operand
fbufferOperandStr = self.getVariable('Sprite Renderer','Fbuffer Op.').get()
self.setRendererColorBlendAttrib('Sprite Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
def setRendererSpriteColorBlendFbufferOperand(self, operand):
blendMethodStr = self.getVariable('Sprite Renderer','Color Blend').get()
incomingOperandStr = self.getVariable('Sprite Renderer','Incoming Op.').get()
fbufferOperandStr = operand
self.setRendererColorBlendAttrib('Sprite Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
# GeomParticleRenderer Functionality
def toggleRendererGeomXScale(self):
self.particles.renderer.setXScaleFlag(
self.getVariable('Geom Renderer', 'X Scale').get())
def toggleRendererGeomYScale(self):
self.particles.renderer.setYScaleFlag(
self.getVariable('Geom Renderer', 'Y Scale').get())
def toggleRendererGeomZScale(self):
self.particles.renderer.setZScaleFlag(
self.getVariable('Geom Renderer', 'Z Scale').get())
def setRendererGeomInitialXScale(self, xScale):
self.particles.renderer.setInitialXScale(xScale)
def setRendererGeomFinalXScale(self, xScale):
self.particles.renderer.setFinalXScale(xScale)
def setRendererGeomInitialYScale(self, yScale):
self.particles.renderer.setInitialYScale(yScale)
def setRendererGeomFinalYScale(self, yScale):
self.particles.renderer.setFinalYScale(yScale)
def setRendererGeomInitialZScale(self, zScale):
self.particles.renderer.setInitialZScale(zScale)
def setRendererGeomFinalZScale(self, zScale):
self.particles.renderer.setFinalZScale(zScale)
@ -2087,7 +2160,6 @@ class ParticlePanel(AppShell):
fbufferOperandStr = operand
self.setRendererColorBlendAttrib('Geom Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
def addConstantInterpolationSegment(self, id = None):
ren = self.particles.getRenderer()
cim = ren.getColorInterpolationManager()
@ -2187,17 +2259,22 @@ class ParticlePanel(AppShell):
def createInterpolationSegmentFrame(self, parent, segName, seg):
frame = tk.Frame(parent, relief = tk.RAISED, borderwidth = 2)
lFrame = tk.Frame(frame, relief = tk.FLAT)
def removeInterpolationSegmentFrame(s = self, seg = seg, fr = frame):
s.particles.getRenderer().getColorInterpolationManager().clearSegment(seg.getId())
fr.pack_forget()
def setSegEnabled(s=self, n=segName):
enabled = s.getVariable('Sprite Renderer', n+' Enabled')
seg.setEnabled(enabled.get())
def setIsModulated(s=self, n=segName):
modulated = s.getVariable('Sprite Renderer', n+' isModulated')
seg.setIsModulated(modulated.get())
def setSegBegin(time):
seg.setTimeBegin(time)
def setSegEnd(time):
seg.setTimeEnd(time)
tk.Button(lFrame, text = 'X',
@ -2236,6 +2313,7 @@ class ParticlePanel(AppShell):
def createConstantInterpolationSegmentWidget(self, parent, segName, segment):
fun = segment.getFunction()
def setSegColorA(color):
fun.setColorA(
Vec4(color[0]/255.0, color[1]/255.0,
@ -2255,10 +2333,12 @@ class ParticlePanel(AppShell):
def createLinearInterpolationSegmentWidget(self, parent, segName, segment):
fun = segment.getFunction()
def setSegColorA(color):
fun.setColorA(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setSegColorB(color):
fun.setColorB(
Vec4(color[0]/255.0, color[1]/255.0,
@ -2284,16 +2364,20 @@ class ParticlePanel(AppShell):
def createStepwaveInterpolationSegmentWidget(self, parent, segName, segment):
fun = segment.getFunction()
def setColorA(color):
fun.setColorA(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setColorB(color):
fun.setColorB(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setWidthA(width):
fun.setWidthA(width)
def setWidthB(width):
fun.setWidthB(width)
@ -2327,14 +2411,17 @@ class ParticlePanel(AppShell):
def createSinusoidInterpolationSegmentWidget(self, parent, segName, segment):
fun = segment.getFunction()
def setColorA(color):
fun.setColorA(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setColorB(color):
fun.setColorB(
Vec4(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0))
def setPeriod(period):
fun.setPeriod(period)
@ -2543,18 +2630,25 @@ class ParticlePanel(AppShell):
def addLinearVectorForce(self):
self.addForce(LinearVectorForce())
def addLinearFrictionForce(self):
self.addForce(LinearFrictionForce())
def addLinearJitterForce(self):
self.addForce(LinearJitterForce())
def addLinearNoiseForce(self):
self.addForce(LinearNoiseForce())
def addLinearSinkForce(self):
self.addForce(LinearSinkForce())
def addLinearSourceForce(self):
self.addForce(LinearSourceForce())
def addLinearCylinderVortexForce(self):
self.addForce(LinearCylinderVortexForce())
def addLinearUserDefinedForce(self):
self.addForce(LinearUserDefinedForce())
@ -2650,6 +2744,7 @@ class ParticlePanel(AppShell):
def createForceFrame(self, forcePage, forceName, force):
frame = tk.Frame(forcePage, relief = tk.RAISED, borderwidth = 2)
lFrame = tk.Frame(frame, relief = tk.FLAT)
def removeForce(s = self, f = force, fr = frame):
s.forceGroup.removeForce(f)
fr.pack_forget()
@ -2667,9 +2762,11 @@ class ParticlePanel(AppShell):
def createLinearForceWidgets(self, frame, pageName, forceName, force):
def setAmplitude(amp, f = force):
f.setAmplitude(amp)
def toggleMassDependent(s=self, f=force, p=pageName, n=forceName):
v = s.getVariable(p, n+' Mass Dependent')
f.setMassDependent(v.get())
def setVectorMasks(s=self, f=force, p=pageName, n=forceName):
xMask = s.getVariable(p, n+' Mask X').get()
yMask = s.getVariable(p, n+' Mask Y').get()
@ -2698,6 +2795,7 @@ class ParticlePanel(AppShell):
def createForceActiveWidget(self, frame, pageName, forceName, force):
cbName = forceName + ' Active'
def toggle(s = self, f = force, p = pageName, n = cbName):
s.toggleForce(f, p, n)
self.createCheckbutton(frame, pageName, cbName,
@ -2741,10 +2839,13 @@ class ParticlePanel(AppShell):
def createLinearCylinderVortexForceWidget(self, forcePage, pageName,
count, force):
forceName = 'Vortex Force-' + repr(count)
def setCoef(coef, f = force):
f.setCoef(coef)
def setLength(length, f = force):
f.setLength(length)
def setRadius(radius, f = force):
f.setRadius(radius)
frame = self.createForceFrame(forcePage, forceName, force)
@ -2775,8 +2876,10 @@ class ParticlePanel(AppShell):
if type == 'FT_ONE_OVER_R_CUBED':
#f.setFalloffType(LinearDistanceForce.FTONEOVERRCUBED)
f.setFalloffType(2)
def setForceCenter(vec, f = force):
f.setForceCenter(Point3(vec[0], vec[1], vec[2]))
def setRadius(radius, f = force):
f.setRadius(radius)
forceName = type + ' Force-' + repr(count)
@ -2813,12 +2916,12 @@ class ParticlePanel(AppShell):
######################################################################
# Create demo in root window for testing.
if __name__ == '__main__':
try:
base
except:
except NameError:
from direct.showbase.ShowBase import ShowBase
base = ShowBase()

View File

@ -15,6 +15,7 @@ import tkinter as tk
#TODO: Task to monitor pose
class Placer(AppShell):
# Override class variables here
appname = 'Placer Panel'
@ -355,8 +356,8 @@ class Placer(AppShell):
self.scaleY['command'] = self.xform
self.scaleZ['command'] = self.xform
### WIDGET OPERATIONS ###
def setMovementMode(self, movementMode):
# Set prefix
namePrefix = ''
@ -407,7 +408,7 @@ class Placer(AppShell):
else:
# Good eval but not a node path, give up
nodePath = None
except:
except Exception:
# Bogus eval
nodePath = None
# Clear bogus entry from listbox
@ -464,7 +465,7 @@ class Placer(AppShell):
else:
# Good eval but not a node path, give up
nodePath = None
except:
except Exception:
# Bogus eval
nodePath = None
# Clear bogus entry from listbox
@ -782,11 +783,13 @@ class Placer(AppShell):
self.orbitFromCS.removeNode()
self.orbitToCS.removeNode()
def place(nodePath):
return Placer(nodePath = nodePath)
######################################################################
# Create demo in root window for testing.
if __name__ == '__main__':
root = Pmw.initialise()

View File

@ -38,10 +38,10 @@ class TaskManagerPanel(AppShell):
self.taskMgrWidget = TaskManagerWidget(
self.interior(), self.taskMgr)
def onDestroy(self, event):
self.taskMgrWidget.onDestroy()
class TaskManagerWidget(DirectObject):
"""
TaskManagerWidget class: this class contains methods for creating

View File

@ -27,9 +27,11 @@ if not hasattr(builtins, "widgetDict"):
if not hasattr(builtins, "variableDict"):
builtins.variableDict = {}
def resetWidgetDict():
builtins.widgetDict = {}
def resetVariableDict():
builtins.variableDict = {}
@ -166,7 +168,6 @@ class AppShell(Pmw.MegaWidget, DirectObject):
padx=self['padx'],
pady=self['pady'])
def __createMessageBar(self):
# Create the message bar area for help and status messages.
frame = self.createcomponent('bottomtray', (), None,
@ -199,9 +200,8 @@ class AppShell(Pmw.MegaWidget, DirectObject):
Pmw.aboutversion(self.appversion)
Pmw.aboutcopyright(self.copyright)
Pmw.aboutcontact(
'For more information, contact:\n %s\n Phone: %s\n Email: %s' %\
(self.contactname, self.contactphone,
self.contactemail))
'For more information, contact:\n %s\n Phone: %s\n Email: %s' % \
(self.contactname, self.contactphone, self.contactemail))
self.about = Pmw.AboutDialog(self._hull,
applicationname=self.appname)
self.about.withdraw()
@ -509,6 +509,7 @@ class AppShell(Pmw.MegaWidget, DirectObject):
# Record widget
self.addWidget(category, text, widget)
return widget
def transformRGB(self, rgb, max = 1.0):
retval = '#'
for v in [rgb[0], rgb[1], rgb[2]]:
@ -520,6 +521,7 @@ class AppShell(Pmw.MegaWidget, DirectObject):
retval = "%s%02x" % (retval, int(v))
return retval
class TestAppShell(AppShell):
# Override class variables here
appname = 'Test Application Shell'
@ -549,5 +551,6 @@ class TestAppShell(AppShell):
self.createButtons()
self.createMain()
if __name__ == '__main__':
test = TestAppShell(balloon_state='none')

View File

@ -22,11 +22,13 @@ INNER_SF = 0.2
DIAL_FULL_SIZE = 45
DIAL_MINI_SIZE = 30
class Dial(Valuator):
"""
Valuator widget which includes an angle dial and an entry for setting
floating point values
"""
def __init__(self, parent = None, **kw):
INITOPT = Pmw.INITOPT
optiondefs = (
@ -70,17 +72,17 @@ class Dial(Valuator):
def addValuatorPropertiesToDialog(self):
self.addPropertyToDialog(
'base',
{ 'widget': self._valuator,
{'widget': self._valuator,
'type': 'real',
'help': 'Dial value = base + delta * numRevs'})
self.addPropertyToDialog(
'delta',
{ 'widget': self._valuator,
{'widget': self._valuator,
'type': 'real',
'help': 'Dial value = base + delta * numRevs'})
self.addPropertyToDialog(
'numSegments',
{ 'widget': self._valuator,
{'widget': self._valuator,
'type': 'integer',
'help': 'Number of segments to divide dial into.'})

View File

@ -57,16 +57,16 @@ class EntryScale(Pmw.MegaWidget):
(('entry', 'entryField_entry'),),
None,
Pmw.EntryField, self.labelFrame,
entry_width = 10,
validate = { 'validator': 'real',
entry_width=10,
validate={'validator': 'real',
'min': self['min'],
'max': self['max'],
'minstrict': 0,
'maxstrict': 0},
entry_justify = 'right',
entry_textvar = self.entryValue,
command = self._entryCommand)
self.entry.pack(side='left', padx = 4)
entry_justify='right',
entry_textvar=self.entryValue,
command=self._entryCommand)
self.entry.pack(side='left', padx=4)
# Create the EntryScale's label
self.label = self.createcomponent('label', (), None,
@ -270,6 +270,7 @@ class EntryScale(Pmw.MegaWidget):
def onRelease(self, *args):
""" User redefinable callback executed on button release """
class EntryScaleGroup(Pmw.MegaToplevel):
def __init__(self, parent = None, **kw):

View File

@ -16,6 +16,7 @@ import tkinter as tk
FLOATER_WIDTH = 22
FLOATER_HEIGHT = 18
class Floater(Valuator):
def __init__(self, parent = None, **kw):
INITOPT = Pmw.INITOPT

View File

@ -28,8 +28,10 @@ DEFAULT_MENU_ITEMS = [
'Place', 'Set Name', 'Set Color', 'Explore',
'Separator']
class SceneGraphExplorer(Pmw.MegaWidget, DirectObject):
"Graphical display of a scene graph"
def __init__(self, parent = None, nodePath = None, isItemEditable = True, **kw):
if nodePath is None:
nodePath = base.render
@ -147,6 +149,7 @@ class SceneGraphExplorer(Pmw.MegaWidget, DirectObject):
sceneGraphItem.reveal()
sceneGraphItem.select()
class SceneGraphExplorerItem(TreeItem):
"""Example TreeItem subclass -- browse the file system."""

View File

@ -9,11 +9,13 @@ from .Valuator import Valuator, rgbPanel, VALUATOR_MINI, VALUATOR_FULL
import Pmw
import tkinter as tk
class Slider(Valuator):
"""
Valuator widget which includes an min/max slider and an entry for setting
floating point values in a range
"""
def __init__(self, parent = None, **kw):
INITOPT = Pmw.INITOPT
optiondefs = (
@ -441,14 +443,19 @@ class SliderWidget(Pmw.MegaWidget):
def _incrementValue(self, event):
self.set(self.value + self.increment)
def _bigIncrementValue(self, event):
self.set(self.value + self.increment * 10.0)
def _decrementValue(self, event):
self.set(self.value - self.increment)
def _bigDecrementValue(self, event):
self.set(self.value - self.increment * 10.0)
def _goToMin(self, event):
self.set(self['min'])
def _goToMax(self, event):
self.set(self['max'])

View File

@ -12,11 +12,13 @@ import Pmw
VALUATOR_MINI = 'mini'
VALUATOR_FULL = 'full'
class Valuator(Pmw.MegaWidget):
sfBase = 3.0
sfDist = 7
deadband = 5
""" Base class for widgets used to interactively adjust numeric values """
def __init__(self, parent = None, **kw):
#define the megawidget options
INITOPT = Pmw.INITOPT
@ -126,12 +128,12 @@ class Valuator(Pmw.MegaWidget):
},
'min':
{ 'widget': self,
{'widget': self,
'type': 'real',
'fNone': 1,
'help': 'Minimum allowable value. Enter None for no minimum.'},
'max':
{ 'widget': self,
{'widget': self,
'type': 'real',
'fNone': 1,
'help': 'Maximum allowable value. Enter None for no maximum.'},
@ -149,7 +151,7 @@ class Valuator(Pmw.MegaWidget):
},
'resetValue':
{ 'widget': self,
{'widget': self,
'type': 'real',
'help': 'Enter value to set widget to on reset.'}
}
@ -308,7 +310,6 @@ class Valuator(Pmw.MegaWidget):
self._popupMenu.post(event.widget.winfo_pointerx(),
event.widget.winfo_pointery())
def _popupPropertiesDialog(self):
WidgetPropertiesDialog.WidgetPropertiesDialog(
self.propertyDict,
@ -339,6 +340,7 @@ DIAL = 'dial'
ANGLEDIAL = 'angledial'
SLIDER = 'slider'
class ValuatorGroup(Pmw.MegaWidget):
def __init__(self, parent = None, **kw):
@ -472,7 +474,6 @@ class ValuatorGroup(Pmw.MegaWidget):
return str
class ValuatorGroupPanel(Pmw.MegaToplevel):
def __init__(self, parent = None, **kw):
@ -593,6 +594,7 @@ class ValuatorGroupPanel(Pmw.MegaToplevel):
def reset(self):
self.set(self['value'])
Pmw.forwardmethods(ValuatorGroupPanel, ValuatorGroup, 'valuatorGroup')
@ -665,7 +667,6 @@ def rgbPanel(nodePath, callback = None, style = 'mini'):
'Valuator Group', 'command',
label='Clear Transparency', command=lambda: nodePath.clearTransparency())
# System color picker
menubar.addmenuitem(
'Valuator Group', 'command',
@ -702,6 +703,7 @@ def lightRGBPanel(light, style = 'mini'):
initialcolor = tuple(vgp.get()[:3]))[0]
if color:
vgp.set((color[0], color[1], color[2], vgp.getAt(3)))
def printToLog():
n = light.getName()
c=light.getColor()

Some files were not shown because too many files have changed in this diff Show More