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

ADN Club => VBA => Тема начата: Khasan Mamaev от 17-06-2017, 13:17:27

Название: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 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))
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 17-06-2017, 18:18:16
Тему закрепил, чтобы её легче было найти. Рекомендую побольше кода выкладывать здесь на форуме, так как с youtube'овского ролика переписывать его не слишком удобно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 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")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 17-06-2017, 18:24:31
Спасибо! Это собственно весь код, который был показан в ролике
Это было моё пожелание на будущее. Надеюсь, что это будет не единственный урок. :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 17-06-2017, 18:26:15
Спасибо! Это собственно весь код, который был показан в ролике
Это было моё пожелание на будущее. Надеюсь, что это будет не единственный урок. :)
Будем стараться
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 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
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 03-07-2017, 22:49:30
Записал ролик с инструкцией как подключать IronPython к Notepad++

Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 05-11-2017, 16:03:23
Доступ к AutoCAD можно получить не только из IronPython, дальнейшее развитие которого, мягко говоря, находится под вопросом, но и из стандартной реализации Python, используя модуль pywin32 https://sourceforge.net/projects/pywin32 (https://sourceforge.net/projects/pywin32):

Код - Python [Выбрать]
  1. import win32com.client
  2. app = win32com.client.Dispatch("AutoCAD.Application")
  3.  
Дальше - всё по COM модели
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 05-11-2017, 16:32:35
Такой способ подключения из Питон к Автокад для меня не секрет, но возникают трудности при создании дотнетовских массивтв необходимых для СОМ. Ну и разговоры о скорой кончине АйронПайтон имеют давнюю историю, однако АйронПайтон не прекращают прикручивать к различным серьёзным программных  комплексам.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 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 - один из лучших языков за счёт относительной простоты и наличия огромного количества модулей.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-11-2017, 17:02:15
dlobyntsev
У меня в подписи написано как следует форматировать код на форуме. Прошу ознакомится и принять к сведению.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 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 и т п. Кстати, недавно закостылил синтез Питон и АйронПитон, осуществил работу с Автокад из Юпитер ноутбука, в ближайшее время покажу на своем канале.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 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])
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 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 - преобразование типов данных, но всё вроде решаемо.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 22-11-2017, 16:49:58
Добрый день!
Пишу скрипт на Python  для черчения в Автокаде.
Столкнулся с проблемой - не могу разобраться с COM моделью AutoCAD, а если конкретнее, не могу настроить создаваемый  мной стиль таблиц. 
Код вроде как работает, стиль создается (хотя и не перезаписывает существующий) :

Код - Python [Выбрать]
  1. import win32com.client
  2.  
  3. app = win32com.client.Dispatch("AutoCAD.Application")
  4. aDoc = app.ActiveDocument
  5. mSp = aDoc.ModelSpace
  6.  
  7. dicts = aDoc.Database.dictionaries
  8.  
  9. ts = dicts.Item("acad_tablestyle")
  10. ts.AddObject("NewStyle", "AcDbTableStyle")

Далее, допустим, мне нужно назначить высоту текста по умолчанию для ячеек с типом  "заголовок" или "данные" этого нового табличного стиля NewStyle.  В справке  по модели COM Автокада читаю:

Цитировать
object.SetTextHeight(rowTypes, TextHeight)

ObjectTable, TableStyle
The object this method applies to.
rowTypesLong; the row types to change.
TextHeight
Double; the text height to use for the specified row types.

Не могу разобраться, что это за rowTypes, и как это реализовать через Пайтон (либо IronPython, либо CPython + win32com)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-11-2017, 17:50:12
Electric,
Приветствую на форуме!
1. Прочитай у меня в подписи как следует форматировать код на форуме и придерживайся этого правила.
2. Ты нашёл неудачную документацию. Удачная здесь: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-35CC52D6-03C1-48EE-90A3-97DFBBAC33C3-htm.html
В частности там сказано, что rowTypes - это одно из значений перечисления (числовые значения я подставил сам):

Код - C++ [Выбрать]
  1. enum AcRowType
  2.     {
  3.         acUnknownRow    = 0,
  4.         acDataRow       = 1,
  5.         acTitleRow      = 2,
  6.         acHeaderRow     = 4
  7.     }   AcRowType;
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 22-11-2017, 19:05:34
Electric,
Приветствую на форуме!

Спасибо за ссылку, помогло!
Но остается проблема, я не могу понять, как реализовать на Пайтоне эту команду  из документации VBA:

Код - Visual Basic [Выбрать]
  1. customObj.SetTextHeight AcRowType.acDataRow + AcRowType.acTitleRow, 1.3

К примеру. у меня все работает, когда передаю "1" или "2" по отдельности , назначая моему табличному стилю newTabStyle высоту 2,5:

Код - Python [Выбрать]
  1. newTabStyle.SetTextHeight("2", 2.5)

 но как передать эти два значения сразу? При попытке передать их в виде списка или кортежа выдает ошибку, когда я передаю "1"+"2" - функция игнорирует  один из них.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-11-2017, 19:18:34
К примеру. у меня все работает, когда передаю "1" или "2" по отдельности , назначая моему табличному стилю newTabStyle высоту 2,5:

Код - Python [Выбрать]

    newTabStyle.SetTextHeight("2", 2.5)


 но как передать эти два значения сразу? При попытке передать их в виде списка или кортежа выдает ошибку, когда я передаю "1"+"2" - функция игнорирует  один из них.
Зачем их передавать сразу?
Вот так тебя не устроит:
Код - Python [Выбрать]
  1. newTabStyle.SetTextHeight(1, 2.5)
  2. newTabStyle.SetTextHeight(2, 2.5)

???

Хотя так тоже должно работать:
Код - Python [Выбрать]
  1. newTabStyle.SetTextHeight(3, 2.5)

Не понял зачем ты пытаешься преобразовать число в строку. Этот метод принимает целые числа, а не строки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-11-2017, 05:45:31
Вот так тебя не устроит:

Да, спасибо. В тот раз мне это помогло, разобрался с той проблемой.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-11-2017, 18:03:00
Возник следующий вопрос.
Пользователю нужно выделить какой-то объект в Автокаде, при этом в командной строке  должен отображаться текст вроде "Выделите прямоугольник"

Этот код работает:

Код - Python [Выбрать]
  1. example, _ = aDoc.Utility.GetEntity()

Но этот выдает уже ошибку:

Код - Python [Выбрать]
  1. example, _ = aDoc.Utility.GetEntity('Укажите прямоугольник: ')

Цитировать
example, _ = aDoc.Utility.GetEntity('Укажите объект: ')
  File "<COMObject <unknown>>", line 3, in GetEntity
  File "C:\ProgramData\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
TypeError: The Python instance can not be converted to a COM object

Кроме того, допустим, пользователю нужно выделить не один, а сразу несколько объектов в Автокаде, через какую команду это реализуется? Если смотрю  в справке (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-DE118C17-4567-48CF-8EFA-CABB52A27275-htm.html) по AcadUtility, то там из методов  в основном только выделение единичного объекта или получение чисел, строк, углов и т.п.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 27-11-2017, 18:09:55
Можно получить предварительно выбранные объекты вот так sset = AcDoc.PickfirstSelectionSet
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-11-2017, 18:16:19
Кроме того, допустим, пользователю нужно выделить не один, а сразу несколько объектов в Автокаде, через какую команду это реализуется?
SelectionSet.SelectOnScreen: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-C4B442A3-D6A9-48FA-8C86-03D49A3B2ED7-htm.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-11-2017, 18:45:03
Но этот выдает уже ошибку:

Код - Python [Выбрать]

    example, _ = aDoc.Utility.GetEntity('Укажите прямоугольник: ')
Я не специалист по Python, но может быть так:
Код - Python [Выбрать]
  1. returnObj = aDoc.Utility.GetEntity("Укажите прямоугольник: ")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-11-2017, 19:16:58
Но этот выдает уже ошибку:

Код - Python [Выбрать]

    example, _ = aDoc.Utility.GetEntity('Укажите прямоугольник: ')
Я не специалист по Python, но может быть так:
Код - Python [Выбрать]
  1. returnObj = aDoc.Utility.GetEntity("Укажите прямоугольник: ")

Ну я так понимаю, aDoc.Utility.GetEntity  возвращает и Объект и  координату точки сразу.  Вместе  они с точки зрения Python  являются кортежем tuple, я просто выбирал объект как первую часть кортежа. Без этого выражения у меня ошибка.

Цитировать
AttributeError: 'tuple' object has no attribute 'Layer'
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-11-2017, 19:24:16
Так. Я был не прав:
Код - Visual Basic [Выбрать]
  1. object.GetEntity Object, PickedPoint [, Prompt]
Т.е. первые два параметра - это объект и точка и только третий - это подсказка типа "Укажите прямоугольник: "
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-69164FAA-F3C7-47A4-962C-5F4B2D5BC583-htm.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 30-11-2017, 10:46:46
Для того, чтобы метод GetEntity корректно работал с подсказкой при обращении к COM Autocad через pywin32, необходимо вызвать его следующим образом:
Код - Python [Выбрать]
  1. result = aDoc.Utility.GetEntity(None, None, "Укажите прямоугольник: ")
  2. picked_object = result[0]
  3. picked_point = result[1]
Выглядит неочевидно, видимо из-за особенностей реализации вызовов в pywin32, но работает. Причем если вместо None подставить переменные, в них ничего не запишется.
Метод возвращает кортеж из объекта и координаты точки. Координаты точки также представляют собой трёхэлементный кортеж: (picked_object, (X, Y, Z))
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 30-11-2017, 19:25:36
Спасибо. Разобрался.

Еще вопрос.
В автокаде во многих стандартных командах в командной строке есть возможность выбора опций.
К примеру, когда запускаем стандартное черчение прямоугольника, возникают опции  "Фаска", "Уровень", "Сопряжение", "Толщина", "Ширина", которые можно щелкнуть или набрать их ключевую букву с клавиатуры.

Возможно ли через COM  сделать подобного рода опции для своих текстовых команд?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 30-11-2017, 22:48:36
В лиспе это делается через пару initget и getkword. В .NET, насколько я помню - PromptOptions. Как это делать через COM: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2018/ENU/AutoCAD-ActiveX/files/GUID-2F1938FE-DE63-456B-9C29-612DA4539EB0-htm.html + https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-5D322A2D-3BC9-44F4-AFFD-C5770A357858-htm.html (ИМХО)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 01-12-2017, 11:47:44
Опции для команд через COM, конечно, доступны. При использовании методов Utility.GetInteger, Utility.GetReal, GetString и т.п. достаточно сформировать строку запроса особым образом. Для автокада наличие в запросе текста вида [Опция1/<оПция2>/опЦия3] означает, что в запросе имеются три опции, причем вторая - опция по-умолчанию. Но, как всегда, дьявол кроется в деталях. И имя его в данном случае - обработка ошибок. Например, ввод опции при использовании Utility.GetReal вызывает ошибку, т.к. автокад ожидает ввода числа, а нажатие опции - это ввод строки. Необходимо этот случай предусмотреть и обработать. Делается это следующим образом:
Код - Python [Выбрать]
  1. from pythoncom import com_error
  2. #Инициируем ввод
  3. doc.Utility.InitializeUserInput(128)
  4. #Запрашиваем ввод числа с плавающей точкой
  5. try:
  6.     inputresult = doc.Utility.GetReal("\nВведите число [Опция1/оПция2]"
  7. except com_error as error:
  8.     #Получаем код COM ошибки
  9.     errnumber = error.excepinfo[-1]
  10.     if errnumber == -2145320928: #Была введена строка вместо числа
  11.         #Запрашиваем введённую строку
  12.         inputresult = doc.Utility.GetInput()
  13.         #Проверяем, соответствует ли введенная строка выбору опций
  14.         if inputresult.upper() == "О" or  inputresult.upper() == "ОПЦИЯ1":
  15.             #Код, выполняемый при выборе "Опция1"
  16.             pass
  17.         elif inputresult.upper() == "П" or  inputresult.upper() == "ОПЦИЯ2":
  18.              #Код, выполняемый при выборе "Опция2"
  19.             pass
  20.         else:
  21.             #Код, выполняемый при вводе любых других символов, кроме относящихся к опциям
  22.             #при наличии опции по умолчанию необходимо сопоставить ей ввод пустой строки ""
  23.             pass
  24.     elif errnumber == -2147352567: #Была нажата кнопка Ecs, обработка приведена для примера
  25.         #Код, выполняемый при нажатии Esc
  26.         pass
  27.     else:
  28.         #Код, выполняемый при любых других ошибках
  29.         pass
Я для себя просто написал функции на основе GetString, и преобразую потом введённое в int, float и т.д. уже средствами pyton, при этом внутри функций предусмотрел автоматический конструктор строки запроса для ввода опций, опций по-умолчанию и т.п., чтобы каждый раз не прописывать, с чем сравнивать введенную строку, чтобы понять, была ли выбрана опция.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 01-12-2017, 13:11:54
Опции для команд через COM, конечно, доступны. При использовании методов Utility.GetInteger, Utility.GetReal, GetString и т.п. достаточно сформировать строку запроса особым образом. Для автокада наличие в запросе текста вида [Опция1/<оПция2>/опЦия3] означает, что в запросе имеются три опции, причем вторая - опция по-умолчанию.
Кто сказал? В лиспе, по крайней мере, это не так. И, насколько я помню, в .NET тоже не так.
Вообще-то вот из официальной справки по VBA:
Код - Text [Выбрать]
  1. Sub Example_InitializeUserInput()
  2.     ' This example prompts for user input of a point. By using the
  3.     ' InitializeUserInput method to define a keyword list, the example can also
  4.     ' return keywords entered by the user.
  5.    
  6.     AppActivate ThisDrawing.Application.Caption
  7.    
  8.     On Error Resume Next
  9.    
  10.     ' Define the valid keywords
  11.     Dim keywordList As String
  12.     keywordList = "Line Circle"
  13.    
  14.     ' Call InitializeUserInput to set up the keywords
  15.     ThisDrawing.Utility.InitializeUserInput 128, keywordList
  16.    
  17.     ' Get the user input
  18.     Dim returnPnt As Variant
  19.     returnPnt = ThisDrawing.Utility.GetPoint(, vbLf & "Enter a point [Line/Circle]: ")
  20.     If Err Then
  21.          If StrComp(Err.Description, "User input is a keyword", 1) = 0 Then
  22.          ' One of the keywords was entered
  23.              Dim inputString As String
  24.              Err.Clear
  25.              inputString = ThisDrawing.Utility.GetInput
  26.              MsgBox "You entered the keyword: " & inputString
  27.          Else
  28.              MsgBox "Error selecting the point: " & Err.Description
  29.              Err.Clear
  30.          End If
  31.     Else
  32.         ' Display point coordinates
  33.         MsgBox "The WCS of the point is: " & returnPnt(0) & ", " & returnPnt(1) & ", " & returnPnt(2), , "GetInput Example"
  34.     End If
  35.    
  36. End Sub
Обрати внимание на InitializeUserInput и его обработку.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 01-12-2017, 13:39:29
Тут ещё накладывается не всегда понятное взаимодействие Python с COM через pywin32.
Когда я с вводом разбирался, особой разницы между
Код - Python [Выбрать]
  1. doc.Utility.InitializeUserInput(128, "Line Circle")
и
Код - Python [Выбрать]
  1. doc.Utility.InitializeUserInput(128)
для последующей обработки не заметил, хотя, может, и упустил что-то.
Моя фраза
Цитировать
достаточно сформировать строку запроса особым образом
относится только к тому,что запрос в командной строке будет выглядеть как запрос с опциями, далее я как раз и показываю, что необходимо предусмотреть в коде, чтобы опции запроса не только выглядели, как опции, но и работали соответствующим образом.
Код из официальной справки VBA действует абсолютно по той же схеме, обрабатывая ошибки при вводе значений опций:
Код - Visual Basic [Выбрать]
  1. If Err Then
  2.          If StrComp(Err.Description, "User input is a keyword", 1) = 0 Then
просто я вместо текста ошибки "User input is a keyword" отслеживаю её по коду -2145320928
Код - Python [Выбрать]
  1. errnumber = error.excepinfo[-1]
  2.     if errnumber == -2145320928:
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 01-12-2017, 14:08:43
Я в питоне дуб-дубом, немного только соображаю на предмет COM-взаимодействия :)
Насколько я понимаю, если не ввести ключевые слова, пользователь получает возможность вводить любую абракадабру.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 01-12-2017, 14:22:28
Пользователь в любом случае имеет возможность ввести любую абракадабру, просто если ввод инициализирован как
Код - Python [Выбрать]
  1. doc.Utility.InitializeUserInput(128, "Line Circle")
то при обработке ошибки "User input is a keyword" метод doc.Utility.GetInput() вернет "Circle" при вводе C, c, Circle или CIRCLE, "Line" при вводе L, l, Line или LINE. В остальных случаях - то, что ввёл пользователь.
А если ввод инициализирован как
Код - Python [Выбрать]
  1. doc.Utility.InitializeUserInput(128)
метод doc.Utility.GetInput() будет всегда возвращать то, что ввёл пользователь.
Вся разница только в обработке пользовательского ввода, но она не принципиальна, т.к. обработку, аналогичную той, что выполняет autocad, можно без проблем выполнить и в своём коде.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 08-12-2017, 12:13:17
Заметил сегодня такую ошибку. Вызываю выделение мышью объектов:

Код - Python [Выбрать]
  1. aDoc.Utility.Prompt("Укажите область на экране")
  2. selection = aDoc.SelectionSets.Add("test")
  3. selection.SelectOnScreen()

Если я выделяю область мышью - все работает. Но если я хочу выделить все объекты и по привычке нажимаю сочетание CNTRL+A - команда выделения в автокаде тут же прерывается. Далее по коду в Python при обращении к selection выдает ошибку, как если selection пуст:

Цитировать
File "C:\Program Files\Python\lib\site-packages\win32com\client\dynamic.py", line 252, in __getitem__
    raise TypeError("This object does not support enumeration")

Возможно ли как-то обработать это исключение в Python  и разрешить выделение сразу всех объектов?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-12-2017, 19:23:42
Но если я хочу выделить все объекты и по привычке нажимаю сочетание CNTRL+A - команда выделения в автокаде тут же прерывается.
Всё правильно. Так и должно быть. У AutoCAD свои правила и их следует соблюдать. Вместо CTRL+A нужно жать _A и пробел/ввод (в английской версии можно просто A (латиница), а в русской В (кириллица)). CTRL+A при стандартных настройках запускает прерывание команды и команду _ai_selall.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 10-12-2017, 15:18:30
Вместо CTRL+A нужно жать _A и пробел/ввод (в английской версии можно просто A (латиница), а в русской В (кириллица)).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-12-2017, 15:51:37
Небольшое уточнение:

    Autocad 2018 Eng - A или a не работают, нужно ввести al или all в любом регистре.
    Autocad 2018 Rus - соответственно не работает _A и _a, необходимы _al или _all в любом регистре, при этом кириллические в, все в любом регистре работают.
Мой промах. A, _A не срабатывают, так как воспринимаются как _ADD, а не как _ALL. В русской локализации же эквивалент _ALL - это Все, а эквивалент _ADD - Добавить, т.е. достаточно одной буквы для того, чтобы понять какая опция выбора введена.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 20-12-2017, 05:51:07
Еще такой вопрос по выделению объектов рамкой.
Не могу разобраться с параметрами выделения в object.SelectOnScreen [FilterType][, FilterData]

К примеру, если я хочу выделить не все объекты, а только отрезки и прямоугольники сразу. Любые варианты вроде этого:

Код - Python [Выбрать]
  1. selection.SelectOnScreen(0, "AcDbPolyline")

выдают ошибку:

Цитировать
File "<COMObject Add>", line 3, in SelectOnScreen
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD', 'Недопустимый аргумент FilterType в SelectOnScreen', 'C:\\Program Files\\AutoCAD\\HELP\\OLE_ERR.CHM', -2145320939, -2147024809), None)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 20-12-2017, 07:55:19
Настоятельно советую изучать справку по VBA - там многое описано:
Код - Visual Basic [Выбрать]
  1. Sub Example_Select()
  2.     ' This example adds members to a selection set, first by crossing and
  3.    ' then by filtering for circles.
  4.    
  5.     ' Create the selection set
  6.    Dim ssetObj As AcadSelectionSet
  7.     Set ssetObj = ThisDrawing.SelectionSets.Add("SSET")
  8.    
  9.     ' Add all object to the selection set that lie within a crossing of (28,17,0) and
  10.    ' (-3.3, -3.6,0)
  11.    Dim mode As Integer
  12.     Dim corner1(0 To 2) As Double
  13.     Dim corner2(0 To 2) As Double
  14.    
  15.     mode = acSelectionSetCrossing
  16.     corner1(0) = 28: corner1(1) = 17: corner1(2) = 0
  17.     corner2(0) = -3.3: corner2(1) = -3.6: corner2(2) = 0
  18.     ssetObj.Select mode, corner1, corner2
  19.    
  20.     ' Add all the Circles to the selection set that lie within the crossing of (28,17,0) and
  21.    ' (-3.3, -3.6,0) by filtering from the current drawing
  22.    Dim gpCode(0) As Integer
  23.     Dim dataValue(0) As Variant
  24.     gpCode(0) = 0
  25.     dataValue(0) = "Circle"
  26.    
  27.     Dim groupCode As Variant, dataCode As Variant
  28.     groupCode = gpCode
  29.     dataCode = dataValue
  30.    
  31.     ssetObj.Select mode, corner1, corner2, groupCode, dataCode
  32.    
  33. End Sub
Тебе нужен последний пример.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 20-12-2017, 17:54:12
Настоятельно советую изучать справку по VBA - там многое описано:

Тебе нужен последний пример.

Насколько я понимаю из VBA, эти gpCode и ataValue(0) - это массивы, в нулевое  значение  которых записываются DXF group code  и значение фильтра соответственно. Когда я пытаюсь то же самое проделать в Python, это не приводит ни к какому  результату, ошибка  та же.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 20-12-2017, 18:04:43
Это не массивы, а Variant'ы, в которые всунуты типовые массивы. Для FilterType - это short (не знаю точно как он обозначатся в Python, но это System.Int16 в .NET), для FilterData это Variant (в данном случае строка "LWPOLYLINE", а не "AcDbPolyline").
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 30-05-2018, 18:17:05
Добрый день!
Требуется начертить график в  определенной пустой области пространства модели автокада, которую я хочу выделить прямоугольником. Хочу сделать диалоговое меню, чтобы выделить эту область.
В данный момент я реализовал это через указание нижней  левой и верхней правой точек с помощью Utility.GetPoint(), для получения крайних координат рамки. Но как-то это не эстетичный метод, возможно ли реализовать это через выделение области прямоугольной рамкой? Стандартное выделение SelectByPolygon, как я понимаю, возвращает только набор объектов, но не координаты.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 30-05-2018, 19:39:17
В данный момент я реализовал это через указание нижней  левой и верхней правой точек с помощью Utility.GetPoint(), для получения крайних координат рамки. Но как-то это не эстетичный метод, возможно ли реализовать это через выделение области прямоугольной рамкой?
Можно. Посмотри в сторону Utility.GetCorner(). Первую точку через Utility.GetPoint(), вторую через Utility.GetCorner().
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 08-06-2018, 16:00:54
Здравстуйте, пытаюсь получить данные из ячейки таблицы используя модуль pywin32.

Код - Python [Выбрать]
  1. tab.GetCellValue(1,1)

Получаю следующую ошибку.

Код - Python [Выбрать]
  1. pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147467263), None)

Смотрю в документацию по функции: Function GetCellValue(row As Long, col As Long)
Т.е. я предполагаю что возможно надо python-овский тип данных int перевести в Long
Как это можно сделать?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-06-2018, 17:01:23
Я не уверен, что проблема в этом, но вроде бы для преобразования в long в Python есть функция long().
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 09-06-2018, 11:54:40
Как я понял long был только в Python 2.
Ещё немного поэкспериментировал:

Код - Python [Выбрать]
  1. >>> tab.GetCellValue([1,1])
  2. TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
  3.  
  4. >>> tab.GetCellValue(1,1,1)
  5. TypeError: GetCellValue() takes from 1 to 3 positional arguments but 4 were given
  6.  
  7. >>> tab.GetCellValue('1','1')
  8. pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147467263), None)
  9.  
  10. >>> win32api.FormatMessage(-2147467263)
  11. 'Не поддерживается\r\n'

Всё таки похоже на ошибку с типами данными как мне кажется.
Вот пример где явно тип данных не верный:

Код - Python [Выбрать]
  1. >>> tab.Move((0,0,0),(1,0,0))
  2. pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147024809), None)
  3.  
  4. >>> win32api.FormatMessage(-2147024809)
  5. 'Параметр задан неверно.\r\n'

Правда код ошибок разный :/
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 09-06-2018, 11:56:37
А если попробовать tab.GetCellValue(1, 1) ?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 09-06-2018, 12:03:10
Пробовал уже Ответ #43 (http://adn-cis.org/forum/index.php?topic=7864.msg32533#msg32533)

Код - Python [Выбрать]
  1. >>> tab.GetCellValue(1, 1)
  2. pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147467263), None)

Попробовал ещё раз, на всякий случай.))
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 09-06-2018, 12:09:25
А
Код - Python [Выбрать]
  1. tab.GetCellValue(0, 0)
?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 09-06-2018, 12:12:43
Код - Python [Выбрать]
  1. >>> tab.Rows
  2. 5
  3. >>> tab.Columns
  4. 3
  5. >>> tab.GetCellValue(0, 0)
  6. pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147467263), None)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 11-06-2018, 10:46:42
Можно Ваш Excel файлик?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 11-06-2018, 12:40:16
Попробуйте так, еще можно воспользоваться библиотекой xlrd

Код - Python [Выбрать]
  1. import win32com.client
  2.  
  3. app = win32com.client.Dispatch("Excel.Application")
  4.  
  5. wb = app.Workbooks[0]
  6.  
  7. sh = wb.ActiveSheet
  8.  
  9. val = sh.Cells(1,1).value
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 11-06-2018, 14:53:03
Повтор сообщения.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 11-06-2018, 14:54:17
Пробовал уже Ответ #43

Код - Python [Выбрать]

    >>> tab.GetCellValue(1, 1)
    pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147467263), None)


Попробовал ещё раз, на всякий случай.))

Речь точно идет об автокаде? Если  да, то предложенный вариант obj.GetCellValue(1, 1)  у меня работает.  Ты  точно находишься в нужном пространстве модели/листа, таблица выполнена как  'AcDbTable'  и имеет достаточный диапазон столбцов/строк, в котором находится запрашиваемая ячейка?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Khasan Mamaev от 11-06-2018, 15:08:21
так это таблица Автокада была?)) прошу прощения
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 12-06-2018, 17:23:43
Речь точно идет об автокаде? Если  да, то предложенный вариант obj.GetCellValue(1, 1)  у меня работает.

Спасибо, что проверили у себя.
Я действительно пытаюсь это реализовать не в AutoCAD-е, а в ZWCAD-е, он претендует на подобие первого но имеет много неприятных особенностей (отличий) и это по видимому ещё одно.
Попробую попытать тех. поддержку. ))
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 12-06-2018, 17:28:04
Я действительно пытаюсь это реализовать не в AutoCAD-е, а в ZWCAD-е
У нас на форуме категорически не обсуждаются "приложения - подобия"!!!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 12-06-2018, 18:34:25
Хорошо, можете удалить тогда всё.  :-X
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 12-06-2018, 19:13:11
Хорошо, можете удалить тогда всё.  :-X
Я оставлю всю эту дискуссию. Она очень поучительна.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 24-06-2018, 18:46:56
Здравствуйте, коллеги!
Я только начинаю осваивать программирование на Python для AutoCAD.
Помогите, пожалуйста, со следующим вопросом.
Пытаюсь успользовать метод AutoCAD.Application.ActiveDocument.Utility.GetEntity().
Ни как не могу пользоваться им в IronPython.
Получилось только при использовании чистого питона с pywin32.
Правда, если пользователь ничего не выбирает, то всеравно получается ошибка.

Код - Python [Выбрать]
  1. >>> import win32com.client
  2. >>> app = win32com.client.Dispatch("AutoCAD.Application")
  3. >>> a = app.ActiveDocument.Utility.GetEntity(None, None, "Select object.")
  4.  
  5. Traceback (most recent call last):
  6.   File "<pyshell#4>", line 1, in <module>
  7.     a = app.ActiveDocument.Utility.GetEntity(None, None, "Select object.")
  8.   File "<COMObject <unknown>>", line 3, in GetEntity
  9.   File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
  10.     result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
  11. com_error: (-2147352567, '\xce\xf8\xe8\xe1\xea\xe0.', (0, None, None, None, 0, -2147352567), None)

Хотелось бы программировать на IronPython, поскольку им я пользуюсь для Revit.

В документации сказано, что GetEntity принимает три параметра: объект (как я понимаю, класса AcadObject, массив и строку.)

Как сформировать объект для передачи в метод???
При попытке создать объект "руками" появляется сообщение, что это не возможно т.к. класс AcadObject абстрактный класс. Что это такое я пока не понимаю. Может быть есть метод, который формирует такой объект?

Заранее благодарю за ответы,
Георгий
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-06-2018, 19:59:02
Пытаюсь успользовать метод AutoCAD.Application.ActiveDocument.Utility.GetEntity().
Ни как не могу пользоваться им в IronPython.
Обязательно с ним? А почему не подходит Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.GetEntity() ?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 24-06-2018, 23:20:12
Я подключаюсь к Autocad следующим образом.
Код - Python [Выбрать]
  1. app = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application")

Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.GetEntity() у меня не видно. Речь идет о другом способе взаимодействия с AutoCAD?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-06-2018, 23:21:36
Я подключаюсь к Autocad следующим образом.
Подключаешься изнутри AutoCAD или снаружи? Если снаружи, то предложенный мной способ недоступен.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 25-06-2018, 00:07:37
Да, я подключаюсь снаружи.

А изнутри, это надо скомилировать код и netload делать?
Есть референс по классам, доступным изнутри?

Еще может быть кто-то питоновую консоль сделал, которая изнутри подключается?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-06-2018, 00:11:52
А изнутри, это надо скомилировать код и netload делать?
Нет. Компилировать ничего не нужно. Точнее создаётся C#-сборка, которая позволяет загрузить и выполнить python'овский-код.
Посмотри эти две темы:
http://through-the-interface.typepad.com/through_the_interface/2009/03/using-ironpython-with-autocad.html
http://through-the-interface.typepad.com/through_the_interface/2009/12/command-line-scripting-of-ironpython-code-in-autocad.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-06-2018, 00:37:35
Есть референс по классам, доступным изнутри?
Это всё в документации ObjectARX SDK, а в онлайне здесь: https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-What_s_New
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 25-06-2018, 00:43:32
Спасибо! Буду изучать. :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-06-2018, 00:54:25
Я приложил файлы к уроку на AU 2009 про использование IronPython с AutoCAD. Могут быть полезны.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 05-07-2018, 10:11:00
Всем доброго времени суток,
Такой вопрос: как можно вывести, что-нибудь в командную строку, типа: код отработан без ошибок, результат такой-то?
На этот раз речь конечно же идёт о ZWAutoCAD.))
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-07-2018, 11:19:13
На этот раз речь конечно же идёт о ZWAutoCAD.))
Если это шутка, то неудачная.
Такой вопрос: как можно вывести, что-нибудь в командную строку, типа: код отработан без ошибок, результат такой-то?
Код - Python [Выбрать]
  1. Utility.Prompt("код отработан без ошибок, результат такой-то")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Randum от 05-07-2018, 12:55:15
Спасибо Александр, помогло.
На первых порах тяжело идёт, час гуглишь, пишешь строчку кода, ещё час гуглишь, пишешь другую строчку кода и т.д.))
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 08-07-2018, 12:43:17
Добрый день!
У меня такой вопрос.
Можно ли компилировать скрипт на ironpython в библиотеку
и подгружать ее для выполнения к c# с помощью каких-либо средств импорта?
(далее плагин на c# с подключенной библиотекой запускать в autocad.)

Примерно так работают макросы в Revit, на сколько я понимаю.

Хотелось бы получить несколько сборок, которые бы работали на других машинах без установленного питона.

Прошу прощения, если чего-то не понимаю.


В документации к ironpython сказано:
Accessing Python code from other .NET code
Statically-typed languages like C# and VB.Net can be compiled into an assembly that can then be used by other .NET code. However, IronPython code is executed dynamically using ipy.exe. If you want to run Python code from other .NET code, there are a number of ways of doing it.

Меня интересует:
Compiling Python code into an assembly
The pyc sample can be used to compile IronPython code into an assembly. The sample builds on top of clr-CompileModules. The assembly can then be loaded and executed using Python-ImportModule. However, note that the MSIL in the assembly is not CLS-compliant and cannot be directly accessed from other .NET languages.
Но более подробной документации найти не могу. Что это за "Python-ImportModule" и как он работает?

Благодарю за ответы.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2018, 14:40:48
Самое главное в этом тексте вот это:
However, note that the MSIL in the assembly is not CLS-compliant and cannot be directly accessed from other .NET languages.
Т.е. эту сборку в AutoCAD загрузить будет нельзя. Так что в компиляции теряется весь смысл.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 08-07-2018, 14:46:17
Идея в том, чтобы загрузить в автокад сборку на c#, которая загрузит другую сборку на ironpython специальным образом.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2018, 14:51:15
Идея в том, чтобы загрузить в автокад сборку на c#, которая загрузит другую сборку на ironpython.
Мне непонятно зачем это всё нужно. Есть традиционные способы работы с AutoCAD API. Если уж смогли сделать сборку на C#, то зачем Python нужен?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 08-07-2018, 15:02:40
Вопрос в том, можно ли загружать из c# не скрипты на питоне с помощью скриптинджин а скомпилированные dll на питоне. Просто интересно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2018, 15:09:03
Вопрос в том, можно ли загружать из c# не скрипты на питоне с помощью скриптинджин а скомпилированные dll на питоне. Просто интересно.
Я вижу как можно создать exe-файл на IronPython: https://habr.com/post/149621/
Но это совсем не то, что нужно для получения нормальной .NET сборки, которую можно было загрузить в AutoCAD.
Я нигде не нашел информации о том, что можно из (Iron)Python скомпилировать нормальную .NET сборку, т.е. компиляторов как для C#/VB.NET судя по всему не существует. И соответственно это тупиковая ветка. Python хорош именно как скриптовый язык.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 08-07-2018, 15:21:31
Понятно.
Однако в Revit при создание макроса на ironpython запускается интегрированный SharpDevelop IDE, которая компилирует макрос в dll(он это умеет делать.) И макрос работает как библиотека классов dll.
Интересно, как это работает.
В случае с автокадом нельзя напрямую это делать т.к. питон не поддерживает атрибуты.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2018, 15:24:12
Однако в Revit при создание макроса на ironpython запускается интегрированный SharpDevelop IDE, которая компилирует макрос в dll(он это умеет делать.)
Попробуй на SharpDevelop IDE скомпилировать макрос для AutoCAD и посмотри что получится.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2018, 15:35:59
В случае с автокадом нельзя напрямую это делать т.к. питон не поддерживает атрибуты.
Атрибуты методов и классов? Т.е. стандартными методами нельзя определить команду. Тогда можно нестандартными:
Код - C# [Выбрать]
  1. Autodesk.AutoCAD.Internal.Utils.AddCommand("GroupName", "MyGlobalCommand", "MyLocalCommand", CommandFlags.UsePickSet | CommandFlags.Redraw, MyCommandHandler);
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 09-07-2018, 11:09:19
Попробовал собрать dll сборку на питоне в sharpdevelop. Все откомпилировалось и загрузилось в автокад. Но ничего не происходит.
Метод Initialize() не работает.

Вот код.

Код - Python [Выбрать]
  1. import clr
  2. clr.AddReferenceToFileAndPath("C:\\ObjectARX 2015\\inc\\AcCoreMgd.dll")
  3. clr.AddReferenceToFileAndPath("C:\\ObjectARX 2015\\inc\\AcDbMgd.dll")
  4. clr.AddReferenceToFileAndPath("C:\\ObjectARX 2015\\inc\\AcMgd.dll")
  5.  
  6. clr.AddReference("System.Windows.Forms")
  7.  
  8. import System.Windows.Forms
  9. import Autodesk.AutoCAD.Runtime
  10.  
  11. from System.Windows.Forms import *
  12. from Autodesk.AutoCAD.Runtime import *
  13.  
  14. class Commands(IExtensionApplication):
  15.     def Initialize():
  16.         MessageBox.Show("Hello!")
  17.    
  18.     def Terminate():
  19.         MessageBox.Show("Goodbye!")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 09-07-2018, 12:15:36
Выложи сборку, которую ты получил. Посмотрю на неё.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Archigeo от 09-07-2018, 12:22:30
Выкладываю сборку
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 09-07-2018, 12:30:32
Выкладываю сборку
Понятно. Ничего не получится. Результат компиляции такой, что не совпадает ни имя класса, ни имя метода, который AutoCAD должен при загрузке этой сборки найти...
(https://farm2.staticflickr.com/1767/43294796831_e1702d7028_o.png)

Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 13-08-2018, 19:57:38
Вопрос: как можно запустить комманду Акада, например "_regenall", из пайтона?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-08-2018, 20:02:50
Вопрос: как можно запустить комманду Акада, например "_regenall", из пайтона?
Если черед COM, то AcadDocument.SendCommand("_regenall ") (обрати внимание на пробел после имени команды).
А если через .NET, то Document.SendStringToExecute("_regenall ")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 15-08-2018, 16:21:17
Если черед COM, то AcadDocument.SendCommand("_regenall ") (обрати внимание на пробел после имени команды).
А если через .NET, то Document.SendStringToExecute("_regenall ")

Спасибо. Использую через pythoncom.
А если допустим я запустил команду "_purge ", появляется меню автокада с возможностью выбора кнопок "Удалить"  "Удалить все"  "Закрыть"  "Справка". Есть ли программная возможность командами выбрать например кнопку "Удалить все", и в  новом открывшемся меню "Удалить все элементы"? Или это невозможно через COM.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 15-08-2018, 21:28:08
Вместо "_purge" попробуй "_-purge". Дальше смотри в командной строке.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 16-08-2018, 08:42:16
Многие команды в AutoCAD имеют вариант работы через ком.строку - достаточно перед именем поставить "-".
Кстати, если хочешь, чтобы командные методы работали в любой локализации AutoCAD, посмотри http://autolisp.ru/2010/03/04/localization/
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 22-08-2018, 16:58:51
Еще вопрос.
В меню "Поле" (ctrl+F)  Автокада при создании и редактировании формул есть возможность указать мышью ссылку на ячейку, даже ячейку другой таблицы, при этом возвращается адрес столба и строки указанной ячейки. Что за метод используется при этом? Ведь при обычном выделении возвращается только выделенная таблица целиком, а не ее ячейка.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 22-08-2018, 17:08:28
Попробуй использовать HitTest (кажется, так называется)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-08-2018, 17:12:34
Что за метод используется при этом?
В COM для этой цели есть только один метод: HitTest.
Описание метода здесь: http://help.autodesk.com/view/OARX/2018/ENU/?guid=GUID-8812BEE2-BD9F-488D-BAA1-A38060FA4D86
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 23-08-2018, 18:37:34
Честно говоря, даже не могу сообразить, как реализовать такой hittest средствами Python, возникает проблема с аргументами функции.

Возможно ли вызвать этот hittest текстовой командой в меню Автокада? по типу _purge или _regenall.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-08-2018, 18:39:51
Возможно ли вызвать этот hittest текстовой командой в меню Автокада? по типу _purge или _regenall.
Нет.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 26-08-2018, 17:20:44
Нет.

Ok, тогда у меня вопрос скорее по документации к HitTest (http://help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-8812BEE2-BD9F-488D-BAA1-A38060FA4D86).
Я правильно понимаю, что нужно каким-то способом инициализировать переменные wpt, wviewVec, resultRowIndex, resultColumnIndex, передать их в качестве  аргументов функции object.HitTest(), и если нажатие  было произведено по таблице, функция возвращает True, а  двум последним переменным назаначаются индексы строки и столбца?

Я попробовал с помощью этого кода:

Код - Python [Выбрать]
  1. resultRowIndex = 0
  2. resultColumnIndex = 0
  3.  
  4. py_coord = [0,0,0]
  5. wpt = win32com.client.VARIANT(VT_ARRAY | VT_I4, py_coord)
  6.  
  7. py_vector = [0, 0, 0]
  8. wviewVec = win32com.client.VARIANT(VT_ARRAY | VT_I4, py_vector)
  9.  
  10. if obj.HitTest(wpt, wviewVec, resultRowIndex, resultColumnIndex):
  11.     print(resultRowIndex, resultColumnIndex)

возвращает ошибку:

Цитировать
if obj.HitTest(wpt, wviewVec, resultRowIndex, resultColumnIndex):
  File "<COMObject <unknown>>", line 3, in HitTest
  File "C:\ProgramData\Anaconda64\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147024809), None)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 26-08-2018, 17:27:41
А как в Python передаются out-параметры?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 26-08-2018, 17:40:25
А как в Python передаются out-параметры?

Ок, я  подкорректировал код, я так понимаю, при работе через Python все выходные параметры HitTest выдаются в виде кортежа (неизменяемого списка):

Цитировать
resultRowIndex = 1
resultColumnIndex = 1

py_coord = [0,0,0]
wpt = win32com.client.VARIANT(VT_ARRAY | VT_R8, py_coord)

py_vector = [0, 0, 0]
wviewVec = win32com.client.VARIANT(VT_ARRAY | VT_R8, py_vector)

print(obj.HitTest(wpt, wviewVec))

Теперь результат вывода на экран:

Цитировать
(False, -1, -1)

Не могу понять, какие нужно подобрать wpt, wviewVec, чтобы функция возвращала True.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 27-08-2018, 08:02:09
На dwg.ru были примеры использования HitTest (правда, на лиспе).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-08-2018, 08:27:30
На dwg.ru были примеры использования HitTest (правда, на лиспе).

Как ни странно, после прочтения примеров LIPS на том сайте, этот вариант у меня сработал  :D

Код - Python [Выбрать]
  1. py_vector = [0.0, 0.0, 1.0]
  2. wviewVec = win32com.client.VARIANT(VT_ARRAY | VT_R8, py_vector)
  3. result = obj.HitTest(cc(aDoc.Utility.GetPoint()), wviewVec)
  4. print(result)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 03-09-2018, 19:43:52
Вопрос: как можно изменить стиль строк с "Данные" на "Заголовок" или "Название" (чтобы  эти строки повторялись при разбиении таблицы).

Т.е. у меня получилось изменить стиль  ячейки (2,2)  через MyTab.SetCellStyle(2, 2, '_Header'). Но тогда стиль ячейки меняется на "Заголовок", а стиль строки по-прежнему "Данные".

Я нашел метод object.GetRowType(row), который возвращает стиль заданной строки. Но с его помощью не получается изменить  значение стиля строки.  Если  ли обратный метод типа  SetRowType?   Ни во встроенной справке, ни через поиск в гугле, ни на dwg.ru форуме  не могу найти.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 03-09-2018, 19:57:07
Т.е. у меня получилось изменить стиль  ячейки (2,2)  через MyTab.SetCellStyle(2, 2, '_Header'). Но тогда стиль ячейки меняется на "Заголовок", а стиль строки по-прежнему "Данные".
Читаем внимательно документацию для метода Table.SetCellStyle:
Цитировать
Notes
To specify cell pass a valid row and column indices; to specify row pass a valid row index and pass -1 as column index; to specify column pass a valid column index and pass -1 as row index.
Перевод нужен или так понятно?
 
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 04-09-2018, 17:14:27
Перевод нужен или так понятно?

Нет, перевод не нужен, с английским на этом уровне проблем нет. Проблема решена.
 
Но в онлайн справке, что я находил через гугл в разделе SetCellStyle Method (ActiveX) (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-2E9EE0DD-31AB-41BC-8ABF-B3ECB549E657-htm.html)   этого пункта notes  нет (или я его в  упор не замечаю?), в моей встроенной chm справке его нет тем более.


Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-09-2018, 17:32:24
Но в онлайн справке, что я находил через гугл в разделе SetCellStyle Method (ActiveX)   этого пункта notes  нет (или я его в  упор не замечаю?), в моей встроенной chm справке его нет тем более.
Посмотри здесь: http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_TableContent_SetCellStyle_int_int_string
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleksey от 11-09-2018, 10:24:49
Подскажите пожалуйста! Как выбрать вхождение блока по имени и считать значение его атрибута (например блок "РАМКА", атрибут PAGE). Пробывал через Blocks.Item, но это не то :o
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 11-09-2018, 10:50:31
У блока может быть несколько вхождений, и при этом не только в пространство модели / листа. Если нужно выбрать вообще все, то лучше будет пройтись по таблице блоков и внутри каждого блока выполнять поиск соответствующих элементов. Если же надо по какому-то пространству, то см.в сторону фильтров в SelectionSet
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 30-01-2019, 16:06:15
У меня тоже вопрос по блокам.
Допустим, я в своем скрипте по очереди выделяю текстовые  объекты и аттрибуты  с помощью GetEntity.
Но среди объектов на чертеже у меня попадается блок вроде этого с текстовыми аттрибутами внутри:

(https://i.postimg.cc/4Hg45ds7/image.jpg) (https://postimg.cc/4Hg45ds7)

если я просто щелкну по его текстовому аттрибуту, GetEntity вернет мне только точку и сам блок в целом. Можно ли как-то таким щелчком сразу получить доступ к текстовому аттрибуту  блока (например, цифре "1") без расчленения самого блока?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 30-01-2019, 16:23:00
Можно ли как-то таким щелчком сразу получить доступ к текстовому аттрибуту  блока (например, цифре "1") без расчленения самого блока?
Можно. Используй GetSubEntity.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 30-01-2019, 16:24:04
Можно, почему нет? Если действительно ткнули на атрибут - см. GetSubEntity. Если нужен доступ к атрибуту со строго определенным тэгом - то получать атрибуты вхождения блока (GetAttributes и GetConstantAttributes) и фильтровать по тэгу.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMA от 19-02-2019, 13:21:21
Подскажите, при данном варианте работы макроса Питона с Автокадом (как в 1-ом ролике: запуск внешнего файла) время срабатывания макроса примерно секунд 5. Это нормально? Или мне настройки покрутить стоит? Такое время ожидания не сильно комфортно при работе...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 21-02-2019, 07:09:14
Задавал тут вопрос, но как то все само собой решилось. Не хотел питон рисовать в пустом документе, зато без проблем нарисовал в одном из рабочих чертежей. Как удалить сообщение не нашел.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 21-02-2019, 12:02:04
Задавал тут вопрос, но как то все само собой решилось. Не хотел питон рисовать в пустом документе, зато без проблем нарисовал в одном из рабочих чертежей. Как удалить сообщение не нашел.
1. Приветствую на форуме!
2. У нас на форуме не удаляют сообщения. Представьте себе, что задан вопрос и кто-то знает и пишет ответ на этот вопрос, а вопроса уже нет...
3. Рад, что вопрос решился, но думаю неплохо было бы исследовать почему не получалось в пустом документе.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 21-02-2019, 12:12:06
По 3 му пункту, согласен, было бы неплохо исследовать этот вопрос. По началу грешил на то что питон 32бит, а автокад64. Потом думал что может версия автокада не та. Потом попробовал с библиотекой pyautocad провести манипуляции, эффект тот же. Причем Эта библиотека возвращала название документа(Чертеж 1). Меня еще больше удивило когда она возвратила название документа при закрытом автокаде, тот же чертеж 1.
Сейчас для того что бы написать этот ответ, провел еще несколько экспериментов, и что библиотека pyautocad, что доступ напрямую через API, нормально отрисовывают элементы.
Даже и не знаю в чем была проблема.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 21-02-2019, 12:14:38
По 3 му пункту, согласен
А по первому и второму? ;)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 21-02-2019, 12:22:30
ОК.
Просто воспринимал этот форум как информационный ресурс, а не как площадку для общения. Поэтому пытался быть краток)) Но если вы не возражаете, то
1. Конечно же здравствуйте, и спасибо за форум и эту тему. В общем то начальное видео в этой теме меня побудило к изучению питона
2. То же согласен. На иных форумах такое наблюдал. Но так же видел и такое, что разрешено удалять и редактировать последнее сообщение, если после него не было сообщений.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 26-02-2019, 19:14:07
По 3 му пункту, согласен, было бы неплохо исследовать этот вопрос. По началу грешил на то что питон 32бит, а автокад64. Потом думал что может версия автокада не та. Потом попробовал с библиотекой pyautocad провести манипуляции, эффект тот же. Причем Эта библиотека возвращала название документа(Чертеж 1). Меня еще больше удивило когда она возвратила название документа при закрытом автокаде, тот же чертеж 1.

У меня наблюдался наверно похожий глюк с win32com библиотекой, когда она выдавала, что автокад или ворд запущены (хотя соответствующие программы были закрыты), при этом в списке процессов в системе действительно висели невидимые процессы с  именами AutoCAD Application или Word. Так и не понял, чем это вызвано.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-02-2019, 20:44:24
По 3 му пункту, согласен, было бы неплохо исследовать этот вопрос. По началу грешил на то что питон 32бит, а автокад64. Потом думал что может версия автокада не та. Потом попробовал с библиотекой pyautocad провести манипуляции, эффект тот же. Причем Эта библиотека возвращала название документа(Чертеж 1). Меня еще больше удивило когда она возвратила название документа при закрытом автокаде, тот же чертеж 1.

У меня наблюдался наверно похожий глюк с win32com библиотекой, когда она выдавала, что автокад или ворд запущены (хотя соответствующие программы были закрыты), при этом в списке процессов в системе действительно висели невидимые процессы с  именами AutoCAD Application или Word. Так и не понял, чем это вызвано.
Ну тут всё просто. Приложение не закрылось корректно. При этом они уже не в состоянии отвечать на COM-запросы.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 04-04-2019, 13:54:18
Коллеги, прошу помощи.
Пишу на питоне код, с помощью которого, хочу собрать значения атрибутов блоков. По аналогии с VBA пытаюсь сделать это с помощью метода GetAttributes, но в ответ получаю ошибку:

Код - Python [Выбрать]
  1. atrr,_ = blk.GetAttributes()
  2.  
  3. ---------------------------------------------------------------------------
  4. KeyError                                  Traceback (most recent call last)
  5. <ipython-input-14-b127d596e8c4> in <module>
  6. ----> 1 atrr,_ = blk.GetAttributes()
  7.  
  8. D:\Programs\lib\site-packages\comtypes\automation.py in __ctypes_from_outparam__(self)
  9.     504     def __ctypes_from_outparam__(self):
  10.     505         # XXX Manual resource management, because of the VARIANT bug:
  11. --> 506         result = self.value
  12.     507         self.value = None
  13.     508         return result
  14.  
  15. D:\Programs\lib\site-packages\comtypes\automation.py in _get_value(self, dynamic)
  16.     455             return value
  17.     456         elif self.vt & VT_ARRAY:
  18. --> 457             typ = _vartype_to_ctype[self.vt & ~VT_ARRAY]
  19.     458             return cast(self._.pparray, _midlSAFEARRAY(typ)).unpack()
  20.     459         else:
  21.  
  22. KeyError: 9
  23.  
  24.  

Кто нибудь может подсказать, как справиться с ошибкой, либо как по-другому собрать значения атрибутов блоков
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-04-2019, 13:58:24
DMuzer,
Посмотри этот код: https://gist.github.com/thengineer/7157510
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 04-04-2019, 14:02:32
DMuzer,
Посмотри этот код: https://gist.github.com/thengineer/7157510

Спасибо!
Это работает.
А не в курсе, с чем связана ошибка? Это Автокад не стыкуется с питоном, или я что то неправльно делаю?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-04-2019, 14:05:05
А не в курсе, с чем связана ошибка? Это Автокад не стыкуется с питоном, или я что то неправльно делаю?
Я же не вижу всего кода, не знаю что такое blk, не знаю есть ли у этой вставки блока атрибуты... Так что затрудняюсь сказать. Но если код, по ссылке которую я дал, работает нормально, то скорее всего это проблема твоего кода.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 04-04-2019, 14:14:17
Привожу весь код.
В  другие операции с объектом выполняются без проблем. Хочется разобраться, т.к. хотелось бы работать через comtypes, потому что я работаю в Jupyter notebook. А при использовании этой библиотекой в интерактивном режиме доступны методы и свойства объектов, это сильно упрощается работу и не нужно каждый раз в справку смотреть.

Код - Python [Выбрать]
  1. import array
  2. import comtypes.client
  3. import comtypes
  4.  
  5. app = comtypes.client.GetActiveObject('AutoCAD.Application')
  6. thisdrawing = app.ActiveDocument
  7.  
  8. blk,_ = thisdrawing.Utility.GetEntity()
  9. print(type(blk))
  10. blk.GetAttributes()
  11.  

Код - Python [Выбрать]
  1. <class 'comtypes.POINTER(IAcadBlockReference)'>
  2.  
  3. ---------------------------------------------------------------------------
  4. KeyError                                  Traceback (most recent call last)
  5. <ipython-input-37-8c74b912e4fb> in <module>
  6.       8 blk,_ = thisdrawing.Utility.GetEntity()
  7.       9 print(type(blk))
  8. ---> 10 blk.GetAttributes()
  9.  
  10. D:\Programs\lib\site-packages\comtypes\automation.py in __ctypes_from_outparam__(self)
  11.     504     def __ctypes_from_outparam__(self):
  12.     505         # XXX Manual resource management, because of the VARIANT bug:
  13. --> 506         result = self.value
  14.     507         self.value = None
  15.     508         return result
  16.  
  17. D:\Programs\lib\site-packages\comtypes\automation.py in _get_value(self, dynamic)
  18.     455             return value
  19.     456         elif self.vt & VT_ARRAY:
  20. --> 457             typ = _vartype_to_ctype[self.vt & ~VT_ARRAY]
  21.     458             return cast(self._.pparray, _midlSAFEARRAY(typ)).unpack()
  22.     459         else:
  23.  
  24. KeyError: 9
  25.  
  26.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-04-2019, 14:22:38
А что даёт:
Код - Python [Выбрать]
  1. HasAttributes = blk.HasAttributes
?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 04-04-2019, 14:28:04
Возвращает True, атрибуты у этого блока есть.
Может это связано что это динамический блок.



привожу код и вывод:
Код - Python [Выбрать]
  1. import array
  2. import comtypes.client
  3. import comtypes
  4.  
  5. app = comtypes.client.GetActiveObject('AutoCAD.Application')
  6. thisdrawing = app.ActiveDocument
  7.  
  8. # blk,_ = thisdrawing.Utility.GetEntity()
  9. blk = thisdrawing.HandleToObject('332A')
  10. print(blk.Handle)
  11. print(f'Наличие атрибутов у блока: {blk.HasAttributes}')
  12. blk.GetAttributes()
  13.  

332A
Наличие атрибутов у блока: True

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-45-72048c5e4e02> in <module>
     10 print(blk.Handle)
     11 print(f'Наличие атрибутов у блока: {blk.HasAttributes}')
---> 12 blk.GetAttributes()

D:\Programs\lib\site-packages\comtypes\automation.py in __ctypes_from_outparam__(self)
    504     def __ctypes_from_outparam__(self):
    505         # XXX Manual resource management, because of the VARIANT bug:
--> 506         result = self.value
    507         self.value = None
    508         return result

D:\Programs\lib\site-packages\comtypes\automation.py in _get_value(self, dynamic)
    455             return value
    456         elif self.vt & VT_ARRAY:
--> 457             typ = _vartype_to_ctype[self.vt & ~VT_ARRAY]
    458             return cast(self._.pparray, _midlSAFEARRAY(typ)).unpack()
    459         else:

KeyError: 9


Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-04-2019, 14:31:58
Может это связано что это динамический блок.
Нет. Это уж точно тут не причем. Если этот же код с этим же блоком у тебя сработает в VBA, то тогда это проблема Python'а.
Особенно интересно вот это:
Цитировать
# XXX Manual resource management, because of the VARIANT bug:
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 04-04-2019, 14:37:27
А может быть это связано с недоработками в библиотеке comtypes?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-04-2019, 14:38:53
А может быть это связано с недоработками в библиотеке comtypes?
Вполне возможно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 24-04-2019, 06:45:30
А кто может подсказать как из питона 3.7 работать с цветами.
В букваре есть такой пример:
 
Код - vb.net [Выбрать]
  1.     Dim color As AcadAcCmColor
  2.         Set color = AcadApplication.GetInterfaceObject("AutoCAD.AcCmColor.16")
  3.     Call color.SetRGB(80, 100, 244)
  4.     layerObj.TrueColor = color

С вижуал бейсиком совсем не знаком, но на сколько понимаю переменная color должна стать каким то специальным автокадовским типом. У меня же не получается запустить подобную конструкцию.

Код - Python [Выбрать]
  1. app = win32com.client.Dispatch("AutoCAD.Application")
  2. color = app.GetInterfaceObject("AutoCAD.AcCmColor.16")

Пробовал и попроще:

Код - Python [Выбрать]
  1. lay.TrueColor = 'Зеленый'
  2. lay.TrueColor = 'Green'
  3. lay.TrueColor=(80,100,244)
  4.  
  5. color = convert_coordinates(80,100,244)
  6. lay.TrueColor=color

И то же ничего не получается. Если кто знает как с цветами работать, подскажите пожалуйста
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 24-04-2019, 15:10:13
Разобрался.
Для 15го автокада нужно указывать "AutoCAD.AcCmColor.20". В остальном все работает по букварю
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 05-05-2019, 21:47:19
Подскажите, как в Python использовать функции с необязательными параметрами? Например, Utiliy.GetPoint(Point, Prompt) имеет два параметра, и мне хотелось-бы не указывать Point, но использовать Prompt. Вариант Utility.GetPoint(None, "Сообщение") вызывает ошибку.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-05-2019, 22:18:51
Вариант Utility.GetPoint(None, "Сообщение") вызывает ошибку.
А так: Utility.GetPoint("Сообщение") ?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 05-05-2019, 23:29:35
Пробовал, тоже не работает. Работает только совсем без аргументов.

Выдает такое вот сообщение об ошибке

return self.aDoc.Utility.GetPoint(Msg)
  File "<COMObject <unknown>>", line 3, in GetPoint
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD', 'Недопустимый аргумент Point в GetPoint', 'C:\\Program Files\\Autodesk\\AutoCAD 2019\\HELP\\OLE_ERR.CHM', -2145320939, -2147024809), None)

Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-05-2019, 23:35:33
Ну тогда что-нибудь типа Utility.GetPoint(pythoncom.Empty,"Сообщение") или Utility.GetPoint(pythoncom.Missing,"Сообщение")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 06-05-2019, 15:04:36
Спасибо. С pythoncom.Empty все отлично работает.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-05-2019, 15:44:14
Спасибо. С pythoncom.Empty все отлично работает.
Отлично. Не имея возможности проверить я интуитивно догадался, что именно может помочь. Так как использование Python для AutoCAD мягко говоря не очень распространено и не поддерживается Autodesk, то поиск решений таких казалось бы простых задач очень усложнён.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 07-05-2019, 11:16:05
Примерно месяц занимаюсь изучением Python и его применением в AutoCad. Все выглядит не так сложно, даже для непрофессионального программиста. Для меня приемущества Python над LISP перевешивают неудобства связи AutoCad со сторонним приложением. Также я никогда не писал ничего с помощью ObjectARX, но есть несколько идей. Я правильно понимаю, что смогу написать модуль на С++ с использованием ObjectARX и потом им пользоваться в программе на Python?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-05-2019, 11:19:33
Я правильно понимаю, что смогу написать модуль на С++ с использованием ObjectARX и потом им пользоваться в программе на Python?
Я не понимаю к чему такие сложности. Для того, чтобы писать для AutoCAD непрофессиональному программисту оптимально использовать AutoCAD .NET API (C# или VB.NET) . Он позволяет делать большинство из того, что можно сделать при помощи ObjectARX и обладает огромным количеством примеров (большинство из них на C#).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 07-05-2019, 20:51:04
Дело в том, что я особо не разбирался с C#, т.к. я не программист, а проектировщик, мне показалось, что в любом случае не буду использовать все его приемущества, а со всеми недостатками придется иметь дело. Python меня привлек простотой изучения, наличием всевозможных плюшек, облегчающих процесс написания программ - динамическая типизация, динамические массивы, множество готовых функций для работы со строками и списками и тд. Также иногда делюсь своими наработками с коллегами и при использовании AutoLisp или Python не надо задумываться над совместимостью с разными версиями AutoCad. Пробовал также VBA, но не пошло.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-05-2019, 22:55:35
SilverWork,
Еще раз.
1) Python не поддерживается Autodesk для AutoCAD.
2) Примеров использования Python с AutoCAD очень мало. Во всяком слуачае по сравнению с VisualLisp/VBA/C#/C++
3) Непрограммисту (да и программисту) разбираться с тонкостями использования COM через Python в AutoCAD очень проблематично.
Так что всё на свой страх и риск.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 08-05-2019, 11:25:10
Ну мы находимся в теме  Python & ActiveX/COM Autocad, следовательно она для тех, кто хочет разобраться в этих тонкостях. Да, конечно, есть свои плюсы и минусы. Все зависит от конкретной задачи. В моем случае не требуется много взаимодействовать с Autocad. Приложение собирает какие-то данные из чертежа (атрибуты блоков, значения из таблиц, длины линий и тд), потом внутри себя из обрабатывает и выдает результат обратно в Autocad в нужном мне виде (расчеты, таблицы, рисует каки-либо примитивы). И основная часть работы - это и есть обработка данных и в этом у Python есть преимущества, остается только написать интерфейс взаимодействия с Autocad, что вызывает трудности, но не смертельно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 10-05-2019, 21:37:35
Столкнулся с проблемой, что очень медленно осуществляется взаимодействие программы с Autocad. Например, получение атрибутов сотни блоков занимает секунд 10-15, рисование объектов также заметно медленнее, чем через AutoLisp. Есть способы исправить это или это особенности работы через COM?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-05-2019, 22:22:29
Есть способы исправить это или это особенности работы через COM?
COM между процессами приводит к таким задержкам. Особенно если эти процессы разной разрядности (32/64).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 17-05-2019, 16:46:23
Есть способы исправить это или это особенности работы через COM?
Для ускорения нужно максимально пользоваться средствами самого када, например select с фильтрами вместо select + перебор, и т.п. Но работа через COM будет всегда несколько медленной, хотя для большинства инженерных задач и достаточной.
Передача через COM каду данных и параметров с преобразованием к нужному типу - отдельная головная боль, но это больше камень в огород com библиотек питона.
Организовать запуск команды на питоне из када - тоже квест. Решаемый, но я нашёл путь только через жуткие костыли.
Питон удобно использовать, если нужно вывести результаты расчётов или построений в кад и получить dwg. Плотно работать с кадом можно, но не совсем удобно.
К сожалению, на данный момент с точки зрения Autodesk в их продуктах нет места не .net языкам и питону в частности. В автокад - только через COM, который непонятно сколько ещё проживёт. В ревите реализована только поддержка .net  вариации питона версии 2, и переход на третью ветку даже в перспективе не виден.
Если нужно плотно программировать под продукты Autodesk, лучше выбрать C#. Порог входа чуть выше, но потенциальных проблем намного меньше.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: SilverWork от 17-05-2019, 17:22:26
Тут будет небольшой оффтоп. Я поразбирался с C# и вроде все выглядит не сложно, но один момент меня смущает - это отладка кода. С лиспом и питоном все ясно: запустил, увидел косяки, исправил, повторил... и так хоть 100 раз. В случае с C#, как я понимаю, придется после каждой попытки перезагружать AutoCad, т.к. нет возможности выгрузить dll. Пытался поискать на форумах, также здесь была тема о выгрузке, но, как я понял, способ не простой и не всегда работает. Хочется сразу писать на том, что будет работать хорош и быстро, но вот процесс отладки кода меня, скажем прямо, пугает.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 17-05-2019, 17:38:59
Off-Topic: показать
Такая же беда... Ну что, написал лиспик для автозагрузки библиотеки - и вперед, с песнями ;)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 17-05-2019, 20:58:48
Хочется сразу писать на том, что будет работать хорош и быстро, но вот процесс отладки кода меня, скажем прямо, пугает.
Не пугайся. Все так делают. Нужно писать максимально чистый код сразу - это сократит количество запусков AutoCAD для отладки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 19-05-2019, 22:51:20
Это если есть понимание, что и как работает. А вот если его нет или оно вызывает сомнения...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 08-06-2019, 11:56:38
Добрый день!
Подскажите, как обработать события автокада из python.
Есть ли подходящие примеры?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-06-2019, 16:22:16
Есть ли подходящие примеры?
Примеров нет. Во всяком случае мне они не известны. Так что пробуй делать по аналогии с Word/Excel:
https://win32com.goermezer.de/microsoft/ms-office/events-in-microsoft-word-and-excel.html
Подписка на события происходит через win32com.client.DispatchWithEvents
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 08-06-2019, 17:10:13
Спасибо, попробую!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 11-07-2019, 13:23:40
Допустим, у меня активирован режим объектной привязки, а конкретно "конточка", "центр", "узел", для удобства выделения объектов на чертеже я программно деактивирую на время привязку с помощью:

Код - Python [Выбрать]
  1. aDoc.ObjectSnapMode = False

Но когда потом я программно пытаюсь восстановить привязку, установив этому свойству значение True, режим привязки не активируется, все поставленные галочки типа  "конточка", "центр", "узел" пропадают. Есть ли способ получить доступ к настройкам привязки и активировать их программно? Либо как вариант, эмулировать нажатие F3 с клавиатуры. Не могу найти этот момент в документации.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 11-07-2019, 13:27:26
Есть ли способ получить доступ к настройкам привязки и активировать их программно?
Это системная переменная OSMODE: https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2018/ENU/AutoCAD-Core/files/GUID-DD9B3216-A533-4D47-95D8-7585F738FD75-htm.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 11-07-2019, 14:07:37
Попробуй получить системную переменную osmode, и работать с ней.
Не увидел предыдущего ответа...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 11-07-2019, 18:22:23
Спасибо!
Сочетание GetVariable и SetVariable с этой системной переменной - то, что мне было нужно.

Код - Python [Выбрать]
  1. OSMODE = aDoc.GetVariable('OSMODE')
  2.  
  3. aDoc.SetVariable('OSMODE', OSMODE)
  4.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 22-08-2019, 14:18:39
Добрый день!
Прошу подсказать. Например, мне нужно изменить порядок отрисовки объектов а чертеже. Я попробовал следующий код:
Код - Python [Выбрать]
  1.  
  2. acad = Dispatch('autocad.application.23')
  3. doc = acad.ActiveDocument
  4.  
  5. ent, _ = doc.Utility.GetEntity()
  6.  
  7. order_dict = doc.ModelSpace.GetExtensionDictionary()
  8. st = order_dict.GetObject("ACAD_SORTENTS")
  9.  
  10. arr = VARIANT(VT_ARRAY | VT_VARIANT, [ent])
  11.  
  12. st.MoveToTop(arr)



Но в результате получаю такое сообщение:


com_error                                 Traceback (most recent call last)
<ipython-input-365-c2e46e7e77cf> in <module>
      9 arr = VARIANT(VT_ARRAY | VT_VARIANT, [ent])
     10
---> 11 st.MoveToTop(arr)

d:\Prorams\Anaconda\lib\site-packages\win32com\client\dynamic.py in MoveToTop(self, Objects)

com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Неверный массив объектов', 'D:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145320837, -2145320837), None)


Мне понятно, что проблема здесь в упаковке параметров функции. Но вот уже все известные мне варианты перепробовал, результат тот же самый.
Может быть найдется у кого работающий кусок кода, чтобы понять как правильно передать параметры?
Пробовал и объекты в вариант упаковывать и получить через SelectionSets. В общем не получается.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-08-2019, 15:16:22
Могу лишь предположить, что вместо:
Код - Python [Выбрать]
  1. arr = VARIANT(VT_ARRAY | VT_VARIANT, [ent])
должно быть:
Код - Python [Выбрать]
  1. arr = VARIANT(VT_ARRAY | VT_DISPATCH, [ent])
Но больше ничем не помогу.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 22-08-2019, 15:45:01
Да, именно так, все работает! Спасибо огромное!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 26-08-2019, 12:08:07
Добрый день!
Нужен совет.

при использовании кода

Код - Python [Выбрать]
  1.    
  2.     ss = doc.SelectionSets.Add("DM_take")
  3.  
  4.     ss.Select(
  5.         acad_mod.constants.acSelectionSetAll,
  6.         None, None        
  7.     )
  8.  
  9.     for e in ss :
  10.         ….  
  11.  

при переборе объектов в SelectionSet получаем e как IAcadEntity instance, при этом получается, что специфичные для объекта методы недоступны, например InsertionPoint если это блок.
Мне приходися делать примерно так:
Код - Python [Выбрать]
  1. e = doc.HandleToObject(e.Handle)

И тогда в e я получаю нужный объект. Но мне кажется что это не самый оптимальный способ, потому что опять же приходится обращаться к ActiveX, как бы лишний запрос.
Может быть кто знает как решать эту задачу поэлегантнее?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-08-2019, 12:10:34
DMuzer,
Прочитай у меня в подписи как следует форматировать код на форуме. Я уже несколько раз исправлял форматирование твоего кода.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 26-08-2019, 12:23:06
Хорошо, я разобрался как это делать, исправлюсь.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-08-2019, 12:25:47
На VBA этот вопрос решается так:
Код - Visual Basic [Выбрать]
  1. Dim obj As AcadEntity
  2. Dim poly As Polyline
  3. Dim polyLength As Double
  4.  
  5. For Each obj In ssetObj
  6.      If TypeOf obj Is AcadPolyline Then
  7.         Set poly = obj
  8.         MsgBox "Длина полилинии " & poly.Length
  9.      End If
  10. Next
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 10-09-2019, 13:53:02
Доброго дня!
Есть ли у кого опыт подключения к AutoCad из Python для обработки событий? Может быть есть какие-нибудь работающие примеры. Мои попытки самостоятельно это сделать пока были неудачные.
Было бы здорово посмотреть примеры обработку событий, например двойного щелчка по объекту, удаления, создания и т.п.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-09-2019, 16:19:24
DMuzer,
По второму кругу? https://adn-cis.org/forum/index.php?topic=7864.msg38829#msg38829
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 10-09-2019, 17:12:50
Ну да, так по аналогии с Word не заработало. Так не смог добиться какого-то работоспособного варианта.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleksey от 13-09-2019, 12:42:07
Здравствуйте! Подскажите пожалуйста по методу Select!
Хочу выбрать все вхождения блока, но не получается задать правильно аргументы FilterType и FilterData!
Код - Python [Выбрать]
  1. import array
  2. from win32com.client import Dispatch, CastTo, VARIANT
  3. from pythoncom import  VT_DISPATCH, VT_ARRAY, VT_UI2,VT_VARIANT,VT_BSTR
  4.  
  5.  
  6.  
  7. acad=Dispatch("Autocad.Application")
  8. doc=acad.ActiveDocument
  9. ms=doc.ModelSpace
  10.  
  11. try:
  12.     for i in doc.SelectionSets:
  13.         i.Delete()
  14. except: pass
  15.        
  16.  
  17. myss=doc.SelectionSets.Add("myss")
  18.  
  19. dxfcode,data=0,"Insert"
  20.  
  21. FilterType=VARIANT(VT_ARRAY|VT_UI2,dxfcode)
  22.  
  23. FilterData=VARIANT(VT_ARRAY|VT_VARIANT,data)
  24.  
  25. SELECT_ALL=5
  26.  
  27. myss.Select(SELECT_ALL,None,None,FilterType,FilterData)


Traceback (most recent call last):
  File "D:\Мои документы\Работа\python exp\AutoCAD\BlocksInBlockCount\block_count2.py", line 27, in <module>
    myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
  File "C:\Program Files\Python34\lib\site-packages\win32com\gen_py\852B2D4E-B1F4-4BD6-8672-9993177C1A40x0x1x0\IAcadSelectionSet.py", line 73, in Select
    , Point1, Point2, FilterType, FilterData)
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.

Научите, что я делаю не так!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-09-2019, 12:53:37
Aleksey,
Прочитай у меня в подписи о правильном форматировании кода на форуме и соблюдай это правило!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-09-2019, 13:27:27
Здравствуйте! Подскажите пожалуйста по методу Select!
Хочу выбрать все вхождения блока, но не получается задать правильно аргументы FilterType и FilterData!
Код - Python [Выбрать]
  1. import array
  2. from win32com.client import Dispatch, CastTo, VARIANT
  3. from pythoncom import  VT_DISPATCH, VT_ARRAY, VT_UI2,VT_VARIANT,VT_BSTR
  4.  
  5.  
  6.  
  7. acad=Dispatch("Autocad.Application")
  8. doc=acad.ActiveDocument
  9. ms=doc.ModelSpace
  10.  
  11. try:
  12.     for i in doc.SelectionSets:
  13.         i.Delete()
  14. except: pass
  15.        
  16.  
  17. myss=doc.SelectionSets.Add("myss")
  18.  
  19. dxfcode,data=0,"Insert"
  20.  
  21. FilterType=VARIANT(VT_ARRAY|VT_UI2,dxfcode)
  22.  
  23. FilterData=VARIANT(VT_ARRAY|VT_VARIANT,data)
  24.  
  25. SELECT_ALL=5
  26.  
  27. myss.Select(SELECT_ALL,None,None,FilterType,FilterData)


Traceback (most recent call last):
  File "D:\Мои документы\Работа\python exp\AutoCAD\BlocksInBlockCount\block_count2.py", line 27, in <module>
    myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
  File "C:\Program Files\Python34\lib\site-packages\win32com\gen_py\852B2D4E-B1F4-4BD6-8672-9993177C1A40x0x1x0\IAcadSelectionSet.py", line 73, in Select
    , Point1, Point2, FilterType, FilterData)
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.

Научите, что я делаю не так!

В функцию VARIANT нужно передавать список, а ты передаешь обычные значения. Поставь их либо в круглые либо в квадратные скобки

Код - Python [Выбрать]
  1. FilterType=VARIANT(VT_ARRAY|VT_UI2,[dxfcode])
  2.  
  3. FilterData=VARIANT(VT_ARRAY|VT_VARIANT,[data])
  4.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-09-2019, 13:27:37
Aleksey,
Подозреваю, что вместо None следует использовать pythoncom.Empty
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleksey от 13-09-2019, 13:48:24
Код - Python [Выбрать]
  1. FilterType=VARIANT(VT_ARRAY|VT_UI2,[dxfcode])
  2.  
  3. FilterData=VARIANT(VT_ARRAY|VT_VARIANT,[data])
  4.  
  5. SELECT_ALL=5
  6.  
  7. myss.Select(SELECT_ALL,pythoncom.Empty,pythoncom.Empty,FilterType,FilterData)

Traceback (most recent call last):
  File "D:\Мои документы\Работа\python exp\AutoCAD\BlocksInBlockCount\block_count2.py", line 32, in <module>
    myss.Select(SELECT_ALL,pythoncom.Empty,pythoncom.Empty,FilterType,FilterData)
  File "C:\Program Files\Python34\lib\site-packages\win32com\gen_py\852B2D4E-B1F4-4BD6-8672-9993177C1A40x0x1x0\IAcadSelectionSet.py", line 73, in Select
    , Point1, Point2, FilterType, FilterData)
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD', 'Недопустимый аргумент FilterType в Select', 'C:\\Program Files\\Autodesk\\AutoCAD 2014\\HELP\\OLE_ERR.CHM', -2145320939, -2147024809), None)

Не получается :-[

Меня этот метод интересует в том смысле, что мне кажется так будет быстрее выбирать элементы, чем через перебор всех элементов документа. Дает ли он выигрыш в скорости или может не стоит мучиться:)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-09-2019, 14:00:10
А если:
Код - Python [Выбрать]
  1. FilterType=VARIANT(VT_ARRAY|VT_I2,[0])
  2. FilterData=VARIANT(VT_ARRAY|VT_VARIANT,['INSERT'])
?
Вообще же вроде не VT_UI2, а VT_I2
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-09-2019, 14:04:30
Не нужно pythoncom.Empty, нужно None оставить,
Код - Python [Выбрать]
  1. myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
  2.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-09-2019, 14:26:26
Не нужно pythoncom.Empty, нужно None оставить,
Код - Python [Выбрать]
  1. myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
  2.  
Здесь None не прокатило: https://adn-cis.org/forum/index.php?topic=7864.msg38367#msg38367
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-09-2019, 14:30:57
У меня работает, по 100 раз в день убеждаюсь в этом,
возможно, дело как раз в том, что нужно заменить VT_UI2 на VT_I2.
Опять же может быть дело в версии AutoCad. у меня 2018, и в 2020 тоже будет работать.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-09-2019, 14:33:44
возможно, дело как раз в том, что нужно заменить VT_UI2 на VT_I2.
Наиболее вероятно, т.к. сообщает об ошибке именно в параметре FilterType
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleksey от 13-09-2019, 15:24:29
Спасибо большое! Заработало! :)
Код - Python [Выбрать]
  1. FilterType=VARIANT(VT_ARRAY|VT_I2,[dxfcode])
  2.  
  3. FilterData=VARIANT(VT_ARRAY|VT_VARIANT,[data])
  4.  
  5. SELECT_ALL=5
  6.  
  7. myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 28-10-2019, 11:40:51
Всем здравствуйте.
Подскажите можно как то из питона передать набор в автокад?
То есть выделить один или несколько объектов в открытом документе автокада из питона.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 28-10-2019, 12:17:43
То есть выделить один или несколько объектов в открытом документе автокада из питона.
Имеется в виду выбрать и подсветить, как выбранное? Средствами только COM/ActiveX это сделать нельзя. И соответственно питоном тоже. В VBA это делалось через запуск lisp-функции (sssetfirst).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 28-10-2019, 12:31:24
Понял. А из питона же то же можно некую лисп функцию запустить? Только вот я не уверен что она переварит питоновский массив...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 28-10-2019, 12:33:35
А из питона же то же можно некую лисп функцию запустить?
Запустить можно. Document.SendCommand. Сложность будет только с передачей параметров.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 28-10-2019, 12:35:07
Я понял. Спасибо
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 28-10-2019, 18:53:59
Подскажите пожалуйста! Как выбрать вхождение блока по имени и считать значение его атрибута (например блок "РАМКА", атрибут PAGE). Пробывал через Blocks.Item, но это не то :o

Возник схожий вопрос по динамическим атрибутам блока.
Допустим я выбрал мышкой  динамический блок и среди его динамических свойств  есть параметр "Ширина"

AllowedValues: (210.0, 297.0, 420.0, 594.0, 630.0, 841.0, 891.0, 1051.0, 1189.0, 1261.0, 1471.0, 1486.0, 1682.0, 1783.0, 1892.0, 2080.0, 2102.0, 2378.0, 2523.0)
Description: Ширина внешней рамки
PropertyName: Ширина
ReadOnly: False
Show: False
UnitsType: 2
Value  : 594.0

Как-то можно получить к нему доступ напрямую по имени без перебора всех свойств блока? Пока я получаю  их таким способом, но выглядит это не очень рационально:

Код - Python [Выбрать]
  1. width = [attr.value for attr in obj.GetDynamicBlockProperties() if attr.PropertyName=='Ширина'][0]

P.S. без использования GetBoundingBox()
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 28-10-2019, 21:13:30
Как-то можно получить к нему доступ напрямую по имени без перебора всех свойств блока?
Никак. Такой возможности в API нет. Впрочем это и логично - теоретически может быть несколько свойств с одним именем.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 29-10-2019, 05:29:30
Я надеюсь что я не сильно злоупотребляю вниманием сообщества, у меня еще один вопрос.
Есть ли возможность изменить видимость атрибута в блоке? И есть ли у кого то для этого уже готовый рецепт?
Судя по доке, параметр "Invisible" - изменяемый, нельзя ли его как то изменить тем же способом что и просматриваю?
Код - Python [Выбрать]
  1. object.GetAttributes()[y1].Invisible

Еще нашел метод вот такой:
Код - Python [Выбрать]
  1. object.SetVariable(Invisible, False)
То же не получается изменить параметр

И еще один метод, но я вообще не могу его применить, потому и прошу пример на питоне
Код - Python [Выбрать]
  1. object.AddAttribute(1, acAttributeModeInvisible, Prompt, InsertionPoint, Tag, Value)

Был настроен на питон, но сталкиваюсь со сложностью с реализацией каждой небольшой идеи. Может выбрать какой то более простой и документированный способ автоматизации автокада? Для Вижуал-бейсика хоть примеры есть, но не уверен что это оптимальный подход. В общем прошу проконсультировать.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 29-10-2019, 06:58:16
Я надеюсь что я не сильно злоупотребляю вниманием сообщества, у меня еще один вопрос.
Есть ли возможность изменить видимость атрибута в блоке? И есть ли у кого то для этого уже готовый рецепт?
Судя по доке, параметр "Invisible" - изменяемый, нельзя ли его как то изменить тем же способом что и просматриваю?

Не могу прямо сейчас проверить, но если параметр изменяемый, то разве нельзя ему просто присвоить логическое значение напрямую, без всяких сеттеров?

Код - Python [Выбрать]
  1. object.GetAttributes()[y1].Invisible = False
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Alexll от 29-10-2019, 07:05:53
Вот - вот. Я и думал что как то так можно )
Спасибо, так получилось:
Код - Python [Выбрать]
  1. object.GetAttributes()[y1].Invisible = False
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 29-10-2019, 09:19:10
Был настроен на питон, но сталкиваюсь со сложностью с реализацией каждой небольшой идеи. Может выбрать какой то более простой и документированный способ автоматизации автокада? Для Вижуал-бейсика хоть примеры есть, но не уверен что это оптимальный подход. В общем прошу проконсультировать.
Рекомендую заняться изучением C#. И писать плагины, которые грузятся внутрь AutoCAD, т.к. AutoCAD .NET API значительно мощнее, чем AutoCAD COM/ActiveX
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 29-10-2019, 18:16:49
Рекомендую заняться изучением C#. И писать плагины, которые грузятся внутрь AutoCAD, т.к. AutoCAD .NET API значительно мощнее, чем AutoCAD COM/ActiveX

Тоже задумываюсь над изучением Си шарпа  для этих целей. Интересно, будет ли на практике какой-то прирост в скорости по сравнению с работой с COM в AutoCAD?
И как я понимаю, программа, написанная  на C# будет сильно зависеть от версии Автокада, в отличие от COM, разницу в работе которой в автокаде я не замечал с 2010 по 2020 версии.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 29-10-2019, 18:23:39
Интересно, будет ли на практике какой-то прирост в скорости по сравнению с работой с COM в AutoCAD?
Да. Причем если сравнивать COM/ActiveX из внешнего приложения и .NET из плагина, загружаемого в сам AutoCAD, то прирост скорости может быть и на порядок.
И как я понимаю, программа, написанная  на C# будет сильно зависеть от версии Автокада, в отличие от COM, разницу в работе которой в автокаде я не замечал с 2010 по 2020 версии.
По хорошему нужно под каждую версию AutoCAD делать свою dll, но если не использовать некоторые особенности (точнее не нарваться на них случайно), то с 2013 и по 2020 должна работать одна dll. Ну и могут быть особенности с версией .NET Framework, так как каждая из версий AutoCAD требует свою (а точнее "не меньшую чем" версию .NET Framework: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2020/ENU/AutoCAD-Customization/files/GUID-A6C680F2-DE2E-418A-A182-E4884073338A-htm.html).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 06-11-2019, 19:18:14
Есть идея написать на Пайтоне аналог скрипта AL (https://forum.dwg.ru/showthread.php?t=124456&page=5) для создания листов с видовыми экранами из рамок/блоков в пространстве модели. Предложенный там скрипт не вполне корректно работает с используемым мной динамическим блоком для рамки, а переделывать LISP пока желания не возникает  :D

Так вот, своим Python скриптом, получаю координату базовой точки рамки-блока (правый нижний угол)  x, y в пространстве модели, ширину width, высоту height, поворот orientation. Далее удаляю существующие листы кроме пространства модели и пустого листа по умолчанию "Лист1".

Затем создаю лист c именем pagename и пытаюсь создать видовой  экран в нем (за основу взял этот код (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-9DCF17E7-717B-4766-AFFE-D3C9ED506BB8-htm.html)):

Код - Python [Выбрать]
  1. newPage = aDoc.Layouts.Add(pagename)
  2.  
  3. aDoc.ActiveLayout = newPage
  4.  
  5. # Установить активным пространство листа
  6. aDoc.ActiveSpace = 0 #acPaperSpace
  7.                                
  8. center = win32com.client.VARIANT(VT_ARRAY | VT_R8, (x-width/2, y+height/2, 0))
  9.  
  10. # Видовой экран
  11. newVport = aDoc.PaperSpace.AddPViewport(center, width, height)  
  12.  
  13. # направление взгляда на viewport
  14.  newVport.Direction = win32com.client.VARIANT(VT_ARRAY | VT_R8, (1,1,1))
  15.  
  16. # Отобразить viewport
  17. newVport.Display(True)
  18.  
  19. # Переключение в пространство модели
  20. aDoc.MSpace = True  
  21.  
  22. # Установить viewport текущим
  23. aDoc.ActivePViewport = newVport
  24.  
  25. # попытка сделать ZoomExtents
  26. win32com.client.Dispatch("AutoCAD.Application").ZoomExtents()
  27.  
  28. # Деактивация пространства модели
  29. aDoc.MSpace = False
  30.  


В результате все вылетает на строчке "aDoc.ActivePViewport = newVport"
Цитировать
0, 'AutoCAD', 'Нет активного видового экрана в пространстве модели. Переключение в пространство листа'

По факту получается пустой лист минимального размера, и где-то полноразмерная рамка видового экрана далеко сбоку (примерно как на расстоянии  от начала координат).
Понимаю, в моем коде может быть много ошибок, укажите хотя бы на несколько из них.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 06-11-2019, 19:31:29
Насколько я помню, средствами ActiveX создавать ВЭ нельзя.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-11-2019, 22:09:00
Насколько я помню, средствами ActiveX создавать ВЭ нельзя.
Вообще-то AddPViewport это делает.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-11-2019, 22:18:09
Electric,
Посмотри в каком состоянии у тебя системная переменная LAYOUTCREATEVIEWPORT: https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Core/files/GUID-799745E4-9804-41A7-BC48-E67CF2615111-htm.html
Если не 1, то установи её в 1.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 07-11-2019, 11:12:47
сть идея написать на Пайтоне аналог скрипта AL для создания листов с видовыми экранами из рамок/блоков в пространстве модели. Предложенный там скрипт не вполне корректно работает с используемым мной динамическим блоком для рамки, а переделывать LISP пока желания не возникает  Так вот, своим Python скриптом, получаю координату базовой точки рамки-блока (правый нижний угол)  x, y в пространстве модели, ширину width, высоту height, поворот orientation. Далее удаляю существующие листы кроме пространства модели и пустого листа по умолчанию "Лист1". Затем создаю лист c именем pagename и пытаюсь создать видовой  экран в нем (за основу взял этот код):

Думаю проблема в настройках листа,
вот этого не нужно:
aDoc.ActivePViewport = newVport

и нужно настроить параметры листа: единицы измерения и т.п.
Я приведу свою функцию для формирования листа, там присутствуют ссылки на другие функции но в целом понять как работает можно. Функцией каждый день по многу раз пользуюсь поэтому код рабочий.
Обычно у меня на чертеже много прямоугольников из которых потом формируются листы. В XData прямоугольников записан масштаб, исходя из этого подбирается подходящий формат бумаги
Код - Python [Выбрать]
  1.  
  2. def CreateLayout(doc, h, i, scale = 100) :
  3.     """
  4.    Создает новый лист и выводит на него область полилинии
  5.    Подбирает размер, исходя из масштаба
  6.    i - число, из которого создается имя листа. Имена листов всегда будут числовые
  7.  
  8.    """
  9.     import time
  10.     pl = doc.HandleToObject(h)
  11.     bb = pl.GetBoundingBox()
  12.  
  13.     dt, dx = pl.GetXData('DM_Page')
  14.  
  15.     try :
  16.         page_scale = dx[2]
  17.     except :
  18.         page_scale = scale  
  19.    
  20.     size = (bb[1][0] - bb[0][0], bb[1][1]-bb[0][1])
  21.     mn = GetMediaName(size, scale = page_scale)
  22.    
  23.     try :
  24.         lo = doc.Layouts.Add(f'{i:05}')
  25.     except Exception as ex:        
  26.         lo = doc.Layouts(f'{i:05}')
  27.        
  28.        
  29.     lo.ConfigName = "DWG To PDF.pc3"
  30.     lo.RefreshPlotDeviceInfo()
  31.     lo.CanonicalMediaName = mn
  32.     lo.RefreshPlotDeviceInfo()
  33.     lo.PaperUnits = acad_mod.constants.acMillimeters
  34.     lo.PlotType = acad_mod.constants.acLayout
  35.    
  36.     lo.PlotRotation = acad_mod.constants.ac0degrees
  37.        
  38.     doc.Regen(0)
  39.    
  40.     doc.ActiveLayout = lo
  41.     doc.MSpace = False
  42.    
  43.     for e in lo.Block :
  44.         e.Delete()
  45.        
  46.     #     Создаем вид
  47.  
  48.     psize = lo.GetPaperSize()
  49.     margins = lo.GetPaperMargins()
  50.     pvsize = (psize[0] - margins[0][0] - margins[1][0], psize[1] - margins[0][1] - margins[1][1])    
  51.    
  52.     center = (pvsize[0] / 2 , pvsize[1] / 2, 0)    
  53.  
  54.     pv = doc.PaperSpace.AddPViewport(vtr(center), pvsize[0], pvsize[1])
  55.     pv.Layer = 'defpoints'
  56.     pv.Display(True)
  57.    
  58.     doc.MSpace = True
  59.     doc.Application.ZoomWindow(vtr(bb[0]), vtr(bb[1]))
  60.     doc.MSpace = False
  61.     doc.Application.ZoomExtents()
  62.     doc.Regen(0)
  63.     doc.ActiveLayout = doc.Layouts("Model")
  64.     doc.ActiveLayout = lo
  65.     doc.Application.ZoomExtents()
  66.     doc.SendCommand("_PSLTSCALE 0 ")
  67.     doc.SendCommand("ВСЕРЕГЕН ")
  68.  



Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 07-11-2019, 11:19:53
Абсолютно не знаю Python, но почему бы не попробовать использовать вместо
Код - Python [Выбрать]
  1.     doc.SendCommand("_PSLTSCALE 0 ")
  2.     doc.SendCommand("ВСЕРЕГЕН ")
нечто типа
Код - Python [Выбрать]
  1. doc.SetVariable("PSLTSCALE", 0)
  2. doc.Regen 1
P.S. acActiveViewport = 0
acAllViewports = 1
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 07-11-2019, 11:31:15
Абсолютно не знаю Python, но почему бы не попробовать использовать вместоКод - Python [Выбрать]    doc.SendCommand("_PSLTSCALE 0 ")    doc.SendCommand("ВСЕРЕГЕН ")нечто типаКод - Python [Выбрать]doc.SetVariable("PSLTSCALE", 0)doc.Regen 1P.S. acActiveViewport = 0acAllViewports = 1

Думаю, так было бы лучше, команду отправлял потому не было времени разбираться в тонкостях переменных, было понимание что такая команда работает правильно поэтому сделал так, с тех пор не трогал)))
 только так работать не будет

Код - Python [Выбрать]
  1. doc.Regen 1

нужно

Код - Python [Выбрать]
  1. doc.Regen(1)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 07-11-2019, 11:48:25
Ну, я в Python ни бум-бум :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 07-11-2019, 18:57:50
Я приведу свою функцию для формирования листа, там присутствуют ссылки на другие функции но в целом понять как работает можно.

Благодарю! Пока подгоняю эту функцию под свой код, застрял на этом моменте:

Цитировать
Код - Python [Выбрать]
  1.     doc.Application.ZoomWindow(vtr(bb[0]), vtr(bb[1]))  
  2.  


Я так понимаю, vtr в этом фрагменте - это аналог convert_coordinates из начала темы (https://adn-cis.org/forum/index.php?topic=7864.msg28996#msg28996)?

Код - Python [Выбрать]
  1. def convert_coordinates(*args):
  2.     """
  3.    Функция преобразования координат в формат AutoCAD
  4.    :param args: координаты для преобразования, допустима передача списка или кортежа
  5.    :return: Координаты в формате AutoCAD
  6.    """
  7.     if isinstance(args[0], (list, tuple)):
  8.         coords = [item for item in args[0]]
  9.     else:
  10.         coords = args
  11.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)

Если применить её, получаю в вышеупомянутой строке:

Цитировать
Ошибка здесь float() argument must be a string or a number, not 'VARIANT'
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 08-11-2019, 09:41:44
Кроме того, у меня на разных современных компах, в различающихся версиях AutoCAD, python-скрипты, например связанные с созданием и обновлением листов, непредсказуемо вылетают во время этих операций с ошибкой:

Цитировать
-2147418111, 'Вызов был отклонен'

Спасает только введение пауз в наиболее проблемные места в коде после длительных действий:

Код - Python [Выбрать]
  1. time.sleep(2)

Это такой глюк только у меня или это в принципе нормально для взаимодействия с AutoCAD  через COM? Если я смотрю существующий аналогичный код на LISP, никаких временных пауз там не вводится.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-11-2019, 09:54:47
Это такой глюк только у меня или это в принципе нормально для взаимодействия с AutoCAD  через COM?
Нормально через COM из внешнего приложения.
Если я смотрю существующий аналогичный код на LISP, никаких временных пауз там не вводится.
Lisp работает внутри AutoCAD.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 08-11-2019, 19:20:33
Я так понимаю, vtr в этом фрагменте - это аналог convert_coordinates из начала темы?

vtr у  меня функция получения массива VARIANT double. я этот код выделил в функцию, поскольку очень часто требуется такое преобразование

Код - Python [Выбрать]
  1.  
  2. def vtr (x) :
  3.     """
  4.        Возвращает variant массив double
  5.        x - массив двоичных чисел
  6.    """
  7.     return VARIANT(VT_ARRAY | VT_R8, x)
  8.  
  9.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 13-11-2019, 18:18:58
Исправил все ошибки в своем скрипте для рамок, благодаря  коду выше. Дома работает идеально, но на чуть более слабом компе вылетает со случайными ошибками на разных участках кода при обращении к Автокаду. Похоже, что работа через COM подходит только для простейших операций.

Возможно ли через COM очистить командную строку и остановить выполняемую в  данный момент операцию в Автокаде? При тестировании скриптов постоянна ситуация, что командная строка занята незавершенной командой от предыдущей запуска с ошибкой, и пространство модели таким образом недоступно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-11-2019, 18:23:38
Возможно ли через COM очистить командную строку и остановить выполняемую в  данный момент операцию в Автокаде?
Попробуй через SendCommand("\003\003"). Это единственный, но негарантированный способ.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 15-11-2019, 18:50:13
Возможно ли через COM очистить командную строку и остановить выполняемую в  данный момент операцию в Автокаде?
Попробуй через SendCommand("\003\003"). Это единственный, но негарантированный способ.

Действительно, этот способ очень негарантированн, у меня он либо не работает, либо  выдает ошибку. Если бы я писал через C#  - у меня было бы больше возможностей для этого?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 15-11-2019, 19:03:37
Действительно, этот способ очень негарантированн, у меня он либо не работает, либо  выдает ошибку.
Это аналог двойного нажатия ESC в AutoCAD - так что сообщение об ошибке должно быть и должна прерываться активная команда.
Если бы я писал через C#  - у меня было бы больше возможностей для этого?
Если через COM/ActiveX - возможностей столько же. Если использовать AutoCAD .NET API, то необходимости прерывать команду быть не должно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 03-12-2019, 11:13:03
Вот такой вопрос, хочу разобраться, связан с формированием листов.
Я программно генерирую листы, лист создается, настраивается и т.п. и затем я распечатываю в pdf
(используется dwg to pdf принтер). Если распечатать сразу, то все ок, если документ закрывается и потом снова открывается, то может появиться такая фигня, что все листы пустые.
Причем так бывает не всегда, иногда листы остаются. Я не могу понять закономерность, может кто знает почему такая ерунда может быть? Ну или по крайней мере
подскажет направление в каком нужно копать.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 03-12-2019, 11:51:08
Возможно поможет эта статья: https://adn-cis.org/pechat-granicz-okna-pri-pomoshhi-vba.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 07-12-2019, 13:22:56
Нормально через COM из внешнего приложения.
Lisp работает внутри AutoCAD.

А если подключаться к AutoCAD не через COM, а через .NET, но не на C#, а например на Python с помощью библиотеки pythonnet - это даст какие-то преимущества? Т.е. с точки зрения Автокад это будет отличасть от написания .NET  на C#?
Просмотрел видеоуроки по C#, вроде синтаксис  понимаю и базовые вещи. Но как только увидел на этом форуме  урок по написанию простейшей программы на C# к AutoCAD -  понимаю, что ничего не понимаю  :D
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-12-2019, 15:02:28
А если подключаться к AutoCAD не через COM, а через .NET, но не на C#, а например на Python с помощью библиотеки pythonnet - это даст какие-то преимущества?
Я не пишу на Python, не знаю возможностей PythonNet. Поэтому затрудняюсь ответить на этот вопрос. В любом случае это неподдерживаемый со стороны Autodesk интерфейс.
Но как только увидел на этом форуме  урок по написанию простейшей программы на C# к AutoCAD -  понимаю, что ничего не понимаю 
Да ладно. Ничего сложного в нём нет - нужно просто разобраться в этом первом примере, а дальше будет проще...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 13-12-2019, 13:14:32
А если подключаться к AutoCAD не через COM, а через .NET, но не на C#, а например на Python с помощью библиотеки pythonnet
Не получится подключится. В Autocad что-то делать извне можно только через COM. Написать с помощью pythonnet .NET код для AutoCAD можно, только никак не скомпилировать его в dll, чтобы запустить из AutoCAD.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 13:57:42
Возможно поможет эта статья: https://adn-cis.org/pechat-granicz-okna-pri-pomoshhi-vba.html
Может быть что то в этом есть,  возможно где то несостыковка именно с координатами. В примере показана печать из пространства модели как я понимаю, и преобразование
применяется когда используется метод печати окна. Я же применяю метод печати листа. После того как настройка выполняется, все нормально, можно печатать. После того как закрываеш чертеж и снова его открываешь, приходится все листы сносить и заново делать. А это бывает довольно много времени для этого требуется.
В общем вот мой код, по возможности посоветуйте где имеет смысл воспользоваться преобразованием координат. Я бы прислал и файл, но не вижу как прицепить чертеж. попробую вставить ссылку на файл на облаке

https://1drv.ms/u/s!Aj6-EzSXLgqnhMYM6Tv1iEobI8uxQg?e=ggJbFg

Код - Python [Выбрать]
  1. def CreateLayout(doc, h, i, scale = 100) :
  2.     """
  3.    Создает новый лист и выводит на него область полилинии
  4.    Подбирает размер, исходя из масштаба
  5.    i - число, из которого создается имя листа. Имена листов всегда будут числовые
  6.  
  7.    """
  8.     import time
  9.     pl = doc.HandleToObject(h)
  10.     bb = pl.GetBoundingBox()
  11.  
  12.     dt, dx = pl.GetXData('DM_Page')
  13.  
  14.     try :
  15.         page_scale = dx[2]
  16.     except :
  17.         page_scale = scale  
  18.    
  19.     size = (bb[1][0] - bb[0][0], bb[1][1]-bb[0][1])
  20.     mn = GetMediaName(size, scale = page_scale)
  21.    
  22.     try :
  23.         lo = doc.Layouts.Add(f'{i:05}')
  24.     except Exception as ex:        
  25.         lo = doc.Layouts(f'{i:05}')
  26.        
  27.        
  28.     lo.ConfigName = "DWG To PDF.pc3"
  29.     lo.RefreshPlotDeviceInfo()
  30.     lo.CanonicalMediaName = mn
  31.     lo.RefreshPlotDeviceInfo()
  32.     lo.PaperUnits = acad_mod.constants.acMillimeters
  33.     lo.PlotType = acad_mod.constants.acLayout
  34.    
  35.     lo.PlotRotation = acad_mod.constants.ac0degrees
  36.        
  37.     doc.Regen(0)
  38.    
  39.     doc.ActiveLayout = lo
  40.     doc.MSpace = False
  41.    
  42.     for e in lo.Block :
  43.         e.Delete()
  44.        
  45.     #     Создаем вид
  46.  
  47.     psize = lo.GetPaperSize()
  48.     margins = lo.GetPaperMargins()
  49.     pvsize = (psize[0] - margins[0][0] - margins[1][0], psize[1] - margins[0][1] - margins[1][1])    
  50.    
  51.     center = (pvsize[0] / 2 , pvsize[1] / 2, 0)    
  52.  
  53.     pv = doc.PaperSpace.AddPViewport(vtr(center), pvsize[0], pvsize[1])
  54.     pv.Layer = 'defpoints'
  55.     pv.Display(True)
  56.    
  57.     doc.MSpace = True
  58.     doc.Application.ZoomWindow(vtr(bb[0]), vtr(bb[1]))
  59.     doc.MSpace = False
  60.     doc.Application.ZoomExtents()
  61.     doc.Regen(0)    
  62.  
  63.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-12-2019, 14:49:36
После того как закрываеш чертеж и снова его открываешь, приходится все листы сносить и заново делать.
Зачем?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 15:10:59
Проблема в том, что настройки листа сбиваются, если посмотреть приложенный файл, то, думаю, будет понятно. А выглядит это так: сформировал все листы,
распечатал, закрыл чертеж, после того, как заново чертеж отрываю, в большинстве листов как бы нет самого листа, можно несколько раз щелкнуть колесико, тогда границы листа появляются, но отображают совсем не то, что нужно. В общем работает все не так как нужно и распечатать лист не получается, поэтому сношу все и создаю все заново. Пока так. Хотелось бы справиться с этой проблемой, поскольку это ерунда какая-то. Так не должно быть.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-12-2019, 16:12:42
DMuzer,
Если я правильно понял, у тебя получается нормальным только последний лист.
И похоже из-за этого:
Код - Python [Выбрать]
  1. for e in lo.Block :
  2.         e.Delete()
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 16:26:55
Возможно, я попробую убрать этот блок. Но все-таки поясню его смысл.
При создании нового листа, на нем может быть вьюпорт, который автоматически создается(в настройках можно отключать), но мне кажется этот кусочек кода работает.
lo - это вновь созданный лист, lo.Block - это объекты на листе, на новом листе, только вьюпорт, его я и удаляю, мне он не нужен, я сделаю новый.

В общем, мне кажется, что этот код не должен удалять объекты на других листах, только на листе, с которым я работаю. При этом, я удаляю объекты до того, как создать все свои.
Кроме того, после создания листов - там же все в порядке, я же их могу всега видеть и распечатать, ведь печатаю я после того, как создаю все листы. Проблема возникает когда я закрываю чертеж. А после того как заново открываю - картина такая как в файле который для примера привел.
Так что, на первый взгляд, этот код не должен вызывать этих проблем, но я попробую, может проблема тут глубже. А у Вас может другие предположения есть?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-12-2019, 16:34:59
Кроме того, после создания листов - там все в порядке, я же их могу всега видеть и распечатать, ведь печатаю я после того, как создаю все листы.
Тогда я ничего не понял. После того как ты создаёшь все эти листы у тебя получается нормальный чертеж, каждый из листов которого нормально печатается? И после сохранения и повторного открытия чертежа информация с листов пропадает??? Но это может только означить, что твой код портит чертеж. Я запустил _AUDIT и что я вижу:

Command: _AUDIT
Fix any errors detected? [Yes/No] <N>: _y
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 800     objects auditedAcDbBlockReference(437)
                     XData String Length 312 > 255      Truncate to 255
Pass 1 15300   objects auditedAcDbSortentsTable(4B4E)
      Error for Entry (4B51,4B53) eDuplicateKey         fixed
Pass 1 15400   objects auditedAcDbSortentsTable(4B9A)
      Error for Entry (4BA9,4BAB) eDuplicateKey         fixed
Pass 1 16600   objects audited
Invalid viewport-configuration name "*Multiple" found.
  Changed to "AUDIT_I_191213153339-0".
AcDbViewportTableRecord: "AUDIT_I_191213153339-0"
        Tilemode Viewport Corners Not filling up whole screen Set to 0,0..1,1
Invalid viewport-configuration name "*Multiple" found.
  Changed to "AUDIT_I_191213153339-1".
AcDbViewportTableRecord: "AUDIT_I_191213153339-1"
        Tilemode Viewport Corners Not filling up whole screen Set to 0,0..1,1
Pass 1 26600   objects audited
Auditing Entities Pass 2
Pass 2 16700   objects auditedAcDb2dVertex(250DF)         layer != owner's            set to owner's
AcDb2dVertex(250E0)         layer != owner's            set to owner's
AcDb2dVertex(250E1)         layer != owner's            set to owner's
AcDb2dVertex(250E2)         layer != owner's            set to owner's
AcDb2dVertex(250E3)         layer != owner's            set to owner's
Pass 2 26600   objects audited
Auditing Blocks
 349     Blocks audited
Auditing AcDsRecords
Regenerating model.
Total errors found 12 fixed 12
Erased 0 objects

Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 16:42:34
И после сохранения и повторного открытия чертежа информация с листов пропадает???
Именно так.

Я понимаю, что что-то не так делаю.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 16:45:58
Я тоже сделал аудит, меня заинтересовала вот какая строка:

           Paperspace vport layer Not "0"               "0"
AcDbViewport(2B4DB)               не восстановлен.

что это может значить? Я должен при создании vport только на слой 0 помещать? Может в этом дело?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 16:48:34
И еще такая строчка:

Обнаружено недопустимое имя конфигурации видовых экранов "*Multiple".
AcDbViewportTableRecord: "*Multiple"

Что это должно значить?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 13-12-2019, 16:52:49
И еще такая строчка:

Обнаружено недопустимое имя конфигурации видовых экранов "*Multiple".
AcDbViewportTableRecord: "*Multiple"

Что это должно значить?
Для начала удали все листы, выполни _AUDIT с исправлением всех ошибок. Затем сохрани чертеж, снова запусти _AUDIT и убедись, что ошибок нет. Дальше можешь запускать свою программу и посмотри что после неё скажет _AUDIT.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 13-12-2019, 17:16:32
Похоже, что дело как раз в этом.
Вроде как после исправления ошибок и сохранения, далее все правильно идет.
Посмотрим, как все будет дальше.
Спасибо!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 14-01-2020, 16:52:15
Доброго дня!
Подскажите, как решить задачу: я через ActiveX вставляю выноски функцией AddMLeader.
Иногда нужно чтобы выноска присоединялась к тексту слева, то все ок, но никак не могу добиться, чтобы при вставке выноска присоединялась справа. Вроде все что в голову приходило перепробовал. Выноска автоматически перескакивает как нужно если ее вручную подвигатть, но это вроде не совсем то что нужно. Можно это через ActiveX решить?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 14-01-2020, 17:04:43
По-моему, надо смотреть в сторону выравнивания аннотации (если там текст).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 14-01-2020, 17:07:23
Подскажите, как решить задачу: я через ActiveX вставляю выноски функцией AddMLeader.
Покажи код, которым ты это делаешь.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 14-01-2020, 17:09:16
Что с выравниванием не получается...
пробовал
TextAttachmentDirection, TextJustify что то не то...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 14-01-2020, 17:11:14
Код - Python [Выбрать]
  1.         ml = doc.ModelSpace.AddMLeader(vtr(pts), 0)
  2.        
  3.        
  4.         ml[0].Layer = '_fsa-anno-notes'
  5.         ml[0].TextBackgroundFill=True
  6.         ml[0].TextJustify = 9
  7.         ml[0].TextString = ts
  8.         ml[0].ArrowHeadType = 19
  9.         ml[0].Update()
  10.  
  11.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 14-01-2020, 17:12:45
DMuzer,
Какие координаты точек ты передаёшь (т.е. что в массиве pts)?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 14-01-2020, 17:13:47
Код - Python [Выбрать]
  1.         ent, p = doc.Utility.GetEntity()
  2.         print(ent, p)
  3.         pl = polyline(ent.Coordinates, doc)
  4.         npoint = pl.get_nearest_point(point2d(p, doc))
  5.         nline = pl.get_nearest_line(point2d(p, doc))
  6.         print(pl, npoint)
  7.        
  8.         ts = re.search(r"dn\d+", ent.Layer).group(0).upper()
  9.        
  10.         a1, b1, c1 = nline[0].nparams
  11.        
  12.         if (a1 != 0) != (b1 != 0) :        
  13.             pts = [npoint[0], npoint[1],0, npoint[0]-1000, npoint[1]-200, 0,]
  14.         else :
  15.              pts = [npoint[0], npoint[1],0, npoint[0]+200, npoint[1]-200, 0,]
  16.        
  17.         ml = doc.ModelSpace.AddMLeader(vtr(pts), 0)
  18.        
  19.        
  20.         ml[0].Layer = '_fsa-anno-notes'
  21.         ml[0].TextBackgroundFill=True
  22.         ml[0].TextJustify = 9
  23.         ml[0].TextString = ts
  24.         ml[0].ArrowHeadType = 19
  25.         ml[0].Update()
  26.  
  27.  
  28.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 14-01-2020, 17:21:56
Пара пояснений к коду:
Выноска - чтобы автоматически проставить диаметры на трубы, которые отрисованы полилиниями на разных слоях.
polyline и point2d - мои классы, для реализации выч. геометрии.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 14-01-2020, 17:52:10
Ответ здесь: https://adn-cis.org/forum/index.php?topic=2709.0
Нужно использовать метод SetDoglegDirection
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 14-01-2020, 18:08:31
Заработало с DogLegDirection, Спасибо!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 22-01-2020, 13:32:00
Добрый день!
Подскажите, какими функциями надо воспользоваться, чтобы сделать копию существующего блока в чертеже? Именно определения  блока, а не блока в чертеже.
Попробовал несколько вариантов не получается. Например я пробовал так:

Код - Python [Выбрать]
  1. ent = doc.Utility.GetEntity()[0]
  2. lst = [doc.Blocks(ent.Name)]
  3. lst = VARIANT(VT_DISPATCH|VT_ARRAY, lst)
  4. res = doc.CopyObjects(lst)
  5.  

Пробовал добавлять и ModelSpace и Document в качестве нового собственника, пока не получилось...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-01-2020, 13:34:59
Пробовал добавлять и ModelSpace и Document в качестве нового собственника, пока не получилось...
Попробуй в качестве нового собственника doc.Blocks
Впрочем подозреваю, что так не сработает. Нужно сначала создать блок с новым именем ( doc.Blocks.Add (...) ) и потом в него при помощи CopyObjects скопировать все объекты первого блока (т.е. новым собственником будет новый блок).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 22-01-2020, 14:37:11
Видимо так и придется. Как думаете, если мне нужно скопировать определение блока в другой чертеж, тоже не получится? У меня получалось скопировать вхождение блока из одного чертежа в другой, и соответственно определение тоже копировалось, на крайний случай пойдет, но все таки на мой взгляд грубовато чтобы скопировать определение блока.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-01-2020, 14:39:41
Как думаете, если мне нужно скопировать определение блока в другой чертеж, тоже не получится?
Попробуй. В пределах одного чертежа скорее всего не получится из-за совпадения имён блоков. В другом чертеже если одноимённого блока нет, то возможно скопируется. 
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 22-01-2020, 14:41:54
Вот так у меня получилось сделать копию блока:

Код - JSON [Выбрать]
  1. ent = doc.Utility.GetEntity()[0]
  2. o_blk = doc.Blocks(ent.Name)
  3.  
  4. i = 0
  5. while True :
  6.     try :
  7.         b_name = f"{o_blk.Name}_{i:02d}"
  8.         n_blk = doc.Blocks.Add(vtr([0,0,0]),b_name)
  9.         break
  10.     except :
  11.         i += 1
  12.         raise
  13.        
  14. lst = [e for e in o_blk]
  15. v_lst = VARIANT(VT_DISPATCH|VT_ARRAY, lst)
  16.  
  17. res = doc.CopyObjects(v_lst, n_blk)
  18. print(n_blk)
  19.  
  20. res
  21.  

Эта функция возвращает кортеж из двух массивов, в котором возвращаются скопированные объекты. Я правильно понимаю, что это возвращаются и исходные объекты и новые? То есть в этом случае их как то можно связать, или после копирования передать какие то данные?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-01-2020, 14:57:55
Я правильно понимаю, что это возвращаются и исходные объекты и новые?
Нет. Эта функция возвращает:
Цитировать
RetVal = object.CopyObjects(Objects [, Owner] [, IDPairs])
RetVal - Variant (array of objects)
An array of newly created duplicate objects. Only primary objects are returned in this array.

Т.е. только новые, да и то не все, а только главные.
А вот в IDPairs:
Цитировать
IDPairs - Variant (array of IDPair objects); input-output; optional
Information on what happened during the copy and translation process.
Input: an empty variant.
Output: an array of IDPair objects.
Т.е. здесь пара: старый-новый объекты.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 23-01-2020, 01:17:23
Ну собственно справку я видел, как раз и вопрос возник, что не совсем понятно, что возвращает функция. Например, скопировала 3 объекта, а возвращает два массива по 3 объекта.
Что касается основных объектов - то я думаю имеется ввиду что если копируется блок, то будет возвращена ссылка именно на блок, а его составляющие возвращены не будут.
Надо будет поэксперементировать, понять, что же все таки она возвращает.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 23-01-2020, 01:20:08
 Еще вопрос, у меня есть динамический блок, функция GetBoundingBox возвращает границы объекта включая все невидимые примитивы этого блока, включая и те, которые входят в другие варианты отображения блока.
Существует ли способ определить именно видимые границы блока? то есть только для активной видимости динамического блока?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-01-2020, 01:41:48
Все примитивы, невидимые в текущей видимости вставки блока в составе своего анонимного блока имеют признак Visible установленную в False. Это наводка для получения правильного GetBoundingBox - такие примитивы следует пропустить. Т.е. необходимо вычислить GetBoundingBox для всех видимых примитивов в блоке, а затем этот "ящик" преобразовать по матрице преобразования блока (которую нужно вычислить и готового алгоритма для COM/ActiveX я не нашел). Альтернативный вариант - вызов метода Explode с вычислением GetBoundingBox и последующим удалением полученных примитивов.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 23-01-2020, 10:44:58
То есть получается, что без костылей никак?
Скажите а в .net такие функции присутствуют?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-01-2020, 11:05:19
Скажите а в .net такие функции присутствуют?
В .NET у BlockReference есть свойство BlockTransform, которое возвращает матрицу преобразования из координат блока в координаты МСК (WCS).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-01-2020, 11:09:23
Вот как решается эта задача в .NET: https://adn-cis.org/forum/index.php?topic=2933.msg12071#msg12071
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 23-01-2020, 14:34:05
Ну даже и с помощью .NET не все так просто...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-01-2020, 17:54:25
В .NET в последних версиях AutoCAD есть метод BlockReference.GeometryExtentsBestFit - я не проверял, но вполне возможно, что он учитывает и установленную видимость в динамическом блоке.