Bug with GetLink/SetLink & Hyperfile
-
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 asNone
. 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()
-
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 -
My apologies: I didn't understand how BaseLink worked and this clarified things. Thank you!