AutoCAD has provided the Overrule .NET API in recent versions. It is the most powerful .NET API so far and can provide almost the custom entity feature that is still only available in the most powerful AutoCAD API, ObjectARX. On the other hand, however, the Overrule API is also the most complex part in the AutoCAD .NET.
From this post on, let us look at the AutoCAD Overrule .NET step by step and demonstrate with simple and functional code example. Centerline Circle is a common drawing element in the engineering design world but is not provided by AutoCAD natively. Though AutoCAD has some means to control how to show the circle center point, it is far from enough.
Here is the centerline circle overrule implementation in the very first version.
#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.Diagnostics;
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
using Autodesk.AutoCAD.GraphicsInterface;
namespace AcadNetAddinWizard_Namespace
{
/// <summary>
/// Features:
/// A derivative from the DrawableOverrule;
/// Being made a singleton to avoid duplicate registrations;
/// UCS being hornored;
/// Adding center lines to all cirlces;
/// WorldDraw.Geometry being used to draw the lines;
/// Drawing the center lines with a particular color (Cyan with index 4);
/// </summary>
public class CenterlineCircle_DrawableOverrule : DrawableOverrule
{
protected CenterlineCircle_DrawableOverrule()
{
}
protected static CenterlineCircle_DrawableOverrule mInstance;
public static CenterlineCircle_DrawableOverrule Instance
{
get
{
if (mInstance == null)
mInstance = new CenterlineCircle_DrawableOverrule();
return mInstance;
}
set
{
mInstance = value;
}
}
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
if (drawable is Circle)
{
Matrix3d ucs = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
Circle cir = drawable as Circle;
Point3d cen = cir.Center.TransformBy(ucs.Inverse());;
double rad = cir.Radius;
Point3d line1Pt1 = new Point3d(cen.X - rad * 1.2, cen.Y, cen.Z).TransformBy(ucs);
Point3d line1Pt2 = new Point3d(cen.X + rad * 1.2, cen.Y, cen.Z).TransformBy(ucs);
Point3d line2Pt1 = new Point3d(cen.X, cen.Y - rad * 1.2, cen.Z).TransformBy(ucs);
Point3d line2Pt2 = new Point3d(cen.X, cen.Y + rad * 1.2, cen.Z).TransformBy(ucs);
short backupColor = wd.SubEntityTraits.Color;
wd.SubEntityTraits.Color = 4;
wd.Geometry.WorldLine(line1Pt1, line1Pt2);
wd.Geometry.WorldLine(line2Pt1, line2Pt2);
wd.SubEntityTraits.Color = backupColor;
}
return base.WorldDraw(drawable, wd);
}
}
}
Here are the commands to show or hide centerlines for circles.
[CommandMethod("ShowCircleCenterline")]
public static void ShowCircleCenterline_Method()
{
CenterlineCircle_Gadgets.RegisterOverrule(typeof(Circle), CenterlineCircle_DrawableOverrule.Instance);
}
[CommandMethod("HideCircleCenterline")]
public static void HideCircleCenterline_Method()
{
CenterlineCircle_Gadgets.UnregisterOverrule(typeof(Circle), CenterlineCircle_DrawableOverrule.Instance);
}
After the centerline circle overrule assembly is loaded into AutoCAD and the ShowCircleCenterline command is run, all regular circles will become centerline circles automatically.
Some highlights may look good to help understand the centerline circle overrule.
• The centerline circle overrule is derived from the DrawableOverrule API class;
• The centerline circle overrule is made a singleton to avoid duplicate registrations or similar issues;
• The centerline circle overrule works with both UCS and WCS;
• The WorldDraw of the centerline circle overrule has been overridden and its Geometry.WorldLine is used to draw the centerlines;
• The centerline circle overrule draws the centerlines with a hard coded color (Cyan with index 4) through setting the WorldDraw.SubEntityTraits.Color property.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders including a Ribbon Creator, and widgets to help program AutoCAD .NET addins.
Hey Spiderinnet,
Tony Tanzillo pointed this out and I have not had time to look into more, but as in your example if you create a block containing a circle which your overruling then just create a table and insert that block into a cell. Then do a save and KABOOM. Not sure how to get around bug, but have seen you got ObjectARX knowledge and might have some insight from creating custom entities that you could maybe shed some light.
Here is thread started by Tony about it http://www.theswamp.org/index.php?topic=42531.0
Posted by: JeffH | 11/05/2012 at 09:08 AM
Sorry I have found some workarounds but the type that make feel un-comfortable and do not like to look at.
Posted by: JeffH | 11/05/2012 at 09:11 AM
Jeff, it also seems like a bug to me. Due to the complexity of the Overrule .NET, there may be something not well taken care of yet here and there. The issue might be among those. In case the workaround works, it is good enough, something is always better than nothing.
In fact, the Overrule .NET articles here will be a series, likely around 30 or more. This is the very first and simple one. More and more Overrule .NET APIs will be covered in the future from simple to complex step by step, as planned. For some particular issues like this, some posts may address them too.
Posted by: Spiderinnet1 | 11/05/2012 at 07:04 PM