Thanks to Stephen Preston, who manages our DevTech Americas team, for donating the samples from his upcoming AU class for posting on this blog.
Let’s start the week with a nice simple sample: the first from Stephen’s AU class. Looking back even to the first C# overrule sample I posted here, I can see that most have been quite complex, mainly because they’ve performed complicated things. Today’s code implements a very simple DrawableOverrule which changes the way lines are displayed in AutoCAD:
Here’s Stephen’s C# code, reformatted to fit the blog:
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.GraphicsInterface;
namespace MyFirstOverrule
{
// This is our custom DrawableOverrule class.
// In this case we're just overruling WorldDraw
public class MyDrawOverrule : DrawableOverrule
{
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
// Cast Drawable to Line so we can access its methods and
// properties
Line ln = (Line)drawable;
// Draw some graphics primitives
wd.Geometry.Circle(
ln.StartPoint + 0.5 * ln.Delta,
ln.Length / 5,
ln.Normal
);
// In this case we don't want the line to draw itself, nor do
// we want ViewportDraw called
return true;
}
}
public class Commands
{
//Shared member variable to store our Overrule instance
private static MyDrawOverrule _drawOverrule;
[CommandMethod("TOG")]
public static void ToggleOverrule()
{
// Initialize Overrule if first time run
if (_drawOverrule == null)
{
_drawOverrule = new MyDrawOverrule();
Overrule.AddOverrule(
RXObject.GetClass(
typeof(Line)),
_drawOverrule,
false
);
Overrule.Overruling = true;
}
else
{
// Toggle Overruling on/off
Overrule.Overruling = !Overrule.Overruling;
}
// Regen is required to update changes on screen
Application.DocumentManager.MdiActiveDocument.Editor.Regen();
}
}
}
Some points to note:
- This code chooses to replace the way lines are currently drawn
- Rather than drawing a line, we draw a circles at the line’s mid-point with a radius relative to the line’s length
- We’ve deliberately kept the code very simple: a single command (TOG) is used to toggle the use of the overrule
- Rather than always relying on toggling the overall Overruling state, we force it to true when we run for the first time
- I have another application loaded that implements overrules: the first time the TOG command was run previously, overruling was actually turned off if we don’t do it this way
To try the code, build the application against AutoCAD 2010 (or even higher, if you’re visiting us from the future :-) and draw some lines:
Now let’s NETLOAD our application and run the TOG command:
Each line has been “replaced” by a circle. But when we select one of the circles, we see it’s really just a line, and shows the grips a line would:
When we grip-edit an end-point of one of our lines, we can see it changing the line, but the graphics displayed continue to be circular:
And finally, if we finish the editing operation and run the TOG command again we see the lines has been modified:
That’s it for today’s post. I’ll probably be delving further into Stephen’s material for posts later in the week.
Update
It seems there has been some kind of change in AutoCAD since this post was made: it's no longer (at least in AutoCAD 2012) possible to disable application-wide overruling by setting Overrule.Overruling to false. This actually makes some sense, in my opinion: it would be logical for overrules to be selective removed, rather than allowing applications to trample on each other.
Here's the updated C# code that shows how to effectively toggle an overrule on and off without relying on this flag:
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.GraphicsInterface;
namespace MyFirstOverrule
{
// This is our custom DrawableOverrule class.
// In this case we're just overruling WorldDraw
public class MyDrawOverrule : DrawableOverrule
{
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
// Cast Drawable to Line so we can access its methods and
// properties
Line ln = (Line)drawable;
// Draw some graphics primitives
wd.Geometry.Circle(
ln.StartPoint + 0.5 * ln.Delta,
ln.Length / 5,
ln.Normal
);
// In this case we don't want the line to draw itself, nor do
// we want ViewportDraw called
return true;
}
}
public class Commands
{
// Shared member variable to store our Overrule instance
private static MyDrawOverrule _drawOverrule;
[CommandMethod("TOG")]
public static void ToggleOverrule()
{
// Initialize Overrule if first time run
if (_drawOverrule == null)
{
// Turn Overruling on
_drawOverrule = new MyDrawOverrule();
Overrule.AddOverrule(
RXObject.GetClass(
typeof(Line)),
_drawOverrule,
false
);
Overrule.Overruling = true;
}
else
{
// Turn Overruling off
Overrule.RemoveOverrule(
RXObject.GetClass(
typeof(Line)), _drawOverrule
);
_drawOverrule.Dispose();
_drawOverrule = null;
}
// Regen is required to update changes on screen
Application.DocumentManager.MdiActiveDocument.Editor.Regen();
}
}
}