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. We also showed how to Move and Rotate a single AutoCAD Entity of any kind using the .NET EntityJig. In this article, let us see how to use jig to scale an entity of any type.
Here is the code of the EntityJig implementation 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 EntityScaleJigger : EntityJig
{
#region Fields
public int mCurJigFactorIndex = 1;
private double mScaleFactor = 1; // Factor #1
private double mLastScaleFactor = 1;
private Point3d mBasePoint = new Point3d();
#endregion
#region Constructors
public EntityScaleJigger(Entity ent, Point3d basePoint) : base(ent)
{
mBasePoint = basePoint;
}
#endregion
#region Properties
private Editor Editor
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
}
}
private Matrix3d UCS
{
get
{
return Editor.CurrentUserCoordinateSystem;
}
}
#endregion
#region Overrides
protected override bool Update()
{
Matrix3d mat = Matrix3d.Scaling(mScaleFactor/mLastScaleFactor, mBasePoint);
Entity.TransformBy(mat);
mLastScaleFactor = mScaleFactor;
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
switch (mCurJigFactorIndex)
{
case 1:
JigPromptDistanceOptions prOptions1 = new JigPromptDistanceOptions("\nScale factor:");
prOptions1.BasePoint = mBasePoint;
prOptions1.UseBasePoint = true;
PromptDoubleResult prResult1 = prompts.AcquireDistance(prOptions1);
if (prResult1.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
if (prResult1.Value.Equals(mScaleFactor))
{
return SamplerStatus.NoChange;
}
else
{
mScaleFactor = prResult1.Value;
return SamplerStatus.OK;
}
default:
break;
}
return SamplerStatus.OK;
}
#endregion
#region Methods to Call
public static bool Jig(Entity ent, Point3d basePt)
{
EntityScaleJigger jigger = null;
try
{
jigger = new EntityScaleJigger(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("TestEntityScaleJigger")]
public static void TestEntityScaleJigger_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
try
{
PromptEntityResult selRes = ed.GetEntity("\nPick an entity:");
PromptPointResult ptRes = ed.GetPoint("\nBase Point: ");
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 (EntityScaleJigger.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 rectangle is being scaled by the dynamic scale jig:
NOTE: The plan view is in a UCS instead of WCS, indicating that our scale Jigger honors UCS perfectly.
A few highlights about the code may be helpful:
• No entity type is needed for our Scale Jig since it works for any type of AutoCAD Entity.
• A base point needs to be picked to determine the center of the scaling operation.
• The Sampler() override is to acquire input for the new scale factor through a distance input.
• 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 new scale factor of the Entity through the TransformBy() call on an updated scaling matrix.
• The old scale factor needs to be cached and replaced each time with the new scale factor just collected so that the scaling can still behave well in every Update() call.
• 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 scaled to the new extent.
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: |