Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

Simple DXF Reader/Viewer with Spline Support

4.50/5 (5 votes)
16 Jun 2014CPOL2 min read 19.9K  
This is an alternative for Simple DXF Reader/Viewer with Spline Support

Introduction

This fixes three bugs in Hasan Gurler's original code:

  • Extra whitespace in the DXF files, in the code tags and in the text objects, confused the parser and so the application failed to read such files.
  • Memory allocated to store the data from the file was not released when another file was read: the result was a significant memory leak.
  • The DXF parser assumes the tags are written to the file in an expected order, but the DXF standard specifically states that this cannot be assumed. If the tags are in a different order, the parser would fail to read the file.

This also provides:

  • Memory management improvements by using STL vectors
  • Updated code to use C++11
  • Addition of an application built using the wxWidgets GUI framework
  • Simplified and more efficient spline drawing

Using the Code

The code is available in a workspace forked from Gurler's.

There are two branches in the workspace. The master branch contains the fixes for the bugs. This will compile and build the MFC application without a C++11 compiler.

The mingw branch also fixes the bugs and adds the wxWidget application with optimized spline drawing plus a few other minor optimizations of the code to scale the drawing to the window. This requires a C++11 compiler.

The MFC application in the mingw branch does not use the optimized spline drawing or improved scaling because I do not have a toolchain that supports both MFC and C+11.

The mingw branch provides a consistent API for drawing all graphical objects found in the DXF file. For objects which can be drawn in one operation (line, circle and arc), it works like this:

  • Construct structure to contain scaled drawing paramters s_dxf_draw
  • Loop over all objects of one type
    • Initalize drawing parameter structure by calling method CDxf::Init( s_dxf_draw& )
    • Fill drawing parameter structure by calling the method getDraw( s_dxf_draw& ) on the current object
    • Call the appropriate drawing method ( e.g. wxDC::DrawLine() ) for your framework using the drawing parameters

Look complex? Here is the code to draw all the lines:

C++
s_dxf_draw draw;

for( CLine& line : dxf->m_Line )
{
    dxf->Init( draw );
    line.getDraw( draw );
    dc.DrawLine( draw.x1, draw.y1, draw.x2, draw.y2 );
}

If the object requires multiple operations to draw ( polyline or spline ), then you need to call getDraw() multiple times until it returns false. Here is the code to draw the splines:

C++
for( CSpline& spline : dxf->m_Spline )
{
    dxf->Init( draw );
    while( spline.getDraw( draw ) )
    {
        dc.DrawLine( draw.x1, draw.y1, draw.x2, draw.y2 );
    }
}

Currently, the getDraw code is designed for wxWidgets v3.0.0 on Windows. It should be a small matter to provide for any differences needed by your favourite framework and platform - let me know the details!

Acknowledgements

This tip would not be possible without the code originally released by Hasan Gurler. In particular, his DXF parser code saved me several days work in understanding the details of the DXF format and I relied heavily on his spline display code.

History

  • 2014-06-14 Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)