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:
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:
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