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;
}
}
}