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 various AutoCAD entities such as Line, Circle, and Block in many early posts. In this article, let us see how to create a Spline jig with the EntityJig AutoCAD .NET class.
Here is the Spline jig class along with a test command:
#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 SplineJig : EntityJig
{
#region Fields
public int mCurJigFactorIndex = 3;
private Autodesk.AutoCAD.Geometry.Point3d mLastVertex;
#endregion
#region Constructors
public SplineJig(Spline ent)
: base(ent)
{
Entity.SetDatabaseDefaults();
Entity.TransformBy(UCS);
}
#endregion
#region Properties
private static Editor Editor
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
}
}
private Matrix3d UCS
{
get
{
return Editor.CurrentUserCoordinateSystem;
}
}
#endregion
#region Overrides
public new Spline Entity // Overload the Entity property for convenience.
{
get
{
return base.Entity as Spline;
}
}
protected override bool Update()
{
if (mCurJigFactorIndex < Entity.NumFitPoints)
Entity.RemoveFitPointAt(mCurJigFactorIndex);
Entity.InsertFitPointAt(mCurJigFactorIndex, mLastVertex);
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nFit point (Enter to finish):");
prOptions1.UserInputControls = UserInputControls.Accept3dCoordinates | UserInputControls.AcceptMouseUpAsPoint | UserInputControls.AnyBlankTerminatesInput | UserInputControls.GovernedByOrthoMode | UserInputControls.GovernedByUCSDetect | UserInputControls.NullResponseAccepted;
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status == PromptStatus.Cancel && prResult1.Status == PromptStatus.Error)
return SamplerStatus.Cancel;
if (prResult1.Value.Equals(mLastVertex))
{
return SamplerStatus.NoChange;
}
else
{
mLastVertex = prResult1.Value;
return SamplerStatus.OK;
}
}
#endregion
#region Methods to Call
public static Spline Jig()
{
SplineJig jigger = null;
try
{
PromptPointOptions prOpt = new PromptPointOptions("\nFit point (Enter to finish):");
PromptPointResult ppr = Editor.GetPoint(prOpt);
if (ppr.Status != PromptStatus.OK) return null;
PromptPointOptions prOpt2 = new PromptPointOptions("\nFit point (Enter to finish):");
PromptPointResult ppr2 = Editor.GetPoint(prOpt2);
if (ppr2.Status != PromptStatus.OK) return null;
PromptPointOptions prOpt3 = new PromptPointOptions("\nFit point (Enter to finish):");
PromptPointResult ppr3 = Editor.GetPoint(prOpt3);
if (ppr3.Status != PromptStatus.OK) return null;
Spline ent = new Spline(new Point3dCollection(new Point3d[] {ppr.Value, ppr2.Value, ppr3.Value}), 2, 0);
ent.SetDatabaseDefaults();
jigger = new SplineJig(ent);
PromptResult pr;
do
{
pr = Editor.Drag(jigger);
if (pr.Status == PromptStatus.Keyword)
{
// Keyword handling code
}
else if (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && pr.Status != PromptStatus.None)
{
jigger.Entity.InsertFitPointAt(jigger.mCurJigFactorIndex++, jigger.mLastVertex);
}
} while (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && pr.Status != PromptStatus.None);
if (pr.Status == PromptStatus.Cancel || pr.Status == PromptStatus.Error)
{
if (jigger != null && jigger.Entity != null)
jigger.Entity.Dispose();
return null;
}
else
return jigger.Entity;
}
catch
{
if (jigger != null && jigger.Entity != null)
jigger.Entity.Dispose();
return null;
}
}
#endregion
#region Test Commands
[CommandMethod("TestSplineJigger")]
public static void TestSplineJigger_Method()
{
try
{
Entity jigEnt = SplineJig.Jig();
if (jigEnt != null)
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(jigEnt);
tr.AddNewlyCreatedDBObject(jigEnt, true);
tr.Commit();
}
}
}
catch (System.Exception ex)
{
Editor.WriteMessage(ex.ToString());
}
}
#endregion
}
}
Here is what the the sceen looked like when a Spline was being jigged by the above code and command.
NOTE: The above test was performed in a UCS instead of the default WCS, indicating the Spline Jig honored UCS perfectly.
A few highlights about the code may be helpful:
• The Spline entity type is specified in the constructor of the EntityJig derivative.
• Three points are picked before the Spline Jig starts to meet the need of the Spline class constructors.
• The Sampler() override is to acquire input for the other fit points of the Spline.
• Some UserInputControls flags are used here, GovernedByUCSDetect, UseBasePointElevation, and Accept3dCoordinates to collect a point from UCS but interpreted in WCS.
• 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.
• Please do not forget to handle the cancel/escape circumstance as demonstrated.
• The Update() override is to update the Spline with a new fit point being added temporarily or really.
• The Editor.Drag() is the power to fire the jig and is called repeatedly in a loop to collect more fit points. That can avoid the unnecessary complexities of the Spline Jig itself such as in the Sampler() and the Update() calls.
• The while loop needs to think about the PromptStatus.Keyword case of the PromptResult after each Jig Drag.
• Keyword handling code can be added as commented.
• Only after the jig succeeds should the entity be moved to the new location.
• A handy index flag is to tell the Spline Jig which fit point input it is so as to determine removing or adding it to the Spline.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides a coder, Entity Jigger, to help us create entity jig code automatically, quickly and reliably.
A better version of the SplineJig has been created and presented in another post:
http://spiderinnet1.typepad.com/blog/2012/09/autocad-net-a-better-spline-jig-from-entityjig.html
Posted by: Spiderinnet1 | 09/10/2012 at 03:12 AM