`DXF` reader enhancement
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
Direzione di ricerca
Inizia esaminando gli entry point proposti DXFReader e DXFParser e i riferimenti a ezdxf nell’issue. Chiarisci quali entità DXF e rappresentazioni dell’output rientrano nell’ambito, incluse linee, mesh, vertici, facce, polilinee e punti. Done dovrebbe essere definito da una matrice di supporto concordata e dal comportamento corrispondente di reader/parser.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Feature Request
Currently, the DXF reader is not development. I had a bit of time looking at it and felt we could develop it. @tomvanmele
Details
.dxf is a fairly complex format containing many many datatypes, but general datatype like Line and Mesh support might be helpful. I found that ezdxf package is pretty lightweight and can be very helpful. shall we introduce this package?
Example code
import ezdxf
class DXF(object):
"""Class for working with DXF files.
Parameters
----------
filepath : path string | file-like object
A path, a file-like object.
precision : str, optional
A precision specification.
Attributes
----------
reader : :class:`DXFReader`, read-only
A DXF file reader.
parser : :class:`DXFParser`, read-only
A DXF data parser.
References
----------
* https://en.wikipedia.org/wiki/AutoCAD_DXF
* http://paulbourke.net/dataformats/dxf/
* http://paulbourke.net/dataformats/dxf/min3d.html
* https://ezdxf.readthedocs.io/
"""
def __init__(self, filepath, precision=None):
self.filepath = filepath
self.precision = precision
self._is_parsed = False
self._reader = None
self._parser = None
def read(self):
"""Read and parse the contents of the file."""
self._reader = DXFReader(self.filepath)
self._parser = DXFParser(self._reader, precision=self.precision)
self._reader.open()
self._reader.read()
self._parser.parse()
self._is_parsed = True
@property
def reader(self):
if not self._is_parsed:
self.read()
return self._reader
@property
def parser(self):
if not self._is_parsed:
self.read()
return self._parser
@property
def vertices(self):
return self.parser.vertices
@property
def lines(self):
return self.parser.lines
@property
def points(self):
return self.parser.points
@property
def face3ds(self):
return self.parser.face3ds
@property
def meshes(self):
return self.parser.meshes
@property
def polyline2ds (self):
return self.parser.polyline2ds
@property
def polyline3ds (self):
return self.parser.polyline3ds
class DXFReader(object):
"""Class for reading data from DXF files.
Parameters
----------
filepath : path string | file-like object
A path, a file-like object.
"""
def __init__(self, filepath):
self.filepath = filepath
self.doc = None
self.content = None
self.lines = None
self.points = None
self.face3ds = None
self.meshes = None
self.polyline2ds = []
self.polyline3ds = []
def open(self):
"""Open the file and read its contents.
Returns
-------
None
"""
try:
self.content = ezdxf.readfile(self.filepath)
except IOError:
print(f"Not a DXF file or a generic I/O error.")
except ezdxf.DXFStructureError:
print(f"Invalid or corrupted DXF file.")
def read(self):
"""Read the contents of the file."""
self.lines = self.content.modelspace().query("LINE")
self.points = self.content.modelspace().query("POINT")
# The 3DFACE entity is real 3D solid filled triangle or quadrilateral.
self.face3ds = self.content.modelspace().query("3DFACE")
# Not yet implemented, example file needed
# self.meshes = self.content.modelspace().query("MESH")
polyline_entities = self.content.modelspace().query("POLYLINE")
for entity in polyline_entities:
if entity.is_2d_polyline:
self.polyline2ds.append(entity)
elif entity.is_3d_polyline:
self.polyline3ds.append(entity)
class DXFParser(object):
"""Class for parsing data from DXF files.
The parser converts the raw geometric data of the file
into corresponding geometry objects and data structures.
Parameters
----------
reader : :class:`DXFReader`
A DXF file reader.
precision : str
Precision specification for parsing geometric data.
"""
def __init__(self, reader, precision):
self.precision = precision
self.reader = reader
self.vertices = None
self.points = None
self.face3ds = None
self.lines = None
self.polylines = None
self.faces = None
self.groups = None
self.objects = None
self.meshes = None
self.polyline2ds = None
self.polyline3ds = None
def parse(self):
"""Parse the the data found by the reader."""
self.lines = [
[list(line.dxf.start), list(line.dxf.end)] for line in self.reader.lines
]
self.points = [list(point.dxf.location) for point in self.reader.points]
# self.meshes = [
# [mesh.MeshData.vertices, mesh.MeshData.faces] for mesh in self.reader.meshes
# ]
# self.parse_face3ds()
self.face3ds = [[v.xyz for v in face.wcs_vertices()] for face in self.reader.face3ds]
# The POLYLINE entity is very complex, it’s used to build 2D/3D polylines, 3D meshes and 3D polyfaces.
# TODO Convert OCS to WCS
self.polyline2ds = [[v.dxf.location for v in polyline.vertices] for polyline in self.reader.polyline2ds]
self.polyline3ds = [[v.dxf.location for v in polyline.vertices] for polyline in self.reader.polyline3ds]
def parse_face3ds_deprecated(self):
# Not used for now
# At the moment, the 3d faces are parsed as points
if self.face3ds is None:
self.face3ds = []
for face3d in self.reader.face3ds:
[f0, f1, f2, f3] = face3d.get_edges_visibility()
if f0:
self.face3ds.append([list(face3d.dxf.vtx0), list(face3d.dxf.vtx1)])
if f1:
self.face3ds.append([list(face3d.dxf.vtx1), list(face3d.dxf.vtx2)])
if f2:
self.face3ds.append([list(face3d.dxf.vtx2), list(face3d.dxf.vtx3)])
if f3:
self.face3ds.append([list(face3d.dxf.vtx3), list(face3d.dxf.vtx0)])
This code support:
| .dxf | |
|---|---|
| unit | |
| coordinate system | |
| vertices | list[list[x,y,z]] |
| faces | list[int] |
| normals | |
| lines | list[[x0,y0,z0],[x1,y1,z1]] |
| polyline | list[list[x,y,z]] |
| points | list[x,y,z] |
| groups | |
| textures |
- Lingua principale
- Python
- Stelle
- 387
- Fork
- 124
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di compas-dev/compas
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
compas-dev/compas#1523 · 3 commenti ·
-
Numpy and Rhino 9Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 30/100
compas-dev/compas#1507 · 2 commenti · 1 reazione ·
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 15/100
compas-dev/compas#1504 · 1 commento ·
-
More transformations of shapesForse già presa @copilot-swe-agent l’ha presa 366 giorni fa. Aperta
compas-dev/compas#1493 · 1 reazione · 1 assegnatario ·
-
`Polygon.normal` with `normal_polygon` instead of `normal_triangle`?Forse già presa @copilot-swe-agent l’ha presa 352 giorni fa. Aperta
compas-dev/compas#1487 · 1 reazione · 1 assegnatario ·
Tutte le issue di compas-dev/compas
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
cellrishi-code/claude-skills-atlas#165 ·
I maintainer di solito rispondono entro 1 giorno
-
bug confirmed issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
open-webui/open-webui#32635 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Filters: ?field:ne=null matches NULL rows instead of non-NULL onesForse già presa @rshdhere l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Netflix/metaflow-service#504 ·
-
needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
gke-labs/kube-agents#3394 ·
I maintainer di solito rispondono entro 1 giorno
-
A2A audit timestamps end in +00:00Z (invalid ISO 8601)Forse già presa @O1sumitkumar l’ha presa oggi. Apertabug good first issue help wanted python
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno