Everything related to the integration for Rhinoceros.
By Wynott
#393383
Hi Jeremy

Writing one last time to plead with you to do something hacky to resolve the material conflicts issue.

I'm doing exports for VR rendering now, and the material duplication is driving me insane. It's like... really so frustrating and impossible for workflow.

What if I was content to just accept the material in the parent scene? Ignore the material in the block when inserting? If the name matches, then consider it good and use the parent file's material.

In a lot of ways this would be better, for example could change all the carpet throughout the model if all the materials were just "carpet" instead of carpet(1) carpet (2) etc.

For a while I got into the habit of putting a prefix on materials like _blockname materialname.mxm or whatever so at least they would alphabetically float to the top of the materials window and I could ignore them.

But now when I export my scene to polygons for VR I'm getting like 50 different stainless steel materials and within the VR editor it's nearly impossible and in practical terms unreasonable to reassign them all to the singular "stainless" material I want to use. Perhaps that's a bad example because there's no bitmap, but in the case of materials that have bitmaps associated with them it's a huge memory waste loading the same image multiple times.

What I'd really REALLY like is to just use the parent file's material when I import a block that contains materials with conflicting names.

I'm starting a new project so it's a good time to sortof switch gears on methodology for me. I'm ok "breaking" my old models by deleting out all the _prefixes from common block files.

Please please. I can't really proceed with Maxwell without getting this sorted.
By JDHill
#393384
I think I understand what you want, but things may not really work the way that you perceive, so I can't really do it that way. However, I'm working on a standalone command for culling duplicate materials, by literally comparing all values in all materials to find materials that are effectively duplicates, removing them, and replacing references to them with references to the ones that they duplicate.
By Wynott
#393389
Thanks Jeremy.

I do appreciate your efforts with the plugin.

Help me understand why you need to compare all the values. Wouldn't you effectively achieve what I'm looking for by just comparing the name? And then remove the duplicates and replace the references same as you plan to? Just faster with less thorough checking?

Is this something I will need to run every time I open a file? Or just after inserting a linked block?
By JDHill
#393390
It is necessary to compare all the values because, although it may be that in your specific case you would consider it acceptable to judge based on name alone, this is not generally true, and would potentially be very destructive to a person's model. The action can only be considered safe if there is no possibility that after running it, the model would render differently, and we can only guarantee this by making sure that we only cull materials that truly are duplicates. In doing so, and perhaps a little ironically, it is actually the case that the material name is one of a very few values that we need to ignore.

As far as saying when you will need to run this, I am not yet certain; it may be that I can do it automatically, or provide an option letting you decide whether to do so.
By Wynott
#393392
OK I understand that completely.

I just can't really imagine I'm the only person that can see some advantages in (at least having the option to) collapse superficially different materials into a single material.

Just to explain where I'm coming from...

Let's say for this new boat I'm doing. It's 48 meters long, and most of the bits and pieces that go into it will come out of my existing library which I have set up for Maxwell... There may be 300? 500? models that get linked in? Electrical components, decor, light fixtures, pilothouse components, etc. etc.

Going into each part and changing the names is easier than actually changing the material assignments. To change the actual material I have to actually reassign each layer to delete the material out of each file and replace it with a controlled material (to ensure exact matching and eventual culling from the parent file).... that is significantly more work than going in and renaming everything to standard names if that's good enough to get them culled.
By Wynott
#393393
I guess put into other words:

1) The goal is to get the unwanted material culled.

2) If all values must match to achieve this, you are going literally going to take 3 days off my life to go in and reassign everything... Lots of opportunity for human errors. Missing layers etc.

3) All this effort, just to have the material deleted!

Doesn't really make sense to me.

Anyway I think you understand this case now anyway.
By JDHill
#393396
I'm not sure where the 3 days comes in, I am talking about a command that should run very quickly, and which will remove what are effectively duplicate materials. I say effectively, because though functionally identical, consider a scenario in which you used one template file, containing a "stainless" material, to create ten different components, which you intend to use later by inserting them into other models. Though it is true, at this point, that all the "stainless" materials are identical, there is nothing stopping you from opening one of the ten files, changing the tiling value of one of the textures in the "stainless" and saving it. Now, in a file where you reference the ten, there are still ten "stainless" materials, but one is subtly different than the rest. The function I am writing must cull eight of the nine still-identical materials, and leave the tenth.

It seems there may be something else to say here, that being, given how you describe your workflow, I think I would probably take a look at making use of MXED, and using an MXM-linking strategy. This would not address duplicate materials showing up in your plugin materials list, but it would give a single point of control for materials, since you can change how all usages of a given MXM render, by editing that single MXM.
By Wynott
#393405
Jeremy the 3 days comes from going into my library of "lecacy" blocks that I set up before there was a need for or before I had an understanding of the importance of consistency of materials.

SO I have like hundreds of boat parts all with subtly varying stainless steel, not out of a desire for very nuanced stainless steels, but more just spur of the moment making it from wizard or grabbing something handy or whatever. Just pure carelessness at the time I created the blocks.

However, now they exist.

I'm trying to avoid needlessly having to update all those blocks. If you're going to introduce a system to allow them to be culled then why not make it easy for me, and presumably others in the same situation.

Can I access Maxwell via script? I know I can call some commands... But how about deleting materials? Maybe I can solve my own problem.

EDIT actually the way the naming in the material browser and the actual maxwell material applied to objects must be happening inside maxwell. Probably a dead end.
By JDHill
#393412
Though the plugin has no requirement that material names be unique, Maxwell itself does, which is why the plugin adds "(2)" and such to duplicate names. That said, if we are not concerned with materials actually being duplicates, and instead wish to make the assumption that similarly-named materials must be similar, then I can write a python script that removes materials and fixes up references based on that assumption:
Code: Select all
import clr
clr.AddReference('Maxwell.dll')
import Maxwell
import System
import Rhino
import re

def remove_similarly_named_materials():
    print('Maxwell: scanning materials...')
    scene = Maxwell.Scenes.Scene.CurrentInstance
    regex = re.compile("\([0-9]*\)\s*$")
    map = {}
    for material in scene.Materials:
        name = material.Name.strip()
        match = regex.search(name)
        if match:
            idx = match.start()
            name = name[:idx].strip()
        if name not in map:
            map[name] = []
        map[name].append(material)
    for materials in map.values():
        if len(materials) < 2:
            continue
        material = materials[0]
        materials.RemoveAt(0)
        for duplicate in materials:
            indices = []
            for rh_material in Rhino.RhinoDoc.ActiveDoc.Materials:
                if duplicate.IDString == rh_material.GetUserString('MWR_ID'):
                    indices.append(rh_material.MaterialIndex)
            for index in indices:
                rh_material = Rhino.RhinoDoc.ActiveDoc.Materials[index]
                rh_material.SetUserString('MWR_ID', material.IDString)
                rh_material.CommitChanges()
            print("Maxwell: removing '%s'." % duplicate.Name)
            scene.Materials.Remove(duplicate)
    print('Maxwell: done.')

if __name__ == "__main__":
    remove_similarly_named_materials()
If you click Tools > PythonScript > Edit and paste the above into a new document, then click the green arrow button to run the script, you should find that the similarly-named materials are removed. This works based on the assumption that we can split the material name into a prefix and a suffix, where the suffix matches the "(2)" pattern. For all materials that share a given prefix (i.e. the name without any suffix), the script changes references to them to point to the first material found for that prefix, and then removes the now-unused duplicates.

You can also save this to a .py file and make a toolbar button with a command macro like this:
Code: Select all
-_RunPythonScript (C:\Users\jeremy\Documents\remove_similarly_named_materials.py)
Will there be a Maxwell Render 6 ?

Let's be realistic. What's left of NL is only milk[…]