Merge RhinoDocs in C#

Good Morning,

I’m hunting for a good way to merge content in two separate RhinoDoc’s which I have generated programatically. I see that i could call A.Import(filepath) but then i’d have to write B to disk. There is no docA.Import(docB)

I wrote the below which works fine for geometry but fails for Text Objects - I assume because the dimension styles don’t copy over? not quite sure how i’d copy them.

I wonder if @dale or @stevebaer might have a sample or a better approach?

Thanks!

private static List<Guid> ImportFromTo(RhinoDoc sDoc, RhinoDoc tDoc) {
			List<Guid> tObjects = new List<Guid>();

			// work layer by layer and copy over objects 
			foreach (var sLayer in sDoc.Layers) {
				// ensure we have a target layer
				var tLayer = tDoc.Layers.FindName(sLayer.Name);
				if (tLayer == null) {
					var id = tDoc.Layers.Add(sLayer.Name, sLayer.Color);
					if (id < 0) throw new Exception("Could not create layer " + sLayer.Name);
					tLayer = tDoc.Layers[id];
				}

				// now copy over objects
				var sObjects = sDoc.SelectObjectsOnLayer(sLayer);

				foreach (var sObject in sObjects) {
					var tGuid = tDoc.Objects.Add(sObject.DuplicateGeometry(), new ObjectAttributes {
						LayerIndex = tLayer.Index,
						ColorSource = sObject.Attributes.ColorSource,
						ObjectColor = sObject.Attributes.ObjectColor
					});

					tObjects.Add(tGuid);
				}
			}

			return tObjects;
		}

The merging logic when importing documents into existing documents is pretty complicated in order to deal with id and name conflicts that often happen for different objects and tables. We don’t really have a merge function in our SDK. I would recommend writing one of the documents to a temporary file on disk and letting the import function handle the merge.

2 Likes

Thank you @stevebaer , I’ve taken this approach & it works with one challenge - how can I suppress the user prompts during import? I’ve a few hundred files to merge. doc.Import doesn’t appear to have further options I can specify (at least in v7)

image

Looks like Import calls the same method as ReadFile but there i can specify options:

		FileReadOptions readoptions = new FileReadOptions() {
			ImportMode       = true,
			BatchMode        = true,
			UseScaleGeometry = true,
			ScaleGeometry    = false, 
		};
		if (!RhinoDoc.ReadFile(tempPath, readoptions)) 

However the BatchMode and UseScaleGeometry (see options here) are not being respected as the user is still prompted during import :frowning:

Further research shows other people with the same issue:
RhinoDoc.ReadFile interrupted with ‘import scaling - DimensionNumbers’ - Rhino Developer - McNeel Forum
RhinoDoc.Import() is interrupted with ‘import scaling’ confirmation - Grasshopper Developer - McNeel Forum
& https://mcneel.myjetbrains.com/youtrack/issue/RH-67948

Is there any way to work around this prompt in Rhino 7?

Hi @david.birch.uk,

How about something like this?

import Rhino
import scriptcontext as sc

def test():
    files = []
    files.append(r"C:\Users\Dale\Downloads\1.3dm")
    files.append(r"C:\Users\Dale\Downloads\2.3dm")
    files.append(r"C:\Users\Dale\Downloads\3.3dm")
    files.append(r"C:\Users\Dale\Downloads\4.3dm")
    files.append(r"C:\Users\Dale\Downloads\5.3dm")
    
    for file in files:
        cmd = "_-Import \"{0}\" _Enter".format(file)
        Rhino.RhinoApp.RunScript(cmd, True)
    
if __name__ == "__main__":
    test()

– Dale

1 Like

Thank you @dale !

That works like a charm! no prompts to be seen anywhere! :grinning:

How strange that importing via the commandline doesn’t give prompts but the RhinoCommon Import commands do give prompts - I’d imagine they eventually call the same functions inside. :thinking:

This is something we are trying to remedy in RhinoCommon in Rhino 8.

1 Like

Thanks Steve, I look forward to migrating to .net 7 and Rhino 8 :slight_smile: