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

    S22: c4d.MCOMMAND_SPLIT returns a Bool instead of a List, while it returned a list in R21 and earlier versions

    Cinema 4D SDK
    2
    5
    775
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • AwesuusA
      Awesuus
      last edited by m_adam

      Hey guys, i have a script which uses the c4d.utils.SendModelingCommand until recently this returned a list to me. https://developers.MAXON.net/docs/Cinema4DPythonSDK/html/modules/c4d.utils/index.html#c4d.utils.SendModelingCommand

      This function either returns a boolean, or a list. Up until R21 the following code returned a list to me. But as of S22 i get returned the bool true, which signifies it ran succesfully, but i cant seem to retrieve the list.

      Any help on how i can get the list ( by passing a parameter or anything else ) would be appreciated.

      Heres the related snippet of my code

      selId = []
          sel = op.GetPolygonS()
          for index, selected in enumerate(sel.GetAll(polyCnt)):
              if not selected: continue
              selId.append(index)
          allPolys = [n for n in allPolys if n not in selId]
          settings = c4d.BaseContainer()
          res = utils.SendModelingCommand(command = c4d.MCOMMAND_SPLIT,
                                      list = [op],
                                      mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                      bc = settings,
                                      doc = doc)
      

      after running this script, res is now true instead of a List

      many thanks in advance.

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @Awesuus first of all welcome in the plugincafe community 🙂

        Unfortunately, I wasn't able to reproduce your result in S22 and we correctly had a list returned.
        So what's your exact Cinema 4D Version? ( I tested on S22.118).
        Could you upload the Cinema 4D file where you are experiencing this issue?

        Thanks in advance,
        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • AwesuusA
          Awesuus
          last edited by

          Hi Maxime,
          Thank you so much for your reply. I also work in S22.118.

          Here's the whole script that I'm trying to get to work:

          import c4d
          from c4d import gui,utils
          
          def main():
              if op.GetType() != c4d.Opolygon : return
              sel = op.GetPolygonS()
              polyCnt = op.GetPolygonCount()
              allPolys = range(polyCnt)
              doc.StartUndo()
              null = c4d.BaseObject(c4d.Onull)
              null[c4d.ID_BASELIST_NAME] = op[c4d.ID_BASELIST_NAME]+"_Segments"
              null.SetMg(op.GetMg())
              cntr = 0
              while allPolys:
                  settings = c4d.BaseContainer()
                  settings[c4d.MDATA_FILLSEL_START_POLY] = allPolys[0]
                  utils.SendModelingCommand(command = c4d.ID_MODELING_FILL_SELECTION_TOOL,
                                              list = [op],
                                              mode = c4d.MODELINGCOMMANDMODE_EDGESELECTION,
                                              bc = settings,
                                              doc = doc)
                  selId = []
                  sel = op.GetPolygonS()
                  for index, selected in enumerate(sel.GetAll(polyCnt)):
                      if not selected: continue
                      selId.append(index)
                  allPolys = [n for n in allPolys if n not in selId]
                  settings = c4d.BaseContainer()
                  res = utils.SendModelingCommand(command = c4d.MCOMMAND_SPLIT,
                                              list = [op],
                                              mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                              bc = settings,
                                              doc = doc)
                  
                  res[0][c4d.ID_BASELIST_NAME] = op[c4d.ID_BASELIST_NAME]
                  res[0].InsertUnderLast(null)
                  res[0].SetMg(op.GetMg())
                  sel.DeselectAll()
                  cntr += 1
              doc.InsertObject(null)
              doc.AddUndo(c4d.UNDOTYPE_NEW, null)
              doc.EndUndo()
              c4d.EventAdd()
          
          
          if __name__=='__main__':
              main()
          

          What I'm trying to get it to do is explode the mesh by edge selection, so that it creates a new null with the separate objects. The c4d file below is just a scene with a sphere with edge selections.

          test.c4d

          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by

            Thanks for the complete code, the issue is not located in the MCOMMAND_SPLIT but in the ID_MODELING_FILL_SELECTION_TOOL, within the S22 development cycle, parameters IDs changed but the new ones were not exposed to Python (I've created a bug report) so you need to hardcode them, like so

            startPolyID = c4d.MDATA_FILLSEL_START_POLY if c4d.GetC4DVersion() < 21600 else 1100 # MDATA_FILL_POLYGON_INDEX in C++
            selectionTypeID = c4d.MDATA_FILLSEL_SELECTION if c4d.GetC4DVersion() < 21600 else 1110 # MDATA_FILL_SELECTION_TYPE in C++
            

            And here your code adapted to work

            import c4d
            from c4d import gui,utils
            
            def main():
                if op.GetType() != c4d.Opolygon : return
                sel = op.GetPolygonS()
                polyCnt = op.GetPolygonCount()
                allPolys = range(polyCnt)
                doc.StartUndo()
                null = c4d.BaseObject(c4d.Onull)
                null[c4d.ID_BASELIST_NAME] = op[c4d.ID_BASELIST_NAME]+"_Segments"
                null.SetMg(op.GetMg())
                cntr = 0
                while allPolys:
                    settings = c4d.BaseContainer()
                    startPolyID = c4d.MDATA_FILLSEL_START_POLY if c4d.GetC4DVersion() < 21600 else 1100 # MDATA_FILL_POLYGON_INDEX in C++
                    selectionTypeID = c4d.MDATA_FILLSEL_SELECTION if c4d.GetC4DVersion() < 21600 else 1110 # MDATA_FILL_SELECTION_TYPE in C++
                    
                    settings[startPolyID] = allPolys[0]
                    settings[selectionTypeID] = c4d.SELECTION_NEW # Or SELECTION_ADD or SELECTION_SUB
            
                    utils.SendModelingCommand(command = c4d.ID_MODELING_FILL_SELECTION_TOOL,
                                                list = [op],
                                                mode = c4d.MODELINGCOMMANDMODE_EDGESELECTION,
                                                bc = settings,
                                                doc = doc)
                    selId = []
                    sel = op.GetPolygonS()
                    for index, selected in enumerate(sel.GetAll(polyCnt)):
                        if not selected: continue
                        selId.append(index)
                        
                    allPolys = [n for n in allPolys if n not in selId]
                    settings = c4d.BaseContainer()
                    res = utils.SendModelingCommand(command = c4d.MCOMMAND_SPLIT,
                                                list = [op],
                                                mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                                bc = settings,
                                                doc = doc)
                    
                    res[0][c4d.ID_BASELIST_NAME] = op[c4d.ID_BASELIST_NAME]
                    res[0].InsertUnderLast(null)
                    res[0].SetMg(op.GetMg())
                    sel.DeselectAll()
                    cntr += 1
                doc.InsertObject(null)
                doc.AddUndo(c4d.UNDOTYPE_NEW, null)
                doc.EndUndo()
                c4d.EventAdd()
            
            
            if __name__=='__main__':
                main()
            

            Cheers,
            Maxime.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            AwesuusA 1 Reply Last reply Reply Quote 1
            • AwesuusA
              Awesuus @m_adam
              last edited by

              Thank you so much, this works like a charm!!!

              1 Reply Last reply Reply Quote 0
              • First post
                Last post