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

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

Страницы: 1 ... 3 4 [5] 6 7 ... 10
41
Добрый день, Александр! Я пробовал вставить блок, в котором не было других динамических свойств, кроме таблицы свойств блока. Проблема сохранялась.
42
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. }

43
Добрый день.
Пробовали вставить в чертеж все варианты блока вручную. А после этого вставлять дополнительные блоки программно?
Проблема сохраняется?
44
Здравствуйте, Александр!
Благодарю за интерес к вопросу.
На самом деле, атрибуты инстансу блока я добавляю тоже программно и там где необходимо (изменение положения атрибутов в зависимости от видимости или выбора) _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. }
45
Я тоже пытался с динамическими блоками программно работать.
При изменении видимости не создаётся анонимный блок, поэтому и не видно ничего.

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

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


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

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

нужно проверить настройку плоттеров и листов. Возможно на стенде отсутствует выставляемый плоттер, либо формат лист у него задан по другому не 210*297 , а 297*210.
50
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 ... 3 4 [5] 6 7 ... 10