Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    ToolPlugin Problems

    Cinema 4D SDK
    python s22 r21 r20 r19
    2
    7
    1.3k
    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.
    • gheyretG
      gheyret
      last edited by gheyret

      Hello!
      I used utils.GeRayCollider in the ToolData.MouseInput() and ToolData.Draw() functions.
      When the specified object is a high poly object then the scene will be calculated very slowly.
      I don't know what causes this. Is there any way to optimize the codes?

      This is my code:

      def UnderCursor(self,doc,bd,mx,my,plane):
          """
          doc = Current document; 
          bd = Current BaseDraw
          mx = mouseX
          my = mouseY
          plane = The object to check for intersections.
          """
      
          pos = bd.SW(c4d.Vector(mx,my,0.1))     #screen to world conversion
          cam_pos = bd.GetSceneCamera(doc).GetAbsPos()
      
          pmg = plane.GetMg()
          pOlocal = cam_pos * ~pmg  
          p1local = pos * ~pmg  
          ldir = p1local-pOlocal
          
          collider = c4d.utils.GeRayCollider()
          collider.Init(plane,False)
          length = 2147483647
          direction = -(cam_pos - pos).GetNormalized()
          did_intersect = collider.Intersect(pOlocal, ldir, length)
          if did_intersect:
              p = collider.GetNearestIntersection()['hitpos']
              nrm = collider.GetNearestIntersection()['f_normal']
              dst = collider.GetNearestIntersection()['distance']
              mg = plane.GetMg()
              position = mg.Mul(p)
              
      
          return position,nrm,dst
      
      def MouseInput(self, doc, data, bd, win, msg):
          mx = msg[c4d.BFM_INPUT_X]
          my = msg[c4d.BFM_INPUT_Y]
      
          device = 0
          if msg[c4d.BFM_INPUT_CHANNEL]==c4d.BFM_INPUT_MOUSELEFT:
              device = c4d.KEY_MLEFT
          elif msg[c4d.BFM_INPUT_CHANNEL]==c4d.BFM_INPUT_MOUSERIGHT:
               device = c4d.KEY_MRIGHT
          else:
              return True
      
          plane = doc.SearchObject("plane")
          
          c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_ANIMATION)
          dx = 0.0
          dy = 0.0
          
          win.MouseDragStart(button=device, mx=int(mx), my=int(my), flags=c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE|c4d.MOUSEDRAGFLAGS_NOMOVE)
          result, dx, dy, channel = win.MouseDrag()
          while result==c4d.MOUSEDRAGRESULT_CONTINUE:
              mx += dx
              my += dy
      
              position = self.UnderCursor(doc,bd,mx,my,plane)[0]
      
              c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_ANIMATION)
              result, dx, dy, channel = win.MouseDrag()
      
          if win.MouseDragEnd()==c4d.MOUSEDRAGRESULT_ESCAPE:
      
              doc.DoUndo(True)
      
          return True
      
      def Draw(self, doc, data, bd, bh, bt, flags):
          bd.SetMatrix_Matrix(None, c4d.Matrix())
      
          bc = c4d.BaseContainer()
          gui.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, bc)
          mouse_x=bc.GetInt32(c4d.BFM_INPUT_X)
          mouse_y=bc.GetInt32(c4d.BFM_INPUT_Y)
          
          # Convert MouseCoordinates to Viewport Coordinates
          win= bd.GetEditorWindow()
          Editor_x, Editor_y = win.Global2Local()        
          mx = mouse_x-abs(Editor_x)
          my = mouse_y-abs(Editor_y)
      
          bd.SetPen(c4d.Vector(1))
      
          p = self.GetObj()[1]
          obj = self.GetObj()[0]
          dst = self.UnderCursor(doc,bd,mx,my,p)[2]
          off = self.UnderCursor(doc,bd,mx,my,p)[0]
          
          size = dst*0.005
          nrm = self.UnderCursor(doc,bd,mx,my,p)[1].GetNormalized()
          nrm_hpb = c4d.utils.VectorToHPB(nrm)
          rm = c4d.utils.HPBToMatrix(nrm_hpb)
          v1 = rm.v1*size
          v2 = rm.v2*size
          v3 = rm.v3*size
          mat = c4d.Matrix(off,v1,v2,v3)
          
          bd.DrawCircle(mat)
      

      low poly fast;
      fast.gif

      high poly slow;
      slow.gif

      www.boghma.com

      1 Reply Last reply Reply Quote 0
      • kbarK
        kbar
        last edited by kbar

        You are initialising the GeRayCollider every time you move your mouse. This rebuilds it every single time you move. Try moving the initialisation out of the UnderCursor method.

        First try making the GeRayCollider a local variable of your tool and initialise it when you mouse click on the surface the first time. Then once you have that working look at detecting when the dirty flag changes and then you can initialize it again only when it is marked as dirty. Once you have that going then change it to doing this check when you activate your tool as well. Then update your code to perhaps work on all selected objects.

        Hope that helps!
        Kent

        https://www.gamelogicdesign.com
        https://www.plugins4d.com

        gheyretG 1 Reply Last reply Reply Quote 1
        • gheyretG
          gheyret @kbar
          last edited by

          @kbar
          First of all, thank you for your reply.
          but I still don't quite understand, because I think if only after the mouse click to initialize, it seems that you can't Draw the circle in the viewport, because the ToolData.Draw() function needs to keep drawing the circle.
          Could you can give me an example?

          www.boghma.com

          1 Reply Last reply Reply Quote 0
          • kbarK
            kbar
            last edited by kbar

            I was only suggesting small incremental steps to help you solve your problem. First step is to refactor your code so that the GeRayCollider is not being initialised every time you move your mouse. So the click to initialize is not your final end solution. Just a step to get you started to show you that the slow down is with the call to Init and that you need to find a place to initialize that only when you absolutely need to. You can still access it in the UnderCursor method, after it has been initialized, allowing you to get draw your cursor. Just iterate through the problem one step at a time. I will let other devs post up a working solution. I only jump in here and answer when I can and don't have much time to code up anything unfortunately.

            https://www.gamelogicdesign.com
            https://www.plugins4d.com

            gheyretG 2 Replies Last reply Reply Quote 0
            • gheyretG
              gheyret @kbar
              last edited by

              @kbar
              I get you point now, I thought too much before.
              Thank you!
              Cheers~🍻

              www.boghma.com

              1 Reply Last reply Reply Quote 0
              • gheyretG
                gheyret @kbar
                last edited by

                @kbar
                I've almost solved my problem!
                Thank you again!

                www.boghma.com

                kbarK 1 Reply Last reply Reply Quote 0
                • kbarK
                  kbar @gheyret
                  last edited by kbar

                  @gheyret great to hear! Looking forward to seeing what it is you are creating.

                  https://www.gamelogicdesign.com
                  https://www.plugins4d.com

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