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. noisyrender
    N
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 3
    • Best 0
    • Controversial 0
    • Groups 0

    noisyrender

    @noisyrender

    0
    Reputation
    2
    Profile views
    3
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    noisyrender Unfollow Follow

    Latest posts made by noisyrender

    • RE: Marquee Selection of Items in GeUserArea

      @ferdinand Got it. Thanks you for the tips. Much appreciated

      posted in Cinema 4D SDK
      N
      noisyrender
    • RE: Marquee Selection of Items in GeUserArea

      Sorry about the confusion 🫠.

      Being not very familiar to the API and doing this by reading example code i was wondering if there is a similar lasso selection in python to the c++
      https://developers.maxon.net/docs/cpp/2025_2_0a/classcinema_1_1_lasso_selection.html

      I realise by now that i'm asking for feedback. Mes plus plates excuses. 🙇🏽‍♂️

      posted in Cinema 4D SDK
      N
      noisyrender
    • Marquee Selection of Items in GeUserArea

      Hi everyone,

      I'm currently working on a custom UI using GeUserArea in Python, and I'd like to implement rectangle selection (by clicking and dragging a selection rectangle over multiple items, similar to how it works in the Object Manager ). A good example is the Xpresso Editor or Kengo Ito's XBarista

      I saw a similar function in the C++ doc and i'm wondering if it is possible in python out the box.
      97855097-ffd1-4d4d-a697-6e89c4fa0ae1-image.png
      I'm fairly new to the api.

      Here is a snippet for a larger project.

      THANK YOU

      import c4d
      
      
      NODE_COLOR = c4d.Vector(c4d.COLOR_MENU_BG_SELECTED)
      
      
      class Node:
          def __init__(self, x, y, ua):
              self.x: int = x
              self.y: int = y
              self.width: int = 80
              self.height: int = 80
              self.is_selected: bool = False
              self.col: c4d.Vector = c4d.Vector(0.6, 0.3, 0.5)
              self.is_selected_col: c4d.Vector = c4d.Vector()
              self.ua = ua
      
          def draw_node(self):
              if self.is_selected:
                  self.ua.DrawSetPen(NODE_COLOR)  # node color when selected
              else:
                  self.ua.DrawSetPen(self.col)  # else the defaault color
      
              x1, y1 = self.x, self.y
              x2, y2 = self.x + self.width, self.y + self.height
      
              self.ua.DrawRectangle(int(x1), int(y1), int(x2), int(y2))
      
          def offset(self, x, y):
              self.x -= x
              self.y -= y
      
          def select(self):
              self.is_selected = True
      
          def deselect(self):
              self.is_selected = False
      
          def is_inside(self, mx, my):  # calculate the area of the node
              return (
                  self.x <= mx <= self.x + self.width and self.y <= my <= self.y + self.height
              )
      
      
      class Gui(c4d.gui.GeDialog):
          ID_AREA = 10001
      
          def __init__(self):
              super().__init__()
      
              self.SetTitle("Marquee Selection Example")
      
              self.area = Area()
      
          def CreateLayout(self):
              self.AddUserArea(self.ID_AREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
              self.AttachUserArea(self.area, self.ID_AREA)
      
              return True
      
      
      class Area(c4d.gui.GeUserArea):
          def __init__(self):
              self.nodes = [
                  Node(250, 250, self),
                  Node(250, 150, self),
              ]  # the two nodes to marque select
      
              self.lasso = False  # start drawing the maarque when true
      
          # This create the actual custom marquee to draw
          def drawLasso(self, start_x, start_y, end_x, end_y):
              self.DrawSetPen(c4d.Vector(0.8, 0.8, 0.18))
              self.DrawFrame(start_x, start_y, end_x, end_y, 1, c4d.LINESTYLE_NORMAL)
      
          def DrawMsg(self, x1, y1, x2, y2, msg):
              self.OffScreenOn()
      
              self.DrawSetPen(c4d.Vector(0.12, 0.12, 0.14))
              self.DrawRectangle(x1, y1, x2, y2)
      
              for node in self.nodes:  # draw all nodes
                  node.draw_node()
      
              if self.lasso:
                  self.drawLasso(
                      self.lasso_start_x,
                      self.lasso_start_y,
                      self.lasso_end_x,
                      self.lasso_end_y,
                  )
      
          def InputEvent(self, msg):  # noqa: C901
              if msg[c4d.BFM_INPUT_DEVICE] == c4d.BFM_INPUT_MOUSE:
                  mx = int(msg[c4d.BFM_INPUT_X])
                  my = int(msg[c4d.BFM_INPUT_Y])
                  mx -= self.Local2Global()["x"]
                  my -= self.Local2Global()["y"]
      
                  channel = msg[c4d.BFM_INPUT_CHANNEL]
      
                  self.lasso_start_x = int(
                      mx
                  )  # Mouse positions at the moment we start drawing
                  self.lasso_start_y = int(my)
      
                  if channel == c4d.BFM_INPUT_MOUSELEFT:
                      self.MouseDragStart(
                          c4d.BFM_INPUT_MOUSELEFT,
                          mx,
                          my,
                          c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE,
                      )
      
                      while True:
                          res, dx, dy, channels = self.MouseDrag()
                          if res == c4d.MOUSEDRAGRESULT_FINISHED:
                              self.lasso = False
                              self.Redraw()
                              break  # We always need this to escape an infinite loop
                          elif res == c4d.MOUSEDRAGRESULT_ESCAPE:
                              break
                          elif res == c4d.MOUSEDRAGRESULT_CONTINUE:
                              self.lasso = True
                              c4d.gui.SetMousePointer(c4d.MOUSE_PAINTSELECTRECT)
      
                              mx -= dx
                              my -= dy
      
                              self.lasso_end_x = int(mx)  # Mouse positions when stopped
                              self.lasso_end_y = int(my)
                              self.Redraw()
      
                      self.MouseDragEnd()
      
                      for node in self.nodes:
                          if node.is_inside(mx, my):
                              node.select()
                              self.Redraw()
                          elif not node.is_inside(mx, my) and c4d.BFM_INPUT_MOUSELEFT:
                              node.deselect()
                              self.Redraw()
      
              return True
      
      
      if __name__ == "__main__":
          Gui().Open(2, 1, xpos=-2, ypos=-2, defaulth=600, defaultw=600)
      
      
      posted in Cinema 4D SDK windows python 2025
      N
      noisyrender