Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hello forum,
In my User Data, I have a customized shape as my Spline DataType. I want to keep this custom shape and be able to rebuild as a preset in my plugin. It would function like the 'Save Preset...' and 'Load Preset...' buttons.
There must be a way to save all the points and tangents in the spline DataType to rebuild the it with python? How would I do this?
Thank You for any thoughts.
Hi,
I have recently shown here how to react to user data button clicks in a scripting tag. You could (de-)serialize your c4d.SplineData with the buildin Python module json (link). Also the c4d.SplineData type already does 50% of the work for you as GetKnots() returns a dictionary which you could serialize directly via json.dumps().
c4d.SplineData
json
GetKnots()
json.dumps()
Cheers zipit
Ah, GetKnots() has the data that I need. Thank you for that. I also see I SetKnot() is read only. The only way to get around that is sending the GetKey data to json then back again? There must be a simpler way of using GetKnots() data and pasting on to a new Spline DataType.
or can I place the GetKnots() data into my .res file? That would work for my plugin too.
I am sorry, I did overlook that you were writing a plugin, because I answered a few scripting questions before and you were talking about user data.
A few assumptions:
ObjectData
TagData
CommandData
Tooldata
A few answers:
res
WorldContainer
c4d.SetWorldContainer()
c4d.GetWorldContainer()
BaseDocument.GetDocumentData()
BaseDocument.SetDocumentData()
Thank You for the thorough reply.
Yes, I am writing a python tag and running it through Prototype Converter. The goal is to create a plugin tag that adds custom animation curves to the transforms of objects such as cubes and circles etc. I haven't looked into it yet but WorldContainer looks like its getting me there. I am assuming there is an easy way to save all of the carefully preset UserData (GUISplines) that I have created and keep it in the plugin for a new animator to use out of the box.
(Sorry, I'm learning a lot all at once here coming from C# in Unity3D. )
Hello, thanks again for @zipit and the answer.
I would like to add a couple of words.
The best way should be to store them in the Content Browser, but it's not available in Python, only C++
So that depend if you want your setting to be available only for the document (use Document BaseContainer). For setting that are available independently from the document, you can use the WorldContainer (even if it's to store "preferences" and not librairies)
you can also retrieves each knots (SplineData.GetKnots()) and save them to an Hyperfile (@zipit talked about json but hyperfile are also a good way)
Of course, If you want just one default "starting" state you can do that in your Init() function
Don't forget that with cinema4D, users can also use "Set to default" or save Tags presets. And as you said, they can also use the regular load preset and save preset
And you can also share content librairies.
also about how to use the forum :
For your next threads, please help us keeping things organised and clean. I know it's not your priority but it really simplify our work here.
I've added the tags and marked this thread as a question so when you considered it as solved, please change the state :
Cheers, Manuel
Thank You @zipit and @m_magalhaes,
You have given me some great leads to solve my problem. It's pretty clear I am in over my head. More code samples in the API would really help a beginner like me. I have done a lot of searching around Hyperfiles and BaseContainers but not finding a solution, mostly due to my lack of familiarity of the sdk.
This is the last problem I need to solve in order to use my Tag Plugin.
Here is another take: I can easily save the splinedata to a file and load it into a blank splineGui like a charm. Can I somehow keep that file in my plugin directory and load it onto the specific user data on initialization of the plugin?
Thanks again.
Hello, About the examples, with the release of R21 there will be a bit more examples. You can still have a look at the c++ examples, you will have some class name and function that can be translate to python.
you can't because there's a dialogbox opened by this command. You can't avoid it.
About the hyperfile you have an example on the hyperfile documentation page
I did write an quick example with splinedata, you can simply use ReadData/WriteData I didn't add comment, you just pick the data and write it. (of course you don't need the LoadDialog)
def Read(): path = st.LoadDialog(type=c4d.FILESELECTTYPE_ANYTHING, title="Please Select the file") hf = st.HyperFile() #spdata = op[c4d.ID_USERDATA,1] spdata = None if hf.Open(ident=0, filename=path, mode=c4d.FILEOPEN_READ, error_dialog=c4d.FILEDIALOG_NONE): spdata = hf.ReadData() else: raise ValueError("can't open file") op[c4d.ID_USERDATA,1] = spdata c4d.EventAdd() def Write(): path = st.SaveDialog(type=c4d.FILESELECTTYPE_ANYTHING, title="Please Select the file") hf = st.HyperFile() spdata = op[c4d.ID_USERDATA,1] if hf.Open(ident=0, filename=path, mode=c4d.FILEOPEN_WRITE, error_dialog=c4d.FILEDIALOG_NONE): writeDone = hf.WriteData(spdata) else: raise ValueError("error loading the file")
I did try to open directly the file saved with the command but the result is not totally an hyperfile.
Hello again,
After digging a bit you can add a key parameter on your Open function. And write the Version of cinema4D retrieved with GetC4DVersion That way, you can read/write hyperfile to save your SplineData with script and/or using the load/save menu (when right clicking on the parameter)
Open
GetC4DVersion
Of course on that example the selected object (op) have a UserData (id 1) that is a spline type.
import c4d from c4d import gui from c4d import storage as st, gui # Welcome to the world of Python def Read(path): hf = st.HyperFile() spdata = None if hf.Open(ident=1885434477, filename=path, mode=c4d.FILEOPEN_READ, error_dialog=c4d.FILEDIALOG_NONE): c4dVersion = hf.ReadInt32() spdata = hf.ReadData() else: raise ValueError("can't open file") op[c4d.ID_USERDATA,1] = spdata def Write(path): hf = st.HyperFile() spdata = op[c4d.ID_USERDATA,1] if hf.Open(ident=1885434477, filename=path, mode=c4d.FILEOPEN_WRITE, error_dialog=c4d.FILEDIALOG_NONE): hf.WriteInt32(c4d.GetC4DVersion()) writeDone = hf.WriteData(spdata) else: raise ValueError("error openging the file") # Execute main() if __name__=='__main__': path = st.SaveDialog(type=c4d.FILESELECTTYPE_ANYTHING, title="Please Select the file") Write(path) spdata = op[c4d.ID_USERDATA,1] spdata.DeleteAllPoints() op[c4d.ID_USERDATA,1] = spdata Read(path) c4d.EventAdd()
Cheers Manuel
Thank You @m_magalhaes very helpful! I succeeded. I should have been able to figure this out from the example in the API. I've used the code basically as you have it with my spline datas saved in different hyperfiles. I then load that data from my tag.