Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Getting the names of the colors in an AutoCAD color-book using .NET | Main | Launching AutoCAD from a .NET application »

    December 12, 2007

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

          }

        }

      }

    }

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200e54fb2f9178834

    Listed below are links to weblogs that reference Creating an AutoCAD Wipeout using .NET:

    Comments

    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

    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

    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

    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

    Hi Dale,

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

    Regards,

    Kean

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search