AutoCAD C#

[AutoCAD C#]오토캐드에서 블럭(Block)들을 수량과 레이어(Layer) 구분하여 출력하기

데브프로그라 2024. 2. 27. 20:19
반응형

AutoCAD에서 Block관리가 중요합니다.
때론 BOM 물량산출을 하고, Block들을 전체 변환하기도 합니다.
아래의 코드는 Block들을 선택하여 수량과 레이어를 정리하여 출력하는 코드입니다.

AutoCAD에서 이 코드를 사용하려면 다음 단계로 실행해 보세요.
1. Visual Studio에서 C# 프로젝트를 만듭니다.
    참조에 accoremgd.dll, acdbmgd.dll, AcDbMgd.dll, AcMgd.dll을 추가합니다.
2. 아래의 코드를 복사하여 프로젝트에 붙여넣습니다.
     빌드하여 .dll 파일을 생성합니다.
3. AutoCAD에서 NETLOAD 명령을 실행하여 .dll 파일을 로드합니다.
4. listBlock 명령을 실행합니다.
5. AutoCAD에서 Block의 출력형식 확인합니다.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BlockQuantityAndLayerReport
{
    public class BlockQuantityAndLayerReportCommands
    {
        [CommandMethod("listBlock)]
        public void BlockQuantityAndLayerReport()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // 블록 선택
            PromptSelectionOptions selOpts = new PromptSelectionOptions();
            selOpts.MessageForAdding = "\nSelect blocks: ";

            PromptSelectionResult selRes = ed.GetSelection(selOpts);
            if (selRes.Status != PromptStatus.OK) return;

            SelectionSet selSet = selRes.Value;
            ObjectId[] objIds = selSet.GetObjectIds();

            Dictionary<string, int> blockCounts = new Dictionary<string, int>();
            Dictionary<string, List<string>> blockLayers = new Dictionary<string, List<string>>();

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                foreach (ObjectId objId in objIds)
                {
                    Entity ent = trans.GetObject(objId, OpenMode.ForRead) as Entity;
                    if (ent == null || !ent.GetType().Equals(typeof(BlockReference))) continue;

                    BlockReference blkRef = (BlockReference)ent;

                    // 블록 이름
                    string blockName = blkRef.Name;

                    // 수량 추가
                    if (blockCounts.ContainsKey(blockName))
                    {
                        blockCounts[blockName]++;
                    }
                    else
                    {
                        blockCounts.Add(blockName, 1);
                    }

                    // 레이어 추가
                    string layerName = blkRef.Layer;
                    if (blockLayers.ContainsKey(blockName))
                    {
                        if (!blockLayers[blockName].Contains(layerName))
                        {
                            blockLayers[blockName].Add(layerName);
                        }
                    }
                    else
                    {
                        blockLayers.Add(blockName, new List<string> { layerName });
                    }
                }
                trans.Commit();
            }

            // 결과 출력
            ed.WriteMessage("\nBlock Quantity Report:");

            foreach (var kvp in blockCounts)
            {
                string blockName = kvp.Key;
                int count = kvp.Value;

                ed.WriteMessage($"\n{blockName}: {count}개");

                if (blockLayers.ContainsKey(blockName))
                {
                    List<string> layers = blockLayers[blockName];
                    string layersStr = string.Join(", ", layers);
                    ed.WriteMessage($" - Layers: {layersStr}");
                }
            }
        }
    }
}

결과 화면:

반응형