using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.DatabaseServices.Styles;
using System;
using System.Collections.Generic;
using AcEntity = Autodesk.AutoCAD.DatabaseServices.Entity;
namespace C3dTest
{
public class ExplodeLabelTest : IExtensionApplication
{
public static List<string> CurrentLabelBlockComponentsNames;
public void Initialize()
{
Overrule.AddOverrule
(RXClass.GetClass(typeof(FeatureLabel)),
FeatureLabelDaravableOverrule.Instance,
true);
Overrule.AddOverrule
(RXClass.GetClass(typeof(FeatureLabel)),
FeatureLabelTransformOverrule.Instance,
true);
Overrule.AddOverrule
(RXClass.GetClass(typeof(BlockTableRecord)),
BlockTableRecordObjectOverrule.Instance,
true);
}
public void Terminate()
{
}
[CommandMethod("ExplodeLabelWithBlockTest")]
public void Run()
{
Document adoc = Application.DocumentManager.MdiActiveDocument;
Editor ed = adoc.Editor;
Database db = adoc.Database;
PromptEntityOptions entityOptions
= new PromptEntityOptions("\nSelect a label: ");
entityOptions.SetRejectMessage("\nIt's not a label!");
entityOptions.AddAllowedClass(typeof(FeatureLabel), false);
PromptEntityResult result = ed.GetEntity(entityOptions);
if (result.Status != PromptStatus.OK) return;
ObjectId selObjId = result.ObjectId;
int blockComponentsCount;
CurrentLabelBlockComponentsNames = new List<string>();
#pragma warning disable CS0618 // Type or member is obsolete
using (FeatureLabel label = result.ObjectId.Open(OpenMode.ForRead) as FeatureLabel)
using (LabelStyle style = label.StyleId.Open(OpenMode.ForRead) as LabelStyle)
#pragma warning restore CS0618 // Type or member is obsolete
{
ObjectIdCollection blkCompCol
= style.GetComponents(LabelStyleComponentType.Block);
blockComponentsCount = blkCompCol.Count;
foreach (ObjectId blkCompId in blkCompCol)
{
LabelStyleBlockComponent blockComponent
#pragma warning disable CS0618 // Type or member is obsolete
= blkCompId.Open(OpenMode.ForRead) as LabelStyleBlockComponent;
#pragma warning restore CS0618 // Type or member is obsolete
CurrentLabelBlockComponentsNames.Add(blockComponent.Block.BlockName.Value);
}
}
PromptIntegerOptions integerOptions
= new PromptIntegerOptions("\nNumber of repeats: ");
integerOptions.AllowNegative = false;
integerOptions.AllowZero = false;
integerOptions.DefaultValue = 300;
integerOptions.UseDefaultValue = true;
PromptIntegerResult intResult = ed.GetInteger(integerOptions);
if (intResult.Status != PromptStatus.OK) return;
FeatureLabelDaravableOverrule.ViewportDrawCounter = 0;
FeatureLabelDaravableOverrule.WorldDrawCounter = 0;
FeatureLabelTransformOverrule.Counter = 0;
BlockTableRecordObjectOverrule.OpenedCounter = 0;
for (int i = 0; i < intResult.Value; i++)
{
ObjectId[] firstExplodeObjIds;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
FeatureLabel label = tr.GetObject(selObjId, OpenMode.ForRead) as FeatureLabel;
firstExplodeObjIds = ExplodeObject(label, tr);
tr.Commit();
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
foreach (ObjectId id in firstExplodeObjIds)
{
AcEntity ent = tr.GetObject(id, OpenMode.ForWrite) as AcEntity;
if (ent is BlockReference blkRef
&& blkRef.Name.StartsWith("*U", StringComparison.OrdinalIgnoreCase))
{
ExplodeObject(ent, tr);
ent.Erase(true);
}
}
tr.Commit();
}
}
Application.ShowAlertDialog
($"Number of block components: {blockComponentsCount}" +
$"\nNumber of explodes: {intResult.Value}\n" +
$"Drawable ViewportDraw hits: {FeatureLabelDaravableOverrule.ViewportDrawCounter}.\n" +
$"Drawable WorldDraw hits: {FeatureLabelDaravableOverrule.WorldDrawCounter}.\n" +
$"Transform hits: {FeatureLabelTransformOverrule.Counter}\n" +
$"Not closed block table records: {BlockTableRecordObjectOverrule.OpenedCounter}.");
CurrentLabelBlockComponentsNames = null;
}
static ObjectId[] ExplodeObject(AcEntity ent, Transaction tr)
{
Database db = ent.Database;
List<ObjectId> objIds = new List<ObjectId>();
DBObjectCollection objCol = new DBObjectCollection();
ent.Explode(objCol);
BlockTableRecord cSpace = tr.GetObject
(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
foreach (AcEntity dBObject in objCol)
{
ObjectId newObjId = cSpace.AppendEntity(dBObject);
objIds.Add(newObjId);
tr.AddNewlyCreatedDBObject(dBObject, true);
}
return objIds.ToArray();
}
}
public class FeatureLabelTransformOverrule : TransformOverrule
{
public static int Counter = 0;
static FeatureLabelTransformOverrule _instance;
public static FeatureLabelTransformOverrule Instance
{
get
{
if (_instance is null)
{
_instance = new FeatureLabelTransformOverrule();
}
return _instance;
}
}
private FeatureLabelTransformOverrule() { }
public override void Explode(AcEntity entity, DBObjectCollection entitySet)
{
Counter++;
base.Explode(entity, entitySet);
}
}
public class FeatureLabelDaravableOverrule : DrawableOverrule
{
public static int ViewportDrawCounter = 0;
public static int WorldDrawCounter = 0;
static FeatureLabelDaravableOverrule _instance;
public static FeatureLabelDaravableOverrule Instance
{
get
{
if (_instance is null)
{
_instance = new FeatureLabelDaravableOverrule();
}
return _instance;
}
}
private FeatureLabelDaravableOverrule() { }
public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
{
if (drawable is FeatureLabel)
{
ViewportDrawCounter++;
}
base.ViewportDraw(drawable, vd);
}
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
if (drawable is FeatureLabel)
{
WorldDrawCounter++;
}
return base.WorldDraw(drawable, wd);
}
}
public class BlockTableRecordObjectOverrule : ObjectOverrule
{
public static int OpenedCounter = 0;
static BlockTableRecordObjectOverrule _instance;
public static BlockTableRecordObjectOverrule Instance
{
get
{
if (_instance is null)
{
_instance = new BlockTableRecordObjectOverrule();
}
return _instance;
}
}
private BlockTableRecordObjectOverrule() { }
public override void Open(Autodesk.AutoCAD.DatabaseServices.DBObject dbObject, OpenMode mode)
{
if (ExplodeLabelTest.CurrentLabelBlockComponentsNames != null
&& dbObject is BlockTableRecord record
&& ExplodeLabelTest.CurrentLabelBlockComponentsNames.Contains(record.Name))
{
OpenedCounter++;
}
base.Open(dbObject, mode);
}
public override void Close(Autodesk.AutoCAD.DatabaseServices.DBObject dbObject)
{
if (ExplodeLabelTest.CurrentLabelBlockComponentsNames != null
&& dbObject is BlockTableRecord record
&& ExplodeLabelTest.CurrentLabelBlockComponentsNames.Contains(record.Name))
{
OpenedCounter--;
}
base.Close(dbObject);
}
}
}