| | |
| |
|
| | |
| | |
| | |
| | |
| | """ |
| | @package importDWG |
| | ingroup DRAFT |
| | \brief DWG file importer & exporter |
| | |
| | This module provides support for importing and exporting Autodesk DWG files. |
| | This module is only a thin layer that uses the ODA (formerly Teigha) File |
| | Converter application to convert to/from DXF. Then the real work is done by |
| | importDXF |
| | |
| | Test files |
| | https://knowledge.autodesk.com/support/autocad/downloads/ |
| | caas/downloads/content/autocad-sample-files.html |
| | """ |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import FreeCAD |
| | from FreeCAD import Console as FCC |
| | from draftutils import params |
| |
|
| | if FreeCAD.GuiUp: |
| | from draftutils.translate import translate |
| | else: |
| |
|
| | def translate(context, txt): |
| | return txt |
| |
|
| |
|
| | def open(filename): |
| | """Open filename and parse using importDXF.open(). |
| | |
| | Parameters |
| | ---------- |
| | filename : str |
| | The path to the filename to be opened. |
| | |
| | Returns |
| | ------- |
| | App::Document |
| | The new FreeCAD document object created, with the parsed information. |
| | """ |
| | dxf = convertToDxf(filename) |
| | if dxf: |
| | import importDXF |
| |
|
| | doc = importDXF.open(dxf) |
| | return doc |
| | return |
| |
|
| |
|
| | def insert(filename, docname): |
| | """Imports a file using importDXF.insert(). |
| | |
| | If no document exist, it is created. |
| | |
| | Parameters |
| | ---------- |
| | filename : str |
| | The path to the filename to be opened. |
| | docname : str |
| | The name of the active App::Document if one exists, or |
| | of the new one created. |
| | |
| | Returns |
| | ------- |
| | App::Document |
| | The active FreeCAD document, or the document created if none exists, |
| | with the parsed information. |
| | """ |
| | dxf = convertToDxf(filename) |
| | if dxf: |
| | import importDXF |
| |
|
| | |
| | doc = importDXF.insert(dxf, docname) |
| | return doc |
| | return |
| |
|
| |
|
| | def export(objectslist, filename): |
| | """Export the DWG file with a given list of objects. |
| | |
| | The objects are exported with importDXF.export(). |
| | Then the result is converted to DWG. |
| | |
| | Parameters |
| | ---------- |
| | exportList : list |
| | List of document objects to export. |
| | filename : str |
| | Path to the new file. |
| | |
| | Returns |
| | ------- |
| | str |
| | The same `filename` input. |
| | """ |
| | import importDXF |
| | import os |
| | import tempfile |
| |
|
| | outdir = tempfile.mkdtemp() |
| | _basename = os.path.splitext(os.path.basename(filename))[0] |
| | dxf = outdir + os.sep + _basename + ".dxf" |
| | importDXF.export(objectslist, dxf) |
| | convertToDwg(dxf, filename) |
| | return filename |
| |
|
| |
|
| | def get_libredwg_converter(typ): |
| | """Find the LibreDWG converter. |
| | |
| | It searches the FreeCAD parameters database, then searches the OS search path. |
| | There are no standard installation paths. |
| | |
| | `typ` is required because LibreDWG uses two converters and we store only one. |
| | |
| | Parameters |
| | ---------- |
| | typ : str |
| | "dwg2dxf" or "dxf2dwg". |
| | |
| | Returns |
| | ------- |
| | str |
| | The full path of the converter. |
| | """ |
| | import os |
| | import platform |
| |
|
| | path = params.get_param("TeighaFileConverter") |
| |
|
| | if "dwg2dxf" in path or "dxf2dwg" in path: |
| | if typ not in path: |
| | path = os.path.dirname(path) + "/" + typ + os.path.splitext(path)[1] |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| | elif platform.system() == "Windows": |
| | for sub in os.getenv("PATH").split(os.pathsep): |
| | path = sub.replace("\\", "/") + "/" + typ + ".exe" |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| | else: |
| | for sub in os.getenv("PATH").split(os.pathsep): |
| | path = sub + "/" + typ |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| |
|
| | return None |
| |
|
| |
|
| | def get_oda_converter(): |
| | """Find the ODA converter. |
| | |
| | It searches the FreeCAD parameters database, then searches for common paths. |
| | |
| | Parameters |
| | ---------- |
| | None |
| | |
| | Returns |
| | ------- |
| | str |
| | The full path of the converter. |
| | """ |
| | import os |
| | import platform |
| |
|
| | path = params.get_param("TeighaFileConverter") |
| |
|
| | if "ODAFileConverter" in path: |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| | elif platform.system() == "Windows": |
| | odadir = os.path.expandvars("%ProgramFiles%\\ODA").replace("\\", "/") |
| | if os.path.exists(odadir): |
| | for sub in os.listdir(odadir): |
| | path = odadir + "/" + sub + "/" + "ODAFileConverter.exe" |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| | elif platform.system() == "Linux": |
| | path = "/usr/bin/ODAFileConverter" |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| | else: |
| | path = "/Applications/ODAFileConverter.app/Contents/MacOS/ODAFileConverter" |
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| |
|
| | return None |
| |
|
| |
|
| | def get_qcad_converter(): |
| | """Find the QCAD converter. |
| | |
| | It searches the FreeCAD parameters database, then searches for common paths. |
| | |
| | Parameters |
| | ---------- |
| | None |
| | |
| | Returns |
| | ------- |
| | str |
| | The full path of the converter. |
| | """ |
| | import os |
| | import platform |
| |
|
| | path = params.get_param("TeighaFileConverter") |
| |
|
| | if "dwg2dwg" in path: |
| | pass |
| | elif platform.system() == "Windows": |
| | path = os.path.expandvars("%ProgramFiles%\\QCAD\\dwg2dwg.bat").replace("\\", "/") |
| | elif platform.system() == "Linux": |
| | |
| | path = os.path.expandvars("/home/$USER/opt") |
| | if os.path.exists(path) and os.path.isdir(path): |
| | for sub in os.listdir(path): |
| | if "qcad" in sub: |
| | path = path + "/" + sub + "/" + "dwg2dwg" |
| | break |
| | else: |
| | path = "/Applications/QCAD.app/Contents/Resources/dwg2dwg" |
| |
|
| | if os.path.exists(path) and os.path.isfile(path): |
| | return path |
| | return None |
| |
|
| |
|
| | def convertToDxf(dwgfilename): |
| | """Convert a DWG file to a DXF file. |
| | |
| | If the converter is found it is used, otherwise the conversion fails. |
| | |
| | Parameters |
| | ---------- |
| | dwgfilename : str |
| | The input filename. |
| | |
| | Returns |
| | ------- |
| | str |
| | The new file produced. |
| | """ |
| | import os |
| | import subprocess |
| | import tempfile |
| |
|
| | dwgfilename = dwgfilename.replace("\\", "/") |
| | conv = params.get_param("DWGConversion") |
| | error_msg = ( |
| | translate( |
| | "draft", |
| | """Error during DWG conversion. |
| | Try moving the DWG file to a directory path without spaces and non-english characters, |
| | or try saving to a lower DWG version.""", |
| | ) |
| | + "\n" |
| | ) |
| |
|
| | if conv in [0, 1]: |
| | libredwg = get_libredwg_converter("dwg2dxf") |
| | if libredwg is not None: |
| | outdir = tempfile.mkdtemp().replace("\\", "/") |
| | basename = os.path.basename(dwgfilename) |
| | result = outdir + "/" + os.path.splitext(basename)[0] + ".dxf" |
| | cmdline = [libredwg, dwgfilename, "-o", result] |
| | FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n") |
| | proc = subprocess.Popen(cmdline) |
| | proc.communicate() |
| | if os.path.exists(result): |
| | FCC.PrintMessage(translate("draft", "Conversion successful") + "\n") |
| | return result |
| | else: |
| | FCC.PrintError(error_msg) |
| | elif conv != 0: |
| | FCC.PrintError(translate("draft", "LibreDWG converter not found") + "\n") |
| |
|
| | if conv in [0, 2]: |
| | oda = get_oda_converter() |
| | if oda is not None: |
| | indir = os.path.dirname(dwgfilename) |
| | outdir = tempfile.mkdtemp().replace("\\", "/") |
| | basename = os.path.basename(dwgfilename) |
| | cmdline = [oda, indir, outdir, "ACAD2000", "DXF", "0", "1", basename] |
| | FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n") |
| | proc = subprocess.Popen(cmdline) |
| | proc.communicate() |
| | result = outdir + "/" + os.path.splitext(basename)[0] + ".dxf" |
| | if os.path.exists(result): |
| | FCC.PrintMessage(translate("draft", "Conversion successful") + "\n") |
| | return result |
| | else: |
| | FCC.PrintError(error_msg) |
| | elif conv != 0: |
| | FCC.PrintError(translate("draft", "ODA converter not found") + "\n") |
| |
|
| | if conv in [0, 3]: |
| | qcad = get_qcad_converter() |
| | if qcad is not None: |
| | outdir = tempfile.mkdtemp().replace("\\", "/") |
| | basename = os.path.basename(dwgfilename) |
| | result = outdir + "/" + os.path.splitext(basename)[0] + ".dxf" |
| | cmdline = [qcad, "-f", "-o", result, dwgfilename] |
| | FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n") |
| | proc = subprocess.Popen(cmdline, cwd=os.path.dirname(qcad)) |
| | proc.communicate() |
| | if os.path.exists(result): |
| | FCC.PrintMessage(translate("draft", "Conversion successful") + "\n") |
| | return result |
| | else: |
| | FCC.PrintError(error_msg) |
| | elif conv != 0: |
| | FCC.PrintError(translate("draft", "QCAD converter not found") + "\n") |
| |
|
| | FCC.PrintError( |
| | translate( |
| | "draft", |
| | """No suitable external DWG converter has been found. |
| | Please set one manually under menu Edit → Preferences → Import/Export → DWG |
| | For more information see: |
| | https://wiki.freecad.org/Import_Export_Preferences""", |
| | ) |
| | + "\n" |
| | ) |
| | return None |
| |
|
| |
|
| | def convertToDwg(dxffilename, dwgfilename): |
| | """Convert a DXF file to a DWG file. |
| | |
| | If the converter is found it is used, otherwise the conversion fails. |
| | |
| | Parameters |
| | ---------- |
| | dxffilename : str |
| | The input DXF file |
| | dwgfilename : str |
| | The output DWG file |
| | |
| | Returns |
| | ------- |
| | str |
| | The same `dwgfilename` file path. |
| | """ |
| | import os |
| | import subprocess |
| |
|
| | dxffilename = dxffilename.replace("\\", "/") |
| | dwgfilename = dwgfilename.replace("\\", "/") |
| | conv = params.get_param("DWGConversion") |
| |
|
| | if conv in [0, 1]: |
| | libredwg = get_libredwg_converter("dxf2dwg") |
| | if libredwg is not None: |
| | cmdline = [libredwg, dxffilename, "-y", "-o", dwgfilename] |
| | FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n") |
| | proc = subprocess.Popen(cmdline) |
| | proc.communicate() |
| | return dwgfilename |
| | elif conv != 0: |
| | FCC.PrintError(translate("draft", "LibreDWG converter not found") + "\n") |
| |
|
| | if conv in [0, 2]: |
| | oda = get_oda_converter() |
| | if oda is not None: |
| | indir = os.path.dirname(dxffilename) |
| | outdir = os.path.dirname(dwgfilename) |
| | basename = os.path.basename(dxffilename) |
| | cmdline = [oda, indir, outdir, "ACAD2000", "DWG", "0", "1", basename] |
| | FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n") |
| | proc = subprocess.Popen(cmdline) |
| | proc.communicate() |
| | return dwgfilename |
| | elif conv != 0: |
| | FCC.PrintError(translate("draft", "ODA converter not found") + "\n") |
| |
|
| | if conv in [0, 3]: |
| | qcad = get_qcad_converter() |
| | if qcad is not None: |
| | cmdline = [qcad, "-f", "-o", dwgfilename, dxffilename] |
| | FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n") |
| | proc = subprocess.Popen(cmdline, cwd=os.path.dirname(qcad)) |
| | proc.communicate() |
| | return dwgfilename |
| | elif conv != 0: |
| | FCC.PrintError(translate("draft", "QCAD converter not found") + "\n") |
| |
|
| | FCC.PrintError( |
| | translate( |
| | "draft", |
| | """No suitable external DWG converter has been found. |
| | Please set one manually under menu Edit → Preferences → Import/Export → DWG |
| | For more information see: |
| | https://wiki.freecad.org/Import_Export_Preferences""", |
| | ) |
| | + "\n" |
| | ) |
| | return None |
| |
|