Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

`DXF` reader enhancement

Aperta
#1,210 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
25/100
Tipo di issue
Funzionalità
Chiarezza
Da chiarire
Stato di attività
Ferma
Stack tecnologico
python
Ambito
data

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

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di compas-dev/compas

Tutte le issue di compas-dev/compas

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.