Striking an enclosed text area in AutoCAD using .NET

I'm still on pseudo-vacation. We really had a great week in the snow: sun during the day (everyday!) with the odd bit of fresh snow overnight on a couple of occasions. It's snowing again now, but unfortunately this time it's set to snow all the way through to the end of the day tomorrow, so it's quite possible we'll head home a little earlier than expected. Which, on the plus side, will allow me to do some prep-work for Monday's Geneva Motor Show project installation.

Anyway, all this to say that I've written this post really quickly with plenty of shortcuts. Alex Fielder pinged me earlier with a requirement he has, and – given the other things going on – I thought I'd start with something quick and dirty.

Consider this a classic strawman implementation that's designed to stimulate user feedback: it probably doesn't come close to meeting Alex's needs, but then it gives him some tyres to kick and say what's working or not.

The various "issues" I have with the implementation are listed in the comments in this simple C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

 

namespace StrikeText

{

  public class Commands

  {

    [CommandMethod("STXT")]

    public static void StrikeTextArea()

    {

      var doc =

        Application.DocumentManager.MdiActiveDocument;

      var db = doc.Database;

      var ed = doc.Editor;

 

      // Ask for a point. Could also ask for an enclosed text entity

      // and use the picked point or the text's insertion point

 

      var ppo = new PromptPointOptions("\nSelect point");

      var ppr = ed.GetPoint(ppo);

      if (ppr.Status != PromptStatus.OK)

        return;

 

      using (var tr = db.TransactionManager.StartTransaction())

      {

        // Use Editor.TraceBoundary() to check for a suitable

        // boundary. This may throw up a dialog, if selecting a

        // space inside a table, for instance (before you explode

        // it manually). Not ideal - it basically uses the same

        // code path as BHATCH or BOUNDARY, which includes a dialog

 

        var oc = ed.TraceBoundary(ppr.Value, false);

 

        // Only deal with the case where we get a single entity

        // returned

 

        if (oc.Count == 1)

        {

          var ent = oc[0] as Entity;

          if (ent != null)

          {

            // Get the extents of the entity and determine points

            // at the top left and bottom right corners. This is

            // super-simplistic: will only work if we're dealing

            // with a WCS-aligned area. More work needed if dealing

            // with areas with other alignments

 

            var ext = ent.GeometricExtents;

            var pt1 = new Point3d(ext.MinPoint.X, ext.MaxPoint.Y, 0);

            var pt2 = new Point3d(ext.MaxPoint.X, ext.MinPoint.Y, 0);

 

            // Create a line between these points

 

            var ln = new Line(pt1, pt2);

 

            // Add it to the current space

 

            var btr =

              (BlockTableRecord)tr.GetObject(

                db.CurrentSpaceId, OpenMode.ForWrite

              );

            btr.AppendEntity(ln);

            tr.AddNewlyCreatedDBObject(ln, true);

          }

        }

 

        // Commit even if we didn't add anything

 

        tr.Commit();

      }

    }

  }

}

When you run the STXT command and selecting a point in an enclosed area, it should strike it through from top-left to bottom-right. Providing the various assumptions mentioned in the code are true, of course.

2 responses to “Striking an enclosed text area in AutoCAD using .NET”

  1. Brian Chapman Avatar

    Hi Kean, thanks for this. Trying to find way to identify the internal areas for the TraceBoundary() without using GetPoints...any suggestions?

  2. Kean Walmsley Avatar

    Hi Brian,

    How about iterating the current space, looking for text objects and then taking their insertion point?

    I assume that's the kind of thing you mean - just say if I have it wrong.

    Regards,

    Kean

Leave a Reply to Brian Chapman Cancel reply

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