Hi @del ,
Those are invisible tags.
You don't need to work with them directly, and also you shouldn't delete these tags.
Technically all points and polygons information contained in these tags.
SplineObject has their own set of invisible tags.
Hi @del ,
Those are invisible tags.
You don't need to work with them directly, and also you shouldn't delete these tags.
Technically all points and polygons information contained in these tags.
SplineObject has their own set of invisible tags.
Hi @gaschka ,
I assume that would be percentile value, so you can also add unit, like
squash_and_stretch_container[c4d.DESC_UNIT] = c4d.DESC_UNIT_PERCENT
Hi @ezeuz, @ferdinand,
Back in a days, it was run with python file as a second argument, like so:
c4dpy.exe dummy.py -g_encryptPypFile py-commanddata_dialog_r13.pyp
where dummy.py
just a blank file.
If anyone interested:
def MatrixBlend(mxA, mxB, t):
quatA = c4d.Quaternion()
quatA.SetMatrix(mxA)
quatB = c4d.Quaternion()
quatB.SetMatrix(mxB)
return utils.MatrixMove( utils.MixVec(mxA.off, mxB.off, t) ) * utils.QSlerp(quatA, quatB, t).GetMatrix() * utils.MatrixScale( utils.MixVec(mxA.GetScale(), mxB.GetScale(), t) )
@bentraje exactly.
I keep source files separately.
And I wrote compilation script and config file, which just loads separate plugin files, scan for local dependencies to load them as well.
So it combines everything into single .pyp
file.
For distribution it encrypts final compilation into .pypv
file.
Not much effort for this script gives development flexibility.
Hi nightmate @love_me_render
Question: how to program plugins with python?
Example: I want to reprogram my "tree-generator" written in C++ as a plugin with Python and I can't get it to work.
You can start from Python samples from official GitHub
and documenation.
One problem in the script-manager is the modification of the generated polygon object or other by user data. After I press "execute" in the script-manager, the script executes but does not respond to any user data afterwards. Is there a solution? Using "message" or something?
Assume you want to make a polygon generator.
Prototype can be done as Python Generator, with some User Data as configuration parameters.
And as a next step you can go with Python plugin.
It's regular python script file, but extension has to be .pyp
rather than .py
with a Python class and plugin registration code — look for RegisterObjectPlugin
. You'll need to generate unique plugin id
Just refer to GitHub samples.
Next problem:
The script manager can't save .pyp files, only py. What is the script manager for anyway?
And the files must all be in the special folder "C:\Users\AppData\Roaming\MAXON\Maxon Cinema 4D R25_1FE0824E\library\scripts" or something like that.
But these are then py files, so no .pyp plugin files.
Plugins must, at least from R20 or so, be in a directory that is specified in the program settings.
But even if you write a .pyp file into this directory, how can you test it while the C4D program is running? Or do you have to restart C4D every time to test it, like with C++?
There're multiple ways to load plugins into Cinema4D:
C:\Program Files\Maxon Cinema 4D R25\plugins
subfolderC:\Users\AppData\Roaming\MAXON\Maxon Cinema 4D R25_1FE0824E\plugins
Plugins/Search Paths
Once plugin is loaded and registred, you'll be able to reload python plugin with Reload Python Plugins
command.
But this would reload logic only, so if you changed description files — you'll neeed to restart Cinema.
In C++ and also in Python there is a function "GetVirtualObjects()". Do I need it? But if I use it, I have to register the plugin. This doesn't work for me, it always says "pyp-file not found".
You'll need to implement that method.
Hi @love_me_render,
It seems like you're a bit overthinking the process.
But it's much simpler.
Python plugin executes in runtime, and there's no compilation needed.
It's required that pyp
file implements a class and registers that class as a plugin (usually in the footer of the pyp
file). That's it.
Also plugin file structure should follow same scheme as c++ plugin, so Cinema would handle resources automatically.
Once again — you just need to download any python plugin (or all of them) from the official GitHub, put them into Cinema4D/plugins
folder (or whatever appropriate place) and start Cinema4D.
Switch to "Script" layout (not necessary, but it's comfortable to see the console).
You'll see those plugins in the "Extension" menu -> click on any item, and it should generate an instance in object manager (if it's an object plugin obviously).
Then you can use any text editor to edit corresponding pyp
file.
Just add some print to the console on Init, or on Update class callback,
save it,
hit "Reload Python Plugins" in Cinema4D,
and create new plugin instance once again
— you'll see message(s) in the python console.
And that would be a time to create new subject with more specific questions
As a side note,
Python computation is relatively slow, and it doesn't support multiprocessor execution in Cinema. Also there're some limitations comparable to c++ api.
In the defence of c++ plugin development — with new Maxon subscription model, you might assume most of users are on the latest release.
So there might be an option for you to maintain latest release versions only.
@love_me_render those are manually created,
luckily all of them also text files.
I'm not really familiar with cpp development, thought it's same manual process...
Btw there's plugin structure overview in official doc: developers.maxon.net/docs/py/2024_0_0a/misc/pluginstructure.html
Hi @mikeudin,
I changed my python plugins to
def Init(self, op, isCloneInit=False):
So in older versions of Cinema4D it supposed to act as it act before
Hi @gaschka
Nothing really confusing in your code, python is not very strict...
I can only suggest to move out constants of the function scope,
and there are plenty space to add verifications...
And c4d.EventAdd()
might be executed just once, in the end of the parent function where you creating objects and attaching tags
Also don't forget to use document's StartUndo()
AddUndo()
EndUndo()
methods when creating your objects.
SOME_PYTHON_TAG_CODE = """
import c4d
def main():
# my code for the Python tag
# Execution
if __name__ == '__main__':
main()
"""
def add_python_tag(obj):
if not isinstance(obj, c4d.BaseObject):
return None
python_tag = obj.MakeTag(c4d.Tpython)
python_tag[c4d.TPYTHON_CODE] = SOME_PYTHON_TAG_CODE
return python_tag