Highlighting Polys/points/and edges.



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

    On 11/02/2010 at 06:07, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   11.5 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I have gotten so that when I click on a polygon it will select.  That was pretty easy.   What I would like to do now is have that polygon highlight when the mouse is over it so that the user knows that that is the polygon they will select.

    What should I be looking for to accomplish this?

    Thanks,
    ~Shawn



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

    On 11/02/2010 at 06:15, xxxxxxxx wrote:

    Also...

    I am trying to figure out how to allow users to hold down the SHIFT key to select more than one polygon.    This is the code I have based on some searches I did on the subject.   It is still not working for me.   The only one I have attempted to set up like this is the polygon selection.

    Here's the code I have.

      
    BaseContainer state;  
      LONG key = state.GetLong(BFM_INPUT_QUALIFIER);  
      ViewportPixel *vpPoly = vps->GetNearestPolygon(op,x,y,rad);  
      ViewportPixel *vpPoint = vps->GetNearestPoint(op,x,y,rad);  
      ViewportPixel *vpEdge = vps->GetNearestEdge(op,x,y,rad);  
      Bool ctrlDown = GetInputEvent(BFM_INPUT_KEYBOARD, state);  
      
      switch (editorMode)  
      {  
          //POLYGONS MODE  
          case Mpolygons:  
          {       
              if(vpPoly)  
              {  
                    
                  if (ctrlDown == TRUE)  
                  {  
                      if (key & QCTRL)  
                      {  
                          GePrint("ctrl");  
                          bsPoly->DeselectAll();  
                      }  
                  }  
                  bsPoly->Select(vpPoly->i);  
                  EventAdd(EVENT_FORCEREDRAW);  
              }  
          }  
            
          //POINTS MODE  
          case Mpoints:  
          {       
              if(vpPoint)  
              {  
                  bsPoint->DeselectAll();  
                  bsPoint->Select(vpPoint->i);  
                  EventAdd(EVENT_FORCEREDRAW);  
              }  
          }  
      
          //EDGES MODE  
          case Medges:  
          {       
              if(vpEdge)  
              {  
                  bsEdge->DeselectAll();  
                  bsEdge->Select(vpEdge->i);  
                  EventAdd(EVENT_FORCEREDRAW);  
              }  
          }  
      }  
      
    

    This is all in the MouseInput() member.   Do you see something I need ot fix?

    ~Shawn



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

    On 12/02/2010 at 06:33, xxxxxxxx wrote:

    Highlighting and SHIFT key for multiselection has to be done manually.

    For highlighting you check in GetCursorInfo() over which polygon, point or edge you are hovering and pass the ID of the element to the Draw() method (call DrawViews() to trigger a redraw).

    Your code should work. I would add following two lines after selecting the polygon

    **
    op- >Message(MSG_CHANGE);
    DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);
    **

    This informs the object of a change and will trigger the redraw to display the polygon selection.

    cheers,
    Matthias



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

    On 14/02/2010 at 18:04, xxxxxxxx wrote:

    So I am guessing that this would be how I would get the index of the poly/point/ or edge that I am over.

      
      AutoAlloc<ViewportSelect> vps;  
      if(!vps) return FALSE;  
        
      BaseObject* op = doc->GetActiveObject();  
      if(!op) return FALSE;  
      
        
      ViewportPixel *vp = vps->GetNearestPolygon(op,x,y,100);  
      LONG polyIndex = vp->i;  
    

    How do I pass that index to the Draw() method?

    Thanks,
    ~Shawn



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

    On 14/02/2010 at 22:06, xxxxxxxx wrote:

    Okay here's what I have in my GetCursorInfo()

      
      if (bc.GetId()==BFM_CURSORINFO_REMOVE) return TRUE;  
      bc.SetString(RESULT_BUBBLEHELP, GeLoadString(IDS_HLP_QUICK_ALIGN));  
      
      CallCommand(10004766);  
      
      AutoAlloc<ViewportSelect> vps;  
      if(!vps) return FALSE;  
      
      BaseObject* op = doc->GetActiveObject();   
      if(!op) return FALSE;  
      
      LONG lngX = x;  
      LONG lngY = y;  
      
      ViewportPixel *vp = vps->GetNearestPolygon(op,lngX,lngY,MAXLONGl, TRUE);  
      if(!vp) return FALSE;  
      
      LONG polyIndex = vp->i;  
      GePrint("POLY INDEX IS: " + LongToString(polyIndex));  
      
      return TRUE;  
    

    the probem I am having is that with the line ->

      
    if(!vp) return FALSE;  
    

    it always returns false.

    if I remove that line, C4D crashes as soon as I have an object in the scene.  Is it my definition of "op" that is the problem?

    should this be something different?

      
      BaseObject* op = doc->GetActiveObject();   
      if(!op) return FALSE;  
    

    Any help you c ould offer would be greatly appreciated.  Also if you have an answer the the post before this one that would be helpful too.   :)

    Thanks,

    ~Shawn



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

    On 15/02/2010 at 01:12, xxxxxxxx wrote:

    ViewportPixel *vp = vps->GetNearestPolygon(op,lngX,lngY,MAXLONGl, TRUE)
    

    This will always return FALSE if the Bool onlyselected is set to TRUE and no polygons are selected in the first place.

    As for passing an index to Draw() you simply store the index in a member variable and call DrawViews(). This will trigger Draw(). In Draw() read out the member variable then.

    cheers,
    Matthias



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

    On 15/02/2010 at 06:36, xxxxxxxx wrote:

    This is what I have in GetCursorInfo() now:

      
      
      if (bc.GetId()==BFM_CURSORINFO_REMOVE) return TRUE;  
      bc.SetString(RESULT_BUBBLEHELP, GeLoadString(IDS_HLP_QUICK_ALIGN));  
      
      CallCommand(10004766);  
      
      AutoAlloc<ViewportSelect> vps;  
      if(!vps) return FALSE;  
      
      BaseObject* op = doc->GetActiveObject();   
      if(!op) return FALSE;  
      
      LONG lngX = x;  
      LONG lngY = y;  
      
      ViewportPixel *vp = vps->GetNearestPolygon(op,lngX,lngY,MAXLONGl, FALSE);  
      if(!vp) return FALSE;  
      
      LONG lngPolyIndex = vp->i;  
      GePrint("POLY INDEX IS: " + LongToString(lngPolyIndex));  
      
      DrawViews(lngPolyIndex,bd);  
      
      return TRUE;  
    

    for some reason (vp) is still returning false so anything below it is not being read.  Do you see any reason why the ViewportPixel would return FALSE?

    Thanks,

    ~Shawn



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

    On 15/02/2010 at 06:43, xxxxxxxx wrote:

    Ah, now I see why it doesn't work for you. You forgot to initialize the ViewportSelect object before using one of the GetNearest functions. Check the ViewportSelect::Init methods.

    cheers,
    Matthias



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

    On 15/02/2010 at 06:55, xxxxxxxx wrote:

    LOL..  what a silly mistake on my part..  I have used ViewPortSelect before too..  I should have remembered that.    Okay..  now it prints out the index to the console and shows me poly I am hovering over,  but the polygon does not highlight when my mouse is over it.   Did I not do the DrawViews()  correctly.  Or is there something I need to add to the Draw() to make it highlight?

    Thanks again.

    ~Shawn



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

    On 16/02/2010 at 01:00, xxxxxxxx wrote:

    Draw() is not automatically displaying the highlighting. You have to do the highlight drawing yourself within Draw(). DrawViews() is just triggering the viewport redraw by internally calling Draw(). You are using DrawViews() wrong. Also as I said you should store the polygon ID within a member variable of the tool class.

    Have a look at eh code below. I store the polygon ID in the polygonid variable and call DrawViews() to trigger a redraw. In Draw() I read out the variable then to draw the highlight polygon. I use the BaseDraw drawing functions for this. The highlight variable is used to prevent highlighting during viewport navigation.

      
    class LiquidToolData : public ToolData  
    {  
      public:  
          LiquidToolData() { polygonid = 0; highlight = FALSE; }  
      
          virtual Bool GetCursorInfo(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, Real x, Real y, BaseContainer &bc);  
          virtual LONG Draw(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt, LONG flags);  
      
      private:  
          LONG polygonid;  
          Bool highlight;  
    };  
      
    Bool LiquidToolData::GetCursorInfo(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, Real x, Real y, BaseContainer &bc)  
    {  
      LONG left, top, right, bottom, width, height;  
      bd->GetFrame(&left,  &top, &right, &bottom);  
      width = right - left + 1;  
      height = bottom - top + 1;  
      
      LONG mode = doc->GetMode();  
      
      BaseObject *op = doc->GetActiveObject();  
      if (!op || op->GetType() != Opolygon) return TRUE;  
        
      AutoAlloc<ViewportSelect> vs;  
      if (!vs || !vs->Init(width,height,bd,op,mode,TRUE,0)) return FALSE;  
      
      if (mode == Mpolygons)  
      {  
          highlight = TRUE;  
      
          ViewportPixel *vpp = NULL;  
      
          LONG mx = x;  
          LONG my = y;  
      
          vpp = vs->GetNearestPolygon(op, mx, my, MAXLONGl, FALSE, NULL, 0);  
      
          if (vpp)  
          {  
              polygonid =  vpp->i;  
      
              DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION, bd);  
          }  
      }  
      
      return TRUE;  
    }  
      
    LONG LiquidToolData::Draw(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt, LONG flags)  
    {  
      if (!(flags & DRAWFLAGS_HIGHLIGHT))  
          return FALSE;  
      
      if (doc->GetMode() != Mpolygons)  
          return TRUE;  
      
      if (!highlight)  
          return TRUE;  
      
      BaseObject *op = doc->GetActiveObject();  
      if (op && op->GetType() == Opolygon)  
      {  
          const CPolygon *polys = ToPoly(op)->GetPolygonR();  
          const Vector *points = ToPoly(op)->GetPointR();  
          Vector *p = bNew Vector[4];  
          p[0] = points[polys[polygonid].a];  
          p[1] = points[polys[polygonid].b];  
          p[2] = points[polys[polygonid].c];  
          p[3] = points[polys[polygonid].d];  
      
          Vector *f = bNew Vector[4];  
          f[0] = 1.0;  
          f[1] = 1.0;  
          f[2] = 1.0;  
          f[3] = 1.0;  
      
          bd->SetMatrix_Matrix(NULL, op->GetMg(), 3);  
          bd->PolygonNew(p,f,TRUE);  
      
          bd->LineZOffset(0);  
      
          bDelete(p);  
          bDelete(f);  
      }  
      
      highlight = FALSE;  
      
      return TRUE;  
    }  
    

    cheers,
    Matthias



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

    On 16/02/2010 at 16:26, xxxxxxxx wrote:

    Thanks Matthias that worked great.

    How does this translate to points and Edges?    Do I use Point3D() for the points?    I am not sure what I would use for edges.    What are your thoughts on points and edges?

    ~Shawn



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

    On 16/02/2010 at 17:17, xxxxxxxx wrote:

    Also,  if I have selected a polygon, how can I then move that particular polygon,  how do I get access to the position of that polygon,   is it possible to convert a BaseSelect polygon selection into a CPolygon so that I can move the position of .a .b .c .d   ?

    Basically, I want the user to click on a polygon, then click a second polygon and the first selected polygon will move to the location of the second selection.    Any thoughts as to how I would go about this?

    Thanks,

    ~Shawn



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

    On 19/02/2010 at 08:59, xxxxxxxx wrote:

    Any thoughts on this?



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

    On 11/03/2010 at 03:59, xxxxxxxx wrote:

    if you are in a tooldata plugin i sugest you to use modeling lib.
    with your baseselect you can recourse in Polygons and ngon and get/ set Point position.
    to convert you standard selection in a ngon one ( modelling lib need it )
    use GetFace Slection.

    all the best
    Franz


Log in to reply