DeepCAD是一款使用Lazarus/FreePascal开发的国产开源二维CAD绘图软件,具有强大的二维绘图功能。
LibreDWG 是一个用于读写 DWG 文件的自由 C 语言库。该程序是 GNU 项目的一部分,在 GNU 的主持下发布。它采用 GNU 通用公共许可证第 3 版(或根据您的选择,任何更高版本)的条款进行许可。
DWG 是一种文件格式,创建于 70 年代,用于新兴的 CAD 应用程序。目前,它是 AutoCAD(由 AutoDesk 开发的专有 CAD 程序)的原生文件格式。
LibreDWG 是 LibDWG 的一个分支,原因是后者使用了世界语,这对于一个旨在吸引大量贡献者的自由软件项目来说并非最佳策略。LibreDWG 使用英语编写。
-
dwg2dxf -- 将 DWG 转换为 DXF(ASCII 或二进制,最小或完整),可选地转换为不同版本。覆盖率约为 90%。
-
dxf2dwg -- 将 ASCII 或二进制 DXF 转换为 DWG(目前仅支持 r2000)。覆盖率约为 80%。
以下是DeepCAD的官网是:https://www.deepgantt.com/ 开发的转换单元代码:
Delphi
unit DWGDxfConvert;
{$I Defs.INC}
interface
uses
Windows, Classes, System.IOUtils;
function DirDxfToDwg(const AInputDir, AOutputDir: string; AOutVersion: TCADVersion = ACAD2000; ARecurseInputDir: Boolean = False): Boolean; overload;
function DirDwgToDxf(const AInputDir, AOutputDir: string; AOutVersion: TCADVersion = ACAD2000; ARecurseInputDir: Boolean = False): Boolean; overload;
function DxfToDwg(const AInputFile, AOutputFile: string; var AErrorMsg: string; AOutVersion: TCADVersion = ACAD2004): Boolean; overload;
function DwgToDxf(const AInputFile, AOutputFile: string; var AErrorMsg: string; AOutVersion: TCADVersion = ACAD2000): Boolean; overload;
implementation
function RunLibreDWGCommand_libredwg(const AExeName, AInputFile, AOutputFile: string; AVersion: string; var AErrorMsg: string): Boolean;
var
CommandLine: string;
WorkingDir: string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
ExitCode: DWORD;
begin
Result := False;
AErrorMsg := '';
// 检查转换工具是否存在
if not FileExists(AExeName) then
begin
AErrorMsg := '找不到转换工具: ' + AExeName;
Exit;
end;
// 检查源文件是否存在
if not FileExists(AInputFile) then
begin
AErrorMsg := '找不到输入文件: ' + AInputFile;
Exit;
end;
// 构建命令行参数
// 注意:根据LibreDWG文档,有些命令可能需要指定输出文件,有些则自动生成
if SameText(ExtractFileName(AExeName), 'dwg2dxf.exe') then
CommandLine := Format('"%s" -y=%s "%s"', [AExeName, AVersion, AInputFile])
else if SameText(ExtractFileName(AExeName), 'dxf2dwg.exe') then
CommandLine := Format('"%s" -y=%s "%s"', [AExeName, AVersion, AInputFile])
else
// 默认命令格式(可以根据需要添加更多命令支持)
CommandLine := Format('"%s" -y=%s "%s"', [AExeName, AVersion, AInputFile]);
// 设置工作目录(通常是转换工具所在目录)
WorkingDir := ExtractFilePath(AExeName);
// 初始化启动信息结构
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_HIDE; // 隐藏命令行窗口
// 创建进程
if CreateProcess(nil, PChar(CommandLine), nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(WorkingDir),
StartupInfo, ProcessInfo) then
begin
try
// 等待进程结束
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
// 获取退出代码
if GetExitCodeProcess(ProcessInfo.hProcess, ExitCode) then
begin
Result := (ExitCode = 0); // 通常返回0表示成功
if not Result then
AErrorMsg := Format('转换工具返回错误代码: %d', [ExitCode]);
end
else
begin
AErrorMsg := '无法获取转换工具的退出代码';
end;
finally
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
end
else
begin
AErrorMsg := Format('无法启动转换进程。错误代码: %d', [GetLastError]);
end;
// 检查输出文件是否存在(如果指定了输出文件)
if Result and (AOutputFile <> '') and (not FileExists(AOutputFile)) then
begin
Result := False;
AErrorMsg := '转换完成,但找不到输出文件: ' + AOutputFile;
end;
end;
function DirDxfToDwg(const AInputDir, AOutputDir: string; AOutVersion: TCADVersion = ACAD2000; ARecurseInputDir: Boolean = False): Boolean;
var
LSearchRec: TSearchRec;
LInputFile, LOutputFile: string;
LErrorMsg: string;
begin
Result := True;
if FindFirst(AInputDir + '\*.dxf', faAnyFile, LSearchRec) = 0 then
begin
repeat
LInputFile := AInputDir + '\' + LSearchRec.Name;
LOutputFile := AOutputDir + '\' + ChangeFileExt(LSearchRec.Name, '.dwg');
if not RunLibreDWGCommand_libredwg('dxf2dwg.exe', LInputFile, LOutputFile, CADVerToLibreDWGVersion(AOutVersion), LErrorMsg) then
begin
Result := False;
Break;
end;
until FindNext(LSearchRec) <> 0;
FindClose(LSearchRec);
end;
end;
function DirDwgToDxf(const AInputDir, AOutputDir: string; AOutVersion: TCADVersion = ACAD2000; ARecurseInputDir: Boolean = False): Boolean;
var
LSearchRec: TSearchRec;
LInputFile, LOutputFile: string;
LErrorMsg: string;
begin
Result := True;
if FindFirst(AInputDir + '\*.dwg', faAnyFile, LSearchRec) = 0 then
begin
repeat
LInputFile := AInputDir + '\' + LSearchRec.Name;
LOutputFile := AOutputDir + '\' + ChangeFileExt(LSearchRec.Name, '.dxf');
if not RunLibreDWGCommand_libredwg('dwg2dxf.exe', LInputFile, LOutputFile, CADVerToLibreDWGVersion(AOutVersion), LErrorMsg) then
begin
Result := False;
Break;
end;
until FindNext(LSearchRec) <> 0;
FindClose(LSearchRec);
end;
end;
type
TUdConvFileKind = (cfkDxf2Dwg, cfkDwg2Dxf);
function FileConvert(const AInputFile, AOutputFile: string; AConvKind: TUdConvFileKind; var AErrorMsg: string; AOutVersion: TCADVersion = ACAD2000): Boolean;
var
LOk: Boolean;
LExeName: string;
begin
Result := False;
if not FileExists(AInputFile) then
begin
AErrorMsg := QuotedStr(AInputFile) + '不存在';
Exit;
end;
LOk := True;
case AConvKind of
cfkDxf2Dwg:
begin
if UpperCase(SysUtils.ExtractFileExt(AInputFile)) <> '.DXF' then
LOk := False;
LExeName := SysUtils.ExtractFilePath(Application.ExeName) + 'LibreDWG64\'+'dxf2dwg.exe';
end;
cfkDwg2Dxf:
begin
if UpperCase(SysUtils.ExtractFileExt(AInputFile)) <> '.DWG' then
LOk := False;
LExeName :=SysUtils.ExtractFilePath(Application.ExeName) + 'LibreDWG64\'+ 'dwg2dxf.exe';
end;
end;
if not LOk then
begin
AErrorMsg := QuotedStr(AInputFile) + '文件格式不正确';
Exit;
end;
Result := RunLibreDWGCommand_libredwg(LExeName, AInputFile, AOutputFile, CADVerToLibreDWGVersion(AOutVersion), AErrorMsg);
end;
function DxfToDwg(const AInputFile, AOutputFile: string; var AErrorMsg: string; AOutVersion: TCADVersion = ACAD2004): Boolean;
begin
Result := FileConvert(AInputFile, AOutputFile, cfkDxf2Dwg, AErrorMsg, AOutVersion);
end;
function DwgToDxf(const AInputFile, AOutputFile: string; var AErrorMsg: string; AOutVersion: TCADVersion = ACAD2000): Boolean;
begin
Result := FileConvert(AInputFile, AOutputFile, cfkDwg2Dxf, AErrorMsg, AOutVersion);
end;
end.