Wow! What an incredible set of answers. You've each addressed a different thing I intended to do with these polygon groups once I had access to them.
Thank you @ferdinand @m_adam and @pyr!
Freelance Plugin Developer
Wow! What an incredible set of answers. You've each addressed a different thing I intended to do with these polygon groups once I had access to them.
Thank you @ferdinand @m_adam and @pyr!
Hi!
Is there an available convenience method for getting all polygon islands in a polygon object? It seems like one exists internally for things like the Texture > View > Multi-Color Islands
option.
Specifically, I'm looking for polygon islands/shells, but an additional command/option for UV Islands would be great too.
If one doesn't exist, I'd like to request that one be added to the Python SDK.
Thank you,
Donovan
Hi,
I'm trying to export object an animated hierarchy of objects from Cinema 4D's left coordinates (z+ = forward) with HPB rotations to Three.js's right-hand coordinates (z+ = backward) with XYZ rotations.
Unfortunately, I'm a bit beyond my depth with the matrix math and conversions involved. I'd like to take my C4D local coords write them out as local coords in this other system.
Any tips on how to approach this?
Thanks
Donovan
PS: Looks like we need an S22 tag in the tags option.
Realizing I never responded to this Thank you @m_magalhaes, @mikegold10, and @PluginStudent.
I ended up manually making a list of the parameters I wanted to copy and iterating through all of them. Not ideal, but at least glad to know there wasn't an automated method I was missing.
Hi,
I just spent a bit of time debugging a couple issues when trying to Solo a Layer in the Layer Manager, and figured I would post my findings to save someone else some trouble:
Q: How do you solo a layer?
layer_root = doc.GetLayerObjectRoot()
if not layer_root: return
# Get the first layer in the scene
layer = layer_root.GetDown()
if not layer: return
# Be sure to use the `rawdata` flag so that you get the stored layer state, not the "effective" layer state
layer_data = layer.GetLayerData(doc, rawdata=True)
start_solo_state = layer_data["solo"]
solo_state = True
layer_data["solo"] = True
# SetLayerData needs a complete LayerData dict, it doesn't work with something like `{"solo": True}`
# doing that will force all other layer state flags to be False
layer.SetLayerData(doc, layer_data)
# This isn't documented near SetLayerData, but you must call this method or C4D won't know to update the
# solo state of layers in the scene.
set_or_clear =
doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_SET)
# Let C4D know something has changed to trigger a redraw
c4d.EventAdd()
Documentation Request:
Please update the docs for SetLayerData to include an example like the above, and make a note that if you plan to SetLayerData you should call GetLayerData with rawdata=True
.
Thanks,
Donovan
-- Edit 2020/03/20 --
Actually this isn't working well in all circumstances. If all layers are unsoloed I'm not getting the expected refresh.
Okay, I think I figured out the issue (but haven't updated the logic above to account for it):
If you turn off solo on all layers, you need to use doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_CLEAR)
, but if even one layer has the solo flag on, you need to use doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_SET)
.
...I think.
@m_adam Thank you for the prompt and thorough reply. I believe I've followed your instructions exactly, but unfortunately: no luck.
I even went so far as to completely remove all other Python installations and reinstall C4D via installer.
It just doesn't seem to be recognizing C4D's embedded python as a valid python installation for some reason. I have confirmed that c4dpy.exe (renamed python.exe) has successfully logged in and is functioning as an interactive intepreter (and in PyCharm).
Any other ideas?
UPDATE: VS Code does seem to be invoking c4dpy, but I'm ~15min into this process with CPU usage pegged near 75% without visible progress:
Hi,
Has anyone had any luck getting R21's c4dpy.exe
to work with the current release of VS Code? I've followed the installation instructions but I'm consistently prompted to "Select Python Interpreter", even though I've set "python.pythonPath": "C:/Program Files/Maxon Cinema 4D R21/c4dpy.exe"
in the VS Code application and workspace settings.
I've been able to get it running in PyCharm, but VS Code doesn't seem to recognize c4dpy.exe as a valid python interpreter.
Any suggestions or insights would be greatly appreciated.
Thanks,
Donovan
Hi,
I'm currently porting a COFFEE script to Python and it seems that accessing/updating tool settings is much more complicated in Python than COFFEE.
I initially tried something like:
active_tool = doc.GetActiveToolData()
active_tool[c4d.MDATA_AXIS_MODE] == 8 # Free Axis Mode
c4d.EventAdd()
But it had no effect. I eventually found my way to this post which led me to a solution like this:
def tool():
"""Retrieves the currently active tool. Doing so allows you to modify tool settings
unlike GetActiveToolData()"""
active_tool_id = doc.GetAction()
if not active_tool_id:
return
active_tool = c4d.plugins.FindPlugin(active_tool_id, c4d.PLUGINTYPE_TOOL)
return active_tool
def main():
"""Switch from Free Mode to Axis mode and vice/versa.
"""
active_tool = tool()
if active_tool is None:
return
active_tool[c4d.MDATA_AXIS_MODE] == 8 # Free Axis Mode
c4d.EventAdd()
ActiveToolData()
vs having to find an instance of the tool/plugin itself?tool()
to the API for accessing the currently active tool, the present method is a bit convoluted for something people will want to do so frequently.Thank you,
Donovan Keith
Hi Maxime - thank you very much for the response, and I'm glad to hear you're considering it for the future.
Hi,
I'm trying to work with doc.StartPickSession(callback, multi) and I'm running into some questions.
Trying this simple code...
import c4d
from c4d import gui
def OnPick(active, multi):
print "active: ", active
print "multi: ", multi
# Main function
def main():
doc.StartPickSession(OnPick, multi=True)
# Execute main()
if __name__=='__main__':
main()
I'm able to start a multi-object pick session, but once I double-click to complete it, I get this error:
TypeError: OnPick() takes exactly 2 arguments (3 given)
After a bit of detective work, it seems that adding a mystery
variable to my callback function def OnPick(mystery, active, multi):
fixes the error. When I run this:
import c4d
from c4d import gui
def OnPick(mystery, active, multi):
print "mystery: ", mystery
print "active: ", active
print "multi: ", multi
# Main function
def main():
doc.StartPickSession(OnPick, multi=True)
# Execute main()
if __name__=='__main__':
main()
I get this console output:
mystery: 0
active: [<c4d.BaseObject object called 'Cube/Cube' with ID 5159 at 0x00000290184D2B90>, <c4d.BaseObject object called 'Cube.1/Cube' with ID 5159 at 0x00000290184D2130>, <c4d.BaseObject object called 'Cube.2/Cube' with ID 5159 at 0x00000290184D2170>]
multi: True
After a bit more detective work, it seems that mystery
is 0
if I complete the pick-session by double-clicking, and it's 1
if I press Esc
to finish the pick session.
mystery
variable, and what is it actually returning.Esc
). What messages/redraws do I need to call after a pick session? Do I need to handle undo or will C4D?Thanks,
Donovan