Selecting objects via partial name

On 15/07/2013 at 08:14, xxxxxxxx wrote:

Hey guys,

I was just wondering if there was a way to select objects in a scene with the same beginning of the name.
Layer panel
Layer panel
Layer window
Layer window

so if I ran the plugin it would then select everything with 'Layer' in or 'Street'

My master plan is to create a script that selects all objects with the same 12 characters at the beginning of their name, groups them into a null, then names the null with those 12 characters.

When importing fbx files to work on, its bringing in 10000 objects, This will help speed up work greatly.

Cheers in advance


On 15/07/2013 at 09:48, xxxxxxxx wrote:

1. c4d has that functionality built in (the magnifying glass icon in the om).
2. yes it is possible, although c4d has not a special method for that exact case. there are the 
search methods in BaseDocument. but they will always only return the first match. a custom 
method could look like that( where nodelist is a list of GeListNodes ) :

def FilterNodeByName( nodelist, filterstring ) :
    result = []
    if isinstance(nodelist, list) :
        for node in nodelist:
            if isinstance(node, c4d.BaseList2D) and filterstring in node.GetName() :
    else: return None
    return result

edit : fyi you might have to modify the filter string and the name string. i always forget if __contains__ () is case sensitive for strings, but i think it is, so for an insensitive search you would have to force both strings into lower or upper case.

On 19/08/2013 at 03:45, xxxxxxxx wrote:

Hey littledevil,

cheers for the reply, sorry its been a while, just coming back to this now.
Here is a script I've found:

import c4d  
def main() :  
  mapping = {}  
  context = doc.GetActiveObject() or doc.GetFirstObject()  
  if not context:  
  root = context.GetUp()  
  # Go to the first object in the context.  
  while context.GetPred() :  
      context = context.GetPred()  
  # Fill the mapping.  
  while context:  
      mapping.setdefault(context.GetName(), []).append(context)  
      context = context.GetNext()  
  # Create Null-Objects.  
  items = sorted(mapping.iteritems(), key=lambda x: x[0])  
  prev = None  
  for name, objects in items:  
      null = c4d.BaseObject(c4d.Onull)  
      for obj in objects:  
          doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)  
      doc.AddUndo(c4d.UNDOTYPE_NEW, null)  
      doc.InsertObject(null, root, prev)  
      prev = null  

I'm trying to tweak it, maybe by adding a range(13) in there to select the characters?

In the section of #Fill The Mapping. I was trying to get in a range, so it only gets the first 12 characters of a name, but the .GetName() takes no arguments.

On 19/08/2013 at 04:06, xxxxxxxx wrote:

strings are arrays of chars (or more pythonic lists).

string = '01234567'
print len(string)
\>> 8
print string[4]
\>> 4
print string[1:4]
\>> 1234
print string[:-1]
\>> 0123456

I did use sort of this quality of strings in my first snippet, when i did call __contains__ on a string
which is an enumerator object method.

> if filterstring in node.GetName() :

On 19/08/2013 at 05:18, xxxxxxxx wrote:

I'm trying to go about removing the last few characters from the end of each string in the list

for x in mapping:  

Or do you think it would be more to do with the first line of the #Create Null-Objects.?

On 19/08/2013 at 07:54, xxxxxxxx wrote:

a negative index does indicate an inverted index order.

> mapping[:-13]

is the short (implicit) form for

> mapping[0:-13]
which means take the list mapping and copy its content form the first index to the last index - 13.
so for a list with 15 indices list[:-13] and list[:2] are the same result list. also not assigning the 
copied list to a variable does not really make any sense. if you do want to copy a list from its first 
to its nth component it is simply mylist[:nth].

mylist = mylist[:11]
or a bit more extensive including checking for oor exceptions :
def cliplist(data, n) :
    if isinstance(data, list) and isinstance(n, int) :
        if len(data) > n-1:
            return data[:n]
            return data
    return None
mylist = cliplist(mylist, 11)