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

    Mouse Over Generator Object, no position info

    Cinema 4D SDK
    3
    6
    948
    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.
    • E
      ElementDan
      last edited by

      I'm using a tooldata plugin and was originally trying to get the polygon data from a generator/objectdata object. That doesn't work because even though it's classed as a polygon object, no polygon data is available to grab from outside. Always returns as None. So I thought I'd just get the hit position and then reference that with the object itself. Only problem is, can't do that either. I can get pickobject to give me the generator object but no more info, no hit position, z-depth, nothing. GeRayCollider is the same story.

      None of the ViewportSelect methods can get me this info either.
      c4d.utils.ViewportSelect.PickObject() is supposed to return a Z value but doesn't.

      Any ideas?

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        Hi,

        could you please follow our forum guidelines when posting a question, using tags and mark you thread as a questions can help us to answer your questions faster.

        Generator are not polygon objects, they store virtual object in their cache. It is also explained on the python documentation

        That's pretty logical to me that you can't have any information from the generator.

        What kind of information are you trying to retrieve ?

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • E
          ElementDan
          last edited by

          Ah apologies, I will make sure to follow the guidelines in future.
          So I'm building a python objectdata plugin that will create geometry but I want to add more geometry to it with a tooldata plugin by brushing over the geometry that has already been created, the tooldata will just tell the objectdata to create the geometry though. The object data plugin will keep track of all geometry in order for other tooldata plugins to act on that geometry.
          To put the new geo in the correct position though, I would need to know on what coordinate of the already generated geometry I would be hitting with the mouse, ideally I'd like access to the normal of the hitpoint too. Is there any way to detect a mouseover event on a virtual object?

          1 Reply Last reply Reply Quote 0
          • fwilleke80F
            fwilleke80
            last edited by fwilleke80

            As Manuel stated, you'll need to get the object's cache (baseObjectPtr->GetCache()). If you need the exact projected position of your mouse cursor on the polygon geometry, my first idea would be to use class GeRayCollider to shoot rays from your camera through the mouse cursor onto the geometry. Since you get a BaseDraw* in ToolData::MouseInput() you have all the necessary functions to transform mouse coordinates to world space.

            Cheers,
            Frank

            www.frankwilleke.de
            Only asking personal code questions here.

            1 Reply Last reply Reply Quote 0
            • ManuelM
              Manuel
              last edited by Manuel

              hi,

              using github example will help you to build your tool.

              using the liquid paint plugin as a base, using the script example to iterate over caches where you can get the function DeformedPolygonCacheIterator

              over.gif

              Int the function GetCursorInfo you have to retrieve the object the mouse is over, this can be done with the fuction c4d.utils.ViewportSelect.PickObject and GetPixelInfoPolygon

                 def GetCursorInfo(self, doc, data, bd, x, y, bc):
               
                      xPos = int(x)
                      yPos = int(y)
              
                      vpSelect = c4d.utils.ViewportSelect()
                      rad = 20
                      flags = c4d.VIEWPORT_PICK_FLAGS_NONE
                      # Retrieve the object that are hovered by the mouse
                      objectsList = c4d.utils.ViewportSelect.PickObject(bd, doc, xPos, yPos, rad, flags)
              
                      # Retrieve the frame information, we need the height and width information to initialize the ViewportSelect object.
                      frame = bd.GetFrame()   
                      width = right - left + 1   
                      height = bottom - top + 1   
              
                      # Retrieve the object as PolygonObject
                      polygonObjectList = list()
                      for op in objectsList:
                          for cache in self.DeformedPolygonCacheIterator(op):
                              polygonObjectList.append(cache)
              
              
                      if len(polygonObjectList) < 1:
                          return True
              
                      # Init the viewportSelect object
                      if not vpSelect.Init(width, height, bd, polygonObjectList, c4d.Mpolyedgepoint, True, c4d.VIEWPORTSELECTFLAGS_IGNORE_HIDDEN_SEL):
                          return True
              
                      # Retrieve the polygon information
                      infopolygon = vpSelect.GetPixelInfoPolygon(xPos, yPos)
                      if not infopolygon:
                          return True
              
                      i = infopolygon["i"]  # int
                      op = infopolygon["op"]  # c4d.BaseObject
                      z = infopolygon["z"]  # float
              
                      # Build the array of the polygon vertices in world coordinates
                      cpoly = op.GetPolygon(i)
                      opmg = op.GetMg()
                      self.pointList = list()
                      self.pointList.append(op.GetPoint(cpoly.a))
                      self.pointList.append(op.GetPoint(cpoly.b))
                      self.pointList.append(op.GetPoint(cpoly.c))
                      if not cpoly.IsTriangle():
                          self.pointList.append(op.GetPoint(cpoly.d))
                      # Transform the local coordinates to world coordinates.
                      self.pointList = [opmg * p for p in self.pointList]
                      
                      # Update the view.
                      c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW | c4d.DA_NO_THREAD | c4d.DA_NO_ANIMATION)
                      
                      # If the cursor has left a user area, simply return True
                      if bc.GetId() == c4d.BFM_CURSORINFO_REMOVE:
                          return True
              
                      # Sets the BubbleHelp string and cursor.
                      bc.SetInt32(c4d.RESULT_CURSOR, c4d.MOUSE_POINT_HAND)
                      return True
              
                
              

              Cheers,
              Manuel

              MAXON SDK Specialist

              MAXON Registered Developer

              E 1 Reply Last reply Reply Quote 1
              • E
                ElementDan @Manuel
                last edited by

                @m_magalhaes Manuel you hero! That was it! DeformedPolygonCacheIterator was the key! Thank you so much!

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