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();

      }

    }

  }

}

9 responses to “Creating an AutoCAD Wipeout using .NET”

  1. 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

  2. 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

  3. 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

  4. Dale Bartlett Avatar

    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

  5. Kean Walmsley Avatar

    Hi Dale,

    Please send me the case and/or change request IDs by email, and I'll take a quick look.

    Regards,

    Kean

  6. Hi Kean,

    Is there a way to programmatically hide the frames of the wipeouts created this way?

    Regards,

    Leonardo

  7. Hi Leonardo,

    Not that I'm aware of. I see there's a read-only property Wipeout.HasFrame, but I can't see a way to control that programmatically (whether in the Wipeout class, its parent RasterImage class or the parallel COM interface).

    You might try ADN or the AutoCAD .NET Discussion Group (please let me know what you find out).

    Regards,

    Kean

    1. Akshay Kulkarni Avatar
      Akshay Kulkarni

      Hi Kean,

      Thanks for the info.
      I am trying to hide particular region in drawing, it includes hiding region of dynamic blocks.(therefore couldn't use trim feature).
      eg- I want to add chamfer to dynamic block, but since we can not apply chamfer feature to the inserted block in drawing, I tried to hide chamfered area using wipeout feature. But because of wipeout frames it doesnt exactly look like chamfer and it seems like we cant hide frames of wipeout through APIs (didn't find any APIs). Do you happen to know any alternative solution for above challenge?
      I just want to hide triangular area on drawing which can look like chamfer to my drawing by any means through APIs.
      Thanks in advance!

      1. Hi Akshay,

        Please post your support questions to the AutoCAD .NET forum.

        Thank you,

        Kean

Leave a Reply to Akshay Kulkarni Cancel reply

Your email address will not be published. Required fields are marked *