October 05, 2011

It’s an interesting little piece of code – nothing very startling, but obviously whenever removing data you have to be a bit careful: in fact I would probably add an “are you sure?” question prior to actually removing the various annotation scales, even if the operation participates in the undo mechanism and can therefore be rolled back easily by the user.

Here’s the C# code for the AIOBJECTSCALEREMOVEOTHERS command (yes, I would normally use a slightly more succinct name, myself, such as DABC for “Delete All But Current”, but I decided to make this one more consistent with the AIOBJECTSCALEREMOVE command).

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

namespace AnnotationScaling

{

publicclassCommands

{

[CommandMethod(

"AIOBJECTSCALEREMOVEOTHERS",

(CommandFlags.Modal | CommandFlags.UsePickSet)

)]

staticpublicvoid RemoveAllButCurrentScale()

{

Document doc =

Application.DocumentManager.MdiActiveDocument;

Database db = doc.Database;

Editor ed = doc.Editor;

// Get the manager object and the list of scales

ObjectContextManager ocm = db.ObjectContextManager;

ObjectContextCollection occ =

ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");

// Prompt the user for objects to process (or get them

// from the pickfirst set)

PromptSelectionOptions pso = newPromptSelectionOptions();

pso.MessageForAdding = "\nSelect annotative objects";

PromptSelectionResult psr = ed.GetSelection(pso);

if (psr.Status != PromptStatus.OK)

return;

// Maintain counters of objects modified and scales removed

int objCount = 0, scaCount = 0;

// Use a flag to check when we first modify an object

bool scalesRemovedForObject = false;

Transaction tr =

doc.TransactionManager.StartTransaction();

using (tr)

{

// If we can't find the current annotation scale in our

// dictionary, we have a problem

if (!occ.HasContext(db.Cannoscale.Name))

{

ed.WriteMessage(

"\nCannot find current annotation scale."

);

return;

}

// Get the ObjectContext associated with the current

// annotation scale

ObjectContext curCtxt =

occ.GetContext(db.Cannoscale.Name);

// Check each selected object

foreach (SelectedObject so in psr.Value)

{

// Open it for read

ObjectId id = so.ObjectId;

DBObject obj = tr.GetObject(id, OpenMode.ForRead);

// Check it's annotative and has the current scale

if (obj.Annotative == AnnotativeStates.True &&

obj.HasContext(curCtxt)

)

{

// Now we get it for write

obj.UpgradeOpen();

// Loop through the various annotation scales in

// the drawing

foreach (ObjectContext oc in occ)

{

// If it's on the object but not current

// (for some reason we have to check the name

// rather than oc == curCtxt)

if (obj.HasContext(oc) &&

oc.Name != db.Cannoscale.Name

)

{

// Remove it and increment our counter/set our

// flag

obj.RemoveContext(oc);

scaCount++;

scalesRemovedForObject = true;

}

}

// Increment our counter for objects once per pass

// and then reset the flag

if (scalesRemovedForObject)

{

objCount++;

scalesRemovedForObject = false;

}

}

}

tr.Commit();

// Report the results

ed.WriteMessage(

"\n{0} scales removed from {1} objects.",

scaCount, objCount

);

}

}

}

}

For fun, I went ahead and manually added the command via the CUI editor, and added it to the corresponding ribbon panel:

If we then launch this command and select some annotative objects, we see that the command reports removing superfluous scales from the selected objects:

Command: AIOBJECTSCALEREMOVEOTHERS

Select annotative objects: Specify opposite corner: 4 found

Select annotative objects:

12 scales removed from 4 objects.

It should be noted that – while it’s unlikely a command this long is going to be entered at the command-line – this command does make use of the implied (aka pickfirst) selection set, should you prefer to prefer working in the noun-verb style. The ribbon item clears the pickfirst selection when launching the command, but it does work if launched via the command-line, in case.