Showing posts with label Sample Code. Show all posts
Showing posts with label Sample Code. Show all posts

Wednesday, August 13, 2008

An Automated Guiding System for Newcomers Using AutoCAD VBA and Microsoft Speech

Have you found the title a little bit confusing? Let me elaborate it. What we are going to see is a simple event oriented AutoCAD VBA program to guide newcomers in a company through proper way until they get familiar with Dos and Don'ts as well as company standards. The program given below is pretty simple and is only intented to show how the system can be implemented. It requires Microsoft Speech (Text-to-speech) to be available in your system. If you wish to implement a comprehensive system, you would better write your code in class modules. Again, this system is not recommended for experienced users as it will definitely check their patience. Here goes the code.

Private Sub AcadDocument_BeginCommand(ByVal CommandName As String)

On Error Resume Next

Dim objSSV As Object

Set objSSV = CreateObject("Sapi.SpVoice")

With objSSV

Select Case CommandName

Case "SAVEAS", "QSAVE", "SAVE"

.speak "Please make sure that the saved drawing version is as per client standard"

Case "BLOCK", "WBLOCK"

.speak "All blocks shall be made in zero layer"

Case "LAYER"

.speak "Please refer CAD manual for standard layering system"

Case "EXPLODE"

.speak "No standard blocks shall be exploded for editing"

Case "REFEDIT", "BEDIT"

.speak "Please contact CAD support before editing any standard blocks"

End Select

End With

Set objSSV = Nothing

End Sub

Keep the above code inside the 'ThisDrawing' section of Visual Basic Editor (for testing purpose) and turn the speakers on. Run any of the fore-mentioned commands inside AutoCAD. You will hear instructions based on the commands. Hope this system will help senior guys to avoid running behind the newcomers for correction and teaching purposes.

Sunday, August 19, 2007

Putting Everything Together - An Enhanced Line Command

I have experienced in the past that the best way to learn something new is to apply it in our own way. So it's time to apply whatever we have learned so far, in a practical way. The result is an enhanced line command which allows the user to change current layer and linetype on the fly. I have also tried to have logical seperations inside the code using reusable methods(See SetCurrentLayer, SetCurrentLType and CreateLine methods).

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace AcadNetSamples
{
public class Commands
{
/// <summary>
/// Enhanced Line Command.
/// Allows user to change current layer and
/// linetype from within the command.
/// </summary>
[CommandMethod("ELINE")]
public static void DrawEnhancedLine()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions prPO = new PromptPointOptions("\nPick start point of line : ");
prPO.AllowNone = true;
prPO.UseBasePoint = false;
PromptPointResult ppr;
ppr = ed.GetPoint(prPO);
//Get start point
Point3d SPoint = ppr.Value;
//Remeber it for the CLOSE option
Point3d CPoint = SPoint;
prPO.Keywords.Add("LAyer");
prPO.Keywords.Add("LType");
prPO.Keywords.Add("Close");
// Continue line command until the user interrupts
while (ppr.Status == PromptStatus.OK ppr.Status ==
PromptStatus.Keyword)
{
prPO.UseBasePoint = true;
//Use the previously picked point as the base point for new line
prPO.BasePoint = SPoint;
prPO.Message = "\nPick next point or ";
ppr = ed.GetPoint(prPO);
Point3d NPoint = ppr.Value;
if (ppr.Status == PromptStatus.OK ppr.Status ==
PromptStatus.Keyword)
{
//Exit command on enter key
if (ppr.Status == PromptStatus.None) break;
//Declare ObjectId variable for common use
ObjectId objID;
// Check to see whether any keyword is choosen
if (ppr.Status == PromptStatus.Keyword)
{
PromptResult prs;
switch (ppr.StringResult)
{
case "LAyer":
prs = ed.GetString("\nEnter a layer name to make it current: ");
if (prs.Status == PromptStatus.OK)
{
//Loop back on Enter
if (prs.StringResult == "")
continue ;
try
{
objID =
SetCurrentLayer(prs.StringResult);
//Check whether the operation was successful
if (objID != ObjectId.Null)
ed.WriteMessage("\nCurrent layer is '"
+ prs.StringResult+"'");
else
ed.WriteMessage("\nThe layer '" +
prs.StringResult + "' was not found.");
continue;
}
catch
{
ed.WriteMessage("\nUnable to change current
layer. An error occured...!!"
);
continue;
}
}
return ;
case "LType":
prs = ed.GetString("\nEnter a linetype name to make it current: ");
if (prs.Status == PromptStatus.OK)
{
//Loop back on Enter
if (prs.StringResult == "")
continue;
try
{
objID =
SetCurrentLType(prs.StringResult);
//Check whether the operation was successful
if (objID != ObjectId.Null)
ed.WriteMessage("\nCurrent linetype is "
+ prs.StringResult +"'");
else
ed.WriteMessage("\nThe linetype '"
+ prs.StringResult + "' was not found.");
continue;
}
catch
{
ed.WriteMessage("\nUnable to change current linetype. An error occured...!!");
continue;
}
}
return ;
case "Close":
try
{
objID =
CreateLine(SPoint, CPoint);
if (objID != ObjectId.Null)
return;
break;
}
catch {}
return;
}
}
try
{
objID = CreateLine(SPoint, NPoint);
//The last end point will serve as the next base point
if (objID != ObjectId.Null) SPoint = NPoint;
}
catch { return; }
}
}
}
private static ObjectId SetCurrentLayer(string LayerName)
{
ObjectId layerId=ObjectId.Null ;
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
using (Transaction tr = tm.StartTransaction())
{
LayerTable lt = (LayerTable)tm.GetObject(db.LayerTableId, OpenMode.ForRead, false);
if (lt.Has(LayerName))
{
layerId = lt[LayerName];
db.Clayer = layerId;
}
tr.Commit();
}
return layerId;
}
private static ObjectId SetCurrentLType(string LineTypeName)
{
ObjectId ltypeId = ObjectId.Null;
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
using (Transaction tr = tm.StartTransaction())
{
LinetypeTable ltt = (LinetypeTable)tm.GetObject(db.LinetypeTableId, OpenMode.ForRead, false);
if (ltt.Has(LineTypeName))
{
ltypeId = ltt[LineTypeName];
db.Celtype = ltypeId;
}
tr.Commit();
}
return ltypeId;
}
private static ObjectId CreateLine(Point3d SPoint,Point3d EPoint)
{
ObjectId lineId = ObjectId.Null;
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Line oLine = new Line(SPoint, EPoint);
Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
using (Transaction tr = tm.StartTransaction())
{
BlockTable bt = (BlockTable)tm.GetObject(db.BlockTableId, OpenMode.ForRead, false);
BlockTableRecord btr = (BlockTableRecord)tm.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
using (oLine)
{
lineId = btr.AppendEntity(oLine);
tm.AddNewlyCreatedDBObject(oLine, true);
}
tr.Commit();
}
return lineId;
}
}
}

Compile the code and type ELINE to activate the command. If you come across and syntax / logical erros, please feel free to post it here.

Tuesday, August 14, 2007

Creating AutoCAD Geometry

I think it's time to get into AutoCAD geometry. So, in this session, we are going to create a line command . We will also see using prompt options in this sample code. The command name used here is DRAWLINE.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace AcadNetSamples
{
public class Commands
{
[CommandMethod("DrawLine")]
public static void DrawLine()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions prPO = new PromptPointOptions("\nPick start point of line: ");
prPO.AllowNone = false;
prPO.UseBasePoint = false;
PromptPointResult ppr1 = ed.GetPoint(prPO);
if (ppr1.Status == PromptStatus.OK)
{
prPO.UseBasePoint = true;
prPO.BasePoint = ppr1.Value;
prPO.Message = "\nPick end point: ";
PromptPointResult ppr2 = ed.GetPoint(prPO);
if (ppr2.Status == PromptStatus.OK)
{
Point3d SPoint = ppr1.Value;
Point3d EPoint = ppr2.Value;
Line oLine = new Line(SPoint, EPoint);
Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
Autodesk.AutoCAD.DatabaseServices.Transaction tr = tm.StartTransaction();
using
(tr)
{
BlockTable bt = (BlockTable)tm.GetObject(db.BlockTableId, OpenMode.ForRead, false);
BlockTableRecord btr = (BlockTableRecord)tm.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
using
(oLine)
{
btr.AppendEntity(oLine);
tm.AddNewlyCreatedDBObject(oLine, true);
}
tr.Commit();
}
}
}
}
}
}

I don't want to confine this blog to learning AutoCAD.Net only. I have got some Tips & Tricks to share with you. You may encounter these in between the dotnet posts (If you see one, just understand that I didn't get enough time to learn next dotnet topic :-).

Saturday, August 11, 2007

AutoCAD Prompts & Error Handling

In this post, we are going to start with basic prompt operations and error handling. You will see samples on common AutoCAD prompts like string prompt, point prompt, distance prompt etc. The first sample in this session also covers very basic form of error handling. There are three commands (OPENDWG, DISPOINT & GETDIST) in the following code. The OPENDWG accepts a drawing path string input from the user and opens that drawing if exists. The DISPOINT prompts the user to pick a point and show the point value in the command prompt. The GETDIST prompts the user to pick two points and returns the distance between them. We will have a look at advanced prompt operations and creating AutoCAD geometry in the forthcoming sessions.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;

namespace AcadNetSamples
{
public class Commands
{
[CommandMethod("OPENDWG")]
public static void OpenDrawing()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
PromptResult res = ed.GetString("\nEnter a drawing path: ");

if (res.Status == PromptStatus.OK)
{
try
{
Application.DocumentManager.Open(res.StringResult,false);
}
catch
{
ed.WriteMessage("\nUnable to open drawing file.");
return;
}
finally
{
ed.WriteMessage("\nThis is an AutoCAD.Net sample command.");
}
}
}
[CommandMethod("DISPOINT")]
public void DisplayPoint()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptPointOptions prPO = new PromptPointOptions("Select a point: ");
PromptPointResult prPR = ed.GetPoint(prPO);
if (prPR.Status != PromptStatus.OK)
{
ed.WriteMessage("An error occured...!");
}
else
{
ed.WriteMessage("The point is " + prPR.Value.ToString());
}
}

[CommandMethod("GETDIST")]
public void GetDistance()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptDistanceOptions prDO = new PromptDistanceOptions("Select first point: ");

PromptDoubleResult prDR = ed.GetDistance(prDO);

if (prDR.Status != PromptStatus.OK)
{
ed.WriteMessage("An error occured...!");
}
else
{
ed.WriteMessage("Distance: " + prDR.Value.ToString());
}
}
}
}

Sunday, August 5, 2007

Iterations in C#

As I mentioned in the last post, in this session, we are going to cover the loop structures in C#. Our primary aim is to concentrate more on the syntax of loops. Here is a sample which shows iteration results in AutoCAD prompt using different looping methods.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
namespace AcadNetSamples
{
public class Commands
{
[CommandMethod("LOOPS")]
public static void LoopOperations()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
string[] strs = new string[10];
int i;
for (i = 0; i < 10; i++)
{
strs[i] = "String No. " + (i + 1).ToString();
}
ed.WriteMessage("\n\nUsing 'foreach' Loop\n");
foreach (string str in strs)
{
ed.WriteMessage("\n\t\t" + str);
}
ed.WriteMessage("\n\nUsing 'While' Loop\n");
i = 0;
while (i < 10)
{
ed.WriteMessage("\n\t\tString No. " + (i + 1).ToString());
i++;
}
ed.WriteMessage("\n\nUsing 'Do While' Loop\n");
i = 0;
do
{
ed.WriteMessage("\n\t\tString No. "+ (i + 1).ToString());
i++;
} while (i < 10);
}
}
}

Next session, I am planning to start with AutoCAD prompt operations. Like an online streaming buffer, I have to keep a little ahead of my posts :-). So the blog post interval will depend on how quickly I learn new things. I highly appreciate any valuable contributions from the readers.

Wednesday, August 1, 2007

Conditions forever

Before starting AutoCAD data specific programs, I would like to put my hands on C# language specific statements like If, Switch etc. Here is a sample program covering very basic condition checking and some output formatting. Next post, I shall try to cover looping in C#.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
namespace AcadNetSamples
{
public class
Commands
{
[CommandMethod("CONDITIONS")]
public static void ConditionalOperations()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
int x = 1; int y = 2; int z = 3;
if ((x + y) == z) ed.WriteMessage("\n{0}+{1} is equal to {2}",x,y,z);
if ((z - y) != x)
{
ed.WriteMessage("\n{0}+{1} is not equal to {2}", z, y, x);
}
else
{
ed.WriteMessage("\n{0}-{1} is equal to {2}", z, y, x);
}
switch (x + y + z)
{
case 3:
ed.WriteMessage("\n{0}+{1}+{2}=3", x, y, z);
break;
case 4:
ed.WriteMessage("\n{0}+{1}+{2}=4", x, y, z);
break;
case 5:
ed.WriteMessage("\n{0}+{1}+{2}=5", x, y, z);
break;
default:
ed.WriteMessage("\n{0}+{1}+{2}={3}", x, y, z, (x + y + z));
break;
}
}
}
}

Try to experiment with the above code using different conditions. Also try to work with common logical operators like AND, OR etc. in your code.

Tuesday, July 31, 2007

Getting Started

Instead of spending time on discussing the concepts and theories behind AutoCAD.Net programming, I think we should better start with some sample code. It defenitely helps us to raise the confindence level. The thrill of watching our first program output in a new technology will defenitely last long and help us to gain momentum and energy for further exploration. So here goes our first program. Please remember that I am also a beginner in this field. So the code may not be of professional standard and may contain errors. I highly appreciate your suggestions for the improvement of these code snippets.

The following code displays a welcome message in the AutoCAD Text Editor window.




Here is the a text version of the code if you want to copy and paste it in your editor. The above one is a screenshot from the code editor window. I used that image for a better understanding of the code. Once you copy the following code and paste it in Visual C# editor, it should arrange it in the manner shown above. So next post onwards, I may not include a screenshot.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
namespace AcadNetSamples
{
public class Commands
{
[CommandMethod("Hello")]
public static void SayHello()
{
Document doc=Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
ed.WriteMessage("\nHello and welcome to AutoCAD.Net world...!!");
}
}
}
Here goes a few thing to be taken care before you start using it.
  • You must have set reference to AutoCAD managed class libraries acmgd.dll and acdbmgd.dll . Otherwise the AutoCAD specific objects and methods will not get detected.
  • If you are using Visual C# editor, then you can use Solution Explorer window to add reference to the above files. If you are using a command line version of compiler (CSC.EXE), then use /r option to set reference. (Type CSC/? in the command line to get help on compiler options)
  • The project type has to be a Class Library in order to use it inside AutoCAD. If you start with VS Editor, the choose project template 'Class Library' in the beginning. If you use Command line, then choose /t:library option to compile it as a library project.

Those are the essentials and once you build the output, load the dll file (here AcadNetSamples.dll) from autocad using netload command. Type "Hello" in the command prompt and if everything goes right, you will see the following message.

"Hello and welcome to AutoCAD.Net world...!!"