Python & ActiveX/COM Autocad

Автор Тема: Python & ActiveX/COM Autocad  (Прочитано 852 раз)

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

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Python & ActiveX/COM Autocad
« : 17-06-2017, 13:17:27 »
Рад приветствовать вас коллеги! Python это язык программирования высокого уровня, который ввиду простоты своего синтаксиса приобрел на сегодняшний день огромную армию пользователей и помогает решать широкий круг задач из различных сфер нашей жизни. Проектирование также не осталось в стороне. В этой теме я хочу делиться с читателями своим опытом использования Python для Autocad. Попытки использовать Питон для Автокад конечно же предпринимались и раньше, нашим соотечественником Романом Харитоновым даже была написана библиотека pyautocad(https://pypi.python.org/pypi/pyautocad), но я покажу более простой способ подключения к Автокад. Начну пожалуй со своего первого урока из цикла "Python for Engineers", который посвящен подключению к Автокад:



А это сам код:
Код - Python [Выбрать]
  1. from math import cos, sin, pi
  2. import System
  3. from System import Array
  4. app = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application")
  5. AcDoc = app.ActiveDocument
  6. mSp = AcDoc.ModelSpace
  7.  
  8. a = 100
  9. fi = range(0,360,10)
  10. r = 4
  11.  
  12. for i in fi:
  13.         x = (a/360.0)*i*cos(i*pi/180.0)
  14.         y = (a/360.0)*i*sin(i*pi/180.0)
  15.         pt = Array[float]([x,y,0])
  16.         mSp.AddCircle(pt,r*(1+i/360.0))

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

  • Administrator
  • *****
  • Сообщений: 6827
  • Карма: 753
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #1 : 17-06-2017, 18:18:16 »
Тему закрепил, чтобы её легче было найти. Рекомендую побольше кода выкладывать здесь на форуме, так как с youtube'овского ролика переписывать его не слишком удобно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #2 : 17-06-2017, 18:22:00 »
Тему закрепил, чтобы её легче было найти. Рекомендую побольше кода выкладывать здесь на форуме, так как с youtube'овского ролика переписывать его не слишком удобно.

Спасибо! Это собственно весь код, который был показан в ролике) могу еще добавить макрос кнопки
Код - Auto/Visual Lisp [Выбрать]
  1. (startapp "C:/Program Files (x86)/IronPython 2.7/ipyw.exe" "g:/Lessons/!PythonForIngeneers/Py4Eng01PythonAutocad/Py4Eng_PythonAutocad.py")

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

  • Administrator
  • *****
  • Сообщений: 6827
  • Карма: 753
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #3 : 17-06-2017, 18:24:31 »
Спасибо! Это собственно весь код, который был показан в ролике
Это было моё пожелание на будущее. Надеюсь, что это будет не единственный урок. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #4 : 17-06-2017, 18:26:15 »
Спасибо! Это собственно весь код, который был показан в ролике
Это было моё пожелание на будущее. Надеюсь, что это будет не единственный урок. :)
Будем стараться

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #5 : 18-06-2017, 19:42:33 »
Ну вот, не прошло и года, и новый ролик, вставка выносок Autocad с автоматической нумерацией:



Код - Python [Выбрать]
  1. ### Autocad MLeaders Insertion
  2. ### ©2017, Khasan Mamaev
  3. ### www.dynamobim.ru
  4.  
  5. import System
  6.  
  7. marsh = System.Runtime.InteropServices.Marshal
  8. app = marsh.GetActiveObject("Autocad.Application")
  9. aDoc = app.ActiveDocument
  10. mSp = aDoc.ModelSpace
  11.  
  12. def ptA(p,x1,y1):
  13.         return System.Array[float]([p[0],p[1],p[2],p[0]+x1,p[1]+y1,p[2]])
  14.  
  15. x1 = 500
  16. y1 = 500
  17. p0 = System.Array[float]([0,0,0])
  18.  
  19. pref = aDoc.Utility.GetString(False, "Enter prefix: ")
  20. j = aDoc.Utility.GetInteger("Enter start num: ")
  21.  
  22. while True:
  23.         pt = aDoc.Utility.GetPoint(p0,'GetPoint: ')
  24.         points = ptA(pt,x1,y1)
  25.         lead = mSp.AddMLeader(points, 0)
  26.         lead.TextString = pref + str(j)
  27.         j += 1

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #6 : 03-07-2017, 22:49:30 »
Записал ролик с инструкцией как подключать IronPython к Notepad++


Оффлайн dlobyntsev

  • ADN OPEN
  • Сообщений: 3
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #7 : 05-11-2017, 16:03:23 »
Доступ к AutoCAD можно получить не только из IronPython, дальнейшее развитие которого, мягко говоря, находится под вопросом, но и из стандартной реализации Python, используя модуль pywin32 https://sourceforge.net/projects/pywin32:

Код - Python [Выбрать]
  1. import win32com.client
  2. app = win32com.client.Dispatch("AutoCAD.Application")
  3.  
Дальше - всё по COM модели
« Последнее редактирование: 05-11-2017, 16:51:42 от Александр Ривилис »

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #8 : 05-11-2017, 16:32:35 »
Такой способ подключения из Питон к Автокад для меня не секрет, но возникают трудности при создании дотнетовских массивтв необходимых для СОМ. Ну и разговоры о скорой кончине АйронПайтон имеют давнюю историю, однако АйронПайтон не прекращают прикручивать к различным серьёзным программных  комплексам.

Оффлайн dlobyntsev

  • ADN OPEN
  • Сообщений: 3
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #9 : 06-11-2017, 16:04:18 »
Массивы достаточно просто создаются, наример один из самых распространенных случаев - преобразование в массив чисел с плавающей точкой (variant array of doubles) для координат:

Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import VT_R8, VT_ARRAY
  3. pythoncoord = [x, y, z]
  4. acadcoord = win32com.client.VARIANT(VT_ARRAY | VT_R8, pythoncoord)
IronPython, к сожалению, продолжают прикручивать к различным серьёзным программных комплексам, потому что другой нормально работающей реализации Python для .NET на данный момент просто не существует. Есть несколько проектов, типа pythonnet, но без танцев с бубном они с тем же автокадом не работают. IronPython вряд ли в обозримом будущем перейдёт на поддержку Python 3x, постепенно поддержка ветки 2х будет свёрнута в первую очередь со стороны разработчиков различных модулей (а множество доступных модулей практически на все случаи жизни - одно из самых весомых преимуществ Python для инженера, когда разработка программ - возможность повысить производительность и облегчить себе жизнь). Автодеск, например, с IronPython в Revit, наступает ровно на те же грабли, что и с LISP в автокаде. Кому сейчас реально нужен лисп вне автокада? Никому. Но заменить его чем-то невозможно - у пользователей просто горы кода на лиспе накопилось за все годы.
Для инженера же Python - один из лучших языков за счёт относительной простоты и наличия огромного количества модулей.
« Последнее редактирование: 06-11-2017, 17:02:44 от dlobyntsev »

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

  • Administrator
  • *****
  • Сообщений: 6827
  • Карма: 753
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #10 : 06-11-2017, 17:02:15 »
dlobyntsev
У меня в подписи написано как следует форматировать код на форуме. Прошу ознакомится и принять к сведению.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #11 : 07-11-2017, 11:03:47 »
Массивы достаточно просто создаются, наример один из самых распространенных случаев - преобразование в массив чисел с плавающей точкой (variant array of doubles) для координат:

Код - Python [Выбрать]
import win32com.client
from pythoncom import VT_R8, VT_ARRAY
pythoncoord = [x, y, z]
acadcoord = win32com.client.VARIANT(VT_ARRAY | VT_R8, pythoncoord)
IronPython, к сожалению, продолжают прикручивать к различным серьёзным программных комплексам, потому что другой нормально работающей реализации Python для .NET на данный момент просто не существует. Есть несколько проектов, типа pythonnet, но без танцев с бубном они с тем же автокадом не работают. IronPython вряд ли в обозримом будущем перейдёт на поддержку Python 3x, постепенно поддержка ветки 2х будет свёрнута в первую очередь со стороны разработчиков различных модулей (а множество доступных модулей практически на все случаи жизни - одно из самых весомых преимуществ Python для инженера, когда разработка программ - возможность повысить производительность и облегчить себе жизнь). Автодеск, например, с IronPython в Revit, наступает ровно на те же грабли, что и с LISP в автокаде. Кому сейчас реально нужен лисп вне автокада? Никому. Но заменить его чем-то невозможно - у пользователей просто горы кода на лиспе накопилось за все годы.
Для инженера же Python - один из лучших языков за счёт относительной простоты и наличия огромного количества модулей.

Про богатство библиотек Питон я в курсе, поскольку пользуюсь для своей работы Jupyter Notebook. Если АйронПайтон будет убит, то это будет крайне прискорбно, но думаю 3-4 года у нас еще есть, а за это время можно сделать кучу всего, дальше посмотрим. Про создание подобных массивов не знал, спасибо за информацию. Буду чаще использовать работу с СОМ из чистого Питона, очень уж хочется использовать модули numpy, scipy и т п. Кстати, недавно закостылил синтез Питон и АйронПитон, осуществил работу с Автокад из Юпитер ноутбука, в ближайшее время покажу на своем канале.

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

  • ADN Club
  • Сообщений: 31
  • Карма: 6
    • Конструктивный диалог
  • Skype: wolfram222
Re: Python & ActiveX/COM Autocad
« Ответ #12 : 13-11-2017, 12:14:55 »
dlobyntsev,

Можно ли в чистом Питоне осуществить этот код:

Код - Python [Выбрать]
  1. import System
  2. from System import Array
  3. import clr
  4. clr.AddReferenceToFileAndPath('C:/Program Files/Autodesk/AutoCAD 2016/Autodesk.AutoCAD.Interop.Common')
  5. from Autodesk.AutoCAD.Interop.Common import AcadEntity, AcBooleanType
  6.  
  7. app = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application")
  8. aDoc = app.ActiveDocument
  9. sset = aDoc.PickfirstSelectionSet
  10. msp = aDoc.ModelSpace
  11.  
  12. elems = list(iter(sset))
  13. def ptA(X,Y,Z):
  14.         return Array[float]([X, Y, Z])
  15.  
  16. def faceToPline(face):
  17.         return msp.AddPolyline(face.Coordinates)
  18.  
  19. def plineToRegion(pl):
  20.         entArr = Array.CreateInstance(AcadEntity,1)
  21.         entArr.SetValue(pl,0)
  22.         return msp.AddRegion(entArr)   
  23.  
  24. def centArea(x):
  25.         return [x.Centroid[0], x.Centroid[1], x.Area]
  26.  
  27. inter = elems[0].Boolean(AcBooleanType.acIntersection, elems[1])

Оффлайн dlobyntsev

  • ADN OPEN
  • Сообщений: 3
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #13 : 13-11-2017, 16:26:50 »
Можно, код с комментариями ниже:
Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import VT_R8, VT_ARRAY, VT_DISPATCH
  3.  
  4. app = win32com.client.Dispatch("AutoCAD.Application")
  5. aDoc = app.ActiveDocument
  6. msp = aDoc.ModelSpace
  7.  
  8. #немного модифицировал функцию ptA(), теперь она преобразует в variant array of doubles
  9. # все аргументы, в т.ч. и представленные в виде списка или кортежа
  10. def convert_coordinates(*args):
  11.     """
  12.    Функция преобразования координат в формат AutoCAD
  13.    :param args: координаты для преобразования, допустима передача списка или кортежа
  14.    :return: Координаты в формате AutoCAD
  15.    """
  16.     if isinstance(args[0], (list, tuple)):
  17.         coords = [item for item in args[0]]
  18.     else:
  19.         coords = args
  20.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)
  21.  
  22. def faceToPline(face):
  23.     #из кода постом выше непонятно, в каком виде передаётся .Coordinates
  24.     #будет работать при условии, что face.Coordinates - это последовательность, список или кортеж
  25.     #не менее чем из шести чисел. Количество аргументов кратно 3 - ограничения .AddPolyline()
  26.     #возможно, необходимы дополнительные преобразования
  27.     return msp.AddPolyline(convert_coordinates(face.Coordinates))
  28.  
  29. def plineToRegion(pl):
  30.     msp.AddRegion(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [pl]))
  31.  
  32. #из кода постом выше непонятно, как работает функция
  33. def centArea(x):
  34.     return [x.Centroid[0], x.Centroid[1], x.Area]
  35.  
  36. #будет работать при условии, что в списке elems содержаться объекты AutoCAD
  37. #возможно, потребуется преобразование win32com.client.VARIANT(VT_DISPATCH, obj)
  38. #для elems[0] и elems[1]
  39. inter = elems[0].Boolean(2, elems[1])
Вообще, основная проблема работы с AutoCAD через COM - преобразование типов данных, но всё вроде решаемо.