Strange behavior when using reparentTo() and attachNewNode() with joints

Hello, I am relatively new to Panda3d and had scripting issues. I think I found a workaround now but was hoping someone here could clarify panda’s behavior for me, as it really felt a little bit erratically to me.

When I tried to reparent or attach nodes to joints of my model, I would often get the error “argument 1 must be panda3d.core.NodePath, not NoneType”. However, depending on the functions within my code I am making the call from, it can also work without issues.

An example would be this test here I made:
In this function of a class wich first loads a model and then attaches additional nodes on the joints, I added a testJoint and then attached a testNode. No issues within the loop.

def setupLights(self):
    for item in self.lights:            
        slight = Spotlight('slight'+item[0])
        slight.setColor((1, 1, 1, 1))
        lens = PerspectiveLens()
        #lens.setFov(150)
        slight.setLens(lens)
        #slight.showFrustum()
        #slight.setAttenuation((1, 0, 0.1))
        slnp = render.attachNewNode(slight)
        slnp.setPos(0, 0, 0)
        slnp.reparentTo(item[1])
        #slnp.reparentTo(self.obj.exposeJoint(None, "modelRoot",jointName = "Main_Thruster_Star_Prefire")) #for testing
        slnp.lookAt(self.obj.exposeJoint(None, "modelRoot",jointName = item[0]+"_Tail"))
        self.obj.setLight(slnp)
        testJoint = self.obj.exposeJoint(None, "modelRoot",jointName = "Main_Thruster_Star_Prefire")
        testNP = testJoint.attachNewNode("NPTest")
    #end setupLights()

Now I just moved testJoint and testNP outside the loop and testJoint suddenly becomes a NoneType.

def setupLights(self):
    for item in self.lights:            
        slight = Spotlight('slight'+item[0])
        slight.setColor((1, 1, 1, 1))
        lens = PerspectiveLens()
        #lens.setFov(150)
        slight.setLens(lens)
        #slight.showFrustum()
        #slight.setAttenuation((1, 0, 0.1))
        slnp = render.attachNewNode(slight)
        slnp.setPos(0, 0, 0)
        slnp.reparentTo(item[1])
        #slnp.reparentTo(self.obj.exposeJoint(None, "modelRoot",jointName = "Main_Thruster_Star_Prefire")) #for testing
        slnp.lookAt(self.obj.exposeJoint(None, "modelRoot",jointName = item[0]+"_Tail"))
        self.obj.setLight(slnp)
    testJoint = self.obj.exposeJoint(None, "modelRoot",jointName = "Main_Thruster_Star_Prefire")
    testNP = testJoint.attachNewNode("NPTest")
    #end setupLights()

There also weren’t any issues yet when I only setup the nodes and joints within the Class and afterwards reparent from my main applycation.

Looking at your code, it doesn’t seem like “testJoint” is ending up with the value of “None”: I don’t see a call in which “testJoint” is the first parameter, as mentioned in the error-text.

You didn’t specify on which line the error is occurring–is it in the call to “exposeJoint”?

All that said, do you have any lights in your “self.lights”? It occurs to me that if the list in question is empty, it may be that the former version doesn’t result in an error simply because the for-loop is iterating over an empty list, and thus never runs its internal code, and thus the program never hits the line that produces the error.

Sorry,
I was a bit inexplicit there.

Self.lights is already filled and the function would normally operate as intended. Because this function worked but similar ones didn’t I added those testJoint lines here to investigate.
As long as I attach the node to the joint inside the loop the applycation starts up like normal.
If I do that outside the loop I get a NoneType error at ’
testNP = testJoint.attachNewNode(“NPTest”)’

While building this further the last few hours, I also noticed that I only get this kind of error when I call the joint related functions from the class’ init(). This leads me to the suspicion that often something might not be fully loaded when I try to grab the joints and that loop in setupLights() simply gives the engine that little bit extra time needed.

Not sure if this matters, but maybe I should also add that the main applycation actually calls another class wich inherit from this one and thus far only adds specified values to distinguish between similar objects.

Hmm… Very odd; I’m not sure of why the code is behaving that way then, I’m afraid!