Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    Bug with GetLink/SetLink & Hyperfile

    Cinema 4D SDK
    sdk python
    2
    3
    390
    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.
    • ?
      A Former User
      last edited by m_adam

      Hello,
      I think that I've found a bug. This is a variation of the same unsolved issue from this topic from a month ago. In the code example below, it is writing an object's CTrack (Position . X/Track) to a Hyperfile, so for it to work an object must have an animation track in position X and be selected. It prints correctly from the BaseContainer prior to saving. When loading the Hyperfile however, the link prints as None. As mentioned in the previous topic, CTracks are of type C4DAtom and I'm passing/retrieving it with the same ID, so it should be writing and reading correctly. If I use BaseContainer.SetString instead of BaseContainer.SetLink, it works.

      If there is a workaround storing a CTrack to a Hyperfile, I'd really appreciate the help. This is a very important part of my current project. Thank you.

      import c4d, os
      from c4d import documents, gui
      
      key = 12345
      OBJ_BC_ID = 90210
      
      desktopPath = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP)
      defaultFilepath = os.path.join(desktopPath, "test.file")
      
      def load_hyperfile():
          global doc
          path = c4d.storage.LoadDialog(def_file=defaultFilepath)
      
          hf = c4d.storage.HyperFile()
          if not hf.Open(ident=key, filename=path, mode=c4d.FILEOPEN_READ,
                         error_dialog=c4d.FILEDIALOG_NONE):
              print "Could not read file."
              return False
          bc = hf.ReadContainer()
      
          for cid, value in bc[OBJ_BC_ID]:
              print cid, value
      
          hf.Close()
      
      
      def save_hyperfile(obj):
          path = c4d.storage.SaveDialog(title="Save your Hyperfile",force_suffix="file",def_file=defaultFilepath)
      
          bc = c4d.BaseContainer()
          objBc = c4d.BaseContainer()
          xPos = c4d.DescID(c4d.DescLevel(903, 23, 5155), c4d.DescLevel(1000, 19, 23))
          pxTrack = obj.FindCTrack(xPos)
          objBc.SetLink(OBJ_BC_ID,pxTrack)
          #objBc.SetString(OBJ_BC_ID,"Test String") # The Hyperfile works when using a String.
          bc.SetContainer(OBJ_BC_ID, objBc)
          print objBc[OBJ_BC_ID]
      
          hf = c4d.storage.HyperFile()
          if not hf.Open(ident=key, filename=path, mode=c4d.FILEOPEN_WRITE,
                         error_dialog=c4d.FILEDIALOG_ANY):
              print "Could not write file."
              return False
          else:
              print "Wrote file at %s"%path
      
          hf.WriteContainer(bc)
      
          for cid, value in bc[OBJ_BC_ID]:
              print cid, value
      
          hf.Close()
      
      class Dlg(gui.GeDialog):
          def __init__(self):
              global doc,obj
      
          def CreateLayout(self):
              self.SetTitle('Hyperfile')
              self.GroupBegin(1001, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 1, 2)
              self.AddButton(1002, c4d.BFH_CENTER | c4d.BFH_SCALE | c4d.BFV_TOP, initw=0, inith=20, name="Save Hyperfile")
              self.AddButton(1003, c4d.BFH_CENTER | c4d.BFH_SCALE | c4d.BFV_TOP, initw=0, inith=20, name="Load Hyperfile")
              self.GroupEnd()
              return True
      
          def Command(self, id, msg):
              if id == 1002:
                  save_hyperfile(obj)
              elif id == 1003:
                  load_hyperfile()
              return True
      
      def main():
          global doc,obj,dlg
          doc = documents.GetActiveDocument()
          obj = doc.GetActiveObject()
          if obj is None:
              gui.MessageDialog("Please select an object to save.")
              return
          dlg = Dlg()
          dlg.Open(c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2, defaultw=200, defaulth=130)
      
      if __name__=='__main__':
          main()
      
      1 Reply Last reply Reply Quote 1
      • ManuelM
        Manuel
        last edited by

        hello,

        A BaseLink is like a shortcut or an alias. if you only save the shortcut you will have nothing. If i save my shortcut and send it to you, you will not be able to start the application.

        Instead what i suggest is

        • isolate the object (as in the previous post) in a temporary document. (or create a null, and copy the track on it)
        • create in the BaseContainer of the document a BaseLink that will point to your track.
        • save the temporary document.

        This way, when you open the file, you know where to get your BaseLink.
        You can also have different BaseLink pointing to different tracks of different objects.

        you can have a look at the BaseLink Manual

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • ?
          A Former User
          last edited by

          My apologies: I didn't understand how BaseLink worked and this clarified things. Thank you!

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