I roughly read the DXF file with python and displayed the contents. I tried it in Windows10 32bit Anaconda environment, but I think that it can be done in almost the same environment if python works.
It is an abbreviation for ** D ** ata e ** X ** change ** F ** ormat (I thought it was ... but it may have been different](http: // qiita. com / kazhida / items / 8a5fa68e8fa135614d5d)). It's a name like a JSON or XML rival or relative, but it's not something like that, it's like an intermediate / common format for exchanging ** drawing data ** between different CADs. The Internet has existed since the era when it was not fragile, and while each company has its own interpretations and extensions, the standards themselves have changed and expanded, making it difficult to get along with. Often, the DXF data spit out by other CAD cannot be read, and when I open the DXF read / write settings in CAD software, it is ** quite huge and I don't want to see it too much **. It is enough to handle 2D data of straight lines, circles and arcs for what I usually use (3D data is often exchanged with SAT, IGES, STEP, etc.), but DXF standards are free curves and free It seems that it has been expanded to handle curved lines, meshes, solids, etc.
There is an application that I am trying to make personally, and if there is a small drawing / drafting function that is not essential, the application is likely to expand. However, implementing such a drawing function is too difficult. Then how about importing the figures created by other CAD software? I looked it up and found a module called ** dxfgrabber ** in python, so why not give it a try? … That's this article (too long introductory). There is also software called pycam that should be able to read and write dxf, so I took a look at the source, but it didn't feel like I could see where and what I was doing, so the pycam hack route was left unattended.
dxfgrabber If you search with the keyword DXF on pypi, it will appear at the top. It doesn't seem to have anything to do with compilation or binaries, and installing it with pip in the Anaconda environment doesn't seem to cause any problems.
pip install dxfgrabber
>>> import dxfgrabber
>>> dxf=dxfgrabber.readfile("hogehoge.dxf")
Various headers are stored in the dictionary by the above reading. I feel the darkness of DXF when there are only a few items or the items come out tightly depending on the CAD software that spit out DXF.
>>> print(dxf.header)
{'$ACADVER': 'AC1015', '$DWGCODEPAGE': 'ANSI_932', '$ACADMAINTVER': 6, '$INSBASE': (0.0, 0.0, 0.0), '$EXTMIN': (-250.0, -250.0, 0.0), '$EXTMAX': (250.0, 250.0, 0.0), '$LIMMIN': (-250.0, -250.0), '$LIMMAX': (250.0, 250.0), '$ORTHOMODE': 0, '$REGENMODE': 1, '$FILLMODE': 1, '$QTEXTMODE': 0, '$MIRRTEXT': 1, '$LTSCALE': 1.0, '$ATTMODE': 1, '$TEXTSIZE': 0.2, '$TRACEWID': 0.05, '$TEXTSTYLE': 'Standard', '$CLAYER': '0', '$CELTYPE': 'ByLayer', '$CECOLOR': 256, '$CELTSCALE': 1.0, '$DISPSILH': 0, '$DIMSCALE': 1.0, '$DIMASZ': 0.18, '$DIMEXO': 0.0625, '$DIMDLI': 0.38, '$DIMRND': 0.0, '$DIMDLE': 0.0, '$DIMEXE': 0.18, '$DIMTP': 0.0, '$DIMTM': 0.0, '$DIMTXT': 0.18, '$DIMCEN': 0.09, '$DIMTSZ': 0.0, '$DIMTOL': 0, '$DIMLIM': 0, '$DIMTIH': 1, '$DIMTOH': 1, '$DIMSE1': 0, '$DIMSE2': 0, '$DIMTAD': 0, '$DIMZIN': 0, '$DIMBLK': '', '$DIMASO': 1, '$DIMSHO': 1, '$DIMPOST': '', '$DIMAPOST': '', '$DIMALT': 0, '$DIMALTD': 2, '$DIMALTF': 25.4, '$DIMLFAC': 1.0, '$DIMTOFL': 0, '$DIMTVP': 0.0, '$DIMTIX': 0, '$DIMSOXD': 0, '$DIMSAH': 0, '$DIMBLK1': '', '$DIMBLK2': '', '$DIMSTYLE': 'Standard', '$DIMCLRD': 0, '$DIMCLRE': 0, '$DIMCLRT': 0, '$DIMTFAC': 1.0, '$DIMGAP': 0.09, '$DIMJUST': 0, '$DIMSD1': 0, '$DIMSD2': 0, '$DIMTOLJ': 1, '$DIMTZIN': 0, '$DIMALTZ': 0, '$DIMALTTZ': 0, '$DIMUPT': 0, '$DIMDEC': 4, '$DIMTDEC': 4, '$DIMALTU': 2, '$DIMALTTD': 2, '$DIMTXSTY': 'Standard', '$DIMAUNIT': 0, '$DIMADEC': 0, '$DIMALTRND': 0.0, '$DIMAZIN': 0, '$DIMDSEP': 46, '$DIMATFIT': 3, '$DIMFRAC': 0, '$DIMLDRBLK': '', '$DIMLUNIT': 2, '$DIMLWD': -2, '$DIMLWE': -2, '$DIMTMOVE': 0, '$LUNITS': 2, '$LUPREC': 4, '$SKETCHINC': 0.1, '$FILLETRAD': 0.5, '$AUNITS': 0, '$AUPREC': 0, '$MENU': '.', '$ELEVATION': 0.0, '$PELEVATION': 0.0, '$THICKNESS': 0.0, '$LIMCHECK': 0, '$CHAMFERA': 0.0, '$CHAMFERB': 0.0, '$CHAMFERC': 0.0, '$CHAMFERD': 0.0, '$SKPOLY': 0, '$TDCREATE': 2453737.5, '$TDUCREATE': 2453737.125, '$TDUPDATE': 2455188.75, '$TDUUPDATE': 2455188.375, '$TDINDWG': 1.16e-08, '$TDUSRTIMER': 1.16e-08, '$USRTIMER': 1, '$ANGBASE': 0.0, '$ANGDIR': 0, '$PDMODE': 0, '$PDSIZE': 0.0, '$PLINEWID': 0.0, '$SPLFRAME': 0, '$SPLINETYPE': 6, '$SPLINESEGS': 8, '$HANDSEED': '220', '$SURFTAB1': 6, '$SURFTAB2': 6, '$SURFTYPE': 6, '$SURFU': 6, '$SURFV': 6, '$UCSBASE': '', '$UCSNAME': '', '$UCSORG': (0.0, 0.0, 0.0), '$UCSXDIR': (1.0, 0.0, 0.0), '$UCSYDIR': (0.0, 1.0, 0.0), '$UCSORTHOREF': '', '$UCSORTHOVIEW': 0, '$UCSORGTOP': (0.0, 0.0, 0.0), '$UCSORGBOTTOM': (0.0, 0.0, 0.0), '$UCSORGLEFT': (0.0, 0.0, 0.0), '$UCSORGRIGHT': (0.0, 0.0, 0.0), '$UCSORGFRONT': (0.0, 0.0, 0.0), '$UCSORGBACK': (0.0, 0.0, 0.0), '$PUCSBASE': '', '$PUCSNAME': '', '$PUCSORG': (0.0, 0.0, 0.0), '$PUCSXDIR': (1.0, 0.0, 0.0), '$PUCSYDIR': (0.0, 1.0, 0.0), '$PUCSORTHOREF': '', '$PUCSORTHOVIEW': 0, '$PUCSORGTOP': (0.0, 0.0, 0.0), '$PUCSORGBOTTOM': (0.0, 0.0, 0.0), '$PUCSORGLEFT': (0.0, 0.0, 0.0), '$PUCSORGRIGHT': (0.0, 0.0, 0.0), '$PUCSORGFRONT': (0.0, 0.0, 0.0), '$PUCSORGBACK': (0.0, 0.0, 0.0), '$USERI1': 0, '$USERI2': 0, '$USERI3': 0, '$USERI4': 0, '$USERI5': 0, '$USERR1': 0.0, '$USERR2': 0.0, '$USERR3': 0.0, '$USERR4': 0.0, '$USERR5': 0.0, '$WORLDVIEW': 1, '$SHADEDGE': 3, '$SHADEDIF': 70, '$TILEMODE': 1, '$MAXACTVP': 64, '$PINSBASE': (0.0, 0.0, 0.0), '$PLIMCHECK': 0, '$PEXTMIN': (1e+20, 1e+20, 1e+20), '$PEXTMAX': (-1e+20, -1e+20, -1e+20), '$PLIMMIN': (0.0, 0.0), '$PLIMMAX': (12.0, 9.0), '$UNITMODE': 0, '$VISRETAIN': 1, '$PLINEGEN': 0, '$PSLTSCALE': 1, '$TREEDEPTH': 3020, '$CMLSTYLE': 'Standard', '$CMLJUST': 0, '$CMLSCALE': 1.0, '$PROXYGRAPHICS': 1, '$MEASUREMENT': 1, '$CELWEIGHT': -1, '$ENDCAPS': 0, '$JOINSTYLE': 0, '$LWDISPLAY': 0, '$INSUNITS': 4, '$HYPERLINKBASE': '', '$STYLESHEET': '', '$XEDIT': 1, '$CEPSNTYPE': 0, '$PSTYLEMODE': 1, '$FINGERPRINTGUID': '{3D9DC12F-B372-4948-9689-D346C0BFA940}', '$VERSIONGUID': '{FAEB1C32-E019-11D5-929B-00C0DF256EC4}', '$EXTNAMES': 1, '$PSVPSCALE': 0.0, '$OLESTARTUP': 0}
>>> dxf.header["$EXTMIN"]
(-250.0, -250.0, 0.0)
>>> dxf.header["$EXTMAX"]
(250.0, 250.0, 0.0)
I don't understand the meaning of various headers and I don't want to understand much, but it seems that the "\ $ EXTMIN" and "$ EXTMAX" keys contain the minimum and maximum coordinates of the drawn data.
all_lines = [entity for entity in dxf.entities if entity.dxftype == 'LINE']
all_cirs = [entity for entity in dxf.entities if entity.dxftype == 'CIRCLE']
all_arcs = [entity for entity in dxf.entities if entity.dxftype == 'ARC']
According to the documentation, the entities property is "list like collection", which seems to be a little different from the list, but the details are unknown. If you do the above, you can retrieve the values like all_lines [0], all_lines [1], .... Further, more detailed graphic information can be extracted as follows.
all_lines[i].start[0] # (i+1)Start X coordinate of the second straight line
all_lines[i].start[1] # (i+1)Start Y coordinate of the second straight line
all_lines[i].end[0] # (i+1)End X coordinate of the second straight line
all_lines[i].end[1] # (i+1)End Y coordinate of the second straight line
all_arcs[i].start_angle # (i+1)Start angle of the second arc[deg]
all_arcs[i].end_angle # (i+1)End angle of the second arc[deg]
all_arcs[i].radius # (i+1)Radius of the second arc
all_arcs[i].center[0] # (i+1)Center X coordinate of the second arc
all_arcs[i].center[1] # (i+1)Center Y coordinate of the second arc
all_cirs[i].radius # (i+1)Radius of the second circle
all_cirs[i].center[0] # (i+1)Center X coordinate of the second circle
all_cirs[i].center[1] # (i+1)Center Y coordinate of the second circle
Try drawing to confirm that dxf is read correctly with dxfgrabber. I wonder if I should use Drawline () or DrawArc () with a nice library or GUI framework such as OpenCV, but for a little reason and idea, I decided to use python's ** turtle module **. I decided to use it. The document was surprisingly large, and I thought, "That? It's more annoying than I expected?", But it was easy to use. The movement of the circle and arc was a little difficult to understand,
turtle.circle(r,extent=deg)
The movement at that time is as shown in the figure below. When deg <0, draw an arc while retreating.
dxf_turtle.py
# -*- coding: utf-8 -*-
import sys
import dxfgrabber as dg
import turtle as tut
from numpy import pi,cos,sin,arctan2,sqrt
fname=sys.argv[1]
dxf=dg.readfile(fname)
print(dxf.header)
def tut_dxfline(l):
x0=l.start[0]
y0=l.start[1]
x1=l.end[0]
y1=l.end[1]
deg = arctan2(y1-y0,x1-x0) / pi*180
dist = sqrt((x1-x0)**2+(y1-y0)**2)
tut.penup()
tut.setpos(x0,y0)
tut.setheading(deg)
tut.pendown()
tut.forward(dist)
def tut_dxfarc(a):
deg0=a.start_angle
deg1=a.end_angle
r=a.radius
x0=a.center[0]
y0=a.center[1]
if deg0 > deg1:
deg0 = deg0-360
tut.penup()
tut.setpos(x0+r*cos(deg0/180.*pi),y0+r*sin(deg0/180.*pi))
tut.setheading(deg0+90)
tut.pendown()
tut.circle(r,extent=(deg1-deg0))
def tut_dxfcir(c):
r=c.radius
x0=c.center[0]
y0=c.center[1]
tut.penup()
tut.setpos(x0+r,y0)
tut.setheading(90)
tut.pendown()
tut.circle(r)
#tut.speed("fastest")
tut.speed("fast")
for entity in dxf.entities:
if entity.dxftype == 'LINE':
tut_dxfline(entity)
elif entity.dxftype == 'CIRCLE':
tut_dxfcir(entity)
elif entity.dxftype == 'ARC':
tut_dxfarc(entity)
else:
print(entity.dxftype)
print("Draw End")
tut.mainloop()
Code above from the command line
python dxf_turtle.py hogehoge.dxf
If you execute, the color, scale, line type, etc. are ignored, but the same figure as the original figure is drawn. I will post the result of the figure I drew as a trial, but it is sober. Looking only at the results, it's sober, but it's surprisingly fun to see how it moves and draws. Regarding the code, it seems that it is longer than drawing quickly with openCV etc. due to the set of the start position and orientation of the turtle and the extra code such as penup () / pendown (), but it is surprisingly fun to move. So it's okay (it's important, so don't do it twice).
When I tried to draw various DXF data with turtle, some arcs were strange. For some reason, the position is reversed symmetrically with the Y axis. It seems that the positive and negative of the property center [0] are reversed and read. Is it a bug of dxfgrabber because it is a phenomenon that does not occur even if it is read by multiple CAD? I think. That said, I admire dxfgrabber and its authors. Thank you for making things that seem annoying easy.
I feel that there is a mysterious turtle guess in the neighborhood of computers and robots, such as the turtle module used here and the ROS turtlebot, but the origin is the LOGO language that is the basis of the python turtle module. Is it?
I also found this beachbot ([One of the sites covered in Japanese](http://makezine.jp/blog/2015/10/disney-turtle- robot-draws.html)). As far as I can see from the explanation of the site, it may happen that the turtle was adopted as a seaside creature regardless of ROS or LOGO ...