AutoCAD .NET API provides two concrete Jig classes for us to jig different things 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 post, let us see how to drag a circle with its center moved by cursor and color changed automatically and dynamically with time using DrawJig. Here is the whole class along with a test command inside it.
#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 Autodesk.AutoCAD.GraphicsSystem;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.ComponentModel;
using Autodesk.AutoCAD.Customization;
using Autodesk.AutoCAD.DataExtraction;
using Autodesk.AutoCAD.Diagnostics;
using Autodesk.AutoCAD.Internal;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.MacroRecorder;
using Autodesk.AutoCAD.Publishing;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Ribbon;
using MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using MgdAcDocument = Autodesk.AutoCAD.ApplicationServices.Document;
using AcWindowsNS = Autodesk.AutoCAD.Windows;
#endregion
namespace AcadNetAddinWizard_Namespace
{
public class DrawJigger2 : DrawJig
{
#region Fields
private double mRadius;
private Point3d mCenter;
private short mColorIndex;
#endregion
#region Constructors
public DrawJigger2()
{
mRadius = 10.0;
mCenter = Point3d.Origin;
mColorIndex = 0;
}
#endregion
#region Properties
public double Radius
{
get { return mRadius; }
set { mRadius = value; }
}
public short Color
{
get
{
mColorIndex = (short) (DateTime.Now.Millisecond % 256);
return mColorIndex;
}
}
public Point3d Center
{
get { return mCenter; }
set { mCenter = value; }
}
private Editor Editor
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
}
}
public Matrix3d UCS
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
}
}
#endregion
#region Overrides
protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
{
WorldGeometry geo = draw.Geometry;
if (geo != null)
{
geo.PushModelTransform(UCS);
draw.SubEntityTraits.Color = Color;
geo.Circle(mCenter, mRadius, Vector3d.ZAxis);
geo.PopModelTransform();
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nCenter:");
prOptions1.UseBasePoint = false;
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status == PromptStatus.Cancel || prResult1.Status == PromptStatus.Error)
return SamplerStatus.Cancel;
Point3d tempPt = prResult1.Value.TransformBy(UCS.Inverse());
mCenter = tempPt;
return SamplerStatus.OK;
}
#endregion
#region Commands
[CommandMethod("TestDrawJigger2")]
public static void TestDrawJigger2_Method()
{
try
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
DrawJigger2 jigger = new DrawJigger2();
PromptResult jigRes = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger);
if (jigRes.Status == PromptStatus.OK)
{
using (Circle ent = new Circle())
{
ent.Center = jigger.Center;
ent.Radius = jigger.Radius;
ent.ColorIndex = jigger.Color;
ent.TransformBy(jigger.UCS);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
}
}
tr.Commit();
}
}
catch (System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
}
}
#endregion
}
}
This DrawJig for Circle here is a bit fancy for it changes the circle color automatically with time based on an algorithm. Here is a screenshot of the DrawJig graphics for the moment that the circle looks light green.
A few highlights about the code may be helpful.
• The key of the DrawJig is its WorldDraw() method. It provides the abilities to draw any graphics.
• The WorldGeometry instance privides various methods to draw anything we want.
• It also provides us a structural and easy way for us to handle any matrix transformations as we did to the UCS.
• The Sampler() override is another core method which is used to collect the user input such as the cursor position in the case.
• Though the Sampler() looks like exackly the same as the one in EntityJig, it has fundamental different. In the EntityJig, the collected point is in UCS unless explicitly specified with the Input Control; but in the DrawJig, the point coordinate is in WCS. That is why we had to transform it back to UCS to make things consistent.
• The WorldGeometry Circle method takes three parameters as usual, center, radius and normal. We used the Z Axis of the current UCS as the normal to make things consistent again.
• The circle color indes was determined this way, the reminder of the current milliseconds divided by 256. It can be adjusted to meet different needs for sure.
• The SubEntityTraits object of the WorldDraw instance can be used to set graphics attributes such as the circle color here and more like line type, layer, line weight and son on. It may not look so obvious.
• The UCS is perfectly hornored with the built-in model transformation mechanism through the PushModelTransform and PopModelTransform method of the WorldGeometry instance and our own measures such as transforming the collected points from the default WCS back to the UCS.
• In generally, we do not pass the entity pointer to the DrawJig as it should not only care about graphics of a particular entity. Otherwise, it becomes right the EntityJig with quite some overheads brought about from the WorldGeometry such as reinventing the draw feature of the entity.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides a coder, Draw Jigger, to help us create starter code for DrawJig implementations automatically, quickly and reliably.
Posted by: |