How to cleanup material table using IO File3dm class

I want to purge all materials from file or decide sometimes which need to stay. So I wrote something simple at the beginning:

using (var tempFile = File3dm.Read(tempPath))
{
 tempFile.Materials.Clear();

 tempFile.Polish();
 tempFile.Write(finalPath, Rhino.RhinoApp.Version.Major);
}

But there is no change in the final file at all - in both files materials are the same. Am i missing some finalizer or committing changes somewhere?


Another possible option is that I have to delete also RenderMaterials but those are ofc not available through File3dm IO class …

Mhm … Guess this is related - How to delete a RenderMaterial

using (var tempFile = File3dm.Read(tempPath, File3dm.TableTypeFilter.Material, File3dm.ObjectTypeFilter.None))
{
  tempFile.AllMaterials.Clear();
  A = tempFile.Write(tempPath, 0);
}

ClearMaterials.gh (3.0 KB)

@Mahdiyar cool thanks but how this is different from above? Btw it doesn’t throw that collection was changed with a deletion in forward order? (guess its because those aren’t deleted upfront but first marked as deleted so they still exist in materialTable)

AllMaterials is no different than Materials of File3dm - File3dmMaterialTable : IList<Material>

Hmm… Ok this could be that I need to delete each independently to delete as Clear doesn’t have cpp callback to do cleanup of table? No this isn’t a case it looks valid here.

Have you tried and tested that across a few files?

I ran into several bugs regarding MaterialTable when trying to copy materials from the current document to File3dm. It looks MaterialTable has some issues.

I’ve used another overload of File3dm.Read, and which makes it possible to choose what tables should be read.

Rhino.FileIO.File3dm.Materials is obsolete.

There seems to be no problem with Clear method. I was only testing if that causes the problem.

No mater if iterating or clearing Materials via Materials or AllMaterials Property

As those shows zero it becomes clear that those are RenderMaterials and are unavailable through File3dm IO - so let’s say its impossible to do as I can’t imagine making user waiting to open for eg 20+ files just to get rid of those materials trying to fix RhinoDoc.Write holes …

It is marked as obsolete but uses the same class wrappers inside so it’s just a matter of what you get - AllMaterials returns Table class which derives from IList so IList is also a valid form of it as normal Materials property.

1 Like

Thanks for effort and doing vid - that makes me confused why i can’t get rid of those. Please can you try the custom with some bitmap ? Maybe it is still kept as simple material not a RenderContent derivative without texture (?) :dizzy_face:

Are you trying to clear the material table of your current open Rhino document? if so, Why don’t you use ActiveDoc.Materials.Clear. It’s impossible to write on an open document with File3dm.Write.
It seems your materials are not standard Rhino materials, If so you can also check this: https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_FileIO_File3dmPlugInDataTable.htm

Not at all, im trying to export blocks from file to independent files - i tried to write 3dm on my own using File3dm - not possible as blocks are losing its contents so ok I found a workaround to export those intact using RhinoDoc.Write with WriteSelectedOnly option but this leads to a huge mess in files so I wanted to handle cleanup on my own right after model file saving but ended up with file3dm empty material table and unnecessary materials in it - those are exactly the same as in the original file not less not more exact same count in material tab and those remains unchanged.

I thought about it but one of those mats is normal rhino custom mat but with texture instead of pure color.

Seems you were right :slight_smile: @nathanletwory Would you mind informing us if Cycles ever put materials in PluginDataTable? As in my case seems it is and im wondering if those are accessible anyway for any changes or decisions which should stay?

Hmm thats weird as i thought those are all Rhino.Render.NativeRenderMaterial but why those belong to data in PluginDataTable?

I also dumped it to the log and found that interesting:
Contents:
0 embedded bitmaps
0 render material definitions
0 line type definitions
1 layers
0 render lights
0 groups
14 objects
4 user data objects

File consist exactly from 1 mesh and 1 instance definition what would give 2 + 12 materials as objetcts? I guess i’m still far from understanding this especially that there is position render material definitions which states there are no materials (?!) :dizzy_face:


Even if i try to rewrite those after clearing materials and plugins data there is no way to reassign correctly materials - normal ones are reassigned but mostly doesn’t work and aren’t read on render time and when those should be RenderMaterials those are unavailable via File3dm IO so can’t be rewritten. Sorry guys sad to say but RhinoCommon when it comes to IO is made out of paper…