SetPoint() in C++ Question



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

    On 25/05/2012 at 14:10, xxxxxxxx wrote:

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

    ---------
    This is very strange.

    I have never used SetPoint() in C++. And I wanted to try it out.
    So I converted a small python script into C++ that aligns a child's axis to the parent's axis. Without rotating the child object (A.K.A- it puts the points back where they were after the rotation).
    But I get different results even though they are identical(AFAIK).

    Python version:

    import c4d  
    from c4d import utils  
      
    def main() :  
      obj = doc.GetActiveObject()   
            
      doc.StartUndo()      
      
      oldm   = obj.GetMg()  
      points = obj.GetAllPoints()  
      pcount = obj.GetPointCount()  
      
      doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)   
      obj.SetAbsRot(c4d.Vector(0))  
      obj.Message(c4d.MSG_UPDATE)  
      newm = obj.GetMg()  
      
      for i in xrange(pcount) :  
          obj.SetPoint(i,~newm*oldm*points[i]) #Set the points back where they were  
      
          obj.Message(c4d.MSG_UPDATE)  
        
      c4d.EventAdd()  
      doc.EndUndo()  
      
    if __name__=='__main__':  
      main()
    

    C++ version :

        BaseObject *obj = doc->GetActiveObject();  
      PointObject *pobj = ToPoint(obj);            //Cast the BaseObject type to a PointObject type and assign it to a variable "pobj"  
      doc->StartUndo();      
      
      Matrix oldm = pobj->GetMg();                //Get and hold the matrix current state before we change it later  
      Vector *points = pobj->GetPointW();         //Get all the object's points before we rotate the object  
      LONG count = pobj->GetPointCount();         //Get the number of total points  
      
      doc->AddUndo(UNDOTYPE_CHANGE, pobj);   
      pobj->SetAbsRot(Vector(0));                 //Rotate the object(also rotates the matrix)  
      pobj->Message(MSG_UPDATE);  
      
      Matrix newm = pobj->GetMg();                //Store the matrix new state values  
      
      AutoAlloc<Modeling> mod;                    //Create an instance of the Modeling class so we can use the SetPoint() function  
      mod->InitObject(pobj);  
      
      for(LONG i=0; i<count; i++)  
      {   
          mod->SetPoint(pobj, i, (!newm*oldm)*points[i], MODELING_SETPOINT_FLAG_EMPTY); //Set the points back where they were before pobj was rotated  
      }  
      
      pobj->Message(MSG_UPDATE);          //Update the changes
    

    The python version works as expected. But the C++ version rotates the object as well as the axis. In other words. The SetPoint() part of the C++ code where it's supposed to set the points back to where they originally were. Does not seem to be working properly. And I'm stumped why this isn't working.

    I know I'm missing something stupid. But I can't see it.
    What am I doing wrong?

    -ScottA



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

    On 25/05/2012 at 16:13, xxxxxxxx wrote:

    As long as I can remember, the points are always in their default positions when retrieved in C++ (GetPoint()).  You must apply the matrix to put them into their transformed positions.  It is possible that GetAllPoints() in Python is already doing this so you are seeing different results between Python and C++.  Also, why are you using Modeling to modify the points?  You can modify them directly:
    _

    points_ _ _[i] = (!newm*oldm)*points_ _ _[i];
    

    Since you retrieved a pointer to the point array, they are updated in place.  It would also be more efficient to calculate the new matrix once outside of the loop and use that instead of doing the matrix inversion and multiplication for every point calculation:_ _

    Matrix tmtx = (!newm * oldm);  
    for (LONG i = 0L; i != count; ++i)  
    {  
      points[i]_ _ _= points_ _ _[i] * tmtx;  
    }
    

    _




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

    On 25/05/2012 at 17:25, xxxxxxxx wrote:

    That's cool Robert. Thanks.
    I'm always looking for new ways to handle matrices. That will probably come in handy.

    But I still really need to know why SetPoint() isn't working in my example.
    As a matter of fact. I don't think I've ever used any of the functions in the Modeling class before. So I'd really like to know how to use it.

    I looked through the archives. But every instance of SetPoint() I find is related to coffee.

    -ScottA



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

    On 25/05/2012 at 22:21, xxxxxxxx wrote:

    I think I've got it figured out.
    Since there's nothing in the archives on SetPoint() for C++. I'll post this simple example:

    //This example will get selected points on an object   
    //And if the selected point happens to be index #4 it will move the point to a new location   
      
      BaseObject *obj = doc->GetActiveObject();      
      PointObject *pobj = ToPoint(obj);            //Cast the BaseObject type to a PointObject type and assign it to a variable "pobj"  
      Vector *points = pobj->GetPointW();  
      LONG pointCount = pobj->GetPointCount();  
      BaseSelect *bs = pobj->GetPointS();  
      
      AutoAlloc<Modeling> mod;  
      mod->InitObject(pobj);  
                
      for (int i = 0; i < pointCount; i++)  
      {  
        if (bs->IsSelected(i))  
        {   
          LONG selected = i;  
          GePrint(LongToString(i));  
          Vector p = pobj->GetPointW()[i];   //Get the selected points  
          GePrint("PosX:"+RealToString(p.x) + " PosY:"+RealToString(p.y) + " PosZ:"+RealToString(p.z)); //Print their positions  
      
          if(selected == 4)  
          {  
             Vector newpos = Vector(0,200,0);  
             Vector p2 = mod->SetPoint(pobj, 4, newpos, MODELING_SETPOINT_FLAG_EMPTY);//Set point index #4 to the new location  
          }  
        }              
      }  
      
      mod->Commit(pobj, MODELING_COMMIT_NO_NGONS , NULL);
    

    -ScottA



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

    On 28/05/2012 at 00:52, xxxxxxxx wrote:

    Hi,

    In C++ we usually use low level methods like PolygonObject::GetPointW(), PolygonObject::GetPolygonW() etc. (They are used a lot in the SDK examples.)
    A writeable points or polygons array is returned and can modified like the code Robert posted.



  • On 25/06/2015 at 05:14, xxxxxxxx wrote:

    Hi,

    Adding to your question, how can one get the pointarray of multiple selected objects?
    Should I store them in one array, en apply a transformation on them in that array?

    This is what I have now: https://plugincafe.maxon.net/topic/8876/11733_set-position-selected-point-in-pointobject-array

    Thanks in advance for your help and time!
    Greetings,
    Casimir Smets


Log in to reply