Ah, gotcha. After some testing, I can get the impetus behind this!
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
var rand = new Random();
List<Brep> blocks = new List<Brep>();
for (int i = 0; i < 1000; i++) {
var xInterval = new Interval(rand.Next(-100, 100), rand.Next(-100, 100));
xInterval.MakeIncreasing();
var yInterval = new Interval(rand.Next(-100, 100), rand.Next(-100, 100));
yInterval.MakeIncreasing();
var zInterval = new Interval(rand.Next(-100, 100), rand.Next(-100, 100));
zInterval.MakeIncreasing();
var box = new Box(Plane.WorldXY, xInterval, yInterval, zInterval).ToBrep();
if(box == null)
{
i--;
continue;
}
blocks.Add(new Box(Plane.WorldXY, xInterval, yInterval, zInterval).ToBrep());
}
List<Plane> planes = new List<Plane>();
for (int i = 0; i < 1000; i++)
{
var point = new Point3d(
rand.Next(-1000, 1000),
rand.Next(-1000, 1000),
rand.Next(-1000, 1000));
var vector = new Vector3d(
rand.NextDouble() - .5,
rand.NextDouble() - .5,
rand.NextDouble() - .5);
Plane p = new Plane(point, vector);
planes.Add(p);
}
int idef_inx = doc.InstanceDefinitions.Add("test_definition", "A test block definition", Plane.WorldXY.Origin, blocks); // 77 ms
var instance = doc.InstanceDefinitions[idef_inx]; // 2 ms
List<GeometryBase> geometries = new List<GeometryBase>();
geometries = MoveCopyElements(blocks, planes); // 24,824 ms
AddGeometryToDoc(geometries, doc); //~200,000 ms
MoveCopyDefinition(instance, planes, doc); // 66 ms
doc.Views.Redraw();
return Result.Success;
}
private List<GeometryBase> MoveCopyElements(List<Brep> geoms, List<Plane> planes)
{
List<GeometryBase> m_geom_list = new List<GeometryBase>();
foreach (var plane in planes)
{
foreach (var geom in geoms)
{
var moved_brep = geom.DuplicateShallow();
Transform xform = Transform.PlaneToPlane(Plane.WorldYZ, plane);
moved_brep.Transform(xform);
m_geom_list.Add(moved_brep);
}
}
return m_geom_list;
}
private void AddGeometryToDoc(List<GeometryBase> list, RhinoDoc doc)
{
foreach(var geom in list) doc.Objects.Add(geom);
}
private void MoveCopyDefinition(InstanceDefinition def, List<Plane> planes, RhinoDoc doc)
{
List<InstanceDefinition> m_def_list = new List<InstanceDefinition>();
foreach (var plane in planes) {
var xform = Transform.PlaneToPlane(Plane.WorldXY, plane);
doc.Objects.AddInstanceObject(def.Index, xform);
}
}
It seems moving and placing block instances is significantly faster than moving and adding Breps. That said, I’m not sure how you could have multiple instances of a BlockDefinition without adding them to the document - if that’s what you want, then go for instances. If it is just for visualization, I would recommend having a display mesh as a property of your class. From what I understand, they are lightweight to move and efficient to display with the DisplayPipeline, with the idea that you create and modify the mesh only when the base geometry is modified and updated.