DIRTY LINK!



  • On 15/07/2017 at 23:21, xxxxxxxx wrote:

    Hello everybody! I experiment with the python and there was a small problem. I have a hierarchy of objects and since the python does not show and does not exist inside the plugin objects, I decided to make links. Everything except the update in the viewport works. And the entire branch of the rig is duplicated. I can not figure this out. Help me please. Explain how it works correctly, please. Code below

    import os
    import sys

    folder = os.path.dirname(__file__)
    if folder not in sys.path:
        sys.path.insert(0, folder)
    from c4d.threading import C4DThread
    import math
    import c4d
    from c4d import plugins, utils, bitmaps, gui, threading
    from c4d.modules import *

    Dummy_Experement_ID = 1039406
    ID_OBJECTPROPERTIES_BC = 3000
    BC_VIEW = 3001
    BC_RENDER = 3002
    BC_LOW_BODY_LINK = 3003
    BC_HIGH_BODY_LINK = 3004
    BC_BODY_LINK = 3005

    pathicons = "res/icons"
    baseicon = "icons_base.png"

    class Dummy_Experement(c4d.plugins.ObjectData) :

    # def __init__(self) :

    #     self.SetOptimizeCache(True)

    def Build(self, name) :

    self.low_body = c4d.BaseObject(1011010)
            self.low_body.SetName('Low Body ' + name.GetName())
            self.low_body[c4d.CONNECTOBJECT_WELD] = 0
            self.low_body[c4d.CONNECTOBJECT_PHONG_MODE] = 0
            self.low_body[c4d.CONNECTOBJECT_CENTERAXIS] = 1

    # self.low_body.ChangeNBit(c4d.NBIT_NOSELECT, c4d.NBITCONTROL_SET)
            # self.low_body.ChangeNBit(c4d.NBIT_OHIDE, c4d.NBITCONTROL_SET)
            #
            #
            #
            #
            self.dytag_low_body = self.low_body.MakeTag(180000102)
            self.dytag_low_body.SetName('Dynamics Tag ' + name.GetName())
            # self.dytag_low_body.ChangeNBit(c4d.NBIT_OHIDE, c4d.NBITCONTROL_SET)
            #
            #
            #
            #
            self.high_body = c4d.BaseObject(1011010)
            self.high_body.SetName('High Body ' + name.GetName())
            self.high_body.InsertUnder(self.low_body)
            self.high_body[c4d.CONNECTOBJECT_WELD] = 0
            self.high_body[c4d.CONNECTOBJECT_PHONG_MODE] = 0
            self.high_body[c4d.CONNECTOBJECT_CENTERAXIS] = 1

    return self.low_body.GetClone()

    def Draw(self, op, drawpass, bd, bh) :

    doc = c4d.documents.GetActiveDocument()

    self.low_body = doc.SearchObject('Low Body ' + op.GetName())
            self.tag = self.low_body.GetTag(180000102)
            self.high_body = doc.SearchObject('High Body ' + op.GetName())
            
            #
            #
            #
            if op[BC_VIEW] == 0:
                self.low_body[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1
                self.high_body[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 0
                c4d.EventAdd()

    elif op[BC_VIEW] == 1:
                self.low_body[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 0
                self.high_body[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1
                c4d.EventAdd()

    if op[BC_RENDER] == 0:
                self.low_body[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1
                self.high_body[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 0
                c4d.EventAdd()

    elif op[BC_RENDER] == 1:
                self.low_body[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 0
                self.high_body[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1
                c4d.EventAdd()

    #
            #
            #
            if op[BC_LOW_BODY_LINK] == None:
                self.low_body[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = 0
                self.tag[c4d.RIGID_BODY_ENABLED] = 0
                c4d.EventAdd()

    elif op[BC_LOW_BODY_LINK].GetDown() == None:
                self.low_body[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = 0
                self.tag[c4d.RIGID_BODY_ENABLED] = 0
                c4d.EventAdd()

    else:
                self.low_body[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = 1
                self.tag[c4d.RIGID_BODY_ENABLED] = 1
                c4d.EventAdd()
            #
            #
            #
            #
            if op[BC_HIGH_BODY_LINK] == None:
                self.high_body[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = 0
                c4d.EventAdd()

    elif op[BC_HIGH_BODY_LINK].GetDown() == None:
                self.high_body[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = 0
                c4d.EventAdd()

    else:
                self.high_body[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = 1
                c4d.EventAdd()

    self.low_body[c4d.CONNECTOBJECT_LINK] = op[BC_LOW_BODY_LINK]
            self.high_body[c4d.CONNECTOBJECT_LINK] = op[BC_HIGH_BODY_LINK]

    return c4d.DRAWRESULT_OK

    def Init(self, op) :

    self.InitAttr(op, bool, [em.BC_VIEW])
            self.InitAttr(op, bool, [em.BC_RENDER])

    op[BC_VIEW] = False
            op[BC_RENDER] = False

    return True

    def GetVirtualObjects(self, op, hierarchyhelp) :

    dirty = op.CheckCache(hierarchyhelp) or op.IsDirty(c4d.DIRTY_DATA)
            if dirty is False:
                return op.GetCache(hierarchyhelp)

    link_low = op[BC_LOW_BODY_LINK]
            link_hight = op[BC_HIGH_BODY_LINK]

    rig = self.Build(op)
            rig.InsertUnder(op)
            
            self.low_body = doc.SearchObject('Low Body ' + op.GetName())
            self.high_body = doc.SearchObject('High Body ' + op.GetName())

    self.low_body[c4d.CONNECTOBJECT_LINK] = link_low
            self.high_body[c4d.CONNECTOBJECT_LINK] = link_hight

    op[BC_BODY_LINK] = self.low_body

    return c4d.BaseObject(c4d.Onull)

    def Reg(self) :

    Dummy_Experement_icon = c4d.bitmaps.BaseBitmap()
            Dummy_Experement_icon.InitWith(os.path.join(dir, pathicons, baseicon))
            return plugins.RegisterObjectPlugin(id = Dummy_Experement_ID, str = "Dummy_Experement", g = Dummy_Experement, description = "Dummy_Experement", info = c4d.OBJECT_INPUT | c4d.PLUGINFLAG_HIDEPLUGINMENU , icon = Dummy_Experement_icon )

    if __name__ == '__main__':
        dir, file = os.path.split(__file__)
        Dummy_Experement.Reg()



  • On 17/07/2017 at 05:23, xxxxxxxx wrote:

    Hi,

    I'm not sure I understand the question. What do you mean with "I have a hierarchy of objects and since the python does not show and does not exist inside the plugin objects"? And what is the actual problem? What update in the viewport? In which scenario?

    There are a few issues in your code, which may or may not be related:

    You shouldn't (must not) use GetActiveDocument() in a plugin derived from NodeData. For example in rendering context, the active document will be different than the one being rendered. You need to get the document from the node/object via GetDocument().

    Please don't do EventAdd() in Draw(). See Threading Information.



  • On 18/07/2017 at 05:36, xxxxxxxx wrote:

    I eliminated those mistakes that were pointed out to me) What about the userdata? Why when I put object in the link box I have a duplicate rig?

    link_low = op[BC_LOW_BODY_LINK]Question
    link_hight = op[BC_HIGH_BODY_LINK]Question



  • On 04/08/2017 at 05:19, xxxxxxxx wrote:

    Hi,

    I'm sorry for not answering here for so long. To be honest, I had hoped, you'd decide to answer at least some of my questions. The SDK Team can help to answer questions and we will try to do so as best as we can, but we are not supposed to debug code. Often we still do, because we really want to help. But we will also need some support... in this case from you. I can't do anything with your code, without the resource files and also a description of what it is supposed to do, how to set up a scene and how to reproduce the issue. I hope you don't mind.

    Looking again at your code (the questions from my first post still continue to exist as well) :

    Why do you store links to objects during Draw()?
    Draw() should be overridden for drawing purposes only, nothing else.

    In general storing links to objects in member variables has it's implications, one needs to carefully check. In most cases for example you will need to take care of these member variables in Read(), Write() and CopyTo().

    Then you are using op.InsertUnder() during GetVirtualObjects(). That is at least unusual... Actually GetVirtualObjects() is supposed to return objects and that's it. No modifications to the scene should be done during GetVirtualObjects() (inserting or deleting objects, changing parameters of other part of the scene,...). I also suspect this to be the cause of any "duplication" you might experience. I mean, what's with the objects you inserted in the previous call of GetVirtualObjects()?
    If you really need to create objects in the scene, other than what you return from GetVirtualObjects(), you'd do so in Message().

    The entire thing looks to me design-wise questionable. I don't mean this as an insult.

    Maybe that's what we should actually do here:
    Discuss what's the best architecture of a plugin for whatever you are trying to achieve? Perhaps you can describe in detail what you want to achieve and then we can provide you with hints on how to do that?


Log in to reply