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

    After undo, point object SetAllPoints not update

    Cinema 4D SDK
    2024 python
    2
    3
    476
    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.
    • chuanzhenC
      chuanzhen
      last edited by chuanzhen

      Hi,
      I encountered a problem. When I set the position of an object's point, however, when I undo it and set it again, the object does not refresh in time. Only if I click on the object again and set it again will it be refreshed in time.

      This is the video,

      This is simple code:

      
      
      import c4d
      import os
      import sys
      from c4d import gui,bitmaps,plugins,utils,modules
      
      
      PLUGIN_ID = 10000001
      
      
      class S_test_Dialog(gui.GeDialog):
      
      
          def CreateLayout(self):
              self.SetTitle("test")
      
      
              self.GroupBegin(1000,c4d.BFH_SCALEFIT,4,0)
      
              self.AddStaticText(1003, c4d.BFH_RIGHT, 80, 20, "  Target ")
              bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_BASELISTLINK)
              self.AddCustomGui(1004, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_SCALEFIT, 300, 0, bc)
      
              self.GroupEnd()
      
              self.AddButton(1010, c4d.BFH_SCALEFIT, 150, 30, "ChangePoints")
      
      
      
              return True
      
      
      
          def Command(self, id, msg):
      
              if id == 1010:
                  doc = c4d.documents.GetActiveDocument()
      
                  target = self.FindCustomGui(1004, c4d.CUSTOMGUI_LINKBOX).GetData()
      
                  all_p = target.GetAllPoints()
                  for id,pos in enumerate(all_p):
                      all_p[id] = c4d.Vector(0)
      
                  doc.StartUndo()
                  doc.AddUndo(c4d.UNDOTYPE_CHANGE,target)
                  target.SetAllPoints(all_p)
                  target.Message(c4d.MSG_UPDATE)
                  doc.EndUndo()
                  c4d.EventAdd()
      
                  return True
      
      
      
      
              return True
      
      
      
      
      
      
      class S_test(plugins.CommandData):
      
          dialog = None
      
          def Execute(self,doc):
              # create the dialog
              if self.dialog is None:
                  self.dialog = S_test_Dialog()
      
              return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=400, defaulth=100)
      
          def RestoreLayout(self, sec_ref):
              # manage nonmodal dialog
              if self.dialog is None:
                  self.dialog = S_test_Dialog()
      
              return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
      
      
      # Execute main()
      if __name__=='__main__':
          path, fn = os.path.split(__file__)
      
          plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                        str="S_test",
                                        info=0,
                                        help="",
                                        dat=S_test(),
                                        icon=None)
      
      
      
      

      Thanks for any help!

      相信我,可以的!

      ferdinandF 1 Reply Last reply Reply Quote 1
      • ferdinandF
        ferdinand @chuanzhen
        last edited by ferdinand

        Hello @chuanzhen,

        Thank you for reaching out to us. The problems you encounter stem from the fact that you use the wrong method to retrieve your link.

        When you undo an action, the object will not be the same anymore since the object has been replaced with whatever was found in the undo-stack. You simply must use the correct method c4d.gui.LinkBoxGui.GetLink and things will also work after an undo.

        Cheers,
        Ferdinand

        Code:

        def CreateLayout(self):
            self.SetTitle("test")
            self.GroupBegin(1000, c4d.BFH_SCALEFIT, 4, 0)
            self.AddStaticText(1003, c4d.BFH_RIGHT, 80, 20, "  Target ")
            # We store the custom GUI so that we do not have to grab it every time.
            self._link = self.AddCustomGui(
                1004, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_SCALEFIT, 300, 0, 
                c4d.GetCustomDataTypeDefault(c4d.DTYPE_BASELISTLINK))
            self.GroupEnd()
            self.AddButton(1010, c4d.BFH_SCALEFIT, 150, 30, "ChangePoints")
        
            return True
        
        def Command(self, id, msg):
        
            if id == 1010:
                doc = c4d.documents.GetActiveDocument()
                # This line was problematic because you did use BaseCustomGui.GetData and not 
                # LinkBoxGui.GetLink which has special logic for this type. This can fail.
                # target = self.FindCustomGui(1004, c4d.CUSTOMGUI_LINKBOX).GetData()
                
                # This cannot, it will automatically reattach a dangling link (after an undo for 
                # example). We could also do that ourself with UUIDs but why when we do not have to :)
                target: c4d.BaseObject | None = self._link.GetLink(doc, c4d.Opolygon)
                if not target:
                    return True
                    
                points: list[c4d.Vector] = [c4d.Vector() for _ in range(target.GetPointCount())]
        
                doc.StartUndo()
                doc.AddUndo(c4d.UNDOTYPE_CHANGE, target)
                target.SetAllPoints(points)
                target.Message(c4d.MSG_UPDATE)
                doc.EndUndo()
                c4d.EventAdd()
            return True
        

        MAXON SDK Specialist
        developers.maxon.net

        chuanzhenC 1 Reply Last reply Reply Quote 1
        • chuanzhenC
          chuanzhen @ferdinand
          last edited by

          @ferdinand Thanks for your help!

          相信我,可以的!

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