The inline comments should explain each segment, a few things to point out are:
- We use two functions - one as our entry point with the AutoCAD defined command, and the other as a support function called by the main one.
- We use some of the provided object methods from the AutoCAD API. For example, as we work with an MText object we use the predefined Location method to determine the coordinates.
Some of the features we will add on in future posts can be:
- Prompt options to allow the user to change the circle color, size, etc.
- Place circles around Text objects as well as MText.
- Place circles around Text/MText objects that match a string provided by the user.
Here is the C# code:
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
Autodesk.AutoCAD.Runtime;
using
Autodesk.AutoCAD.ApplicationServices;
using
Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using
Autodesk.AutoCAD.Geometry;
namespace SLD
{
public class SLDtools
{
[CommandMethod("SLDcirText")]
public void SLDcirText()
{
//get current document
Document acDoc =
Application.DocumentManager.MdiActiveDocument;
//get AutoCAD database
Database acCurDb = acDoc.Database;
//start db transaction
using (Transaction acTrans =
acCurDb.TransactionManager.StartTransaction())
{
//open block table
/*all drawing objects
are in the block table so in
order to look at
each object we need to have the
block table open
for read*/
BlockTable bt = (BlockTable)acTrans.GetObject
(acCurDb.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)
acTrans.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead);
//iterate through
block table to locate mtext objects
/*this foreach loop
will loop through the block table
record looking
at each object in the drawing.*/
foreach (ObjectId id in btr)
{
//open each object to
read
DBObject obj =
acTrans.GetObject
(id, OpenMode.ForRead);
//only deal with
MText objects
MText dbMText = obj as MText;
//if current object
is Mtext then draw a circle
//around it
if (dbMText != null)
{
//call separate function to draw circle
/*here we want to pass the acad db, the current
transaction, and the mtext object that we want
to draw a circle around*/
SLDdrawCir(acCurDb, acTrans, dbMText);
}
}
//commit the
transaction so we do not leave the db open
acTrans.Commit();
}
}
//function to draw circle around an MText object
public void SLDdrawCir(Database acCurDb,
Transaction acTrans, MText MtextObj)
{
//define a new point object for the center
point of circle
Point3d cenPoint = new Point3d();
//use the location method of the Mtext object
to define
//the center point coordinates
cenPoint = MtextObj.Location;
//define a new Circle object
/*we use the center point defined above,
assign a diameter
and assign a color using the
ColorIndex method from the
circle object*/
Circle textCir = new Circle();
textCir.Center = cenPoint;
textCir.Diameter = 1.0;
textCir.ColorIndex = 1;
//now add the circle to the drawing (model
space)
/*We need to add it to the block table, this
is the same
basic operations when adding
geometry to a drawing*/
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(
acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(
acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite)
as BlockTableRecord;
acBlkTblRec.AppendEntity(textCir);
acTrans.AddNewlyCreatedDBObject(textCir, true);
}
}
}
To test this build the solution and NETLOAD the .dll into AutoCAD. Place some MText objects in the drawing and then type in SLDcirText at the command line.
Hi I have just seen your post about drawing circles around mtext. This would be extremely useful for what I am trying to do. However I am having difficulty getting your programme to work. You will have to excuse me I am very new to this side of AutoCAD having only just started using lisp files. Is there any way you could simplify the steps of what I need to do to get this programme to work. I am currently using AutoCAD 2012. Many thanks for your time. Sally
ReplyDeleteHi Sally, thanks for reading! To get this program to work you can just copy and paste the code into a C#.Net solution using Microsoft Visual Studio. This might sound intimidating if you are new to programming but please read my post on getting started with this development environment http://www.streamlined-design.blogspot.com/2010/09/custom-apps.html
DeleteThis will guide you through the entire process of downloading the (Free) software from Microsoft, installing it, creating a new solution, and then loading the program into AutoCAD. Please let me know if this helps.
This comment has been removed by the author.
ReplyDeleteHi, I am new to progaramming. How to do if I want a circle a text which is on a certain layer? Thanks
ReplyDeleteHi oakam, great question which is a good exercise for learning. In the original code we are looking through each object in the drawing and then only dealing with MText objects. We could further our requirements (i.e. only deal with MText objects on a certain layer by adding an additional check in the:
ReplyDeleteif (dbMtext != null) section. It would look like this:
if (dbMtext != null)
{
if (dbMtext.Layer == "G-TEXT") //this is the new conditional check
{
SLDdrawCir(acCurDb, acTrans, dbMtext);
}
}
This updated code will only call the SLDdrawCir function if the MText entity is on the layer G-TEXT.
I hope this helps.