Tool Plugin Question



  • 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 ?



  • 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



  • 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



  • 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



  • 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.



  • 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.



  • 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



  • 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



  • 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



  • 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



  • 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



  • 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



  • 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;  
      
    


  • 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



  • 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!



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

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

    Okay here it is all cleaned up and working.  Still a small delay with objects with a ton of points but I can't see any other way to optimize.  Any suggestions are greatly appreciated.  But here's the code for anyone who wants it.  :)

      
      
        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;  
      
        Real radius        = data.GetReal(MY_RADIUS);  
        Real strength    = data.GetReal(MY_STRENGTH);  
        Real falloff    = data.GetReal(MY_FALLOFF);  
        Vector color    = data.GetVector(MY_COLOR);  
      
        LONG pointCount = objPoly->GetPointCount();  
        Vector * points = objPoly->GetPointW();  
      
        AutoAlloc<GeRayCollider> cRay;  
      
        cRay->Init(objPoly, TRUE);  
      
        Vector wtail = bd->SW(Vector(cursorX, cursorY, 0));  
        Vector whead = bd->SW(Vector(cursorX, cursorY, 100000));  
      
        // Make sure RayCollider is there  
        if (!cRay)  
        {  
            GePrint("ERROR - RayCollider not Initialized");  
            return TOOLDRAW_0;  
        }  
      
        for(int i = 0; i < pointCount; i++){  
      
            Vector otail = (!points[i]) * wtail;  
            Vector oray  = (whead - wtail) ^ (!points[i]);  
      
            Vector distance = PointLineDistance(wtail, whead, points[i]);  
            Real dist = distance.GetLength();  
            //const Real threshold = 20; //Tool Radius  
              
          
            if(dist <= radius){              
                bd->SetPen(color);  
                bd->DrawHandle(points[i], DRAWHANDLE_BIG, NOCLIP_Z);          
            }            
        }  
      
        return    TOOLDRAW_AXIS|TOOLDRAW_HANDLES;  
      
    


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

    On 10/05/2011 at 18:21, xxxxxxxx wrote:

    Could you possibly post your MouseInput function Shawn?

    I'm getting results when hovering over the objects. But I don't know how to set up the mouse function to do anything with it.

    -ScottA



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

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

    I'm currently working on that.  I will post it when I get some results that I am happy with.  :)



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

    On 11/05/2011 at 02:59, xxxxxxxx wrote:

    Well here is my MouseInput function.  It is still not doing what I want it to.  My goal is to be able to change Y position of the point when the user drags the mouse over the point.  Not sure why this isn't doing anything right now.   :)

      
      
    BaseObject* op = doc->GetActiveObject();  
      if(!op) return FALSE;  
      
      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 FALSE;  
      
      bd->SetMatrix_Matrix(objPoly, Matrix());  
      
      Real radius        = data.GetReal(MY_RADIUS);  
      Real strength    = data.GetReal(MY_STRENGTH);  
      Real falloff    = data.GetReal(MY_FALLOFF);  
      
      LONG pointCount = objPoly->GetPointCount();  
      Vector * points = objPoly->GetPointW();  
      
      AutoAlloc<GeRayCollider> cRay;  
      
      cRay->Init(objPoly, TRUE);  
      
      Vector wtail = bd->SW(Vector(cursorX, cursorY, 0));  
      Vector whead = bd->SW(Vector(cursorX, cursorY, 100000));  
      
      // Make sure RayCollider is there  
      if (!cRay)  
      {  
          GePrint("ERROR - RayCollider not Initialized");  
          return FALSE;  
      }  
        
      Real mx = msg.GetReal(BFM_INPUT_X);  
      Real my = msg.GetReal(BFM_INPUT_Y);  
      LONG button;  
      
      switch (msg.GetLong(BFM_INPUT_CHANNEL))  
      {  
        case BFM_INPUT_MOUSELEFT : button=KEY_MLEFT; break;  
        case BFM_INPUT_MOUSERIGHT: button=KEY_MRIGHT; break;  
        default: return TRUE;  
      }  
      
      BaseContainer device;  
      Real dx, dy;  
      
      doc->AddUndo(UNDOTYPE_CHANGE, op);  
      
      win->MouseDragStart(KEY_MLEFT, mx, my, MOUSEDRAGFLAGS_DONTHIDEMOUSE);  
      
      while (win->MouseDrag(&dx, &dy, &device) == MOUSEDRAGRESULT_CONTINUE)  
      {  
          if (dx == 0.0 && dy == 0.0) continue;  
      
          for(int i = 0; i < pointCount; i++){  
        
          Vector otail = (!points[i]) * wtail;  
          Vector oray  = (whead - wtail) ^ (!points[i]);  
      
          Vector distance = PointLineDistance(wtail, whead, points[i]);  
          Real dist = distance.GetLength();  
            
          if(dist <= radius){    
              points[i].y += 100;  
              objPoly->Message(MSG_UPDATE);  
          }            
      }  
      
      
      
        
      }  
      
      if (win->MouseDragEnd()== MOUSEDRAGRESULT_ESCAPE)  
      {  
          doc->DoUndo(TRUE);  
      }  
      
      EventAdd();  
        
      return TRUE;  
      
    

    What I expect to happen with this code is that when the user drags over the points, those points increase in height by 100.  But as it is, it does absolutely nothing to the points.  So I am stumped right now.  :)

    ~Shawn



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

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

    Not much to make the code faster except for some smart preprocessing step to eliminate points but probably would not improve performance much (you gain some in the final loop but lose some in the preprocessing).  A small improvement would be to use pointers instead of array indices.  Also notice that you can gain more performance by referencing the point in the array once.

        Vector* lpoints =    points+pointCount;  
      Vector pt;  
      for(; points != lpoints; ++points){  
            pt = *points;  
          Vector otail = (!pt) * wtail;  
          Vector oray  = (whead - wtail) ^ (!pt);  
          Vector distance = PointLineDistance(wtail, whead, pt);  
          Real dist = distance.GetLength();  
          //const Real threshold = 20; //Tool Radius  
      
          if(dist <= radius){              
              bd->SetPen(color);  
              bd->DrawHandle(pt, DRAWHANDLE_BIG, NOCLIP_Z);          
          }            
      }
    

Log in to reply