Start a new topic

One Click Button for Adding Group Beads On Externals.

Original Post by: Wed Dec 3 21:11:46 2014


Hi,


I want to ask something regarding External references. I find it really difficult to add Group Beads to external files. Like if I converted 10 models to external references, now i want each externals to be under individual Group beads, also those group beads should have the same name of the external referenced file. I thought about adding a button to do than in one shot.

In creator we have insert level option but still we have to rename each Group bead matching the name of External file. Is it possible to do? Can you suggest the way or a sample to do that? These are the painful stuffs to do if its only 10 Group beads still manageable to do but if that number increases renaming manually is a hectic task. Is there any way to automate it through a button?


Original Post by: SteveThompson Wed Dec 3 22:17:00 2014


This sounds like it could be automated by a plugin. But frankly I am not sure what you want your tool to do. Would you mind explaining it more concisely?


Thanks.

Original Post by: Fri Dec 5 13:33:04 2014


Yeah sure Steve I'll explain. Suppose I have an external reference node, now its directly under header. What I want is I want that external node to be under a group node and that group node should have the name of the external nodes name, like if the external file name is "Model1.flt" I want that group node also have same name without ".flt" . All thus should happen with the click of a button and it should happen to all external beads if there are more than one (each should have a parent group bead inserted and with their file name).

Original Post by: SteveThompson Fri Dec 5 15:01:00 2014


What I want is I want that external node to be under a group node

Use mgDetach to remove the external reference from the header node. Use mgNewRec to create the new group. Use mgAttach, mgInsert or mgAppend to put the new group in the hierarchy and the x-ref under the group node.


and that group node should have the name of the external nodes name, like if the external file name is “Model1.flt” I want that group node also have same name without “.flt”

Use mgGetAttList with fltXrefFilename to get the xref name. Use mgSetName to set the group name. I'll leave it to you to figure out how to extract the name part without the .flt. Start by looking at the c-runtime string functions to parse the name. Or if you're using C++ the std::string class has all you will need.

All this should happen with the click of a button and it should happen to all external beads if there are more than one (each should have a parent group bead inserted and with their file name).

Of course, there is no single API function to do this ;-) This is a matter of finding all the x-refs (perhaps in a list of some sort) and then processing each x-ref in the list. You might use mgWalk to build the list or you could manually traverse the hierarchy to find the x-refs.


Finally since you are now "editing" the scene, this button really should be inside an Editor plugin. You really should not be modifying the db in any way in Viewer plugins. To understand why this is dangerous, check out volume 2 of the OpenFlight API User/Developer Guide. Read about Editor vs Viewer plugins.


Let us know how you get on and if you have more questions.

Original Post by: Sat Dec 6 04:13:25 2014


Yeah Steve this is a separate plugin which is an editor. Ill try as you said and if I'm finding any difficulty i'll post.Thanks.....

Original Post by: Sun Dec 7 08:32:51 2014


This helped me adding group beads and to insert external reference as child.


static mgbool gbeadApply (mgrec* db, mgrec* parent, mgrec* rec, void* gBead)

{

toolrec* toolRec = (toolrec*)gBead;


if (mgGetCode(rec) == fltXref)

{

parent = mgNewRec(fltGroup);

mgDetach(rec);

mgAttach(db,parent);

mgAppend(parent,rec);

}

return MG_TRUE;

}


Now i want to make the group bead's name to be same as the external flt name. I'm kind of stuck there, Can you please help me in that. This is what i tried with but its applying some weird random characters (àÞ-0&§@)


static mgbool gbeadNApply (mgrec* db, mgrec* parent, mgrec* rec, void* gBead)

{

toolrec* toolRec = (toolrec*)gBead;

if (mgGetCode(rec) == fltXref);

{

char* xName;

parent = mgGetParent(rec);

mgGetAttList(rec,fltXrefFilename,&xName;,MG_NULL);

mgSetName(parent,&xName;);

}

return MG_TRUE;

}

Original Post by: SteveThompson Sun Dec 7 16:45:20 2014


Now i want to make the group bead’s name to be same as the external flt name. I’m kind of stuck there, Can you please help me in that. This is what i tried with but its applying some weird random characters (àÞ-0&§@)

This is easy and a common mistake for new C programmers. Character strings can be a bit tricky.


Look at the reference page for mgSetName. There you will see that the 2nd parameter is declared as const char* name. That means you must pass it a pointer to a char. In your code you have declared xName as a pointer to a char. But you pass the address of xName to mgSetName. That is a pointer to a pointer to a char. You need to pass simply xName not the address of xName as shown here:


mgSetName(parent,xName);

Original Post by: Mon Dec 8 14:55:48 2014


mgSetName(parent,xName);

Thanks for that info.. i did that but still the group bead name coming as G3 G4 like that... is that anything wrong in my code... its not writing the name as the external reference file name.

Original Post by: SteveThompson Mon Dec 8 15:25:22 2014


Check the return status of mgSetName. Does it return MG_TRUE or MG_FALSE? If the latter, check the Creator status log. It might be trying to tell you why the node cannot be named what you want. There are many potential reasons for that. Also show us (on this forum) the exact string you are trying to set. Maybe we'll see something wrong with it.

Original Post by: SteveThompson Mon Dec 8 16:29:51 2014


Also make sure no other node in the database already has the name you are trying to assign. Nodes are required to have unique names.

Original Post by: Mon Dec 8 17:55:40 2014


Yeah I can understand if there is similar name existing on other nodes it refuses to take same name. But in my case externals file name is 1.flt and still the group name comes as usual naming like g1 g2 etc. Is there anything wrong in code what I showed earlier in post.

Original Post by: SteveThompson Mon Dec 8 18:25:04 2014


Yeah I can understand if there is similar name existing on other nodes it refuses to take same name. But in my case externals file name is 1.flt and still the group name comes as usual naming like g1 g2 etc. Is there anything wrong in code what I showed earlier in post.

Nothing looks wrong (except there are some syntax errors that I attribute to copy/paste on the forum as the compiler would have caught these so they cannot be in your final code). Run through the debugger and "look" at the string value you are sending. This might give you a clue as to what might be going wrong. Also use the debugger to make sure you are setting the node you think you are.

Original Post by: Tue Dec 9 18:48:07 2014


Nothing looks wrong (except there are some syntax errors that I attribute to copy/paste on the forum as the compiler would have caught these so they cannot be in your final code). Run through the debugger and "look" at the string value you are sending. This might give you a clue as to what might be going wrong. Also use the debugger to make sure you are setting the node you think you are.


xName getting me the file name of external file as " C:/db/OOSA/LIBRARIES/OOSA00/MS/Model1.flt"

I tried referring many places to find out how to filter out only the file name (here "Model1"). As you mentioned earlier i tried searching for string funtions too but bad luck there too.

How can I filter out only Model1 from xName?. Steve can you please help me out in this. I dont want file path and .flt extension while using mgSetname.

Original Post by: ChrisRogers Tue Dec 9 20:22:38 2014


To filter out only the filename portion, there are many ways to do it. The most robust and reliable involves using the boost library. It has a great set of path functions to do everything you can imagine. However, I know not everyone wants to download and integrate a library just for a quick operation like this.


Below is a small snippet of code that should work for you. Basically all you need to do is find the last slash, and as long as the string is a path to a file, the filename is everything after that slash. You can use the strrchr to find the location of the last slash or backslash character, then just use a pointer to the next character as your filename.


Test this out to see if it gets your filename.

const char* PathToFilename(const char* path)

{

const char* location1 = strrchr (path, '/');

const char* location2 = strrchr (path, '\\');

const char* lastSlash = location1 > location2? location1: location2;

if (strlen (lastSlash) > 0)

return & lastSlash[1]; // strip off the beginning slash;

}



Were you able to modify node names though? Having a full path shouldn't stop you from doing that as long as you didn't have a path that exceeded the maximum node name length.

Original Post by: Wed Dec 10 13:46:36 2014


Yeah I'm able to get the file name and change the group bead name, but it says in status message bar that id already exists because its getting the entire path including the filename.flt as i mentioned earlier following is the code i used for the same.



static mgbool gbeadNApply (mgrec* db, mgrec* parent, mgrec* rec, void* gBead)

{

toolrec* toolRec = (toolrec*)gBead;

if (mgGetCode(rec) == fltXref);

{

char *xName;

parent = mgGetParent(rec);

mgGetAttList(rec,fltXrefFilename,& xName,MG_NULL);

mgSetName(parent,xName);

}

return MG_TRUE;

}



I have seen the way Chriss suggested to extract "filename" but as I am a beginner I don't know how to implement that in the code I wrote. Can anyone of you help me in adding that string function in the code I provided above. This function in my plugin will really help a lot doing repeated task of renaming group beads.

Login to post a comment