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.
In this article, let us see how to rotate a Block (a commonly used but confusing term)/BlockReference (API term) /INSERT (AutoCAD term) using EntityJig.
Here is the test command for the block rotating jig we are going to talk about:
[CommandMethod("TestEntityJigger5")]
public static void TestEntityJigger5_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
PromptEntityResult selRes = ed.GetEntity("Pick a block:");
if (selRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockReference ent = tr.GetObject(selRes.ObjectId, OpenMode.ForWrite) as BlockReference;
if (ent != null)
{
using (Transaction tr1 = db.TransactionManager.StartTransaction())
{
ent.Highlight();
tr1.Commit();
}
if (BlockRotating.Jig(ent))
tr.Commit();
else
tr.Abort();
}
}
}
}
Here is how the block rotating jig behaves in AutoCAD after the test command runs and a block is picked:
As can be seen, the block rotating behavior looks nicer than the block moving jig we introduced a bit earlier, almost the same as the AutoCAD rotate command exhibits. This is achieved easily and reliably by applying a sub transaction as demonstrated in the succinct test command. And better, a few other situations have been nicely handled as well.
The block’s graphics is only highlighted temporarily during the jigging period. In case of anything wrong during the jigging or users just cancel or escape out the operation, the block will be restored to its very original status automatically thus nothing messy about the database.
So this is a simple but very useful practical example that demonstrates the usage of the AutoCAD .NET sub transaction. It is not something fancy that just makes people wonder.
Here is the core source about the block rotating jig class derived from the EntityJig:
#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 BlockRotating : EntityJig
{
#region Fields
public int mCurJigFactorNumber = 1;
private double mRotation = 0.0; // Factor #1
#endregion
#region Constructors
public BlockRotating(Entity ent)
: base(ent)
{
}
#endregion
#region Overrides
protected override bool Update()
{
switch (mCurJigFactorNumber)
{
case 1:
(Entity as BlockReference).Rotation = mRotation;
break;
default:
return false;
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
switch (mCurJigFactorNumber)
{
case 1:
JigPromptAngleOptions prOptions1 = new JigPromptAngleOptions("\nBlock rotation angle:");
prOptions1.BasePoint = (Entity as BlockReference).Position;
prOptions1.UseBasePoint = true;
PromptDoubleResult prResult1 = prompts.AcquireAngle(prOptions1);
if (prResult1.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
if (prResult1.Value.Equals(mRotation))
{
return SamplerStatus.NoChange;
}
else
{
mRotation = prResult1.Value;
return SamplerStatus.OK;
}
default:
break;
}
return SamplerStatus.OK;
}
#endregion
#region Method to Call
public static bool Jig(BlockReference ent)
{
try
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
BlockRotating jigger = new BlockRotating(ent);
PromptResult pr;
do
{
pr = ed.Drag(jigger);
jigger.mCurJigFactorNumber++;
} while (pr.Status != PromptStatus.Cancel &&
pr.Status != PromptStatus.Error &&
pr.Status != PromptStatus.Keyword &&
jigger.mCurJigFactorNumber <= 1);
return pr.Status == PromptStatus.OK;
}
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 BlockReference here.
• The Sampler() override is to acquire input for rotation angle.
• 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 block rotation property as acquired in the Sampler().
• The Editor.Draw() is the power to fire the jig.
• The last but important, please return a good status value to the caller so that it knows whether to really modify the block or roll any changes back.
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