Kean Walmsley


  • About the Author
    Kean on Google+

July 2014

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    








« Retro computing with the Raspberry Pi | Main | Animating transient AutoCAD graphics using .NET »

October 05, 2012

Querying for XCLIP information inside AutoCAD using .NET

This question came in recently by email:

I have reached a snag when trying to find the boundaries of external references that have been "xclipped" by the user. Or, to be more precise, I can't even really find the data telling me whether or not the external reference has been "xclipped" at all. I'm wondering if you have any idea how or where I could find this data.

While I found this previous post showing how to perform an XCLIP, I couldn’t find anything showing how to query for XCLIP information.

Here’s some C# code that does just that for a selected block or external reference:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.DatabaseServices.Filters;

using System.Collections.Generic;

 

namespace SpatialFiltering

{

  public class Commands

  {

    const string filterDictName = "ACAD_FILTER";

    const string spatialName = "SPATIAL";

 

    [CommandMethod("DXC")]

    static public void DetectXClip()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      var ed = doc.Editor;

 

      // Ask for an xclipped xref to be selected

 

      var peo =

        new PromptEntityOptions(

          "\nSelect xclipped block or xref"

        );

      peo.SetRejectMessage("Must be a block or xref.");

      peo.AddAllowedClass(typeof(BlockReference), false);

 

      var per = ed.GetEntity(peo);

 

      if (per.Status != PromptStatus.OK)

        return;

 

      var tr = doc.TransactionManager.StartTransaction();

      using (tr)

      {

        // Open the selected BlockReference

 

        var br =

          tr.GetObject(per.ObjectId, OpenMode.ForRead)

          as BlockReference;

 

        // To save multiple codepaths with the same message

        // ("No clipping information found"), we'll use a flag to

        // see whether we've found anything

 

        bool found = false;

 

        // It should always be a block reference, but it might

        // not have an extension dictionary

 

        if (

          br != null && br.ExtensionDictionary != ObjectId.Null)

        {

          // The extension dictionary needs to contain a nested

          // dictionary called ACAD_FILTER

 

          var extdict =

            tr.GetObject(br.ExtensionDictionary, OpenMode.ForRead)

            as DBDictionary;

          if (extdict != null && extdict.Contains(filterDictName))

          {

            var fildict =

              tr.GetObject(

                extdict.GetAt(filterDictName), OpenMode.ForRead

              ) as DBDictionary;

            if (fildict != null)

            {

              // The nested dictionary should contain a

              // SpatialFilter object called SPATIAL

 

              if (fildict.Contains(spatialName))

              {

                var fil =

                  tr.GetObject(

                    fildict.GetAt(spatialName), OpenMode.ForRead

                  ) as SpatialFilter;

                if (fil != null)

                {

                  // We have a SpatialFilter: print its bounds

 

                  var ext = fil.GetQueryBounds();

                  ed.WriteMessage(

                    "\nFound clip from {0} to {1}.",

                    ext.MinPoint, ext.MaxPoint

                  );

                  var pts = fil.Definition.GetPoints();

                  foreach (var pt in pts)

                  {

                    ed.WriteMessage(

                      "\nBoundary point at {0}", pt

                    );

                  }

                  found = true;

                }

              }

            }

          }

        }

        if (!found)

        {

          ed.WriteMessage("\nNo clipping information found.");

        }

        tr.Commit();

      }

    }

  }

}

When we run the DXC command and selected an XCLIPped block or external reference, we see its clipping information printed to the command-line:

Command: DXC

Select xclipped block or xref:

Found clip from (4.05811894970383,5.24702344885421,-10000000000) to (6.37251127340078,8.93717310957857,10000000000).

Boundary point at (4.39197755714056,8.93717310957849)

Boundary point at (4.05811894970388,7.08011285053157)

Boundary point at (4.71314514170174,5.24702344885429)

Boundary point at (5.97105160306316,6.93165698166899)

Boundary point at (6.13163547119819,7.89430470599807)

Boundary point at (6.37251127340073,8.34888837222314)

blog comments powered by Disqus

10 Random Posts