mozman / ezdxf

Python interface to DXF
https://ezdxf.mozman.at
MIT License
935 stars 191 forks source link

Extrusion attribute not read if extrusion.x (210) is not present #933

Closed HugoBallee closed 1 year ago

HugoBallee commented 1 year ago

The bug When reading a dxf file, the extrusion attribute is not considered if the extrusion.x component is not present in the file (DXF group 210). If the extrusion.y (DXF group 220) and/or the extrusion.z (DXF group 230) are present, they are omitted. It fallback to the default extrusion value (0,0,1). If the extrusion.x (DXF group 210) component is present but not the extrusion.y (DXF group 220), it will throw an exception (ezdxf.lldxf.const.DXFStructureError) instead of falling back to default values (0.0?) for missing values.

To Reproduce extrusion.zip In this zip file you can find 3 simplified DXF files and a python script that triggers the error and bug.

Expected behavior If at least one component is present I would expect to get it with the missing components to be 0.

DXF Expected behavior Current behavior
  0
POINT
  8
4
(0, 0, 1) (0, 0, 1)
  0
POINT
  8
4
  230
230.0
(0, 0, 230.0) (0, 0, 1)
  0
POINT
  8
4
  220
220.0
(0, 220.0, 0) (0, 0, 1)
  0
POINT
  8
4
  220
220.0
  230
230.0
(0, 220.0, 230.0) (0, 0, 1)
  0
POINT
  8
4
  210
210.0
(210.0, 0, 0) ezdxf.lldxf.const.DXFStructureError
  0
POINT
  8
4
  210
210.0
  230
230.0
(210.0, 0, 230.0) ezdxf.lldxf.const.DXFStructureError
  0
POINT
  8
4
  210
210.0
  220
220.0
(210.0, 220.0, 0) (210.0, 220.0, 0)
  0
POINT
  8
4
  210
210.0
  220
220.0
  230
230.0
(210.0, 220.0, 230.0) (210.0, 220.0, 230.0)
mozman commented 1 year ago

Hi!

Please use the recover module to load messy DXF files from unreliable sources.

You can find the documentation for the recovermodule here.

This script loads your files without raising any exceptions:

from ezdxf import recover

files = [
    "./extrusion omitted.dxf",
    "./extrusion error no 220 no 230.dxf",
    "./extrusion error no 220 with 230.dxf",
]

for file in files:
    print(f"\nReading file: {file}")
    doc, auditor = recover.readfile(file)

    layers = []
    for entity in doc.entitydb.values():
        if entity.dxf.hasattr("layer"):
            l = entity.dxf.layer
            if l not in layers:
                layers.append(l)

    for layer in layers:
        for entity in doc.entitydb.values():
            if entity.dxf.hasattr("layer"):
                if layer == entity.dxf.layer:
                    if layer == "4":
                        print(f"\textrusion: {entity.dxf.extrusion}")