Вставка листов из стороннего чертежа

Автор Тема: Вставка листов из стороннего чертежа  (Прочитано 142 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн AtomohodАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 463
  • Карма: 1
Здравствуйте.
Пишу код для вставки листов (пространств) из чертежа на диске в текущий. В итоге работы метода получаю фатал. Не знаю как исправить код. Кто-нибудь может подсказать где у меня ошибка? Акад 2019
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4.  
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.Geometry;
  9. using Autodesk.AutoCAD.Runtime;
  10.  
  11. public class Commands
  12. {
  13.     /// <summary>
  14.     /// Copies all layouts from a specified source DWG file into the current drawing,
  15.     /// including all objects within each layout while preserving their positions.
  16.     /// If a layout name already exists in the current drawing, a suffix is appended to avoid conflicts.
  17.     /// </summary>
  18.     [CommandMethod("22CopyLayoutsFromDwg")]
  19.     public void CopyLayoutsFromDwg()
  20.     {
  21.         Document currentDocument = Application.DocumentManager.MdiActiveDocument;
  22.         Database destinationDatabase = currentDocument.Database;
  23.         Editor editor = currentDocument.Editor;
  24.         // Prompt the user for the source DWG file using a file dialog
  25.         PromptOpenFileOptions options = new PromptOpenFileOptions("\nSelect the source DWG file:");
  26.         options.Filter = "Drawing files (*.dwg)|*.dwg";
  27.         options.PreferCommandLine = false;
  28.         PromptFileNameResult promptResult = editor.GetFileNameForOpen(options);
  29.         if (promptResult.Status != PromptStatus.OK)
  30.         {
  31.             return;
  32.         }
  33.         string sourceFilePath = promptResult.StringResult;
  34.         // Validate the file existence
  35.         if (!File.Exists(sourceFilePath))
  36.         {
  37.             editor.WriteMessage("\nThe specified file does not exist.");
  38.             return;
  39.         }
  40.         // Open the source database in read-only mode
  41.         using (Database sourceDatabase = new Database(false, true))
  42.         {
  43.             sourceDatabase.ReadDwgFile(sourceFilePath, FileOpenMode.OpenForReadAndAllShare, true, null);
  44.             sourceDatabase.CloseInput(true);
  45.             // Start transactions for both databases
  46.             using (Transaction sourceTx = sourceDatabase.TransactionManager.StartTransaction())
  47.             using (Transaction destTx = destinationDatabase.TransactionManager.StartTransaction())
  48.             {
  49.                 // Access layout dictionaries
  50.                 DBDictionary sourceLayouts = (DBDictionary)sourceTx.GetObject(sourceDatabase.LayoutDictionaryId, OpenMode.ForRead);
  51.                 DBDictionary destinationLayouts = (DBDictionary)destTx.GetObject(destinationDatabase.LayoutDictionaryId, OpenMode.ForWrite);
  52.                 LayoutManager layoutManager = LayoutManager.Current;
  53.                 foreach (DBDictionaryEntry layoutEntry in sourceLayouts)
  54.                 {
  55.                     // Skip the Model layout
  56.                     if (layoutEntry.Key == "Model")
  57.                     {
  58.                         continue;
  59.                     }
  60.                     Layout sourceLayout = (Layout)sourceTx.GetObject(layoutEntry.Value, OpenMode.ForRead);
  61.                     // Determine a unique name for the new layout
  62.                     string newLayoutName = layoutEntry.Key;
  63.                     int suffix = 1;
  64.                     while (destinationLayouts.Contains(newLayoutName))
  65.                     {
  66.                         newLayoutName = layoutEntry.Key + "_" + suffix++;
  67.                     }
  68.                     // Create the new layout using LayoutManager
  69.                     ObjectId destinationLayoutId = layoutManager.CreateLayout(newLayoutName);
  70.                     // Open the new layout for write
  71.                     Layout destinationLayout = (Layout)destTx.GetObject(destinationLayoutId, OpenMode.ForWrite);
  72.                     // Copy properties from source layout
  73.                     destinationLayout.CopyFrom(sourceLayout);
  74.                     // Get source and destination block table records
  75.                     BlockTableRecord sourceBlockTableRecord = (BlockTableRecord)sourceTx.GetObject(sourceLayout.BlockTableRecordId, OpenMode.ForRead);
  76.                     BlockTableRecord destinationBlockTableRecord = (BlockTableRecord)destTx.GetObject(destinationLayout.BlockTableRecordId, OpenMode.ForWrite);
  77.                     // Collect objects to clone and track viewports for freeze settings
  78.                     ObjectIdCollection objectsToClone = new ObjectIdCollection();
  79.                     Dictionary<ObjectId, List<string>> viewportFrozenLayers = new Dictionary<ObjectId, List<string>>();
  80.                     foreach (ObjectId objectId in sourceBlockTableRecord)
  81.                     {
  82.                         using (DBObject obj = sourceTx.GetObject(objectId, OpenMode.ForRead))
  83.                         {
  84.                             if (obj is Viewport viewport && viewport.Number == 1)
  85.                             {
  86.                                 continue; // Skip the paper space viewport to avoid duplication and corruption
  87.                             }
  88.                             objectsToClone.Add(objectId);
  89.                             // Capture frozen layers only for non-paper space viewports
  90.                             if (obj is Viewport vp && vp.Number != 1)
  91.                             {
  92.                                 List<string> frozenLayerNames = new List<string>();
  93.                                 ObjectIdCollection frozenLayerIds = vp.GetFrozenLayers();
  94.                                 foreach (ObjectId layerId in frozenLayerIds)
  95.                                 {
  96.                                     LayerTableRecord layer = (LayerTableRecord)sourceTx.GetObject(layerId, OpenMode.ForRead);
  97.                                     frozenLayerNames.Add(layer.Name);
  98.                                 }
  99.                                 viewportFrozenLayers.Add(objectId, frozenLayerNames);
  100.                             }
  101.                         }
  102.                     }
  103.                     if (objectsToClone.Count > 0)
  104.                     {
  105.                         IdMapping idMapping = new IdMapping();
  106.                         destinationDatabase.WblockCloneObjects(objectsToClone, destinationBlockTableRecord.ObjectId, idMapping, DuplicateRecordCloning.Replace, false);
  107.                         // Reapply frozen layers to cloned viewports
  108.                         LayerTable lt = (LayerTable)destTx.GetObject(destinationDatabase.LayerTableId, OpenMode.ForRead);
  109.                         foreach (var kvp in viewportFrozenLayers)
  110.                         {
  111.                             ObjectId sourceVpId = kvp.Key;
  112.                             List<string> frozenNames = kvp.Value;
  113.                             IdPair pair = idMapping.Lookup(sourceVpId);
  114.                             if (pair != null)
  115.                             {
  116.                                 ObjectId destVpId = pair.Value;
  117.                                 Viewport destViewport = (Viewport)destTx.GetObject(destVpId, OpenMode.ForWrite);
  118.                                 ObjectIdCollection destLayerIds = new ObjectIdCollection();
  119.                                 foreach (ObjectId layerId in lt)
  120.                                 {
  121.                                     LayerTableRecord ltr = (LayerTableRecord)destTx.GetObject(layerId, OpenMode.ForRead);
  122.                                     if (frozenNames.Contains(ltr.Name))
  123.                                     {
  124.                                         destLayerIds.Add(layerId);
  125.                                     }
  126.                                 }
  127.                                 destViewport.FreezeLayersInViewport(destLayerIds.GetEnumerator());
  128.                             }
  129.                         }
  130.                     }
  131.                 }
  132.                 destTx.Commit();
  133.                 // sourceTx.Commit() not needed as no writes, dispose will handle
  134.             }
  135.         }
  136.         editor.WriteMessage("\nLayouts copied successfully.");
  137.     }
  138. }