AutoCAD .NET API provides two concrete Jig classes for us to jig different entities in different circumstances, EntityJig and DrawJig. EntityJig is to jig a specific entity as its name indicates and the DrawJig is to jig anything that has graphics to draw, which can be a single entity, a group of entities, or something that is not available natively in AutoCAD.
We have demonstrated jigging a circle by its center and radius with keyword support before. In this article, let us see how to add the ColorIndex input rather than only some pre-set color keywords during the circle jigging.
Here is the test command for the circle jig we are going to talk about:
[CommandMethod("TestEntityJigger2")]
public static void TestEntityJigger2_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
if (EntityJigger2.Jig())
{
ed.WriteMessage("\nA circle has been successfully jigged and added to the database.\n");
}
else
{
ed.WriteMessage("\nIt failed to jig and add a circle to the database.\n");
}
}
Here is how the circle jig behaves in AutoCAD after the test command runs, a center is input, the Color keyword is chosen, some color index is input, and its radius is jigging:
The following outputs may be there in the AutoCAD command line window:
Command: TESTENTITYJIGGER2
Circle center [Color]: color
Color index: 50
Circle center [Color]:
Circle radius [Color]: c
Color index: 100
Circle radius [Color]:
A circle has been successfully jigged and added to the database.
By the way, cancellations/escapes by users will gracefully be handled by the jig as usual.
Here is the core source:
#region Namespaces
using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows;
using MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using MgdAcDocument = Autodesk.AutoCAD.ApplicationServices.Document;
using AcWindowsNS = Autodesk.AutoCAD.Windows;
#endregion
namespace AcadNetAddinWizard_Namespace
{
public class EntityJigger2 : EntityJig
{
#region Fields
private Circle mEntity;
public int mCurJigFactorNumber = 1;
private Point3d mCenter = new Point3d(); // Factor #1
private double mRadius = 0.0001; // Factor #2 : It is critical to set it as none zero to avoid the degeneration problem.
public int mColorIndex = -1; // Factor #3 : Also a flag to indicate if a ColorIndex is input.
#endregion
#region Constructors
public EntityJigger2(Entity ent) : base(ent)
{
mEntity = ent as Circle;
mEntity.Center = mCenter;
mEntity.Radius = mRadius;
}
#endregion
#region Overrides
protected override bool Update()
{
if (mColorIndex >= 0 && mColorIndex <= 256)
{
(Entity as Circle).ColorIndex = mColorIndex;
mColorIndex = -1;
return true;
}
switch (mCurJigFactorNumber)
{
case 1:
(Entity as Circle).Center = mCenter;
break;
case 2:
(Entity as Circle).Radius = mRadius;
break;
default:
return false;
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
switch (mCurJigFactorNumber)
{
case 1:
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nCircle center:");
prOptions1.Keywords.Add("Color");
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status != PromptStatus.OK) return SamplerStatus.Cancel;
if (prResult1.Value.Equals(mCenter))
{
return SamplerStatus.NoChange;
}
else
{
mCenter = prResult1.Value;
return SamplerStatus.OK;
}
case 2:
JigPromptDistanceOptions prOptions2 = new JigPromptDistanceOptions("\nCircle radius:");
prOptions2.Keywords.Add("Color");
prOptions2.BasePoint = mCenter;
PromptDoubleResult prResult2 = prompts.AcquireDistance(prOptions2);
if (prResult2.Status != PromptStatus.OK) return SamplerStatus.Cancel;
if (prResult2.Value.Equals(mRadius))
{
return SamplerStatus.NoChange;
}
else
{
if ( prResult2.Value < 0.0001) // To avoid the degeneration problem!
{
return SamplerStatus.NoChange;
}
else
{
mRadius = prResult2.Value;
return SamplerStatus.OK;
}
}
default:
break;
}
return SamplerStatus.OK;
}
#endregion
#region Method to Call
public static bool Jig()
{
try
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
EntityJigger2 jigger = new EntityJigger2(new Circle());
PromptResult pr;
do {
pr = ed.Drag(jigger);
if (pr.Status == PromptStatus.Keyword)
{
if (pr.StringResult == "Color")
{
PromptIntegerResult prResult = ed.GetInteger("\nColor index:");
jigger.mColorIndex = prResult.Value;
}
}
} while ( pr.Status == PromptStatus.Keyword ||
(pr.Status == PromptStatus.OK && jigger.mCurJigFactorNumber++ <= 2) );
if (pr.Status == PromptStatus.OK)
{
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(jigger.Entity);
tr.AddNewlyCreatedDBObject(jigger.Entity, true);
tr.Commit();
}
}
else
{
return false;
}
return true;
}
catch
{
return false;
}
}
#endregion
}
}
A few highlights about the code may be helpful:
• An entity type needs to be specified in the EntityJig derivative, as Circle here.
• The Sampler() override is to acquire input for the center and the radius in a certain order.
• If the input is the same as the stored variable, we’d better return SamplerStatus.NoChange to avoid unnecessary flashing; if not, return SamplerStatus.OK.
• The keywords can be added easily through the Keywords collection of the JigPromptPointOptions or other similar prompt options objects.
• Please do not forget to handle the cancel/escape circumstance as demonstrated.
• The Update() override is to update the center and the radius properties of the circle in the same order as set in the Sampler().
• The Editor.Draw() is the power to fire the jig. If two properties need to be set, the jig needs to be fired off twice. That is why a while loop is used.
• The while loop needs to think about the PromptStatus.Keyword case of the PromptResult after each Jig Drag.
• The color index needs to be collected from outside of the Jig itself using the GetInteger() of the Editor object instead of the JigPrompts of the Jig object.
• Only after the jig succeeds should the circle be added to the database to avoid database corruption.
• The last but important, please make sure the radius of the circle either in memory or database resident is never zero, otherwise a degeneration exception would come up.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides a coder, Entity Jigger, to help us create entity jig code automatically, quickly and reliably.
Posted by: |