• ZeroConf error: Couldn’t get bonjour version [sys_bonjour.cpp(1725)]

    2
    0 Votes
    2 Posts
    849 Views
    ManuelM
    Hi, This forum is dedicated for questions from developers about our API. Your issue is a user issue, please contact our support for that question. Cheers, Manuel
  • overwrite the alembic file loading in c4d?

    4
    0 Votes
    4 Posts
    2k Views
    ferdinandF
    Hello @atticuslv, as indicated in my last posting, this is not a programming question, as you do not invoke any of our APIs, and you should reach out to customer support with that question. We only deliver API related support here. Cheers, Ferdinand
  • [Python] LayerShader.AddLayer() -> Defining Shader

    4
    0 Votes
    4 Posts
    8k Views
    indexofrefractionI
    Hi... I'm trying to figure out how to handle nested LayerShaders mat.InsertShader(gradient_shader, sha_xlayer) inserts gradient_shader as a child of sha_xlayer ? Would sha_xlayer.InsertShader(gradient_shader) do exactly the same thing ? If yes, does mat.InsertShader(sha_xlayer) have to be done first as well, or can you set up a shader tree first and then add it to the material? best, index
  • How CINEBENCH_R15 set processor affinity?

    2
    0 Votes
    2 Posts
    910 Views
    ferdinandF
    Hello @sucky012, welcome to the forum and thank you for reaching out to us. This is a forum dedicated to plugin programming for Cinema 4D. The General Talk forum is our sort of Off-Topic forum, but your question is even out of scope for that. We will let your question remain in the forum, but you will not get an answer from the MAXON SDK Team, as Cinebench is simply not our area of expertise, and it seems also unlikely that the community will be able to answer this. When you want end-user support, you should contact them via a support ticket. But I somehow doubt that CINEBENCH 15 is still in the support cycle. But I might be wrong about that. Cheers, Ferdinand
  • Script Request: Multiple STL file Export

    2
    0 Votes
    2 Posts
    904 Views
    ferdinandF
    Hello @prowl, Welcome to the forum and thank you for reaching out to us. I am not sure how your posting is meant. Are you looking for a developer or are you looking for support for developing a solution yourself? If the latter is the case, then you are posting in the wrong sub-forum. When you are indeed looking for a developer, then you are in the right forum. If this is a task which you could solve on your own depends on the details of what you want to achieve, but the principal logic is not that hard to realize. Assuming that you want to implement your idea in Python: Use c4d.utils.SendModelingCommand and the command identifiers for Current State to Object and Connect and Delete to collapse some geometry as you would do it manually in Cinema 4D. Use c4d.documents.SaveDocument with c4d.FORMAT_STL_EXPORT to export the output of the modelling commands. As lined out in the forum guidelines, we cannot design applications for users. There can be things which complicate this simple task (like for example collecting dependencies in a scene). If you do not want to take the risk of being overwhelmed by your task, you should hire a developer. In general, I would say this is a manageable task for a beginner. The Maxon SDK Team will be happy to answer further questions when you decide to implement this yourself. But you must provide code and specific questions related to our APIs. Cheers, Ferdinand
  • Cinema4D CAD Translator SDK

    3
    0 Votes
    3 Posts
    1k Views
    C
    Very good. Thank you for the response and guiding me towards the appropriate channel of communication for this. Best, Clayton
  • Calling a blocking Plugin

    4
    0 Votes
    4 Posts
    1k Views
    FSSF
    Understood.
  • Zertificates for developer documentation expired yesterday

    6
    0 Votes
    6 Posts
    1k Views
    fwilleke80F
    Working again, thanks!
  • Looking for Developer of custom Mograph effector

    3
    0 Votes
    3 Posts
    1k Views
    CairynC
    Done and delivered.
  • Script request: Automatic scale UVW map to a specific size

    Moved
    4
    1
    0 Votes
    4 Posts
    1k Views
    a_blockA
    Well, helping out is generally my business. Although I have to admit, I have some problems understanding the actual goal. If you like, contact me via job AT andreasblock DOT de
  • 0 Votes
    9 Posts
    2k Views
    ferdinandF
    Yeah, I understood that. I did not take any offense here; I just gave a little insight into why I sometimes simplify things to a degree where an expert might say: "But this is not quite right!". I modified the sentence you had an issue with to: So, the Python approach (which is also used by many other languages) is more memory efficient within this simplified view, as you only must store a value once. To more clearly indicate that this is an abstraction. I still would not point out that non-managed languages are effectively more memory efficient than managed ones, as that is not the subject here and actively obfuscates one of the reasons why this is done in these managed languages: To save memory.
  • Thread lost?

    4
    1
    0 Votes
    4 Posts
    1k Views
    ferdinandF
    Hello @a_block , we have removed the restriction of having to add at least one tag to postings in the General Tak forum, allowing for more open-ended and broader questions in this forum. The tagging restrictions for all other forums remain. Cheers, Ferdinand
  • Commandline.exe not loading lib4d preset materials

    r19
    2
    1
    0 Votes
    2 Posts
    1k Views
    ManuelM
    Hi, This forum is dedicated to the support of our API. Your issue does not seem to be related to any coding question. If this is not the case, please contact our user support for any question. Cheers, Manuel
  • Python Plugin Development

    python r21
    3
    0 Votes
    3 Posts
    1k Views
    FSSF
    Hi Ferdinand, thank you for your reply. You were indeed correct, my imports were not working due to bugs. If software bugs had protein, i alone could end world hunger. I was able to solve them after providing the -nogui argument, which then piped out the errors again to the commandline. This worked without in the old version of the plugin, due to it not using any imports besides the local ones (none in the \AppData\Roaming\Python\{PYTHON_VERSION}). As a result the commandline put out errors. If using imports though, the commandline swallowed the output (error+stacktrace) and stayed blank until the plugin was erroring out and the system continued with other plugin calls and the CONSTRING NOT FREED at the end.
  • Wish / request: c4d.CallComand()

    7
    0 Votes
    7 Posts
    2k Views
    a_blockA
    Sorry, my bad, different forum, different rules... I had forgotten, we do not have PMs in here. Send me an email to "job AT andreasblock dot de".
  • Invoke Parent Function inside / outside class (TreeView)

    3
    1
    0 Votes
    3 Posts
    1k Views
    M
    Thank You @ferdinand Access an Enclosing Entity from a Subordinate Entity, was the solution I was searching for hence I needed to alter the GeDialog from inside the TreeViewFunctions. This seems to be the only solution hence these checkboxes belong to the treeview ?!? Anyway its working and I am very happy User sets checkbox -> Sum is calculated -> button is activated. I updated the example code (and removed the now unnecessary button to prevent further confusion) with the desired behavior for future readers. kind regards mogh """ Adapted from: https://developers.maxon.net/forum/topic/10654/14102_using-customgui-listview/2 """ import c4d import random # Be sure to use a unique ID obtained from [URL-REMOVED] PLUGIN_ID = 1000010 # TEST ID ONLY # TreeView Column IDs. ID_CHECKBOX = 1 ID_NAME = 2 ID_OTHER = 3 ID_LONGFILENAME = 4 MY_BUTON = 5 HOW_MANY = 6 ID_FILESIZE = 7 HOW_MANY_MB = 8 MY_CALC = 9 TREEVIEW = 99 # A tuple of characters to select from (a-z). CHARACTERS = tuple( chr ( n) for n in range(97, 122)) class TextureObject(object): """ Class which represent a texture, aka an Item in our list """ def __init__(self): self.texturePath = TextureObject.RandomString(5, 10) self.otherData = TextureObject.RandomString(5, 20) self.longfilename = "-" self._selected = False self.filesize = TextureObject.RandomNumber() @staticmethod def RandomString(minLength, maxLength): """Returns a string of random characters with a length between #minLength and #maxLength. The characters are taken from the 97 (a) to 122 (z) ASCII range. """ return "".join( (random.choice(CHARACTERS) for _ in range(minLength, maxLength))) @staticmethod def RandomNumber(): return random.randrange(1, 99) @property def IsSelected(self): return self._selected def Select(self): self._selected = True def Deselect(self): self._selected = False def __repr__(self): return str(self) def __str__(self): return self.texturePath class ListView(c4d.gui.TreeViewFunctions): def __init__(self, host): """Initializes a ListView with a host. Args: host (c4d.gui.GeDialog): The hosting dialog. """ # Add ten mock data texture objects. self.listOfTexture = [TextureObject() for _ in range(10)] if not isinstance(host, c4d.gui.GeDialog): raise TypeError("Expected {} for argument 'host'. Received: {}".format(c4d.gui.GeDialog, host)) else: self._host = host def DoSomethingWithDialog(self): """Calls the dialog over the stored reference. """ self._host.calc_selected() def IsResizeColAllowed(self, root, userdata, lColID): return True def IsTristate(self, root, userdata): return False def GetColumnWidth(self, root, userdata, obj, col, area): """Measures the width of cells. Although this function is called #GetColumnWidth and has a #col, it is not only executed by column but by cell. So, when there is a column with items requiring the width 5, 10, and 15, then there is no need for evaluating all items. Each item can return its ideal width and Cinema 4D will then pick the largest value. Args: root (any): The root node of the tree view. userdata (any): The user data of the tree view. obj (any): The item for the current cell. col (int): The index of the column #obj is contained in. area (GeUserArea): An already initialized GeUserArea to measure the width of strings. Returns: TYPE: Description """ # The default width of a column is 80 units. width = 80 # Replace the width with the text width. area is a prepopulated # user area which has already setup all the font stuff, we can # measure right away. if col == ID_NAME: return area.DrawGetTextWidth(obj.texturePath) + 5 if col == ID_OTHER: return area.DrawGetTextWidth(obj.otherData) + 5 if col == ID_LONGFILENAME: return area.DrawGetTextWidth(obj.longfilename) + 5 return width def IsMoveColAllowed(self, root, userdata, lColID): # The user is allowed to move all columns. # TREEVIEW_MOVE_COLUMN must be set in the container of AddCustomGui. return True def GetFirst(self, root, userdata): """ Return the first element in the hierarchy, or None if there is no element. """ rValue = None if not self.listOfTexture else self.listOfTexture[0] return rValue def GetDown(self, root, userdata, obj): """ Return a child of a node, since we only want a list, we return None everytime """ return None def GetNext(self, root, userdata, obj): """ Returns the next Object to display after arg:'obj' """ rValue = None currentObjIndex = self.listOfTexture.index(obj) nextIndex = currentObjIndex + 1 if nextIndex < len(self.listOfTexture): rValue = self.listOfTexture[nextIndex] return rValue def GetPred(self, root, userdata, obj): """ Returns the previous Object to display before arg:'obj' """ rValue = None currentObjIndex = self.listOfTexture.index(obj) predIndex = currentObjIndex - 1 if 0 <= predIndex < len(self.listOfTexture): rValue = self.listOfTexture[predIndex] return rValue def GetId(self, root, userdata, obj): """ Return a unique ID for the element in the TreeView. """ return hash(obj) def Select(self, root, userdata, obj, mode): """ Called when the user selects an element. """ # I only use the checkbox to select list elemenmts """ if mode == c4d.SELECTION_NEW: for tex in self.listOfTexture: tex.Deselect() obj.Select() elif mode == c4d.SELECTION_ADD: obj.Select() elif mode == c4d.SELECTION_SUB: obj.Deselect() """ def IsSelected(self, root, userdata, obj): """ Returns: True if *obj* is selected, False if not. """ return obj.IsSelected def SetCheck(self, root, userdata, obj, column, checked, msg): """ Called when the user clicks on a checkbox for an object in a `c4d.LV_CHECKBOX` column. """ if checked: obj.Select() else: obj.Deselect() self.DoSomethingWithDialog() def IsChecked(self, root, userdata, obj, column): """ Returns: (int): Status of the checkbox in the specified *column* for *obj*. """ if obj.IsSelected: return c4d.LV_CHECKBOX_CHECKED | c4d.LV_CHECKBOX_ENABLED else: return c4d.LV_CHECKBOX_ENABLED def GetName(self, root, userdata, obj): """ Returns the name to display for arg:'obj', only called for column of type LV_TREE """ return str(obj) # Or obj.texturePath def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor): """ Draw into a Cell, only called for column of type LV_USER """ if col in (ID_OTHER, ID_LONGFILENAME): text = obj.otherData if col == ID_OTHER else obj.longfilename canvas = drawinfo["frame"] textWidth = canvas.DrawGetTextWidth(text) textHeight = canvas.DrawGetFontHeight() xpos = drawinfo["xpos"] ypos = drawinfo["ypos"] + drawinfo["height"] if (drawinfo["width"] < textWidth): while (drawinfo["width"] < textWidth): if len(text) <= 4: text = "..." break text = text[:-4] + "..." textWidth = canvas.DrawGetTextWidth(text) textWidth = canvas.DrawGetTextWidth(text) drawinfo["frame"].DrawText(text, xpos, ypos - int(textHeight * 1.1)) if col == ID_FILESIZE: text = obj.filesize canvas = drawinfo["frame"] # w = geUserArea.DrawGetTextWidth(name) h = canvas.DrawGetFontHeight() # xpos = drawinfo["xpos"] + 10 xpos = drawinfo["xpos"] + drawinfo["width"] - canvas.DrawGetTextWidth(text) ypos = drawinfo["ypos"] + drawinfo["height"] drawinfo["frame"].DrawText(text, xpos, ypos - int(h * 1.1)) def DoubleClick(self, root, userdata, obj, col, mouseinfo): """ Called when the user double-clicks on an entry in the TreeView. Returns: (bool): True if the double-click was handled, False if the default action should kick in. The default action will invoke the rename procedure for the object, causing `SetName()` to be called. """ c4d.gui.MessageDialog("You clicked on " + str(obj)) return True def DeletePressed(self, root, userdata): "Called when a delete event is received." for tex in reversed(self.listOfTexture): if tex.IsSelected: self.listOfTexture.remove(tex) class TestDialog(c4d.gui.GeDialog): _treegui = None # Our CustomGui TreeView # _listView = ListView() # Our Instance of c4d.gui.TreeViewFunctions def __init__(self): """ """ # Create an instance of ListView and give it access to the dialog # which carries it. self._listView = ListView(host=self) self.overall = len(self._listView.listOfTexture) def CreateLayout(self): # Create the TreeView GUI. customgui = c4d.BaseContainer() customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN) customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) # True if the tree view may have a header line. customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, True) # True if no lines should be drawn. customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, True) # True if the user can move the columns. customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user. customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height. customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) # Alternate background per line. customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed. customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, False) # Suppresses the rename popup when the user presses enter. if self.GroupBegin(id=1000, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, rows=2, cols=1, groupflags=c4d.BORDER_OUT): self.GroupBorderSpace(left=5, top=5, right=5, bottom=5) self.GroupBorderNoTitle(borderstyle=c4d.BORDER_NONE) if self.GroupBegin(id=1001, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, rows=2, cols=3, groupflags=c4d.BORDER_OUT): self.GroupBorderNoTitle(borderstyle=c4d.BORDER_NONE) self._treegui = self.AddCustomGui(TREEVIEW, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, minw=430, minh=160, customdata=customgui) if not self._treegui: print("[ERROR]: Could not create TreeView") return False self.GroupEnd() if self.GroupBegin(id=1002, flags=c4d.BFH_FIT | c4d.BFV_FIT, rows=2, cols=3, groupflags=c4d.BORDER_OUT): self.GroupBorderNoTitle(borderstyle=c4d.BORDER_NONE) self.AddStaticText(HOW_MANY, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_LEFT | c4d.BFH_SCALE, name="Selected: 0 / " + str(self.overall)) self.AddStaticText(HOW_MANY_MB, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_LEFT | c4d.BFH_SCALE, name="Filesize Sum: __________") self.AddButton(MY_BUTON, c4d.BFH_CENTER, name="Enable me by check-boxing") self.Enable(MY_BUTON, False) self.GroupEnd() self.GroupEnd() return True def calc_selected(self): """this is a helper to calculate the selected elements and to enable the button :return: # slected and sum of the selecteed filsize """ selected = 0 filsizesum = 0 self.overall = len(self._listView.listOfTexture) # update our count for fileitem in self._listView.listOfTexture: if fileitem.IsSelected is True: filsizesum += fileitem.filesize selected += 1 if selected > 0: self.Enable(MY_BUTON, True) else: self.Enable(MY_BUTON, False) sel_string = "Selected: " + str(selected) + " / " + str(self.overall) self.SetString(HOW_MANY, sel_string) mb_string = "Filesize Sum: " + str(filsizesum) self.SetString(HOW_MANY_MB, mb_string) return selected, filsizesum def InitValues(self): # Initialize the column layout for the TreeView. layout = c4d.BaseContainer() layout.SetLong(ID_CHECKBOX, c4d.LV_CHECKBOX) layout.SetLong(ID_NAME, c4d.LV_TREE) layout.SetLong(ID_LONGFILENAME, c4d.LV_USER) layout.SetLong(ID_OTHER, c4d.LV_USER) layout.SetLong(ID_FILESIZE, c4d.LV_USER) self._layout = layout self._treegui.SetLayout(5, layout) # Set the header titles. self._treegui.SetHeaderText(ID_CHECKBOX, "Check") self._treegui.SetHeaderText(ID_NAME, "Name") self._treegui.SetHeaderText(ID_LONGFILENAME, "Long Filename") self._treegui.SetHeaderText(ID_OTHER, "Other") self._treegui.SetHeaderText(ID_FILESIZE, "Filesize") self._treegui.Refresh() # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW self._treegui.SetRoot(self._treegui, self._listView, None) return True def Command(self, id, msg): # Click on button if id == MY_BUTON: newID = int(len(self._listView.listOfTexture) + 1) tex = TextureObject() tex.texturePath = "Some new data " + str(newID) tex.longfilename = TextureObject.RandomString(20, 40) self._listView.listOfTexture.append(tex) self.calc_selected() self._treegui.Refresh() return True class MenuCommand(c4d.plugins.CommandData): dialog = None def Execute(self, doc): if self.dialog is None: self.dialog = TestDialog() return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, defaulth=300, defaultw=430) def RestoreLayout(self, sec_ref): if self.dialog is None: self.dialog = TestDialog() return self.dialog.Restore(PLUGIN_ID, secret=sec_ref) def main(): c4d.plugins.RegisterCommandPlugin( PLUGIN_ID, "Python TreeView Example", 0, None, "Python TreeView Example", MenuCommand()) if __name__ == "__main__": main() [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
  • fbx import missing animation

    2
    0 Votes
    2 Posts
    1k Views
    ferdinandF
    Hello @christajj, welcome to the Plugin Café and thank you for reaching out to us. These are the forums of the development community of Cinema 4D. The subjects discussed in these forums are exclusively the APIs related to Cinema 4D. Your question is therefore unfortunately off topic, even in our more broadly scope forum General Talk. When you require customer support from Maxon, you should contact us in our customer Support Center. Established and English-speaking Cinema 4D user communities can be found at Core 4D and CGTalk. Thank you for your understanding, Ferdinand
  • Looking for Developer of custom Mograph effector

    2
    0 Votes
    2 Posts
    1k Views
    ManuelM
    Hi, There is the EffectorData class that could help you to create your own effector. This class is only available on c++. With python the only option is to use the python effector. And that could be tricky because you need to retrieve the size of all clones. Doable but tricky imo. I hope that you will find a developer to do it, this might look easy to do but is harder than you might thought. Cheers, Manuel
  • particle direction driven by texture

    3
    2
    0 Votes
    3 Posts
    2k Views
    H
    Thank you alot Ferdinand for your time, thoughs and help. I really appreciate that:)' I will get my head in it and try to figure it out.
  • Xpreso plugin development

    python
    2
    0 Votes
    2 Posts
    698 Views
    ferdinandF
    Hello @rastan_cgi, Thank you for reaching out to us. This forum is targeted at software development with the Cinema 4D & Cineware SDK. Xpresso or Scene Nodes are not part of the scope of the forum and the support Maxon does deliver here. However, you already did post in the correct forum for asking an off-topic question, the General Talk forum. The community is welcome to discuss here topics that are adjacent to the Cinema 4D & Cineware SDKs, as for example Xpresso. But the SDK-Team cannot offer any support for these questions. If you seek an official answer from Maxon, you should contact user support. With that being said: Xpresso setups cannot automatically be converted into a Python or C++ plugin. You can provide a scene with a null object and your setup, but these workflows are not within the scope of the SDK-Team. When you seek help with reimplementing your Xpresso setup as a plugin, for example as a Python plugin, then we will need more information on what the Xpresso setup does. We can then tell you where you can find learning resources related to your goals, but you will have to write the code yourself. Cheers, Ferdinand