By Wynott
#380574
Often the assigned materials in the layer tree show a previous name of the material.

For example if I make a new material with a wizard or whatever, assign it to a layer (by dragging from the scene manager to describe my exact process) then rename the material, the layer tree does not update with the revised name, and any layers I assign it to after renaming it show the old name.

If I rename the material BEFORE applying it to any layers then it shows the new name. But if I rename it again, then any layers it gets assigned to after that show the previous name.

This is kind of confusing me because we're going through a lot of different paint schemes and I'm cloning materials to make slight variations and I can't tell what's assigned to what layer because they've been previously renamed.
By Wynott
#380680
Okay this isn't a Maxwell issue... but Jeremy you are obviously knowledgeable about this maybe you can point me in the right direction.

Something that would be really helpful is if I could somehow flag layers, perhaps by putting a # or @ or _ or whatever after the name and then some kind of script outputs a list of the materials applied to those layers. Then I could paste that into the overlay text field in Maxwell Render and the rendering would have a list of what's applied to what surface right on the image.

Thoughts?
By JDHill
#380684
Give this a try:
  • 1. Make a new toolbar button.
    2. SHIFT+right-click the new button to edit its commands.
    3. Paste the following script into the command for one of the mouse buttons:
Code: Select all
_NoEcho
-_RunPythonScript (
import Rhino
import rhinoscriptsyntax as rs
import System.Windows.Forms
import re
def LayersAndMaterials():
  by_layer = rs.GetString('List Style', 'ByLayer', ['ByLayer', 'ByMaterial'])
  if by_layer is None or by_layer == '': return 0
  by_layer = by_layer == 'ByLayer'
  filter = rs.GetString('Filter', 'none')
  if filter is None or filter == '': return 0
  if filter == 'none': filter = ''
  replace = 'Yes'
  if filter != '':
    replace = rs.GetString('Remove filter?', 'Yes', ['Yes', 'No'])
    if replace == None: return 0
  replace = replace == 'Yes'
  map = {}
  doc = Rhino.RhinoDoc.ActiveDoc
  for layer in doc.Layers:
    idx = layer.RenderMaterialIndex
    mat = doc.Materials[idx]
    matName = 'default'
    layerName = layer.Name
    if mat != None: matName = mat.Name
    if matName == '': matName = '<unnamed>'
    if by_layer:
      if filter == '':
        map[layerName] = matName
      elif re.search(filter, layerName):
        if replace:
          replaced = re.sub(filter, '', layerName)
          if replaced != '':
            layerName = replaced
        map[layerName] = matName
    else:
      if filter == '':
        if map.get(matName) is None:
          map[matName] = []
        map[matName].append(layerName)
      elif re.search(filter, matName):
        if replace:
          replaced = re.sub(filter, '', matName)
          if replaced != '':
            matName = replaced
        if map.get(matName) is None:
          map[matName] = []
        map[matName].append(layerName)
  out = ''
  if by_layer:
    for pair in sorted(map.items()):
      out += pair[0] + ': ' + pair[1] + '\n'
  else:
    for pair in sorted(map.items()):
      out += pair[0] + ': \n'
      for value in pair[1]:
        out += '    ' + value + '\n'
  if out == '':
    if by_layer:
      print 'No matching layers were found.'
    else:
      print 'No matching materials were found.'
  else:
    out = out.rstrip()
    System.Windows.Forms.Clipboard.SetText(out)
    print '------------------------------------------------------'
    print 'The following list has been copied to the clipboard:'
    print '------------------------------------------------------'
    print out
    print '------------------------------------------------------'
  return 0
LayersAndMaterials()
)
Take care to copy it exactly, since it is written in python, in which the indentation of the code is significant.

When you run it, it will first prompt for whether you'd like to categorize materials by layer, or layers by material. It will then prompt for a filter, which will be used to match characters in the material or layer names. Leaving the filter set to 'none' (meaning, just hitting Enter to get past it) will cause all names to be included. Once built, the final list will be printed to the console, and copied to the clipboard. [edit: updated to add an option for removing the filter string from names in the output list.]

The filter is searched using regular expressions, so it's not limited to matching just the ends of names, and you could get pretty fancy with it if you wanted to. Just for example, if you had five layers named Layer 01, Layer 02, Layer 03, Layer 04, and Layer 05, you could select the second and the fourth using the filter: 0[24], which matches occurrences of a zero, followed by either a 2 or a 4. The filter \s0[0-9], which matches a space followed by a digit, would match all five. Were the second one named Layer x02, and the third Layer X03, you could pick them from the list using \s[a-zA-Z], which matches a space followed by a letter, either lower or upper case. A simple Layer or aye filter would match all of these examples.

So that's the general idea; if necessary, you can find more information by searching for regex (regular expression); you can find lots of tutorials and free programs available for playing around with patterns.
By Wynott
#380688
fantastic.

for my own purposes I replaced the '/n' with ', ' in the output to separate things a bit in a one line output for the maxwell text overlay.

Thanks very much for this Jeremy. Gold star for you.
Help with swimming pool water

Hi Andreas " I would say the above "fake[…]

render engines and Maxwell

Other rendering engines are evolving day by day, m[…]