Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    DIRTY LINK!

    Scheduled Pinned Locked Moved PYTHON Development
    4 Posts 0 Posters 532 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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]Question
              link_hight = op[BC_HIGH_BODY_LINK]Question

      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()

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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.

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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[URL-REMOVED]
          link_hight = op[BC_HIGH_BODY_LINK]!Question[URL-REMOVED]


          [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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?

            1 Reply Last reply Reply Quote 0
            • First post
              Last post