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

ADN Club => AutoCAD .NET API => Тема начата: Judas от 02-04-2020, 12:04:51

Название: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 12:04:51
Привет всем.
Думаю тема избитая, но я не могу ее реализовать "просто".
Идея в чем строю профиль трубопровода для разработки схемы ГИ.
Сам профиль - полилиния, по которой я определяю ПК, отметки и прочее, но нужно добавить отдельные ординаты (типа оборудование, с указание ПК и отметки).
С ПК все понятно - сделал (данные полинии переписал в блок и потом извлек и пересчитал дистанцию)
С отметками в тупике, т.е. есть ордината 11+11 мне нужно получить координату Y на полилинии в этой орадинате.
Может подскажете как это проще сделать (передавать в метод полилинию каждый раз не очень хочеться - долго)
(https://i.postimg.cc/pySy9NLV/image.jpg) (https://postimg.cc/pySy9NLV)
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 12:21:15
Пять раз перечитал, но ничего не понял. И причем здесь удлинение отрезка?
P.S.: Ордината - это и есть координата Y.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 12:32:29
Получить точку пересечения (а там же ординату т.к. Y) можно удлинив отрезок-ординату "11+11" до пересечения с полилинией вверху и тем самы получить координату Y пересечения и по ней посчитать отметку.
Можно сделать, чтобы каждый раз выбирать полилинию и line.IntersectWith вернет нам все что нужно.
Но хотелось бы этого избежать.
Сделать виртуальное пересечение без выбора полилинии.
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 12:37:20
Можно сделать, чтобы каждый раз выбирать полилинию и line.IntersectWith вернет нам все что нужно.
Выбирать то её зачем? Ты её ObjectId знаешь, раз её нарисовал. Вот и открой её и выполни IntersectWith. Причем второй объект может быть Line или XLine, который даже не добавляется в базу.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 12:41:47
Да верно.
Но когда построен профиль где мне хранить ее id это же "разные кнопки".
Я все исходные данные пишу в блок - шапку, там где масштабы.

Даже если я туда запишу id полилинии я его потом не верну, как string преобразовать в ObjectId?
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 12:59:18
Даже если я туда запишу id полилинии я его потом не верну, как string преобразовать в ObjectId?
Во-первых, в этом случае нужно писать не ObjectId, а Handle, т.е. ObjectId меняется между сеансами AutoCAD.
Во-вторых, Handle преобразовывается в строку: Handle.ToString
Кроме того для идентификации полилинии в неё можно записать расширенные данные, по которым её можно найти в чертеже. Вообще-то вариантов масса. Выбирай любой.
Название: Re: Удлинение отрезка
Отправлено: Привалов Дмитрий от 02-04-2020, 14:18:01
Да верно.
Но когда построен профиль где мне хранить ее id это же "разные кнопки".
Я все исходные данные пишу в блок - шапку, там где масштабы.

Даже если я туда запишу id полилинии я его потом не верну, как string преобразовать в ObjectId?

Я давно делал подобную задачу по оформлению профиля.
ObjectId или Handle не сохранял. Пользователь перед началом работы выбирал объекты, образующие разрез на профиле, указывал привязки(4 точки и значения), потом строил что надо.
Профиля были разные построенные в различных программах внутри отдела, так и присланные на обработку извне.
Так универсально, объектов, образующих разрез может быть несколько, их могут изменить, разбить по файлам, разбить полилинии, объединить отрезки, скопировать в новый чертеж и т.д.

Я не призываю к такому-же подходу. Но если помечать объекты в чертеже, то продумай кнопки, для снятия пометок и нанесения вновь, на случай непредвиденных действий пользователя.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 14:46:41
Мне нужно обрабатывать один профиль в одном листе - схему гидроиспытаний.
Зная "наших" лучше думаю лишних кнопок не делать "затыкаются", хочу чтобы было все однокнопочно и строго.

Через handle получилось, спасибо, но теперь прерывание выкидывается на line.IntersectWith(localPoly, Intersect.OnBothOperands, points, IntPtr.Zero, IntPtr.Zero);

Код - C# [Выбрать]
  1.         //Создание свободной ординаты
  2.         [CommandMethod("DrawTableGidroOrdinate", CommandFlags.UsePickSet)]
  3.         public static void DrawTableGidroOrdinate()
  4.         {
  5.             //Получаем ссылки на документ
  6.             AcadMain.AccessToDocument AcadDoc = new AcadMain.AccessToDocument();
  7.             Database db = AcadDoc.DBase;
  8.             //экземпляр формы
  9.             DrawTableGidroOrdinateForm drawTableGidroOrdinateForm = new DrawTableGidroOrdinateForm();
  10.             drawTableGidroOrdinateForm.ShowDialog();
  11.             if (drawTableGidroOrdinateForm.ButtonWasClicked != false)
  12.             {
  13.                 //Параметры с формы исходной
  14.                 double dblpiketOrdinate = PKtoMT(drawTableGidroOrdinateForm.TextBoxText(1));
  15.                 string strPiketOrdinate = drawTableGidroOrdinateForm.TextBoxText(2);
  16.                 //Контрольные параметры для построение ординаты
  17.                 InfoDataGidro(out double scaleX, out double scaleY, out double infoX, out double infoY, out double Mark, out string Piket,out string handle);
  18.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  19.                 {
  20.                     double dblPiket = PKtoMT(Piket);
  21.                     TableGidroTest tableGidroTest = new TableGidroTest();
  22.                     //Ссылка на слои
  23.                     TableLayers TableLayer = new TableLayers();
  24.                     TableLayer.PreparationLayer();
  25.                     //Открываем таблицу блоков на запись
  26.                     BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
  27.                     //Создаем новое определение блока, задаем ему имя
  28.                     BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  29.                     //Запоминание текущего слоя для возврата к нему
  30.                     string CurrentLayer = TableLayer.CurrentLayerData();
  31.                     //Слой таблички
  32.                     TableLayer.ActiveLayerSetup(TableLayers.layerGI);
  33.                     //Пересчет координат
  34.                     infoX = Math.Round(infoX + (dblpiketOrdinate - dblPiket) * scaleX / 1000, 2);
  35. ;                    //Рисование ординат
  36.                     Line line = new Line(new Point3d(   infoX,
  37.                                                         infoY - tableGidroTest.HeightMoveAbs - tableGidroTest.HeightTable(0),
  38.                                                         0),
  39.                                         new Point3d(    infoX,
  40.                                                         infoY - tableGidroTest.HeightMoveAbs + 10000,
  41.                                                         0));
  42.  
  43.  
  44.                  
  45.                     ObjectId newidPoly = db.GetObjectId(false, new Handle(Convert.ToInt64(handle)), 0);
  46.                     MessageBox.Show(handle.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  47.                     MessageBox.Show(newidPoly.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  48.                     Polyline localPoly = tr.GetObject(newidPoly, OpenMode.ForRead) as Polyline;
  49.  
  50.                     //MessageBox.Show((typeof().ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  51.  
  52.                     //MessageBox.Show(points[0].X.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  53.  
  54.  
  55.  
  56.                     Point3dCollection points = new Point3dCollection();
  57.                     line.IntersectWith(localPoly, Intersect.OnBothOperands, points, IntPtr.Zero, IntPtr.Zero);
  58.                     MessageBox.Show(points[0].X.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  59.                     MessageBox.Show(points[0].Y.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  60.                     btr.AppendEntity(line);
  61.                     tr.AddNewlyCreatedDBObject(line, true);
  62.                    
  63.                     //Создаем однострочный текстовый объект - пикет
  64.                     DBText Text = new DBText
  65.                     {
  66.                         Height = heightTextOrdinate,
  67.                         Position = new Point3d(infoX - heightTextOrdinate / 2 - deltaTextOrdinate, infoY - tableGidroTest.HeightMoveAbs + deltaTextOrdinate, 0),
  68.                         TextString = MTtoPK(dblpiketOrdinate) + " "  + strPiketOrdinate,
  69.                         HorizontalMode = TextHorizontalMode.TextLeft,
  70.                         VerticalMode = TextVerticalMode.TextVerticalMid,
  71.                         AlignmentPoint = new Point3d(infoX - heightTextOrdinate / 2 - deltaTextOrdinate, infoY - tableGidroTest.HeightMoveAbs + deltaTextOrdinate, 0),
  72.                         Rotation = Math.PI / 2
  73.                     };
  74.                     btr.AppendEntity(Text);
  75.                     tr.AddNewlyCreatedDBObject(Text, true);
  76.                    
  77.                     //Создаем однострочный текстовый объект - отметка
  78.                     Text = new DBText
  79.                     {
  80.                         Height = heightTextOrdinate,
  81.                         Position = new Point3d(infoX - heightTextOrdinate / 2 - deltaTextOrdinate, infoY - tableGidroTest.HeightMoveAbs + deltaTextOrdinate - tableGidroTest.HeightTable(0), 0),
  82.                         TextString = MTtoPK(dblpiketOrdinate),
  83.                         HorizontalMode = TextHorizontalMode.TextLeft,
  84.                         VerticalMode = TextVerticalMode.TextVerticalMid,
  85.                         AlignmentPoint = new Point3d(infoX - heightTextOrdinate / 2 - deltaTextOrdinate, infoY - tableGidroTest.HeightMoveAbs + deltaTextOrdinate - tableGidroTest.HeightTable(0), 0),
  86.                         Rotation = Math.PI / 2
  87.                     };
  88.                     btr.AppendEntity(Text);
  89.                     tr.AddNewlyCreatedDBObject(Text, true);
  90.                     TableLayer.ActiveLayerSetup(CurrentLayer);
  91.                     tr.Commit();
  92.                 }
  93.             }
  94.         }
  95.  
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 15:05:48
но теперь прерывание выкидывается на line.IntersectWith(localPoly, Intersect.OnBothOperands, points, IntPtr.Zero, IntPtr.Zero);
Какое прерывание?
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 15:16:16
dmpuserinfo:
Извините, вам запрещён просмотр содержимого спойлеров.
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 15:20:26
dmpuserinfo:
Так это не прерывание, а Fatal Error. Круто. Ну тогда анализируй newidPoly - не равен ли он null.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 15:30:57
В том то и дело не что не равны!
handle.ToString():
(https://i.postimg.cc/vgHKN5ZY/hendle.jpg) (https://postimg.cc/vgHKN5ZY)
newidPoly.ToString()
(https://i.postimg.cc/G4xqn9NH/ID.jpg) (https://postimg.cc/G4xqn9NH)

Проблема (какая-то) в получении объекта по ID:
ObjectId newidPoly = db.GetObjectId(false, new Handle(Convert.ToInt64(handle)), 0);
Polyline localPoly = tr.GetObject(newidPoly, OpenMode.ForRead) as Polyline;
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 15:37:23
Могу лишь посоветовать предельно упростить код и отлаживать его.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 15:43:05
Беда!
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 15:46:16
Проблема (какая-то) в получении объекта по ID:
ObjectId newidPoly = db.GetObjectId(false, new Handle(Convert.ToInt64(handle)), 0);
Polyline localPoly = tr.GetObject(newidPoly, OpenMode.ForRead) as Polyline;
Убедись при помощи MGDDBG, что newidPoly соответствует ObjectId твоей полилинии.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 15:52:23
начну с того, что такое MGDDBG)))
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 15:54:35
начну с того, что такое MGDDBG)))
Поиск у нас уже запретили? ;) https://adn-cis.org/forum/index.php?topic=7274.0
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 16:04:01
Нет конечно.
Hendle - верный и там и программе.
Пока ищу Id.

Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:15:35
Я так понял там нет ID объекта, только Hendle.
Где нет? Чего нет? Пожалуйста пиши подробно.
А есть какие-то другие варианты посмотреть, что она положил в объект?
Кто она? Куда положила? Какой объект?
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 16:19:02
Все нашел.

(https://i.postimg.cc/qz3S7cYZ/1.jpg) (https://postimg.cc/qz3S7cYZ)

ID не совпадают!
Получается проблема в получении корректного ID по Handle, а именно:
ObjectId newidPoly = db.GetObjectId(false, new Handle(Convert.ToInt32(handle)), 0);
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:21:10
ID не совпадают!
А Handle совпадает?
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 16:26:25
Так есть.
(https://i.postimg.cc/gwvjvBJX/2.jpg) (https://postimg.cc/gwvjvBJX)

Я не сильно силен в схеме организации чертежа, но хочу сразу уточнить, Handle - это второй уникальный ключ?
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:30:19
Handle - это второй уникальный ключ?
Скорее это первый уникальный ключ. И он в виде шестнадцатеричной строки. Поэтому Convert.ToInt64 не подходит.
Нужно Convert.ToInt64(handle, 16)
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 16:34:01
Странно, но плагин отражает его как обычный формат числа.
Название: Re: Удлинение отрезка
Отправлено: Дмитрий Загорулькин от 02-04-2020, 16:34:23
Я всегда для получения Id использовал другой метод: Database.TryGetObjectId. Странно, но похоже, что его нет в справке.
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:35:22
Я всегда для получения Id использовал другой метод: Database.TryGetObjectId. Странно, но похоже, что его нет в справке.
Да. Он недокументированный и более быстрый.
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:36:28
Странно, но плагин отражает его как обычный формат числа.
Шестнадцатиричное 274 - это 628 десятичное.
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 16:43:43
Александр склоняю голову!!!
Дмитрий "Database.TryGetObjectId" будет учтено!!!

Спасибо всем.

Вот она красота!!! Векторная!
(https://i.postimg.cc/BtRFRCQm/4.jpg) (https://postimg.cc/BtRFRCQm)
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:52:09
Александр склоняю голову!!!
Дмитрий "Database.TryGetObjectId" будет учтено!!!

Спасибо всем.
Заработало?
Название: Re: Удлинение отрезка
Отправлено: Judas от 02-04-2020, 16:53:51
Да, все работает как часики!
Если нужен код - могу выложить)
Название: Re: Удлинение отрезка
Отправлено: Александр Ривилис от 02-04-2020, 16:57:12
Да, все работает как часики!
Если нужен код - могу выложить)
Отлично. Код выкладывать не имеет смысла, так как всё что нужно для результата уже есть в теме.