Click here to Skip to main content
15,886,026 members
Articles / Programming Languages / C#
Article

Using DOTNETARX To Develop Your .NET ObjectARX Applications

Rate me:
Please Sign up or sign in to vote.
3.12/5 (11 votes)
7 Jun 20055 min read 108.7K   3.4K   36   21
With the help of DOTNETARX, .NET programmers can write their ObjectARX programs more easily.

Introduction

With the newest AutoCAD 2006, the .NET programmers can use the ObjectARX Managed Wrapper Classes to develop their AutoCAD programs. But there are many inconveniences and bugs in the wrapper classes. For example, you cannot do conditional filtering, and many global functions in C++ is not provided in the wrapper class. To solve the problems, I have developed a tool “DOTNETARX” to help the .NET programmers to write the ObjectARX programs more easily.

First, let’s look at the traditional ObjectARX programs written in C#. The following example adds an entity to the AutoCAD.

C#
Entity ent……; 
Database db= Application.DocumentManager.MdiActiveDocument.Database; 
DBTransMan tm=db.TransactionManager; 
using(Transaction trans=tm.StartTransaction()) 
{
  BlockTable bt=(BlockTable)tm.GetObject(db.BlockTableId,OpenMode. ForRead,false); 
  BlockTableRecord btr=
    (BlockTableRecord)tm.GetObject(bt[BlockTableRecord.ModelSpace],
    OpenMode.ForWrite,false);
  btr.AppendEntity(ent); 
  tm.AddNewlyCreatedDBObject(ent,true);
  trans.Commit(); 
}

Oh, I have to write so many codes only to add an entity!! Even more, when I want change the property (such as color) of the entity after it is added into the AutoCAD, I must use the same codes to open the entity (using the transaction) and then change its property. Can it be done more easily? The answer is DOTNETARX. With this tool, you can write the above codes like this:

C#
Entity ent……. 

Tools.AddEntity(ent);

Note: To use DOTNETARX, you must add the reference to “DOTNETARX.dll”, and import the DOTNETARX namespace in your source code:

C#
using DOTNETARX;

Now, you only need two lines of codes to finish the same thing! Can’t believe it? It’s true, your work will become simple with DOTNETARX.

DOTNETARX is a .NET assembly with many useful classes. Let’s see the main classes in DOTNETARX.

The most important class in DOTNETARX is Tools. The members of this class are static. It has the following members:

  • Properties:
    • Database: gets the current AutoCAD database.
    • Editor: gets the editor associated with the current document.
    • TransactionManager: gets transaction manager of the current database.
  • Functions:

    With the three properties, you can replace the long codes such as Application.DocumentManager.MdiActiveDocument.Database with Tools.Database.

    • public static ObjectId AddEntity(Entity ent)

      Adds an entity to the current AutoCAD drawing. The following codes add a line to the database:

      C#
      Line line;
      
      …….
      
      Tools.AddEntity(line);
    • public static ObjectId AddSymbolTableRecord(SymbolTableRecord str,ObjectId symbolTableId)

      Adds symbol table records to the current database. The following codes add a new layer to the database:

      C#
      LayerTableRecord ltr;
      ……
      Tools.AddSymbolTableRecord(ltr,Tools.Database.LayerTableId);
    • public static ObjectId AddDictionaryObject(string searchKey)

      Adds the dictionary object to the current database.

    • public static ObjectId AddDictionaryObject(string searchKey,DBObject newValue,ObjectId ownerId)

      Adds dictionary objects such as XRecords and groups.

    • Functions used to set or get the general properties of an entity:

      The properties are: Color, ColorIndex, Layer, Linetype, LinetypeScale, LineWeight, PlotStyleName and Visible. The name of the function which sets the general properties of an entity starts with Put, and then followed by the property’s name. For example, PutColor is used to set the color of an entity. There are two forms of this kind of function.

      1. The first one is PutColor(Entity ent,Color color), the ent parameter is for the entity, and color is for the color value.
      2. The second one is PutColor(ObjectId id,Color color), the id parameter is for the object Id of the entity, and color is for the color value.

      The name of the function which gets the general properties of an entity starts with Get, and then followed by the property’s name. For example, GetColor is used to get the color of an entity. There are two forms of this kind of function.

      1. The first one is GetColor(Entity ent), the ent parameter is for the entity.
      2. The second one is GetColor(ObjectId id), the id parameter is for the object Id of the entity.
    • public static void Move(Entity ent,Point3d fromPoint,Point3d toPoint)

      Moves an entity object along a vector.

    • public static void Rotate(Entity ent,Point3d basePoint,double rotationAngle)

      Rotates an entity object around a base point.

    • public static void Scale(Entity ent,Point3d basePoint,double scaleFactor)

      Scales an entity object equally in the X, Y, and Z directions.

    • public static ObjectId Mirror(Entity ent,Point3d mirrorPoint1,Point3d mirrorPoint2,bool eraseSourceObject)

      Creates a mirror-image copy of a planar entity object around an axis.

    • public static ObjectId Copy(Entity ent)

      Duplicates the given entity object to the same location.

    • public static void Erase(Entity ent)

      Erases the given entity object.

    • public static Entity GetEntity(ObjectId id)

      Gets AutoCAD entity object by its object ID.

    • public static DBObject GetDBObject(ObjectId id)

      Gets AutoCAD DBObject by its object ID.

    • public static DBObjectCollection GetIteratorForSymbolTable(ObjectId id)

      Gets an iterator. It is used to iterate through a symbol table record.

    • public static ObjectIdCollection GetIteratorForSymbolTableID(ObjectId id)

      Gets an iterator. It is used to iterate through a symbol table record.

    • public static Point3d GetMidPoint(Point3d pt1,Point3d pt2)

      Gets the midpoint of two points.

The other classes in DOTNETARX are derived from the AutoCAD entity classes such as Circle and Line.

By the latest edition of DOTNETARX, I have derived from the following classes:

Line, Circle, Arc, Ellipse, Polyline, DBText, MText, Table, Hatch and the Dimensions. The names of the new classes are their ancestors’ name and with appended an ‘s’. For example, Lines is the derived class of Line. The first purpose of the derived classes is to create entities more easily. For example, you can only use center, radius and vector to create a circle with the original constructor of the Circle class. But with the help of DOTNETARX, you can use three or two points to create a circle. The following example explains how to create a circle through three points:

C#
Circles circle=new Circles(pt1,pt2,pt3);

For detailed explanation, you can refer to the help document in the accessory.

The second purpose of the derived classes is to access the entity which is added into the database. We take two examples to explain this. First is not using the derived classes:

C#
Circle circle=new Circle (center,normal,radius); 
//Because the circle is not added into database, 
//changing the circle’s radius is allowed 
circle.Radius=1;
//Add the circle into the database 
Tools.AddEntity(circle);
circle. Radius =2;
//Error,because the circle is added into the database,
//you must open it first, then operate on it

Codes using the derived classes:

C#
Circles circle =new Circles (center, radius);//even the constructor is more simple
      circle. Radius =1;// Because the circle is not added into database, 
                        // changing the circle’s radius is allowed

Tools.AddEntity(circle);// Add the circle into the database 
// Though the circle is added into the database, you can edit its property
circle. Radius =2;

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
ray889912-Sep-10 5:27
ray889912-Sep-10 5:27 
QuestionOpen and send command to Acad Pin
Habeeb.net21-Jul-08 5:05
Habeeb.net21-Jul-08 5:05 
GeneralDotNetARX 5.0 supports for Linq and .NET3.5 features such as extension method Pin
csharpbird7824-Nov-07 20:12
csharpbird7824-Nov-07 20:12 
GeneralUCS Pin
shers11-Nov-07 19:21
shers11-Nov-07 19:21 
Can anybody tell me where I have gone wrong? As this code is intended to change the ucs after the XATTACH command ends, it does not change back to the previous ucs. Here is the code.

using Autodesk.AutoCAD.ApplicationServices;<br />
using Autodesk.AutoCAD.Runtime;<br />
using Autodesk.AutoCAD.EditorInput;<br />
using Autodesk.AutoCAD.DatabaseServices;<br />
using Autodesk.AutoCAD.Colors;<br />
using Autodesk.AutoCAD.Geometry;<br />
<br />
using System;<br />
using System.Collections.Specialized;<br />
using System.Windows.Forms;<br />
<br />
namespace XU2<br />
{<br />
    public class XU:IExtensionApplication<br />
    {<br />
        public static Matrix3d ucs;<br />
<br />
        public void Initialize()<br />
        {<br />
            DocumentCollection dm = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;<br />
            dm.DocumentLockModeChanged += new DocumentLockModeChangedEventHandler(Change);<br />
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;<br />
            doc.CommandEnded += new CommandEventHandler(doc_CommandEnded);<br />
           <br />
        }<br />
<br />
        public void Terminate()<br />
        {<br />
        }<br />
<br />
        private void Change(object sender,DocumentLockModeChangedEventArgs e)<br />
        {<br />
            if (e.GlobalCommandName == "XATTACH")<br />
            {<br />
                ModifyLayers();<br />
                CreateLayer();<br />
                ucs = UCS2WCS();<br />
            }<br />
        }<br />
<br />
        private static ObjectId CreateLayer()<br />
        {<br />
            ObjectId layerId = ObjectId.Null;//the return value for this function<br />
            Database db = HostApplicationServices.WorkingDatabase;<br />
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;<br />
<br />
            using (Transaction trans = db.TransactionManager.StartTransaction())<br />
            {<br />
                //Get the layer table first...<br />
                LayerTable lt = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForRead);<br />
<br />
                //Check if 0-XREF exists;;;<br />
                if (lt.Has("0-XREF"))<br />
                {<br />
                    layerId = lt["0-XREF"];<br />
                    db.Clayer = layerId;<br />
                }<br />
                else<br />
                {<br />
                    //if not, create the layer here.<br />
                    LayerTableRecord ltr = new LayerTableRecord();<br />
                    ltr.Name = "0-XREF";<br />
                    ltr.Color = Color.FromColorIndex(ColorMethod.ByAci, 1);<br />
                    ltr.IsFrozen = false;<br />
                    ltr.IsLocked = false;<br />
                    ltr.IsOff = false;<br />
                    //upgrade the open from read to write<br />
                    lt.UpgradeOpen();<br />
                    layerId = lt.Add(ltr);<br />
                    trans.AddNewlyCreatedDBObject(ltr, true);<br />
                    db.Clayer = layerId;<br />
                }<br />
                trans.Commit();<br />
            }<br />
            return layerId;<br />
        }<br />
<br />
        public void ModifyLayers()<br />
        {<br />
            Database db = HostApplicationServices.WorkingDatabase;<br />
<br />
            try<br />
            {<br />
                using (Transaction tr = db.TransactionManager.StartTransaction())<br />
                {<br />
                    LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);<br />
                    foreach (ObjectId objId in lt)<br />
                    {<br />
                        LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(objId, OpenMode.ForWrite);<br />
<br />
                        if (ltr.Name == "0" || ltr.Name == "Defpoints")<br />
                        {<br />
                            if (ltr.IsLocked) { ltr.IsLocked = false; }<br />
                            if (ltr.IsFrozen) { ltr.IsFrozen = false; }<br />
                            if (ltr.IsOff) { ltr.IsOff = false; }<br />
                        }<br />
                    }<br />
                }<br />
            }<br />
            catch (System.Exception ex)<br />
            {<br />
                MessageBox.Show(ex.Message);<br />
            }<br />
            <br />
        }<br />
<br />
        public static Matrix3d UCS2WCS()<br />
        {<br />
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;<br />
<br />
            Matrix3d original = ed.CurrentUserCoordinateSystem;<br />
<br />
            ed.CurrentUserCoordinateSystem = Matrix3d.Identity;<br />
<br />
            return original;<br />
       <br />
        }<br />
<br />
        void doc_CommandEnded(object sender, CommandEventArgs e)<br />
        {<br />
            try<br />
            {<br />
                if (e.GlobalCommandName == "XATTACH")<br />
                {<br />
                    Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;<br />
                    ed.WriteMessage("\n The command is XATTACH");<br />
                    ed.CurrentUserCoordinateSystem = ucs;<br />
                    ed.WriteMessage("\n" + ucs);<br />
                }                <br />
            }<br />
            catch (System.Exception ex)<br />
            {<br />
                MessageBox.Show(ex.Message);<br />
            }<br />
        }<br />
       <br />
    }<br />
}


Thanks
QuestionHow can I write a program for AutoCad? Pin
mrv230026-Sep-07 22:44
mrv230026-Sep-07 22:44 
GeneralNeed advise when using Autocad file Pin
sanong27-Aug-07 19:41
sanong27-Aug-07 19:41 
GeneralPS to previous post on Acad 2007 Pin
tedcx26-Jan-07 8:58
tedcx26-Jan-07 8:58 
GeneralAcad 2007 upgrade Pin
tedcx26-Jan-07 8:54
tedcx26-Jan-07 8:54 
QuestionTools.AddEntity(circle) throws an exception Pin
tedcx25-Jan-07 13:36
tedcx25-Jan-07 13:36 
QuestionUsing command line arguements Pin
davethiss1-Sep-06 6:15
davethiss1-Sep-06 6:15 
QuestionAutoCAD 2006 Pin
Varun Jain 78626-Aug-06 20:04
Varun Jain 78626-Aug-06 20:04 
Generalinstallation of autocad 2006 Pin
Adnan Siddiqi14-Jun-05 19:19
Adnan Siddiqi14-Jun-05 19:19 
QuestionWhere's the CODE? Pin
Bababooey10-Jun-05 21:34
Bababooey10-Jun-05 21:34 
GeneralDOTNETARX now can use conditional selectionset. Pin
arxbird9-Jun-05 14:57
arxbird9-Jun-05 14:57 
QuestionNo sources ??? Pin
Hartmut Kluge7-Jun-05 22:19
Hartmut Kluge7-Jun-05 22:19 
AnswerRe: No sources ??? Pin
arxbird8-Jun-05 15:44
arxbird8-Jun-05 15:44 
GeneralRe: No sources ??? Pin
Apuhjee21-Nov-06 19:17
Apuhjee21-Nov-06 19:17 
GeneralRe: No sources ??? Pin
djonio14-Dec-06 1:15
djonio14-Dec-06 1:15 
GeneralFinally an Article in this topic!! Pin
anderslundsgard7-Jun-05 21:58
anderslundsgard7-Jun-05 21:58 
GeneralRe: Finally an Article in this topic!! Pin
arxbird8-Jun-05 15:40
arxbird8-Jun-05 15:40 
GeneralRe: Finally an Article in this topic!! Pin
anderslundsgard8-Jun-05 21:49
anderslundsgard8-Jun-05 21:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.