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

    GetCursorInfo()

    SDK Help
    0
    12
    1.1k
    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.
    • H
      Helper
      last edited by

      On 23/08/2016 at 07:06, xxxxxxxx wrote:

      Howdy,

      1. Have you tried ViewportSelect::PickObject()?

      Adios,
      Cactus Dan

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 30/08/2016 at 01:53, xxxxxxxx wrote:

        Hi Dan - apologies for the delay, thanks.

        I did try it initially, but couldn't work it out! Went back in and gave it another crack and got it going. The issue I'm having though is that it doesn't seem to work in model or object mode. GetNearestPolygon() returns a null pointer if the mode is one of the two mentioned.

        I tried setting the mode and changing it back after I've finished, but it seems to cause a lot of messaging and redrawing, which seems a bit unnecessary. Is there a way to address this without changing modes?

        WP.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 30/08/2016 at 06:01, xxxxxxxx wrote:

          Howdy,

          Well, I've only ever used GetNearestPoint() on the active object. Is it possible that the object needs to be the active object for GetNearestPoint(), GetNearestEdge() and GetNearestPolygon() to work?

          Adios,
          Cactus Dan

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 30/08/2016 at 07:17, xxxxxxxx wrote:

            Hi,
            Just a word of caution about what you're doing.

            What you are doing is traditionally done in a ToolData plugin because polling for objects might collide with other things running in C4D.
            We have to be very careful not to do any tasks in a SH that would interfere with the normal operation of the program. And this sounds like it would.

            Using a ToolData plugin allows us to temporarily override these things safely.
            If you do decide to use a SH. Make sure that the user has a way to turn it off.

            -ScottA

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 14/09/2016 at 02:13, xxxxxxxx wrote:

              Hi Dan and Scott, apologies for the delay, I have a lot on at the moment.

              Scott, I had originally stayed away from a tool plugin because I didn't want to deal with the AM. It was meant to be something that sits in the background and is only used when another plugin I have is active. But I found an excuse to use the AM to display a few things so I've since changed the above over to a ToolData. Is this the correct one? Or should I be using DescriptionToolData?

              However, I still seem to be having the same problem. If the mode is Mobject then it doesn't want to work as GetNearestPolygon() returns null. In polygon mode the same code works fine. I'm wondering if this is not possible in Mobject mode?

              WP.

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 14/09/2016 at 07:44, xxxxxxxx wrote:

                ToolData is the older version.
                -ToolData: Uses a hard coded subdialog in the .cpp file for it's GUI options
                -ToolDataDescription: Uses a .res file for it's GUI options (also has the 3 reset buttons option)
                Both work. But most people will probably use ToolDataDescription version.

                You didn't say if you need to detect unselected objects or not?
                Most people test for hits like this only while the LMB is being held down. This gives the user more control while the tool is active. And this kind of code is typically done in the MouseInput() function. Not GetCursorInfo().

                Here is a small example of getting the object under the cursor

                Bool DrawTool::GetCursorInfo(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, Real x, Real y, BaseContainer &bc)  
                {  
                  AutoAlloc<C4DObjectList> list;  
                  if (!list) return FALSE;  
                  LONG radius = 50;  
                  if (ViewportSelect::PickObject(bd, doc, x, y, radius, VIEWPORT_PICK_FLAGS_0, NULL, list))  
                  {  
                      if (list->GetCount() > 0)  
                      {  
                          GePrint(LongToString(list->GetCount()));  
                          GePrint(list->GetObject(0)->GetName());  //<--Print the name of the first object in the list  
                      }   
                  }  
                  
                  bc.SetLong(RESULT_CURSOR, MOUSE_POINT_HAND);      
                    
                  return TRUE;  
                }
                

                -ScottA

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 15/09/2016 at 04:50, xxxxxxxx wrote:

                  I usually do things the hard-coded way 🙂. I didn't see this before but the description tool looks derived from tool data, I was thinking the two were entirely separate. The ToolData should be fine for me at this stage though. The object doesn't need to be selected.

                  Your code seems to work, and I'm curious to know why mine won't in Mobject mode. Am going to fiddle with mine to see if I can spot why. It never ends though, the mouse wheel doesn't work inside a tool plugin it seems, unless you start with something else first (e.g. left mouse button). The viewport zoom seems to take precedence. How irritating, there's always something. Will take a further look at this tomorrow.

                  Thanks again!

                  WP.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 15/09/2016 at 05:29, xxxxxxxx wrote:

                    Hey guys,

                    terribly sorry for leaving you alone so long.
                    WP. can you please post us some code, so we can get a better idea of what's going on.

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 16/09/2016 at 05:15, xxxxxxxx wrote:

                      Hi Andreas,

                      it's no worries!

                      I've realised I've jumped the gun with my last response to Scott above. What I had was working, up until needing to test the polygon. That's where the issue is. If it's in polygon mode, it works fine. If I try it in Mobject mode, I get a null ViewportPixel reference. I.e the line in the middle here:

                      // doc->SetMode(Mpolygon); <-- hack
                      ViewportPixel *ViewPixel = ViewSel->GetNearestPolygon(objL,mx,my,MAXLONGl,FALSE,nullptr,0);
                      // doc->SetMode(Mobject);   <-- hack
                      

                      I have a hack I could use, which is to change the mode, run the above line, then change the mode back to what it was again, but that seems to cause a lot of unnecessary messaging. Is there a way to get the polygon hit in Mobject mode?

                      WP.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 26/09/2016 at 09:37, xxxxxxxx wrote:

                        Hi,

                        sorry, this is taking so long.

                        I have done some tests here and for me GetNearestPolygon() seems to work quite well, even in Object mode.

                        This is what I did in a ToolData:

                        	Bool MyToolData::GetCursorInfo(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, Float x, Float y, BaseContainer& bc)
                        	{
                        		AutoAlloc<AtomArray> ops;
                        		AutoAlloc<ViewportSelect> vpsel;
                        		if (!doc || !bd || !ops || !vpsel)
                        			return false;
                          
                        		// Get viewport dimensions
                        		Int32 cl, ct, cr, cb;
                        		bd->GetFrame(&cl, &ct, &cr, &cb);
                          
                        		// Get some objects from the scene
                        		BaseObject* op = doc->GetFirstObject();
                        		while (op)
                        		{
                        			if (op->GetType() == Opolygon)
                        			{
                        				ops->Append(op);
                        			}
                        			else
                        			{
                        				// GetNearestPolygon() only works with polygonal objects, so get the cache instead
                        				BaseObject* opCache = op->GetCache(); // Note: Depending on the scene, this probably is not sufficient, please see GetCache() and GetDeformCache() docs
                        				if (opCache)
                        					ops->Append(opCache);
                        			}
                        			op = op->GetNext();
                        		}
                          
                        		if (!vpsel->Init(cr - cl + 1, cb - ct + 1, bd, ops, Mpolygons, true, VIEWPORTSELECTFLAGS_0))
                        			return false;
                          
                        		for (Int32 idxObj = 0; idxObj < ops->GetCount(); ++idxObj)
                        		{
                        			Int32 ix = SAFEINT32(x);
                        			Int32 iy = SAFEINT32(y);
                        			BaseObject* opCurrent = static_cast<BaseObject*>(ops->GetIndex(idxObj));
                        			if (!opCurrent)
                        				continue;
                          
                        			ViewportPixel* vpp = vpsel->GetNearestPolygon(opCurrent, ix, iy, 5, false);
                        			if (vpp && vpp->op)
                        				GePrint("Found: " + vpp->op->GetName() + " - Poly Idx: " + String::IntToString(vpp->i));
                        		}
                          
                        		return true;
                        	}
                        

                        I hope this helps.

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 30/09/2016 at 01:30, xxxxxxxx wrote:

                          Hi Andreas,

                          thanks. I've spent a bit of time trying to diagnose why my code didn't work and I'm thinking it has something to do with the caches. When I pass an object to the vpsel->Init() instead of an object array, then the ViewportPixel reference was returning null. After a bit of fiddeling, I've managed to pass an object and successfully test it. Looks like I need to learn a little more on caches!

                          Cheers,

                          WP.

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