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