Plugin Cafe Homepage
Forum Home Forum Home > Plugin Cafe > SDK Help
  New Posts New Posts
  FAQ FAQ  Forum Search   Register Register  Login Login

Polygon Position

 Post Reply Post Reply Page  123>
Author
Message
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Topic: Polygon Position
    Posted: 2010 Feb 21 at 5:47am

User Information:

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

---------

How do I determine the vector positions of the points that make up a given polygon?

~Shawn
Back to Top
c4dJack View Drop Down
Member
Member
Avatar

Joined: 2007 Jul 13
Location: Turkey
Online Status: Offline
Posts: 454
Post Options Post Options   Quote c4dJack Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 21 at 6:00am
Have a look into const CPolygon* PolygonObject::GetPolygonR(void). It gives you an array of all polygons (CPolygon). Each Polygon contains the point indexes of the points it's made from.
Then use const Vector* PointObject::GetPointR(void) to get an array with all points contained in the object. To do your calculation, use the point indexes you got from the CPolygon.

Cheers,
Jack
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 21 at 6:03am
Thanks Jack,   I appreciate your response.

~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 21 at 12:23pm
So here's what I have so far.


    LONG lngPolygonCount = objPoly->GetPolygonCount();
    LONG lngPointCount = objPoly->GetPointCount();
    const CPolygon * selectedPoly = objPoly->GetPolygonR();
    const Vector* points = objPoly->GetPointR();
    LONG lngI;

 for (lngI=0; lngI < lngPolygonCount; lngI++)
                    {
                        if (bsPoly->IsSelected(lngI))
                        {
                            GePrint ("First Polygon " + LongToString(lngI) + " is selected.");
                            lngA = selectedPoly[lngI].a;
                            lngB = selectedPoly[lngI].b;
                            lngC = selectedPoly[lngI].c;
                            lngD = selectedPoly[lngI].d;
                           
                        }
                    }




this gives me the index for each of the points...  

so now would I do something like this....?

Vector pointLocation = Vector(points[lngA].x,points[lngA].y,points[lngA].z);



Edited by emberintherain - 2010 Feb 21 at 12:24pm
Back to Top
c4dJack View Drop Down
Member
Member
Avatar

Joined: 2007 Jul 13
Location: Turkey
Online Status: Offline
Posts: 454
Post Options Post Options   Quote c4dJack Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 22 at 5:46am
What you do now depends on what you consider to be the "polygon's position". Is it a position centered between the polygon's points? In that case, add the positions of points a, b and c, then divide by 3.0. If it's not only a triangle but a quad (check if point c == d to find out about that), add a, b, c and d, then divide by 4.0.

Or is it the centered (or otherwise weighted) position on a triangle face? Then use barycentric coordinates (AFAIK this does only work with triangles).

Vector pointLocation = Vector(points[lngA].x,points[lngA].y,points[lngA].z);

This is not necessary. Since the points are stored as vectors (point positions) the following is sufficient: Vector pointLocation = points[lngA];

Cheers,
Jack

Edited by c4dJack - 2010 Feb 22 at 5:51am
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 22 at 5:53am
Thanks Jack,  that helps a lot.  I think I've got it figured out thanks!

Cheers,
~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 22 at 4:05pm
Is it possible to get the rotation of a a particular polygon?

~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 22 at 5:28pm
or better yet,   how would I align my first object to the normal of the polygon that is selected?


~Shawn
Back to Top
Matthias Bober View Drop Down
Forum Moderator
Forum Moderator


Joined: 2006 Oct 16
Location: Germany
Online Status: Offline
Posts: 1647
Post Options Post Options   Quote Matthias Bober Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 23 at 2:38am
What you want to do is not clearly defined. Basically you have to create a rotation matrix for the polygon. For this you need at least two vectors. One is the normal, the other one has to be defined by you. For instance you could choose the vector pointing from the polygon's midpoint to its first vertex. Or you choose a global vector.

cheers,
Matthias

MAXON
developer support
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 23 at 2:54am
I want to move one object and have it sit on the polygon of another object and have it rotate to the normal of that polygon so that the object is sitting flush with that polygon.   SO I will need the center between all of the points of that polygon (which I have) and a point in space that points directly outward from that polygon?  There is no function in the sdk that provides the normal of a polygon? 

so the vector from the center to the first point would create a plane upon which I could determine rotation?

how would I get that?

Here's how I determine the center of the polygon


                            //Caclulate the polygon position.
                            if (selectedPoly[lngI].c == selectedPoly[lngI].d)
                            {
                                polyLocation = (points[lngA] + points[lngB] + points[lngC]) / 3; //Polygon is a Triangle
                               
                            }
                            else
                            {
                                polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4; //Polygon is not a Triangle
                            }


 
how would I set up the rotation matrix with this info if points[lngA]  is the first point of the polygon?

Thanks,

~SHawn



Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 23 at 3:44pm
Okay so I want to set up a rotation matrix for the selected polygon.  do I do this by mulitplying the vector of one point by the vector of a second point in the polygon?  

~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 23 at 3:49pm
Here's what I have so far......



C4DObjectList * objList = C4DObjectList::Alloc();
    if (!objList) return FALSE;
   
    //DECLARATIONS & DEFINITIONS
    if (!doc) return FALSE;

    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 lngPolygonCount = objPoly->GetPolygonCount();
    LONG lngPointCount = objPoly->GetPointCount();
    const CPolygon * selectedPoly = objPoly->GetPolygonR();
    const Vector * points = objPoly->GetPointR();
    LONG lngI;

    Matrix opMatrix  = op->GetMg();
   
   
    switch (lngEditorMode)
    {    
        //POLYGONS MODE   
        case Mpolygons:
        {
            if(vpPoly)
            {
                //FIRST SELECTION
                if (secondSelection == FALSE)
                {
                    bsPoly->DeselectAll();
                    bsPoly->Select(vpPoly->i);
                    firstSelection = vpPoly->op;
                    secondSelection = TRUE;
                }

                //SECOND SELECTION
                else if (secondSelection == TRUE)
                {
                    bsPoly->DeselectAll();
                    bsPoly->Select(vpPoly->i);
                   
                    for (lngI=0; lngI < lngPolygonCount; lngI++)
                    {
                        if (bsPoly->IsSelected(lngI))
                        {
                            lngA = selectedPoly[lngI].a;
                            lngB = selectedPoly[lngI].b;
                            lngC = selectedPoly[lngI].c;
                            lngD = selectedPoly[lngI].d;
                           
                            //Caclulate the polygon position.
                            if (selectedPoly[lngI].c == selectedPoly[lngI].d)
                            {
                                polyLocation = (points[lngA] + points[lngB] + points[lngC]) / 3; //Polygon is a Triangle
                               
                            }
                            else
                            {
                                polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4; //Polygon is not a Triangle
                            }

                            //Align 1st Selection to the polygon of 2nd Selection (X AXIS)
                            if (polyLocation.x > 0)
                            {
                                firstSelection->SetPos(op->GetPos() + polyLocation + Vector(firstSelection->GetRad().x,0,0));
                                firstSelection->SetRot(CalcFaceNormal(points,selectedPoly[lngI]) * opMatrix);
                               
                            }

                            if (polyLocation.x < 0)
                            {
                                firstSelection->SetPos(op->GetPos() + polyLocation - Vector(firstSelection->GetRad().x,0,0));
                                firstSelection->SetRot(CalcFaceNormal(points,selectedPoly[lngI]) * opMatrix);
                               
                            }

                            //Align 1st Selection to the polygon of 2nd Selection (Y AXIS)
                            if (polyLocation.y > 0)
                            {
                                firstSelection->SetPos(op->GetPos() + polyLocation + Vector(0,firstSelection->GetRad().y,0));
                                firstSelection->SetRot(op->GetRot());
                            }

                            if (polyLocation.y < 0)
                            {
                                firstSelection->SetPos(op->GetPos() + polyLocation - Vector(0,firstSelection->GetRad().y,0));
                                firstSelection->SetRot(op->GetRot());
                            }

                            //Align 1st Selection to the polygon of 2nd Selection (Z AXIS)
                            if (polyLocation.z > 0)
                            {
                                firstSelection->SetPos(op->GetPos() + polyLocation + Vector(0,0,firstSelection->GetRad().z));
                                firstSelection->SetRot(op->GetRot());
                            }

                            if (polyLocation.z < 0)
                            {
                                firstSelection->SetPos(op->GetPos() + polyLocation - Vector(0,0,firstSelection->GetRad().z));
                                firstSelection->SetRot(op->GetRot());
                            }

                           
                            bsPoly->DeselectAll();   
                        }
                    }
                    secondSelection = FALSE;   
                }
       
                EventAdd(EVENT_FORCEREDRAW);
                op->Message(MSG_CHANGE);
                DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);
            }


I am trying to get (firstSelection) to rotate to the normal of the selected polygon on (op).    I am using CalcFaceNormal() but that seems to return incorrect results.  Does anyone know how I could get this to rotate properly?

Thanks,

~SHawn



Edited by emberintherain - 2010 Feb 23 at 4:34pm
Back to Top
Matthias Bober View Drop Down
Forum Moderator
Forum Moderator


Joined: 2006 Oct 16
Location: Germany
Online Status: Offline
Posts: 1647
Post Options Post Options   Quote Matthias Bober Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 24 at 2:43am
I recommend to read up on Vector and Matrix arithmetics.

http://www.flipcode.com/documents/matrfaq.html

Also the CINEMA 4D R9.5 COFFEE documentation has a very good tutorial on using matrices.

Especially vector cross products are essential to build your own cutom rotation matrices.

I can not debug or write your plugin, sorry.

cheers,
Matthias

MAXON
developer support
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 24 at 2:48am
Thanks for the link Matthias.   LOL...  I don't want you to write it for me.   Where's the fun in that.   :)

~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 24 at 7:31am
Great tutorial on Matrices.  Thanks for that.

~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 25 at 3:47am
Is there a c++ equivalent to the function you mention in the tutorial GetMulP()?

or would I just use

firstSelection->SetPos(opMatrix * points[lngA]);

first selection being my object,  and points[lngA] being the vector location of the point I am trying to move the object to. 

Thanks,

~Shawn
Back to Top
Matthias Bober View Drop Down
Forum Moderator
Forum Moderator


Joined: 2006 Oct 16
Location: Germany
Online Status: Offline
Posts: 1647
Post Options Post Options   Quote Matthias Bober Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 25 at 5:47am
Yes, multiplying a vector with a matrix transforms the vector into the matix' space.

The Matrix class has several overloaded operators for matrix-matrix and matrix-vector arithmetics.

cheers,
Matthias

MAXON
developer support
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Feb 26 at 9:38am
Okay... SO I think I kindof understand a rotation matrix now.   I need to find the vector from the center of the polygon which I did with


polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4;


This gives me a vector that represents the very center of the polygon

Then I need another point along the same plane which I use points[lngA].  This is the first point in the polygon.

So mathematically that gives me A & B.   Assuming my equation is C = A x B.     So to get the point which represents the Z axis or the point hovering directly above the polygon face, I simply multiply


Vector rotC =  polyLocation * points[lngA];


And this should give me my rotation matrix correct?   

So now my question is how do I then rotate my object to match that  rotation matrix?  Here is what I am trying. 


    //ROTATION MATRIX
                               
                                //GetPoints
                                Vector p1 = polyLocation;
                                Vector p2 = points[lngA];
                               
                                //Contruct Matrix
                                Matrix rotMatrix;

                                rotMatrix.off = p1; //The base of the matrix
                                rotMatrix.v1 = !(p2 - p1); //X axis points toward the second point
                                rotMatrix.v2 = !(p2-p1%Vector(0,1,0)); //Y Axis is perpendicular to the X axis
                                rotMatrix.v3 = rotMatrix.v1 * rotMatrix.v2;

                                Vector scale = Vector(Len(rotMatrix.v1), Len(rotMatrix.v2), Len(rotMatrix.v3)); //Get Scale
                                Vector pos = rotMatrix.off; ///Get the Position
                               
                                //Create a vector which contains the rotation matrix.
                                Vector rot1 = MatrixToHPB(rotMatrix);


                                firstSelection->SetPos(opMatrix * polyLocation);
                                firstSelection->SetRot((rot1));   



Please let me know if I am way off base here and am going about this completely wrong so that I know not to continue in this way.    Thanks lot for your help.

Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Mar 01 at 6:22am
Thanks for all your help Jack.  I have officially filled up your PM box.   I didn't notice that what you sent me was different.  Thanks for that.

~Shawn
Back to Top
emberintherain View Drop Down
Member
Member
Avatar

Joined: 2008 Dec 23
Location: United States
Online Status: Offline
Posts: 487
Post Options Post Options   Quote emberintherain Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Mar 03 at 5:15pm
Hey folks.  So I believe that I have created the rotation matrix correctly.  And when I click the polygon on the second object the object moves to that polygon correctly, however it does not rotate correctly.  Sometimes it rotates a bit but not the way it should.  I want the firstSelection object to rotate so that it is sitting flush with the polygon no matter what the rotation of the polygon is.    Does anyone see any reason in the following code why this wouldn't be happening?   

Any help would be greatly appreciated.  This one's a bit frustrating.

for (lngI=0; lngI < lngPolygonCount; lngI++)
                    {
                        if (bsPoly->IsSelected(lngI))
                        {
                            lngA = selectedPoly[lngI].a;
                            lngB = selectedPoly[lngI].b;
                            lngC = selectedPoly[lngI].c;
                            lngD = selectedPoly[lngI].d;
//Caclulate the polygon position.
if (selectedPoly[lngI].c == selectedPoly[lngI].d) 
{
polyLocation = (points[lngA] + points[lngB] + points[lngC]) / 3; //Polygon is a Triangle
}
else
{
polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4; //Polygon is not a Triangle
}

//Align 1st Selection to the polygon of 2nd Selection (X AXIS)
if (polyLocation.x > 0)
{
//ROTATION MATRIX
//GetPoints
Vector p1 = polyLocation; 
Vector p2 = points[lngA];
Vector scale = Vector(Len(opMatrix.v1), Len(opMatrix.v2), Len(opMatrix.v3)); //Get Scale
//Contruct Matrix
Matrix rotMatrix;

rotMatrix.off = p1; //The base of the matrix
rotMatrix.v3 = !(p1); //Z Axis is along the normal
rotMatrix.v1 = !(p2 - p1); //X axis points toward the second point
rotMatrix.v2 = rotMatrix.v1%rotMatrix.v3;//Y Axis is perpendicular to the X axis
rotMatrix.v1 = !(rotMatrix.v3%rotMatrix.v2);//recreated second axis..   using cross product.
rotMatrix.v1 = !(rotMatrix.v1 * scale.x);
rotMatrix.v2 = !(rotMatrix.v2 * scale.y);
rotMatrix.v3 = !(rotMatrix.v3 * scale.z);
Vector rot1 = MatrixToHPB(rotMatrix);
firstSelection->SetMg(rotMatrix);
firstSelection->SetPos((opMatrix * polyLocation) + firstSelection->GetRad().x);
//firstSelection->SetRot(rot1);
}


Back to Top
 Post Reply Post Reply Page  123>

Forum Jump Forum Permissions View Drop Down

Bulletin Board Software by Web Wiz Forums® version 9.61 [Free Express Edition]
Copyright ©2001-2009 Web Wiz

This page was generated in 0.141 seconds.