Great input, thanks.
I will have a look at the Mac mini, if not, I will go back to a windows desktop.
Again, thank you both.
Regards,
pim
Great input, thanks.
I will have a look at the Mac mini, if not, I will go back to a windows desktop.
Again, thank you both.
Regards,
pim
I am looking for a new pc with windows 11.
This time I would like to buy a mini pc.
However, most mini pc have none NVidia card, for example the AMD Ryzen 680M 12 Core 2400 MHz graphic card.
Is that a good choice for running cinema 4d?
Ok, I understand it now better, thanks.
@pim
I solved it.
You must insert the shader into the document and then insert it in the displacer
from typing import Optional
import c4d
doc: c4d.documents.BaseDocument # The active document
op: Optional[c4d.BaseObject] # The active object, None if unselected
def main() -> None:
displacer = c4d.BaseObject(c4d.Odisplacer)
doc.InsertObject(displacer)
shd = c4d.BaseList2D(c4d.Xnoise)
doc.InsertShader(shd)
displacer[c4d.ID_MG_SHADER_SHADER] = shd
#displacer.InsertShader(shd)
c4d.EventAdd()
if __name__ == '__main__':
main()
I am trying to set the Shader field in the Displacemtn object to Noise. However, the filed is not filled.
Here the code.
What am I doing wrong?
from typing import Optional
import c4d
doc: c4d.documents.BaseDocument # The active document
op: Optional[c4d.BaseObject] # The active object, None if unselected
def main() -> None:
displacer = c4d.BaseObject(c4d.Odisplacer)
doc.InsertObject(displacer)
shd = c4d.BaseList2D(c4d.Xnoise)
#displacer[c4d.ID_MG_SHADER_SHADER] = shd
displacer.InsertShader(shd)
c4d.EventAdd()
if __name__ == '__main__':
main()
Thanks again for the great explanation.
I guess I will go for a different workflow then.
I am not sure what you mean with a Baselink?
A Cloner, imo, does not notice when a child is added or deleted.
I guess there is (somewhere) a message that signals a deletion?
I have a plugin that created a Cloner and insert planes as children of that cloner. After that I update the Cloner Count.
However, when the user deletes a plane ( a child of that cloner), the Cloner count must be updated.
What is the best way to detect an object has been deleted and I can update the Cloner count?
I really do appreciate all your effort and I will take your warning seriously and create my own menu Tab.
Thanks again.
Regards,
Pim
@ferdinand
I run the script, but it hangs cinema 4d.
After some debugging, I could see that the insertion point was found and that it was inserted in items.
I am not sure what statement hangs cinema 4d.
I am using R2023.2.1 on a Windows 10 Pro 22H2.
@ferdinand
Ok, I can now insert my command in the render Tab, but it is positioned at the end.
This is, I guess, because I use InsData() instead of InsDataAfter()
Refering to my first code, this was my thinking:
When using InsDataAfter(), looking at the documentation, I thought that last(any) indicates the position after where to insert the command. That is why I used sub.
So, how to indicate where to insert the command?
BaseContainer.InsDataAfter(self, id, n, last)¶
Inserts an arbitrary data at the specified id after last.
Warning This function does not check if the ID already exists in the container!
Parameters
id (int) – The ID to insert at.
n (any) – The data to insert.
last (any) – The data to insert after.
Working code that inserts the command at the end.
from typing import Optional
import c4d
pluginId = "1052844" # official plugin ID
def main() -> None:
MainMenu = c4d.gui.GetMenuResource("M_EDITOR")
for bcMenuId, bcMenu in MainMenu:
#print (bcMenu[c4d.MENURESOURCE_SUBTITLE])
if bcMenu[c4d.MENURESOURCE_SUBTITLE] == "IDS_EDITOR_RENDER":
for sub in bcMenu:
if (sub[1] == "IDM_RENDERAUSSCHNITT"):
print ("*** Insert after this ***")
# Add my plugin
#bcMenu.InsDataAfter(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_5159", sub)
bcMenu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_" + pluginId)
c4d.gui.UpdateMenus()
if __name__ == '__main__':
main()
I found where to insert my own command (plugin),
but I get following message.
Traceback (most recent call last):
File "scriptmanager", line 22, in <module>
File "scriptmanager", line 18, in main
TypeError: argument 3 must be PyCapsule, not tuple
Also I am not sure I insert my plugin correctly.
I do not fully understand how to indicate my plugin; PLUGIN_CMD_5159, name or id?
Here the code
from typing import Optional
import c4d
doc: c4d.documents.BaseDocument # The active document
op: Optional[c4d.BaseObject] # The active object, None if unselected
def main() -> None:
MainMenu = c4d.gui.GetMenuResource("M_EDITOR")
for bcMenuId, bcMenu in MainMenu:
#print (bcMenu[c4d.MENURESOURCE_SUBTITLE])
if bcMenu[c4d.MENURESOURCE_SUBTITLE] == "IDS_EDITOR_RENDER":
for sub in bcMenu:
if (sub[1] == "IDM_RENDERAUSSCHNITT"):
print ("*** Insert after this ***")
# Add my plugin
bcMenu.InsDataAfter(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_5159", sub)
c4d.gui.UpdateMenus()
if __name__ == '__main__':
main()
Aha, good to know.
I had the same issue, but now I know what to do.
Great work!!!
Thank you.
Regards,
Pim
If I understand your ps correctly;
I do think that c4d.gui.MessageDialog indeed interrupts/stops the slider.
However, I think the slider already 'gave' multiple messages before I handle them in Command()
Are you also saying I should handle this in GeDialog::Message() and not in GeDialog::Command()?
Also, could it be the same issue as in post https://developers.maxon.net/forum/topic/14470/?
I have a commandplugin with a dialof with a slider.
In Command() I check the input.
If it its the slider, I check the active object and then get the input.
def Command(self, id, msg):
doc = documents.GetActiveDocument()
if (id == ID_GETSLIDER):
parent = doc.GetActiveObject()
if (not parent):
gui.MessageDialog('Please select an object')
return True
....
However, when I change (slide) the slider and there is no active object, the message is displayed, but immediately a second, third, etc. message is displayed.
This is - I think - because due to the slider (slide) the field is selected multiple times and thus Command() is triggered multiple times.
How can I make sure that only the last value of the slide is returned.
So, not all values during the slide, but only the 'last' value.
I have a commandplugin with two CUSTOMGUI_LINKBOX.
One for an object link and one for a material link.
How do I store these links in a hyperfile?
Thanks, clear now.
I will stop using ChatGPT.
Regards,
Pim
I want to add user data with type Spline.
However DTYPE _SPLINE is not recognized?
AttributeError: module 'c4d' has no attribute 'DTYPE_SPLINE'
What am I doing wrong?
import c4d
def main():
# Get the active document
doc = c4d.documents.GetActiveDocument()
# Add user data for the spline
userdata_id = c4d.DescID(c4d.DescLevel("MySpline", c4d.DTYPE_SPLINE, 0))
userdata = op.AddUserData(userdata_id, "MySpline", c4d.CUSTOMGUI_SPLINE)
# Set the spline data for the user data
userdata_data = userdata.GetData()
userdata_data.SetData(c4d.DESC_NAME, "MySpline")
userdata_data.SetData(c4d.DESC_DEFAULT, c4d.SplineData())
userdata_data.SetData(c4d.DESC_ANIMATE, c4d.DESC_ANIMATE_ON)
userdata_data.SetData(c4d.DESC_UNIT, c4d.DESC_UNIT_REAL)
userdata_data.SetData(c4d.DESC_CUSTOMGUI, c4d.CUSTOMGUI_SPLINE)
userdata_data.SetData(c4d.DESC_SCALEH, 100)
userdata_data.SetData(c4d.DESC_CUSTOMGUI, spline_data)
# Update the document
c4d.EventAdd()
if __name__ == '__main__':
main()
In this post https://developers.maxon.net/forum/topic/14045
an example is given, how to define the SplineCustomGui interface.
I like to know how to get the spline data from the interface.
I added a button to the dialog and tried this, but I got None as result.
def Command(self, id, msg):
if (id == 210200):
print ("Button")
print (self.descriptionGUI.GetData())
return True