wait, what about a block insert, isn't that graphical?
So if I picked a line, within a block insert, within an xref, I would expect the ownerID of the line to be the ID of an insert.
In the case of a plain line, it is essentially not nested.
Dim obj As Object = CType(tm.GetObject(globalIDArray(level), OpenMode.ForRead), Object)
' Time to see if we can process this entity type
Select Case aType.FullName
'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord
Case "Autodesk.AutoCAD.DatabaseServices.BlockReference"
blkRef = CType(tm.GetObject(resCont(0), OpenMode.ForRead, True), AcDb.BlockReference)
Case "Autodesk.AutoCAD.DatabaseServices.BlockTableRecord"
btr = CType(tm.GetObject(resCont(0), OpenMode.ForRead, True), AcDb.BlockTableRecord)
Case Else
ent = CType(tm.GetObject(resCont(0), OpenMode.ForRead, True), AcDb.Entity)
End Select
Only thing I did not like is that I cannot encapsulate the whole process, and get the specific object back.
I would perfer to do a function like:
public function EntGetNet(byval objID as objectID) as object
but have it return a specific object already cast to the right type. Is there a way to do that?
#region Using declarations
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;
#endregion
[assembly: CommandClass(typeof(ClassLibrary.tcgsClass))]
namespace ClassLibrary
{
/// <summary>
/// Summary description for tcgsClass.
/// </summary>
public class tcgsClass
{
public tcgsClass( ) { }
// Define Command "LNE"
[CommandMethod("LNE")]
static public void ListNestedEntityCommand( )
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Set up the options...
PromptNestedEntityOptions pneOpts = new PromptNestedEntityOptions("\nSelect entity: ");
pneOpts.AllowNone = false;
// Ask the question...
PromptNestedEntityResult pneRes = ed.GetNestedEntity(pneOpts);
// Were we successful...?
if (pneRes.Status != PromptStatus.OK)
return;
// Cast to an 'Entity' as this is the lowest common object type
// in the inheritance tree for graphical entities...
Entity selectedEntity = tr.GetObject(pneRes.ObjectId, OpenMode.ForRead, false) as Entity;
// List some info about it...
DumpEntityInfo(selectedEntity);
// Get the list of 'graphical' containers for the entity picked...
ObjectId[] containerIds = pneRes.GetContainers();
// This should never happen, but check anyway...
if (containerIds == null || containerIds.Length == 0)
return;
// Loop over the array of containers and dump some info...
foreach (ObjectId containerId in containerIds)
{
Entity containerEnt = tr.GetObject(containerId, OpenMode.ForRead, false) as Entity;
DumpEntityInfo(containerEnt);
}
// Commit the transaction...
tr.Commit();
}
}
static private void DumpEntityInfo(Entity ent)
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ed.WriteMessage("\nType of selected entity: {0}", ent.GetType());
ed.WriteMessage("\nDXF name: {0}", ent.GetRXClass().DxfName);
ed.WriteMessage("\nARX class name: {0}", ent.GetRXClass().Name);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// See if the type of ent is an AcDbBlockReference...
// Shows one way of using 'RTTI' to discover the type
// of an object at runtime...not really necessary in this
// case, as the 'container' will always be ultimately of
// type AcDbBlockReference.
if (ent.GetType() == typeof(BlockReference))
{
// Cast the entity to a block reference...
BlockReference blkRef = ent as BlockReference;
// Did the cast succeed?
if (blkRef == null)
return;
// Get the objectid of the AcDbBlockTableRecord representing/defining
// this insert and open it up...
BlockTableRecord btr = tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead, false) as BlockTableRecord;
// Print out it's name...
ed.WriteMessage("\nBlock name: {0}", btr.Name);
if (btr.IsFromExternalReference || btr.IsFromOverlayReference)
ed.WriteMessage("\nXref: true");
}
tr.Commit();
}
ed.WriteMessage("\n\n");
}
}
}
That "variant" collection would serve the same purpose as a lisp list, which is powerful in that it stores different data types.