• Best Practices for Reporting Errors to Users?

    python
    4
    0 Votes
    4 Posts
    1k Views
    dskeithbuckD
    @s_bach & @zipit - Thank you both for the thoughtful replies! I think I'll opt for the status bar for most user-facing feedback, and console logging for anything bigger. Watching the "What could possibly go wrong?" talk now.
  • Copy shader from one material to another

    3
    0 Votes
    3 Posts
    800 Views
    M
    Thanks Bach! I knew it was going to be something simple like that.
  • Selecting the text in a GeDialog MultiLineEditText

    python
    3
    1 Votes
    3 Posts
    428 Views
    ?
    @m_adam You know so much! Thank you for the example code. You have helped me so much, Maxime, particularly on my current project. I am very grateful!
  • New subdivision algorithm as a plugin

    c++ r21
    3
    0 Votes
    3 Posts
    703 Views
    ManuelM
    hello, since r17, some part have change but other remain the same. I would suggest you to first compile the SDK. For that you will need some steps: use the right version of visual studio or xcode, you can find information here[URL-REMOVED] use our project tool to build the solution files. compile a debug versions and a release version. Those should just compile out of the box with no errors. We have a General Plugin Information Manual After that you have to choose a plugin type that fit your need. For your project as @PluginStudent said, an ObjectData (generator) should be the right one. You will find tons of information in our manual for example about the Generator In our sdk (you compiled in first step) there are some example that will help you. You have to register your plugin with RegisterObjectPlugin where you can specify a flag so the generator will pick the child object as an input. About the slider for your parameter you will find information in this page and that manual Of course if you need help we have this forum where you can find a lot of example, information and help. And you can open a new thread for each question you have, we will try to answer them as fast as possible. Cheers, Manuel. [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
  • Remove observer from ObservableFinished

    4
    0 Votes
    4 Posts
    704 Views
    ManuelM
    i'll set that thread as solved.
  • Hide Layers

    Moved
    2
    0 Votes
    2 Posts
    730 Views
    r_giganteR
    Hi @myosis, thanks for reaching out us. With regard to your question, I'm not aware of any mean to hide a layer from the LayerManager nor any function in Cinema that has been designed to achieve this functionality. Cheers, R
  • Switch layout issue in R21.115

    r21
    7
    0 Votes
    7 Posts
    795 Views
    r_giganteR
    Hi Daniel, the reason why it worked "as expected" on older revision was by pure chance - as much as it was for the Redraw thread. Cheers,
  • Setting UA vertical size

    r21 python r20
    3
    1
    0 Votes
    3 Posts
    379 Views
    P
    Ok, something to think about. Never considered using GeuserArea.LayoutChanged when changing the UA size. I will give it a try.
  • No multiple selection in Treeview not working?

    r21 r20 python
    12
    0 Votes
    12 Posts
    2k Views
    P
    Thanks, that solved the issue. -Pim
  • How to Check If you are in a Specific Tab?

    r21 python
    3
    0 Votes
    3 Posts
    346 Views
    B
    @m_adam Thanks. Works as expected.
  • Menu items without RegisterCommandPlugin?

    11
    0 Votes
    11 Posts
    2k Views
    M
    Hi, I'm sorry for the delay, but I can only confirm what you said. In C++ it's possible to call RegisterCommandPlugin but not in Python at runtime. So I guess the best approach is to have as you suggested a menu entry (a pre-registered c4d script or CommandData) that will then create a PopuDialog with a list of all scripts, and then it's up to you to execute them with the code @lasselauch provided. So here an example of how to implement it. import c4d import os def main(): # Gets all python script of a folder searchPath = r"%appdata%\Roaming\Maxon\Maxon Cinema 4D R21_115_XXXXXX\library\scripts" pythonFiles = [os.path.join(folder, f) for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f)) and f.endswith(".py")] # Build the menu for all the entries menu = c4d.BaseContainer() for pythonFileId, pythonFile in enumerate(pythonFiles): menuId = c4d.FIRST_POPUP_ID + pythonFileId filename = os.path.basename(pythonFile) menu.InsData(menuId, filename) # Example to also list regular command. # Uses POPUP_EXECUTECOMMANDS in ShowPopupDialog flag so if its a command its executed directly menu.InsData(c4d.Ocube, "CMD") # Display the PopupDialog result = c4d.gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS, flags=c4d.POPUP_EXECUTECOMMANDS | c4d.POPUP_BELOW | c4d.POPUP_CENTERHORIZ) # If result is bigger than FIRST_POPUP_ID it means user selected something if result >= c4d.FIRST_POPUP_ID: # Retrieves the selected python file scriptId = result - c4d.FIRST_POPUP_ID pythonFile = pythonFiles[scriptId] # Execute it and copy the global to it ( so doc, op are accessible as well) fl = open(pythonFile, 'rb') code = compile(fl.read(), pythonFile, 'exec') exec(code, globals()) # Execute main() if __name__=='__main__': main() ``` Cheers, Maxime.
  • Make Button Invisible And Still Occupies Space?

    r21 python
    7
    0 Votes
    7 Posts
    2k Views
    B
    @PluginStudent @s_bach Thank you for the response. Both works as expected. RE: don't know why you think you need two groups. Just for reference, I was thinking of this logic if self.mode == True: self.Group1_Layout() else: self.Group2_Layout() Anyhow, no further action required
  • BaseDraw scale

    r19 r20 r21 c++
    3
    0 Votes
    3 Posts
    588 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
    581 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
    330 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
    1k 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
    2k 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
    425 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
    856 Views
    P
    Thanks for the answer. And yes, you are fully correct. Things should not be done in DrawMsg()