C# based on AutoCAD2025 secondary development

C# based on AutoCAD2025 secondary development

1124633662
Observer Observer
567 Views
2 Replies
Message 1 of 3

C# based on AutoCAD2025 secondary development

1124633662
Observer
Observer

Use C# for AutoCAD secondary development, design their own dll plug-in, hope to complete the following functions: read dwg format files, and then the model space in the various blocks to block name save as pictures. But met a lot of problems, may also be the version of the problem, I hope someone can help solve. The code is as follows:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Runtime;
using System;
using System.IO;
using System.Linq;

namespace BlockExporter
{
public class ExportCommands
{
[CommandMethod("ExportBlocksToPNG")]
public static void ExportBlocksToPNG()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

string outputDir = GetOutputDirectory(ed);
if (string.IsNullOrEmpty(outputDir)) return;

using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

foreach (ObjectId btrId in bt)
{
BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
if (ShouldSkipBlock(btr)) continue;

try
{
ExportBlockAsImage(btr, db, outputDir, ed);
}
catch (Exception ex)
{
ed.WriteMessage($"\n错误:导出块 {btr.Name} 失败 - {ex.Message}");
}
}
tr.Commit();
}
}

private static string GetOutputDirectory(Editor ed)
{
var pso = new PromptStringOptions("\n请输入输出目录路径:")
{
AllowSpaces = true,
UseDefaultValue = true,
DefaultValue = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
};
return ed.GetString(pso).StringResult;
}

private static bool ShouldSkipBlock(BlockTableRecord btr)
{
return btr.IsLayout || btr.Name.StartsWith("*") ||
btr.IsFromExternalReference || btr.Name.Equals("_ADESK_BLOCK");
}

private static void ExportBlockAsImage(BlockTableRecord btr, Database db, string outputDir, Editor ed)
{
string layoutName = $"TEMP_{Guid.NewGuid():N}";
LayoutManager.Current.CreateLayout(layoutName);

using (var tr = db.TransactionManager.StartTransaction())
{
var layout = (Layout)tr.GetObject(
LayoutManager.Current.GetLayoutId(layoutName),
OpenMode.ForWrite);

try
{
// 创建并配置 PlotSettings
PlotSettings ps = new PlotSettings(layout.ModelType);
ps.CopyFrom(layout);
PlotSettingsValidator psv = PlotSettingsValidator.Current;

// 设置打印机和纸张
if (!SetPlotterConfiguration(psv, ps, "PublishToWeb PNG.pc3", ed))
return;

// 设置打印范围和类型
psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
SetPlotWindow(psv, ps, btr, db);

// 创建 PlotConfig 并设置输出参数
PlotConfig plotConfig = PlotConfig.CreateDefault();
plotConfig.ApplyFromPlotSettings(ps); // 从 PlotSettings 导入配置
plotConfig.PlotToFile = true; // 启用文件输出
plotConfig.OutputFileName = GetOutputFileName(btr, outputDir); // 设置文件名

// 创建 PlotInfo
PlotInfo plotInfo = new PlotInfo();
plotInfo.Layout = layout.ObjectId;

// 执行打印
ExecutePlot(db, plotInfo, plotConfig, ed);
}
finally
{
LayoutManager.Current.DeleteLayout(layoutName);
tr.Commit();
}
}
}

private static bool SetPlotterConfiguration(PlotSettingsValidator psv, PlotSettings ps, string configName, Editor ed)
{
try
{
psv.SetPlotConfigurationName(ps, configName, null);
return true;
}
catch
{
ed.WriteMessage($"\n错误:找不到打印机配置 {configName}");
return false;
}
}

private static void SetPlotWindow(PlotSettingsValidator psv, PlotSettings ps, BlockTableRecord btr, Database db)
{
using (var tr = db.TransactionManager.StartTransaction())
{
using (var tempRef = new BlockReference(Point3d.Origin, btr.ObjectId))
{
Extents3d extents = tempRef.GeometricExtents;
psv.SetPlotWindowArea(ps, new Extents2d(
new Point2d(extents.MinPoint.X, extents.MinPoint.Y),
new Point2d(extents.MaxPoint.X, extents.MaxPoint.Y)));
}
tr.Commit();
}
}

private static string GetOutputFileName(BlockTableRecord btr, string outputDir)
{
string safeName = Path.GetInvalidFileNameChars()
.Aggregate(btr.Name, (current, c) => current.Replace(c, '_'));
return Path.Combine(outputDir, $"{safeName}.png");
}

private static void ExecutePlot(Database db, PlotInfo plotInfo, PlotConfig plotConfig, Editor ed)
{
using (PlotEngine plotEngine = PlotFactory.CreatePublishEngine())
using (PlotProgressDialog progress = new PlotProgressDialog(false, 1, false))
{
plotEngine.BeginPlot(progress, null);
plotEngine.BeginDocument(plotInfo, db.Filename, null, 1, true, plotConfig.OutputFileName);

PlotPageInfo pageInfo = new PlotPageInfo();
plotEngine.BeginPage(pageInfo, plotInfo, true, null);
plotEngine.BeginGenerateGraphics(null);
plotEngine.EndGenerateGraphics(null);
plotEngine.EndPage(null);

plotEngine.EndDocument(null);
plotEngine.EndPlot(null);
}
ed.WriteMessage($"\n成功导出:{plotConfig.OutputFileName}");
}
}
}

0 Likes
568 Views
2 Replies
Replies (2)
Message 2 of 3

kerry_w_brown
Mentor
Mentor

Please post your code inside code tags

 

ie:

2025-02-15_16-46-45.PNG

From the description in your post you are expecting someone to write the application, is that correct ??

 

Regards,

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 3 of 3

norman.yuan
Mentor
Mentor

Besides posting code properly as @kerry_w_brown suggested, you should at least provide some details of "...a lot problems...", rather than test people's patience with many lines of code. Did you run into errors? Did you step through the code in debugging...

Norman Yuan

Drive CAD With Code

EESignature

0 Likes