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
    M
    • Profile
    • Following 0
    • Followers 0
    • Topics 33
    • Posts 146
    • Best 10
    • Controversial 0
    • Groups 0

    mogh

    @mogh

    Industrial Designer, Product Visualization, a slight itch for scripting.

    9
    Reputation
    99
    Profile views
    146
    Posts
    0
    Followers
    0
    Following
    Joined Last Online
    Location South Germany

    mogh Unfollow Follow

    Best posts made by mogh

    • RE: How to setup c4d.utils.ViewportSelect() and GetNearestPoint to work

      @m_magalhaes

      This morning: uff more learning and work.
      This Afternoon lets try this code ... mind blown ... thank you !

      I'll mark this as solved hence I think ist a good way to close a thread with a working prototype for others to learn.

      Thank You again, @zipit & @m_magalhaes
      mogh

      posted in Cinema 4D SDK
      M
      mogh
    • RE: Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.

      Wow ... good stuff
      My c4d Programing slowed down this year, but this might be something I want to use some day ...

      posted in General Talk
      M
      mogh
    • RE: Table With TreeViewCustomGui with no Tree Icon

      @mikeudin

      In my case setting this to true hides them.

      customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, True) # True if no lines should be drawn.

      kind regards
      mogh

      posted in Cinema 4D SDK
      M
      mogh
    • RE: Metadata Supported for FBX Imports?

      Just additional reinforcement.

      We talk here a lot of Metadata in CAD files for Digital Twins, so a universal handling of "additional" data not processed by cinema is an area to explore at Maxon !

      posted in General Talk
      M
      mogh
    • RE: Layers checker

      Beginner solution:
      If you do not need a certain layer you could also implement the call comand "Delete unused layers"
      Its not pretty but beats any convulated self written code if it is not called to often.

      c4d.CallCommand(100004760) # Remove unused layers

      cheers
      mogh

      posted in Cinema 4D SDK
      M
      mogh
    • RE: How can I make a simple input form for my Python script?

      ... while the Team probalby will ask you to provide more context / detail ... have you looked at the sdk examples ?

      https://github.com/PluginCafe/cinema4d_py_sdk_extended/tree/master/scripts/03_application_development/gui/dialog

      kind regards

      posted in Cinema 4D SDK
      M
      mogh
    • RE: Dialog Menu

      EDIT:
      Sorry this was not what I thought I have a dual Dialog example somewhere but not at hand ...

      *This is an Subdialog Example from the SDK.

      Github Subdialog

      hope that is in line what you are searching.*
      Cheers mogh

      posted in Cinema 4D SDK
      M
      mogh
    • RE: Quicktab SDK Example

      Here is my latest Example Code, I will check for R2023.1 on Monday.
      selecting FFFF and DDDD results in GUI weirdness ... on R20

      Update: Also on 2023.1 I get this UI glitch ... selecting KKKKK / LLLLLL (last ones)

      Update 2: fiddled a little bit with the IDs (the class has an offset now so the ids are unique) and Layoutchange() no updated on the glitch when selecting the KKKK + X elements.

      2023-03-27-Window_000269.png

      import c4d # pyright: ignore[reportMissingImports]
      import json
      import os
      from collections import OrderedDict
      
      DEBUG = True
      
      # Ids used in our Dialog
      ID_MAINGROUP = 1000  # ID used for the Group that holds all the other group representing the tab content
      ID_QUICKTAB_BAR = 1001  # ID for the quicktab customGui
      
      ID_LOADDEFAULT_MAT_ASIGN = 1003
      ID_CREATE_MATERIALS = 1004
      BUTTON_PRINT_TEXT = 1005  # ID used for the Print text Button
      BUTTON_PRINT_SELECTED = 1006  # ID used for the Print Selected Button
      BUTTON_FLUSH_ALL = 1007  # ID used for the Flush All Button
      BUTTON_ADD = 1008  # ID used for the Add Button
      BUTTON_REMOVE = 1009  # ID used for the Remove Button
      
      # Id used in our SubDialog
      ID_QUICKTAB_BASE_GROUP = 5000
      
      # Defines the ID for the string to be displayed
      CUSTOM_GROUP_ID_TEXT_BASE = 4000  
      
      DEFAULT_FLAGS = c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT
      DEFAULT_SPACE = (5, 5, 5, 5)
      DEFAULT_BORDER_STYLE =c4d.BORDER_NONE
      
      LAYOUT_DEBUG = True
      if LAYOUT_DEBUG is True:
          DEFAULT_BORDER_STYLE = c4d.BORDER_BLACK
      
      GENERATOR_START_ID = 2000
      def plusone_id():
          n = GENERATOR_START_ID
          while n < GENERATOR_START_ID+999:
              yield n
              n += 1
      
      some_json = '{"AAAAAAA 85": ["a part_num_1","a part_num_2","a part_num_3"],"BBBBB 40": ["b part_num_4","b part_num_5"],"CCCCCCC": ["c part_num_6","c part_num_7","c part_num_8","c part_num_9"],"DDDDDD": ["d part_num_6","d part_num_7","d part_num_8","d part_num_9"],"FFFFF": ["f Plane"],"GGGGGGG": ["g part_num_6","g part_num_7","g part_num_8","g part_num_9"],"HHHHHHHH": ["h part_num_6","h part_num_7","h part_num_8","h part_num_9"],"IIIIII": ["i part_num_6","i part_num_7","i part_num_8","i part_num_9"],"JJJJJJJJJ": ["j part_num_6","j part_num_7","j part_num_8","j part_num_9"],"KKKKKKKK": ["k part_num_6","k part_num_7","k part_num_8","k part_num_9"],"LLLLLLLLL": ["l part_num_6","l part_num_7","l part_num_8","l part_num_9"],"MMMMMM": ["m part_num_6","m part_num_7","m part_num_8","m part_num_9"]}'
      
      ### Json
      #####################################################################################
      
      def read_parts_json(json_file_path):
          #with open(json_file_path) as f: data = json.load(f)
          data = json.loads(some_json)
      
          materials = {}
          for material_id, part_numbers in data.items():
              materials[material_id] = part_numbers
          
          material_ids = list(data.keys())
          return material_ids, materials
      
      class CustomGroup(c4d.gui.SubDialog):
          """A SubDialog to display the passed string, its used as example for the actual content of a Tab"""
          
          def __init__(self, material, parts, offset):
      
              self._material = material
              self._parts = '\n'.join(parts)
              self.gui_id = CUSTOM_GROUP_ID_TEXT_BASE + offset
      
          def CreateLayout(self):
              
              self.GroupBegin(self.gui_id + 4, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=1, rows=2, title=self.gui_id)
              self.GroupBorder(DEFAULT_BORDER_STYLE)
              self.GroupBorderSpace(left=5, top=5, right=5, bottom=5)
              self.AddStaticText(self.gui_id + 1 , flags=c4d.BFH_LEFT | c4d.BFV_TOP | c4d.BFH_FIT | c4d.BFV_FIT, name=self._material)
              #self.AddStaticText(self.gui_id + 2 , flags=c4d.BFH_LEFT | c4d.BFV_TOP | c4d.BFH_FIT | c4d.BFV_FIT, name=self.gui_id)
              self.AddMultiLineEditText(self.gui_id + 3, flags=c4d.BFH_LEFT | c4d.BFV_TOP | c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, initw=0, inith=0, style=0)
              self.SetString(self.gui_id + 3, value=self._parts)
              self.GroupEnd()
              #for i, parts in enumerate(self._parts):
              #    self.AddStaticText(self.gui_id + i, c4d.BFH_SCALEFIT, name=parts)
              return True
      
      
      class MyDialog(c4d.gui.GeDialog):
      
          def __init__(self, items=[]):
      
              # this is from the linkbox example from ferdinand
              super(MyDialog, self).__init__() 
      
              # will be link box
              self._items = [] 
              self._doc = None 
              self._hasCreateLayout = False
              self.Items = items
      
              self._quickTab = None  # Stores the quicktab custom GUI
              self._tabList = OrderedDict()  # Stores the TabName and the SubDialog that represents each tab of the QuickTab
      
          def _DrawQuickTabGroup(self):
              """ 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
      
              # 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()):
                  self.AddSubDialog(ID_QUICKTAB_BASE_GROUP + tabId, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0)
                  self.AttachSubDialog(tabGui, ID_QUICKTAB_BASE_GROUP + tabId)
      
              # Notifies the content of the MainGroup has changed
              self.LayoutChanged(ID_MAINGROUP)
      
              return True
      
      
          def GetActiveTabs(self):
              """Retrieves two list of currently selected tabs from the self._quickTab.
      
              Returns:
                  list(int), list(name): The first list, contains tabs Id (from self._quickTab the dict) and the second list contains all names of the selected tabs.
              """
              # Checks if the quicktab is defined
              if self._quickTab is None:
                  return False, False
      
              returnIds = []
              returnNames = []
      
              for tabId, (tabName, tabGui) in enumerate(self._tabList.items()):
                  if self._quickTab.IsSelected(tabId):
                      returnIds.append(tabId)
                      returnNames.append(tabName)
      
              return returnIds, returnNames
      
      
          def DisplayCorrectGroup(self):
              """Hides all unused groups and display the correct one.
      
              Returns: 
                  True if success otherwise False.
              """
              # Retrieves the selected tab
              activeIds, activeNames = self.GetActiveTabs()
              
              print("Display Correct Group")
              print(activeIds)
      
              # Iterates each CustomGui and defines if they are hidden or not
              for tabId in range(len(self._tabList)):
                  toDisplay = tabId in activeIds
                  #print("activeIds: ", activeIds, "current: ", ID_QUICKTAB_BASE_GROUP, tabId, " -> toDisplay: ", toDisplay)
                  self.HideElement(ID_QUICKTAB_BASE_GROUP + tabId, not toDisplay)
      
      
              # Notifies the content of the MainGroup has changed
              self.LayoutChanged(ID_MAINGROUP)
              
              return True
      
          def AppendTab(self, tabName, content, active=True):
              """Appends a tab to the current quicktab with the associated content to be displayed.
      
              Args:
                  tabName (str): The name the tab should have.
                  content (c4d.gui.SubDialog): The SubDialog to be drawn/linked when the tab is selected.
                  active (bool, optional): If True, the inserted tab will be selected. Defaults to True.
      
              Returns:
                  True if success otherwise False.
              """
              # Checks if the quicktab is defined
              if self._quickTab is None:
                  return False
      
              # Adds the tab entry n the quicktab
              self._quickTab.AppendString(len(self._tabList), tabName, active)
      
              # Updates our current tabList with tabName and the Subdialog to be linked
              self._tabList.update({tabName: content})
      
              """ I uncommented below because it resulted in a lot of gui calls 
                  It seems to work fine just calling self.DisplayCorrectGroup() at the right places
                  not inside here hence this functionis called for each tab
              """
      
              # Retrieves the current selected tab
              #previousActiveId, previousActiveName = self.GetActiveTabs()
      
              # Draws the quicktab SubDialog (in order to have the new one drawn)
              #self._DrawQuickTabGroup()
      
              # Defines the just added tab according state
              #self._quickTab.Select(len(self._tabList) - 1, active)
      
              # Defines previous active tab
              #for tabId in previousActiveId: self._quickTab.Select(tabId, True)
      
              # Display only the selected tab and hides all others
              #self.DisplayCorrectGroup()
      
              return True
      
          def FlushAllTabs(self):
              """Removes all tabs and their content from the GUI.
      
              Returns: 
                  True if success otherwise False.
              """
              # Checks if the quicktab is defined
              if self._quickTab is None:
                  return False
      
              # Removes all the tabs
              self._quickTab.ClearStrings()
      
              # Removes all the customGui
              for tabId in range(len(self._tabList)):
                  self.RemoveElement(ID_QUICKTAB_BASE_GROUP + tabId)
      
              # Reinitializes the stored tablist to an empty dict
              self._tabList = OrderedDict()
      
              # Flush the content of the group that holds all ours SubDialogs
              self.LayoutFlushGroup(ID_MAINGROUP)
              # Notifies the content of the MainGroup has changed
              self.LayoutChanged(ID_MAINGROUP)
      
              return True
      
          def RemoveTab(self, tabNameToRemove):
              """Removes a tab by its name
      
              Args:
                  tabNameToRemove (str): The tab to remove.
      
              Returns:
                  True if success otherwise False.
              """
              # Checks if the quicktab is defined
              if self._quickTab is None:
                  return False
      
              # Copies the tabList
              newDict = OrderedDict(self._tabList)
      
              # Checks if the entry exist
              if tabNameToRemove not in newDict:
                  return True
      
              # Removes the entry we want to delete
              del newDict[tabNameToRemove]
      
              # Removes all groups
              self.FlushAllTabs()
      
              # Re-adds all the one from our copy
              for tabName, tabGui in newDict.items():
                  self.AppendTab(tabName, tabGui)
      
              return True
      
          def CreateLayout(self):
              """This Method is called automatically when Cinema 4D Create the Layout (display) of the Dialog."""
      
              # Creates a QuickTab Custom Gui
              bc = c4d.BaseContainer()
              bc.SetInt32(c4d.QUICKTAB_BAR, 0) # (0=off, 1=on, 2=non-bold, 3=special separator look)
              bc.SetString(c4d.QUICKTAB_BARTITLE, "Title")
              bc.SetBool(c4d.QUICKTAB_SPRINGINGFOLDERS, True) # if we can get link fields usefull
              bc.SetBool(c4d.QUICKTAB_SHOWSINGLE, False)
              bc.SetBool(c4d.QUICKTAB_NOMULTISELECT, False)
              bc.SetBool(c4d.QUICKTAB_SEPARATOR, True)
      
              self.GroupBegin(next(plusone_id()), c4d.BFH_SCALEFIT | c4d.BFV_TOP | c4d.BFV_FIT, 0, 0, 'ID_QUICKTAB_BAR', 0)
              #self.GroupBorderNoTitle(borderstyle=DEFAULT_BORDER_STYLE)
              self.GroupBorder(DEFAULT_BORDER_STYLE)
              self.GroupBorderSpace(left=5, top=5, right=5, bottom=5)
              self._quickTab = self.AddCustomGui(ID_QUICKTAB_BAR, c4d.CUSTOMGUI_QUICKTAB, 'the tabs', c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, bc)
              #self.AddStaticText(id=next(plusone_id()), flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, name="tabs")
              #print("layout cusrom gui: ", self._quickTab)
              self.GroupEnd()
      
              # Creates a group that will contain all the group representing each tab
              self.GroupBegin(ID_MAINGROUP, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=10, rows=10, title='ID_MAINGROUP')
              #self.GroupBorderNoTitle(borderstyle=DEFAULT_BORDER_STYLE)
              self.GroupBorder(DEFAULT_BORDER_STYLE)
              self.GroupBorderSpace(left=5, top=5, right=5, bottom=5)
              self.AddStaticText(id=next(plusone_id()), flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, name="main")
              self.GroupEnd()
              
              # dummy group to spread vertically
              if self.GroupBegin(id=next(plusone_id()),  flags=c4d.BFH_FIT | c4d.BFV_FIT): #cols=1, rows=1,
                  self.GroupBorderSpace(left=0, top=0, right=0, bottom=0)
                  self.GroupBorderNoTitle(borderstyle=DEFAULT_BORDER_STYLE)
                  self.AddStaticText(id=next(plusone_id()), flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, name="")
                  self.GroupEnd()
      
              # Creates a group with button in order to do some operation with the QuickTab CustomGUI
              if self.GroupBegin(next(plusone_id()), c4d.BFH_SCALEFIT | c4d.BFV_BOTTOM, 4, 1, '', 0):
                  self.AddButton(ID_LOADDEFAULT_MAT_ASIGN, c4d.BFH_SCALEFIT, name="Populate")
                  self.AddButton(BUTTON_PRINT_TEXT, c4d.BFH_SCALEFIT, name="Print text")
                  self.AddButton(BUTTON_PRINT_SELECTED, c4d.BFH_SCALEFIT, name="Print Selected")
                  self.AddButton(BUTTON_FLUSH_ALL, c4d.BFH_SCALEFIT, name="Flush All")
                  #self.AddButton(BUTTON_ADD, c4d.BFH_SCALEFIT, name="Add")
                  #self.AddButton(BUTTON_REMOVE, c4d.BFH_SCALEFIT, name="Remove")
                  self.GroupEnd()
              
              return True
      
          def InitValues(self):
              """This Method is called automatically after the GUI is initialized."""
              # Creates the first Tab
              #cg1 = CustomGroup(["This is the first Tab", "Just dummy text here"])
              #self.AppendTab("First Tab", cg1, True)
      
              # Creates the second Tab
              #cg2 = CustomGroup(["This is the second Tab", "Just another dummy text here"])
              #self.AppendTab("Second Tab", cg2, False)
              #return True
          
              return super(MyDialog, self).InitValues()
      
          def Command(self, id, msg):
              """This Method is called automatically when the user clicks on a gadget and/or changes its value this function will be called.
               It is also called when a string menu item is selected.
      
              Args:
                  id: The ID of the gadget that triggered the event.
                  msg: The original message container
      
              Returns:
                  False if there was an error, otherwise True.
              """
      
              # If the user interacts with the quicktab, we make sure to display the CustomGUI linked to the active one
              if id == ID_QUICKTAB_BAR and self._quickTab:
                  print("user interacted with tab")
                  self.DisplayCorrectGroup()
                  c4d.EventAdd()
                  return True
      
              # Displays all the Tab name
              if id == BUTTON_PRINT_TEXT:
                  print([key for key in self._tabList])
                  return True
      
              # Displays the ID and name of the selected tab
              if id == BUTTON_PRINT_SELECTED:
                  print(self.GetActiveTabs())
      
              # Removes all tabs
              if id == BUTTON_FLUSH_ALL:
                  self.FlushAllTabs()
      
              """        
              # Adds a new Tab to the quicktab
              if id == BUTTON_ADD:
                  cg3 = CustomGroup(["This is the third Tab"])
                  self.AppendTab("Third Tab", cg3, True)
      
              # Removes the first tab of the quicktab
              if id == BUTTON_REMOVE:
                  self.RemoveTab("First Tab")
              """
      
              if id == ID_LOADDEFAULT_MAT_ASIGN:
                  self.Populate()
      
              return True
          
      
          def Populate(self):
              doc = c4d.documents.GetActiveDocument()
              directory, _ = os.path.split(__file__)
              poart_json_file = os.path.join(directory, "default_asignment.json")
              material_ids, materials_dict = read_parts_json(poart_json_file)
      
              self.FlushAllTabs() # clear the GUI
      
              print( str( material_ids))
              print("-"*80)
              
              offset=0
              
              for material_id in materials_dict:
                  part_list = materials_dict[material_id]
      
                  #print( str(material_id), str(part_list) )
      
                  ### Tabs
                  ##############################################
                  
                  tab_Content = CustomGroup(str(material_id), part_list, offset)
                  self.AppendTab(str(material_id), tab_Content, True)
                  offset += 10
              
              print("-"*80)
              self._DrawQuickTabGroup()
              c4d.EventAdd()    
            
      
      # Main function
      def main():
          
          if DEBUG:
              c4d.CallCommand(13957)  # clear console
          
          # Initializes a QuickTabDialogExample Dialog
          diag = MyDialog()
      
          # Opens the Dialog in modal mode
          diag.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=960, defaulth=600)
      
      
      # Execute main()
      if __name__ == '__main__':
          main()
      
      posted in Cinema 4D SDK
      M
      mogh
    • RE: How to create UV of obj.

      I use this to Thank You Ferdinand.

      This is how I imagine an SDK example should look like .... a simplest version , an altered simple version and a complex touching the boundaries of the subject.
      I am thankful and praise your work .... !

      cheers mogh

      posted in Cinema 4D SDK
      M
      mogh

    Latest posts made by mogh

    • RE: How to create UV of obj.

      I use this to Thank You Ferdinand.

      This is how I imagine an SDK example should look like .... a simplest version , an altered simple version and a complex touching the boundaries of the subject.
      I am thankful and praise your work .... !

      cheers mogh

      posted in Cinema 4D SDK
      M
      mogh
    • RE: How to receive the high definition / Interpolation version of a spline?

      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.

      posted in Cinema 4D SDK
      M
      mogh
    • RE: How to receive the high definition / Interpolation version of a spline?

      @ferdinand
      Thank you for your answer, exactly what i need, I am trying to incorporate the additional data but get weird results.

      Is there a switch up /typo in the above code I get m.v3 <-> m.v1 ? meaning v1 is the normal ?

      Is there a page in the SDK besides the "Matrix" one that explains the additional values and their features ?

      Thank you for your Time.
      mogh

      posted in Cinema 4D SDK
      M
      mogh
    • RE: TagData Plugin with Gui not using *.res

      Understood Thanks.

      posted in Cinema 4D SDK
      M
      mogh
    • RE: How to receive the high definition / Interpolation version of a spline?

      Ok I guess I have been vague what my issue is.

      from the above helper I only get the points the spline is set to (eg. adaptive 5°) but I perhaps want more points in between. That of course only makes sense in certain scenarios but even though if the spline is a straight line there must be a solution to get points in between.

      Example different adaptive degree values and the resulting points displayed as lines on the spline - Spline is a copy so no altering of the gizmos.
      2025-02-18-Cinema 4D 2025.1.2 - [Untitled 2 _] - Main_000813.png

      sorry to be so basic
      mogh

      posted in Cinema 4D SDK
      M
      mogh
    • How to receive the high definition / Interpolation version of a spline?

      How to receive the high definition version / Interpolation of a spline even when the user has set it to "low" detail?
      How high definition can I get ? is there more than the user Interface of C4D offers ?

      E.g. Interpolation adaptive, angle 0.0

      Or am I using c4d.utils.SplineHelp() wrong and there is a another helper that gives me requested amount of points from a spline?

      helper = c4d.utils.SplineHelp()
      if not helper.InitSplineWith(spline, c4d.SPLINEHELPFLAGS_RETAINLINEOBJECT):
          raise RuntimeError("Could not initialize spline helper.")
      line = helper.GetLineObject()
      points = line.GetAllPoints()
      

      cheers
      mogh

      posted in Cinema 4D SDK python
      M
      mogh
    • TagData Plugin with Gui not using *.res

      How to add a GUI to a TagData Plugin without *.res files ?
      ... I am on the fence with these 😉

      Hope this is basic an clear enough for no further explanation.

      cheers
      mogh

      posted in Cinema 4D SDK python
      M
      mogh
    • RE: General Question: Which Plugin Type? -> Curvature Comb / Plot

      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

      posted in Cinema 4D SDK
      M
      mogh
    • RE: General Question: Which Plugin Type? -> Curvature Comb / Plot

      Thanks @ferdinand for your considered reply,

      At this stage because I just want to "make stuff" I will start as a tool and perhaps learn / have an idea to transfer it to something more useful.

      The obvious simple minded question - why is a tag Plugin not enough can a tag not draw into viewport ? Or only not via Python?

      Thanks
      mogh

      posted in Cinema 4D SDK
      M
      mogh
    • General Question: Which Plugin Type? -> Curvature Comb / Plot

      Dear Developers,

      I am starting to build a new Plugin, which should in the end, draw Curvature Combs / plots onto the selected edges / splines, preferable real time on editing the splines/models.

      My question is which Plugintype would be best suited ?
      Comb

      Thinking out loud:
      I was thinking a Tag Plugin but It could be to restricted as per the Tag plugin has some programing limits as I understand. Command or Tool plugin could work but I fear it will be clunky from a user experience.
      At best a Polygon model with Hypernurbs applied should display several combs at the same time using the Hypernurbs Subdivision for more "accuracy" than a pure Polygon edge.

      The plugin probably needs a Link Box to "receive" a selection. I am thinking of Ferdinands Dynamyc Link Example would be cool to have more than on comb active but only one "Tag / Plugin / ...." per object ...

      Closest thing C4D has is measure and construct Tool.
      As a starting point I would start to display Combs on Splines ...

      So to Pick the hive mind - > What Plugin Type is best suited for stuff like this?

      Moderators: feel free to move this Topic if aplicable.

      Cheers
      mogh

      posted in Cinema 4D SDK python
      M
      mogh