Создание полилинии по точкам COGO в AutoCAD Civil 3d 2012

Автор Тема: Создание полилинии по точкам COGO в AutoCAD Civil 3d 2012  (Прочитано 33033 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
if (myPoint.PointNumber = 1)
Только мне кажется, что в этой строке ты присваиваешь myPoint.PointNumber значение 1?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
if (myPoint.PointNumber = 1)
Только мне кажется, что в этой строке ты присваиваешь myPoint.PointNumber значение 1?

Посыпаю голову пеплом, конечно же if (myPoint.PointNumber == 1) , VB еще сказывается...

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

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Re: Создание и редактирование точек COGO
« Ответ #32 : 22-04-2015, 21:51:43 »
Но чего то я не могу найти в Civil 2012 методы для работы с точками COGO.
Видимо этого то и нет. Придётся руками

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Но чего то я не могу найти в Civil 2012 методы для работы с точками COGO.
Видимо этого то и нет. Придётся руками
Так может всё-таки через COM/ActiveX?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Re: Создание и редактирование точек COGO
« Ответ #34 : 23-04-2015, 12:03:54 »
Ни как не могу понять в чём суть COM/ActiveX. Есть какая-нибудь документация для Autocad?
А документацию лучше тут %ProgramFiles%\Common Files\Autodesk Shared\acad_aag.chm смотреть?
Как я понял, эволюция такая: OLE -> COM -> COM/ActiveX -> .NET.
Т.е. те же яйца - вид сбоку.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ни как не могу понять в чём суть COM/ActiveX.
После того, как ты подключил нужные dll-файлы (или на вкладке COM) - всё остальное для тебя не отличается от работы с .NET. Единственно что тебе нужно смотреть в Object Browser какие классы/методы/свойства есть у Civil 3D в этих библиотеках.
Есть какая-нибудь документация для Autocad?
Документация на что? Как работать с ActiveX/COM моделью AutoCAD? Есть. Хотя она написана больше для работы в VBA:
Или это: AutoCAD ActiveX Guide 2013
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Re: Создание и редактирование точек COGO
« Ответ #36 : 23-04-2015, 12:14:23 »
Большое спасибо. Как то понятнее стало

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

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Re: Создание и редактирование точек COGO
« Ответ #37 : 23-04-2015, 15:36:02 »
В общем, допёр я как использовать COM. Как-то. Скорее всего ещё будут проблемы. Спасибо вашим пинкам, иначе забросил бы это дело уже.
Вот мой тренировочный код, в котором я выбираю через COM точку типа AeccPoint по номеру:
Код - C# [Выбрать]
  1. //-----------------------------------------
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. //-----------------------------------------
  7. using Autodesk.Civil.ApplicationServices;
  8. using Autodesk.Civil.Land.DatabaseServices;
  9.  
  10. using Autodesk.AutoCAD.Interop;
  11. using Autodesk.AECC.Interop.Land;
  12. using Autodesk.AECC.Interop.UiLand;
  13.  
  14. namespace HelloWorld
  15. {
  16.     public class Class1:IExtensionApplication
  17.     {
  18.         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  19.         public void Initialize()
  20.         {
  21.             ed.WriteMessage("Поздравляю вас, сборка загружена.");
  22.         }
  23.         public void Terminate()
  24.         {
  25.             ed.WriteMessage("Сборка выгружена. До свидания");
  26.         }
  27.         [CommandMethod("HelloWorld")]
  28.         public void HelloWorld()
  29.         {
  30.             ed.WriteMessage("Пхай-Пхай");
  31.             AcadApplication oAcadApp = (AcadApplication)Application.AcadApplication;
  32.             string sCivilAppName = "AeccXUiLand.AeccApplication.9.0";
  33.             AeccApplication oCivilApp = (AeccApplication)oAcadApp.GetInterfaceObject(sCivilAppName);
  34.             AeccDocument oDocument = (AeccDocument)oCivilApp.ActiveDocument;
  35.             AeccPoints oPoints = (AeccPoints)oDocument.Points;
  36.             AeccPoint oPoint1;
  37.             oPoint1 = oPoints.Find(3);
  38.             ed.WriteMessage("\n------------------------------");
  39.             ed.WriteMessage("\nНомер точки: " + oPoint1.Number);
  40.             ed.WriteMessage("\nКоординаты точки: X={0}; Y={1}", oPoint1.Northing, oPoint1.Easting);
  41.             double[] lower = new double[3] { 10, 10, 0 };
  42.             double[] upper = new double[3] { 100, 100, 0 };
  43.             ZoomPlineCOM(lower, upper);
  44.         }
  45.         public void ZoomPlineCOM(double[] lower,double[] upper) //Зум по координатам окна, которые берутся из созданной полилинии
  46.         {
  47.             AcadApplication oAcadApp = (AcadApplication)Application.AcadApplication;
  48.             string sCivilAppName="AeccXUiLand.AeccApplication.9.0";
  49.             AeccApplication oCivilApp = (AeccApplication)oAcadApp.GetInterfaceObject(sCivilAppName);
  50.             AeccDocument oDocument = (AeccDocument)oCivilApp.ActiveDocument;
  51.             oCivilApp.ZoomWindow(lower, upper);
  52.         }
  53.     }
  54. }

Вопрос 1: насчёт транзакции. Надо ли её использовать при обращении к объектам через COM? Так то всё работает.
Вопрос 2: Код ниже обязательно в каждой функции прописывать или же достаточно один раз где то?

Код - C# [Выбрать]
  1. AcadApplication oAcadApp = (AcadApplication)Application.AcadApplication;
  2. string sCivilAppName="AeccXUiLand.AeccApplication.9.0";
  3. AeccApplication oCivilApp = (AeccApplication)oAcadApp.GetInterfaceObject(sCivilAppName);
  4. AeccDocument oDocument = (AeccDocument)oCivilApp.ActiveDocument;

Вопрос 3: рефёренсы. Вылезло 88 варнингов типа "Warning   1   Reference to type 'Autodesk.AutoCAD.Interop.AcWindowState' claims it is defined in 'c:\Autocad DLL\Autodesk.AutoCAD.Interop.dll', but it could not be found   c:\Autocad DLL\Autodesk.AECC.Interop.UiLand.dll   HelloWorld".
Взял dll из папки [Дистрибутив Autocad]\x64\C3D\Program Files\root. Может я чего то не так или может не то подключил?

Нашёл по этой ошибке в AutoCAD_Civil_3D_2011_API_Developer_s_Guide вот это:
Цитировать
NOTE You may see warnings about types not being found in various Autodesk.AutoCAD.Interop namespaces
(warning type 1684). To disable these warnings, enter 1684 under Supress Warnings on the Build tab of the
project’s properties.
На это стоит обращать внимание?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вопрос 1: насчёт транзакции. Надо ли её использовать при обращении к объектам через COM? Так то всё работает.
Если работаешь только через COM, то транзакция необязательна, но желательна для группировки действий для отмены.

Вопрос 2: Код ниже обязательно в каждой функции прописывать или же достаточно один раз где то?
Можешь это сделать и один раз и объявить эти переменные не локальными в методе, а на уровне класса. Но тут есть нюансы. 
У каждого документа (чертежа) своё значение oDocument. Поэтому вычислить его один раз и навсегда не получится.

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
P.S.: Как я понимаю следующая строка:
Код - C# [Выбрать]
  1. oPoint1 = oPoints.Find(3);
при отсутствии точки с номером 3 приводит к исключению, которое у тебя не обрабатывается. Так что не забудь поставить там try/catch
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Нашёл по этой ошибке в AutoCAD_Civil_3D_2011_API_Developer_s_Guide вот это
Так-так-так! А можно поподробнее? Где нашли это руководство и где в нем эта запись? Меня эти предупреждения об ошибках очень уже очень сильно достали.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Дмитрий Загорулькин, а поиском не пробовал? ;)
http://knowledge.autodesk.com/support/autocad-civil-3d/learn-explore/caas/CloudHelp/cloudhelp/2015/ENU/Civil3D-DevGuide/files/GUID-DD447A5A-DF8B-4905-8BFC-4CBFA1C7C121-htm.html
Там как раз про это предупреждение.

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

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

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Так что не забудь поставить там try/catch
Спасибо за совет
« Последнее редактирование: 24-04-2015, 12:55:10 от Stoner »

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

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Получилось написать таки некое подобие чего хотелось. Спасибо большое за подсказки
Подключенные библиотеки (подскажите, если что лишнее):
---- Мною ----
acdbmgd.dll
acmgd.dll
AecBaseMgd.dll
AeccDbMgd.dll
Autodesk.AEC.Interop.Base.dll
Autodesk.AEC.Interop.UIBase.dll
Autodesk.AECC.Interop.Land.dll
Autodesk.AECC.Interop.UiLand.dll
Autodesk.AutoCAD.Interop.dll
Autodesk.AutoCAD.Interop.Common.dll
---- Были в стандартном проекте Visual Studio ----
Microsoft.CSharp.dll
stdole.dll
System.dll
System.Core.dll
System.Data.dll
System.Data.DataSetExtensions.dll
System.Xml.dll
System.Xml.Linq.dll

Сам код:
Код - C# [Выбрать]
  1. using System;
  2. //-----------------------------------------
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. //-----------------------------------------
  9. using Autodesk.AutoCAD.Interop;
  10. using Autodesk.AECC.Interop.Land;
  11. using Autodesk.AECC.Interop.UiLand;
  12.  
  13. namespace LineObstacles
  14. {
  15.     public class PolylineObs:IExtensionApplication
  16.     {
  17.         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  18.         public void Initialize()
  19.         {
  20.             ed.WriteMessage("Поздравляю вас, сборка загружена.");
  21.         }
  22.         public void Terminate()
  23.         {
  24.             ed.WriteMessage("Сборка выгружена. До свидания");
  25.         }
  26.         //Подключение к документу через COM
  27.         static AcadApplication oAcadApp = (AcadApplication)Application.AcadApplication;
  28.         static AeccApplication oCivApp = (AeccApplication)oAcadApp.GetInterfaceObject("AeccXUiLand.AeccApplication.9.0");
  29.         static AeccDocument oDoc = (AeccDocument)oCivApp.ActiveDocument;
  30.         //---------------------------------
  31.         static Document acDoc = Application.DocumentManager.MdiActiveDocument;
  32.         static Database acCurDb = acDoc.Database;
  33.         AeccPoints oPoints = (AeccPoints)oDoc.Points;
  34.         AeccPoint oPointTMP = null;
  35.         AeccPoint oPointA = null;
  36.         AeccPoint oPointB = null;
  37.         bool exit=false;
  38.  
  39.         [CommandMethod("plineCOGO")]
  40.         public void plineCOGO()
  41.         {
  42.             do//Создание полилинии циклично пока не ESC
  43.             {
  44.                 PromptIntegerResult intResult;
  45.                 //Сообщения для ввода номера
  46.                 intResult = inputNumCogo("\nВведите номер начальной точки [Выход - ESC]: ");
  47.                 if (intResult.Status == PromptStatus.OK)
  48.                 {
  49.                     oPointA = oPointTMP;
  50.                     ed.WriteMessage("\nВыбрана точка с номером " + oPointA.Number);
  51.                     ed.WriteMessage("\nКоординаты точки: Y={0}; X={1}", oPointA.Northing, oPointA.Easting);
  52.                     intResult = inputNumCogo("\nВведите номер конечной точки [Выход - ESC]: ");
  53.                     if (intResult.Status == PromptStatus.OK)
  54.                     {
  55.                         oPointB = oPointTMP;
  56.                         ed.WriteMessage("\nВыбрана точка с номером " + oPointB.Number);
  57.                         ed.WriteMessage("\nКоординаты точки: Y={0}; X={1}", oPointB.Northing, oPointB.Easting);
  58.                         //Переменные minX,minY,maxX,maxY для зума на созданную полилинию
  59.                         double minY = Math.Min(oPointA.Northing, oPointB.Northing);
  60.                         double minX = Math.Min(oPointA.Easting, oPointB.Easting);
  61.                         double maxY = Math.Max(oPointA.Northing, oPointB.Northing);
  62.                         double maxX = Math.Max(oPointA.Easting, oPointB.Easting);
  63.                         using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  64.                         {
  65.                             BlockTable acBlkTbl;
  66.                             acBlkTbl = (BlockTable)acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);
  67.                             BlockTableRecord acBlkTblRec;
  68.                             acBlkTblRec = (BlockTableRecord)acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  69.                             Polyline acPoly = new Polyline();
  70.                             //Задание свойств полилинии (в будущем сделать окно выбора при загрузке сборки с дефолтом)
  71.                             acPoly.SetDatabaseDefaults();
  72.                             acPoly.ColorIndex = 7;
  73.                             acPoly.LineWeight = LineWeight.LineWeight060;
  74.                             acPoly.Layer = "11_Препятствия";//Сделать проверку на наличие
  75.                             int num = oPointA.Number;
  76.                             int v = 0;//Счётчик вершин полилинии
  77.                             bool status;//Статус пропуска отсутствующий номеров
  78.                             while (num <= oPointB.Number)//В будущем сделать с реверсом, если oPointA.Number>oPointB.number
  79.                             {
  80.                                 status = true;
  81.                                 try
  82.                                 {
  83.                                     oPointTMP = oPoints.Find(num);
  84.                                 }
  85.                                 catch (ArgumentException)
  86.                                 {
  87.                                     ed.WriteMessage("\nПолучен отсутствующий номер - " + num);
  88.                                     status = false;
  89.                                 }
  90.                                 if (status == true)
  91.                                 {
  92.                                     acPoly.AddVertexAt(v, new Point2d(oPointTMP.Easting, oPointTMP.Northing), 0, 0, 0);
  93.                                     v++;
  94.                                     minX = Math.Min(minX, oPointTMP.Easting);
  95.                                     minY = Math.Min(minY, oPointTMP.Northing);
  96.                                     maxX = Math.Max(maxX, oPointTMP.Easting);
  97.                                     maxY = Math.Max(maxY, oPointTMP.Northing);
  98.                                 }
  99.                                 num++;
  100.                             }
  101.                             //Запись полилинии в базу (в будущем сделать возможность замыкания)
  102.                             acBlkTblRec.AppendEntity(acPoly);
  103.                             acTrans.AddNewlyCreatedDBObject(acPoly, true);
  104.                             acTrans.Commit();
  105.                             //Зум с офсетом 100
  106.                             double[] lower = new double[3] { minX - 100, minY - 100, 0 };
  107.                             double[] upper = new double[3] { maxX + 100, maxY + 100, 0 };
  108.                             oCivApp.ZoomWindow(lower, upper);
  109.                         }
  110.                     }
  111.                     else
  112.                     {
  113.                         ed.WriteMessage("\nПроизведён выход");//Выход при нажатии ESC
  114.                         exit = true;
  115.                     }
  116.                 }
  117.                 else
  118.                 {
  119.                     ed.WriteMessage("\nПроизведён выход");
  120.                     exit = true;
  121.                 }
  122.             } while (exit == false);
  123.            
  124.         }
  125.         //Ввод номеров точек с поиском по базе, возвращает результат поиска
  126.         //На входе сообщение для ввода данных (в будущем сделать ввод интервала через "-")
  127.         public PromptIntegerResult inputNumCogo(string Message)
  128.         {
  129.             PromptIntegerResult intResult;
  130.             PromptIntegerOptions intOption = new PromptIntegerOptions("");
  131.             intOption.AllowNone = false;
  132.             intOption.AllowZero = false;
  133.             intOption.AllowNegative = false;
  134.             intOption.Message = Message;
  135.             int num;
  136.             bool status;
  137.             do
  138.             {
  139.                 intResult = ed.GetInteger(intOption);
  140.                 num = intResult.Value;
  141.                 status = true;
  142.                 if (intResult.Status == PromptStatus.OK)
  143.                 {
  144.                     try
  145.                     {
  146.                         oPointTMP = oPoints.Find(num);
  147.                     }
  148.                     catch (ArgumentException)
  149.                     {
  150.                         status = false;
  151.                         ed.WriteMessage("\nПолучен отсутствующий номер!");
  152.                     }
  153.                 }
  154.             } while ((status == false) && (intResult.Status == PromptStatus.OK));
  155.             return intResult;
  156.         }
  157.     }
  158. }
Может что то в смысле алгоритмизации не так?
Транзакцию использовал только при создании полилинии. Подумал, что точки COGO только читаются, поэтому нафиг.
Всем спасибо
ЗЫ: код должен строить полилинию с заданными свойствами по интервалу номеров точек COGO, заданным пользователем.
« Последнее редактирование: 28-04-2015, 11:21:59 от Stoner »

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Я бы убрал реализацию IExtensionApplication - она тут не нужна. Или, если нужно как-то просигнализировать о загрузке сборки, выводить более информативное сообщение вместо "Поздравляю, сборка загружена". Какая сборка? Кто автор? Какие команды она добавляет? Такая информация будет более полезна.
Если нужен зум по полилинии, то можно воспользоваться ее свойством acPoly.GeometricExtents. Тогда, возможно, не надо будет танцев с определением минимальных и максимальных координат. В любом случае, использование Extents3d в данном случае будет удобнее.
А по алгоритму сложно что-то сказать - по комментариям сложно понять, что должен делать код.