We provided various jig implementations before, either using EntityJig or DrawJig, either from scratch or with the assistance of the Entity Jigger or Draw Jigger of AcadNetAddinWizard(Pro).
We demonstrated how to jig a MultiLeader programmatically through an arrow location and a single landing location using AutoCAD .NET and C#. We also showed how to jig multiple landing locations. We presented last time how to jig block content instead of the default MText content. In this post, we are going to extend the jig to support any blocks having attributes defined. This will make the MLeaderJigger more flexible and useful since the block content will likely change from one case to another in the real design world.
Here we go.
#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.Diagnostics;
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 AcadNetCSharp
{
public class MLeaderJigger4 : EntityJig
{
#region Fields
private const string BlockName = "tagAtt";
public static string TagContent = "";
public int mCurJigFactorIndex = 1; // Jig Factor Index
public Autodesk.AutoCAD.Geometry.Point3d mArrowLocation; // Jig Factor #1
public Autodesk.AutoCAD.Geometry.Point3d mLandingLocation; // Jig Factor #2
#endregion
#region Constructors
public MLeaderJigger4(MLeader ent)
: base(ent)
{
Entity.SetDatabaseDefaults();
Entity.ContentType = ContentType.BlockContent;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
Entity.BlockContentId = bt[BlockName];
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(Entity.BlockContentId, OpenMode.ForWrite);
if (btr.HasAttributeDefinitions)
{
foreach (ObjectId id in btr)
{
DBObject obj = tr.GetObject(id, OpenMode.ForRead);
if (obj is AttributeDefinition)
{
AttributeDefinition ad = obj as AttributeDefinition;
AttributeReference ar = new AttributeReference();
ar.SetAttributeFromBlock(ad, Matrix3d.Displacement(Entity.BlockPosition - Point3d.Origin));
ar.TextString = TagContent;
Entity.SetBlockAttribute(id, ar);
}
}
}
tr.Commit();
}
Entity.EnableDogleg = true;
Entity.EnableLanding = true;
Entity.EnableFrameText = false;
Entity.AddLeaderLine(mLandingLocation);
Entity.SetFirstVertex(0, mArrowLocation);
Entity.TransformBy(UCS);
}
#endregion
#region Properties
private Editor Editor
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
}
}
private Matrix3d UCS
{
get
{
return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
}
}
#endregion
#region Overrides
public new MLeader Entity // Overload the Entity property for convenience.
{
get
{
return base.Entity as MLeader;
}
}
protected override bool Update()
{
switch (mCurJigFactorIndex)
{
case 1:
Entity.SetFirstVertex(0, mArrowLocation);
Entity.SetLastVertex(0, mArrowLocation);
break;
case 2:
Entity.SetLastVertex(0, mLandingLocation);
break;
default:
return false;
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
switch (mCurJigFactorIndex)
{
case 1:
JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nArrow Location:");
// Set properties such as UseBasePoint and BasePoint of the prompt options object if necessary here.
prOptions1.UserInputControls = UserInputControls.Accept3dCoordinates | UserInputControls.GovernedByOrthoMode | UserInputControls.GovernedByUCSDetect | UserInputControls.UseBasePointElevation;
PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
if (prResult1.Status == PromptStatus.Cancel && prResult1.Status == PromptStatus.Error)
return SamplerStatus.Cancel;
if (prResult1.Value.Equals(mArrowLocation)) //Use better comparison method if necessary.
{
return SamplerStatus.NoChange;
}
else
{
mArrowLocation = prResult1.Value;
return SamplerStatus.OK;
}
case 2:
JigPromptPointOptions prOptions2 = new JigPromptPointOptions("\nLanding Location:");
// Set properties such as UseBasePoint and BasePoint of the prompt options object if necessary here.
prOptions2.UseBasePoint = true;
prOptions2.BasePoint = mArrowLocation;
prOptions2.UserInputControls = UserInputControls.Accept3dCoordinates | UserInputControls.GovernedByOrthoMode | UserInputControls.GovernedByUCSDetect | UserInputControls.UseBasePointElevation;
PromptPointResult prResult2 = prompts.AcquirePoint(prOptions2);
if (prResult2.Status == PromptStatus.Cancel && prResult2.Status == PromptStatus.Error)
return SamplerStatus.Cancel;
if (prResult2.Value.Equals(mLandingLocation)) //Use better comparison method if necessary.
{
return SamplerStatus.NoChange;
}
else
{
mLandingLocation = prResult2.Value;
return SamplerStatus.OK;
}
default:
break;
}
return SamplerStatus.OK;
}
#endregion
#region Methods to Call
public static MLeader Jig()
{
MLeaderJigger4 jigger = null;
try
{
jigger = new MLeaderJigger4(new MLeader());
PromptResult pr;
do
{
pr = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger);
if (pr.Status == PromptStatus.Keyword)
{
// Keyword handling code
}
else
{
jigger.mCurJigFactorIndex++;
}
} while (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && jigger.mCurJigFactorIndex <= 2);
if (pr.Status == PromptStatus.Cancel || pr.Status == PromptStatus.Error)
{
if (jigger != null && jigger.Entity != null)
jigger.Entity.Dispose();
return null;
}
return jigger.Entity;
}
catch(System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
if (jigger != null && jigger.Entity != null)
jigger.Entity.Dispose();
return null;
}
}
#endregion
#region Test Commands
[CommandMethod("TestMLeaderJigger4")]
public static void TestMLeaderJigger4_Method()
{
try
{
TagContent = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.GetString("\nTag: ").StringResult;
Entity jigEnt = MLeaderJigger4.Jig();
if (jigEnt != null)
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(jigEnt);
tr.AddNewlyCreatedDBObject(jigEnt, true);
tr.Commit();
}
}
}
catch (System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
}
}
#endregion
}
}
The workflow and output may look like the following:
As can be seen, the block attribute value (tag) is collected first so that the tag with the exact string value can be jigged nicely along with the arrow, leader line, and standing line. The UCS is still perfectly honored. Before running the jig test code, please make sure a block named “tagAtt” exists and it has at least a block attribute defined. The block attribute can have any tag name. If multiple block attributes defined, all of them will have the value as input at the beginning of the jigging.
By the way, the leading edge AutoCAD .NET Addin Wizard Professional (AcadNetAddinWizardPro) helped create the project, the jig class, and the test command automatically in a moment. If you find the article and code here, or any wizards/coders/widgets of AcadNetAddinWizardPro helpful, please kindly make a donation.
Recent Comments