@m_adam Thank you, unfortunately that didn't work either... I check the object, the list head, and the list nodes all for being alive, and I do not get any output that they aren't. The crashes continue.
I have compiled the SDK, and the "Active Object Properties" dialog works fine even in places where the Python script hangs. So, it might be a Python-only issue.
So far, I think that these places are when the script encounters a "Tags" object (type 200001048). The first place I saw this was under ProjektHooks/PLKHUD/PSUNDOHEAD/PKHOP
. When I skipped that branch explicitly, the next place of crash was under Modeling Objects Hooks/Modeling Objects Branch/Plane Manipulator
and Pivot Manipulator
(both branches contain a "Tags" element). Didn't continue after that.
However, trying to exclude these node types didn't help either. Apparently, the objects are so volatile that any way of touching them creates the crash already.
(Since the scene tags also hide under these nodes, I do not want to exclude them, anyway.)
Here's the code I tried last:
import c4d
from c4d import gui
emCount = 0
handledList = []
def showBranchInfo(depth, obj, f):
global emCount, handledList, maxCount, dialogCount
try:
# Validity check
if obj == None: return
if obj in handledList:
print "Already handled! : ", obj
print >>f, "Already handled! : ", obj
f.flush()
return
else:
handledList.append(obj)
if not obj.IsAlive():
print "Object not alive!"
print >>f, "Object not alive!"
f.flush()
return
if obj.GetType() == 200001048:
print "Object is 200001048!"
print >>f, "Object is 200001048!"
f.flush()
return
except:
print >>f, "ERROR in validity check"
f.flush()
return
try:
# Object output
emCount += 1
print " " * depth, "Count=", emCount, "(object)"
print >>f, " " * depth, "Count=", emCount, "(object)"
f.flush()
if isinstance(obj, c4d.documents.BaseDocument):
print " " * depth, "DOC:", obj.GetDocumentName()
print >>f, " " * depth, "DOC:", obj.GetDocumentName()
f.flush()
# this is also a BaseList2D so we can continue
elif not isinstance(obj, c4d.BaseList2D):
print " " * depth, "Not a BaseList2D: ", obj
print >>f, " " * depth, "Not a BaseList2D:", obj
f.flush()
return
else:
print " " * depth, "OBJ:", obj.GetName()
print >>f, " " * depth, "OBJ:", obj.GetName()
f.flush()
except:
print >>f, "ERROR in object output"
f.flush()
return
try:
child = obj.GetDown()
if child != None:
while child:
showBranchInfo(depth + 1, child, f)
child = child.GetNext()
except:
print >>f, "ERROR in subobject recursion"
f.flush()
return
try:
bis = obj.GetBranchInfo()
if bis == None:
print "ERROR: no branch info retrieved"
print >>f, "ERROR: no branch info retrieved"
f.flush()
return
# empty branch info is allowed, so no len() check!
except:
print >>f, "ERROR in GetBranchInfo"
f.flush()
return
try:
for bi in bis: # list of dict{‘head’, ‘name’, ‘id’, ‘flags’}
try:
if len(bi) == 0:
print "ERROR: no entries in dict list"
print >>f, "ERROR: no entries in dict list"
f.flush()
return
listHead = bi['head']
nodeName = bi['name']
# print bi['id']
# print bi['flags']
except:
print >>f, "ERROR in dict list check"
f.flush()
return
try:
# List head output
emCount += 1
node = None
print " " * (depth+1), "Count=", emCount, "(list head)", nodeName
print >>f, " " * (depth+1), "Count=", emCount, "(list head)", nodeName
f.flush()
# Crash irgendwo hier
if listHead == None:
print " " * (depth+1), "No list head"
print >>f, " " * (depth+1), "No list head"
f.flush()
elif not listHead.IsAlive():
print "List head not alive!"
print >>f, "List head not alive!"
f.flush()
elif not isinstance(listHead, c4d.GeListHead):
print " " * (depth+1), "Not a GeListHead:", listHead
print >>f, " " * (depth+1), "Not a GeListHead:", listHead
f.flush()
else:
print " " * (depth+1), nodeName, listHead
print >>f, " " * (depth+1), nodeName, listHead
f.flush()
node = listHead.GetFirst()
except:
print >>f, "ERROR in list head output"
f.flush()
return
try:
# Content of sublist branch
locCount = 0
if node == None:
print " " * (depth+2), "Empty list"
print >>f, " " * (depth+2), "Empty list"
f.flush()
while node != None:
if node.IsAlive():
if node.GetType() != 200001048:
emCount += 1
print " " * (depth+2), "El:", locCount, node
print >>f, " " * (depth+2), "El:", locCount, node
f.flush()
locCount += 1
if isinstance(node, c4d.BaseList2D):
showBranchInfo(depth + 3, node, f)
# no else case; node was already printed
else:
print "List node is 200001048!"
print >>f, "List node is 200001048!"
f.flush()
return
else:
print "List node not alive!"
print >>f, "List node not alive!"
f.flush()
node = node.GetNext()
except:
print >>f, "ERROR in sublist branch handling"
f.flush()
return
# missing here: recurse into children of "node" or "obj"
except:
print >>f, "ERROR in dictionary loop"
f.flush()
return
try:
print >>f, " " * depth, "Returning from depth:", depth
f.flush()
except:
print >>f, "ERROR in return"
f.flush()
return
def main():
print " "
print "GetBranchInfo"
print "============="
f = open("L:/getbranchinfo.txt", "at")
showBranchInfo(1, doc, f)
f.close()
if __name__=='__main__':
main()
You can happily ignore the try/except
blocks, as they never caught any error.
Considering that the code now consists of 80% error checking, this is a very frustrating exercise.
Interestingly, my initial example that uses GetCTracks()
works fine (for what it does) and does not crash, even when handling (scene) tags. I suspect the issue ultimately lies in the GetBranchInfo()
function somewhere.