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



    « Automatic closing of AutoCAD objects with ObjectARX SmartPointers | Main | The New RibbonBar API in AutoCAD 2009 »

    April 07, 2008

    Extracting XML data from drawings using a new .NET API in AutoCAD 2009

    This post is the latest in the series of closer looks at the new APIs in AutoCAD 2009. It covers the Data Extraction API, a new .NET API allowing you to drive the Data Extraction feature inside AutoCAD.

    There is a very thorough C# sample included on the ObjectARX SDK (under samples/dotNet/DataExtraction), so I thought I'd focus on a much simpler example where we extract data from a single drawing.

    Here's the C# code:

    using System.Collections.Generic;

    using Autodesk.AutoCAD.ApplicationServices;

    using Autodesk.AutoCAD.EditorInput;

    using Autodesk.AutoCAD.Runtime;

    using Autodesk.AutoCAD.DataExtraction;


    namespace DataExtraction

    {

      public class Commands

      {

        const string path =

          @"c:\Program Files\Autodesk\AutoCAD 2009\Sample\";

        const string fileName =

          "Visualization - Aerial.dwg";

        const string outputXmlFile =

          @"c:\temp\data-extract.xml";


        [CommandMethod("extd")]

        public void extractData()

        {

          if (!System.IO.File.Exists(path + fileName))

          {

            Document doc =

              Application.DocumentManager.MdiActiveDocument;

            Editor ed =

              doc.Editor;

            ed.WriteMessage("\nFile does not exist.");


            return;

          }


          // Create some settings for the extraction


          IDxExtractionSettings es =

            new DxExtractionSettings();


          IDxDrawingDataExtractor de =

            es.DrawingDataExtractor;


          de.Settings.ExtractFlags =

            ExtractFlags.ModelSpaceOnly |

            ExtractFlags.XrefDependent |

            ExtractFlags.Nested;


          // Add a single file to the settings


          IDxFileReference fr =

            new DxFileReference(path, path + fileName);


          de.Settings.DrawingList.AddFile(fr);


          // Scan the drawing for object types & their properties


          de.DiscoverTypesAndProperties(path);


          List<IDxTypeDescriptor> types =

            de.DiscoveredTypesAndProperties;


          // Select all the types and properties for extraction

          // by adding them one-by-one to these two lists


          List<string> selTypes = new List<string>();

          List<string> selProps = new List<string>();


          foreach (IDxTypeDescriptor type in types)

          {

            selTypes.Add(type.GlobalName);

            foreach (

              IDxPropertyDescriptor pr in type.Properties

            )

            {

              if (!selProps.Contains(pr.GlobalName))

                selProps.Add(pr.GlobalName);

            }

          }


          // Pass this information to the extractor


          de.Settings.SetSelectedTypesAndProperties(

            types,

            selTypes,

            selProps

          );


          // Now perform the extraction itself


          de.ExtractData(path);


          // Get the results of the extraction


          System.Data.DataTable dataTable =

            de.ExtractedData;


          // Output the extracted data to an XML file


          if (dataTable.Rows.Count > 0)

          {

            dataTable.TableName = "My_Data_Extract";

            dataTable.WriteXml(outputXmlFile);

          }

        }

      }

    }

    Here are the first few objects from the output file found in c:\temp\data-extract.xml after running the EXTD command:

    <?xml version="1.0" standalone="yes"?>

    <DocumentElement>

      <My_Data_Extract>

        <AcDxHandleData>183</AcDxHandleData>

        <Layer>0</Layer>

        <LinetypeScale>1</LinetypeScale>

        <PlotStyleName>ByLayer</PlotStyleName>

        <LineWeight>ByLayer</LineWeight>

        <Material>Material 3</Material>

        <Linetype>ByLayer</Linetype>

        <Color>ByLayer</Color>

        <AcDxObjectTypeName>3D Solid</AcDxObjectTypeName>

        <AcDxObjectTypeGlobalName>

          Autodesk.AutoCAD.DatabaseServices.Solid3d

        </AcDxObjectTypeGlobalName>

        <AcDxDwgSummaryDwgName>

          Visualization - Aerial.dwg

        </AcDxDwgSummaryDwgName>

        <AcDxDwgSummaryDwgLocation>

          c:\Program Files\Autodesk\AutoCAD 2009\Sample

        </AcDxDwgSummaryDwgLocation>

        <AcDxDwgSummaryDwgSize>472480</AcDxDwgSummaryDwgSize>

        <AcDxDwgSummaryDwgCreated>

          2007-01-03T00:44:20+01:00

        </AcDxDwgSummaryDwgCreated>

        <AcDxDwgSummaryDwgModified>

          2007-01-03T00:44:20+01:00

        </AcDxDwgSummaryDwgModified>

        <AcDxDwgSummaryDwgAccessed>

          2008-03-03T11:40:53.796875+01:00

        </AcDxDwgSummaryDwgAccessed>

        <AcDxDwgSummaryDwgTitle />

        <AcDxDwgSummaryDwgSubject />

        <AcDxDwgSummaryDwgAuthor />

        <AcDxDwgSummaryDwgKeywords />

        <AcDxDwgSummaryDwgComments />

        <AcDxDwgSummaryDwgHyperLinkBase />

        <AcDxDwgSummaryDwgLastSavedBy>

          thompsl

        </AcDxDwgSummaryDwgLastSavedBy>

        <AcDxDwgSummaryDwgRevisionNumber />

        <AcDxDwgSummaryDwgTotalEditingTime>

          1179

        </AcDxDwgSummaryDwgTotalEditingTime>

        <AcDxEntityHyperlink />

      </My_Data_Extract>

      <My_Data_Extract>

        <AcDxHandleData>191</AcDxHandleData>

        <Layer>0</Layer>

        <LinetypeScale>1</LinetypeScale>

        <PlotStyleName>ByLayer</PlotStyleName>

        <LineWeight>ByLayer</LineWeight>

        <Material>Material 3</Material>

        <Linetype>ByLayer</Linetype>

        <Color>ByLayer</Color>

        <AcDxObjectTypeName>3D Solid</AcDxObjectTypeName>

        <AcDxObjectTypeGlobalName>

          Autodesk.AutoCAD.DatabaseServices.Solid3d

        </AcDxObjectTypeGlobalName>

        <AcDxDwgSummaryDwgName>

          Visualization - Aerial.dwg

        </AcDxDwgSummaryDwgName>

        <AcDxDwgSummaryDwgLocation>

          c:\Program Files\Autodesk\AutoCAD 2009\Sample

        </AcDxDwgSummaryDwgLocation>

        <AcDxDwgSummaryDwgSize>472480</AcDxDwgSummaryDwgSize>

        <AcDxDwgSummaryDwgCreated>

          2007-01-03T00:44:20+01:00

        </AcDxDwgSummaryDwgCreated>

        <AcDxDwgSummaryDwgModified>

          2007-01-03T00:44:20+01:00

        </AcDxDwgSummaryDwgModified>

        <AcDxDwgSummaryDwgAccessed>

          2008-03-03T11:40:53.796875+01:00

        </AcDxDwgSummaryDwgAccessed>

        <AcDxDwgSummaryDwgTitle />

        <AcDxDwgSummaryDwgSubject />

        <AcDxDwgSummaryDwgAuthor />

        <AcDxDwgSummaryDwgKeywords />

        <AcDxDwgSummaryDwgComments />

        <AcDxDwgSummaryDwgHyperLinkBase />

        <AcDxDwgSummaryDwgLastSavedBy>

          thompsl

        </AcDxDwgSummaryDwgLastSavedBy>

        <AcDxDwgSummaryDwgRevisionNumber />

        <AcDxDwgSummaryDwgTotalEditingTime>

          1179

        </AcDxDwgSummaryDwgTotalEditingTime>

        <AcDxEntityHyperlink />

      </My_Data_Extract>

      <!-- Stuff deleted from the XML output -->

      <!-- ... -->

    </DocumentElement>

    TrackBack

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

    Listed below are links to weblogs that reference Extracting XML data from drawings using a new .NET API in AutoCAD 2009:

    Comments

    Kean,
    Is this available through C++?
    How to make our custom objects support XML exporting?

    Fernando.

    Fernando,

    I don't think that's currently possible: it doesn't appear to pick up properties exposed through COM, although I haven't tried with a managed wrapper.

    Please submit your question via the ADN site for someone to look into.

    Regards,

    Kean

    Oh - and this is a managed API, so it can be called from C++. There isn't an unmanaged C++ API, though.

    Kean

    When compiling, I get the following message: The type or namespace name 'DataExtraction' does not exist in the namespace 'Autodesk.AutoCAD' (are you missing an assembly reference?)

    Which assembly do I need to add as a reference?

    Ah yes - I missed a step: you need to add a project reference to AcDx.dll, which can be found in the inc-win32 and inc-x64 folders of the ObjectARX 2009 SDK (as well as being in the AutoCAD 2009 root folder).

    Regards,

    Kean

    Hello,

    Was the following an error:
    IDxExtractionSettings es =
    es = new DxExtractionSettings();

    Should it have been written like:
    IDxExtractionSettings es = new DxExtractionSettings();

    Or, doesn't it make any difference?

    Thank You

    Hi Tom,

    It was a typo - thanks for spotting it. I've fixed the post.

    Regards,

    Kean

    you can filter the properties customized and bring only what you need?

    I believe so, although I didn't try it.

    Kean

    Hi Kean.
    I just popped this into VB and took out the hard coded filenames. I ran it on a drawing created by my automation program, and the only thing I don't see extracted is Xdata.
    I'd be interested in figuring out if that could be done. (in the data extraction tool, I know how to do it otherwise)

    Actually I also saw something else a little strange... I have a particular type of block which is inserted with varying X-scales so that the length of the block changes. The Attribute references show up under the data for the block, but the specific data for the attribute references themselves does not show up next in the list, like it did for other uniformly scaled blocks. At the moment I don't think this concerns me, I just found it interesting.

    Hi David,

    I hadn't tried this with Xdata, but it doesn't fully surprise me that this isn't currently supported.

    Xdata content tends to be stored fairly generically - the group codes don't have standardised, human-readable labels - so some logic would be needed to map these to XML elements. Not to say it's very hard to do, but it doesn't surprise me that it hasn't been done.

    I hadn't come across non-uniform blocks acting differently. If you're an ADN member it would be great if you could submit it there with a reproducible case.

    Thanks,

    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