using System; using System.Collections.Generic; using System.Linq; using Rhino; using Rhino.DocObjects; using Rhino.Commands; using Rhino.Input.Custom; namespace sample.Commands { [System.Runtime.InteropServices.Guid("C096BA1E-CC6F-4133-B228-CE6DFC695BEC")] public class sampleEmbedBlocks : Command { static sampleEmbedBlocks _instance; public sampleEmbedBlocks() { _instance = this; } ///The only instance of the sampleEmbedBlocks command. public static sampleEmbedBlocks Instance { get { return _instance; } } public override string EnglishName { get { return "sampleEmbedBlocks"; } } protected override Result RunCommand(RhinoDoc doc, RunMode mode) { GetObject getObject = new GetObject(); getObject.SetCommandPrompt("Select blocks to embed"); getObject.EnablePreSelect(true, true); getObject.GeometryFilter = ObjectType.InstanceReference; getObject.GetMultiple(1, 0); if (getObject.CommandResult() != Result.Success) return getObject.CommandResult(); ObjRef[] objRefs = getObject.Objects(); List blocksToEmbed = objRefs.Select(x => x.Object() as InstanceObject).ToList(); EmbedBlocks(blocksToEmbed, doc, true); return Result.Success; } static void EmbedBlocks(List instanceobjects, RhinoDoc Doc, bool includeNestedreferences) { var namesOfInstanceObjectsToEmbed = instanceobjects.Select(x => x.InstanceDefinition.Name); var distinctNames = namesOfInstanceObjectsToEmbed.Distinct(); if (includeNestedreferences) { List NestedBlocks; List NonNestedBlocks; GetAllBlocksList(instanceobjects, out NestedBlocks, out NonNestedBlocks); var allBlocks = NonNestedBlocks.Union(NestedBlocks); namesOfInstanceObjectsToEmbed = allBlocks.Select(x => x.InstanceDefinition.Name); distinctNames = namesOfInstanceObjectsToEmbed.Distinct(); } var instanceDefinitionsToEmbed = Doc.InstanceDefinitions.Where(x => namesOfInstanceObjectsToEmbed.Contains(x.Name)).ToList(); for (int i = instanceDefinitionsToEmbed.Count - 1; i >= 0; i--) { Doc.InstanceDefinitions.DestroySourceArchive(instanceDefinitionsToEmbed[i], true); } } static void GetAllBlocksList(List inputBlocks, out List NestedBlocks, out List NonNestedBlocks) { NonNestedBlocks = new List(); NestedBlocks = new List(); List _tempNested = new List(); foreach (InstanceObject instObj in inputBlocks) { if (CheckIfNestedBlock(instObj)) { NestedBlocks.Add(instObj); _tempNested.Add(instObj); } else { NonNestedBlocks.Add(instObj); } } while (_tempNested.Count > 0) { for (int i = 0; i < NestedBlocks.Count; i++) { if (_tempNested.Contains(NestedBlocks[i])) { InstanceDefinition definition = NestedBlocks[i].InstanceDefinition; RhinoObject[] blockObjects = definition.GetObjects(); foreach (RhinoObject rObj in blockObjects) { if (rObj.ObjectType == ObjectType.InstanceReference) { InstanceObject instChildObj = rObj as InstanceObject; if (!CheckIfNestedBlock(instChildObj)) { NonNestedBlocks.Add(instChildObj); } else { NestedBlocks.Add(instChildObj); _tempNested.Add(instChildObj); } } } _tempNested.Remove(NestedBlocks[i]); } } } } static bool CheckIfNestedBlock(InstanceObject instanceObj) { bool isNested = false; RhinoObject[] blockElements = instanceObj.InstanceDefinition.GetObjects(); var childBlocks = blockElements?.Where(x => x.ObjectType == ObjectType.InstanceReference)?.ToList(); if (childBlocks != null) { if (childBlocks.Count > 0) isNested = true; } return isNested; } } }