def test_readfile(filename): try: recover.readfile(filename) except ezdxf.DXFStructureError: pytest.fail(f'{filename}: DXFStructureError in recover mode.') else: assert True
def _main(): parser = argparse.ArgumentParser() parser.add_argument('--cad_file') parser.add_argument('--layout', default='Model') parser.add_argument('--ltype', default='internal', choices=['internal', 'ezdxf']) args = parser.parse_args() signal.signal(signal.SIGINT, signal.SIG_DFL) # handle Ctrl+C properly app = qw.QApplication(sys.argv) v = CadViewer(params={ 'linetype_renderer': args.ltype }) if args.cad_file is not None: try: doc, auditor = recover.readfile(args.cad_file) except IOError: print(f'Not a DXF file or a generic I/O error: {args.cad_file}') sys.exit(1) except ezdxf.DXFStructureError: print(f'Invalid or corrupted DXF file: {args.cad_file}') sys.exit(2) v.set_document(doc, auditor) try: v.draw_layout(args.layout) except KeyError: print(f'could not find layout "{args.layout}". Valid layouts: {[l.name for l in v.doc.layouts]}') sys.exit(3) sys.exit(app.exec_())
def _audit(filename: str) -> None: msg = f"auditing file: {filename}" print(msg) logger.info(msg) try: doc, auditor = recover.readfile(filename) except IOError: msg = 'Not a DXF file or a generic I/O error.' print(msg) logger.error(msg) return # keep on processing additional files except const.DXFStructureError: msg = 'Invalid or corrupted DXF file.' print(msg) logger.error(msg) return # keep on processing additional files if auditor.has_errors: auditor.print_error_report() log_errors(auditor) if auditor.has_fixes: auditor.print_fixed_errors() log_fixes(auditor) if auditor.has_errors is False and auditor.has_fixes is False: print('No errors found.') else: print(f'Found {len(auditor.errors)} errors, ' f'applied {len(auditor.fixes)} fixes') if args.save: outname = build_outname(filename) doc.saveas(outname) print(f"Saved recovered file as: {outname}")
def _select_doc(self): path, _ = qw.QFileDialog.getOpenFileName( self, caption="Select CAD Document", filter="CAD Documents (*.dxf *.DXF *.dwg *.DWG)", ) if path: try: if os.path.splitext(path)[1].lower() == ".dwg": doc = odafc.readfile(path) auditor = doc.audit() else: try: doc = ezdxf.readfile(path) except ezdxf.DXFError: doc, auditor = recover.readfile(path) else: auditor = doc.audit() self.set_document(doc, auditor) except IOError as e: qw.QMessageBox.critical(self, "Loading Error", str(e)) except DXFStructureError as e: qw.QMessageBox.critical( self, "DXF Structure Error", f'Invalid DXF file "{path}": {str(e)}', )
def load_every_document(filename: str): def io_error() -> str: msg = f'Not a DXF file or a generic I/O error: "{filename}"' print(msg, file=sys.stderr) return msg def structure_error() -> str: msg = f'Invalid or corrupted DXF file: "{filename}"' print(msg, file=sys.stderr) return msg binary_fmt = False if is_binary_dxf_file(filename): try: doc = ezdxf.readfile(filename) except IOError: raise const.DXFLoadError(io_error()) except const.DXFStructureError: raise const.DXFLoadError(structure_error()) auditor = doc.audit() binary_fmt = True else: try: doc, auditor = recover.readfile(filename) except IOError: raise const.DXFLoadError(io_error()) except const.DXFStructureError: raise const.DXFLoadError(structure_error()) return doc, auditor, binary_fmt
def test_recover(self, filename): doc, auditor = recover.readfile(filename, errors='ignore') assert doc.filename == filename assert doc.dxfversion == 'AC1032' assert auditor.has_errors is True assert len(auditor.errors) == 238, 'expected decoding errors' assert len(auditor.fixes) == 536
def _main(): parser = argparse.ArgumentParser( description='draw the given CAD file and save it to a file or view it') parser.add_argument('cad_file', nargs='?') parser.add_argument('--supported_formats', action='store_true') parser.add_argument('--layout', default='Model') parser.add_argument('--out', required=False) parser.add_argument('--dpi', type=int, default=300) parser.add_argument('--ltype', default='internal') args = parser.parse_args() if args.supported_formats: fig = plt.figure() for extension, description in fig.canvas.get_supported_filetypes().items(): print(f'{extension}: {description}') sys.exit() if args.cad_file is None: print('no CAD file specified') sys.exit(1) try: doc = ezdxf.readfile(args.cad_file) except IOError: print(f'Not a DXF file or a generic I/O error.') sys.exit(2) except ezdxf.DXFError: try: doc, auditor = recover.readfile(args.cad_file) except ezdxf.DXFStructureError: print(f'Invalid or corrupted DXF file: {args.cad_file}') sys.exit(3) else: auditor = doc.audit() if auditor.has_errors: # But is most likely good enough for rendering. print(f'Found {len(auditor.errors)} unrecoverable errors.') if auditor.has_fixes: print(f'Fixed {len(auditor.fixes)} errors.') try: layout = doc.layouts.get(args.layout) except KeyError: print(f'Could not find layout "{args.layout}". ' f'Valid layouts: {[l.name for l in doc.layouts]}') sys.exit(4) fig: plt.Figure = plt.figure() ax: plt.Axes = fig.add_axes([0, 0, 1, 1]) ctx = RenderContext(doc) out = MatplotlibBackend(ax, params={'linetype_renderer': args.ltype}) Frontend(ctx, out).draw_layout(layout, finalize=True) if args.out is not None: print(f'saving to "{args.out}"') fig.savefig(args.out, dpi=args.dpi) plt.close(fig) else: plt.show()
def test_readfile_recover02_dxf(): doc, auditor = recover.readfile(fullpath(RECOVER2)) assert doc.dxfversion == 'AC1032' assert auditor.has_errors is False table_head = doc.block_records.head assert table_head.dxf.handle is not None assert table_head.dxf.handle in doc.entitydb
def test_load_special_dxf_unicode_notation(filename): doc, auditor = recover.readfile(filename) layer = doc.layers.get("ΛΑΓΕΡÄÜÖ") assert layer.dxf.name == "ΛΑΓΕΡÄÜÖ" msp = doc.modelspace() lines = msp.query('LINE[layer=="ΛΑΓΕΡÄÜÖ"]') assert len(lines) == 2
def test_read_cc_dxflib_file(): doc, auditor = recover.readfile(fullpath(CC_DXFLIB)) codes = {fix.code for fix in auditor.fixes} assert AuditError.REMOVED_UNSUPPORTED_SECTION in codes assert AuditError.REMOVED_UNSUPPORTED_TABLE in codes msp = doc.modelspace() polyline = msp.query('POLYLINE').first assert polyline is not None
def test_readfile_empty_handles_dxf(): doc, auditor = recover.readfile(fullpath(EMPTY_HANDLES)) msp = doc.modelspace() assert doc.dxfversion == "AC1009" assert auditor.has_errors is False assert len(msp.query("LINE")) == 8 assert len(msp.query("*[layer=='GEOMETRY-CUTTING']")) == 4 assert len(msp.query("*[layer=='GEOMETRY-ENGRAVING']")) == 4
def test_coordinate_order_problem(filename): try: doc, auditor = recover.readfile(filename) except ezdxf.DXFError as e: pytest.fail(str(e)) else: msp = doc.modelspace() lines = msp.query("LINE") assert lines[0].dxf.start == (1.5, 0, 0)
def toPdf(self): self.toDxf(remove_duplicates=False, for_prime_center=False) dox, auditor = recover.readfile(self.dxf_file_path) if not auditor.has_errors: file_path = './pdf/' + self.getBrand() + '/' + self.getColor() + '/' + str(self.getWidth()) if not os.path.exists(file_path): os.makedirs(file_path) file_name = '/grid_' + str(self.getName()) + '.png' matplotlib.qsave(dox.modelspace(), file_path + file_name)
def test_recover_duplicate_handles(filename, tmp_path): doc, auditor = recover.readfile(filename) fixed_dxf_name = tmp_path / "fixed.dxf" doc.saveas(fixed_dxf_name) assert doc.layers.head.dxf.handle != "2" assert doc.linetypes.head.dxf.handle != "4" doc2 = ezdxf.readfile(fixed_dxf_name) auditor = doc2.audit() assert len(auditor.fixes) == 0 assert len(doc2.modelspace()) == 132
def fixed_by_ezdxf(filename): new_filename = filename.replace(".dxf", ".fix.dxf") # The original file is only readable but not to fix! doc, auditor = recover.readfile(filename) # Create a new valid DXF document: doc2 = ezdxf.new() # Import data into new document: importer = Importer(doc, doc2) importer.import_modelspace() importer.finalize() doc2.saveas(new_filename) print(f'saved fixed DXF file "{new_filename}"')
def find_unused_blocks(filename): try: doc = ezdxf.readfile(filename) except IOError: return except ezdxf.DXFStructureError: try: print('Using recover mode.') doc, auditor = recover.readfile(filename) except ezdxf.DXFStructureError: print(f'DXF structure error!') return _find_unused_blocks(doc)
def has_dxf_entity(filename, entity_name): try: doc = ezdxf.readfile(filename) except IOError: return False except ezdxf.DXFError: try: print("Using recover mode.") doc, auditor = recover.readfile(filename) except ezdxf.DXFStructureError: print(f"DXF structure error!") return False entities = doc.modelspace().query(entity_name) if len(entities): return True entities = doc.objects.query(entity_name) return bool(len(entities))
def audit(filename: str, safe=False) -> None: try: if safe: print('Running in recover mode.') doc, auditor = recover.readfile(filename) else: doc = ezdxf.readfile(filename) auditor = doc.audit() except IOError: print(f"Unable to read DXF file '{filename}'.") sys.exit(1) except ezdxf.DXFStructureError as e: print(str(e)) sys.exit(2) if auditor.has_errors: auditor.print_error_report() if auditor.has_fixes: auditor.print_fixed_errors()
def _main(): parser = argparse.ArgumentParser() parser.add_argument("--cad_file") parser.add_argument("--layout", default="Model") parser.add_argument("--ltype", default="internal", choices=["internal", "ezdxf"]) # disable lineweight at all by default: parser.add_argument("--lineweight_scaling", type=float, default=0) args = parser.parse_args() # setup drawing add-on configuration config = Configuration.defaults() config = config.with_changes( line_policy=LinePolicy.ACCURATE if args.ltype == "ezdxf" else config.line_policy, lineweight_scaling=args.lineweight_scaling, ) signal.signal(signal.SIGINT, signal.SIG_DFL) # handle Ctrl+C properly app = qw.QApplication(sys.argv) v = CadViewer(config=config) if args.cad_file is not None: try: doc, auditor = recover.readfile(args.cad_file) except IOError: print(f"Not a DXF file or a generic I/O error: {args.cad_file}") sys.exit(1) except ezdxf.DXFStructureError: print(f"Invalid or corrupted DXF file: {args.cad_file}") sys.exit(2) v.set_document(doc, auditor) try: v.draw_layout(args.layout) except KeyError: print( f'could not find layout "{args.layout}". Valid layouts: {[l.name for l in v.doc.layouts]}' ) sys.exit(3) sys.exit(app.exec())
def load_document(filename: str): try: doc, auditor = recover.readfile(filename) except IOError: msg = f'Not a DXF file or a generic I/O error: "{filename}"' print(msg, file=sys.stderr) sys.exit(2) except const.DXFStructureError: msg = f'Invalid or corrupted DXF file: "{filename}"' print(msg, file=sys.stderr) sys.exit(3) if auditor.has_errors: # But is most likely good enough for rendering. msg = f"Audit process found {len(auditor.errors)} unrecoverable error(s)." print(msg) logger.error(msg) if auditor.has_fixes: msg = f"Audit process fixed {len(auditor.fixes)} error(s)." print(msg) logger.info(msg) return doc, auditor
def test_readfile_recover02_dxf(): doc, auditor = recover.readfile(fullpath(RECOVER2)) assert doc.dxfversion == 'AC1032' assert auditor.has_errors is False # Auditor should restore deleted BLOCK-RECORD table head: blkrec_head = doc.block_records.head assert blkrec_head.dxf.handle is not None assert blkrec_head.dxf.handle in doc.entitydb # Auditor should update/fix BLOCK_RECORD entries owner handle: for entry in doc.block_records: assert entry.dxf.owner == blkrec_head.dxf.handle, \ 'Auditor() should update table-entry owner handle.' # Auditor should restore invalid VPORT table-head owner handle: vport_head = doc.viewports.head assert vport_head.dxf.owner == '0', \ 'Auditor() should repair invalid table-head owner handle.' # Auditor should fix invalid VPORT table-entry owner handle: vport = doc.viewports.get('*Active')[0] assert vport.dxf.owner == vport_head.dxf.handle, \ 'Auditor() should update table-entry owner handle.'
def test_recover_ProE_file(self, filename): doc, auditor = recover.readfile(filename) assert doc.filename == filename assert doc.dxfversion is not None assert len(auditor.errors) == 0 assert len(auditor.fixes) == 0
def test_readfile_and_raise_exception(self, filename): with pytest.raises(UnicodeDecodeError): ezdxf.readfile(filename, errors='strict') with pytest.raises(UnicodeDecodeError): recover.readfile(filename, errors='strict')
def recover_mtext_entities(name: str) -> Iterable[MText]: doc, auditor = recover.readfile(DATA / name) msp = doc.modelspace() entities = msp.query('MTEXT') return entities
def _main(): parser = argparse.ArgumentParser( description="draw the given CAD file and save it to a file or view it" ) parser.add_argument("cad_file", nargs="?") parser.add_argument("--supported_formats", action="store_true") parser.add_argument("--layout", default="Model") parser.add_argument("--out", required=False) parser.add_argument("--dpi", type=int, default=300) parser.add_argument("--ltype", default="internal") args = parser.parse_args() if args.supported_formats: fig = plt.figure() for ( extension, description, ) in fig.canvas.get_supported_filetypes().items(): print(f"{extension}: {description}") sys.exit() if args.cad_file is None: print("no CAD file specified") sys.exit(1) try: doc = ezdxf.readfile(args.cad_file) except IOError: print(f"Not a DXF file or a generic I/O error.") sys.exit(2) except ezdxf.DXFError: try: doc, auditor = recover.readfile(args.cad_file) except ezdxf.DXFStructureError: print(f"Invalid or corrupted DXF file: {args.cad_file}") sys.exit(3) else: auditor = doc.audit() if auditor.has_errors: # But is most likely good enough for rendering. print(f"Found {len(auditor.errors)} unrecoverable errors.") if auditor.has_fixes: print(f"Fixed {len(auditor.fixes)} errors.") try: layout = doc.layouts.get(args.layout) except KeyError: print( f'Could not find layout "{args.layout}". ' f"Valid layouts: {[l.name for l in doc.layouts]}" ) sys.exit(4) # setup drawing add-on configuration config = Configuration.defaults() config = config.with_changes( line_policy=LinePolicy.ACCURATE if args.ltype == "ezdxf" else config.line_policy ) fig: plt.Figure = plt.figure(dpi=args.dpi) ax: plt.Axes = fig.add_axes([0, 0, 1, 1]) ctx = RenderContext(doc) out = MatplotlibBackend(ax) Frontend(ctx, out, config=config).draw_layout(layout, finalize=True) if args.out is not None: print(f'saving to "{args.out}"') fig.savefig(args.out, dpi=args.dpi) plt.close(fig) else: plt.show()
files = list( chain(*[glob.glob(os.path.join(EZDXF_TEST_FILES, d)) for d in DIRS])) @pytest.mark.parametrize('filename', files) def test_readfile(filename): try: recover.readfile(filename) except ezdxf.DXFStructureError: pytest.fail(f'{filename}: DXFStructureError in recover mode.') else: assert True if __name__ == '__main__': import logging logging.basicConfig(level=logging.WARNING) for name in files: print(f'Loading file: "{name}"') try: doc = ezdxf.readfile(name) auditor = doc.audit() except ezdxf.DXFStructureError: print('Regular loading function failed, using recover mode.') doc, auditor = recover.readfile(name) if auditor.has_errors: print(f'Found {len(auditor.errors)} unrecoverable error(s).') if auditor.has_fixes: print(f'Fixed {len(auditor.fixes)} error(s).')
def recover_mtext_entities(name: str): doc, auditor = recover.readfile(DATA / name) return doc
def test_readfile_01(filename01): doc = recover.readfile(filename01) assert doc.dxfversion == 'AC1009' auditor = doc.audit() assert auditor.has_errors is False
def test_readfile_recover01_dxf(): doc, auditor = recover.readfile(fullpath(RECOVER1)) assert doc.dxfversion == 'AC1009' assert auditor.has_errors is False
def recover_by_ezdxf(filename): # The original file is only readable but not to fix! new_filename = filename.replace(".dxf", ".rec.dxf") doc, auditor = recover.readfile(filename) doc.saveas(new_filename) print(f'saved recovered DXF file "{new_filename}"')