Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login
    1. Maxon Developers Forum
    2. mogh
    3. Topics
    M
    • Profile
    • Following 0
    • Followers 0
    • Topics 33
    • Posts 146
    • Best 10
    • Controversial 0
    • Groups 0

    Topics created by mogh

    • M

      How to receive the high definition / Interpolation version of a spline?

      Cinema 4D SDK
      • python • • mogh
      7
      0
      Votes
      7
      Posts
      922
      Views

      M

      Ok Understood,

      Ok I guess that explains my "nice" comb from the cache and my jagged flip/flop . sometimes zero comb from the "full" matrix normal ...

      I also have different tangents from manually "calculating" them then v3, v2. But I will make a "sanity" check this weekend (feed manual matrixes into my code instead of spline "point" matrixes), before I post about this.

      Thanks Ferdinand
      I'll divide and conquer away.

    • M

      TagData Plugin with Gui not using *.res

      Cinema 4D SDK
      • python • • mogh
      3
      0
      Votes
      3
      Posts
      455
      Views

      M

      Understood Thanks.

    • M

      General Question: Which Plugin Type? -> Curvature Comb / Plot

      Cinema 4D SDK
      • python • • mogh
      6
      0
      Votes
      6
      Posts
      676
      Views

      M

      curvature_comb.png

      not bad for 5 hours of dabbling --- thanks to you @ferdinand

      Gotcha's:
      The Curvature was 90dgree rotated - LLM to the rescue ...

      # c4d.plugins.RegisterTagPlugin( .... # That one nearly got me ;-) # c4d.TAG_IMPLEMENTS_DRAW_FUNCTION # R22

      cheers

    • M

      res file, formatting, line ending, or encoding ?

      Cinema 4D SDK
      • windows c++ python • • mogh
      11
      0
      Votes
      11
      Posts
      1.0k
      Views

      ferdinandF

      Thanks for helping out @spedler!

    • M

      Programing a Tabulated BRDF Node / Shader - possible ?

      Cinema 4D SDK
      • 2024 • • mogh
      6
      0
      Votes
      6
      Posts
      875
      Views

      ferdinandF

      Hey,

      Out of curiosity, I did some poking in Redshift, and what I forgot, is that you are in principle unable to escape the current shading context of a sample in Redshift. I.e., you cannot just say, "screw the current UV coordinate, please sample my texture 'there'" due to the closure thing which Redshift has going.

      With the Standard Renderer, you can do the following, which is pretty close. I compute the v (i.e., view angle coordinate) as described above. Standard also does not give you directly light ray angles, but you can get the light contribution where I use the diffuse component of the light(s) as a faksimile: High diffuse = high angle of incident/light contribution.

      82ee51e1-15a9-487b-8cb0-91eec633352e-image.png
      Fig. I: A crude iridescence setup in Standard. test.png is your texture from above, I forgot to take the inverse of values as 1 - x.

      view_angle.zip

      In Redshift you cannot do the same light contribution hack, and I currently do not see how you could set the sampling coordinate of the texture in the first place. Maybe the Redshift pro's know more.

      Cheers,
      Ferdinand

    • M

      How to add "scripts" to a menu?

      Cinema 4D SDK
      • 2024 python • • mogh
      4
      0
      Votes
      4
      Posts
      1.3k
      Views

      ferdinandF

      Hey @mogh,

      I know that you did not meant any harm and the word hijack was a bit strong - which is why reworded that before you answered. But topics should remain focused on a singular thing, the specific question of the original poster, rather than being a collection of questions from multiple people which roughly align with whatever broader topic they see embodied in a thread.

      Cheers,
      Ferdinand

    • M

      GUI created Redshift Camera is registered as baseobject not as OCamera ?

      Cinema 4D SDK
      • python 2024 • • mogh
      3
      0
      Votes
      3
      Posts
      544
      Views

      M

      Thanks you answered my question, if it solves my problem we will see. 🙂

    • M

      Python version suddenly reported as 3.1 in 2023.2

      Cinema 4D SDK
      • sdk python 2023 • • mogh
      3
      0
      Votes
      3
      Posts
      575
      Views

      M

      Ok, thanks Ferdinand your clarification shed some light on my problem.

      I convert the version to a float which is the culprit ...

      import sys if sys.version_info < (3, 2): print("This Plugin requires at least Python 3.2")

      thank you

    • M

      Quicktab SDK Example

      Cinema 4D SDK
      • r20 2023 python sdk • • mogh
      9
      0
      Votes
      9
      Posts
      1.8k
      Views

      M

      While rethinking about it last night, it may not be that slow if on user interaction you just flush the main group and re-attach already existing dialog.

      So you need to modify your `def _DrawQuickTabGroup(self)`` method like so to only display visible dialog:

      def _DrawQuickTabGroup(self, onlyVisible=True): """ Creates and draws all the SubDialog for each tab, take care it does not hide these according to a selection state. Returns: True if success otherwise False. """ # Checks if the quicktab is defined if self._quickTab is None: return False activeIds, activeNames = self.GetActiveTabs() # Flush the content of the group that holds all ours SubDialogs self.LayoutFlushGroup(ID_MAINGROUP) #self.GroupBorderSpace(left=5, top=5, right=5, bottom=5) # Iterates over the number of tab to create and attach the correct SubDialog for tabId, (tabName, tabGui) in enumerate(self._tabList.items()): toDisplay = tabId in activeIds if not toDisplay: continue self.AddSubDialog(ID_QUICKTAB_BASE_GROUP + tabId, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0) self.AttachSubDialog(tabGui, ID_QUICKTAB_BASE_GROUP + tabId) self.LayoutChanged(ID_MAINGROUP) return True

      Then in the Command message instead of calling DisplayCorrectGroup you should call _DrawQuickTabGroup like so:

      def Command(self, id, msg): if id == ID_QUICKTAB_BAR and self._quickTab: self._DrawQuickTabGroup() return True

      Regarding your question and classic Tab, find an example in Remove a GeDialog Tab Group but as you can see this is also not possible to remove a tab without redrawing everything .

      Cheers,
      Maxime.

    • M

      Color accuracy 32 bit - how to archive - things to look out for ...

      General Talk
      • • • mogh
      7
      0
      Votes
      7
      Posts
      1.1k
      Views

      M

      Thanks, @ferdinand

      Yes seems intended but could be troublesome if you use mograph / redshift object color to drive something ?

      C4D Version : 2023.1.2

      A solution to guide the user could be to disable the object color when set to "Render Instance" , but from a UX standpoint I am not a fan of taking away control from the user.

      thanks for taking it to CS
      kind regards mogh

    • M

      SDK typo/discrepancy ? bitmap.Init() regarding bitdepth

      Bugs
      • python sdk • • mogh
      7
      0
      Votes
      7
      Posts
      1.8k
      Views

      M

      Thank you Ferdinand for your time,
      and also providing a high / low level solution.

      As far as I can tell it works all as intended - my code now results in clean colors "measured". (in lowlvl R20 and highlvl 2023)

      I found a small discrepancy with render instances but that's another topic.
      Cheers,
      mogh

    • M

      Catch - 'c4d.BaseDraw' is not alive

      Cinema 4D SDK
      • • • mogh
      2
      0
      Votes
      2
      Posts
      491
      Views

      ferdinandF

      Hey @mogh,

      Thank you for reaching out to us. The idea of a node, a c4d.C4DAtom not being alive means that the Python layer cannot find the C++ C4DAtom which the Python layer c4d.C4DAtom was referencing, usually because something has been reallocated in the background while someone was long-term storing a c4d.C4DAtom instance. We talked about it here in more detail.

      Sometimes you then must write elaborate interfaces which recapture the same thing over their UUID, e.g., get hold of the same shader once its Python reference has gone bad. But that does not seem necessary here since you are interested only in the active viewport of the active document. It is in this case also not only the case that the viewport could have been reallocated, but also what is the active viewport could have changed (although that will likely cause viewports to be reallocated).

      So, when you want to modify the active base draw, in fact any node, make sure to get a fresh reference when possible.

      doc: c4d.document.BaseDocument = c4d.documents.GetActiveDocument() bd: c4d.BaseDraw = doc.GetActiveBaseDraw() self.AddCheckbox(ID_SAVEFRAME, flags=c4d.BFH_LEFT, initw=270, inith=0, name="Show Save Frame") self.SetBool(ID_SAVEFRAME, bd[c4d.BASEDRAW_DATA_SHOWSAFEFRAME])

      If you need access to the active viewport of the active document very often, you could make it a property with some mild caching.

      import c4d import typing class Foo: """Provides cached access to the active document and active viewport. """ def __init__(self) -> None: self._activeDocument: typing.Optional[c4d.documents.BaseDocument] = None self._activeViewport: typing.Optional[c4d.BaseDraw] = None @property def ActiveDocument(self) -> c4d.documents.BaseDocument: """Returns the active document. """ if self._activeDocument is None or not self._activeDocument.IsAlive(): self._activeDocument = c4d.documents.GetActiveDocument() return self._activeDocument @property def ActiveBaseDraw(self) -> c4d.BaseDraw: """Returns the active viewport in the active document. """ if self._activeViewport is None or not self._activeViewport.IsAlive(): self._activeViewport = self.ActiveDocument.GetActiveBaseDraw() return self._activeViewport def Bar(self) -> None: """Makes use of the #ActiveBaseDraw property. """ self.ActiveBaseDraw[c4d.BASEDRAW_DATA_TEXTURES] = True ⚠ Although this also suffers from the problem that what is the active viewport could have changed. Caching anything that is "active" is a bad idea as what is active can change. Active entities should always be retrieved when required unless one can guarantee that they cannot change (by being in a modal dialog for example).

      Cheers,
      Ferdinand

    • M

      Button Hover -> Helptext - searching for example

      Cinema 4D SDK
      • • • mogh
      5
      0
      Votes
      5
      Posts
      688
      Views

      M

      I use CreateLayout ... no description file ...

      but as I wrote probably a little bit to cryptic I am fine for now.

      Thanks for the reply Manuel.
      Cheers mogh

    • M

      MCOMMAND_MAKEEDITABLE why does this comand need an object in scene oposed to passing it in Ram?

      Cinema 4D SDK
      • python sdk • • mogh
      4
      0
      Votes
      4
      Posts
      673
      Views

      ferdinandF

      Hey @mogh,

      just to clarify: I found that bit of the documentation before you pointed it out, but in my mind I could not link "needs a document" to "the object has to be present" ...

      Well, the documentation clearly states it:

      doc (Optional[c4d.documents.BaseDocument]) – The document for the operation. Should be set if possible. Must be set for MCOMMAND_JOIN, MCOMMAND_MAKEEDITABLE, MCOMMAND_CURRENTSTATETOOBJECT and MCOMMAND_SPLINE_PROJECT.

      If you set the document, the objects which you pass to this function have to be in the same document. So pay attention that you use one send_modeling_command per document for objects.

      But that could be more visible. I'll see if I can rework the function documentation a bit to make that important information more prominent.

      Cheers,
      Ferdinand

    • M

      Wish / request: c4d.CallComand()

      General Talk
      • • • mogh
      7
      0
      Votes
      7
      Posts
      1.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".

    • M

      Invoke Parent Function inside / outside class (TreeView)

      General Talk
      • • • mogh
      3
      0
      Votes
      3
      Posts
      760
      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.

    • M

      Treeview Column adjust

      Cinema 4D SDK
      • python r20 r25 • • mogh
      8
      0
      Votes
      8
      Posts
      1.4k
      Views

      ferdinandF

      Hey @mogh,

      Thank you for the kind words and I am happy that this solved your problem.

      While I sometimes channel here my inner librarian and press for a formal order for new topics, so that the SDK Team can answer them effectively, I want to make clear that all Cinema 4D programming questions are welcome on Plugin Café.

      Just remember to open a new topic for new questions and to place them in the General Talk forum when they are general programming questions not directly related to our APIs. We will treat them then with a lower priority and rigor, but we usually also answer there.

      Cheers,
      Ferdinand

    • M

      Draw Icon (maxon id) into treeview list geUserArea()

      Cinema 4D SDK
      • r25 python • • mogh
      3
      0
      Votes
      3
      Posts
      559
      Views

      M

      Thanks, @m_magalhaes
      yes my code is inside the drawcell() method.

      I didn' have any luck with c4d.gui.GetIcon(lIconID)
      but i got c4d.bitmaps.InitResourceBitmap(resource_id)
      working.

      here are my 3 lines of code that got me an icon.

      ICON_SIZE = drawinfo["height"] bmp = c4d.bitmaps.InitResourceBitmap(12098) geUserArea.DrawBitmap(bmp, drawinfo["xpos"], drawinfo["ypos"], ICON_SIZE, ICON_SIZE, 0, 0, bmp.GetBw(), bmp.GetBh(), c4d.BMP_ALLOWALPHA)

      kind regards
      mogh

    • M

      Best practice getting all objects in a certain Null

      Cinema 4D SDK
      • • • mogh
      12
      0
      Votes
      12
      Posts
      1.8k
      Views

      M

      Found the problem I tried to Kill a document which was not alive, don't know if this is necessary with a merge.

      if c4d.C4DAtom.IsAlive(temp): c4d.documents.KillDocument(temp)

      And another gotcha c4d.documents.SetActiveDocument(temp) seems to be mandatory if you want to use CallCommand() -> and do not to forget to set the doc back to active after your routine.

      Thank you

    • M

      Compare Matrices Matrix with matrix.__eq__

      Cinema 4D SDK
      • r25 python • • mogh
      3
      0
      Votes
      3
      Posts
      601
      Views

      M

      I was suspecting something like this ...
      Thanks for taking the time to type a solution which I could copy ...