View Full Version : How do I append Strings in COFFEE?
Scott Ayers 10-18-2009, 11:53 PM Help please,
I can't seem to figure out how to incrementally append strings.
I'm assuming that the way to do this is by using a for loop?
Here's a script that creates clones of a parent sphere.
It works. But the part I'm having trouble with is adding incremental numbers to the clone's names after they get created.
main(doc,op)
{
var sphere = doc->FindObject("ParentSphere");// Look for this object
if ( !sphere ) // if not found
{
println( "Parent sphere not found" );// print this error to the console
return;
}
var NewNull = doc->FindObject("Clones"); //Find object named Clones
if( !NewNull ) //if the object called Clonces doesn't exist
{
NewNull = new(NullObject); // Create a new Null
NewNull->SetName("Clones");// Name it Clones
doc->InsertObject( NewNull, NULL, NULL );//Insert it into the OM
}
var NewSphere = sphere->GetClone(0);// Make a clone of the parent sphere
for(i=0; NewSphere++)
{
Here's where I'm lost and need help
}
NewSphere->SetName("Sphere" + tostring(i));
doc->InsertObject(NewSphere, NewNull, NULL); //insert the clones under the NewNull named "Clones"
}
Can anyone help me out?
-ScottA
|
|
Hi,
you append strings in COFFEE with stradd(). You can cast an integer or float to string with tostring(); So for example:
var name = op->GetName();
var number = 10;
var name = stradd(name, ".", tostring(number));
op->SetName(name);
That gives:
a sphere called sphere will then be called sphere.10
cheers mnu
You can use "+" to append strings, it's overloaded. I don't think that was what Scott was asking about. Have a look at this script, hopefully it will be helpful.
main(doc,op)
{
var clone_cnt = 5;// Number of Clones
var sphere = doc->FindObject("ParentSphere"); // Look for this object
var temp;
if ( !sphere ) // if not found
{
println( "Parent sphere not found" );// print this error to the console
return;
}
var NewNull = new(NullObject); // Create a new Null
NewNull->SetName("Clones");// Name it Clones
doc->InsertObject( NewNull, NULL, NULL );//Insert it into the OM
var NewSphere = sphere->GetClone(0);// Make a clone of the parent sphere
var i = 0;
for(i=0; i<clone_cnt; i++)
{
var NewSphere = sphere->GetClone(0);// Make a clone of the parent sphere
NewSphere->SetName("Sphere." + tostring(i));
if(!NewNull->GetDown())
{
doc->InsertObject(NewSphere, NewNull, NULL); //insert the clones under the NewNull named "Clones"
EventAdd();
temp = NewNull->GetDown(); // Get first child of "clones" (the inserted object)
}
else
{
NewSphere->InsertAfter(temp); //insert the clone under the last child of "Clones"
EventAdd();
temp = temp->GetNext();
}
}
}
Scott Ayers
10-20-2009, 06:31 PM
Thanks for the replies.
Right off the bat I see that I forgot to declare a variable for "i" in my example. Doh!:blush:
But I guess I didn't describe what I'm trying to do clearly.
Instead of generating a set number of clones and incrementally numbering them all in one step.
I'm trying to generate a single clone (Which I can do) when the script is run for the first time. Then when the script is run again. It generates and inserts another clone under the same Clones Null (I can do that too). Then lastly. It will look at the previous clone's number and add +1 to it.
That last part is where I'm stuck.
In the SDK it says that a checknames Bool option can be applied to an InsertObject(); function:
InsertObject(BaseObject* op, BaseObject* parent, BaseObject* pred, Bool checknames = TRUE)
But it's too vague for me to understand without seeing an example.
Without knowing how that works. I don't know if it will solve my problem or not.
Ah. The way this script is set up the first child must have a number appended to its name but hopefully it's enough info to get you on your way if you don't want this behaviour.
main(doc,op)
{
var sphere = doc->FindObject("ParentSphere");// Look for this object
if ( !sphere ) // if not found
{
println( "Parent sphere not found" );// print this error to the console
return;
}
var NewNull = doc->FindObject("Clones"); //Find object named Clones
if( !NewNull ) //if the object called Clonces doesn't exist
{
NewNull = new(NullObject); // Create a new Null
NewNull->SetName("Clones");// Name it Clones
doc->InsertObject( NewNull, NULL, NULL );//Insert it into the OM
}
// increment number
var child ;
var name;
var str;
if(NewNull->GetDown())
{
child = NewNull->GetDown();
str = child->GetName();
var i;
var pos = 0;
for(i=0; i<sizeof(str); i++) // find position of first digit
{
if(isdigit(str[i]))
{
pos = i;
break;
}
}
if(pos)
{
var length = sizeof(str) - pos; // length of numeric portion of str
var numberstr = strmid(str, pos, length); // create string of numeric portion
var newnumb = int(evaluate(numberstr)) + 1; // convert numberstr to int, add 1
var newstr = new(string,pos);
for(i = 0; i<pos; i++) // copy alpha portion of str to newstr
{
newstr[i]= str[i];
}
str = stradd(newstr, tostring(newnumb)); //add alpha and numeric strings
}
}
else
str = "Sphere.1";
///////////////////////////////
var NewSphere = sphere->GetClone(0);// Make a clone of the parent sphere
NewSphere->SetName(str);
doc->InsertObject(NewSphere, NewNull, NULL); //insert the clones under the NewNull named "Clones"
}
What version of C4D are you using? If your using R11.5 c4d will automatically increment the numbers depending upon object type and hierarchy.
Scott Ayers
10-21-2009, 05:11 PM
That's fantastic JDP.
Thank you.
Oh Boy. There's a whole bunch of things happening in there to make this happen.
It's too bad that there isn't a shorter way to do this.
I downloaded the 11.5 Demo. But I haven't had time to play around with it.
-ScottA
Your welcome Scott. Yeah there's a bit going on and I made assumptions that the name would always be of the same format, did no real error checking etc., etc. I couldn't find any reference to a checknames Bool option in the sdk, what version are you using?
Scott Ayers
10-22-2009, 06:56 PM
I'm using both the 9.6 and the 10.5 SDK for researching COFFEE structure. Because they contain slightly different things.
The Bool checknames is listed under the InsertObject(BaseDocument) header.
The MAXON SDK's are impossible for the average person like me to use for learning how to use the various COFFEE functions.
They're written by a person who already knows COFFEE.
And if you're new to COFFEE. An SDK entry like this isn't going to help you learn it:
void InsertObject(BaseObject (file:///C:/Users/user/Desktop/tutorials/COFFEE%20&%20scripts%20examples/COFFEE%20SDK/C4DR105SDKHTML/pages/c4d_baseobject/class_BaseObject55.html)* op, BaseObject (file:///C:/Users/user/Desktop/tutorials/COFFEE%20&%20scripts%20examples/COFFEE%20SDK/C4DR105SDKHTML/pages/c4d_baseobject/class_BaseObject55.html)* parent, BaseObject (file:///C:/Users/user/Desktop/tutorials/COFFEE%20&%20scripts%20examples/COFFEE%20SDK/C4DR105SDKHTML/pages/c4d_baseobject/class_BaseObject55.html)* pred, Bool checknames = TRUE)
I'm in the process of decoding the SDK's into something more understandable.
But it's slow going because the SDK's are utter jibberish to me. So I'm using examples from people all over the internet to use as a way to re-write them into an SDK that the common person can learn from.
I've included a copy of your script in it. I hope you don't mind.
-ScottA
I don't mind at all. It occurred to me today while waiting for a render, just popped into my head, that there is an easier solution for your problem. If we know the clones hierarchy will always be the same why not just count the number of NewNulls children. Obvious really, and probably along the lines of what you were thinking. :banghead:
main(doc,op)
{
var sphere = doc->FindObject("ParentSphere");// Look for this object
if ( !sphere ) // if not found
{
println( "Parent sphere not found" );// print this error to the console
return;
}
var NewNull = doc->FindObject("Clones"); //Find object named Clones
if( !NewNull ) //if the object called Clonces doesn't exist
{
NewNull = new(NullObject); // Create a new Null
NewNull->SetName("Clones");// Name it Clones
doc->InsertObject( NewNull, NULL, NULL );//Insert it into the OM
}
// increment number
var child;
var i = 0;
if(NewNull->GetDown())
{
child = NewNull->GetDown();
i++;
while(child->GetNext())
{
child = child->GetNext();
i++;
}
}
///////////////////////////////
var str = stradd("Sphere.", tostring(i));
var NewSphere = sphere->GetClone(0);// Make a clone of the parent sphere
NewSphere->SetName(str);
doc->InsertObject(NewSphere, NewNull, NULL);
}
Scott Ayers
10-22-2009, 10:15 PM
That looks much nicer.:bowdown:
I had tried something like that myself before posting here. But I was having a problem with conflicting data types.
But I wasn't using the "stradd" option. So That might have been why.
Thanks for the help.
-ScottA
CGTalk Moderation
10-22-2009, 10:15 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.