Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / MFC
Article

CadLib for creating DXF(Drawing Interchange Format) files

Rate me:
Please Sign up or sign in to vote.
4.90/5 (117 votes)
25 Aug 2004CPOL4 min read 779.2K   34.4K   229   217
A link-library and its interface class to create, load and modify DXF files.

Image 1

Introduction

What is DXF?

Drawing Interchange Format (DXF) files enable the interchange of drawings between AutoCAD and other programs. DXF files can be either ASCII or binary formats. Because ASCII DXF files are more common than the binary format, CadLib uses ASCII DXF format.

What is CadLib?

The CadLib is not a Computer Aided Design (CAD) program. It is a tool for creating DXF files that are used in the CAD programs. It consists of two parts. One of them is a Dynamic Link Library to create the DXF file. The other part is the programming interface. It is a class that integrates the cadio.dll functions. It can be used in Microsoft Visual C++ projects. In addition, the cadio.dll can be used in other Win32 programs.

Why use CadLib?

In some programs, it is needed to create a drawing output for use in other programs such as AutoCad. For example, in a "Building Detail Sheet Generator Program", the program needs to create a drawing output. And the most standard format for communicating drawing data is DXF.

Image 2

DXF file structure

The DXF format is a tagged data representation of all the information contained in a drawing file. Tagged data means that each data element in the file is preceded by an integer number that is called a group code. A group code's value indicates what type of data element follows. This value also indicates the meaning of a data element for a given object (or record) type. Virtually all user-specified information in a drawing file can be represented in DXF format. (from AutoCad's DXF reference)

A DXF file consists of some sections. Each section has some drawing data in itself. The CadLib uses the following sections:

  1. HEADER
  2. TABLES
  3. BLOCKS
  4. ENTITIES

The main reference for DXF file structure that is used for CadLib is the AutoCad's DXF reference. You can find more information about DXF file structure here.

Classes

The classes are interfaces between CadIO.dll and the main program. "Test" has come with CadLib to demonstrate how to generate a DXF file with CDxfFileWrite and CDrawing classes.

CDxfFileWrite class

CDxfFileWrite gathers all the commands needed to directly create a DXF file. Usage of CDxfFileWrite is as follows:

  1. Create the DXF file
    CDxfFileWrite dxffile;
    dxffile.Create( "d:\\test.dxf" );
  2. Begin and end the HEADER section. It's here for compatibility with some CAD programs. Others work without having HEADER section.
    // Header Section ------------------------------------------
    dxffile.BeginSection(SEC_HEADER);
    dxffile.EndSection();
    // close HEADER section ------------------------------------
  3. Begin the TABLES section and put the LAYER, LTYPE, STYLE, DIMSTYLE table-types as many as you want and then close the section
    // Tables Section ------------------------------------------
    dxffile.BeginSection(SEC_TABLES);
    
    // LTYPE table type -------------------------
    dxffile.BeginTableType(TAB_LTYPE);
    
    DXFLTYPE ltype;
    double elem[4];
    
    // Continuous
    ZeroMemory(<ype, sizeof(ltype));
    ltype.Name = "Continuous";
    ltype.DescriptiveText = "Solid line";
    dxffile.AddLinetype(<ype);
    
    // DASHDOT2
    ZeroMemory(<ype, sizeof(ltype));
    ltype.Name = "DASHDOT2";
    ltype.DescriptiveText = "Dash dot (.5x) _._._._._._._._._._._._._._._.";
    ltype.ElementsNumber = 4;
    ltype.TotalPatternLength = 0.5;
    ltype.Elements = elem;
    elem[0] = 0.25;
    elem[1] = -0.125;
    elem[2] = 0.0;
    elem[3] = -0.125;
    dxffile.AddLinetype(<ype);
    
    dxffile.EndTableType();
    // close LTYPE table type -------------------
    
    // LAYER table type -------------------------
    result &= dxffile.BeginTableType(TAB_LAYER);
    result &= dxffile.AddLayer("Layer1", 1, "Continuous");
    result &= dxffile.AddLayer("Layer2", 2, "Continuous");
    result &= dxffile.AddLayer("Layer3", 3, "Continuous");
    result &= dxffile.AddLayer("Layer4", 4, "Continuous");
    result &= dxffile.EndTableType();
    // close LAYER table type -------------------
    
    // STYLE table type -------------------------
    dxffile.BeginTableType(TAB_STYLE);
    
    DXFSTYLE tstyle;
    ZeroMemory(&tstyle, sizeof(tstyle));
    tstyle.Name = "Style1";
    tstyle.PrimaryFontFilename = "TIMES.TTF";
    tstyle.Height = 0.3;
    tstyle.WidthFactor = 1;
    dxffile.AddTextStyle(&tstyle);
    
    dxffile.EndTableType();
    // close STYLE table type -------------------
    
    // DIMSTYLE table type ----------------------
    dxffile.BeginTableType(TAB_DIMSTYLE);
    
    DXFDIMSTYLE dimstyle;
    
    // DIM1
    ZeroMemory(&dimstyle, sizeof(dimstyle));
    dimstyle.Name = "DIM1"; // DimStyle Name
    dimstyle.DIMCLRD = 2; // Dimension line & Arrow heads color
    dimstyle.DIMDLE = 0.0000; // Dimension line size after Extensionline
    dimstyle.DIMCLRE = 2; // Extension line color
    dimstyle.DIMEXE = 0.1800; // Extension line size after Dimline
    dimstyle.DIMEXO = 0.0625; // Offset from origin
    dimstyle.DIMBLK1 = "ClosedFilled";// 1st Arrow head
    dimstyle.DIMBLK2 = "ClosedFilled";// 2nd Arrow head
    dimstyle.DIMASZ = 0.1800; // Arrow size
    dimstyle.DIMTXSTY = "Style1"; // Text style
    dimstyle.DIMCLRT = 3; // Text color
    dimstyle.DIMTXT = 0.1800; // Text height
    dimstyle.DIMTAD = 1; // Vertical Text Placement
    dimstyle.DIMGAP = 0.0900; // Offset from dimension line
    dxffile.AddDimStyle(&dimstyle);
    
    dxffile.EndTableType();
    // close DIMSTYLE table type ----------------
    
    dxffile.EndSection();
    // close TABLES section ------------------------------------
  4. Begin ENTITIES section and put entities data (LINE, CIRCLE, SOLID, TEXT, ARC, POINT, DIMLINEAR) and finally close the section
    // Entities Section ------------------------------------------
    dxffile.BeginSection(SEC_ENTITIES);
    
    // set current layer to Layer2
    dxffile.SetCurrentLayer("Layer2");
    // draw a line
    dxffile.Line(1.2, 3.3, 7.5, 7.7);
    // draw a circle
    dxffile.Circle(7.8, 4.3, 1.75);
    // set current layer to Layer4
    dxffile.SetCurrentLayer("Layer4");
    
    // draw a solid
    REALPOINT points[4];
    points[0].x = 10.4; points[0].y = 7.2;
    points[1].x = 13.6; points[1].y = 7.4;
    points[2].x = 13.1; points[2].y = 4.9;
    points[3].x = 10.9; points[3].y = 5.9;
    Solid(4, points);
    
    // set current textstyle to Style1
    dxffile.SetCurrentTextStyle("Style1");
    // draw text
    dxffile.Text("Sample Text", 5.9, 6.7, 0.3, 35);
    // draw a dimension line
    dxffile.SetCurrentDimStyle("DIM1");
    dxffile.DimLinear(6.05, 3, 9.55, 3, 9.55, 2, 0, "3.50");
    
    dxffile.EndSection();
    // close ENTITIES section ----------------------------------
  5. Close the DXF file
    dxffile.Close();

CDrawing class

CDrawing class has all the commands to create a drawing in memory and save it as a DXF file. Usage of CDrawing is as follows:

  1. Create the on-memory drawing
    CDrawing drw;
    drw.Create( );
  2. Create new LAYER, LTYPE, STYLE, DIMSTYLE table-types as many as you want.
    // Tables Section ------------------------------------------
    // LTYPE table type -------------------------
    LTYPE ltype;
    OBJHANDLE objhandle1;
    
    // Continuous
    ZeroMemory(<ype, sizeof(ltype));
    strcpy(ltype.Name, "Continuous");
    strcpy(ltype.DescriptiveText, "Solid line");
    objhandle1 = drw.AddLinetype(<ype);
    
    // DASHDOT2
    ZeroMemory(<ype, sizeof(ltype));
    strcpy(ltype.Name, "DASHDOT2");
    strcpy(ltype.DescriptiveText, 
      "Dash dot (.5x) _._._._._._._._._._._._._._._.");
    ltype.ElementsNumber = 4;
    ltype.PatternLength = 0.5;
    ltype.Elements[0] = 0.25;
    ltype.Elements[1] = -0.125;
    ltype.Elements[2] = 0.0;
    ltype.Elements[3] = -0.125;
    drw.AddLinetype(<ype);
    
    // LAYER table type -------------------------
    LAYER layer;
    
    // Layer1
    ZeroMemory(&layer, sizeof(layer));
    strcpy(layer.Name, "Layer1");
    layer.Color = 1;
    layer.LineTypeObjhandle = objhandle1; // Continuous
    drw.AddLayer(&layer);
    
    // Layer2
    ZeroMemory(&layer, sizeof(layer));
    strcpy(layer.Name, "Layer2");
    layer.Color = 2;
    layer.LineTypeObjhandle = objhandle1; // Continuous
    drw.AddLayer(&layer);
    
    // STYLE table type -------------------------
    STYLE style;
    
    ZeroMemory(&style, sizeof(style));
    strcpy(style.Name, "Style1");
    strcpy(style.PrimaryFontFilename, "TIMES.TTF");
    style.LastHeightUsed = 0.3;
    style.WidthFactor = 1;
    objhandle1 = drw.AddTextStyle(&style);
    
    // DIMSTYLE table type ----------------------
        DIMSTYLE dimstyle;
    
    // DIM1
    ZeroMemory(&dimstyle, sizeof(dimstyle));
    strcpy(dimstyle.Name, "DIM1"); // DimStyle Name
    dimstyle.dimclrd = 2; // Dimension line & Arrow heads color
    dimstyle.dimdle = 0.0000; // Dimension line size after Extensionline
    dimstyle.dimclre = 2; // Extension line color
    dimstyle.dimexe = 0.1800; // Extension line size after Dimline
    dimstyle.dimexo = 0.0625; // Offset from origin
    strcpy(dimstyle.dimblk1, "ClosedFilled");// 1st Arrow head
    strcpy(dimstyle.dimblk2, "ClosedFilled");// 2nd Arrow head
    dimstyle.dimasz = 0.1800; // Arrow size
    dimstyle.dimtxstyObjhandle = objhandle1;// Text style
    dimstyle.dimclrt = 3; // Text color
    dimstyle.dimtxt = 0.1800; // Text height
    dimstyle.dimtad = 1; // Vertical Text Placement
    dimstyle.dimgap = 0.0900; // Offset from dimension line
    drw.AddDimStyle(&dimstyle);
  3. Make entities data (LINE, CIRCLE, SOLID, TEXT, ARC, POINT, DIMLINEAR, POLYLINE).
    // Entities Section ------------------------------------------
    // set current layer to Layer2
    drw.SetLayer("Layer2");
    // draw a line
    drw.Line(1.2, 3.3, 7.5, 7.7);
    // draw a circle
    drw.Circle(7.8, 4.3, 1.75);
    // set current layer to Layer1
    drw.SetLayer("Layer1");
    
    // draw a solid
    REALPOINT points[4];
    points[0].x = 10.4; points[0].y = 7.2;
    points[1].x = 13.6; points[1].y = 7.4;
    points[2].x = 13.1; points[2].y = 4.9;
    points[3].x = 10.9; points[3].y = 5.9;
    drw.Solid(points[0], points[1], points[2], points[3]);
    
    // set current textstyle to Style1
    drw.SetTextStyle("Style1");
    // draw text
    drw.Text("Sample Text", 5.9, 6.7, 0.3, 35);
    // draw a dimension line
    drw.SetDimStyle("DIM1");
    drw.DimLinear(6.05, 3, 9.55, 3, 9.55, 2, 0, "3.50");
  4. Save data to a DXF file.
    drw.SaveDXFFile(DxfFileName);
  5. Destroy CDrawing and free allocated memory.
    drw.Destroy();

Loading data from a DXF file

  1. Create the on-memory drawing.
    CDrawing drw;
    drw.Create( );
  2. Use LoadDXFFile member function to load DXF file into memory.
    drw.LoadDXFFile("Sample.dxf");

That's all!

Conclusion

Since I am a Civil Engineer, I decided to write a program to generate a beam or columns detail sheet without the use of AutoCAD. I have written a program that, with a little data about beam or column, will create the detail sheet automatically. Output of this program is a DXF file and it can be shown in AutoCAD or it can be plotted with it. This program can save the time for drawing the detail sheet with AutoCAD. If you are an AutoCAD operator, you will understand the meaning of words that are used in this article, or if you are a programmer who wants to write a program to create DXF files, first you need a little knowledge about AutoCAD or the drawing programs such as is mentioned above. This code can be useful for programmers who need to create DXF files from their programs. CadLib is not the best one and also there are many commercial software for creating DXF files but they are not open source. Feel free to change the code. Your comments in regards to this article will cause the improvement of CadLib.

History

  • 20 Dec 2002
    • First release of CadLib
  • 19 Jan 2003
    • Some bug fixes
    • Added Dimension-Line support. It's a combination of other entity commands like "Line" and "Solid"
    • Added BLOCKS section support
    • Added Arc, Point and InsertBlock commands for ENTITIES section
    • Text command has been improved
  • 11 May 2003
    • Added CDrawing class to store drawing data in memory and change the data before saving it as a DXF file.
  • 28 June 2003
    • Added DXF read capability to CDrawing class
    • Some bug fixes of CDrawing class when writing data to a DXF file
  • 22 Nov 2003 (CadLib Version 2.00)
    • Added Drawing View capability
    • Added PolyLine command (by Tran duy Dung)
    • Improved DXF loading speed
    • Some bug fixes of drawing memory management functions
  • 24 Aug 2004 (CadLib Version 2.10)
    • Added ZoomExtents Function
    • Improved Viewing functions to show Dashed Lines
    • Added "ChangeEntity" & "DeleteEntity" commands
    • Added Dimension view capability
    • Fixed a bug occures when viewing a rotated block
    • Improved viewing of texts

License

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


Written By
Engineer ODCC
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerRe: How to read the dxf file in mfc application? Pin
Tapas Mondal29-Sep-04 17:54
Tapas Mondal29-Sep-04 17:54 
GeneralRe: How to read the dxf file in mfc application? Pin
andrewtruckle30-Sep-04 20:37
andrewtruckle30-Sep-04 20:37 
GeneralRe: How to read the dxf file in mfc application? Pin
pafa00721-Feb-05 13:33
pafa00721-Feb-05 13:33 
GeneralRe: How to read the dxf file in mfc application? Pin
andrewtruckle21-Feb-05 20:37
andrewtruckle21-Feb-05 20:37 
GeneralVC++.Net version Pin
AnsGe2-Sep-04 20:43
AnsGe2-Sep-04 20:43 
GeneralRe: VC++.Net version Pin
Radim Tylecek17-Sep-04 1:58
Radim Tylecek17-Sep-04 1:58 
GeneralRe: VC++.Net version Pin
Reanalyse15-Jun-05 13:02
Reanalyse15-Jun-05 13:02 
GeneralRe: VC++.Net version Pin
Radim Tylecek21-Jun-05 2:56
Radim Tylecek21-Jun-05 2:56 
I use following way to call DXFLib from managed code:

1) I added routines I need to C++ library (DXFLib.cpp):

static CDrawing* drawing = NULL;

BOOL __stdcall dxfLoadFile(wchar_t* strFile) {
  if(!strFile) return FALSE;
  if(drawing) {
    drawing->Destroy();
    delete drawing;
  }
  drawing = new CDrawing;

	// Create Drawing
	if(!drawing->Create()) return FALSE;
	
	// Load data from dxf file
	if(!drawing->LoadDXFFile(strFile)) return FALSE;

  return TRUE;
}

double bzl;

BOOL __stdcall dxfInitView(long w, long h) {
  if(!drawing) return false;
  drawing->InitView(0, 0, w, h);
	drawing->ZoomExtents();
  bzl = drawing->GetZoomLevel();
  return true;
}

bool dxfDrawView(HDC dc, long dx, long dy, double z) {

  VIEW view;
  drawing->SetZoomLevel(bzl*z);
  drawing->GetViewProperties(&view);
  double pix = (1/(view.PPU*view.ZoomLevel));
  view.ViewLeft -= dx * pix;
  view.ViewBottom += dy * pix;

  drawing->SetViewProperties(&view);
  drawing->Paint(dc);

  return true;
}

void dxfClose() {
  if(drawing) drawing->Destroy();
  drawing = NULL;
}


2) Also it is necessary to add them to exports of the dll (end of DXFLib.def file):

LIBRARY   DXFLib

EXPORTS
        ...
	
	dxfLoadFile
	dxfInitView
	dxfDrawView
	dxfClose


3) Declare exports in managed code (VB.NET):

Private Declare Unicode Function dxfLoadFile Lib "DXFLib.dll" Alias "dxfLoadFile" (ByVal strFileName As String) As Boolean
Private Declare Unicode Function dxfInitView Lib "DXFLib.dll" Alias "dxfInitView" (ByVal w As Integer, ByVal h As Integer) As Boolean
Private Declare Unicode Function dxfDrawView Lib "DXFLib.dll" Alias "dxfDrawView" (ByVal dc As System.IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal z As Double) As Boolean
Private Declare Unicode Sub dxfClose Lib "DXFLib.dll" Alias "dxfClose" ()

Public Shared Function DrawDXF(ByVal strFile As String, ByVal nWidth As Integer, ByVal nHeight As Integer) As Bitmap
  Try
    If dxfLoadFile(strFile) = False Then Return Nothing
    If dxfInitView(nWidth, nHeight) = False Then Return Nothing
    Dim bmp As New Bitmap(nWidth, nHeight, Imaging.PixelFormat.Format32bppRgb)
    Dim gfx As Graphics = Graphics.FromImage(bmp)
    If dxfDrawView(gfx.GetHdc, 0, 0, 1.0) = False Then Return Nothing
    dxfClose()
    gfx.Dispose()
    Return bmp
  Catch ex As Exception
    Return Nothing
  End Try
End Function


This is enough for viewing, you can add more functions in the same way (or use existing DXFLib functions directly).
Wrapper code is in VB.BET, but you'll be able to convert it to C# easily.

Enjoy,

Radim

Cool | :cool:
GeneralRe: VC++.Net version Pin
Radim Tylecek22-Jun-05 0:54
Radim Tylecek22-Jun-05 0:54 
Generalbmp to dxf file Pin
Tapas Mondal15-Aug-04 18:25
Tapas Mondal15-Aug-04 18:25 
GeneralRe: bmp to dxf file Pin
eXplodus15-Aug-04 22:32
eXplodus15-Aug-04 22:32 
GeneralRe: bmp to dxf file Pin
eXplodus19-Aug-04 20:28
eXplodus19-Aug-04 20:28 
GeneralRe: bmp to dxf file Pin
Philippe Lhoste10-Sep-04 7:26
Philippe Lhoste10-Sep-04 7:26 
GeneralRe: bmp to dxf file Pin
andrewtruckle30-Sep-04 20:35
andrewtruckle30-Sep-04 20:35 
GeneralRe: bmp to dxf file Pin
Svetoslav Chekanov24-Oct-04 23:24
Svetoslav Chekanov24-Oct-04 23:24 
Generallittle error Pin
eXplodus15-Aug-04 11:46
eXplodus15-Aug-04 11:46 
QuestionHow to enabled SetMapMode(MM_ISOTROPIC) in CDrawing? Pin
yacsha2-Aug-04 10:36
yacsha2-Aug-04 10:36 
GeneralNeed your help Pin
Tapas Mondal31-Jul-04 19:58
Tapas Mondal31-Jul-04 19:58 
Generalview dxf and help please Pin
freddy1ca25-Jul-04 21:19
freddy1ca25-Jul-04 21:19 
GeneralI write a c# version DxfWriter Pin
boss_qiu10-Jul-04 20:27
boss_qiu10-Jul-04 20:27 
GeneralRe: I write a c# version DxfWriter Pin
skboey12-Jul-04 6:05
skboey12-Jul-04 6:05 
GeneralRe: I write a c# version DxfWriter Pin
freddy1ca2-Aug-04 22:25
freddy1ca2-Aug-04 22:25 
GeneralRe: I write a c# version DxfWriter Pin
David Boland19-Aug-04 1:34
David Boland19-Aug-04 1:34 
GeneralRe: I write a c# version DxfWriter Pin
philipp.bracher30-Aug-04 7:02
philipp.bracher30-Aug-04 7:02 
GeneralRe: I write a c# version DxfWriter Pin
Member 6670483-Sep-04 19:33
Member 6670483-Sep-04 19:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.