Jump to content
3DCoat Forums
AntonTenitsky

Improving batch renaming script

Recommended Posts

Hi all,

I'm pretty dumb scripter but I had a huge need in the renaming of 100+ layers so I came up with this:

void main() {


    Vox  v;
        
    string x = GetCurVolume();

     v.firstForRoot().rename(x);
     for ( int i = 0; i < v.count(); ++i ) {
        v.at( i ).rename( x + i ).parent();
        Wait( 100 );
    }
}
 

It works but I don't know how to add intelligent zero padding to numbers like "003, 013, 334" I would be glad if we could improve this script.

Cheers,

Anton

 

  • Like 2

Share this post


Link to post
Share on other sites

Alright, I decided to add if else loops because I couldn't wait for an answer.

I don't know how to make it rename inside parent layers so atm you have to select each one of the parents to continue renaming them.

Also, you have to hide parent layers higher in the stack and only have visible one for renaming. Sigh... Hopefully, somebody more knowledgeable could make it a more versatile script

void main() {


    Vox  v;
        
    string x = GetCurVolume();
    SelectFirstVolume(true);
     v.rename(x);
     for ( int i = 0; i < v.count(); ++i ) {
        if (i < 10) { 
    v.at( i ).rename( x + "_00" + i ).parent();
            }
    else if ( i > 9){
    v.at( i ).rename( x + "_0"  + i ).parent();
    }
    else if ( i > 99){
    v.at( i ).rename( x + "_" + i ).parent();
    }
    
    }
}
 

Edited by AntonTenitsky
  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Hey Anton,

I don't know how to add intelligent zero padding to numbers like "003, 013, 334" I would be glad if we could improve this script.

you can use formatInt for that:

void main() {
    Vox  v;
    string x = GetCurVolume();
    SelectFirstVolume(true);
    v.rename(x);
    for ( int i = 0; i < v.count(); ++i ) {
        v.at( i ).rename( x + "_" + formatInt(i, '0', 3) ).parent();
    }
}

more info here.

On a side note, I wonder if it's possible to get a list of children of the current volume or a parent? Iterating through all the visible nodes is not ideal...

Share this post


Link to post
Share on other sites

...a follow up. This will only rename child layers of the current layer, no need to hide any other layer:

void main() {
    Vox  v;
    string x = GetCurVolume();
    for ( int i = 0; i < v.count(); ++i ) {
        v.at( i ).rename( x + "_" + formatInt(i, '0', 3) ).parent();
    }
}

I'm not sure why you were selecting the root object in your code, I think it's more clear this way or am I missing something?

Share this post


Link to post
Share on other sites

Sorry for posting a lot, but Edit button disapears after several hours, so... Anyway, this will also rename all the nested children:

int count = 0;
string original_name = "";

void main() {
    count = 0;
    original_name = GetCurVolume();
    Vox v;
    v.forEach("rename");
}

void rename() {
  count++;
  Vox v;
  RenameCurVolume(original_name + "_" + formatInt(count,"0",3));
  v.forEach("rename");
}

image.png.b7dfca83d3d37cc6abf0f70d2e65b8af.png

 

P.S. I wonder if it's possible to pass values to forEach? don't want to put contaminate the global scope...

Share this post


Link to post
Share on other sites

Ok here's another version. This is fun!

1) if a layer has children, children will get parent name + counter

2) if a layer has no children and its parent is Root all layers will be renamed to volume_001, volume_002, etc

3) if a layer has no children but has a different layer as a parent, parent layer will be selected and children will be renamed the same as in 1)

// globals
int count;
int padding = 3; // how many symbols in the counter (with padding = 3, 1 will become 001, 2 - 002, etc)
string original_name;

void main() {
    count = 0; // resetting counter
    original_name = GetCurVolume(); // current layer

    Vox v;
    string global_name = "volume";


    // if current layer has children, start renaming them
    if (v.count() > 0) {
      v.forEach("rename");}
    else {
      // if there're no children, selecting the parent layer
      v.parent();

      //and getting its name
      string parent_name = GetCurVolume();

      // if parent name is the same as the original name we're at Root, globally renaming everything
      if (parent_name == original_name) {
        original_name = global_name;
        v.forRootEach("rename");
      } else {
        // if parent has a different name, renaming all its children
        original_name = parent_name;
        v.forEach("rename");
      }
    }
}

void rename() {
  count++;
  Vox child;
  RenameCurVolume(original_name + "_" + formatInt(count,"0",padding));
  child.forEach("rename");
}

There's an interesting... thing. I assigned this script to Shift+1 and it went CRAZY starting renaming both parent layer and children with huge counters. I wonder what's happening there?

image.png.efbc5529cc2b4c26ce170893166e0db7.png

Share this post


Link to post
Share on other sites

Update.

Rename children will now adds _inst_ to instanced volumes (only if the had inst in their names already)

Another script, Add Material Name as Suffix will add a shader name to an object as name suggests

add_material_as_suffix.cpp

rename_children.cpp

Note that currently there's a bug where scripts will work on an object under a cursor. Make sure you hover your cursor over nothing before running them.

Edited by kritskiy
  • Like 1

Share this post


Link to post
Share on other sites

Hi

Thx for sharing it

Using 4.9.33

When i use script twice or more over the same mesh, suffix was added but previously is not deleted.

suffix.jpg

Share this post


Link to post
Share on other sites
12 minutes ago, Carlosan said:

Hi

Thx for sharing it

Using 4.9.33

When i use script twice or more over the same mesh, suffix was added but previously is not deleted.

suffix.jpg

I think you've changed an object shader between the runs?

It only checks a name against the current shader, so if you have an object Volume with a shader Cartoon_Orange, after adding a suffix you'll get Volume_Cartoon_Orange. Next time you run the script, it'll check if there's Cartoon_Orange in the Volume_Cartoon_Orange, and if there is, it won't change it. But if you change the shader to Cartoon_Blue, the script will check if there's Cartoon_Blue in Volume_Cartoon_Orange: it's not there, so the suffix will be added to the whole thing: Volume_Cartoon_Orange_Cartoon_Blue.

Edited by kritskiy
  • Thanks 1

Share this post


Link to post
Share on other sites

I think you've changed an object shader between the runs?

yes i do

Ahhhh, ok.

Thanks for explaining it, excellent scrip. Very useful !

Share this post


Link to post
Share on other sites

I guess a solution would be to have a specific pattern for a material name in the volume name and check against it: something like Volume_mat_Mat_Name, a regex would look for mat_*, something like (?<=_mat_)(.*), but I'm not sure AngelScript in 3DC supports regex

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×