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

ADN Club => AutoCAD .NET API => Тема начата: Tatiana85 от 25-10-2014, 19:35:55

Название: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 25-10-2014, 19:35:55
Я никогда раньше не сталкивалась с AutoCADом, но появилась задача написать приложение С#.net, которое будет из текущего чертежа вытаскивать периметр детали.
На чертеже обычно одна деталь,  что то типа длинного прямоугольника или 2х соединенных под углом. В детали присутствуют сквозные отверстия. Надо сложить все ее длины, и если в ней есть отверстия - то и их тоже.  Грубо говоря надо узнать длину распила при изготовлении этой детали.
Пока что я смогла только создать простенькую dll, которую можно подгрузить в AutoCAD. Что делать дальше непонятно.

Мне хотелось бы чтобы эта dll подгружалась в AutoCAD при старте и отзывалась на горячие клавиши. Например, выделили деталь, нажали ctr+A -> вызвался метод ddl, который считает периметр.

Но самое главное, абсолютно непонятно как вытаскивать длины детали. Надо обращаться к самому документу чертежа или в базе данных? Может кто встречал примеры? Как проходить по внутренним частям детали? 
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Дима_ от 25-10-2014, 22:08:39
В автокаде нет "деталей", есть линии, полилинии, области, окружности, дуги элипсы, 3dтела и пр. - надо для начала определиться что есть ваша "деталь".
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 26-10-2014, 00:48:02
Приветствую на форуме.
Абсолютно согласен с Димой. Без знания того, что такое есть "деталь" решить поставленную задачу не получится. Поэтому ждём пример такой детали (dwg-файл).
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 26-10-2014, 10:28:38
Пока у меня есть  4  типа  деталей
Заказчику надо узнать длину распила, которая потребуется, чтобы изготовить эту деталь. Т.е. сумма всех внешних линий + длина внутренних  окружностей и эллипсов.
 
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Дима_ от 26-10-2014, 12:52:51
Я не очень ухватываю что такое "длинна распила", судя по всему Вы хотите посчитать ход фрезы, но это не будет длинная всех линий - т.к. фреза ваша вряд-ли диаметром 0.1 мм, то есть окружности она вырезает простым сверлением, а продольне фрезеровки того-же диаметра - за один проход, а не за два (вдоль периметра). Но это только мои фантазии - быть может у Вас все совсем не так.
По существу вопроса - получить длины линейных объектов достаточно просто - все они наследуются от класса Curve? То есть Вам надо "пробежать" по всем примитивам (выбранным пользователем, или которые есть в модели - в зависимости от задачи) и к тем которые преобразуются в класс Curve применить curve.GetDistanceAtParameter(curve.EndParam) где curve - объект класса Curve. После чего их сложить и выдать результат в необходимой форме.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 26-10-2014, 13:51:14
Пример подсчета полной длины всех линий в Пространстве Модели:
Код - 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 AcRx = Autodesk.AutoCAD.Runtime;
  8. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  9. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  10. using AcGe = Autodesk.AutoCAD.Geometry;
  11. using AcEd = Autodesk.AutoCAD.EditorInput;
  12.  
  13. [assembly: CommandClass(typeof(TestLength.Commands))]
  14.  
  15. namespace TestLength
  16. {
  17.   public class Commands
  18.   {
  19.     [CommandMethod("TLen")]
  20.     static public void TLen()
  21.     {
  22.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  23.       AcEd.Editor ed = doc.Editor;
  24.       AcDb.Database db = doc.Database;
  25.       double nTotalLength = 0;
  26.       using (AcDb.BlockTable bt = db.BlockTableId.Open(AcDb.OpenMode.ForRead) as AcDb.BlockTable) {
  27.         AcDb.ObjectId modelId = bt[AcDb.BlockTableRecord.ModelSpace];
  28.         using (AcDb.BlockTableRecord btr = modelId.Open(AcDb.OpenMode.ForRead) as AcDb.BlockTableRecord) {
  29.           foreach (AcDb.ObjectId id in btr) {
  30.             if (id.ObjectClass.IsDerivedFrom(AcRx.RXObject.GetClass(typeof(AcDb.Curve)))) {
  31.               using (AcDb.Curve curve = id.Open(AcDb.OpenMode.ForRead) as AcDb.Curve) {
  32.                 nTotalLength += curve.GetDistanceAtParameter(curve.EndParam);
  33.               }
  34.             }
  35.           }
  36.         }
  37.       }
  38.       ed.WriteMessage("\nСуммарная длина: {0}", nTotalLength);
  39.     }
  40.   }
  41. }
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 26-10-2014, 18:31:17
Круто, спасибо!  Завтра попробую.  А возможно подключаться к AutoCAD  из приложения без создания плагина?

Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 26-10-2014, 19:56:33
А возможно подключаться к AutoCAD  из приложения без создания плагина?
Можно. Но не нужно.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Дима_ от 27-10-2014, 00:15:01
До кучи - Вашу задачу можно решить и без программирования вообще. Честно говоря меня несколько пугают Ваши строки
Я никогда раньше не сталкивалась с AutoCADом, но появилась задача написать приложение С#.net, которое будет ...
да и насчет "распила детали" тут "явно не все явно".
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 00:18:21
До кучи - Вашу задачу можно решить и без программирования вообще.
Кстати, как вариант мой GeomProps (http://www.maestrogroup.com.ua/support/GeomProps.zip). Нажал Ctrl+A и смотришь результат в Панели свойств.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 27-10-2014, 17:48:36
все работает, но теперь не понятно как получить полученные значения назад в  .net приложение.
Если вызываю TLen из приложения  - ругаются библиотеки Autocada.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 18:11:44
не понятно как получить полученные значения назад в  .net приложение.
Что имеется в виду под ".net приложение." ? Это внешний exe-файл? Тогда этот код нельзя никак вызвать из него. В таком виде и с этими библиотеками его можно использовать только в сборке, загружаемой внутрь AutoCAD.

Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 27-10-2014, 18:16:09
Да, .exe файл должен вытащить этот периметр для дальнейших подсчетов
Т.е. плагин мне не подходит? А тогда как?
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 18:22:35
Детали всегда в формате dxf-файла? Может тогда AutoCAD вообще не нужен и поискать готовую библиотеку для чтения dxf-файлов. Например, http://www.codeproject.com/Articles/156522/DXF-Import-NET-Read-and-View-AutoCAD-Format-Files
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 27-10-2014, 18:28:39
похоже что нужен, т.к. они хотят получать данные в процессе рисования. Т.е. похоже могут еще и не сохранить чертеж. 
Мне надо как то достучаться до объектной модели autocad. Я видела примеры на VBA через comObject. А вот как это сделать в C# и какие библиотеки для autocad 2010 нужны - что то не могу найти.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 18:43:55
Для этой цели нужно подключить Autodesk.AutoCAD.Interop.dll и Autodesk.AutoCAD.Interop.Common.dll. Они есть в подкаталогах inc-win32 и inc-x64 в составе ObjectARX SDK (для AutoCAD 2010 нужно брать ObjectARX SDK 2010: http://download.autodesk.com/akdlm/esd/dlm/objectarx/ObjectARX_2010_Win_64_and_32Bit.exe )
Сразу предупрежу, что такой короткий и красивый код как у меня в этом случае не получится, т.к. в ActiveX/COM модели AutoCAD нужно будет для каждого типа примитива вычислять его длину и специальных методов для этого нет.
Возможен второй вариант. Всё-таки ты делаешь сборку, которая грузится твоим exe-файлом в AutoCAD, запускается команда TLEN, которая кроме того что считает суммарную длину еще устанавливает системную переменную USERR1 этим значением (используя Application.SetSystemVariable("USERR1",...), а ты из exe-файла через ActiveX/COM метод AcadDocument.GetVariable("USERR1") считываешь это значение.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 18:50:23
P.S.: Хочу сказать, что ты слишком усложняешь задачу. Видимо от незнания AutoCAD. И описываешь постановку задачи очень расплывчато. Допустим чертится деталь. Как ты собираешься из своего отдельного exe-файла посчитать её длину? А вдруг открыты сразу два AutoCAD? А вдруг в AutoCAD открыты сразу несколько чертежей? С каким из них работать? Нужно написать нормальную постановку задачи и описать условия, в которых она может работать.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 27-10-2014, 19:23:33
Сорри, я и вправду autocad вот в первый раз увидела.

Нужно  windows приложение (.exe файл) в котором есть кнопка, которая  обращается к открытому, текущему чертежу в autocad.
В автокаде выделяем мышкой  деталь  (пока  не понимаю зачем)
нажимаем enter
Считается периметр и отображается  в  приложении в текстовом поле.
кроме периметра еще нужны длина и ширина детали, что пока вообще непонятно
вот как то так
 
 
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 19:40:07
В автокаде выделяем мышкой  деталь  (пока  не понимаю зачем)
нажимаем enter
Не получится. Деталь состоит из нескольких примитивов AutoCAD (в данном случае это было несколько отрезков, дуги и окружности). Так что одним нажатием мышки это сделать не получится.
P.S.: Меняйте постановку задачи. Всё нужно делать внутри AutoCAD без никаких дополнительных exe-файлов.
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Tatiana85 от 27-10-2014, 21:25:44
Большое спасибо за наводку на ObjectARX. Сейчас подключилась  и смогла вытащить выделенные примитивы. Хотя да, использовать Autocad было бы правильнее, переговорю с заказчиком.  А еще лучше было бы вытаскивать из  dxf файла.
 
Название: Re: Подсчет периметра детали AutoCAD 2010
Отправлено: Александр Ривилис от 27-10-2014, 21:35:19
Хотя да, использовать Autocad было бы правильнее, переговорю с заказчиком.
Обязательно! К сожалению Ваше и заказчика незнание AutoCAD, а точнее возможностей его API, приводит к неправильной (и как минимум сложно реализуемой) постановке задачи. В качестве особенности сразу подскажу, что если работать внутри AutoCAD и обратится к AutoCAD из внешнего приложения через ActiveX/COM, то AutoCAD откажется выполнять ваше действие (результат - exception). Потребуется ожидание освобождения AutoCAD и еще куча разных тонкостей...
Вот пример элементарного обращения к AutoCAD (на C++): http://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html
Там одни сплошные проверки на то, что AutoCAD готов выполнить ваши действия.