Jump to content
3DCoat Forums

Improving batch renaming script


AntonTenitsky
 Share

Recommended Posts

  • Contributor

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
Link to comment
Share on other sites

  • Contributor

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
Link to comment
Share on other sites

  • 3 weeks later...
  • 1 year later...
  • Member

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...

Link to comment
Share on other sites

  • Member

...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?

Link to comment
Share on other sites

  • Member

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...

Link to comment
Share on other sites

  • Member

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

Link to comment
Share on other sites

  • 2 months later...
  • Member

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
Link to comment
Share on other sites

  • Member
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
Link to comment
Share on other sites

  • Member

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
Link to comment
Share on other sites

  • 6 months later...
  • Member

All good - for reference if anyone needs a similar alteration to the code just remove everything after the original_name in the 'if' statement.

if (inst_pos == -1) RenameCurVolume(original_name);
  else RenameCurVolume(original_name));

Thanks guys

- Rich

  • Thanks 1
Link to comment
Share on other sites

  • 2 years later...
  • Member

The renaming scripts are really handy. I'm doing Anton Tenitsky's Udemy class on "Learn hardsurface-modeling with Voxels. It's a few years old and even as he provides the original script, I found this thread talking about how it was updated. But I can't get the 'material' one to run. I get an error when running it directing me to see the 'View execution log'. In that 'log.txt' there is no info, just this:

============================================================================
17.09.2023 19:11:32 : Executing script: E:/1_My Documents/3DCoat/UserPrefs/Scripts/ExtraMenuItems/add_material_as_suffix.cpp
============================================================================

I know nothing about scripting in 3DC. I may not be using it correctly. But, I put different materials on 5 parts under a root folder. If I change the roots name and use the 'rename_children' script, it works perfectly. If I click the root and run the 'add_material_as_suffix' I just get the error message and no other changes. 

 

Edit:  

Ha, I just relized this is Anton's post. Good job Anton. 

I do have another question. Is there a script that will just modify one word in all the layers. For instance, in doing this course I've renamed a lot of layers nicely. But the first word I have in all of them is "Sketch_", like "Sketch_Collar" and "Sketch_Ribs1" and "Sketch_Ribs2." I don't want to get rid of the specific naming, just want to get rid of the word "Sketch". Is there a script to do that?

Edited by RobH2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...