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

ADN Club => AutoCAD .NET API => Тема начата: garipov72 от 23-09-2014, 12:58:03

Название: Контур AutoCAD 2012
Отправлено: garipov72 от 23-09-2014, 12:58:03
Добрый день!
В работе с AutoCAD я новичок. Поставили передо мной задачу: После ввода команды (пишется DLL на C#) заставить пользователя выбрать замкнутый контур и его заполнить объектами. Объекты я научился рисовать, и все приготовил. Но теперь встал в тупик, подскажите пожалуйста, как заставить пользователя нарисовать замкнутый контур? Что бы после ввода команды ему осталось только выбрать область для заполнения? Область может быть произвольной формы, с произвольным количеством точек.
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 13:04:45
Привествую на форуме!
Так
заставить пользователя выбрать замкнутый контур
или
как заставить пользователя нарисовать замкнутый контур?
?
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 23-09-2014, 13:13:32
Спасибо за приветствие, мелочь а приятно. И так, я ошибся. Надо что бы после ввода команды пользователь нарисовал  область линиями. По аналогии с инструментом "Отрезок", где можно вернутся в точку начала т.е. замкнуть фигуру.
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 13:26:22
Надеюсь, что контур может быть только прямолинейный, т.е. состоящий только из линейных сегментов и не может содержать дуг? С дугами будет сложнее.
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 23-09-2014, 13:30:03
Достаточно прямолинейных линий)))) Главное что бы не прямоугольник. Даже  не знаю что искать у гугла, подтолкните на идею.
Пример такой области во вложении.
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 13:31:19
Я тебе лучше код подкину. Подожди.
Название: Re: Контур AutoCAD 2012
Отправлено: Дима_ от 23-09-2014, 14:00:10
Тут проще и лучше не изобретать велосипед, а запустить стандартную команду создания полилинии, после чего проверить созданна ли она (появился ли новый объект), проверить ее на замкнутость (и замкнуть если что) - после чего заполнять контур.
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 23-09-2014, 14:21:32
 :) решилось обычным вызовом _LINE
Подскажите как теперь вычислить попадает ли точка в эту область?
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 14:26:19
Упрощенный вариант получения контура (замкнутая полилиния с линейными сегментами):
Код - 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 AcEd = Autodesk.AutoCAD.EditorInput;
  8. using AcRx = Autodesk.AutoCAD.Runtime;
  9. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcGe = Autodesk.AutoCAD.Geometry;
  12.  
  13. [assembly: CommandClass(typeof(MakeContour.MyCommands))]
  14.  
  15. namespace MakeContour
  16. {
  17.  
  18.   public class MyCommands
  19.   {
  20.     [CommandMethod("MakeContour")]
  21.     public void MyCommand()
  22.     {
  23.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  24.       AcDb.Database db = doc.Database;
  25.       AcEd.Editor ed = doc.Editor;
  26.       AcEd.PromptPointOptions pr = new AcEd.PromptPointOptions("\nУкажите вершину контура: ");
  27.       AcDb.ObjectId idPoly;
  28.       AcGe.Point3d lastPt = AcGe.Point3d.Origin;
  29.       using (AcDb.Polyline poly = new AcDb.Polyline()) {
  30.         using (AcDb.BlockTableRecord space = db.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord) {
  31.           idPoly = space.AppendEntity(poly);
  32.         }
  33.       }
  34.       int nVert = 0;
  35.       while (true) {
  36.         if (nVert > 1) {
  37.           pr.BasePoint = lastPt;
  38.           pr.UseBasePoint = true;
  39.           pr.UseDashedLine = true;
  40.         }
  41.         if (nVert >= 3) {
  42.           pr.AllowNone = true;
  43.           pr.Message = "\nУкажите вершину контура (ENTER - завершение): ";
  44.         } else {
  45.           pr.AllowNone = false;
  46.         }
  47.         AcEd.PromptPointResult res = ed.GetPoint(pr);
  48.         if (res.Status == AcEd.PromptStatus.Cancel) {
  49.           using (AcDb.Polyline poly = idPoly.Open(AcDb.OpenMode.ForWrite) as AcDb.Polyline) {
  50.             poly.Erase();
  51.             break;
  52.           }
  53.         } else if (res.Status == AcEd.PromptStatus.None) {
  54.           break;
  55.         } else {
  56.           lastPt = res.Value;
  57.           using (AcDb.Polyline poly = idPoly.Open(AcDb.OpenMode.ForWrite) as AcDb.Polyline) {
  58.             poly.AddVertexAt(poly.NumberOfVertices, new AcGe.Point2d(res.Value.X, res.Value.Y), 0, 0, 0);
  59.             poly.Closed = true;
  60.           }
  61.           nVert++;
  62.         }
  63.       }
  64.     }
  65.   }
  66. }
При помощи Jig можно конечно сделать и красивее. В моём коде считается что ПСК == МСК. Если это не так, то следует выполнить преобразование системы координат. Еще неплохо бы задать слой/типлини/цвет... Но это уже в качестве домашнего задания.

Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 14:30:08
Подскажите как теперь вычислить попадает ли точка в эту область?
В какую??? Если ты нарисовал контур отрезками, а не полилинией, то это становится не такой тривиальной задачей.
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 23-09-2014, 14:31:30
Александр   :D это шедевр))) С меня пиво!
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 23-09-2014, 14:32:17
В какую??? Если ты нарисовал контур отрезками, а не полилинией, то это становится не такой тривиальной задачей.
В вашем варианте это полилиния?
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 14:33:09
В вашем варианте это полилиния?
Да. Посмотри код. А еще лучше попробуй его.
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 23-09-2014, 15:56:12
Проверка попадания точки внутрь контура:
Код - C# [Выбрать]
  1. using System;
  2. using System.Reflection;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using AcEd = Autodesk.AutoCAD.EditorInput;
  9. using AcRx = Autodesk.AutoCAD.Runtime;
  10. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  11. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  12. using AcGe = Autodesk.AutoCAD.Geometry;
  13.  
  14. //////////////////////////////////////////////////////////////////////////
  15. //  Необходимо подключить ссылку на AcMPolygonMGD.dll !!!
  16. //////////////////////////////////////////////////////////////////////////
  17.  
  18. [assembly: CommandClass(typeof(MakeContour.MyCommands))]
  19.  
  20. namespace MakeContour
  21. {
  22.  
  23.   public class MyCommands
  24.   {
  25.     static MyCommands()
  26.     {
  27.       AcRx.SystemObjects.DynamicLinker.LoadModule("AcMPolygonObj" + AcAp.Application.Version.Major + ".dbx", false, false);
  28.     }
  29.     [CommandMethod("TestPointInContour")]
  30.     public void TestPointInContour()
  31.     {
  32.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  33.       AcDb.Database db = doc.Database;
  34.       AcEd.Editor ed = doc.Editor;
  35.       AcEd.PromptPointOptions pr = new AcEd.PromptPointOptions("\nУкажите точку: ");
  36.       AcEd.PromptPointResult res = ed.GetPoint(pr);
  37.       if (res.Status != AcEd.PromptStatus.OK) return;
  38.       AcEd.PromptEntityOptions pre = new AcEd.PromptEntityOptions("\nУкажите контур: ");
  39.       pre.SetRejectMessage("Это не контур (полилиния)");
  40.       pre.AddAllowedClass(typeof(AcDb.Polyline), true);
  41.       AcEd.PromptEntityResult rese = ed.GetEntity(pre);
  42.       if (rese.Status != AcEd.PromptStatus.OK) return;
  43.       using (AcDb.MPolygon mp = new AcDb.MPolygon()) {
  44.         using (AcDb.Polyline poly = rese.ObjectId.Open(AcDb.OpenMode.ForRead) as AcDb.Polyline) {
  45.           try {
  46.             mp.AppendLoopFromBoundary(poly, true, AcGe.Tolerance.Global.EqualPoint);
  47.             if (mp.IsPointOnLoopBoundary(res.Value, 0, AcGe.Tolerance.Global.EqualPoint)) {
  48.               ed.WriteMessage("\nТочка на границе контура!");
  49.             } else if (mp.IsPointInsideMPolygon(res.Value, AcGe.Tolerance.Global.EqualPoint).Count > 0) {
  50.               ed.WriteMessage("\nТочка внутри контура!");
  51.             } else {
  52.               ed.WriteMessage("\nТочка вне контура!");
  53.             }
  54.           } catch { }
  55.         }
  56.       }
  57.     }
  58.   }
  59. }
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 24-09-2014, 14:03:05
Спасибо Александр  за помощь! Очень выручили. С меня пиво!
Название: Re: Контур AutoCAD 2012
Отправлено: garipov72 от 25-09-2014, 11:42:36
Александр прошу простить меня за навязчивость, где почитать можно за свойства Polyline ?
Название: Re: Контур AutoCAD 2012
Отправлено: Александр Ривилис от 25-09-2014, 23:27:47
где почитать можно за свойства Polyline ?
В смысле? Какие есть методы и свойства у класса Polyline ? Это есть:

1) В документации в составе ObjectARX:

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F6736%2F7842324.1%2F0_e836e_5c019ba9_orig.png&hash=1d034f1d982783d0b97b776741523c54)

2) В Object Browser внутри Visual Studio:

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F4113%2F7842324.2%2F0_e838e_d453d636_orig.png&hash=739fba2bec8576a607af62788e519f8b)

Название: Re: Контур AutoCAD 2012
Отправлено: Андрей Бушман от 26-09-2014, 11:24:50
следующим вопросом будет: а что это и где это вы смотрите?  ;)