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 use jig to mirror an entity of any type along a line.
Here is the core code of dynamic mirroring an entity of any type along a line and 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 EntityMirrorJigger : EntityJig
{
#region Fields
public int mCurJigFactorIndex = 1;
private Point3d m2ndPoint = new Point3d(); // Factor #1
private Point3d m1stPoint;
#endregion
#region Constructors
public EntityMirrorJigger(Entity ent, Point3d basePoint) : base(ent)
{
m1stPoint = basePoint.TransformBy(UCS);
}
#endregion
#region Properties
private Editor Editor
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
}
}
private Matrix3d UCS
{
get
{
return Editor.CurrentUserCoordinateSystem;
}
}
#endregion
#region Overrides
private Matrix3d mLastMat = Matrix3d.Identity;
protected override bool Update()
{
Matrix3d mat = Matrix3d.Mirroring(new Line3d(m1stPoint, m2ndPoint));
Entity.TransformBy(mLastMat.Inverse().PostMultiplyBy(mat));
mLastMat = mat;
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
switch (mCurJigFactorIndex)
{
case 1:
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nThe second point of the mirror line: ");
prOptions1.UserInputControls = UserInputControls.GovernedByUCSDetect | UserInputControls.UseBasePointElevation | UserInputControls.Accept3dCoordinates;
prOptions1.BasePoint = m1stPoint;
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
if (prResult1.Value.Equals(m2ndPoint))
{
return SamplerStatus.NoChange;
}
else
{
m2ndPoint = prResult1.Value;
return SamplerStatus.OK;
}
default:
break;
}
return SamplerStatus.OK;
}
#endregion
#region Methods to Call
public static bool Jig(Entity ent, Point3d basePt)
{
EntityMirrorJigger jigger = null;
try
{
jigger = new EntityMirrorJigger(ent, basePt);
PromptResult pr;
do
{
pr = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger);
if (pr.Status == PromptStatus.Keyword)
{
// Add keyword handling code below
}
else
{
jigger.mCurJigFactorIndex++;
}
} while (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && jigger.mCurJigFactorIndex <= 1);
if (pr.Status == PromptStatus.Cancel || pr.Status == PromptStatus.Error)
{
if (jigger != null && jigger.Entity != null)
jigger.Entity.Dispose();
return false;
}
else
return true;
}
catch
{
if (jigger != null && jigger.Entity != null)
jigger.Entity.Dispose();
return false;
}
}
#endregion
#region Test Commands
[CommandMethod("TestEntityMirrorJigger")]
public static void TestEntityMirrorJigger_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
try
{
PromptEntityResult selRes = ed.GetEntity("\nPick an entity:");
PromptPointResult ptRes = ed.GetPoint("\nThe first point of the mirror line: ");
if (selRes.Status == PromptStatus.OK && ptRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = tr.GetObject(selRes.ObjectId, OpenMode.ForWrite) as Entity;
if (ent != null)
{
using (Transaction tr1 = db.TransactionManager.StartTransaction())
{
ent.Highlight();
tr1.Commit();
}
if (EntityMirrorJigger.Jig(ent, ptRes.Value))
tr.Commit();
else
tr.Abort();
}
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
#endregion
}
}
Here is what the the sceen looks like when a solid box is being mirrored along the line composed by the two input points. To make the visual effect look better, the box has been duplicated a copy at its original place and a reference line in cyan has also been generated.
NOTE: The box is created in a UCS instead of the WCS and its faces and edges are not parallel to the WCS plans or X/Y/Z axises.
A few highlights about the code may be helpful:
• No entity type is needed for our Mirror Jig since it works for any type of AutoCAD Entity.
• The first point of the mirrow line needs to be picked beforehand to determine where the line starts from.
• The Sampler() override is to acquire input for the second point of the mirrow line.
• Some UserInputControls flags are used here, GovernedByUCSDetect, UseBasePointElevation, and Accept3dCoordinates to collect a point from UCS but intepreted 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 entity with the new mirroring matrix through the TransformBy() call . We use a temporary Matrix3d variable to transform the entity back to its original status first and then transform it to the mirrored status.
• The Editor.Draw() is the power to fire the jig.
• 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.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides a coder, Entity Jigger, to help us create entity jig code automatically, quickly and reliably.
Recent Comments