Making AutoCAD objects annotative using .NET
In the last post we looked at how to add a new annotative scale to an AutoCAD drawing.
In this post we'll look at what's needed to make an object annotative - providing it's of a type that supports annotation scaling, of course. Once again, this post is based on functionality introduced in AutoCAD 2008.
I hit my head against the problem for a while, having tried my best to convert the technique shown in the AnnotationScaling ObjectARX sample (which uses a protocol extension to access objects stored in an annotative entity's extension dictionary) to .NET. I finally ended up asking our Engineering team: Ravi Pothineni came back with some code that uses an internal assembly (but one that ships with AutoCAD) to do this. Apparently this will become standard functionality in a future release of AutoCAD - it'll just be available directly from DBObject, rather than being in a separate "helper" - but in the meantime you will have to use slightly more cumbersome code, such as that shown below, and add a reference to AcMgdInternal.dll for it to work. As indicated by the name, this functionality is unsupported and to be used at your own risk.
Here's the C# code - the "ADS" command is basically the one shown previously (renamed from "AS") and the "ATS" function is the new command that makes an object annotative, attaching annotation scales to it:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Internal;
namespace AnnotationScaling
{
public class Commands
{
[CommandMethod("ADS")]
static public void addScale()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
ObjectContextManager ocm =
db.ObjectContextManager;
if (ocm != null)
{
// Now get the Annotation Scaling context collection
// (named ACDB_ANNOTATIONSCALES_COLLECTION)
ObjectContextCollection occ =
ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
if (occ != null)
{
// Create a brand new scale context
AnnotationScale asc = new AnnotationScale();
asc.Name = "MyScale 1:28";
asc.PaperUnits = 1;
asc.DrawingUnits = 28;
// Add it to the drawing's context collection
occ.AddContext(asc);
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
[CommandMethod("ATS")]
static public void attachScale()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ObjectContextManager ocm =
db.ObjectContextManager;
ObjectContextCollection occ =
ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
PromptEntityOptions opts =
new PromptEntityOptions("\nSelect entity: ");
opts.SetRejectMessage(
"\nEntity must support annotation scaling."
);
opts.AddAllowedClass(typeof(DBText), false);
opts.AddAllowedClass(typeof(MText), false);
opts.AddAllowedClass(typeof(Dimension), false);
opts.AddAllowedClass(typeof(Leader), false);
opts.AddAllowedClass(typeof(Hatch), false);
PromptEntityResult per = ed.GetEntity(opts);
if (per.ObjectId != ObjectId.Null)
{
DBObject obj =
tr.GetObject(per.ObjectId, OpenMode.ForRead);
if (obj != null)
{
obj.UpgradeOpen();
obj.Annotative = AnnotativeStates.True;
ObjectContexts.AddContext(obj, occ.GetContext("1:1"));
ObjectContexts.AddContext(obj, occ.GetContext("1:2"));
ObjectContexts.AddContext(obj, occ.GetContext("1:10"));
ObjectContext oc = occ.GetContext("MyScale 1:28");
if (oc != null)
{
ObjectContexts.AddContext(obj, oc);
}
}
}
tr.Commit();
}
}
}
}
You'll notice that if you run the ADS command before ATS, you'll also get the newly-added annotation scale in the selected object's list:
April 27, 2007 in Annotation scaling, AutoCAD, AutoCAD .NET | Permalink | Comments (23) | TrackBack
Adding a new annotation scale in AutoCAD using .NET
Thanks to Nikolay Poleshchuk and Roland Feletic for suggesting this topic, and to Wayne Brill, from DevTech Americas, for providing the code.
In this post we're going to look at some functionality that's specific to AutoCAD 2008 - adding a new annotative scale to a drawing. The next post (assuming I can work out how to do it :-) will cover how you can attach a scale programmatically to make an entity annotative.
Firstly, I should cover what the annotation scaling feature is all about...
Here's a quick overview from the AutoCAD 2008 online help:
Objects that are commonly used to annotate drawings have a property called Annotative. This property allows you to automate the process of scaling annotations so that they plot or display at the correct size on the paper.
Instead of creating multiple annotations at different sizes and on separate layers, you can turn on the annotative property by object or by style, and set the annotation scale for layout or model viewports. The annotation scale controls the size of the annotative objects relative to the model geometry in the drawing.
The following objects are commonly used to annotate drawings and contain an annotative property:
- Text
- Dimensions
- Hatches
- Tolerances
- Multileaders
- Blocks
- Attributes
When the Annotative property for these objects is turned on (set to Yes), these objects are called annotative objects.
Here's some code in C# that creates a new annotation scale and adds it to the active drawing in AutoCAD:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace AnnotationScaling
{
public class Commands
{
[CommandMethod("AS")]
static public void addScale()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
ObjectContextManager cm =
db.ObjectContextManager;
if (cm != null)
{
// Now get the Annotation Scaling context collection
// (named ACDB_ANNOTATIONSCALES_COLLECTION)
ObjectContextCollection occ =
cm.GetContextCollection("ACDB_ANNOTATIONSCALES");
if (occ != null)
{
// Create a brand new scale context
AnnotationScale asc = new AnnotationScale();
asc.Name = "MyScale 1:28";
asc.PaperUnits = 1;
asc.DrawingUnits = 28;
// Add it to the drawing's context collection
occ.AddContext(asc);
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
}
}
Here's the new annotation scale, selected manually in the Property Palette after running the code:
In the next post we'll look at what it takes to make an object annotative programmatically, by setting its annotative property and annotation scale.
April 25, 2007 in Annotation scaling, AutoCAD, AutoCAD .NET | Permalink | Comments (4) | TrackBack

Atom

