Последние сообщения

Последние сообщения

Страницы: [1] 2 3 ... 10
1
Добрый день, Александр! Я пробовал вставить блок, в котором не было других динамических свойств, кроме таблицы свойств блока. Проблема сохранялась.
2
AutoCAD .NET API / Вставка листов из стороннего чертежа
« Последний ответ от Atomohod 11-10-2025, 19:54:23 »
Здравствуйте.
Пишу код для вставки листов (пространств) из чертежа на диске в текущий. В итоге работы метода получаю фатал. Не знаю как исправить код. Кто-нибудь может подсказать где у меня ошибка? Акад 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. }

3
Добрый день.
Пробовали вставить в чертеж все варианты блока вручную. А после этого вставлять дополнительные блоки программно?
Проблема сохраняется?
4
Здравствуйте, Александр!
Благодарю за интерес к вопросу.
На самом деле, атрибуты инстансу блока я добавляю тоже программно и там где необходимо (изменение положения атрибутов в зависимости от видимости или выбора) _attsync для блока применяю. Моя проблема повторится даже если у динамического блока не будет других параметров, только таблица свойств блока.
По всей видимости, зависимости не вычисляются в автокаде при программном изменении значения свойства из таблицы свойств.
Поэтому я загугли как организуется доступ к таблице свойств и пока что через код стал записывать значения в атрибуты в зависимости от того, что выбрано для поля Lang в соответствие с таблицей:
Код - C# [Выбрать]
  1. public static void SetPropertyFromPropertyTable(Transaction tr, BlockReference blockRef, string value, string propertyName = "Lang")
  2. {
  3.     if (blockRef == null) return;
  4.  
  5.     if (value == null) return;
  6.  
  7.     try
  8.     {
  9.         var blockDef = tr.GetObject(blockRef.DynamicBlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  10.         DBDictionary extDic = tr.GetObject(blockDef.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
  11.         // Открываем словарь ENHANCEDBLOCK  
  12.         Autodesk.AutoCAD.Internal.DatabaseServices.EvalGraph graph = tr.GetObject(extDic.GetAt("ACAD_ENHANCEDBLOCK"), OpenMode.ForRead) as EvalGraph;
  13.         var nodeIds = graph.GetAllNodes();
  14.         foreach (uint nodeId in nodeIds)
  15.         {
  16.             DBObject node = graph.GetNode(nodeId, OpenMode.ForRead, tr);
  17.             if (!(node is BlockPropertiesTable)) continue;
  18.  
  19.             var table = node as BlockPropertiesTable;
  20.  
  21.             Dictionary<string, string> props = new Dictionary<string, string>();
  22.             for (int i = 0; i < table.Rows.Count; i++)
  23.             {
  24.                 var par = table.Columns[0].Parameter;
  25.                 if (par == null)
  26.                     break;
  27.  
  28.                 if (par.Name != propertyName)
  29.                     break;
  30.  
  31.                 var tapedValue = (TypedValue)table.Rows[i][0].AsArray().GetValue(0); //RU-EN
  32.                 if (tapedValue.TypeCode == (int)DxfCode.Text)
  33.                 {
  34.                     if (value != (string)tapedValue.Value)
  35.                     {
  36.                         continue;
  37.                     }
  38.                 }
  39.  
  40.                 for (int j = 1; j < table.Columns.Count; j++)
  41.                 {
  42.                     var lableAttrName = table.Columns[j].Parameter.Name;
  43.  
  44.                     var lableValTV = (TypedValue)table.Rows[i][j].AsArray().GetValue(0);
  45.                     if (lableValTV.TypeCode == (int)DxfCode.Text)
  46.                     {
  47.                         var lableVal = (string)lableValTV.Value;
  48.                         props.Add(lableAttrName, lableVal);
  49.                     }
  50.                 }
  51.             }
  52.             SetParam(tr, blockRef, props);
  53.             break;
  54.         }
  55.     }
  56.     catch(System.Exception ex)
  57.     {
  58.         //log
  59.     }
  60. }
5
Я тоже пытался с динамическими блоками программно работать.
При изменении видимости не создаётся анонимный блок, поэтому и не видно ничего.

Как я сделал.
При первой вставке блока вставляю все варианты видимостей (у Вас 2 получается)
и выполняю _attsync для блока, при этом создаются анонимные блоки для всех видимостей блока на чертеже.
Потом удаляю вставки, а анонимные блоки остаются.
При новой вставке и выборе видимости будет использован готовый анонимный блок.
6
Всем здравствуйте!
Я создал динамический блок. В котором задал некоторые текстовые поля через аттрибут. Для возможности подменять значение текста на его перевод на другом языке.
Внутри блока создал таблицу свойств, в котором задал соответствие языку:

Если такой блок вставляю руками и ручкой меняю значения этого свойства, то всё ок работает:


Однако, когда я вставляю этот же блок кодом, блок вставляется с пустым текстовым полем. Аттрибут не отображает какой-либо текст.
Когда я взгляну на ручку - оно отображает корректное выставленное кодом значение.
Но текст на блоке появляется только после повторного выбора значения через ручку.

Можете подсказать куда копать?
7
1. Возможность добавлять свойства группе листов.
2. Возможность присоединять файлы doc и xls с последующим помещением их в формируемый комплект.
8
AutoCAD .NET API / Re: Не меняется ориентация листа
« Последний ответ от brook 23-09-2025, 11:06:55 »
на самом деле я неправильно сформулировала. один лист формируется с  настроенным поворотом. но все последующие листы будто наследуют этот поворот. у меня чаще всего два листа в одной ориентации и два  в другой. но может быть по-разному. и вот какой ему первый задался, так он остальные и поворачивает, невзирая на текущие настройки. Причём это всё внутри отдельной команды. то есть транзакция точно закрывается и никак они не связаны друг с другом. может что-то попытаться сбросить между командами?
9
AutoCAD .NET API / Re: Не меняется ориентация листа
« Последний ответ от Привалов Дмитрий 19-09-2025, 13:31:21 »
пока на одном стенде не поставили с другого дистрибутива acad, и он стал на 90 градусов всё переворачивать. раньше явно не задавали поворот вообще, он как-то сам вставал. сейчас пытаюсь задать явно, и не работает

нужно проверить настройку плоттеров и листов. Возможно на стенде отсутствует выставляемый плоттер, либо формат лист у него задан по другому не 210*297 , а 297*210.
10
AutoCAD .NET API / Re: Не меняется ориентация листа
« Последний ответ от pavka_97 19-09-2025, 12:15:17 »
Свои плагины я использовал в 13,16,21,24 и под них нередко приходилось редактировать что-то (появлялись новые методы, библиотеки, да и глюки). В консоли тоже не все работает. Если напрямую (не из консоли запускать), работает? Лучше конечно задавать все в явном виде и в порядке как в руководстве или в примерах на форуме. Если раньше работало, а теперь нет, проверьте соответствие библиотек, фреймворков, версий автокада друг другу. Может дистрибутив новый, который вы ставили последним, кривой. Попробуйте местами поменять PlotRotation.Degrees000 и PlotRotation.Degrees090 (если глюк), дополнительно "пошевелить"/ регенерировать лист, например отцентровать psv.SetPlotCentered(ps, true).
Страницы: [1] 2 3 ... 10