The Maxon SDK Team is currently short staffed due to the winter holidays. No forum support is being provided between 15/12/2025 and 5/1/2026. For details see Maxon SDK 2025 Winter Holidays.
  • BaseDraw scale

    r19 r20 r21 c++
    3
    0 Votes
    3 Posts
    544 Views
    rsodreR
    @r_gigante Thanks, I used an inverse scale matrix wen calculating my gizmo points.
  • Get the Button GadgetID Directly Under the Mouse?

    r21 python
    11
    0 Votes
    11 Posts
    2k Views
    B
    Hi @m_adam Thanks for the patience. Your suggestions and reminders works are greatly appreciated. I guess the confusion stems mainly on my part because I posted slightly two different codes. You were responding to my initial post but I was thinking with the code from the succeeding post(the one in the rar file). Totally my bad. Anyhow, here is the working code (using the initial post) which works as I expected: import c4d class ColorButton(object): def __init__(self): self.width = None self.height = None self.color = None self.color = None self.btn_id = None self.menu_list = None def create(self, dlg, w, h, color, btn_id): self.width = w self.height = h self.color = color self.btn_id = btn_id bmp_color = c4d.bitmaps.BaseBitmap() bmp_color.Init(w, h) for y in xrange(w): for x in xrange(h): bmp_color.SetPixel(x, y, color[0], color[1], color[2]) bcBitmapButton = c4d.BaseContainer() bcBitmapButton[c4d.BITMAPBUTTON_BUTTON] = True bmp_btn = dlg.AddCustomGui(self.btn_id, c4d.CUSTOMGUI_BITMAPBUTTON, "", c4d.BFH_CENTER | c4d.BFV_CENTER, w, h, bcBitmapButton) bmp_btn.SetImage(bmp_color, True) def create_menu(self): self.menu = c4d.BaseContainer() for menu_item in self.menu_list: counter = 0 IDM_MENU = c4d.FIRST_POPUP_ID + counter self.menu.InsData(IDM_MENU, menu_item) counter += 1 class MyDialog(c4d.gui.GeDialog): def __init__(self): self.btn_id_list = [] self.class_btn_id_dict = {} def CreateLayout(self): red_button = ColorButton() red_button.create(self, w=50,h=50,color=(255,0,0), btn_id=6000) red_button.menu_list = ['Menu1', 'Menu2', 'Menu3'] self.btn_id_list.append(red_button.btn_id) self.class_btn_id_dict[6000] = red_button blue_button = ColorButton() blue_button.create(self, w=50,h=50,color=(0,0,255), btn_id=7000) blue_button.menu_list = ['Menu4', 'Menu5', 'Menu6', 'Menu7'] self.btn_id_list.append(blue_button.btn_id) self.class_btn_id_dict[7000] = blue_button green_button = ColorButton() green_button.create(self, w=50,h=50,color=(0,255,0), btn_id=8000) green_button.menu_list = ['Menu8', 'Menu9'] self.btn_id_list.append(green_button.btn_id) self.class_btn_id_dict[8000] = green_button return True def IsPositionOnGadget(self, gadgetId, x, y): # Be sure that the windows is opened, # in our case since we call it in BFM_INTERACTSTART it's ok buttonData = self.GetItemDim(gadgetId) if not buttonData["x"] < x < buttonData["x"] + buttonData["w"]: return False if not buttonData["y"] < y < buttonData["y"] + buttonData["h"]: return False return True def function_to_determine_gadgetId_under_mouse_cursor(self, x, y): for gadgetId in self.btn_id_list: if self.IsPositionOnGadget(gadgetId, x, y): return gadgetId def Message(self, msg, result): if msg.GetId() == c4d.BFM_ADJUSTSIZE: self._x = msg[3] # Retrieve Y size of the GeDialog self._y = msg[4] # Retrieve Y size of the GeDialog # We are on the main thread here elif msg.GetId() == c4d.BFM_INTERACTSTART: c4d.StopAllThreads() state = c4d.BaseContainer() self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSERIGHT, state) if state.GetInt32(c4d.BFM_INPUT_VALUE) == True: x = state.GetInt32(c4d.BFM_INPUT_X) y = state.GetInt32(c4d.BFM_INPUT_Y) g2l = self.Global2Local() x += g2l['x'] y += g2l['y'] gadgetId = self.function_to_determine_gadgetId_under_mouse_cursor(x=x,y=y) if gadgetId in self.btn_id_list: if self.IsPositionOnGadget(gadgetId=gadgetId, x=x, y=y): button_class = self.class_btn_id_dict[gadgetId] button_class.create_menu() l2s = self.Local2Screen() print str(x+l2s['x']) + " :: " + str(y+l2s['y']) self.KillEvents() res = c4d.gui.ShowPopupDialog(cd=self, bc=button_class.menu, x=x+l2s['x'], y=y+l2s['y']) return True return c4d.gui.GeDialog.Message(self, msg, result) if __name__ == "__main__": dlg = MyDialog() dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=20304050)
  • Alembic camera properties

    python r21
    2
    0 Votes
    2 Posts
    541 Views
    ManuelM
    Hello, Some symbols are not exposed to public. There's no particular reason for that. There's no real place where all exposed symbols are. (and we agree it's could be nice) To know if a BaseObject is a camera (or something) you can use IsInstanceOf You can also send a message using the ID MSG_GETREALCAMERADATA : with an alembic generator you can use this code : camera = doc.GetActiveObject() if camera is None: return if camera.IsInstanceOf(c4d.Oalembicgenerator) == False: return # This example tries to get the internal camera from a generator. # Typically used with the Alembic Generator camera. data = {} data["res"] = None res = camera.Message(c4d.MSG_GETREALCAMERADATA, data) if res: camera = data["res"] print("Camera: " + camera.GetName()) 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. Q&A New Functionality. How to Post Questions especially the tagging part. I've marked this thread as a question so when you considered it as solved, please change the state Cheers, Manuel
  • Reacting on Treeview user action

    r21 r20 python
    2
    0 Votes
    2 Posts
    311 Views
    P
    I found a reply here. https://developers.maxon.net/forum/topic/11447/get-message-from-treeview-gui-dialog/2
  • std compile error

    r19 c++
    6
    0 Votes
    6 Posts
    987 Views
    M
    I know this is quite an old topic, @m_magalhaes @Jmelon it would compile if you put c4d.h at the end of all other STL includes
  • Grayed out or disabled X button

    Moved
    8
    0 Votes
    8 Posts
    1k Views
    M
    @mp5gosu This sounds like the solution I was looking for Thanks a lot! Ps, yes im a noob...
  • Adding my own field to the Preference dialog

    r21 python
    3
    0 Votes
    3 Posts
    415 Views
    P
    Thank you. I will look into it and try it.
  • UA is update too often

    r21 r20 python
    3
    0 Votes
    3 Posts
    770 Views
    P
    Thanks for the answer. And yes, you are fully correct. Things should not be done in DrawMsg()
  • How do I compile a plug-in that is compatible with both R20 and R21

    r21 r20 c++
    4
    0 Votes
    4 Posts
    698 Views
    r_giganteR
    Hi sean, thanks for reaching out us. The broken forward compatibility between R20 and R21 is reported on Changes in R21. With regard to backward binary compatibility, it has never been possible to run a plugin built against a more recent API and load on a previous Cinema 4D executable as reported on Portability and Compatibility. Best, R.
  • GeUserArea lag in R21 versus R20

    r21 r20 c++
    8
    0 Votes
    8 Posts
    1k Views
    M
    Yes your code could be optimized but we agree with you here this is not really the point, a R20 code is expected to have the same performance with R21 and here this is not the case. And @C4DS I agree using GeIsMainThread() == false I would say partially fix the issue (sometimes it works as R20, sometimes not) We keep investigating it. Cheers, Maxime.
  • Plugin not found after switching layout

    r21 c++
    3
    0 Votes
    3 Posts
    554 Views
    C4DSC
    @s_bach said in Plugin not found after switching layout: The ID used with GeDialog::Open() and RestoreLayout() is typically the plugin ID of the CommandData plugin. See e.g. activeobject.cpp Thanks. It had to be something so simple I kept missing when reviewing the code.
  • Unable to Add Objects for User Data with In/Exclusion Data Type

    r21 python
    3
    0 Votes
    3 Posts
    369 Views
    B
    Thanks for the explanation. Works as expected.
  • Exporting Motion Clips & what are .c4dsrc Files?

    sdk python
    3
    0 Votes
    3 Posts
    662 Views
    ?
    @m_adam Hi Maxime, thank you for the quick reply and insight into this. I look forward to trying this.
  • Understanding SetCommandDragId

    6
    0 Votes
    6 Posts
    1k Views
    M
    Correct, and I would say a CommandData id.
  • AddUserData() for In/Exclusion List?

    r21 python
    3
    0 Votes
    3 Posts
    400 Views
    B
    @r_gigante Thanks for the response. Works as expected.
  • Integrating a CallCommand() with Built-In Save Dialog?

    r21 python
    3
    0 Votes
    3 Posts
    383 Views
    B
    @m_magalhaes Thanks for the confirmation.
  • Redrawing GeUserArea in ScrollGroup with Slider Input

    sdk python
    7
    1
    0 Votes
    7 Posts
    1k Views
    ?
    @m_adam Thank you, Maxime, for going to this effort.
  • Generator crashes and guidance

    c++
    13
    0 Votes
    13 Posts
    2k Views
    ManuelM
    Hello, please open a new thread for that question, we will probably need your code. You can send it to us using our email [email protected] Cheers, Manuel
  • Listening for Selection Events

    python
    5
    0 Votes
    5 Posts
    618 Views
    ManuelM
    hello, To retrieve the active object you have to iteration trough the hierarchy. (even GetActiveObject) In Python, GetActiveObjects is calling a c++ function so with lots of object it will be faster than iterating the hierarchy with python functions. We don't know what the limit is. To mesure that you have to make a bunch of tests with different scenarios and get the mean. Cheers, Manuel
  • Getting GeDialog Group Width & Height?

    python
    3
    0 Votes
    3 Posts
    341 Views
    ?
    @r_gigante Thank you, Riccardo! I don't know how I missed that in the documentation, but it is what I needed.