mozman / ezdxf

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

Read messed up LAYOUT structure created by QGIS #997

Closed iembry closed 8 months ago

iembry commented 8 months ago

Describe the bug

I attempted to read a DXF file only, but I encountered various issues.

To Reproduce

Using ezdxf version 1.1.4b3 with Python 3.11.2 & GCC 12.2.0 on a Debian GNU/Linux 12 (bookworm) server in a virtual environment

The dxf file has been zipped and sent to confidential@mozman.at.

import ezdxf print(ezdxf) <module 'ezdxf' from 'ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/init.py'> doc = ezdxf.readfile("bolton5_text_2d.dxf") Traceback (most recent call last): File "", line 1, in File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/filemanagement.py", line 154, in readfile doc = read(fp) # type: ignore ^^^^^^^^ File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/filemanagement.py", line 95, in read return Drawing.read(stream) ^^^^^^^^^^^^^^^^^^^^ File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/document.py", line 337, in read return cls.load(tag_loader) ^^^^^^^^^^^^^^^^^^^^ File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/document.py", line 352, in load doc._load(tag_loader) File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/document.py", line 368, in _load self._load_section_dict(sections) File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/document.py", line 456, in _load_section_dict self.layouts = Layouts.load(self) ^^^^^^^^^^^^^^^^^^ File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/layouts/layouts.py", line 154, in load layouts.setup_from_rootdict() File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/layouts/layouts.py", line 199, in setup_from_rootdict layout = Paperspace(dxf_layout, self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/layouts/layout.py", line 73, in init block_record = doc.entitydb[layout.dxf.block_record_handle]


File "ezdxf/ezdxf/ezdxf/lib/python3.11/site-packages/ezdxf/entitydb.py", line 83, in __getitem__
return self._database[handle]
~~~~~~~~~~~~~~^^^^^^^^
KeyError: '1B'

Expected behavior

I expected to be able to read the DXF file and proceed from there to change the file's coordinates.

mozman commented 8 months ago

This file contains a layout with a handle to a BLOCK_RECORD that does not exist. Surprisingly, AutoCAD opens the file without any nagging. Ezdxf can read many crappy DXF files via the recover module, but this case is not covered and I'm not sure if I want to change that because I'm tired of repairing crappy DXF files. So don't expect this issue to be fixed.

mozman commented 8 months ago

I used the RECOVER command of BricsCAD to load your file:

829 objects audited Total errors found during audit 85, fixed 85

Around 10% of the file content has issues, no chance to open that by ezdxf.

And a proud comment states: "DXF created from QGIS"

There are no timestamps in the HEADER section, but the file date in the zip-file is 2023-12-21. Is this a new created file or an old file downloaded from somewhere in the internet?

iembry commented 8 months ago

@mozman

The file was created from QGIS (export project to DXF) yesterday by me.

I was able to open the file with no issues in LibreCAD and FreeCAD as well.

Thank you for letting me know about the issues with the DXF file.

mozman commented 8 months ago

I don't think LibreCAD or FreeCAD are using paperspace layouts at all.

mozman commented 8 months ago

I try to fix this issue and maybe file a bug report at QGIS to improve their DXF output but there are currently 1685 open issues tagged as BUG.

The project implements the DXF exporter from scratch in C++ and I found the problem:

They write the same OBJECTS section for every DXF file with fixed handles, but the entities handles of the content are created dynamically. So the handles in the OBJCTS section (fixed handles) will never match the handles in the TABLES section (dynamic handles). And this is true for every entity in the OBJECTS section and therefor 85 or more errors in every DXF file they export!

This is not a simple fix they have to rewrite the exporter for the OBJECTS section completely - I guess this will not happen.

EDIT: They're so lucky that AutoCAD accepts this mess - it took me a very long time to create a DXF R2000+ file from scratch that was accepted by AutoCAD.

iembry commented 8 months ago

Thank you for providing the follow up details. I appreciate it.

I filed a bug issue with QGIS (https://github.com/qgis/QGIS/issues/55705).

I was able to remove the empty block and save the DXF file that I sent to you with LibreCAD. I was then able to read the file using exdzf.

mozman commented 8 months ago

The current version v1.1.5b0 can open the QGIS file.

iembry commented 7 months ago

Thank you for the update, but I can't install the development version on the system that I'm using. I'll have to wait until there is another stable release version.