Enumerate object names

Next
 From:  andrewsimper
6648.1 
I have a scene where I have lots of objects with duplicate names, but some of them I want to automatically enumerate by adding a number at the end so when I export they appear as separate meshes. I found a script that almost did what I wanted here: http://kyticka.webzdarma.cz/3d/moi/#SeparateObjectName but this would go through all objects in the scene, and it didn't zero pad the numbers. I've updated the script so it does exactly what I wanted:


Enumerate Object names (by adding a zero padded enumeration index to matching names):
(1) if no objects are selected then all objects are searched for matching names
(2) if there is a selection then if multiple objects of the same name are selected then only those objects that are selected are updated, if only one object of a name is selected then all objects with that matching name are updated. The multiple or single modes can both be done at once for different object names

Currently this operation if mapped to a key has no undo. Does anyone know how I can add undo functionality?

code:
script: /* Enumerate object names */
var selected_objects = moi.geometryDatabase.getSelectedObjects();
var all_objects = moi.geometryDatabase.getObjects();
var matched_names = new Object();
var selected_names = new Object ();
// if no objects are selected then update all objects
if (selected_objects.length == 0)
{ 
    for ( var i = 0; i < all_objects.length; i++ )
    {
        var obj = all_objects.item(i);
        if ( obj.name == '' ) { continue; }
        if ( !matched_names[obj.name] )
        {
            matched_names[obj.name] = new Array();
        }
        matched_names[obj.name].push( obj );
    }
}
// if there is a selection then use that to dictate which names to search for and update
else
{
    for ( var j = 0; j < selected_objects.length; j++ )
    {
        var name = selected_objects.item(j).name;
        if ( name == '') { continue; }
        if (! selected_names[name] )
        {
            selected_names[name] = 0
        }
        selected_names[name]++;
    }
    for ( var name in selected_names)
    {
        var search_objects;
        if (selected_names[name] == 1)
        {
            // if there is only one name selected then update all objects with this name
            search_objects = all_objects;
        }
        else
        {
            // if there are multiple of the same name selected then only update those in the selection
            search_objects = selected_objects;
        }
        matched_names[name] = new Array ();
        for ( var i = 0; i < search_objects.length; i++ )
        {
            var obj = search_objects.item(i);
            if ( obj.name == '' ) { continue; }
            if ( obj.name == name )
            {
                matched_names[obj.name].push( obj );
            }
        }
    }
}
// update the matched objects
for ( var name in matched_names )
{
    if ( matched_names[name].length == 1 ) { continue; }
    var num_names = matched_names[name].length;
    var digits = Math.floor (Math.log(num_names)/Math.log(10))+1;
    var zeros = "0000000000000000";
    for ( var i = 0; i < num_names; i++ )
    {
        var padded_num = zeros + (i+1).toString ();
        matched_names[name][i].name = name + ' ' + padded_num.slice (-digits);
    }
}


(edit: updated [code][/code] to <code></code> version as suggested)

EDITED: 23 Apr 2014 by ANDREWSIMPER


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6648.2 In reply to 6648.1 
Hi andrew, thanks for sharing your code!

If you want it displayed in a forum post with whitespace maintained, use <code> xxxxx </code> rather than [code] [/code]


> Does anyone know how I can add undo functionality?

There isn't currently any way set up for an "inline script" to generate undo units. That is something I want to make happen automatically in the future when I get a chance to make various improvements to the script system.

Currently only code that's run as a "command" (with the script file located in the "commands" folder, and launched by command name) that makes stuff work with undo. Prepping stuff for undo is part of the command launch and command exit processes.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  andrewsimper
6648.3 In reply to 6648.2 
You're welcome! Thanks for writing such a great product :) I've got a bunch more little things I would like to add to make my life easier so I'll share them all.

Ok great, that's good to know that commands automatically get undo support :) This one definitely needs it since it is quite an intrusive operation, so I'll switch it to being a command instead. I also want to make a De-enumerator operation where you can specify a trailing string to remove, so this will need user input as well so will need to be a command.

Do commands have access to any extra java script libs? Something like string.js http://stringjs.com/ would be really useful!
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6648.4 In reply to 6648.3 
Hi andrew,

> Ok great, that's good to know that commands automatically get undo support :) This one definitely
> needs it since it is quite an intrusive operation, so I'll switch it to being a command instead.

Actually I should clarify that a bit - commands automatically get undo support for all added and removed geometry. Changing just an attribute like the object name will not be covered by that current system. You could do something like clone the object, change the name on the cloned object, remove the old object from the geometry database and add in the renamed object into the geometry database in a command and then that would be undoable. The undo record will consist of the entire old object though.


> Do commands have access to any extra java script libs?

No, they have the same stuff available as inline script, but the command launcher does some various set up and tear down tasks like setting up undo records for added and removed geometry, loading the command's UI file, canceling any currently running command, clearing previous picked points, clearing any selection transition or selection lock, etc...


> Something like string.js http://stringjs.com/ would be really useful!

You can probably use it if you want, try copying the .js file to the commands folder and then in your command put #include "string.js".

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  andrewsimper
6648.5 In reply to 6648.4 
I implemented the script as a command and came to post here to complain that it wouldn't undo, but you have beaten me to it :)

Copying all of the geometry by a clone is a very heavyweight operation for a simple re-name. Is it possible to add the name field to your undo system?

edit: how does the current system work when I click on the top left name field and type in a new name? I can undo that operation, is this also a completely clone of all geometry that is being renamed?
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
 From:  Michael Gibson
6648.6 In reply to 6648.5 
Hi andrew,

> edit: how does the current system work when I click on the top left name field and type
> in a new name? I can undo that operation, is this also a completely clone of all geometry
> that is being renamed?

I had to look it up, I had forgotten about this.

When you use the regular UI to edit the name it does set up a special undo unit that just contains object state (including name, style assignment, hidden and locked states), and just the geometry's ID number as a reference to it, rather than storing a clone of the actual geometry.

But currently the creation of these particular undo units is baked in to some specific functions like the property panel's name edit function (which includes showing the dialog as part of it), there isn't any way to trigger it by itself from script right now.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All