mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-27 13:42:28 -06:00
401 lines
14 KiB
Python
401 lines
14 KiB
Python
|
from pandac.PandaModules import *
|
||
|
import ObjectGlobals as OG
|
||
|
|
||
|
class ActionMgr:
|
||
|
def __init__(self):
|
||
|
self.undoList = []
|
||
|
self.redoList = []
|
||
|
|
||
|
def reset(self):
|
||
|
while len(self.undoList) > 0:
|
||
|
action = self.undoList.pop()
|
||
|
action.destroy()
|
||
|
|
||
|
while len(self.redoList) > 0:
|
||
|
action = self.redoList.pop()
|
||
|
action.destroy()
|
||
|
|
||
|
def push(self, action):
|
||
|
self.undoList.append(action)
|
||
|
if len(self.redoList) > 0:
|
||
|
self.redoList.pop()
|
||
|
|
||
|
def undo(self):
|
||
|
if len(self.undoList) < 1:
|
||
|
print 'No more undo'
|
||
|
else:
|
||
|
action = self.undoList.pop()
|
||
|
self.redoList.append(action)
|
||
|
action.undo()
|
||
|
|
||
|
def redo(self):
|
||
|
if len(self.redoList) < 1:
|
||
|
print 'No more redo'
|
||
|
else:
|
||
|
action = self.redoList.pop()
|
||
|
self.undoList.append(action)
|
||
|
action.redo()
|
||
|
|
||
|
class ActionBase(Functor):
|
||
|
""" Base class for user actions """
|
||
|
|
||
|
def __init__(self, function, *args, **kargs):
|
||
|
self.function = function
|
||
|
if function is None:
|
||
|
def nullFunc():
|
||
|
pass
|
||
|
function = nullFunc
|
||
|
Functor.__init__(self, function, *args, **kargs)
|
||
|
self.result = None
|
||
|
|
||
|
def _do__call__(self, *args, **kargs):
|
||
|
self.saveStatus()
|
||
|
self.result = Functor._do__call__(self, *args, **kargs)
|
||
|
self.postCall()
|
||
|
return self.result
|
||
|
|
||
|
# needed this line to override _do__call__
|
||
|
__call__ = _do__call__
|
||
|
|
||
|
def redo(self):
|
||
|
self.result = self._do__call__()
|
||
|
return self.result
|
||
|
|
||
|
def saveStatus(self):
|
||
|
# save object status for undo here
|
||
|
pass
|
||
|
|
||
|
def postCall(self):
|
||
|
# implement post process here
|
||
|
pass
|
||
|
|
||
|
def undo(self):
|
||
|
print "undo method is not defined for this action"
|
||
|
|
||
|
class ActionAddNewObj(ActionBase):
|
||
|
""" Action class for adding new object """
|
||
|
|
||
|
def __init__(self, editor, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
function = self.editor.objectMgr.addNewObject
|
||
|
ActionBase.__init__(self, function, *args, **kargs)
|
||
|
self.uid = None
|
||
|
|
||
|
def postCall(self):
|
||
|
obj = self.editor.objectMgr.findObjectByNodePath(self.result)
|
||
|
if obj:
|
||
|
self.uid = obj[OG.OBJ_UID]
|
||
|
|
||
|
def redo(self):
|
||
|
if self.uid is None:
|
||
|
print "Can't redo this add"
|
||
|
else:
|
||
|
self.result = self._do__call__(uid=self.uid)
|
||
|
return self.result
|
||
|
|
||
|
def undo(self):
|
||
|
if self.result is None:
|
||
|
print "Can't undo this add"
|
||
|
else:
|
||
|
print "Undo: addNewObject"
|
||
|
if self.uid:
|
||
|
obj = self.editor.objectMgr.findObjectById(self.uid)
|
||
|
else:
|
||
|
obj = self.editor.objectMgr.findObjectByNodePath(self.result)
|
||
|
if obj:
|
||
|
self.uid = obj[OG.OBJ_UID]
|
||
|
self.editor.ui.sceneGraphUI.delete(self.uid)
|
||
|
base.direct.deselect(obj[OG.OBJ_NP])
|
||
|
base.direct.removeNodePath(obj[OG.OBJ_NP])
|
||
|
self.result = None
|
||
|
else:
|
||
|
print "Can't undo this add"
|
||
|
|
||
|
class ActionDeleteObj(ActionBase):
|
||
|
""" Action class for deleting object """
|
||
|
|
||
|
def __init__(self, editor, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
function = base.direct.removeAllSelected
|
||
|
ActionBase.__init__(self, function, *args, **kargs)
|
||
|
self.selectedUIDs = []
|
||
|
self.hierarchy = {}
|
||
|
self.objInfos = {}
|
||
|
self.objTransforms = {}
|
||
|
|
||
|
def saveStatus(self):
|
||
|
selectedNPs = base.direct.selected.getSelectedAsList()
|
||
|
def saveObjStatus(np, isRecursive=True):
|
||
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
||
|
if obj:
|
||
|
uid = obj[OG.OBJ_UID]
|
||
|
if not isRecursive:
|
||
|
self.selectedUIDs.append(uid)
|
||
|
objNP = obj[OG.OBJ_NP]
|
||
|
self.objInfos[uid] = obj
|
||
|
self.objTransforms[uid] = objNP.getMat()
|
||
|
parentNP = objNP.getParent()
|
||
|
if parentNP == render:
|
||
|
self.hierarchy[uid] = None
|
||
|
else:
|
||
|
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNP)
|
||
|
if parentObj:
|
||
|
self.hierarchy[uid] = parentObj[OG.OBJ_UID]
|
||
|
|
||
|
for child in np.getChildren():
|
||
|
if child.hasTag('OBJRoot'):
|
||
|
saveObjStatus(child)
|
||
|
|
||
|
for np in selectedNPs:
|
||
|
saveObjStatus(np, False)
|
||
|
|
||
|
def undo(self):
|
||
|
if len(self.hierarchy.keys()) == 0 or\
|
||
|
len(self.objInfos.keys()) == 0:
|
||
|
print "Can't undo this deletion"
|
||
|
else:
|
||
|
print "Undo: deleteObject"
|
||
|
def restoreObject(uid, parentNP):
|
||
|
obj = self.objInfos[uid]
|
||
|
objDef = obj[OG.OBJ_DEF]
|
||
|
objModel = obj[OG.OBJ_MODEL]
|
||
|
objProp = obj[OG.OBJ_PROP]
|
||
|
objRGBA = obj[OG.OBJ_RGBA]
|
||
|
objNP = self.editor.objectMgr.addNewObject(objDef.name,
|
||
|
uid,
|
||
|
obj[OG.OBJ_MODEL],
|
||
|
parentNP)
|
||
|
self.editor.objectMgr.updateObjectColor(objRGBA[0], objRGBA[1], objRGBA[2], objRGBA[3], objNP)
|
||
|
self.editor.objectMgr.updateObjectProperties(objNP, objProp)
|
||
|
objNP.setMat(self.objTransforms[uid])
|
||
|
|
||
|
while (len(self.hierarchy.keys()) > 0):
|
||
|
for uid in self.hierarchy.keys():
|
||
|
if self.hierarchy[uid] is None:
|
||
|
parentNP = None
|
||
|
restoreObject(uid, parentNP)
|
||
|
del self.hierarchy[uid]
|
||
|
else:
|
||
|
parentObj = self.editor.objectMgr.findObjectById(self.hierarchy[uid])
|
||
|
if parentObj:
|
||
|
parentNP = parentObj[OG.OBJ_NP]
|
||
|
restoreObject(uid, parentNP)
|
||
|
del self.hierarchy[uid]
|
||
|
|
||
|
base.direct.deselectAllCB()
|
||
|
for uid in self.selectedUIDs:
|
||
|
obj = self.editor.objectMgr.findObjectById(uid)
|
||
|
if obj:
|
||
|
self.editor.select(obj[OG.OBJ_NP], fMultiSelect=1, fUndo=0)
|
||
|
|
||
|
self.selecteUIDs = []
|
||
|
self.hierarchy = {}
|
||
|
self.objInfos = {}
|
||
|
|
||
|
class ActionDeleteObjById(ActionBase):
|
||
|
""" Action class for deleting object """
|
||
|
|
||
|
def __init__(self, editor, uid):
|
||
|
self.editor = editor
|
||
|
function = self.editor.objectMgr.removeObjectById
|
||
|
self.uid = uid
|
||
|
ActionBase.__init__(self, function, self.uid)
|
||
|
self.hierarchy = {}
|
||
|
self.objInfos = {}
|
||
|
self.objTransforms = {}
|
||
|
|
||
|
def saveStatus(self):
|
||
|
def saveObjStatus(uid_np, isUID=False):
|
||
|
if isUID:
|
||
|
obj = self.editor.objectMgr.findObjectById(uid_np)
|
||
|
else:
|
||
|
obj = self.editor.objectMgr.findObjectByNodePath(uid_np)
|
||
|
if obj:
|
||
|
uid = obj[OG.OBJ_UID]
|
||
|
objNP = obj[OG.OBJ_NP]
|
||
|
self.objInfos[uid] = obj
|
||
|
self.objTransforms[uid] = objNP.getMat()
|
||
|
parentNP = objNP.getParent()
|
||
|
if parentNP == render:
|
||
|
self.hierarchy[uid] = None
|
||
|
else:
|
||
|
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNP)
|
||
|
if parentObj:
|
||
|
self.hierarchy[uid] = parentObj[OG.OBJ_UID]
|
||
|
|
||
|
for child in objNP.getChildren():
|
||
|
if child.hasTag('OBJRoot'):
|
||
|
saveObjStatus(child)
|
||
|
|
||
|
saveObjStatus(self.uid, True)
|
||
|
|
||
|
def undo(self):
|
||
|
if len(self.hierarchy.keys()) == 0 or\
|
||
|
len(self.objInfos.keys()) == 0:
|
||
|
print "Can't undo this deletion"
|
||
|
else:
|
||
|
print "Undo: deleteObjectById"
|
||
|
def restoreObject(uid, parentNP):
|
||
|
obj = self.objInfos[uid]
|
||
|
objDef = obj[OG.OBJ_DEF]
|
||
|
objModel = obj[OG.OBJ_MODEL]
|
||
|
objProp = obj[OG.OBJ_PROP]
|
||
|
objRGBA = obj[OG.OBJ_RGBA]
|
||
|
objNP = self.editor.objectMgr.addNewObject(objDef.name,
|
||
|
uid,
|
||
|
obj[OG.OBJ_MODEL],
|
||
|
parentNP)
|
||
|
self.editor.objectMgr.updateObjectColor(objRGBA[0], objRGBA[1], objRGBA[2], objRGBA[3], objNP)
|
||
|
self.editor.objectMgr.updateObjectProperties(objNP, objProp)
|
||
|
objNP.setMat(self.objTransforms[uid])
|
||
|
|
||
|
while (len(self.hierarchy.keys()) > 0):
|
||
|
for uid in self.hierarchy.keys():
|
||
|
if self.hierarchy[uid] is None:
|
||
|
parentNP = None
|
||
|
restoreObject(uid, parentNP)
|
||
|
del self.hierarchy[uid]
|
||
|
else:
|
||
|
parentObj = self.editor.objectMgr.findObjectById(self.hierarchy[uid])
|
||
|
if parentObj:
|
||
|
parentNP = parentObj[OG.OBJ_NP]
|
||
|
restoreObject(uid, parentNP)
|
||
|
del self.hierarchy[uid]
|
||
|
|
||
|
self.hierarchy = {}
|
||
|
self.objInfos = {}
|
||
|
|
||
|
class ActionChangeHierarchy(ActionBase):
|
||
|
""" Action class for changing Scene Graph Hierarchy """
|
||
|
|
||
|
def __init__(self, editor, oldGrandParentId, oldParentId, newParentId, childName, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
self.oldGrandParentId = oldGrandParentId
|
||
|
self.oldParentId = oldParentId
|
||
|
self.newParentId = newParentId
|
||
|
self.childName = childName
|
||
|
function = self.editor.ui.sceneGraphUI.parent
|
||
|
ActionBase.__init__(self, function, self.oldParentId, self.newParentId, self.childName, **kargs)
|
||
|
|
||
|
def undo(self):
|
||
|
self.editor.ui.sceneGraphUI.parent(self.oldParentId, self.oldGrandParentId, self.childName)
|
||
|
|
||
|
class ActionSelectObj(ActionBase):
|
||
|
""" Action class for adding new object """
|
||
|
|
||
|
def __init__(self, editor, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
function = base.direct.selectCB
|
||
|
ActionBase.__init__(self, function, *args, **kargs)
|
||
|
self.selectedUIDs = []
|
||
|
|
||
|
def saveStatus(self):
|
||
|
selectedNPs = base.direct.selected.getSelectedAsList()
|
||
|
for np in selectedNPs:
|
||
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
||
|
if obj:
|
||
|
uid = obj[OG.OBJ_UID]
|
||
|
self.selectedUIDs.append(uid)
|
||
|
|
||
|
def undo(self):
|
||
|
print "Undo : selectObject"
|
||
|
base.direct.deselectAllCB()
|
||
|
for uid in self.selectedUIDs:
|
||
|
obj = self.editor.objectMgr.findObjectById(uid)
|
||
|
if obj:
|
||
|
self.editor.select(obj[OG.OBJ_NP], fMultiSelect=1, fUndo=0)
|
||
|
self.selectedUIDs = []
|
||
|
|
||
|
class ActionTransformObj(ActionBase):
|
||
|
""" Action class for object transformation """
|
||
|
|
||
|
def __init__(self, editor, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
function = self.editor.objectMgr.setObjectTransform
|
||
|
ActionBase.__init__(self, function, *args, **kargs)
|
||
|
self.uid = args[0]
|
||
|
#self.xformMat = Mat4(args[1])
|
||
|
self.origMat = None
|
||
|
|
||
|
def saveStatus(self):
|
||
|
obj = self.editor.objectMgr.findObjectById(self.uid)
|
||
|
if obj:
|
||
|
self.origMat = Mat4(self.editor.objectMgr.objectsLastXform[obj[OG.OBJ_UID]])
|
||
|
#self.origMat = Mat4(obj[OG.OBJ_NP].getMat())
|
||
|
|
||
|
def _do__call__(self, *args, **kargs):
|
||
|
self.result = ActionBase._do__call__(self, *args, **kargs)
|
||
|
obj = self.editor.objectMgr.findObjectById(self.uid)
|
||
|
if obj:
|
||
|
self.editor.objectMgr.objectsLastXform[self.uid] = Mat4(obj[OG.OBJ_NP].getMat())
|
||
|
return self.result
|
||
|
|
||
|
def undo(self):
|
||
|
if self.origMat is None:
|
||
|
print "Can't undo this transform"
|
||
|
else:
|
||
|
print "Undo: transformObject"
|
||
|
obj = self.editor.objectMgr.findObjectById(self.uid)
|
||
|
if obj:
|
||
|
obj[OG.OBJ_NP].setMat(self.origMat)
|
||
|
self.editor.objectMgr.objectsLastXform[self.uid] = Mat4(self.origMat)
|
||
|
del self.origMat
|
||
|
self.origMat = None
|
||
|
|
||
|
class ActionDeselectAll(ActionBase):
|
||
|
""" Action class for adding new object """
|
||
|
|
||
|
def __init__(self, editor, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
function = base.direct.deselectAllCB
|
||
|
ActionBase.__init__(self, function, *args, **kargs)
|
||
|
self.selectedUIDs = []
|
||
|
|
||
|
def saveStatus(self):
|
||
|
selectedNPs = base.direct.selected.getSelectedAsList()
|
||
|
for np in selectedNPs:
|
||
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
||
|
if obj:
|
||
|
uid = obj[OG.OBJ_UID]
|
||
|
self.selectedUIDs.append(uid)
|
||
|
|
||
|
def undo(self):
|
||
|
print "Undo : deselectAll"
|
||
|
base.direct.deselectAllCB()
|
||
|
for uid in self.selectedUIDs:
|
||
|
obj = self.editor.objectMgr.findObjectById(uid)
|
||
|
if obj:
|
||
|
self.editor.select(obj[OG.OBJ_NP], fMultiSelect=1, fUndo=0)
|
||
|
self.selectedUIDs = []
|
||
|
|
||
|
class ActionUpdateObjectProp(ActionBase):
|
||
|
""" Action class for updating object property """
|
||
|
|
||
|
def __init__(self, editor, fSelectObject, obj, propName, val, oldVal, function, undoFunc, *args, **kargs):
|
||
|
self.editor = editor
|
||
|
self.fSelectObject = fSelectObject
|
||
|
self.obj = obj
|
||
|
self.propName = propName
|
||
|
self.newVal = val
|
||
|
self.oldVal = oldVal
|
||
|
self.undoFunc = undoFunc
|
||
|
ActionBase.__init__(self, function, *args, **kargs)
|
||
|
|
||
|
def saveStatus(self):
|
||
|
self.obj[OG.OBJ_PROP][self.propName] = self.newVal
|
||
|
|
||
|
def redo(self):
|
||
|
self.result = self._do__call__()#uid=self.uid, xformMat=self.xformMat)
|
||
|
if self.editor and self.fSelectObject:
|
||
|
base.direct.select(self.obj[OG.OBJ_NP], fUndo=0)
|
||
|
return self.result
|
||
|
|
||
|
def undo(self):
|
||
|
print "Undo : updateObjectProp"
|
||
|
if self.oldVal:
|
||
|
self.obj[OG.OBJ_PROP][self.propName] = self.oldVal
|
||
|
if self.undoFunc:
|
||
|
self.undoFunc()
|
||
|
if self.editor and self.fSelectObject:
|
||
|
base.direct.select(self.obj[OG.OBJ_NP], fUndo=0)
|