Blip before Correctly Updating



  • Hello, I'm working on a plugin where I'm taking the points of a Matrix and using them as an input. The problem is that when the Matrix is changed there is a 'blip' where I'm getting the previous state of it, the old locations of the points, before it updates and then gives me the new updated locations.

    This doesn't happen if the Matrix is above my plugin in the Object Manager, which makes sense to me.

    The blip happens if the Matrix is after my plugin, which makes sense and is fine.

    But the blip also happens if the Matrix is a child of my plugin and this is the behavior I would like to fix.

    I'd like to get this working correctly in GetVirtualObjects() and GetContour() if possible. I currently have no dirty checking going on in GVO, since it should be updating at all possible then.

    Is there a flag or a check I should be doing to update at the right time and avoid the blip?

    Dan



  • hi,

    @d_schmidt said in Blip before Correctly Updating:

    I currently have no dirty checking going on in GVO, since it should be updating at all possible then.

    Not sure to understand that the right way.
    As i understood, your matrix is linked to your generator using a input field or a InExclude List.

    Did you try to send an update message to the matrix object ?
    You could also add the flag OBJECT_CALL_ADDEXECUTION when you register the generator and use that Execution function to delay the execution of your GVO.

    Don't be afraid of making the Matrix calculate its cache twice in a frame execution.

    Using GVO and GetContour at the same time can be strange sometimes.

    Cheers,
    Manuel



  • @m_magalhaes said in Blip before Correctly Updating:

    As i understood, your matrix is linked to your generator using a input field or a InExclude List.

    I did when I posted this, but I can have it work from an InExclude or from the child input, in either case the 'blip' exists.

    Did you try to send an update message to the matrix object ?

    I didn't. From what I can tell GVO is being called twice. Once before the child Matrix is dirty and once after, which is creating the blip.

    How would I know if I should update the Matrix in the first GVO call?

    Don't be afraid of making the Matrix calculate its cache twice in a frame execution.

    This isn't something I should avoid? Seems risky to update an object multiple times per frame.

    Using GVO and GetContour at the same time can be strange sometimes.

    I'm not doing both at the same time, but I wanted to be able to use the solution in either function. It seems like each one has it's own way of updating and access to different variables. So I wanted to make sure I wasn't limited to just one case.

    How would I delay the GVO call in Execution?

    Thanks,
    Dan



  • Hi,

    first of all: It is unclear to me what you mean by "the points of a Matrix". Do you actually interpret the components of a matrix as points, or do you mean by that the vertices of a PointObject which are influenced by the matrix of that BaseObject (i.e. the PointObject)?

    How would I know if I should update the Matrix in the first GVO call?

    Technically you could clone the whole document and the execute the passes on that document. But I agree, this would be wildly inefficient.

    How would I delay the GVO call in Execution?

    You could of course just simply return the cache while certain conditions are not met (e.g. that PointObject not being dirty). But @m_magalhaes probably meant here, that you should register your generator with OBJECT_CALL_ADDEXECUTION and then overwrite ObjectData.AddToExecution to tell Cinema that that object type should be evaluated after all other generators (via EXECUTIONPRIORITY_GENERATOR).

    Cheers,
    zipit



  • first of all: It is unclear to me what you mean by "the points of a Matrix". Do you actually interpret the components of a matrix as points

    Correct, I'm getting them from the MoData.

    you should register your generator with OBJECT_CALL_ADDEXECUTION and then overwrite ObjectData.AddToExecution to tell Cinema that that object type should be evaluated after all other generators (via EXECUTIONPRIORITY_GENERATOR).

    I'm unsure how to do this part.
    Adding to the PriorityList is easy enough, but from my testing it seems like using AddToExecution() only effects when Execute is called. Should I be doing this in Execute then?



  • hi,

    sorry it was not very clear.

    I was trying to say that you can probably check the state of the matrix on your execute passe (the Initial priority maybe or one that could work for you)
    and set your generator to dirty. That will "force" the recalculation of your generator with the modified matrix.

    But maybe in your case that will not make a big difference

      def AddToExecution(self, op, list):
            list.Add(op, c4d.EXECUTIONPRIORITY_INITIAL, 0)
            return True
    
        def Execute(self, op, doc, bt, priority, flags):
            if priority == c4d.EXECUTIONPRIORITY_INITIAL:
                
                print ("priority init")
                #Gets child 
                child = op.GetDown()
                if child is None:
                    return c4d.EXECUTIONRESULT_OK
                if self.lastdirty != child.GetDirty(c4d.DIRTYFLAGS_DATA):
                    self.lastdirty = child.GetDirty(c4d.DIRTYFLAGS_DATA)
                    op.SetDirty(c4d.DIRTYFLAGS_ALL)
           
            return c4d.EXECUTIONRESULT_OK
    
        # Override method, should generate and return the object.
        def GetVirtualObjects(self, op, hierarchyhelp):
            print ("GVO")
            #force the update of object 
            child = op.GetDown()
            if child:
                print "child", child
                moData = c4d.modules.mograph.GeGetMoData(child)
                if moData is not None:
                    cnt = moData.GetCount()
                    print cnt
            return c4d.BaseObject(c4d.Ocube)
    
    

    Cheers,
    Manuel



  • Hi Manuel,

    I implemented that and didn't notice a difference in my error though.

    To be clear this is the sort of error I'm getting as shown with the Voronoi Fracture.

    image001.gif

    When the Matrix is above or a child of the Voronoi Fracture it updates correctly. When after the Voronoi Fracture it doesn't, there's a blip, that makes sense to me.

    The difference is that in my plugin having the Matrix as a child of my plugin still has the blip where the Voronoi Fracture doesn't.



  • hi,

    the voronoi object is registered with the flag OBJECT_INPUT.
    The voronoi is a really special object generator with many line of code, it really take a lof of cases into account.

    I'm going to find out what it's really doing with the matrix object in case you have it in the in/exclude list and as a child of the generator. But i just thing that as the generator is waiting for an input object and updating its cache. Even if it's a matrix, this matrix is updated during this process.

    Cheers,
    Manuel



  • Sorry about the delayed reply!

    the voronoi object is registered with the flag OBJECT_INPUT.

    I have this set as well, and I've swapped to taking the child matrix in as a child and I'm still having the same blip.



  • hi,

    you can check this thread it could help.

    Touching the matrix could be the issue.

    We are doing a lot of guessing here.

    If you could send us your code that would probably help us a lot to find why it's not working properly. The voronoi object isn't a simple one and neither the matrix object.

    Cheers,
    Manuel



  • Hi Manuel,

    I was going to post my code but at the moment it looks as if the linked thread is giving the results I need with the matrix object, the blip is gone! using Current State to Object.

    I'm not sure if you'd prefer for me to make a new thread for this question, but I've had similar 'blip' issue with Generators returning Polygon or Spline objects in both GVO and GetContour.

    Using GetCache I'm able to browse and get the actual Polygon and Spline object, but when they're a child or further down the Object Manager Hierarchy than my plugin, I'm getting the previous cache, not the new one.

    I know there are plenty of ways to rebuild the cache but is there a best practice method that offers the least overhead?

    Dan



  • where are you calling that "getcache" ? Inside the GetContour function ?



  • @m_magalhaes

    Yes, or in GVO() depending if I'm returning a spline or not.



  • @m_magalhaes

    Hi! I don't mean to be a bother but I'm just giving this a bump in hope of a response!

    Dan



  • hi,

    you are never bothering us, sorry if you have that feeling.

    There's "no one" way to go. That depend a lot of what you are doing (this is still a bit blurry to me).
    You often have to write specific code for specific cases.

    The problem here is that it's a bit hard to answer you without having your code.

    Cheers,
    Manuel



  • @m_magalhaes

    Sorry about the late reply again! I went to build some simplified code to post and I might have figured it out in the process.

    It seems that if I correctly mark the children with AddDependence then GetCache returns the cache I expect. Having the object lower in the object manager than mine causes it to lag behind slightly, but that seems consistent with other Cinema objects.

    Dan


Log in to reply