How to copy materals and textures to another RhinoDoc

Hello.

I recently started developing a Rhino Plug-In.

I am developing a plugin that outputs multiple selected objects to a glb for each layer.

However, the following code does not output the texture and material to the glb, only the shape.

using ExportGlb.Utilities;
using Rhino;
using Rhino.Commands;
using Rhino.DocObjects;
using System.Collections.Generic;
using System.IO;

namespace ExportGlb
{
    public class ExportGlbCommand : Command
    {
        public ExportGlbCommand()
        {
            // Rhino only creates one instance of each command class defined in a
            // plug-in, so it is safe to store a refence in a static property.
            Instance = this;
        }

        ///<summary>The only instance of this command.</summary>
        public static ExportGlbCommand Instance { get; private set; }

        ///<returns>The command name as it appears on the Rhino command line.</returns>
        public override string EnglishName => "ExportArchModelCommand";

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            RhinoApp.WriteLine("The {0} command is under construction.", EnglishName);

            var objs = ObjectSelector.SelectObjects("Please select objects");
            var go = objs.Geometry;

            var selectedObjects = new List<RhinoObject>();
            for (int i = 0; i < go.ObjectCount; i++)
            {
                selectedObjects.Add(go.Object(i).Object());
            }

            // Group by layer
            var layerObjects = new Dictionary<string, List<RhinoObject>>();
            foreach (var obj in selectedObjects)
            {
                var layerName = doc.Layers[obj.Attributes.LayerIndex].Name;
                if (!layerObjects.ContainsKey(layerName))
                {
                    layerObjects[layerName] = new List<RhinoObject>();
                }
                layerObjects[layerName].Add(obj);
            }

            // Output by layer
            var dir = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "rhino_plugin_output", "glb_by_layer");
            if(!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            foreach (var layer in layerObjects)
            {
                var tempDoc = RhinoDoc.CreateHeadless(null);
                foreach (var obj in layer.Value)
                {
                    // Copy material
                    var materialIndex = obj.Attributes.MaterialIndex;
                    if (materialIndex >= 0)
                    {
                        var material = doc.Materials[materialIndex];
                        materialIndex = tempDoc.Materials.Add(material);
                    }

                    var attributes = obj.Attributes.Duplicate();
                    attributes.MaterialSource = ObjectMaterialSource.MaterialFromObject;
                    attributes.MaterialIndex = materialIndex;

                    // Copy geometory
                    tempDoc.Objects.Add(obj.Geometry, attributes);
                }

                var savePath = Path.Combine(dir, $"{layer.Key}.glb");
                tempDoc.Export(savePath);
                tempDoc.Dispose();
            }

            return Result.Success;
        }
    }
}

When I debug it, I can confirm that the material information is being passed from the original RhinoDoc to tempDoc.Materals.

Do you know the correct procedure to copy materials and textures to another RhinoDoc?

Notes

Screenshot of Rhino object and output glb.


The output glb file is attached.
default.glb (3.8 KB)

Environment

  • Windows11
  • Rhino8
  • .NET7

Any reason you are not using the built in FileGltf.Write method?

@fraguada
As you say, you should use FileGltf.Write().

This time, I achieved the desired result by repeating selection → glb output → deselection without copying all objects.

Thank you advise.