[PYTHON] DXF et tortue

Résumé de cet article

J'ai lu approximativement le fichier DXF avec python et j'en ai affiché le contenu. Je l'ai essayé dans l'environnement Anaconda Windows10 32 bits, mais je pense que cela peut être fait dans presque le même environnement si python fonctionne.

Qu'est-ce que DXF

C'est une abréviation pour ** D ** à un e ** X ** change ** F ** ou mat (je pensais ... mais cela peut avoir été différent](http: // qiita. com / kazhida / items / 8a5fa68e8fa135614d5d)). C'est un nom comme un rival ou un parent de JSON ou XML, mais ce n'est pas comme ça, c'est comme un format intermédiaire / commun pour échanger des ** données de dessin ** entre différents CAD. Internet existe depuis l'époque où il n'était pas fragile, et si chaque entreprise a ses propres interprétations et extensions, les normes elles-mêmes ont changé et se sont développées, ce qui rend difficile la compréhension. Souvent, les données DXF crachées par d'autres CAO ne peuvent pas être lues, et lorsque j'ouvre les paramètres de lecture / écriture DXF dans un logiciel CAO, elles sont ** assez énormes et je ne veux pas trop les voir **. Il suffit de gérer des données 2D de lignes droites, de cercles et d'arcs pour ce que j'utilise habituellement (les données 3D sont souvent échangées avec SAT, IGES, STEP, etc.), mais le standard DXF est une courbe libre, gratuite Il semble qu'il ait été étendu pour gérer les surfaces courbes, les maillages, les solides, etc.

Alors c'est quoi?

Il y a une application que j'essaie de créer personnellement, et s'il y a une petite fonction de dessin / dessin qui n'est pas essentielle, l'application est susceptible de s'étendre. Cependant, la mise en œuvre d'une telle fonction de dessin est trop difficile. Alors que diriez-vous d'importer une figure créée avec un autre logiciel de CAO? Quand je l'ai recherché, python a un module appelé ** dxfgrabber **, alors pourquoi ne pas l'essayer? … C'est cet article (trop longue introduction). Il existe un autre logiciel appelé pycam qui devrait être capable de lire et d'écrire dxf, j'ai donc jeté un coup d'œil à la source, mais je n'avais pas l'impression de voir où et ce que je faisais, donc la route de piratage pycam a été laissée sans surveillance.

dxfgrabber Si vous recherchez avec le mot-clé DXF avec pypi, il apparaîtra en haut. Cela ne semble rien avoir à voir avec la compilation ou les binaires, et l'installer avec pip dans l'environnement Anaconda ne semble pas avoir de problèmes.

pip install dxfgrabber

Facile à utiliser

Lecture de fichiers

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

Affichage de différents en-têtes

Divers en-têtes sont stockés dans le dictionnaire par la lecture ci-dessus. Je ressens l'obscurité du DXF lorsqu'il n'y a que quelques éléments ou que les éléments sortent étroitement en fonction du logiciel de CAO qui crache le 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)

Je ne connais pas la signification des différents en-têtes et je ne veux pas beaucoup comprendre, mais il semble que les clés "\ $ EXTMIN" et "$ EXTMAX" contiennent les coordonnées minimum et maximum des données dessinées.

Exemple d'extraction de lignes droites, de cercles et d'arcs

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

Selon la documentation, la propriété des entités est "list like collection", ce qui semble être un peu différent de la liste, mais les détails sont inconnus. Si vous faites ce qui précède, vous pouvez récupérer les valeurs telles que all_lines [0], all_lines [1], .... En outre, des informations graphiques plus détaillées peuvent être récupérées comme suit.

all_lines[i].start[0] # (i+1)Commencer la coordonnée X de la deuxième ligne droite
all_lines[i].start[1] # (i+1)Commencer la coordonnée Y de la deuxième ligne droite
all_lines[i].end[0]   # (i+1)Coordonnée X de fin de la deuxième ligne droite
all_lines[i].end[1]   # (i+1)Coordonnée Y de fin de la deuxième ligne droite

all_arcs[i].start_angle # (i+1)Angle de départ du deuxième arc[deg]
all_arcs[i].end_angle   # (i+1)Angle de fin du deuxième arc[deg]
all_arcs[i].radius      # (i+1)Rayon du deuxième arc
all_arcs[i].center[0]   # (i+1)Coordonnée X centrale du deuxième arc
all_arcs[i].center[1]   # (i+1)Coordonnée centrale Y du deuxième arc

all_cirs[i].radius    # (i+1)Rayon du deuxième cercle
all_cirs[i].center[0] # (i+1)Coordonnée X centrale du deuxième cercle
all_cirs[i].center[1] # (i+1)Coordonnée centrale Y du deuxième cercle

Il semble que j'ai pu récupérer les informations graphiques avec dxfgrabber ... Dessinons et vérifions.

Essayez de dessiner pour confirmer que dxf est lu correctement avec le grabber dxf. Je me demande si je devrais utiliser Drawline () ou DrawArc () dans une bibliothèque soignée ou un cadre GUI tel qu'OpenCV, mais pour une petite raison et une petite idée, j'ai décidé d'utiliser le ** module turtle ** de python. J'ai décidé de l'utiliser. Le document était étonnamment volumineux et je me suis dit: "C'est? C'est plus ennuyeux que ce à quoi je m'attendais?", Mais après tout, c'était facile à utiliser. Le mouvement du cercle et de l'arc était un peu difficile à comprendre,

turtle.circle(r,extent=deg)

Le mouvement à ce moment-là est comme indiqué dans la figure ci-dessous. Lorsque deg <0, dessinez un arc en reculant.

turtle_dir.png

Code pour lire le fichier DXF et dessiner avec la tortue

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 ci-dessus à partir de la ligne de commande

 python dxf_turtle.py hogehoge.dxf

Si vous exécutez, la couleur, l'échelle, le type de ligne, etc. sont ignorés, mais la même figure que la figure d'origine est dessinée. Je posterai le résultat de la figure que j'ai dessinée à titre d'essai, mais il est sobre. En regardant uniquement les résultats, c'est sobre, mais c'est étonnamment amusant de voir comment il bouge et dessine. En ce qui concerne le code, il semble que ce soit plus long que dessiner rapidement avec openCV etc. en raison de l'ensemble de la position de départ et de l'orientation de la tortue et du code supplémentaire tel que penup () / pendown (), mais c'est étonnamment amusant à déplacer. Alors ça va (c'est important, alors ne le fais pas deux fois).

hw-k.png

wheelhub.png

punaise?

Lorsque j'ai essayé de dessiner diverses données DXF avec une tortue, certains arcs étaient étranges. Pour une raison quelconque, la position est inversée symétriquement avec l'axe Y. Il semble que le positif et le négatif du centre de propriété [0] soient inversés et lus. Est-ce un bug de dxfgrabber car c'est un phénomène qui ne se produit pas même s'il est lu par plusieurs CAO? Je pense. Cela dit, j'admire dxfgrabber et ses auteurs. Merci de rendre les choses qui semblent ennuyeuses faciles.

À part: tortue mystérieuse poussant

Je pense qu'il y a une mystérieuse supposition de tortue dans le voisinage des ordinateurs et des robots, comme le module turtle utilisé ici et le turtlebot ROS, mais l'origine est le langage LOGO qui est à la base du module python turtle. C'est ça?

J'ai aussi trouvé ce beachbot ([Un des sites couverts en japonais](http://makezine.jp/blog/2015/10/disney-turtle- robot-draws.html)). D'après l'explication du site, il peut arriver que la tortue ait été adoptée comme créature balnéaire indépendamment de ROS ou LOGO ...

Recommended Posts

DXF et tortue
Algorithme de lapin et de tortue
Graphique de tortue
À propos de _ et __