Draft: improve handling of DWG-converters (#9444)
* Draft: improve handling of DWG-converters * Lint import statement.
This commit is contained in:
@@ -12,10 +12,6 @@ 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
|
||||
|
||||
The converter may be called
|
||||
/usr/bin/TeighaFileConverter
|
||||
/usr/bin/ODAFileConverter
|
||||
|
||||
Test files
|
||||
https://knowledge.autodesk.com/support/autocad/downloads/
|
||||
caas/downloads/content/autocad-sample-files.html
|
||||
@@ -125,7 +121,9 @@ def export(objectslist, filename):
|
||||
str
|
||||
The same `filename` input.
|
||||
"""
|
||||
import importDXF, os, tempfile
|
||||
import importDXF
|
||||
import os
|
||||
import tempfile
|
||||
outdir = tempfile.mkdtemp()
|
||||
_basename = os.path.splitext(os.path.basename(filename))[0]
|
||||
dxf = outdir + os.sep + _basename + ".dxf"
|
||||
@@ -134,11 +132,54 @@ def export(objectslist, filename):
|
||||
return filename
|
||||
|
||||
|
||||
def getTeighaConverter():
|
||||
"""Find the ODA (formerly Teigha) executable.
|
||||
def get_libredwg_converter(typ):
|
||||
"""Find the LibreDWG converter.
|
||||
|
||||
It searches the FreeCAD parameters database, then searches the OS search path
|
||||
on Linux and Windows systems. 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
|
||||
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
path = p.GetString("TeighaFileConverter")
|
||||
|
||||
if "dwg2dxf" in path or "dxf2dwg" in path: # path set manually
|
||||
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() == "Linux":
|
||||
for sub in os.getenv("PATH").split(":"):
|
||||
path = sub + "/" + typ
|
||||
if os.path.exists(path) and os.path.isfile(path):
|
||||
return path
|
||||
elif platform.system() == "Windows":
|
||||
for sub in os.getenv("PATH").split(";"):
|
||||
path = sub.replace("\\", "/") + "/" + typ + ".exe"
|
||||
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 in Linux and Windows systems.
|
||||
paths on Linux and Windows systems.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -147,26 +188,67 @@ def getTeighaConverter():
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
The full path of the converter executable
|
||||
'/usr/bin/ODAFileConverter'
|
||||
The full path of the converter.
|
||||
"""
|
||||
import FreeCAD, os, platform
|
||||
import os
|
||||
import platform
|
||||
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
path = p.GetString("TeighaFileConverter")
|
||||
if path:
|
||||
# path set manually
|
||||
return path
|
||||
|
||||
if "ODAFileConverter" in path: # path set manually
|
||||
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):
|
||||
if os.path.exists(path) and os.path.isfile(path):
|
||||
return path
|
||||
elif platform.system() == "Windows":
|
||||
odadir = os.path.expandvars("%ProgramFiles%\ODA")
|
||||
odadir = os.path.expandvars("%ProgramFiles%\\ODA").replace("\\", "/")
|
||||
if os.path.exists(odadir):
|
||||
for sub in os.listdir(odadir):
|
||||
path = os.path.join(odadir, sub, "ODAFileConverter.exe")
|
||||
if os.path.exists(path):
|
||||
path = odadir + "/" + sub + "/" + "ODAFileConverter.exe"
|
||||
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 on Linux and Windows systems.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
None
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
The full path of the converter.
|
||||
"""
|
||||
import os
|
||||
import platform
|
||||
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
path = p.GetString("TeighaFileConverter")
|
||||
|
||||
if "dwg2dwg" in path: # path set manually
|
||||
pass
|
||||
elif platform.system() == "Linux":
|
||||
# /home/$USER/opt/qcad-3.28.1-trial-linux-qt5.14-x86_64/dwg2dwg
|
||||
path = os.path.expandvars("/home/$USER/opt")
|
||||
for sub in os.listdir(path):
|
||||
if "qcad" in sub:
|
||||
path = path + "/" + sub + "/" + "dwg2dwg"
|
||||
break
|
||||
elif platform.system() == "Windows":
|
||||
path = os.path.expandvars("%ProgramFiles%\\QCAD\\dwg2dwg.bat").replace("\\", "/")
|
||||
|
||||
if os.path.exists(path) and os.path.isfile(path):
|
||||
return path
|
||||
return None
|
||||
|
||||
|
||||
@@ -185,63 +267,76 @@ def convertToDxf(dwgfilename):
|
||||
str
|
||||
The new file produced.
|
||||
"""
|
||||
import os, tempfile, subprocess, sys
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
dwgfilename = dwgfilename.replace("\\", "/")
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
conv = p.GetInt("DWGConversion",0)
|
||||
path = p.GetString("TeighaFileConverter","")
|
||||
conv = p.GetInt("DWGConversion", 0)
|
||||
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 dxf2dwg/dwg2dxf
|
||||
if not path:
|
||||
path = "dwg2dxf"
|
||||
if path.endswith("dxf2dwg"):
|
||||
path = os.path.join(os.path.dirname,"dwg2dxf")
|
||||
try:
|
||||
outdir = tempfile.mkdtemp()
|
||||
if conv in [0, 1]: # LibreDWG
|
||||
libredwg = get_libredwg_converter("dwg2dxf")
|
||||
if libredwg is not None:
|
||||
outdir = tempfile.mkdtemp().replace("\\", "/")
|
||||
basename = os.path.basename(dwgfilename)
|
||||
result = outdir + os.sep + os.path.splitext(basename)[0] + ".dxf"
|
||||
proc = subprocess.Popen((path, dwgfilename, "-o", result))
|
||||
proc.communicate()
|
||||
return result
|
||||
except Exception:
|
||||
if conv != 0:
|
||||
FCC.PrintError(translate("draft", "LibreDWG error") + "\n")
|
||||
|
||||
if conv in [0,2]: # ODA
|
||||
teigha = getTeighaConverter()
|
||||
if teigha:
|
||||
indir = os.path.dirname(dwgfilename)
|
||||
outdir = tempfile.mkdtemp()
|
||||
basename = os.path.basename(dwgfilename)
|
||||
cmdline = [teigha, indir, outdir, "ACAD2000", "DXF", "0", "1", basename]
|
||||
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()
|
||||
result = outdir + os.sep + os.path.splitext(basename)[0] + ".dxf"
|
||||
if os.path.exists(result):
|
||||
FCC.PrintMessage(translate("draft", "Conversion successful") + "\n")
|
||||
return result
|
||||
else:
|
||||
FCC.PrintError(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")
|
||||
else:
|
||||
if conv != 0:
|
||||
FCC.PrintError(translate("draft", "ODA File Converter not found") + "\n")
|
||||
FCC.PrintError(error_msg)
|
||||
elif conv != 0:
|
||||
FCC.PrintError(translate("draft", "LibreDWG converter not found") + "\n")
|
||||
|
||||
if conv in [0,3]: # QCAD
|
||||
if not path:
|
||||
path = "dwg2dwg"
|
||||
try:
|
||||
outdir = tempfile.mkdtemp()
|
||||
if conv in [0, 2]: # ODA
|
||||
oda = get_oda_converter()
|
||||
if oda is not None:
|
||||
indir = os.path.dirname(dwgfilename)
|
||||
outdir = tempfile.mkdtemp().replace("\\", "/")
|
||||
basename = os.path.basename(dwgfilename)
|
||||
result = outdir + os.sep + os.path.splitext(basename)[0] + ".dxf"
|
||||
proc = subprocess.Popen((path, "-f", "-o", result, dwgfilename))
|
||||
cmdline = [oda, indir, outdir, "ACAD2000", "DXF", "0", "1", basename]
|
||||
FCC.PrintMessage(translate("draft", "Converting:") + " " + str(cmdline) + "\n")
|
||||
proc = subprocess.Popen(cmdline)
|
||||
proc.communicate()
|
||||
return result
|
||||
except Exception:
|
||||
FCC.PrintError(translate("draft", "QCAD error") + "\n")
|
||||
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
|
||||
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)) # cwd required for Windows
|
||||
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
|
||||
|
||||
|
||||
@@ -262,51 +357,52 @@ def convertToDwg(dxffilename, dwgfilename):
|
||||
str
|
||||
The same `dwgfilename` file path.
|
||||
"""
|
||||
import os, subprocess, shutil
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
dxffilename = dxffilename.replace("\\", "/")
|
||||
dwgfilename = dwgfilename.replace("\\", "/")
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
conv = p.GetInt("DWGConversion",0)
|
||||
path = p.GetString("TeighaFileConverter","")
|
||||
conv = p.GetInt("DWGConversion", 0)
|
||||
|
||||
if conv in [0,1]: # LibreDWG dxf2dwg/dwg2dxf
|
||||
if not path:
|
||||
path = "dxf2dwg"
|
||||
if path.endswith("dwg2dxf"):
|
||||
path = os.path.join(os.path.dirname,"dxf2dwg")
|
||||
try:
|
||||
proc = subprocess.Popen((path, dxffilename, "-y", "-o", dwgfilename))
|
||||
proc.communicate()
|
||||
return dwgfilename
|
||||
except Exception:
|
||||
if conv != 0:
|
||||
FCC.PrintError(translate("draft", "LibreDWG error") + "\n")
|
||||
|
||||
if conv in [0,2]: # ODA
|
||||
teigha = getTeighaConverter()
|
||||
if teigha:
|
||||
indir = os.path.dirname(dxffilename)
|
||||
outdir = os.path.dirname(dwgfilename)
|
||||
basename = os.path.basename(dxffilename)
|
||||
cmdline = [teigha, indir, outdir, "ACAD2000", "DWG", "0", "1", basename]
|
||||
if conv in [0, 1]: # LibreDWG
|
||||
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
|
||||
else:
|
||||
if conv != 0:
|
||||
FCC.PrintError(translate("draft", "ODA File Converter not found") + "\n")
|
||||
elif conv != 0:
|
||||
FCC.PrintError(translate("draft", "LibreDWG converter not found") + "\n")
|
||||
|
||||
if conv in [0,3]: # QCAD
|
||||
if not path:
|
||||
path = "dwg2dwg"
|
||||
try:
|
||||
proc = subprocess.Popen((path, "-o", dwgfilename, dxffilename))
|
||||
if conv in [0, 2]: # ODA
|
||||
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
|
||||
except Exception:
|
||||
if conv != 0:
|
||||
FCC.PrintError(translate("draft", "QCAD error") + "\n")
|
||||
else:
|
||||
FCC.PrintError(translate("draft", """No suitable DWG converter has been found.
|
||||
Please set one manually under menu Edit -> Preferences -> Import/Export -> DWG""") + "\n")
|
||||
elif conv != 0:
|
||||
FCC.PrintError(translate("draft", "ODA converter not found") + "\n")
|
||||
|
||||
if conv in [0, 3]: # QCAD
|
||||
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)) # cwd required for Windows
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user