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 use the DrawJig to drag a 2d light weight Polyline with line segments.
Here is the whole DrawJig implementation 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 DrawJigger6 : DrawJig
{
#region Fields
private Point3dCollection mAllVertexes = new Point3dCollection();
private Point3d mLastVertex;
#endregion
#region Constructors
public DrawJigger6()
{
}
~DrawJigger6()
{
}
#endregion
#region Properties
public Point3d LastVertex
{
get { return mLastVertex; }
set { mLastVertex = 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);
Point3dCollection tempPts = new Point3dCollection();
foreach (Point3d pt in mAllVertexes)
{
tempPts.Add(pt);
}
if( mLastVertex != null )
tempPts.Add(mLastVertex);
if (tempPts.Count > 0)
geo.Polyline(tempPts, Vector3d.ZAxis, IntPtr.Zero);
geo.PopModelTransform();
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nVertex(Enter to finish)");
prOptions1.UseBasePoint = false;
prOptions1.UserInputControls =
UserInputControls.NullResponseAccepted | UserInputControls.Accept3dCoordinates |
UserInputControls.GovernedByUCSDetect | UserInputControls.GovernedByOrthoMode |
UserInputControls.AcceptMouseUpAsPoint;
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status == PromptStatus.Cancel || prResult1.Status == PromptStatus.Error)
return SamplerStatus.Cancel;
Point3d tempPt = prResult1.Value.TransformBy(UCS.Inverse());
mLastVertex = tempPt;
return SamplerStatus.OK;
}
#endregion
#region Commands
public static DrawJigger6 jigger;
[CommandMethod("TestDrawJigger6")]
public static void TestDrawJigger6_Method()
{
try
{
Database db = HostApplicationServices.WorkingDatabase;
jigger = new DrawJigger6();
PromptResult jigRes;
do
{
jigRes = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger);
if( jigRes.Status == PromptStatus.OK )
jigger.mAllVertexes.Add(jigger.mLastVertex);
} while (jigRes.Status == PromptStatus.OK);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
Autodesk.AutoCAD.DatabaseServices.Polyline ent = new Autodesk.AutoCAD.DatabaseServices.Polyline();
ent.SetDatabaseDefaults();
for (int i = 0; i < jigger.mAllVertexes.Count; i++)
{
Point3d pt3d = jigger.mAllVertexes[i];
Point2d pt2d = new Point2d(pt3d.X, pt3d.Y);
ent.AddVertexAt(i, pt2d, 0, db.Plinewid, db.Plinewid);
}
ent.TransformBy(jigger.UCS);
btr.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
}
catch (System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
}
}
#endregion
}
}
After the test assembly is loaded and the test command run, we will see the jigging of the poly lines may behave like the following:
A few highlights about the code may be more helpful.
• The key of the DrawJig is its WorldDraw() method. It provides the abilities to draw any graphics.
• The WorldGeometry instance provides 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 exactly the same as the one in EntityJig, it has a fundamental difference. 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 Polyline method takes some parameters about the poly line graphics such as point collection and normal. Other properties such as Color can be set through the SubEntityTraits as was demonetrated a few times before.
• The SubEntityTraits object of the WorldDraw instance can be used to set graphics attributes such as color and more like line type, layer, line weight and so on. It may not look so obvious.
• The UCS is perfectly honored with the built-in model transformation mechanism through the PushModelTransform and PopModelTransform methods 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.
• In terms of a poly line jig, we can use EntityJig to reproduce the same behavior as the DrawJig does here, with some possible overheads such as the last temporary vetext adding and removing frequently as we did to the MLine EntityJig that we demonstrated a bit earlier. We may do so in the future so as to compare their implementations.
Enjoy it! More and cooler jigging samples and cases will be demonstrated in the future. Please stay tuned.
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: |