counterpart of GetPointIndex ?

On 09/11/2013 at 11:07, xxxxxxxx wrote:

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

---------
Hi there,

i'd like to get the position along a spline for a specific point. looks like i need the counterpart for GetPointIndex. is there a function for this?

On 10/11/2013 at 03:09, xxxxxxxx wrote:

Hi ello,

this question was asked quite recently in the Python forum.

https://plugincafe.maxon.net/topic/7511/9397_percentage-offsets-of-interpolation-points

Best,
-Niklas

On 11/11/2013 at 03:55, xxxxxxxx wrote:

thank you :)

On 13/11/2013 at 11:53, xxxxxxxx wrote:

Hey, i need to get back on this as i am having problems using it. how can i get the spline position?

LONG *seg;
LONG *ind;
Real *offset;
baseSplineHelp->GetSplinePointSegment(i,offset,ind,seg);

but, how do i access the offset now? when i try to GePrint it i get an error "cannot convert parameter 1 from 'LReal *' to 'LReal'" for obvious reason, but the question is where is the accessible offset for me?

aside from this, i guess i am doing it wrong anyway. is there any example on how to get the offset for point x on a spline?

On 13/11/2013 at 14:36, xxxxxxxx wrote:

When you see pointers used in SDK functions like this: void GetSplinePointSegment(LONG index, Real* offset, LONG* ind, LONG* segment).
It means that those parameters are placeholder pointer references to variables that will get filled in with data by the function.

Like this:

  
LONG seg;  
LONG ind;  
Real offset;  
baseSplineHelp->GetSplinePointSegment(i, &offset, &ind, &seg);

This is a somewhat common technique used throughout in the C4d C++ SDK.
Where you first create some empty variables....Then you execute a function that has these same variables in it's parameters. Which are pointing to the variables, and then assigning values to them.

You gotta love this C++ pointer stuff. :wink:

-ScottA

On 13/11/2013 at 23:08, xxxxxxxx wrote:

ah, thank you! just didn't know that * and & stuff was the same. already use the &

On 14/11/2013 at 03:47, xxxxxxxx wrote:

ok, still got a message. when i have for example a spline with three points (-100,0,0) / (0,0,0) / (100,0,0) i thought that the offset for the second point would be 0.5, but it is actually 0.333
why??

  
AutoAlloc <SplineHelp> splineHelp;  
if (!splineHelp) return false;  
splineHelp->InitSpline(spline,Vector(0),0,0,1,1,0);  
  
LONG seg;  
LONG ind;  
Real offset;  
splineHelp->GetSplinePointSegment(i, &offset, &ind, &seg);  
GePrint(RealToString(offset));  

On 14/11/2013 at 09:17, xxxxxxxx wrote:

I've only briefly explored the spline classes myself. So I'm not sure if any of this code will help or not.

This is the code from a tag plugin I wrote that moves an object along a spline :

//This tag plugin works similar to the Align-to-Spline tag in C4D  
//Except my tag gets put on a spline object. And the object traveling along it gets dropped into the tag's linkfield  
  
EXECUTIONRESULT MyTag::Execute(BaseTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, EXECUTIONFLAGS flags)  
{      
  BaseContainer *tagdata = tag->GetDataInstance();   //Get the data in the tag and assign it to a variable  
  
  BaseObject *obj = tag->GetObject();                //Get the object the tag is on  
  if (!obj) return EXECUTIONRESULT_USERBREAK;  
  
  //Only work if the object the tag is on is a spline type (all types of splines)  
  if(!obj->GetInfo()&OBJECT_ISSPLINE) return EXECUTIONRESULT_USERBREAK;  
  
  //I used a linkfield gizmo to store the object that will move along the spline   
  BaseObject *target = tagdata->GetObjectLink(MY_LINK,doc);   
  
  if(target) //If the linkfield is not empty  
  {  
      //Gets the position of the object in the link field  
      Vector position = target->GetRelPos();  
        
      //Convert the object the tag is on to a spline type  
      SplineObject *myspline = ToSpline(obj);  
  
      SplineLengthData *sld = SplineLengthData::Alloc();  
      sld->Init(myspline, 0, NULL);  
      if (!sld) return EXECUTIONRESULT_USERBREAK;  
  
      SplineHelp *sh = SplineHelp::Alloc();  
      if (!sh) return EXECUTIONRESULT_USERBREAK;  
      sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);  
  
      LONG segment = 0;                                      //NOTE:If the spline is a Primitive...only segment 0 works  
      Real PosOnSpline = tag->GetData().GetReal(MYNUMERIC);  //The position the object is along the spline's segment   
      Vector splinepos = sh->GetPosition(PosOnSpline, segment, TRUE);  
      sh->FreeSpline();  
    
      target->SetRelPos(Vector(splinepos.x,splinepos.y,splinepos.z));  //Moves the object along the spline  
      target->Message(MSG_UPDATE);  
  }  
  
  return EXECUTIONRESULT_OK;  
}

These are a few examples that I've created in my notes about how to use some of the various spline functions in the SDK:

  
//This code gets the global position of a spline's point + an offset value  
  
  BaseObject *obj = doc->GetActiveObject();  
  if (!obj) return FALSE;  
  
  SplineObject *myspline = ToSpline(obj);  
  SplineLengthData *sld = SplineLengthData::Alloc();  
  sld->Init(myspline,0,NULL);  
  if (!sld) return FALSE;  
  
  SplineHelp *sh = SplineHelp::Alloc();  
  if (!sh) return FALSE;  
  sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);  
  
  Real offsetValue = 10.5;  
  Real offset = sh->GetOffsetFromUnit(offsetValue, 0);  
  //Real offset = sh->GetOffsetFromReal(offsetValue, 0);  
  
  //Get the global position of the first spline point + the offset  
  Vector p0 = sh->GetPosition(offset,0,TRUE,TRUE);  
  //Vector p0 = sh->GetPosition(sld->UniformToNatural(offset), 0, TRUE, TRUE);  
  GePrint(RealToString(p0.x));  
  
  
  
  
  
  
  
//This code gets the offset, and segment values for the points in a selected spline object  
//It calculates the distance the "offset" variable is from the first spline point  
//NOTE: The offset values never change no matter where the points are placed(results are local..not global)  
//      Example: offset = 0.5; is always the middle of the spline. No matter how the spline looks  
  
  BaseObject *obj = doc->GetActiveObject();             //The active object should be a spline object  
  if (!obj) return FALSE;  
  
  SplineObject *myspline = ToSpline(obj);               //Convert the type to a spline type so we can work on it  
  
  //Create the SplineHelp class for the spline so we can use it's methods  
  SplineHelp *sh = SplineHelp::Alloc();  
  if (!sh) return FALSE;  
  sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);  
    
  Real offset = 0.5;   //The position along the spline. The range is: 0.0 - 1.0  
  
  //The values for these 2 variables are filled in by the GlobalToLocal() function  
  Real off;      //This value will match the value set with the "offset" variable above  
  LONG segment;  
  sh->GlobalToLocal(offset, &off, &segment, FALSE);  
  GePrint("offset: " + RealToString(off) + " " + "segment: " + LongToString(segment));  
  
  
  
  
  
  
//This code gets the index, offset, and segment values for the points in a selected spline object  
//The code calculates results based upon how many points in the spline. In relation to how long the spline length is  
//It calculates the offset distance each point is from the first spline point  
//NOTE: The offset values never change no matter where the points are placed(results are local..not global)  
  
  
  BaseObject *obj = doc->GetActiveObject();             //The active object should be a spline object  
  if (!obj) return FALSE;  
  
  SplineObject *myspline = ToSpline(obj);               //Convert the type to a spline type so we can work on it  
  
  //Create the SplineHelp class for the spline so we can use it's methods  
  SplineHelp *sh = SplineHelp::Alloc();  
  if (!sh) return FALSE;  
  sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);  
  
  LONG count = myspline->GetPointCount();  
  for(LONG i=0; i<count; i++)  
  {  
      LONG index = i;       //Check each of the spline's index points  
  
      //The values for these 3 variables are filled in by the GetSplinePointSegment() function  
      LONG ind;  
      Real offset;  
      LONG segment;  
      sh->GetSplinePointSegment(index, &offset, &ind, &segment);  
      GePrint("index: " + LongToString(ind) + " " + "offset: " + RealToString(offset) + " " + "segment: " + LongToString(segment));   
  }  
  

Maybe the code in these examples will help you.

-ScottA

On 14/11/2013 at 12:12, xxxxxxxx wrote:

thank you very much for those. much appreciated. still, i am not able to get the desired results. 0.333 is not what i think should be returned in my test-case. hopefully someone has an idea. in the end i want to get the position of points around a spline point at a certain distance (e.g. 0.01 left and right from the spline point)...