Introduction
This project
mainly deals with
reading a dxf file, but in order to
demonstrate the reader is working I also
included a viewer,
which interpretes the data and draw it on the
screen. In fact, at the beginning my sole
purpose was to extract data from a
DXF file but
later on interpretation and
drawing of
the data on the screen started to take lot much
more time and shaded the priority of the data
extraction. After all of these here is the
result.
Background
There are a
couple of DXF writer
projects here in UCanCode (one is from
Omid Shahabi, the other is from
Claude Gagnon), but I couldn't find a DXF
reader which
reads DXF files. After a various
scans through the net I came across the
DXF
specification of the
AutoCad and
I decided to make my own
reader. But then I found out that
a reader by
itself will have no value, there should also be
a viewer. And the project become partially a
DXF reader and mainly a viewer
program, and I also made a drawing editor.
However, the only interaction that the editor
presents to the user is to highlight the shapes
(to highlight keep shift button pressed while
moving the cursor)...all drawing are made by the
software. (I'll try to provide details later
on.)
General
Structure
_________
________________________________ ________ _______
/ DXF FILE/-->/ / DXF READER/ + /
INTERPRETATION/ ---> / VIEWER/ ---> /SCREEN/
--------- ------------------------------------- ---------
--------
Well, as you
can see the structure is as above. The data is
extracted from the DXF
file and interpreted and then
necessary methods of the viewer is called and
the result is shown on the screen.
Although the
intended structure is as above, the code itself
is not separated this much.
The
application is a MDI application. You can open
multiple DXF files
for viewing.
There is a
Canvas class for drawing and a Shape class for
defining objects. Currently Line, Polyline,
Circle and Arc shapes of the Autocad can be
recognized. In near future I'm planning to add
B-Spline, too.
DXF
Interpretation methods are included to the
canvas class. Separating these methods from the
drawing methods would be much better but for now
this is all I can present.
Methods
When you click
File/Open the following method will be called:
Collapse |
Copy
Code
private void menuItem2_Click(object sender,
System.EventArgs e)
{
inputFileTxt = "";
openFileDialog1.InitialDirectory = "c:\\" ;
//sets the initial directory of the openfile dialog
openFileDialog1.Filter = "dxf files (*.dxf)|*.dxf|All" +
" files (*.*)|*.*" ; //filters the visible files...
openFileDialog1.FilterIndex = 1 ;
if (openFileDialog1.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
//open file dialog is shown here...
//if "cancel" button is clicked then
//nothing will be done...
{
inputFileTxt = openFileDialog1.FileName;
//filename is taken (file path is also
//included to this name example:
// c:\windows\system\blabla.dxf
int ino = inputFileTxt.LastIndexOf("\\");
//index no. of the last "\" (that is before
// the filename) is found here
newCanvas = new Canvas(); //a new canvas is created...
newCanvas.MdiParent = this; //...its mdiparent is set...
newCanvas.Text = inputFileTxt.Substring(ino+1,
inputFileTxt.Length - ino - 1);
//...filename is extracted from the text.(blabla.dxf).
newCanvas.MinimumSize = new Size (500, 400);
//...canvas minimum size is set...
if(inputFileTxt.Length > 0)
{
newCanvas.ReadFromFile(inputFileTxt);
//the filename is sent to the method
// for data extraction and interpretation...
}
newCanvas.Show(); //the canvas is displayed...
newCanvas.Activate();
newCanvas.Focus();
}
openFileDialog1.Dispose();
}
As mentioned
above DXF
interpretation is made in the Canvas class.
Canvas class is a Windows Form. In addition to
the standard namespaces the following namespaces
are included:
Collapse |
Copy
Code
using System.IO;
using System.Drawing.Drawing2D;
using System.Data;
The
ReadFromFile(string
filename)
method
of the Canvas deals with extracting data from
the DXF file
and forwarding data to the necessary
drawing methods.
Collapse |
Copy Code
public void ReadFromFile (string textFile)
{
string line1, line2;
line1 = "0"; line2 = "0";
long position = 0;
theSourceFile = new FileInfo (textFile); StreamReader reader = null;
try
{
reader = theSourceFile.OpenText();
}
catch (FileNotFoundException e)
{
MessageBox.Show(e.FileName.ToString() + " cannot be found");
}
catch
{
MessageBox.Show("An error occured while opening the DXF file");
return;
}
do
{
if (line1 == "0" && line2 == "LINE")
LineModule(reader);
else if (line1 == "0" && line2 == "LWPOLYLINE")
PolylineModule(reader);
else if (line1 == "0" && line2 == "CIRCLE")
CircleModule(reader);
else if (line1 == "0" && line2 == "ARC")
ArcModule(reader);
GetLineCouple (reader, out line1, out line2);
}
while (line2 != "EOF");
reader.DiscardBufferedData(); theSourceFile = null;
reader.Close(); }
Let me explain a little
bit about the structure
of a
DXF file.
In
DXF files
(they can be opened in
Notepad) the data is
stored in two-line
(bi-line, dual,
coupling..what ever you
call it) structures. The
first line contains a
kind of an identifier
(or a Tag) and the
second line contains the
data value. So in order
to interpret a
dxf file we
must interperet lines
two-by-two.
Depending on this dual
structure we can
interpret all entities
that reside in a
DXF file.
But currently only LINE,
LWPOLYLINE, CIRCLE and
ARC entities can be
recognizable. For near
future I'm planning to
add BSPLINE.
I provided plenty of
comments in the
source code,
so please look in the
source code
itself for
explanation of the
modules.
DXF Viewer
Viewer part contains
much more coding than
the reader. As I
mentioned above
currently I can draw a
limited number of
shapes. I hope to expand
it in near future.
While I'm developing the
Viewer I got lot's of
ideas and knowledge from
the UCanCode. It
varies from double
buffering techniques to
making a
GradientBackground.
In the beginning I said
that the viewer is a MDI
application. In this way
you can open multiple
DXF files
to view. After opening a
file, if you click on
the "Window" button in
the main menu you can
see a list of the opened
windows.
To make this add a menu
item to the main menu,
and then in its
properties find MdiList
and change its value to
"true
".
I made the gradient
background with
overriding
OnPaintBackground event:
Collapse |
Copy Code
protected override void
OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaintBackground(e);
...
Graphics g = e.Graphics;
Rectangle rect = new Rectangle(this.pictureBox1.Location,
this.pictureBox1.Size);
System.Drawing.Drawing2D.LinearGradientBrush brush =
new System.Drawing.Drawing2D.LinearGradientBrush(
rect, Color.SteelBlue, Color.Black,
System.Drawing.Drawing2D.LinearGradientMode.ForwardDiagonal);
if (this.WindowState != FormWindowState.Minimized)
{
e.Graphics.FillRectangle(brush, rect);
Draw(g); }
brush.Dispose();
}
Conclusion
The main purpose of this
project is to
demonstrate that the
dxf files
can be read with the
above mentioned
techniques. In fact, the
viewer part has a
secondary priority at
the beginning. Later on
I paid some attention to
it, but I cannot claim
that the viewer is
composed of the best
practices.
The compressed file for
the demo application the
executable file and two
sample
dxf files.
One of the dxf files is
the one that can be seen
in the screenshot. The
drawing seems to be 3-D
but it is not. it is
drawn in
2D...
News:
1
UCanCode Advance E-XD++
CAD Drawing and Printing Solution
Source Code Solution for C/C++, .NET V2023 is released!
2
UCanCode Advance E-XD++
HMI & SCADA Source Code Solution for C/C++, .NET V2023 is released!
3
UCanCode
Advance E-XD++ GIS SVG Drawing and Printing Solution
Source Code Solution for C/C++, .NET V2023 is released!
Contact UCanCode Software
To buy the source code or learn more about with: