Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Ese от 28-05-2018, 18:05:40

Название: Как правильно задать толщину линии для слоя
Отправлено: Ese от 28-05-2018, 18:05:40
Пытаюсь создать слои, но почему-то все линии одной толщины:
Код - C# [Выбрать]
  1.   LineWeight [] kg_layerLineWeight = { LineWeight.LineWeight040, LineWeight.LineWeight020, LineWeight.LineWeight035, LineWeight.LineWeight025,
  2.                                                 LineWeight.LineWeight020, LineWeight.LineWeight030, LineWeight.LineWeight030, LineWeight.LineWeight020, LineWeight.LineWeight030,
  3.                                                 LineWeight.LineWeight015, LineWeight.LineWeight015};
  4.  
  5.             //Red
  6.  
  7.             Color color = Color.FromColorIndex(ColorMethod.ByAci, 3);
  8.  
  9. foreach (var name in kg_layerName)
  10.             {
  11.                 foreach (var lnWeight in kg_layerLineWeight)
  12.                 {
  13.                    CreateLayer(name,lnWeight, color);
  14.                 }    
  15.             }
  16.  
  17.  



 
Код - C# [Выбрать]
  1.  public static void CreateLayer(string sLayerName, LineWeight lineWeight, Color color)
  2.         {
  3.             // Get the current document and database
  4.             Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.             Database acCurDb = acDoc.Database;
  6.  
  7.  
  8.             // Start a transaction
  9.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  10.             {
  11.                 // Open the Layer table for read
  12.                 LayerTable acLyrTbl;
  13.                 acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,
  14.                                              OpenMode.ForRead) as LayerTable;
  15.                 //string  sLayerName= "Center";
  16.  
  17.                 LayerTableRecord acLyrTblRec;
  18.                 if (acLyrTbl.Has(sLayerName) == false)
  19.                 {
  20.                     acLyrTblRec = new LayerTableRecord();
  21.                     // Assign the layer the ACI color 1 and a name
  22.                     acLyrTblRec.Color = color;
  23.                     acLyrTblRec.LineWeight = lineWeight;
  24.                     acLyrTblRec.Name = sLayerName;
  25.  
  26.                     // Upgrade the Layer table for write
  27.                     acLyrTbl.UpgradeOpen();
  28.  
  29.                     // Append the new layer to the Layer table and the transaction
  30.                     acLyrTbl.Add(acLyrTblRec);
  31.                     acTrans.AddNewlyCreatedDBObject(acLyrTblRec, true);
  32.                 }
  33.                 else {
  34.                     acLyrTblRec = acTrans.GetObject(acLyrTbl[sLayerName],
  35.                                       OpenMode.ForRead) as LayerTableRecord;
  36.                 }
  37.  
  38.                 // Open the Layer table for read
  39.                 LinetypeTable acLinTbl;
  40.                 acLinTbl = acTrans.GetObject(acCurDb.LinetypeTableId,
  41.                                              OpenMode.ForRead) as LinetypeTable;
  42.  
  43.                 if (acLinTbl.Has("Center") == true)
  44.                 {
  45.                     // Upgrade the Layer Table Record for write
  46.                     acLyrTblRec.UpgradeOpen();
  47.  
  48.                     // Set the linetype for the layer
  49.                     acLyrTblRec.LinetypeObjectId = acLinTbl["Center"];
  50.                    
  51.                 }
  52.  
  53.                 // Save the changes and dispose of the transaction
  54.                 acTrans.Commit();
  55.             }
  56.         }
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Пекшев aka Modis от 28-05-2018, 18:08:45
Вы сначала задаете свойства для слоя, а потом только открываете его на запись. Т.е. вы не задаете свойства слою  :D
вру! не так прочитал ))
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: avc от 28-05-2018, 18:13:07
Не, там UpgradeOpen для таблицы слоев. Нормальный вроде код. Должен работать
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Пекшев aka Modis от 28-05-2018, 18:15:15
а где acLyrTbl.DowngradeOpen(); ?
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: avc от 28-05-2018, 18:19:52
там acLyrTblRec.UpgradeOpen() явно лишний, когда назначается тип линий. но все равно должно работать. DowngradeOpen не нужен.
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Пекшев aka Modis от 28-05-2018, 18:26:02
там acLyrTblRec.UpgradeOpen() явно лишний, когда назначается тип линий. но все равно должно работать. DowngradeOpen не нужен.
Там UpgradeOpen() не лишний, так как acLyrTbl открывается только для чтения. Но так как на мой взгляд тоже не совсем понятно почему не работает, то я выдвигаю предположения. И одно из них, что нужно вызвать DowngradeOpen()
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Пекшев aka Modis от 28-05-2018, 18:29:04
Вот части кода из моего плагина:
1. Метод который создает слои:
Код - C# [Выбрать]
  1. private static List<LayerTableRecord> GetMpStandardsLayers()
  2.         {
  3.             var layers = new List<LayerTableRecord>();
  4.             var acLyrTblRec = new LayerTableRecord
  5.             {
  6.                 Name = Language.GetItem(LangItem, "l1"),
  7.                 Color = Color.FromColorIndex(ColorMethod.ByAci, 7),
  8.                 LineWeight = LineWeight.LineWeight040
  9.             };
  10.             layers.Add(acLyrTblRec);
  11.             ///.............
  12.             acLyrTblRec = new LayerTableRecord
  13.             {
  14.                 Name = Language.GetItem(LangItem, "l9"),
  15.                 Color = Color.FromColorIndex(ColorMethod.ByColor, 253),
  16.                 LineWeight = LineWeight.ByLineWeightDefault
  17.             };
  18.             layers.Add(acLyrTblRec);
  19.             return layers;
  20.         }
2. Кусок из метода, который добавляет слои в чертеж:
Код - C# [Выбрать]
  1. foreach (var layer in layersList.Layers)
  2.                                     {
  3.                                         if (lyrTbl.Has(layer.Name)) continue;
  4.                                         lyrTbl.UpgradeOpen();
  5.                                         lyrTbl.Add(layer);
  6.                                         lyrTbl.DowngradeOpen();
  7.                                         tr.AddNewlyCreatedDBObject(layer, true);
  8.                                         lNames.Add(layer.Name);
  9.                                         if (showInfo) ed.WriteMessage("\n     - " + layer.Name);
  10.                                     }
Работает как часы.

Кстати, я бы еще посоветовал попробовать заблокировать документ using (doc.LockDocument())
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: avc от 28-05-2018, 18:38:49
Не, там какая-то другая проблема. Не с UpgradeOpen, и не с блокировкой. Без блокировки был бы exception. Без Downgrade у меня работает уйма разного кода. Просто Commit транзакции и порядок. Я б и ваш код сразу исправил - раз куча записей добавляется в таблицу, так зачем испытывать Автокад на прочность и открывать/закрывать запись на каждом цикле?
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Ривилис от 28-05-2018, 22:53:59
Ese
Точно не устанавливается вес линии или просто не установлено отображение веса линии?
LWDISPLAY  (https://knowledge.autodesk.com/ru/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2018/RUS/AutoCAD-Core/files/GUID-18CA6E8F-0008-402E-9F6B-2F9ED8A0A7DD-htm.html)
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Ese от 29-05-2018, 10:04:09
Всем спасибо, ошибка была в двойном foreach. 

1) Александр Пекшев aka Modis, спасибо за код. А в каком месте ставить (doc.LockDocument())?

2)
Я б и ваш код сразу исправил - раз куча записей добавляется в таблицу, так зачем испытывать Автокад на прочность и открывать/закрывать запись на каждом цикле?

То есть документ или транзакцию передавать как объект? или как ссылку на объект? Я не передаю, потому что еще не разобрался насколько это безопасно и как правильно это делать.

 
3)
Точно не устанавливается вес линии или просто не установлено отображение веса линии?
LWDISPLAY
Устанавливалась одна толщина на всех слоях.  Спасибо, буду иметь ввиду по LWDISPLAY.

--------------------------оффтоп-----------------------------

4) Подскажите как узнать какие стандартные типы линий доступны? И где про них почитать можно.

5)  Классы и методы плагина(Помеченные аттрибутом COMMAND) должны быть статические или все равно?  В примерах от автодеска часто статические.


(Почему-то имена сбились на цитировании, извиняюсь, это глюк форума)
 
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Пекшев aka Modis от 29-05-2018, 10:14:36
1) Александр Пекшев aka Modis, спасибо за код. А в каком месте ставить (doc.LockDocument())?
Перед стартом транзакции
То есть документ или транзакцию передавать как объект? или как ссылку на объект? Я не передаю, потому что еще не разобрался насколько это безопасно и как правильно это делать.
avc говорил совсем про другое. В моем коде таблица слоев открывается на запись каждый раз перед добавлением слоя и закрывается после. Я мог всего этого не делать, открыв её на запись один раз. Вы тоже можете переделать - открыть таблицу слоев один раз и сразу на запись, а потом только запускать ваши foreach'ы. При этом переменную, хранящую ссылку на транзакцию, нужно будет передавать в метод CreateLayer
4) Подскажите как узнать какие стандартные типы линий доступны? И где про них почитать можно.
Прям в справке (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-NET/files/GUID-81423588-A182-4511-B9D3-115014C96BCE-htm.html) и читайте. Типы линий в документе (чистом новом) отсутствуют и их нужно подгружать из файла типов линии. По умолчанию в поставке автокада вам доступно два таких файла - acad.lin и acadiso.lin. Их уже вручную можете посмотреть
5)  Классы и методы плагина(Помеченные аттрибутом COMMAND) должны быть статические или все равно?  В примерах от автодеска часто статические.
Статический класс нельзя создать как экземпляр (т.е. нельзя написать MyClass class = new MyClass()). Что логично и не должно происходить с классом команды. Поэтому от греха подальше делайте его статическим. А вообще пофиг - если это только ваш код и вы знаете, что не будете пытаться создать экземпляр класса - то можете не делать статическим
Почему-то имена сбились на цитировании, извиняюсь, это глюк форума)
А вот тут враки - форум отлично работает и никогда не глючил!
Название: Re: Как правильно задать толщину линии для слоя
Отправлено: Александр Ривилис от 29-05-2018, 10:18:47
4) Подскажите как узнать какие стандартные типы линий доступны? И где про них почитать можно.
Стандартный тип линии только один: Continuous
Все остальные могут быть, а могут и не быть... Почитать можно здесь: https://knowledge.autodesk.com/ru/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/RUS/AutoCAD-Core/files/GUID-20B4D4B3-1220-426A-847B-5BBE36EC6FDF-htm.html