AutoCAD has both WCS and UCS as we know but people commonly work in the default WCS most times. However, that does not prevent anybody from invoking any commands to create something into the current UCS. AutoCAD commands generally handle UCS well but a few still do not in some cases such as the INSERT command doing with a block with some attributes in UCS, as mentioned and demonstrated before in one of our Jig articles.
Therefore, as AutoCAD programmers we’d better take UCS into account always when trying to jig something on screen or add something into the AutoCAD database, just as our final Block Insert jig does. It is another good practice that I would like to emphasize here.
Let us create a simple command first which can create a circle in WCS.
[CommandMethod("CreateCircleInWCS")]
public void Test_CreateCircleInWCS()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
try
{
PromptPointOptions prOpt = new PromptPointOptions("\nCircle center: ");
PromptPointResult pr = ed.GetPoint(prOpt);
if (pr.Status != PromptStatus.OK) return;
PromptDistanceOptions prOpt1 = new PromptDistanceOptions("\nCircle radius: ");
prOpt1.UseBasePoint = true;
prOpt1.UseDashedLine = true;
prOpt1.BasePoint = pr.Value;
PromptDoubleResult pr1 = ed.GetDistance(prOpt1);
if (pr1.Status != PromptStatus.OK) return;
using (Circle cir = new Circle(pr.Value, Vector3d.ZAxis, pr1.Value))
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
btr.AppendEntity(cir);
tr.AddNewlyCreatedDBObject(cir, true);
tr.Commit();
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
There is no double that the command can successfully collect input from command line or screen in WCS and create the circle into the model space of the AutoCAD database.
However, if we switch to a UCS and try the same command again, we will find most likely nothing appears though we do click a point somewhere and input a distance in the current visible drawing area of the UCS. After a ZOOM Extents and possibly a PAN as well, we finally find it, but it may look like this: (depending on how the UCS is defined)
It is not good and should not be expected by users of our software tools.
How to fix it then?
Pretty easy! Do some matrix transformation to the circle before adding it to the AutoCAD database. Here is another simple command which can create a circle in the same way but honors UCS:
[CommandMethod("CreateCircleInUCS")]
public void Test_CreateCircleInUCS()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Matrix3d ucs = ed.CurrentUserCoordinateSystem;
try
{
PromptPointOptions prOpt = new PromptPointOptions("\nCircle center: ");
PromptPointResult pr = ed.GetPoint(prOpt);
if (pr.Status != PromptStatus.OK) return;
PromptDistanceOptions prOpt1 = new PromptDistanceOptions("\nCircle radius: ");
prOpt1.UseBasePoint = true;
prOpt1.UseDashedLine = true;
prOpt1.BasePoint = pr.Value;
PromptDoubleResult pr1 = ed.GetDistance(prOpt1);
if (pr1.Status != PromptStatus.OK) return;
using (Circle cir = new Circle(pr.Value, Vector3d.ZAxis, pr1.Value))
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
cir.TransformBy(ed.CurrentUserCoordinateSystem);
btr.AppendEntity(cir);
tr.AddNewlyCreatedDBObject(cir, true);
tr.Commit();
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
Here is the screenshot showing what the circle looks like in the current UCS after the circle center and radius have been input interactively in the drawing area:
Once again, please keep this good practice in mind and do the extra but simple matrix transformation to the entities going to be added to the database. Please also always test the related commands in a UCS. If they work in a UCS, they will also work in WCS since WCS is just a special UCS. However, vise is not versa.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) exercises the good practice in its various wizards, coders and widgets when applicable.
Posted by: |