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

    Tool Plugin Question

    SDK Help
    0
    37
    22.9k
    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

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 09/05/2011 at 09:32, xxxxxxxx wrote:

      I tried using GetNearestPoint() but that doesn't want to work.  Maybe I will need to use a RayCollider to get the point that is closest to the mouse? 
       
      ~Shawn

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

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 09/05/2011 at 09:59, xxxxxxxx wrote:

        I thought there was a way to map the mouseposition to global space ? I'm not sure but i think I have read about it.

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

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 09/05/2011 at 11:03, xxxxxxxx wrote:

          WS() and SW() from the BaseDraw convert world to screen and screen to world spaces.

          Yes, you need to use a RayCollider to find the point nearest the cursor position (and nearest the screen plane if that is a parameter).

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

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 09/05/2011 at 17:17, xxxxxxxx wrote:

            okay So I am trying this to see if I can even get a collision.  The problem is that when I run this on an object that is not editable the "pountCount" returns 0 every time.  Any idea why this would be happening?

              
              
            //Get the object  
              BaseObject *op = doc->GetActiveObject();   
              if (!op) return TOOLDRAW_0;  
              
              //Convert the object to a polygon  
              PolygonObject *objPoly = (PolygonObject* )op;  
              if (!objPoly) return TOOLDRAW_0;  
              
              LONG pointCount = objPoly->GetPointCount();  
              Vector * points = objPoly->GetPointW();  
              
              AutoAlloc<GeRayCollider> cRay;  
              
              // Make sure RayCollider is there  
              if (!cRay)  
              {  
                  GePrint("ERROR - RayCollider not Initialized");  
                  return TOOLDRAW_0;  
              }  
              
              for(int i = 0; i < pointCount; i++){  
              
              Vector wtail =    bd->SW(Vector(cursorX, cursorY, 0));  
              Vector whead =    bd->SW(Vector(cursorX, cursorY, 1000000));  
              Vector otail = (!points[i]) * wtail;  
              Vector oray     = (whead - wtail) ^ (!points[i]);  
              
              cRay->Init(objPoly, TRUE);  
              cRay->Intersect(otail, !oray, 1000000.0);  
              
                  Vector distance = PointLineDistance(wtail, whead, points[i]);  
                  const Real threshold = 200.0;  
                  Real dist = distance.GetLength();  
              
                
                  if(dist <= threshold)    
                  {  
                        
                      bd->DrawHandle(points[i], DRAWHANDLE_BIG, NOCLIP_Z);  
                      GePrint("Collision");  
              
                      return TOOLDRAW_AXIS|TOOLDRAW_HANDLES;;  
                  }  
                  else  
                  {  
                      GePrint("No Collision");  
                      return TOOLDRAW_0;  
                  }  
              }  
            

            Thanks,

            Shawn

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

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 09/05/2011 at 21:15, xxxxxxxx wrote:

              Not sure of the best way to go about doing this with 'procedural objects'.  My first thought would be to clone the original object (you might not need to clone first so try without and see the results), use current-state-to-object (SendModelingCommand()), and either insert into the actual document temporarily (not recommended) or into a fake doc (possibly better option).  Then apply the global matrix of the original object to the clone and use the cursor values with the RayCollider on that.  You need a PolygonObject to get polygons and vertices.  I have read that you can simply cast primitives (sphere, cube, etc.) into PolygonObject but this won't work with more complex objects such as those created with splines using SweepNURBS, for instance.

              So, in essence, you are using a proxy object in a hidden document (do not insert into the document list!) to do the work behind the scenes.  To expedite things, create the fake document for reuse so that you don't have to constantly create/delete it as the tool is being used.

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

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 09/05/2011 at 23:25, xxxxxxxx wrote:

                What about "isinstance()" testing for a pointobject ? Or do you want to make it editable and then apply your tool ?

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

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 10/05/2011 at 02:55, xxxxxxxx wrote:

                  Ah yes!  I forgot about current-state-to-object.  Works like a charm now.  Using this...

                    
                    ModelingCommandData mcd;  
                    mcd.op = op;  
                    mcd.mode = MODELINGCOMMANDMODE_ALL;  
                    mcd.doc = doc;  
                    SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd);  
                    BaseObject *res = static_cast<BaseObject*>(mcd.result->GetIndex(0));  
                    
                    PolygonObject *objPoly = (PolygonObject * )res;  
                    if (!objPoly) return TOOLDRAW_0;  
                    
                  

                  Thanks again Robert!

                  ~Shawn

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

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 10/05/2011 at 09:25, xxxxxxxx wrote:

                    well..   the collision is being found now but only for the first point in the object.  It doesn't find a collision with any other point in the object.  Weird huh?
                     
                    ~Shawn

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

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 10/05/2011 at 11:06, xxxxxxxx wrote:

                      I was just going to post that I got the same results. That it only gets the first indexed point.
                      If you find the solution. Please post it. This is something that could probably be very handy.

                      -ScottA

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

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 10/05/2011 at 11:15, xxxxxxxx wrote:

                        Nevermind that last post.  I see what your problem is.  You are returning after the first loop pass on either case.  One loop and return.

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

                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                          On 10/05/2011 at 11:26, xxxxxxxx wrote:

                          You might want to use GetNearestPoint() instead and check for a radial distance from there or modify your loop to exhaust the available point set, only taking those best matching your criteria.

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

                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                            On 10/05/2011 at 11:37, xxxxxxxx wrote:

                            LOL  oh duh.   I didn't notice that I was returning out of the loop.  Thanks for catching that.   Would GetNearestPoint() work outside of points mode?  Sorry.  I'm not home to test it. I will when I get home. 
                            Thanks yet again.

                            Shaw

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

                              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                              On 10/05/2011 at 12:20, xxxxxxxx wrote:

                              Thanks Robert.
                              With that information I was able to change the for loop so it works with every point.

                                  for(int i = 0; i < pointCount; i++)  
                                  {  
                                  Vector wtail = bd->SW(Vector(mouseX, mouseY, 0));  
                                  Vector whead = bd->SW(Vector(mouseX, mouseY, 100000));  
                                  Vector otail = (!points[i]) * wtail;  
                                  Vector oray  = (whead - wtail) ^ (!points[i]);  
                                
                                  cRay->Init(objPoly, TRUE);  
                                  cRay->Intersect(otail, !oray, 10000.0);  
                                
                                  Vector distance = PointLineDistance(wtail, whead, points[i]);  
                                  const Real threshold = 20.0; // How close the mouse is to the point befor triggering the collision  
                                  Real dist = distance.GetLength();  
                                  
                                  if(dist <= threshold)    
                                    {              
                                      bd->DrawHandle(points[i], DRAWHANDLE_BIG, NOCLIP_Z);  
                                      GePrint("Collision with index#:" + RealToString(i)); // Prints the point index when collided           
                                    }        
                                  }
                              

                              Thanks for posting this example code Shawn.
                              It really helps me to learn this stuff.

                              -ScottA

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

                                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                On 10/05/2011 at 14:11, xxxxxxxx wrote:

                                Hey glad you got it working Scott.  What function are you calling this code in?  And, does your sample draw the handle at the point that is being collided with?

                                Thanks.  ~Shawn

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

                                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                  On 10/05/2011 at 15:01, xxxxxxxx wrote:

                                  I'm not calling any function with it. Other than printing the index number of the object's point array as the mouse collides with it.
                                  The handle code doesn't do anything. I just forgot to delete it.

                                  -ScottA

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

                                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                    On 10/05/2011 at 15:15, xxxxxxxx wrote:

                                    Sorry.  I wasn't clear.  I meant in what function is this code currently?  Do you have it in your Draw() function or MouseInput().  And I meant is the handle code working on your end because it wasn't working on mine but it is now.  I am thinking that this might actually be a performance monster.  I may try Roberts recommendation of using GetNearestPoint().

                                    Thanks

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

                                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                      On 10/05/2011 at 15:51, xxxxxxxx wrote:

                                      I was using it in draw. So when the mouse hovered over the point it would trigger the collide.
                                      But since you asked. I just tried putting it under the mouse input function.
                                      And while the print still works properly when the left mouse button is clicked. The handle doesn't do anything.

                                      I'm very new to this stuff. So I might not be writing it properly. Or the same way as you.
                                      So here's my MouseInput code in case you're curious:

                                      Bool DrawTool::MouseInput(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, EditorWindow *win, const BaseContainer &msg)  
                                      {  
                                        if (!doc) return FALSE;  
                                        
                                        BaseContainer state;  
                                        while (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, state)) //While the left mouse button is pressed  
                                        {  
                                        if (state.GetLong(BFM_INPUT_VALUE) == 0) break; // Break out of the loop when left mouse button is NOT pressed      
                                        LONG x = state.GetLong(BFM_INPUT_X);  
                                        LONG y = state.GetLong(BFM_INPUT_Y);      
                                        //GePrint("Left Mouse Button is pressed");  
                                        
                                        BaseObject* obj = doc->GetActiveObject();  
                                        if(!obj) return TOOLDRAW_0;  
                                        
                                        PolygonObject *objPoly = (PolygonObject* )obj;  
                                        if (!objPoly) return TOOLDRAW_0;  
                                        LONG pointCount = objPoly->GetPointCount();  
                                        Vector *points = objPoly->GetPointW();  
                                              
                                        AutoAlloc<GeRayCollider> cRay;  
                                        GeRayColResult res;  
                                        
                                        // Make sure RayCollider is there  
                                        if (!cRay)  
                                        {  
                                            GePrint("ERROR - RayCollider not Initialized");  
                                            return TOOLDRAW_0;  
                                        }  
                                        
                                        for(int i = 0; i < pointCount; i++)  
                                          {  
                                          Vector wtail = bd->SW(Vector(mouseX, mouseY, 0));  
                                          Vector whead = bd->SW(Vector(mouseX, mouseY, 100000));  
                                          Vector otail = (!points[i]) * wtail;  
                                          Vector oray  = (whead - wtail) ^ (!points[i]);  
                                        
                                          cRay->Init(objPoly, TRUE);  
                                          cRay->Intersect(otail, !oray, 10000.0);  
                                        
                                          Vector distance = PointLineDistance(wtail, whead, points[i]);  
                                          const Real threshold = 20.0; // How close the mouse is to the point befor triggering the collision  
                                          Real dist = distance.GetLength();  
                                          
                                          if(dist <= threshold)    
                                            {              
                                              bd->DrawHandle(points[i], DRAWHANDLE_BIG, NOCLIP_Z);  
                                              GePrint("Collision with index#:" + RealToString(i)); // Prints the point index when collided           
                                            }        
                                          }  
                                        }  
                                      return TRUE;  
                                      }
                                      

                                      -ScottA

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

                                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                        On 10/05/2011 at 16:29, xxxxxxxx wrote:

                                        Hmm looks like GetNearestPoint only works in Points mode

                                        And as is, this GeRayCollider code runs super slow when there are a lot of points.

                                        Here's what I have,  I am doing it in the draw because I want it to update live..  😉  Which I could probably do more effectively in GetCursorInfo() or write my own function and call that from the Draw() but this is mostly for testing.  🙂

                                          
                                          
                                          AutoAlloc<ViewportSelect> vps;  
                                          if(!vps) return TOOLDRAW_0;  
                                          
                                          BaseObject* op = doc->GetActiveObject();  
                                          if(!op) return TOOLDRAW_0;  
                                            
                                          bd->SetMatrix_Matrix(op, Matrix());  
                                            
                                          ModelingCommandData mcd;  
                                          mcd.op = op;  
                                          mcd.mode = MODELINGCOMMANDMODE_ALL;  
                                          mcd.doc = doc;  
                                          SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd);  
                                          BaseObject *res = static_cast<BaseObject*>(mcd.result->GetIndex(0));  
                                          
                                          PolygonObject *objPoly = (PolygonObject * )res;  
                                          if (!objPoly) return TOOLDRAW_0;  
                                          
                                          LONG pointCount = objPoly->GetPointCount();  
                                          Vector * points = objPoly->GetPointW();  
                                          
                                          AutoAlloc<GeRayCollider> cRay;  
                                          
                                          // Make sure RayCollider is there  
                                          if (!cRay)  
                                          {  
                                              GePrint("ERROR - RayCollider not Initialized");  
                                              return TOOLDRAW_0;  
                                          }  
                                          
                                          for(int i = 0; i < pointCount; i++){  
                                          
                                              Vector wtail = bd->SW(Vector(cursorX, cursorY, 0));  
                                              Vector whead = bd->SW(Vector(cursorX, cursorY, 100000));  
                                              Vector otail = (!points[i]) * wtail;  
                                              Vector oray  = (whead - wtail) ^ (!points[i]);  
                                          
                                              cRay->Init(objPoly, TRUE);  
                                              cRay->Intersect(otail, !oray, 10000.0);  
                                          
                                              Vector distance = PointLineDistance(wtail, whead, points[i]);  
                                              const Real threshold = 20.0; // How close the mouse is to the point befor triggering the collision  
                                              Real dist = distance.GetLength();  
                                            
                                              if(dist <= threshold){              
                                                  bd->SetPen(Vector(1,0,0));  
                                                  bd->DrawHandle(points[i], DRAWHANDLE_BIG, NOCLIP_Z);          
                                              }            
                                          }  
                                            
                                          return    TOOLDRAW_AXIS|TOOLDRAW_HANDLES;  
                                          
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • H
                                          Helper
                                          last edited by

                                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                          On 10/05/2011 at 16:41, xxxxxxxx wrote:

                                          okay I moved a few things.  I took the cray->Init out of the loop so it doesn't get reinitialized each time..  that helped a lot with performance..  still working out some kinks  but I iwll post when I am done so that you have a working and optimized sample.

                                          ~Shawn

                                          PS if anyone has any tips for further optimizing this code, I am all ears.  LOL

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

                                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                            On 10/05/2011 at 17:14, xxxxxxxx wrote:

                                            SORRY- ACCIDENTAL DUPLICATE POST REMOVED!

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