[PYTHON] DXF und Schildkröte

Zusammenfassung dieses Artikels

Ich habe die DXF-Datei grob mit Python gelesen und den Inhalt angezeigt. Ich habe es in einer Windows10 32-Bit-Anaconda-Umgebung versucht, aber ich denke, dass es in fast derselben Umgebung durchgeführt werden kann, wenn Python funktioniert.

Was ist DXF?

Es ist eine Abkürzung für ** D ** ata e ** X ** change ** F ** oder mat (ich dachte ... aber es könnte anders gewesen sein) (http: // qiita. com / kazhida / items / 8a5fa68e8fa135614d5d)). Es ist ein Name wie ein Rivale oder Verwandter von JSON oder XML, aber es ist nicht so, es ist wie ein mittleres / gemeinsames Format für den Austausch von ** Zeichnungsdaten ** zwischen verschiedenen CADs. Das Internet existiert seit der Zeit, als es nicht fragil war, und obwohl jedes Unternehmen seine eigenen Interpretationen und Erweiterungen hat, haben sich die Standards selbst geändert und erweitert, was es schwierig macht, damit auszukommen. Oft können die von anderen CAD-Daten ausgespuckten DXF-Daten nicht gelesen werden, und wenn ich die DXF-Lese- / Schreibeinstellungen in der CAD-Software öffne, sind sie ** ziemlich groß und ich möchte sie nicht zu sehr sehen **. Es reicht aus, 2D-Daten von geraden Linien, Kreisen und Bögen für das zu verarbeiten, was ich normalerweise verwende (3D-Daten werden häufig mit SAT, IGES, STEP usw. ausgetauscht), aber DXF-Standards sind freie Kurven und frei Es scheint, dass es erweitert wurde, um gekrümmte Oberflächen, Maschen, Feststoffe usw. zu handhaben.

Also, was ist es?

Es gibt eine Anwendung, die ich persönlich erstellen möchte, und wenn es eine kleine Zeichen- / Zeichenfunktion gibt, die nicht unbedingt erforderlich ist, wird die Anwendung wahrscheinlich erweitert. Die Implementierung einer solchen Zeichenfunktion ist jedoch zu schwierig. Wie wäre es dann mit dem Importieren einer mit einer anderen CAD-Software erstellten Figur? Als ich es nachgeschlagen habe, hat Python ein Modul namens ** dxfgrabber **. Warum also nicht mal ausprobieren? … Das ist dieser Artikel (zu lange Einführung). Es gibt eine andere Software namens pycam, die dxf lesen und schreiben kann, also habe ich mir die Quelle angesehen, aber es fühlte sich nicht so an, als könnte ich sehen, wo und was ich tat, also wurde die Pycam-Hack-Route unbeaufsichtigt gelassen.

dxfgrabber Wenn Sie mit dem Schlüsselwort DXF mit pypi suchen, wird es oben angezeigt. Es scheint nichts mit Kompilierung oder Binärdateien zu tun zu haben, und die Installation mit pip in der Anaconda-Umgebung scheint keine Probleme zu haben.

pip install dxfgrabber

Einfach zu verwenden

Datei lesen

>>> import dxfgrabber
>>> dxf=dxfgrabber.readfile("hogehoge.dxf")

Anzeige verschiedener Header

Durch das obige Lesen werden verschiedene Überschriften im Wörterbuch gespeichert. Ich spüre die Dunkelheit von DXF, wenn es nur wenige Elemente gibt oder die Elemente fest herauskommen, abhängig von der CAD-Software, die DXF ausspuckt.

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

Ich kenne die Bedeutung verschiedener Header nicht und möchte nicht viel verstehen, aber es scheint, dass die Schlüssel "\ $ EXTMIN" und "$ EXTMAX" die minimalen und maximalen Koordinaten der gezeichneten Daten enthalten.

Beispiel zum Extrahieren von geraden Linien, Kreisen und Bögen

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']

Laut der Dokumentation handelt es sich bei der Eigenschaft entity um "list like collection", was sich ein wenig von der Liste zu unterscheiden scheint, aber die Details sind unbekannt. Wenn Sie dies oben tun, können Sie die Werte wie all_lines [0], all_lines [1], .... abrufen. Darüber hinaus können detailliertere grafische Informationen wie folgt abgerufen werden.

all_lines[i].start[0] # (i+1)Starten Sie die X-Koordinate der zweiten Geraden
all_lines[i].start[1] # (i+1)Beginnen Sie die Y-Koordinate der zweiten Geraden
all_lines[i].end[0]   # (i+1)Ende der X-Koordinate der zweiten Geraden
all_lines[i].end[1]   # (i+1)Ende der Y-Koordinate der zweiten Geraden

all_arcs[i].start_angle # (i+1)Startwinkel des zweiten Bogens[deg]
all_arcs[i].end_angle   # (i+1)Endwinkel des zweiten Bogens[deg]
all_arcs[i].radius      # (i+1)Radius des zweiten Bogens
all_arcs[i].center[0]   # (i+1)X-Koordinate des zweiten Bogens zentrieren
all_arcs[i].center[1]   # (i+1)Zentrierte Y-Koordinate des zweiten Bogens

all_cirs[i].radius    # (i+1)Radius des zweiten Kreises
all_cirs[i].center[0] # (i+1)X-Koordinate des zweiten Kreises zentrieren
all_cirs[i].center[1] # (i+1)Zentrieren Sie die Y-Koordinate des zweiten Kreises

Es scheint, dass ich die Grafikinformationen mit dxfgrabber abrufen konnte ... Lassen Sie uns sie zeichnen und überprüfen.

Versuchen Sie zu zeichnen, um zu bestätigen, dass dxf mit dxf grabber korrekt gelesen wird. Ich frage mich, ob ich Drawline () oder DrawArc () in einer ordentlichen Bibliothek oder einem GUI-Framework wie OpenCV verwenden soll, aber aus einem kleinen Grund und einer kleinen Idee habe ich mich für das ** Turtle-Modul ** von Python entschieden. Ich habe mich entschieden, es zu benutzen. Das Dokument war überraschend groß und ich dachte: "Das? Es ist ärgerlicher als ich erwartet hatte?", Aber schließlich war es einfach zu bedienen. Die Bewegung des Kreises und des Bogens war etwas schwer zu verstehen,

turtle.circle(r,extent=deg)

Die Bewegung zu diesem Zeitpunkt ist wie in der folgenden Abbildung gezeigt. Wenn deg <0 ist, zeichnen Sie beim Zurückziehen einen Bogen.

turtle_dir.png

Code zum Lesen der DXF-Datei und zum Zeichnen mit der Schildkröte

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 oben von der Kommandozeile

 python dxf_turtle.py hogehoge.dxf

Wenn Sie ausführen, werden Farbe, Maßstab, Linientyp usw. ignoriert, es wird jedoch dieselbe Figur wie in der Originalfigur gezeichnet. Ich werde das Ergebnis der Figur, die ich gezeichnet habe, als Versuch veröffentlichen, aber es ist nüchtern. Wenn man nur die Ergebnisse betrachtet, ist es nüchtern, aber es macht überraschend Spaß zu sehen, wie es sich bewegt und zeichnet. In Bezug auf den Code scheint es aufgrund der eingestellten Startposition und Ausrichtung der Schildkröte und des zusätzlichen Codes wie penup () / pendown () länger zu dauern, als mit openCV usw. schnell zu zeichnen, aber es macht überraschend Spaß, sich zu bewegen. Also ist es okay (es ist wichtig, also mach es nicht zweimal).

hw-k.png

wheelhub.png

Fehler?

Als ich versuchte, verschiedene DXF-Daten mit Turtle zu zeichnen, waren einige Bögen seltsam. Aus irgendeinem Grund ist die Position symmetrisch zur Y-Achse umgekehrt. Es scheint, dass das Positive und das Negative des Immobilienzentrums [0] umgekehrt und gelesen werden. Ist es ein Fehler von dxfgrabber, weil es ein Phänomen ist, das nicht auftritt, selbst wenn es von mehreren CAD gelesen wird? Ich denke. Trotzdem bewundere ich dxfgrabber und seine Autoren. Vielen Dank, dass Sie Dinge, die nervig erscheinen, einfach gemacht haben.

Nebenbei: Geheimnisvolles Schildkrötenschieben

Ich habe das Gefühl, dass es in der Nähe von Computern und Robotern eine mysteriöse Vermutung über Schildkröten gibt, wie das hier verwendete Schildkrötenmodul und das ROS-Schildkrötenbottich, aber der Ursprung ist die LOGO-Sprache, die die Grundlage des Python-Schildkrötenmoduls bildet. Ist es?

Ich fand auch diesen beachbot ([eine der auf Japanisch abgedeckten Websites](http://makezine.jp/blog/2015/10/disney-turtle- robot-draws.html)). Soweit ich aus der Erklärung der Website ersehen kann, kann es vorkommen, dass die Schildkröte unabhängig von ROS oder LOGO als Meerestier adoptiert wurde ...

Recommended Posts

DXF und Schildkröte
Kaninchen- und Schildkrötenalgorithmus
Schildkrötengrafik
Über _ und __