Creating an AutoCAD Wipeout using .NET
This topic was suggested via a comment from Dale Bartlett on this post.
In AutoCAD 2008 an API was exposed for the Wipeout object. For those of you who aren't familiar with Wipeouts: this handy object was originally developed as part of the AutoCAD Express Tools, and has since been integrated into core AutoCAD. The implementation uses a raster image of the same colour as the drawing canvas to "wipe out" the graphics behind it (assuming it's nearer the front in terms of draw order relative to the entities being masked). This is the main reason the Wipeout class is derived from RasterImage in the managed API.
The RasterImage-based implementation was chosen at a time when True Color support was not available through AutoCAD's graphics interface (a.k.a. AcGi for the ObjectARX coders reading this). Since then it has been altogether possible to implement Wipeouts without using RasterImage: you can simply use the AcGi protocol to create the same effect. But that's history - once the Wipeout class became widely used it was unfeasible to change the implementation and introduce an incompatibility. On a design note: if the raster had been contained rather that derived from, the choice would have been simpler (an implementation detail, rather than something affecting the class hierarchy in AutoCAD). The design choice was probably due to the capabilities of the ObjectARX API at the time the object was originally developed - containment was inherently more complicated that derivation, back then. Anyway, I digress.
The below C# code shows how to create a Wipeout based on an array of points - in this case we simply make it square, from 0,0 to 100,100. The tricky part is to make sure we close the wipeout manually by specifying the first vertex again as the last point in the list - something Dale and I discovered independently when researching this.
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace WipeoutApplication
{
public class Commands
{
[CommandMethod("CW")]
public void CreateWipeout()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead,
false
);
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite,
false
);
Point2dCollection pts =
new Point2dCollection(5);
pts.Add(new Point2d(0.0, 0.0));
pts.Add(new Point2d(100.0, 0.0));
pts.Add(new Point2d(100.0, 100.0));
pts.Add(new Point2d(0.0, 100.0));
pts.Add(new Point2d(0.0, 0.0));
Wipeout wo = new Wipeout();
wo.SetDatabaseDefaults(db);
wo.SetFrom(pts, new Vector3d(0.0, 0.0, 0.1));
btr.AppendEntity(wo);
tr.AddNewlyCreatedDBObject(wo, true);
tr.Commit();
}
}
}
}

Subscribe via RSS
Hi Kean,
I have an anomoly in that the contents of pts collection change after the SetFrom call:
wo.SetFrom(pts, new Vector3d(0.0, 0.0, 0.1));
I place the following "Before" and "After" the above SetFrom line:
Dim s As String = ""
s = "Before"
For i = 0 To pts.Count - 1
s = s & vbCrLf & "ID " & i & " X: " &pts(i).X & " Y: " & pts(i).Y
Next i
MsgBox(s)
SetFrom appears to return pts scaled to fit in the 1x1 base graphic? Regards, Dale
Posted by: Dale Bartlett | December 13, 2007 at 01:13 AM
Hi Kean, I believe you will find that running your code a few times in the one drawing will result in a Fatal Error, or inconsistant results. Life is one big mystery... Regards, Dale
Posted by: Dale Bartlett | December 13, 2007 at 06:42 AM
Hi Dale,
Yes - it seems the pts array is used to return some data to the caller (perhaps it's related to the clip boundary - it's not fully clear to me what the data represents).
I found that the application did freeze, if CW was called repeatedly. Interestingly this stopped happening if I declared the array as being exactly 5 items long, rather than using the default constructor (which creates a 10-item array). I've adjusted the code by passing 5 to the Point2dCollection constructor. I haven't tested whether this helps in situations where a different number of vertices is passed in (at which point I'd use a different number to 5, of course).
I'd be curious to know whether this helps on your side,
Kean
Posted by: Kean | December 13, 2007 at 10:01 AM
Hi Kean, I have a continuing problem with multiple Wipeouts which ADN has stated requires a product modification. If several Wipeouts are created in the one drawing, AutoCAD will Fatal Error, randomly the Wipeout will have a single grip instead of 4, and the displayed boundary is not the same as the actual boundary. I thought 2009 may have resolved. Do you happen to have a brilliant workaround? Don't say draw them manually...
Thanks, Dale
Posted by: Dale Bartlett | July 09, 2008 at 06:31 AM
Hi Dale,
Please send me the case and/or change request IDs by email, and I'll take a quick look.
Regards,
Kean
Posted by: Kean | July 09, 2008 at 08:37 AM