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 even something that is not available natively in AutoCAD.
We have demonstrated various ways to jig a block (INSERT as used in AutoCAD users and BlockReference in programmers) such as by its position, rotation or both of these factors, from the block name input on, with the original graphics highlighted or not, with user cancellation handling or not, honoring UCS or not, inputting True Color or not, and so on.
In this article, we are going to add the block scaling support. Here is the test command:
[CommandMethod("TestEntityJigger9")]
public static void TestEntityJigger9_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
PromptResult pr = ed.GetString("\nBlock name:");
if (pr.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[pr.StringResult], OpenMode.ForRead) as BlockTableRecord;
if (btr != null)
{
BlockReference ent = new BlockReference(new Point3d(0, 0, 0), btr.ObjectId);
if (BlockMovingScalingRotating.Jig(ent))
{
BlockTableRecord modelspace = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
modelspace.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
else
{
ent.Dispose();
tr.Abort();
}
}
}
}
}
Here is what the block (INSERT/BlockReference) looks like when it’s jigging for the scale factor in percentage after a good block name, position, and rotation angle are given.
Please note the purple one is there for the comparison purpose only for us to see the current white one is being properly scaled, about 23% big as the original size. And the uniform scaling is applied here.
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 BlockMovingScalingRotating : EntityJig
{
#region Fields
public int mCurJigFactorNumber = 1;
private Point3d mPosition; // Factor #1
private double mRotation; // Factor #2
private double mScaleFactor; // Factor #3
private double mAngleOffset;
#endregion
#region Constructors
public BlockMovingScalingRotating(Entity ent)
: base(ent)
{
ent.TransformBy(MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem);
mAngleOffset = (ent as BlockReference).Rotation;
}
#endregion
#region Overrides
protected override bool Update()
{
switch (mCurJigFactorNumber)
{
case 1:
(Entity as BlockReference).Position = mPosition;
break;
case 2:
(Entity as BlockReference).Rotation = mAngleOffset + mRotation;
break;
case 3:
(Entity as BlockReference).ScaleFactors = new Scale3d(mScaleFactor, mScaleFactor, mScaleFactor);
break;
default:
return false;
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
switch (mCurJigFactorNumber)
{
case 1:
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nBlock position:");
prOptions1.UserInputControls = UserInputControls.GovernedByUCSDetect | UserInputControls.UseBasePointElevation | UserInputControls.Accept3dCoordinates;
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
if (prResult1.Value.Equals(mPosition))
{
return SamplerStatus.NoChange;
}
else
{
mPosition = prResult1.Value;
return SamplerStatus.OK;
}
case 2:
JigPromptAngleOptions prOptions2 = new JigPromptAngleOptions("\nBlock rotation angle:");
prOptions2.BasePoint = mPosition;
prOptions2.UseBasePoint = true;
PromptDoubleResult prResult2 = prompts.AcquireAngle(prOptions2);
if (prResult2.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
if (prResult2.Value.Equals(mRotation))
{
return SamplerStatus.NoChange;
}
else
{
mRotation = prResult2.Value;
return SamplerStatus.OK;
}
case 3:
JigPromptDistanceOptions prOptions3 = new JigPromptDistanceOptions("\nBlock scale factor in percentage:");
prOptions3.BasePoint = mPosition;
prOptions3.UseBasePoint = true;
PromptDoubleResult prResult3 = prompts.AcquireDistance(prOptions3);
if (prResult3.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
if (prResult3.Value.Equals(mRotation))
{
return SamplerStatus.NoChange;
}
else
{
mScaleFactor = prResult3.Value / 100;
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;
BlockMovingScalingRotating jigger = new BlockMovingScalingRotating(ent);
PromptResult pr;
do
{
pr = ed.Drag(jigger);
} while (pr.Status != PromptStatus.Cancel &&
pr.Status != PromptStatus.Error &&
jigger.mCurJigFactorNumber++ <= 3);
return pr.Status == PromptStatus.OK;
}
catch
{
return false;
}
}
#endregion
}
}
Some highlights about the code may be helpful:
• The UserInputControls enumerator values GovernedByUCSDetect and Accept3dCoordinates for the JigPromptPointOptions indicate if the point input honors the UCS and if the picked point is in 3D.
• The UCS transformation can be obtained from the static property Editor.CurrentUserCoordinateSystem.
• An entity type needs to be specified in the EntityJig derivative, as BlockReference here.
• The Sampler() override is to acquire input for the block position and rotation angle 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.
• Please do not forget to handle the cancel/escape circumstance as demonstrated.
• The Update() override is to update the position and the rotation properties of the block 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.
• Only after the jig succeeds should the BlockReference be added to the database to avoid database messy.
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