Цвет штриховки для полигона

Автор Тема: Цвет штриховки для полигона  (Прочитано 10195 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Возникла проблема с определением цвета штриховки. MPolygon.PatternColor бросает исключение. на 2013 год есть сообщение от тех. поддержки (http://forums.autodesk.com/t5/autocad-map-3d-developer/c-modify-color-of-hach-in-mpolygon/td-p/3741933) о том что они в курсе. Однако в 2014 автокаде проблема всё ещё есть. Есть ли другие пути определения цвета штриховки MPlolygon'а?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #1 : 05-12-2014, 09:53:52 »
Однако в 2014 автокаде проблема всё ещё есть.
Сделай пожалуйста пример файл с одним МПолигоном, цвет которого ты пытаешься определить и код при помощи которого ты это делаешь (полный). Я или подскажу как выйти из ситуации или, если не получится, отправлю этот вопрос в ADN DevHelp.
Пока (не имея твоего кода) я вижу только одну возможность - использовать P/Invoke для AcDbMPolygon::patternColor, если конечно и в нём не возникает исключение.

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Цвет штриховки для полигона
« Ответ #2 : 05-12-2014, 10:10:48 »
Спасибо Александр. Вот код, с помощью которого пытаюсь получить цвет штриховки.
Код - C# [Выбрать]
  1.   [CommandMethod("GetPatternColor")]
  2.   public static void GetPatternColor()
  3.   {
  4.    var doc = Application.DocumentManager.MdiActiveDocument;
  5.    var ed = doc.Editor;
  6.  
  7.    var selection = ed.GetSelection();
  8.    if (selection.Status != PromptStatus.OK)
  9.     return;
  10.  
  11.    var objId = selection.Value[0].ObjectId;
  12.  
  13.    using (var trans = doc.Database.TransactionManager.StartTransaction())
  14.    {
  15.     var polygon = trans.GetObject(objId, OpenMode.ForRead) as MPolygon;
  16.  
  17.     if (polygon == null)
  18.      return;
  19.  
  20.     try
  21.     {
  22.      var color = polygon.PatternColor;
  23.      var colorString = string.Format("{0},{1},{2}", color.ColorValue.R, color.ColorValue.G, color.ColorValue.B);
  24.      ed.WriteMessage("Цвет штриховки полигона: {0}\n", colorString);
  25.     }
  26.     catch (Exception ex)
  27.     {
  28.      ed.WriteMessage("Исключение при попытке получить цвет штриховки: " + ex);
  29.     }
  30.    }
  31.   }
  32.  
« Последнее редактирование: 05-12-2014, 10:50:00 от Александр Ривилис »

Отмечено как Решение MikhailTAP 10-12-2014, 07:46:12

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #3 : 06-12-2014, 00:11:45 »
Я начал с проверки, а работает ли аналогичный код в ObjectARX 2014:
Код - C++ [Выбрать]
  1.   // - MPolygonTest.MPTEST command (do not rename)
  2.   static void MPolygonTestMPTEST(void)
  3.   {
  4.     ads_name en; ads_point pt;
  5.     if (acedEntSel(_T("\nВыбрите МПолигон (Select MPolygon): "), en, pt) == RTNORM) {
  6.       AcDbObjectId eId; acdbGetObjectId(eId,en);
  7.       AcDbObjectPointer<AcDbMPolygon> pMPoly(eId, AcDb::kForRead);
  8.       if (pMPoly.openStatus() == Acad::eOk) {
  9.         AcCmColor cm = pMPoly->patternColor();
  10.         acutPrintf(_T("\nPattentColor: R=(%d) G=(%d) B=(%d)"), cm.red(), cm.green(), cm.blue());
  11.       } else if (pMPoly.openStatus() == Acad::eWrongObjectType) {
  12.         acutPrintf(_T("\nЭто не МПолигон (Not MPolygon selected)."));
  13.         return;
  14.       }
  15.     }
  16.   }
Код работает. Никаких проблем нет:
Цитировать
Выбрите МПолигон (Select MPolygon):
PattentColor: R=(176) G=(88) B=(0)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #4 : 06-12-2014, 02:06:35 »
Ну а вот так выглядит P/Invoke для AcDbMPolygon::patternColor:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Colors;
  8. using System.Runtime.InteropServices;
  9.  
  10. [assembly: CommandClass(typeof(MpolygonTest.MyCommands))]
  11.  
  12. namespace MpolygonTest
  13. {
  14.   public class MyCommands
  15.   {
  16.     // Зависит от версии AutoCAD и разрядности. В данном случае это для AutoCAD 2013-2014 и x64
  17.     [DllImport("AcMPolygonObj19.dbx", CallingConvention = CallingConvention.ThisCall,
  18.        EntryPoint = "?patternColor@AcDbMPolygon@@UEBA?AVAcCmColor@@XZ")]
  19.     // Для AutoCAD 2013-2014 и x86
  20.     // [DllImport("AcMPolygonObj19.dbx", CallingConvention = CallingConvention.ThisCall,
  21.     //   EntryPoint = "?patternColor@AcDbMPolygon@@UBE?AVAcCmColor@@XZ")]
  22.     extern static private System.IntPtr getPatternColorOfMPolygon(System.IntPtr Mpolygon);
  23.  
  24.     [CommandMethod("GetPatternColor")]
  25.     public static void GetPatternColor()
  26.     {
  27.       Document doc = Application.DocumentManager.MdiActiveDocument;
  28.       Editor ed = doc.Editor;
  29.       // Не обязательно, но желательно
  30.       SystemObjects.DynamicLinker.LoadModule("AcMPolygonObj" + Application.Version.Major + ".dbx", false, false);
  31.       PromptSelectionResult selection = ed.GetSelection();
  32.       if (selection.Status != PromptStatus.OK)
  33.         return;
  34.       ObjectId objId = selection.Value[0].ObjectId;
  35.       using (var trans = doc.Database.TransactionManager.StartTransaction())
  36.       {
  37.         var polygon = trans.GetObject(objId, OpenMode.ForRead) as MPolygon;
  38.  
  39.         if (polygon == null)
  40.           return;
  41.  
  42.         try
  43.         {
  44.           System.IntPtr clptr = getPatternColorOfMPolygon(polygon.UnmanagedObject);
  45.           Autodesk.AutoCAD.Colors.Color cl =
  46.              DisposableWrapper.Create(typeof(Autodesk.AutoCAD.Colors.Color), clptr, false) as Autodesk.AutoCAD.Colors.Color;
  47.           string colorString = string.Format("{0},{1},{2}", cl.Red, cl.Green, cl.Blue);
  48.           ed.WriteMessage("Цвет штриховки полигона: {0}\n", colorString);
  49.         }
  50.         catch (System.Exception ex)
  51.         {
  52.           ed.WriteMessage("Исключение при попытке получить цвет штриховки: " + ex);
  53.         }
  54.       }
  55.     }
  56.   }
  57. }

И результат:

Цитировать
Command: GETPATTERNCOLOR

Select objects: 1 found

Select objects:
Цвет штриховки полигона: 176,88,0
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Цвет штриховки для полигона
« Ответ #5 : 08-12-2014, 10:53:07 »
Ну а вот так выглядит P/Invoke для AcDbMPolygon::patternColor:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Colors;
  8. using System.Runtime.InteropServices;
  9.  
  10. [assembly: CommandClass(typeof(MpolygonTest.MyCommands))]
  11.  
  12. namespace MpolygonTest
  13. {
  14.   public class MyCommands
  15.   {
  16.     // Зависит от версии AutoCAD и разрядности. В данном случае это для AutoCAD 2013-2014 и x64
  17.     [DllImport("AcMPolygonObj19.dbx", CallingConvention = CallingConvention.ThisCall,
  18.        EntryPoint = "?patternColor@AcDbMPolygon@@UEBA?AVAcCmColor@@XZ")]
  19.     // Для AutoCAD 2013-2014 и x86
  20.     // [DllImport("AcMPolygonObj19.dbx", CallingConvention = CallingConvention.ThisCall,
  21.     //   EntryPoint = "?patternColor@AcDbMPolygon@@UBE?AVAcCmColor@@XZ")]
  22.     extern static private System.IntPtr getPatternColorOfMPolygon(System.IntPtr Mpolygon);
  23.  
  24.     [CommandMethod("GetPatternColor")]
  25.     public static void GetPatternColor()
  26.     {
  27.       Document doc = Application.DocumentManager.MdiActiveDocument;
  28.       Editor ed = doc.Editor;
  29.       // Не обязательно, но желательно
  30.       SystemObjects.DynamicLinker.LoadModule("AcMPolygonObj" + Application.Version.Major + ".dbx", false, false);
  31.       PromptSelectionResult selection = ed.GetSelection();
  32.       if (selection.Status != PromptStatus.OK)
  33.         return;
  34.       ObjectId objId = selection.Value[0].ObjectId;
  35.       using (var trans = doc.Database.TransactionManager.StartTransaction())
  36.       {
  37.         var polygon = trans.GetObject(objId, OpenMode.ForRead) as MPolygon;
  38.  
  39.         if (polygon == null)
  40.           return;
  41.  
  42.         try
  43.         {
  44.           System.IntPtr clptr = getPatternColorOfMPolygon(polygon.UnmanagedObject);
  45.           Autodesk.AutoCAD.Colors.Color cl =
  46.              DisposableWrapper.Create(typeof(Autodesk.AutoCAD.Colors.Color), clptr, false) as Autodesk.AutoCAD.Colors.Color;
  47.           string colorString = string.Format("{0},{1},{2}", cl.Red, cl.Green, cl.Blue);
  48.           ed.WriteMessage("Цвет штриховки полигона: {0}\n", colorString);
  49.         }
  50.         catch (System.Exception ex)
  51.         {
  52.           ed.WriteMessage("Исключение при попытке получить цвет штриховки: " + ex);
  53.         }
  54.       }
  55.     }
  56.   }
  57. }

И результат:

Цитировать
Command: GETPATTERNCOLOR

Select objects: 1 found

Select objects:
Цвет штриховки полигона: 176,88,0

Александр, возникла проблема с данным методом. Метод вызывается без проблем, но один раз. Начал выяснять проблему, оказалось, что даже если вызвать в одном месте метод дважды, то возникает исключение Access violation, и Автокад падает. Код тот же что и был, только повторно вызов стоит. Автокад 2012. В атрибуте импорта либы стоит AcMPolygonObj18.dbx. В чем может быть проблема?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #6 : 08-12-2014, 20:19:14 »
Похоже, что при первом вызове getPatternColorOfMPolygon портится участок памяти, в котором находится MPolygon. Возможно у меня не вполне корректное описание для P/Invoke, т.к. в чистом ObjectARX возвращается не указатель на AcCmColor, а сам AcCmColor. Думаю, что это тот случай, когда придется обратится к ADN DevHelp. Хотя очень вероятно, что они предложат использовать чистый ObjectARX, так как с ним всё в порядке.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #7 : 08-12-2014, 21:04:07 »
Кстати баг с MPolygon.PatternColor имеет место быть и в AutoCAD 2015. И P/Invoke ведет себя точно также, т.е. в первый раз срабатывает, а во второй Fatal Error.

P.S.: Отправил в ADN DevHelp. Я сообщу если (или когда) появится дополнительная информация.
« Последнее редактирование: 08-12-2014, 22:22:49 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Цвет штриховки для полигона
« Ответ #8 : 09-12-2014, 05:16:51 »
Спасибо Александр! Будем надеяться что в в будущем исправят ошибку.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #9 : 09-12-2014, 08:43:28 »
Спасибо Александр! Будем надеяться что в в будущем исправят ошибку.
Это было одной из моих просьб к ADN DevHelp. Но пока меня не оставляет надежда, что они подскажут как обойти этот Fatal Error при использовании P/Invoke. Я оставлял такую часть кода:
Код - C# [Выбрать]
  1. try
  2. {
  3.    System.IntPtr clptr = getPatternColorOfMPolygon(polygon.UnmanagedObject);
  4. }
  5. catch (System.Exception ex)
  6. {
  7.    ed.WriteMessage("Исключение при попытке получить цвет штриховки: " + ex);
  8. }
И всё равно при втором вызове AutoCAD падал. Значит что-то не так в сигнатуре P/Invoke.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #10 : 09-12-2014, 16:23:29 »
Очень оперативно получил ответ от ADN DevHelp о том, что об ошибке они знаю, что есть запрос на исправление, что вызвать  метод AcDbMPolygon::patternColor() .NET через P/Invoke по этой причине нельзя, т.к. этот метод возвращает неправильный адрес. Мне это честно говоря не очень понятно. Так как в первый раз мы получаем нормальные правильные значения.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Цвет штриховки для полигона
« Ответ #11 : 10-12-2014, 07:45:17 »
Спасибо, Александр. Что ж, остаётся единственный способ -  ObjectArx, других альтернатив нет.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #12 : 11-12-2014, 15:06:27 »
Тут ребята из ADN DevHelp вспомнили что можно воспользоваться группой DXF 63 для получения PatternColor: http://help.autodesk.com/view/ACD/2015/ENU/?guid=GUID-C6C71CED-CE0F-4184-82A5-07AD6241F15B
P.S.: Посмотрел группу 63 - в ней не может быть truecolor цвета, т.е. стоит ближайший ACI цвет (в данном случае 34).
« Последнее редактирование: 11-12-2014, 15:45:58 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Цвет штриховки для полигона
« Ответ #13 : 13-12-2014, 07:34:11 »
Не могу сообразить, как считать значение по этому коду? Точнее откуда? XData у полигона пуста. Спасибо.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Цвет штриховки для полигона
« Ответ #14 : 13-12-2014, 22:45:09 »
Не могу сообразить, как считать значение по этому коду? Точнее откуда? XData у полигона пуста. Спасибо.
Это группа не в XData и считать в AutoCAD .NET API её можно только при помощи P/Invoke функции acdbEntGet из ObjectARX.
Примеры использования:
http://adn-cis.org/forum/index.php?topic=1029.msg4743#msg4743
http://adn-cis.org/forum/index.php?topic=1128.msg5628#msg5628
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение