Move 1 object to another.



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

    On 19/02/2010 at 17:48, xxxxxxxx wrote:

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

    ---------
    So I am trying to create a tool that allows the user to click one polygon on an object and then a polygon on a different object and the first object will then move to the second polygon selection and rotate so that the first selected polygon is touching the second selected polygon.    I am trying to figure out the best way to store the first selection so that when the user clicks the second selection the plugin knows which polygon needs to be facing which direction.     Here's what I have so far.  I apologize for the clutter.  I am just bouncing around ideas right now.

      
      
    Bool QuickAlign::MouseInput(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, EditorWindow *win, const BaseContainer &msg)  
    {  
      C4DObjectList * objList = C4DObjectList::Alloc();   
      if (!objList) return FALSE;  
        
      //DECLARATIONS & DEFINITIONS  
      if (!doc) return FALSE;  
      
      AtomArray *atom = AtomArray::Alloc();  
      if (!atom) return FALSE;  
        
      //BaseObject *op = doc->GetRealActiveObject(atom,NULL);  
      BaseObject *op = doc->GetActiveObject();  
      if(!op) return TRUE;  
      
      PolygonObject *objPoly = ToPoly(op);  
      if (!objPoly) return FALSE;  
      
      BaseSelect *bsPoly = objPoly->GetPolygonS();  
      BaseSelect *bsPoint = objPoly->GetPointS();  
      BaseSelect *bsEdge = objPoly->GetEdgeS();  
         
      Real dx, dy, len = data.GetReal(1, 0.0);  
      BaseContainer device;  
      Real mousex = msg.GetLong(BFM_INPUT_X);  
      Real mousey = msg.GetLong(BFM_INPUT_Y);  
      win->MouseDragStart(KEY_MLEFT, mousex, mousey, MOUSEDRAG_NOMOVE);  
      
      
      LONG lngRad = 1;  //MAXIMUM SELECTION RADIUS  
      LONG lngEditorMode = doc->GetMode();  
      
      AutoAlloc<ViewportSelect> vps;  
      if(!vps) return FALSE;  
      
      LONG left, top, right, bottom, width, height;  
      bd->GetFrame(&left, &top, &right, &bottom);  
      width = right - left + 1;  
      height = bottom - top + 1;  
      
      if(!vps->Init(width, height, bd, op, doc->GetMode(), TRUE, VIEWPORT_IGNORE_HIDDEN_SEL)) return FALSE;  
      
      LONG lngX = mousex;  
      LONG lngY = mousey;  
      
      //DRAW CIRCLE TO SHOW HOTSPOT  
      
      vps->SetBrushRadius(data.GetLong(SELECTION_RADIUS)); //SET BRUSH RADIUS  
      
      while (win->MouseDrag(&dx, &dy, &device) == MOUSEDRAG_CONTINUE)  
       {  
            if (dx == 0 && dy == 0)  
            continue;  
      
            lngX += dx;  
            lngY += dy;  
      
            DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
            vps->ShowHotspot(win, lngX, lngY);  
       }  
      
       vps->ShowHotspot(win, lngX, lngY);  
      
      //SELECT THE POLYGON THAT IS CLICKED  
        
      BaseContainer state;  
      LONG lngKey = state.GetLong(BFM_INPUT_QUALIFIER);  
      ViewportPixel *vpPoly = vps->GetNearestPolygon(op,lngX,lngY,lngRad);  
      ViewportPixel *vpPoint = vps->GetNearestPoint(op,lngX,lngY,lngRad);  
      ViewportPixel *vpEdge = vps->GetNearestEdge(op,lngX,lngY,lngRad);  
      Bool shiftDown = GetInputEvent(BFM_INPUT_KEYBOARD, state);  
      LONG lngPolySelCount = bsPoly->GetCount();  
      LONG lngPointSelCount = bsPoint->GetCount();  
      LONG lngEdgeSelCount = bsEdge->GetCount();  
      LONG lngPolygonCount = objPoly->GetPolygonCount();  
      LONG lngPointCount = objPoly->GetPointCount();  
      LONG lngI;  
        
      CPolygon * firstPolygon = objPoly->GetPolygonW();  
      CPolygon * secondPolygon = objPoly->GetPolygonW();  
      
      Matrix *m = op->GetMg();  
        
        
      
      switch (lngEditorMode)  
      {       
          //POLYGONS MODE      
          case Mpolygons:  
          {  
              if(vpPoly)  
              {  
                  //FIRST SELECTION  
                  if (lngPolySelCount == 0)  
                  {  
                      bsPoly->Select(vpPoly->i);  
      
                      for (lngI=0; lngI < lngPolygonCount; lngI++)  
                      {  
                          if (bsPoly->IsSelected(lngI))  
                          {  
                              GePrint ("First Polygon " + LongToString(lngI) + " is selected.");  
                              lngA = firstPolygon[lngI].a;  
                              lngB = firstPolygon[lngI].b;  
                              lngC = firstPolygon[lngI].c;  
                              lngD = firstPolygon[lngI].d;  
                          }  
                      }  
                  }  
                    
                  //GET SECOND SELECTED POLYGON AND DETERMINE IT'S LOCATION,    
                  //MOVE 1ST SELECTED POLYGON TO THE LOCATION OF 2ND, THEN  
                  //ROTATE THE REST OF THE OBJECT TO MATCH.  
      
                  else if (lngPolySelCount == 1)  
                  {  
                      bsPoly->DeselectAll();  
                      bsPoly->Select(vpPoly->i);  
                        
                      for (lngI=0; lngI < lngPolygonCount; lngI++)  
                      {  
                          if (bsPoly->IsSelected(lngI))  
                          {  
                              GePrint ("Polygon " + LongToString(lngI) + " is selected.");  
                              secondPolygon[lngI].a = lngA;  
                              secondPolygon[lngI].b = lngB;  
                              secondPolygon[lngI].c = lngC;  
                              secondPolygon[lngI].d = lngD;  
                          }  
                      }  
                  }  
        
                  EventAdd(EVENT_FORCEREDRAW);  
                  op->Message(MSG_CHANGE);  
                  DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
              }  
          }  
            
          //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);  
              }  
          }  
      }  
      
      
      EventAdd(EVENT_FORCEREDRAW);  
      win->MouseDragEnd();  
      return TRUE;  
    }  
      
    

    I am not sure of the approach to take to get the first selection to move to the second selection and take the whole object with it.  You can see that I have declared a matrix because I am thinking that this will be how I have to move the whole object and rotate the whole object.  But how can I determine which way the object should be rotated.

    I know this is complex but all I am looking for is a nudge in the right direction.

    Any thoughts would be greatly appreciated.

    Thanks,

    ~Shawn



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

    On 20/02/2010 at 17:06, xxxxxxxx wrote:

    Okay so this is kinda working now.

    here's the code

      
          //POLYGONS MODE      
          case Mpolygons:  
          {  
              if(vpPoly)  
              {  
                  //FIRST SELECTION  
                  if (secondSelection == FALSE)  
                  {  
                      GePrint("FIRST SELECTION");  
                      bsPoly->Select(vpPoly->i);  
                      firstSelection = vpPoly->op;  
                      secondSelection = TRUE;  
                  }  
                    
                  //GET SECOND SELECTED POLYGON AND DETERMINE IT'S LOCATION,    
                  //MOVE 1ST SELECTED POLYGON TO THE LOCATION OF 2ND, THEN  
                  //ROTATE THE REST OF THE OBJECT TO MATCH.  
      
                  else if (secondSelection == TRUE)  
                  {  
                      GePrint("SECOND SELECTION");  
                      GePrint("ALIGNING OBJECT");  
                      bsPoly->DeselectAll();  
                      bsPoly->Select(vpPoly->i);  
                        
                      firstSelection->SetPos(Vector (mousex,mousey,vpPoly->z));  
                      secondSelection = FALSE;  
                  }  
        
                  EventAdd(EVENT_FORCEREDRAW);  
                  op->Message(MSG_CHANGE);  
                  DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
              }  
          }  
      
    

    The object is now moving on the second click but the problem is it is not moving to the coordinates of the polygon selection on the second click.

    I'm sure the problem is this line

      
    firstSelection->SetPos(Vector (mousex,mousey,vpPoly->z));  
    

    apparently the mousex, and mouse y are not giving me the x and y coordinates of that selected polygon.   How do I determine the x and y coordinates of a polygon?

    ~Shawn



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

    On 23/02/2010 at 02:18, xxxxxxxx wrote:

    bd- >SW(Vector(mx,my,500.0) will convert screen to worldspace. Check BaseView::SW() for a description.

    cheers,
    Matthias



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

    On 23/02/2010 at 02:21, xxxxxxxx wrote:

    Also check the liquidtool.cpp SDK example's MouseInput() method.

    cheers,
    Matthias


Log in to reply