Weird behavior with Remove() and InsertObject()



  • Hey everybody,

    I'm currently trying to figure out, what's going on in the following code.
    Given the following situation: I have two objects in my document. 1 Cube Primitive and an instance pointing to that cube.
    Now I simply want to swap them. I'm fetching the instance link so I get access to the cube.

    My current code looks like this, it is executed inside a CommandData Execute() method:

    BaseObject* instance = doc->GetActiveObject();
    GeData data;
    if (!instance->GetParameter(DescID(INSTANCEOBJECT_LINK), data, DESCFLAGS_GET::NONE))
        return nullptr;
    
    const auto refObj = static_cast<BaseObject*>(data.GetLinkAtom(doc, Obase));
    
    // Temporary insertion points
    BaseObject* refUp = refObj->GetUp();
    BaseObject* refPred = refObj->GetPred();
    
    // Remove the reference object and move it to the instances place
    refObj->Remove();
    doc->InsertObject(refObj, instance->GetUp(), instance->GetPred());
    
    // Remove the instance object and move it to the reference object's place
    instance->Remove();
    doc->InsertObject(instance, refUp, refPred);
    

    With his code, however, the result is somewhat weird.
    You can see what happens, if you create the following scene:

    • Create a cube
    • Create an instance from that cube
    • Make sure, the instance is placed topmost in OM
    • Run this code, the ref object (Cube) will be removed.

    So what am I missing here?
    refPred points to the instance itself, which is wrong, imho. Any push in the right direction would be great!
    Maybe there's some concepts available how to swap object in a OM hierarchy.

    Thanks,
    Robert



  • Okay, I can now answer this myself, after numerous testing cases. Turned out that I was thinkin a completely wrong way.
    Of course the code above did what it should, to some extent. I just had to take care of where Pred points to.
    If one passes the same object as insertion point, things get messed up. That's all. :)

    Now here's my provisional solution:

    		// Move the instance object to the reference object's place
    		if (instance->GetDown() != refObj && instanceUp != refObj) // Abort when one of both objects is child or parent of the other one
    		{
    			instance->Remove();
    			doc->InsertObject(instance, refObj->GetUp(), refObj->GetPred());
    		}
    
    		// 
    		if (refObj->GetDown() != instance && refObj->GetUp() != instance) // Abort when one of both objects is child or parent of the other one
    		{
    			if (instancePred != refObj)	// Skip if the constellation has just been changed so both objects are next to each other
    			{
    				refObj->Remove();
    				doc->InsertObject(refObj, instanceUp, instancePred);
    			}
    		}
    

  • Global Moderator

    Hi mp5gosu,

       in order to deliver a consistent knowledge-base for future visitors, I kindly recommend:

    • to un-delete the previously deleted post if a correct answer is found and added to the discussion;
      or
    • leave the post deleted without adding any further answer.

    In this case we've decided to un-delete the first post (because of your second answer) but for the future, we count on users collaboration to avoid incomplete information to appear around.

    Last but not least, for the sake of completeness, further details on your topics can be found in the GeListNode Manual.

    Best, Riccardo



  • @r_gigante said in Weird behavior with Remove() and InsertObject():

    Hi mp5gosu,

       in order to deliver a consistent knowledge-base for future visitors, I kindly recommend:

    • to un-delete the previously deleted post if a correct answer is found and added to the discussion;
      or
    • leave the post deleted without adding any further answer.

    In this case we've decided to un-delete the first post (because of your second answer) but for the future, we count on users collaboration to avoid incomplete information to appear around.

    Last but not least, for the sake of completeness, further details on your topics can be found in the GeListNode Manual.

    Best, Riccardo

    Hi Riccardo,

    then I have to file a bug report. ;)
    I actually tried to delete the whole thread, but the site gave me the error about not having the right privileges. So I assumed that the post has not been deleted. Another clue on that was that I still was able to see the first post (greyed out, but visible - I was wondering about that).
    But now that you are telling me that that post got deleted, I know how this works. Will keep it in mind for future posts!

    However, the mesage about the missing privileges seems like a bug.

    Back to topic: I facepalmed myself. I was so disappointed about the behaviour, I wasn't really able to wrap my head around that I already did the very same with GeListNodes in another plugin. Thank you very much for pointing me to the manual again. :)


  • Global Moderator

    Thanks @mp5gosu, for following up and for "filing" the bug report. I've replicated the behavior and we're going to fix soon.

    Cheers, Riccardo


  • Global Moderator

    @mp5gosu deleted an owned topic is now enabled for all users and no error is anymore notified when attempting to delete a first post.

    Best Riccardo